diff options
Diffstat (limited to 'trunk')
241 files changed, 0 insertions, 53682 deletions
diff --git a/trunk/AUTHORS b/trunk/AUTHORS deleted file mode 100644 index 96a4141..0000000 --- a/trunk/AUTHORS +++ /dev/null @@ -1,2 +0,0 @@ -For Now: -Jakub Jelinek. diff --git a/trunk/COPYING b/trunk/COPYING deleted file mode 100644 index eeb586b..0000000 --- a/trunk/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - 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. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/trunk/ChangeLog b/trunk/ChangeLog deleted file mode 100644 index c24ba7b..0000000 --- a/trunk/ChangeLog +++ /dev/null @@ -1,729 +0,0 @@ -2013-10-05 Jakub Jelinek <jakub@redhat.com> - - * src/arch-s390.c (s390_prelink_conflict_rela): For R_390_IRELATIVE, - always use that relocation type in the conflict section. - -2013-10-01 Jakub Jelinek <jakub@redhat.com> - - * testsuite/ifunc.h (IFUNC_ASM): Add s390x and s390 version. - -2013-09-30 Richard Sandiford <rsandifo@linux.vnet.ibm.com> - - * src/arch-s390.c (s390_prelink_conflict_rela): Fix handling of - R_390_IRELATIVE. - * src/arch-s390x.c (s390x_prelink_conflict_rela): Likewise. - -2013-07-19 Marek Polacek <polacek@redhat.com> - - * doc/prelink.8 (--usage): Document it. - (--layout-page-size=): Likewise. - -2013-05-03 Jakub Jelinek <jakub@redhat.com> - - * src/cache.c (prelink_save_cache_check): For ET_CACHE_DYN - or ET_UNPRELINKABLE dependencies, call prelink_save_cache_check - recursively. - * testsuite/Makefile.am (TESTS): Add unprel1.sh. - * testsuite/Makefile.in: Regenerated. - * testsuite/unprel1.sh: New test. - * testsuite/unprel1.c: New file. - * testsuite/unprel1lib1.c: New file. - * testsuite/unprel1lib2.c: New file. - - * src/prelink.h (R_390_IRELATIVE): Define if not defined. - -2013-04-25 Jakub Jelinek <jakub@redhat.com> - - * src/arch-s390.c (s390_adjust_rela, s390_prelink_rela, - s390_apply_conflict_rela, s390_prelink_conflict_rela, - s390_undo_prelink_rela): Handle R_390_IRELATIVE. - * src/arch-s390x.c (s390x_adjust_rela, s390x_prelink_rela, - s390x_apply_conflict_rela, s390x_prelink_conflict_rela, - s390x_undo_prelink_rela, s390x_reloc_size): Likewise. - -2013-04-18 Jakub Jelinek <jakub@redhat.com> - - * testsuite/reloc4.sh: Add libraries to link lines to make - testsuite work both with --no-add-needed and with --add-needed, - including latest ld.bfd. - * testsuite/reloc5.sh: Likewise. - * testsuite/reloc8.sh: Likewise. - * testsuite/reloc9.sh: Likewise. - -2013-04-17 Jakub Jelinek <jakub@redhat.com> - - * testsuite/ifunc.h (IFUNC_DECL): Fix up .size on ppc64. - * testsuite/cxx1.sh: Add libraries to link lines to make - testsuite work both with --no-add-needed and with --add-needed, - including latest ld.bfd. - * testsuite/cxx2.sh: Likewise. - * testsuite/cxx3.sh: Likewise. - * testsuite/deps1.sh: Likewise. - * testsuite/deps2.sh: Likewise. - * testsuite/ifunc1.sh: Likewise. - * testsuite/ifunc2.sh: Likewise. - * testsuite/ifunc3.sh: Likewise. - * testsuite/quick1.sh: Likewise. - * testsuite/quick2.sh: Likewise. - * testsuite/quick3.sh: Likewise. - * testsuite/reloc1.sh: Likewise. - * testsuite/reloc10.sh: Likewise. - * testsuite/reloc11.sh: Likewise. - * testsuite/reloc3.sh: Likewise. - * testsuite/reloc6.sh: Likewise. - * testsuite/reloc7.sh: Likewise. - * testsuite/shuffle1.sh: Likewise. - * testsuite/shuffle2.sh: Likewise. - * testsuite/shuffle3.sh: Likewise. - * testsuite/shuffle4.sh: Likewise. - * testsuite/shuffle5.sh: Likewise. - * testsuite/shuffle6.sh: Likewise. - * testsuite/shuffle7.sh: Likewise. - * testsuite/shuffle8.sh: Likewise. - * testsuite/shuffle9.sh: Likewise. - * testsuite/tls1.sh: Likewise. - * testsuite/tls2.sh: Likewise. - * testsuite/tls3.sh: Likewise. - * testsuite/tls4.sh: Likewise. - * testsuite/tls5.sh: Likewise. - * testsuite/tls6.sh: Likewise. - * testsuite/undo1.sh: Likewise. - -2012-06-28 Jakub Jelinek <jakub@redhat.com> - - * src/get.c (is_ldso_soname): Add arm dynamic linker SONAMEs. - - * src/dwarf2.h (DW_FORM_GNU_ref_alt, - DW_FORM_GNU_strp_alt): Define. - * src/dwarf2.c (read_abbrev): Allow those forms. - (adjust_attributes): Handle them. - -2012-04-10 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.c (DEBUG_MACRO): Define. - (debug_sections): Add .debug_macro entry. - -2012-04-02 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.c (adjust_attributes): For DWARF4+ treat - DW_AT_data_member_location with DW_FORM_data[48] as - large constant instead of loclistptr. - -2011-10-12 Jakub Jelinek <jakub@redhat.com> - - * src/main.c (layout_page_size): New variable. - (OPT_LAYOUT_PAGE_SIZE): Define. - (options): Add --layout-page-size option. - (set_default_layout_page_size): New function in i?86/x86_64 - resp. empty macro on other architectures. - (main): Call it. - * src/arch-i386.c (i386_layout_libs_init): Fail if - l->max_page_size is larger than 2MB and exec_shield is true. - Compute reg0s as REG0S rounded up to l->max_page_size - boundary and use it instead of REG0S. - (i386_layout_libs_pre): Compute reg0s as REG0S rounded up to - l->max_page_size boundary and use it instead of REG0S. - Fix up a pasto in computation of virt parameter for - third i386_find_free_addr call. - * src/prelink.h (layout_page_size): New decl. - * src/layout.c (layout_libs): Set max_page_size and - l.max_page_size to maximum of plarch->max_page_size - and layout_page_size. Fail if mmap_base or mmap_end - aren't max_page_size aligned. - * src/arch-ppc.c (ppc_layout_libs_pre): Give up if - l->max_page_size is larger than 64KB. - -2011-08-26 Jakub Jelinek <jakub@redhat.com> - - * testsuite/cxx3.sh: Expect fewer conflicts. - - * src/arch-arm.c (PL_ARCH): Change .dynamic_linker to - /lib/ld-linux.so.3. - -2011-08-25 Jakub Jelinek <jakub@redhat.com> - - * src/gather.c (gather_func): When looking for PT_PHDR header, - skip any PT_LOPROC ... PR_HIPROC phdrs. - - * testsuite/cxx1.sh: Don't check for any "Removing C++ conflict" - messages on arm. - * testsuite/cxx2.sh: Likewise. - * testsuite/cxx3.sh: New test. - * testsuite/cxx3.C: New file. - * testsuite/cxx3.h: New file. - * testsuite/cxx3lib1.C: New file. - * testsuite/cxx3lib2.C: New file. - * testsuite/Makefile.am (TESTS): Add cxx3.sh. - * testsuite/Makefile.in: Regenerated. - -2011-08-25 William Cohen <wcohen@redhat.com> - - * testsuite/shuffle2.c: Use %nobits instead of @nobits - to be arm assembler friendly. - * testsuite/shuffle9.c: Likewise. - * testsuite/reloc5.c (main): Likewise. - -2011-06-22 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.h (DW_OP_GNU_parameter_ref): Define. - * src/dwarf2.c (adjust_location_list): Handle - DW_OP_GNU_parameter_ref. - -2011-05-11 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.h (DW_OP_GNU_const_type, DW_OP_GNU_regval_type, - DW_OP_GNU_deref_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret): - Define. - * src/dwarf2.c (adjust_location_list): Handle DW_OP_GNU_const_type, - DW_OP_GNU_retval_type, DW_OP_GNU_defer_type, DW_OP_GNU_convert and - DW_OP_GNU_reinterpret. - -2011-04-01 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.h (DW_TAG_GNU_template_template_param, - DW_TAG_GNU_template_parameter_pack, DW_TAG_GNU_formal_parameter_pack, - DW_TAG_GNU_call_site, DW_TAG_GNU_call_site_parameter, - DW_AT_GNU_vector, DW_AT_GNU_guarded_by, DW_AT_GNU_pt_guarded_by, - DW_AT_GNU_guarded, DW_AT_GNU_pt_guarded, DW_AT_GNU_locks_excluded, - DW_AT_GNU_exclusive_locks_required, DW_AT_GNU_shared_locks_required, - DW_AT_GNU_odr_signature, DW_AT_GNU_template_name, - DW_AT_GNU_call_site_value, DW_AT_GNU_call_site_data_value, - DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered, - DW_AT_GNU_tail_call, DW_AT_GNU_all_tail_call_sites, - DW_AT_GNU_all_call_sites, DW_AT_GNU_all_source_call_sites, - DW_OP_GNU_entry_value): Define. - * src/dwarf2.c (adjust_location_list): Handle DW_OP_GNU_entry_value. - (adjust_attributes): Handle DW_AT_GNU_call_site_value, - DW_AT_GNU_call_site_data_value, DW_AT_GNU_call_site_target and - DW_AT_GNU_call_site_target_clobbered. - -2010-11-23 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.h (DW_OP_GNU_implicit_pointer): Define. - * src/dwarf2.c (adjust_location_list): Add CU argument, fix - handling of DW_OP_call_ref, handle DW_OP_GNU_implicit_pointer. - (adjust_dwarf2_loc): Add CU argument, adjust adjust_location_list - caller. - (adjust_attributes): Adjust adjust_location_list and - adjust_dwarf2_loc callers. - (adjust_dwarf2_frame): Likewise. - -2010-11-22 Jakub Jelinek <jakub@redhat.com> - - * src/dso.c: Include sys/xattr.h. - (copy_xattrs): New function. - (set_security_context): Call it. - -2010-07-14 Jakub Jelinek <jakub@redhat.com> - - * src/prelink.h (copy_fd_to_file): New prototype. - * src/undo.c (prelink_undo): If undo_output and .gnu.prelink_undo - section is not present, don't reopen_dso, just return 0. - * src/main.c (main): If dso isn't writable with undo_output, - copy_fd_to_file dso->fd. - * src/dso.c (copy_fd_to_file): New function. - (update_dso): Use it. - -2010-04-13 Jakub Jelinek <jakub@redhat.com> - - * testsuite/reloc8.sh: Don't use -Wl,-z,nocopyreloc on - sparc64. - * testsuite/reloc9.sh: Likewise. - - * src/dwarf2.c (DEBUG_TYPES): Define. - (debug_sections): Add .debug_types entry. - (read_abbrev): Handle new DWARF4 forms. - (adjust_attributes): DW_AT_segment can be a loclistptr. - DW_AT_byte_size, DW_AT_bit_offset, DW_AT_bit_size, - DW_AT_string_length, DW_AT_lower_bound, DW_AT_return_addr, - DW_AT_bit_stride, DW_AT_upper_bound, DW_AT_count, - DW_AT_segment, DW_AT_static_link, DW_AT_use_location, - DW_AT_allocated, DW_AT_associated, DW_AT_data_location - and DW_AT_byte_stride can be exprloc. Handle new DWARF4 forms. - (adjust_dwarf2_line): Handle adjusting DWARF4 .debug_line - sections. - (adjust_dwarf2_frame): Handle adjusting DWARF4 .debug_frame - section. - (adjust_dwarf2_info): New function, moved from adjust_dwarf2. - Handle DWARF4 .debug_info and handle .debug_types too. - (adjust_dwarf2): Call it for .debug_info and .debug_types - sections. - * src/dwarf2.h (DW_TAG_type_unit, DW_TAG_rvalue_reference_type, - DW_TAG_template_alias, DW_FORM_sec_offset, DW_FORM_exprloc, - DW_FORM_flag_present, DW_FORM_ref_sig8, DW_AT_bit_stride, - DW_AT_byte_stride, DW_AT_description, DW_AT_binary_scale, - DW_AT_decimal_scale, DW_AT_small, DW_AT_decimal_sign, - DW_AT_digit_count, DW_AT_picture_string, DW_AT_mutable, - DW_AT_threads_scaled, DW_AT_explicit, DW_AT_object_pointer, - DW_AT_endianity, DW_AT_elemental, DW_AT_pure, DW_AT_recursive, - DW_AT_signature, DW_AT_main_subprogram, DW_AT_data_bit_offset, - DW_AT_const_expr, DW_AT_enum_class, DW_AT_linkage_name, - DW_LNS_set_prologue_end, DW_LNS_set_epilogue_begin, - DW_LNS_set_isa, DW_LNE_set_discriminator, DW_LANG_Python): Define. - - * src/prelink.h (send_file): New prototype. - * src/execstack.c (send_file): New dummy function. - * src/verify.c (send_file): No longer static. Don't loop forever - if write or read return 0. - * src/undo.c (prelink_undo): If undo_output is -, use /tmp/undo - instead of - as temp file prefix. - * src/dso.c (set_security_context): Drop unused dso argument, add - ignore_errors argument. If it is non-zero, don't error if - setfilecon failed. - (update_dso): If orig_name is non-NULL, don't error if fchown or - fchmod fails. If rename fails or name1 is - and orig_name is - non-NULL, copy the temporary file to name1 (or to stdout if - name1 is -) instead of failing. - -2010-01-06 Jakub Jelinek <jakub@redhat.com> - - * src/arch-s390.c (s390_prelink_conflict_rela) <case R_390_PC32DBL>: - Ensure negative addends are sign-extended to 64-bits, instead of - zero-extended. - -2010-01-05 Jakub Jelinek <jakub@redhat.com> - - * src/arch-s390.c (s390_prelink_rela, s390_apply_rela, - s390_prelink_conflict_rela, s390_prelink_conflict_rela, - s390_undo_prelink_rela, s390_reloc_size): Handle - R_390_{PC32DBL,16,PC16,PC16DBL,8} relocs. - -2009-12-16 Jakub Jelinek <jakub@redhat.com> - - * testsuite/reloc2.sh: Don't assume textrel works if getenforce - exists, but doesn't print Permissive or Disabled. - * testsuite/reloc8.sh: Likewise. - * testsuite/reloc9.sh: Likewise. - * testsuite/tls3.sh: Likewise. - -2009-11-03 Jakub Jelinek <jakub@redhat.com> - - * src/arch-x86_64.c (x86_64_reloc_size): Handle R_X86_64_IRELATIVE. - - * src/prelink.h (R_PPC_IRELATIVE, R_PPC64_IRELATIVE, - R_PPC64_JMP_IREL): Define if not defined. - * src/undo.c (undo_sections, prelink_undo): Allow .iplt section to - change from SHT_NOBITS to SHT_PROGBITS. - * src/arch-ppc.c (ppc_adjust_rela, ppc_prelink_rela, - ppc_apply_conflict_rela, ppc_undo_prelink_rela): Handle - R_PPC_IRELATIVE. - (ppc_prelink_conflict_rela): Handle R_PPC_IRELATIVE and - conflict->ifunc conflicts. - * src/arch-ppc64.c (ppc64_adjust_rela, ppc64_prelink_rela, - ppc64_undo_prelink_rela): Handle R_PPC64_IRELATIVE and - R_PPC64_JMP_IREL. - (ppc64_apply_conflict_rela, ppc64_reloc_size): Handle - R_PPC64_IRELATIVE. - (ppc64_prelink_conflict_rela): Handle R_PPC64_IRELATIVE, - R_PPC64_JMP_IREL and conflict->ifunc conflicts. - * testsuite/ifunc.h (IFUNC_ASM): Add powerpc definition. - (IFUNC_DECL): Define. - (IFUNC): Use IFUNC_DECL. - -2009-10-19 Joseph Myers <joseph@codesourcery.com> - - * src/conflict.c (prelink_build_conflicts): Use >= not > to - determine whether a relocation points outside the first bss - section. - - * m4/libelf.m4: Resync with version of code in aclocal.m4. - -2009-09-25 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.c (adjust_location_list) <case DW_OP_implicit_value>: Add - missing break statement. - -2009-08-06 Joseph Myers <joseph@codesourcery.com> - - * src/dwarf2.c (dwarf2_write_le64, dwarf2_write_be64): Shift by 56 - not 58 for MSB. - -2009-07-09 Jakub Jelinek <jakub@redhat.com> - - * src/conflict.c (prelink_build_conflicts): Don't call - prelink_conflict_rel{,a} on .gnu.conflict section in executables. - -2009-06-15 Jakub Jelinek <jakub@redhat.com> - - * src/prelink.h (R_386_IRELATIVE, R_X86_64_IRELATIVE): Define - if not defined. - (struct PLArch): Add dest_addr argument to apply_conflict_rela - hook. - (struct prelink_conflict): Change used type from int to unsigned - char, add ifunc field. - (get_relocated_mem): Add dest_addr argument. - * src/get.c (prelink_record_relocations): Handle lookups resolving - to STT_GNU_IFUNC symbols. - * src/conflict.c (get_relocated_mem): Add dest_addr argument, pass - it through to the apply_conflict_rela hook. Fail if - apply_conflict_rela hook failed. - (prelink_build_conflicts): Build conflicts even in the executable, - and for libraries even if no conflicts were reported by the dynamic - linker. In the executable ignore any unused conflicts except for - ifunc conflicts. Adjust get_relocated_mem callers. - * src/cxx.c (remove_redundant_cxx_conflicts): Adjust - get_relocated_mem callers. - * arch-alpha.c (alpha_apply_conflict_rela): Add dest_addr argument. - (alpha_prelink_conflict_rela): Return early if info->dso == dso. - * arch-arm.c (arm_apply_conflict_rela): Add dest_addr argument. - (arm_prelink_conflict_rel, arm_prelink_conflict_rela): Return early - if info->dso == dso. - * arch-cris.c (cris_apply_conflict_rela): Add dest_addr argument. - (cris_prelink_conflict_rela): Return early if info->dso == dso. - * arch-ia64.c (ia64_apply_conflict_rela): Add dest_addr argument. - (ia64_prelink_conflict_rela): Return early if info->dso == dso. - * arch-ppc.c (ppc_apply_conflict_rela): Add dest_addr argument. - (ppc_prelink_conflict_rela): Return early if info->dso == dso. - * arch-ppc64.c (ppc64_apply_conflict_rela): Add dest_addr argument. - (ppc64_prelink_conflict_rela): Return early if info->dso == dso. - * arch-s390.c (s390_apply_conflict_rela): Add dest_addr argument. - (s390_prelink_conflict_rela): Return early if info->dso == dso. - * arch-s390x.c (s390x_apply_conflict_rela): Add dest_addr argument. - (s390x_prelink_conflict_rela): Return early if info->dso == dso. - * arch-sh.c (sh_apply_conflict_rela): Add dest_addr argument. - (sh_prelink_conflict_rela): Return early if info->dso == dso. - * arch-sparc.c (sparc_apply_conflict_rela): Add dest_addr argument. - (sparc_prelink_conflict_rela): Return early if info->dso == dso. - * arch-sparc64.c (sparc64_apply_conflict_rela): Add dest_addr argument. - (sparc64_prelink_conflict_rela): Return early if info->dso == dso. - * arch-mips.c (mipz_apply_conflict_rela): Add dest_addr argument. - (mips_prelink_conflict_reloc, mips_arch_prelink_conflict): Return - early if info->dso == dso. - * arch-i386.c (i386_adjust_rel, i386_adjust_rela, i386_prelink_rel, - i386_prelink_rela, i386_rel_to_rela, i386_undo_prelink_rel, - i386_rela_to_rel): Handle R_386_IRELATIVE. - (i386_apply_conflict_rela): Add dest_addr argument, handle - R_386_IRELATIVE. - (i386_prelink_conflict_rel, i386_prelink_conflict_rela): Handle - R_386_IRELATIVE and conflict->ifunc conflicts. - * arch-x86_64.c (x86_64_adjust_rela, x86_64_prelink_rela, - x86_64_undo_prelink_rela): Handle R_X86_64_IRELATIVE. - (x86_64_apply_conflict_rela): Handle R_X86_64_IRELATIVE and - conflict->ifunc conflicts. - * testsuite/Makefile.am (TESTS): Add ifunc1.sh, ifunc2.sh and - ifunc3.sh. - * testsuite/Makefile.in: Regenerated. - * testsuite/ifunc1.sh: New test. - * testsuite/ifunc2.sh: New test. - * testsuite/ifunc3.sh: New test. - * testsuite/ifunc1.c: New file. - * testsuite/ifunc1lib1.c: New file. - * testsuite/ifunc1lib2.c: New file. - * testsuite/ifunc3.c: New file. - * testsuite/ifunc3lib1.c: New file. - * testsuite/ifunc.h: New file. - * testsuite/ifunctest.c: New file. - - * src/Makefile.am (DEFS, AM_CFLAGS): Add -Wno-pointer-sign. - * src/Makefile.in: Regenerated. - * src/data.c (reopen_dso): Initialize data variable to avoid - warnings. - - * src/dwarf2.h (DW_TAG_condition, DW_TAG_shared_type): Define. - (DW_OP_form_tls_address, DW_OP_call_frame_cfa, DW_OP_bit_piece, - DW_OP_implicit_value, DW_OP_stack_value, DW_OP_GNU_uninit, - DW_OP_GNU_encoded_addr): Define. - (DW_ATE_packed_decimal, DW_ATE_numeric_string, DW_ATE_edited, - DW_ATE_signed_fixed, DW_ATE_unsigned_fixed, DW_ATE_decimal_float): - Define. - (DW_CFA_val_offset, DW_CFA_val_offset_sf, DW_CFA_val_expression): - Define. - (DW_LANG_PLI, DW_LANG_ObjC, DW_LANG_ObjC_plus_plus, DW_LANG_UPC, - DW_LANG_D): Define. - * src/dwarf2.c (debug_sections): Add .debug_pubtypes. - (DEBUG_PUBTYPES): Define. - (DEBUG_MACINFO, DEBUG_LOC, DEBUG_STR, DEBUG_FRAME, DEBUG_RANGES): - Adjust. - (struct cu_data): Add cu_version field. - (read_abbrev): Adjust error messages not to be DWARF-2 specific. - (adjust_location_list): Likewise. Fix up DW_OP_call_ref handling, - handle DW_OP_form_tls_address, DW_OP_call_frame_cfa, - DW_OP_GNU_uninit, DW_OP_bit_piece, DW_OP_stack_value and - DW_OP_implicit_value. - (adjust_attributes): For cu->cu_version == 2 skip ptr_size bytes - instead of just 4. Adjust error messages not to be DWARF-2 - specific. - (adjust_dwarf2_line): Handle version 3 of .debug_line. - (adjust_dwarf2_frame): Just that CIE version is 1 or 3, for - version 1 skip just one byte instead of uleb128 for return address - column. Handle DW_CFA_val_offset, DW_CFA_val_offset_sf and - DW_CFA_val_expression. - (adjust_dwarf2): Handle version 3 of .debug_info, initialize - cu.cu_version. Adjust error messages not to be DWARF-2 specific. - Note that .debug_pubtypes doesn't need adjustments. - -2009-03-11 Jakub Jelinek <jakub@redhat.com> - - * src/prelink.h (PLArch): Add rtype_class_valid field. - * src/get.c (prelink_record_relocations): If not /4, or - dso->arch->rtype_class_valid instead of RTYPE_CLASS_VALID - into reloc_class. - * src/cxx.c (remove_redundant_cxx_conflicts): Use - info->dso->arch->rtype_class_valid instead of RTYPE_CLASS_VALID. - * src/arch-ppc64.c (ppc64_reloc_class): For R_PPC64_COPY return - RTYPE_CLASS_COPY | RTYPE_CLASS_PLT, for non-TLS relocs return - RTYPE_CLASS_PLT. - (PL_ARCH): Set rtype_class_valid to RTYPE_CLASS_PLT. - * src/arch-alpha.c (PL_ARCH): Set rtype_class_valid to - RTYPE_CLASS_VALID. - * src/arch-arm.c (PL_ARCH): Likewise. - * src/arch-cris.c (PL_ARCH): Likewise. - * src/arch-i386.c (PL_ARCH): Likewise. - * src/arch-ia64.c (PL_ARCH): Likewise. - * src/arch-mips.c (PL_ARCH): Likewise. - * src/arch-ppc.c (PL_ARCH): Likewise. - * src/arch-s390.c (PL_ARCH): Likewise. - * src/arch-s390x.c (PL_ARCH): Likewise. - * src/arch-sh.c (PL_ARCH): Likewise. - * src/arch-sparc.c (PL_ARCH): Likewise. - * src/arch-sparc64.c (PL_ARCH): Likewise. - * src/arch-x86_64.c (PL_ARCH): Likewise. - -2009-03-04 Joseph Myers <joseph@codesourcery.com> - - * testsuite/reloc2.sh, testsuite/tls3.sh: Add ARM to architectures - requiring PIC shared libraries. - -2009-03-04 Daniel Jacobowitz <dan@codesourcery.com> - Joseph Myers <joseph@codesourcery.com> - - * src/arch-arm.c (arm_prelink_rel, arm_prelink_rela, - arm_prelink_conflict_rel, arm_prelink_conflict_rela, arm_rel_to_rela, - arm_rela_to_rel, arm_need_rel_to_rela, arm_undo_prelink_rel, - arm_reloc_class): Handle TLS relocations. - * src/prelink.h (R_ARM_TLS_DTPMOD32, R_ARM_TLS_DTPOFF32, - R_ARM_TLS_TPOFF32): Define if R_ARM_TLS_DTPMOD32 not already - defined. - -2009-03-04 Daniel Jacobowitz <dan@codesourcery.com> - - * src/arch-arm.c (arm_adjust_dyn, arm_adjust_rel, arm_adjust_rela, - arm_prelink_rel, arm_prelink_rela, arm_apply_conflict_rela, - arm_apply_rel, arm_apply_rela, arm_prelink_conflict_rela, - arm_rel_to_rela, arm_rela_to_rel, arm_need_rel_to_rela, - arm_arch_prelink, arm_arch_undo_prelink, arm_undo_prelink_rel): - Use endian-neutral functions. - -2008-09-29 Joseph Myers <joseph@codesourcery.com> - - * src/arch-sparc64.c (sparc64_prelink_rela, - sparc64_prelink_conflict_rela, sparc64_undo_prelink_rela, - sparc64_reloc_class): Handle TLS relocations. - (PL_ARCH): Update mmap_base and mmap_end for TASK_UNMAPPED_BASE - change to 0xfffff80100000000. - -2007-12-04 Daniel Jacobowitz <dan@codesourcery.com> - - * src/gather.c (gather_object): Print an error if nftw64 fails. - -2007-10-09 Jakub Jelinek <jakub@redhat.com> - - * src/cxx.c (remove_redundant_cxx_conflicts): Allow .sdata - section as well. - - * src/prelink.h (struct prelink_conflict): Add next2 field. - (struct prelink_conflicts): Add hash2 field. - * src/get.c (prelink_record_relocations): Clear next2 fields. - * src/prelink.c (free_info): Also free hash2 table. - * src/cxx.c (remove_redundant_cxx_conflicts): Populate hash2 - if not populated yet, use it to speed up pltref checking. - - * src/prelink.h (struct prelink_conflicts): New type. - (struct prelink_info): Change type of conflicts and curconflicts - fields to struct prelink_conflicts *. - * src/get.c (conflict_hash_init): New function. - (prelink_record_relocations): Adjust initialization of conflicts - array. If conflict linked lists has more than 15 entries, use - hash table with chains. - * src/prelink.c (free_info): Handle freeing conflict list using a hash - table. - * src/fptr.c (opd_init): Only walk corresponding hash chain if - conflict list is using a hash table. - * src/conflict.c (prelink_conflict): Likewise. - (prelink_build_conflicts): Handle conflict list using a hash table. - * src/cxx.c (remove_redundant_cxx_conflicts): Likewise. Only walk - corresponding hash chain if conflict list is using a hash table. - - * src/doit.c (find_ents): Clear e->u.tmp. - (clear_ent_marks, find_unlisted_dependency): Remove. - (prelink_ent): More efficient non-recursive check for - unlisted dependencies. - - * src/cxx.c (find_cxx_sym): If fcs->lastndx != -1, search first - among symbols around it. - -2007-10-08 Jakub Jelinek <jakub@redhat.com> - - * src/space.c (find_readonly_space): Disallow section insertion in - between adjacent SHT_NOTE sections. When creating new PT_LOAD, - handle multiple consecutive SHT_NOTE sections with just one PT_NOTE - segment for them. - * testsuite/Makefile.am (TESTS): Add shuffle9.sh. - * testsuite/Makefile.in: Regenerated. - * testsuite/shuffle9.sh: New test. - * testsuite/shuffle9.c: New. - - * testsuite/shuffle2.c: Add .previous at the end of __asm. - * testsuite/reloc5.c (main): Likewise. - - * testsuite/tls3.sh: If libs aren't built with -fpic, - disable the test under SELinux in enforcing mode. - - * src/cxx.c: Include alloca.h. - (specials): Moved out of remove_redundant_cxx_conflicts to toplevel. - Remove section fields. - (find_cxx_sym_valsize, find_cxx_sym_cache): New structs. - (struct find_cxx_sym): Add cache and lastndx fields. - (cachecmp, create_cache): New functions. - (find_cxx_sym): Add cache argument. If cache[n] is NULL, call - create_cache. Do a binary search in cache[n]->vals array instead - of always reading the whole symbol table. - (remove_redundant_cxx_conflicts): Adjust find_cxx_sym caller. - Check if secname is ".data" or ".data.rel.ro" instead of comparing - it against specials[k].secname. Use binary search in binsymcache - when doing check_pltref checks. - * testsuite/Makefile.am (TESTS): Add cxx2.sh. - * testsuite/Makefile.in: Regenerated. - * testsuite/cxx1.sh: Check that some conflicts are optimized out - by C++ optimizations. - * testsuite/cxx2.sh: New test. - * testsuite/cxx2.C: New. - -2007-10-04 Jakub Jelinek <jakub@redhat.com> - - * src/prelink.h (read_config): New prototype. - (gather_config, blacklist_from_config): Remove argument. - * src/gather.c (struct config_line): New type. - (config_lines, config_end): New variables. - (read_config): New function. - (gather_config, blacklist_from_config): Walk config_lines - chain instead of reading the config file. - * src/verify.c (prelink_verify): Call read_config. Don't - pass any argument to gather_config. - * src/main.c (main): Likewise. Also for blacklist_from_config. - * testsuite/quick2.sh: Use new -c etc/prelink.conf.d/*.conf - feature in prelink.conf and multiple config snippets. - -2007-06-27 Jakub Jelinek <jakub@redhat.com> - - * testsuite/reloc2.sh: If libs aren't built with -fpic, - disable the test under SELinux in enforcing mode. - -2007-03-02 Sandra Loosemore <sandra@codesourcery.com> - - * doc/prelink.8: Spelling and grammar fixes. - -2006-12-01 Jakub Jelinek <jakub@redhat.com> - - * src/verify.c (prelink_verify): Unlink ent->filename in case of - failures between closing the unprelinked dso and unlinking - ent->filename. - -2006-10-27 Jakub Jelinek <jakub@redhat.com> - - * src/prelink.h (READWRITEPROTOSIZE): Undef after use. - -2006-10-24 Richard Sandiford <richard@codesourcery.com> - - * testsuite/tls3.sh: Use -fpic for MIPS too. - * testsuite/reloc2.sh: Likewise. - - * testsuite/reloc4.sh: Use -mxgot when compiling for MIPS targets. - * testsuite/reloc5.c (main): Make the printed inline asm globalize - testzero. - - * testsuite/shuffle2.c (testzero): Globalize asm definition. - - * src/Makefile.am (arch_SOURCES): Add arch-mips.c - * src/Makefile.in: Regenerate. - * src/arch-mips.c: New file. - - * src/prelink.h (DT_MIPS_RLD_VERSION): Define. - (DT_MIPS_TIME_STAMP): Likewise. - (DT_MIPS_ICHECKSUM): Likewise. - (DT_MIPS_IVERSION): Likewise. - (DT_MIPS_FLAGS): Likewise. - (DT_MIPS_BASE_ADDRESS): Likewise. - (DT_MIPS_CONFLICT): Likewise. - (DT_MIPS_LIBLIST): Likewise. - (DT_MIPS_LOCAL_GOTNO): Likewise. - (DT_MIPS_CONFLICTNO): Likewise. - (DT_MIPS_LIBLISTNO): Likewise. - (DT_MIPS_SYMTABNO): Likewise. - (DT_MIPS_UNREFEXTNO): Likewise. - (DT_MIPS_GOTSYM): Likewise. - (DT_MIPS_HIPAGENO): Likewise. - (DT_MIPS_RLD_MAP): Likewise. - (R_MIPS_TLS_DTPMOD): Likewise. - (R_MIPS_TLS_DTPREL): Likewise. - (R_MIPS_TLS_TPREL): Likewise. - (R_MIPS_GLOB_DAT): Likewise. - (DSO): Add info_DT_MIPS_LOCAL_GOTNO, info_DT_MIPS_GOTSYM, - and info_DT_MIPS_SYMTABNO. - - * src/dso.c (read_dynamic): Initialize the new DSO fields. - (adjust_symbol_p): Handle stub values on MIPS. - * src/prelink.c (prelink_prepare): Handle SHT_DYNAMIC and - SHT_MIPS_REGINFO on MIPS. - * src/space.c (find_readonly_space): Don't place the new section - in the PT_PHDR segment. - - * src/prelink.h (data_iterator): New structure. - (init_data_iterator): Declare. - (get_data_from_iterator): Likewise. - (get_sym_from_iterator): Likewise. - * src/data.c (init_data_iterator): New function. - (get_data_from_iterator): Likewise. - (get_sym_from_iterator): Likewise. - - * src/prelink.h (READWRITEPROTOSIZE): New macro. Instantiate - READWRITEPROTO for big and little endian. Add prototypes for - native-endian functions (buf_read_uneNN, read_uneNN, buf_write_neNN - and write_neNN). Replace uses of READWRITEPROTO with uses of - this macro. - * src/data.c (BUFREADUNE, READUNE, WRITENE, BUFWRITENE): New macros. - (READWRITESIZE): New macro. Instantiate READWRITE for big and - little endian. Instantiate BUFREADUNE, READUNE, WRITENE - and BUFWRITENE. Replace uses of READWRITE with uses of this macro. - * src/arch-sh.c (read_une32, write_ne32, buf_write_ne32): Delete. - - * src/prelink.h (PLArch): Add an arch_prelink_conflict callback. - * src/conflict.c (prelink_build_conflicts): If defined, call it - for each dependency. - - * src/prelink.h (PLArch): Make the arch_prelink callback take - a "struct prelink_info *" argument, not a "DSO *" argument. - * src/prelink.c (prelink): Adjust call accordingly. - * src/arch-alpha.c (alpha_arch_prelink): Adjust definition accordingly. - * src/arch-arm.c (arm_arch_prelink): Likewise. - * src/arch-cris.c (cris_arch_prelink): Likewise. - * src/arch-i386.c (i386_arch_prelink): Likewise. - * src/arch-ia64.c (ia64_arch_prelink): Likewise. - * src/arch-ppc.c (ppc_arch_prelink): Likewise. - * src/arch-s390.c (s390_arch_prelink): Likewise - * src/arch-s390x.c (s390x_arch_prelink): Likewise - * src/arch-sh.c (sh_arch_prelink): Likewise. - * src/arch-sparc64.c (sparc64_arch_prelink): Likewise. - * src/arch-sparc.c (sparc_arch_prelink): Likewise - * src/arch-x86_64.c (x86_64_arch_prelink): Likewise. - - * src/prelink.h (PLArch): Add an arch_adjust callback. - * src/dso.c (adjust_dso): Use it, if defined. - - * src/prelink.h (adjust_symbol_p): Declare. - * src/dso.c (adjust_symbol_p): New function, extracted from... - (adjust_symtab): ...here. - -2006-10-27 Jakub Jelinek <jakub@redhat.com> - - * src/dwarf2.c (adjust_dwarf2_ranges): Fix adjusting if end of range - is at the end of some section and there is padding before the - following one. - -2006-07-28 Alexandre Oliva <aoliva@redhat.com> - - * src/cache.c (deps_cmp): Avoid segfault if both a and b are NULL. - -2001-05-24 Jakub Jelinek <jakub@redhat.com> - - * The beginning. diff --git a/trunk/ChangeLog.cross b/trunk/ChangeLog.cross deleted file mode 100644 index 52a3d40..0000000 --- a/trunk/ChangeLog.cross +++ /dev/null @@ -1,753 +0,0 @@ -2015-10-21 Mark Hatle <mark.hatle@windriver.com> - * Resync src/rtld to glibc-2.22 - * src/elf.h, src/rtld/*: - Update elf.h to glibc 2.22 version - * get.c, prelink.h: Add symname to conflict structure - * conflict.c: Provide more debuggign on a conflict (symname) - -2015-09-11 Mark Hatle <mark.hatle@windriver.com> - * doc/prelink.8: Add --ld-preload docs - * testsuite/Maekfile.am, testsuite/preload1*: Add test - -2015-09-11 Vaneet Narang <v.narang@samsung.com> - * src/gather.c, src/get.c, src/main.c, src/prelink.h: - Add ability to specify preloaded libraries that influence the - prelinker. - -2015-09-09 Akhilesh Kumar <akhilesh.k@samsung.com> - * src/gather.c: Remove unnecessary dso NULL check - -2015-09-09 Maninder Singh <maninder1.s@samsung.com> - * src/doit.c, src/gather.c, src/undoall.c: Fix realloc memory leak - -2015-09-07 Andrew Stubbs <ams@codesourcery.com> - * src/arch-arm.c (PL_ARCH(arm)): Set max_page_size to match - the new BFD default. - -2015-04-06 Mark Hatle <mark.hatle@windriver.com> - Maninder Singh <maninder1.s@samsung.com> - * src/rtld/dl-version.c: Add debug for mising ld-linux or libc - * src/gather.c: Return rtld error messages on failure - -2015-03-31 Mark Hatle <mark.hatle@windriver.com> - * Based on submission by Maninder Singh <maninder1.s@samsung.com> - src/get.c: Remove extra check for ld-linux.so.3 in strcmp - (remove first entry, second is already in upstream code) - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * testsuite/Makefile.am: latest autotools has changed the - way TEST_ENVIRONMENT is defined. Remove the $(SHELL) - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * Resync src/rtld to glibc-2.20 - * src/elf.h, src/rtld/rtld.c, src/rtld/dl-tls.c: - Update elf.h to glibc 2.20 version - Add basic aarch64 support - (do_relocs): fix comparison pltrel_end >= rel_end - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * src/rtld/COPYING, src/rtld/COPYING.LIB, - src/rtld/ChangeLog, src/rtld/README-rtld: Add local history - information to setup for a resync to glibc-2.20 - -2014-12-09 Jon Masters <jcm@jonmasters.org> - Mark Hatle <mark.hatle@windriver.com> - * src/arch-arm.c: Remove support for OABI arm ld-linux.so.2 - Add support for hard float ld-linux-armhf.so.3 - * src/rtld/rtld.c: Add ld-linux-armhf.so.3 as a ldso name - -2014-08-13 Kyle McMartin <kmcmartin@redhat.com> - Jakub Jelinek <jakub@redhat.com> - Julian Brown <julian@codesourcery.com> - * testsuite/ifunc.h: Add ARM support. - * src/prelink.h (R_ARM_IRELATIVE): Define. - * src/arch-arm.c (arm_adjust_rel, arm_adjust_rela) - (arm_prelink_rel, arm_prelink_rela, arm_apply_conflict_rela) - (arm_rela_to_rel, arm_rel_to_rela, arm_undo_prelink_rel): - Handle R_ARM_IRELATIVE. - (arm_prelink_conflict_rel, arm_prelink_conflict_rela): Handle - R_ARM_IRELATIVE, ifunc conflicts. - -2014-07-22 Maciej W. Rozycki <macro@codesourcery.com> - * src/arch-arm.c (arm_prelink_conflict_rel): Always create a - conflict for R_ARM_TLS_DESC relocs. - (arm_prelink_conflict_rela): Likewise. - -2013-10-15 Mark Hatle <mark.hatle@windriver.com> - * Merged to upstream r209 - -2013-08-01 Mark Hatle <mark.hatle@windriver.com> - * testsuite/unprel1.sh: Enable RUN_HOST for new test. - -2013-04-23 Mark Hatle <mark.hatle@windriver.com> - * README.cross: Add patch submission information based on a - suggestion from Tom de Vries. - -2013-04-19 Tom de Vries <tom@codesourcery.com> - * README.cross: Fix typo. - -2013-04-19 Tom de Vries <tom@codesourcery.com> - * src/arch-mips.c (PL_ARCH(mips64)): Set rtype_class_valid field to - RTYPE_CLASS_VALID. - -2013-01-03 Marko Lindqvist <cazfi74@gmail.com> - * configure.in -> configure.ac: Rename - * Replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS - -2012-09-12 Joseph Myers <joseph@codesourcery.com> - * src/rtld/dl-lookup.c: Fix variable copy reloc when host/target - byte size is different - -2012-09-08 Joseph Myers <joseph@codesourcery.com> - * src/arch-arm.c: Fix ARM_TLS_DTPOFF32 addends - * src/dwarf2.c: Fix address range handling related to DW_AT_high_pc - * src/dwarf2.c: Fix address range handling when dup data addr - -2012-06-14 Joseph Myers <joseph@codesourcery.com> - * src/exec.c: Fix issue for Power related to empty PROGBITS - change - -2012-05-30 Mark Hatle <mark.hatle@windriver.com> - * configure.in: Change the default bug report address to me - * testsuite/ifunc*.sh: Update a test to only run when !CROSS - -2012-05-22 Joseph Myers <joseph@codesourcery.com> - * src/prelink.h: Add missing wrap_glob declaration - -2012-05-28 Joseph Myers <joseph@codesourcery.com> - * m4/libelf.m4: Add unistd.h - -2012-05-29 Mark Hatle <mark.hatle@windriver.com> - * testsuite/tls*.sh: Update TLS __thread check - * README.cross: change instructions to use autoreconf -if - -2012-05-29 Mark Hatle <mark.hatle@windriver.com> - Integrate testsuite patches: - - 2012-05-25 Joseph Myers <joseph@codesourcery.com> - - * testsuite: Introduce $READELF - * testsuite: Introduce $RUN - * testsuite: Introduce $RUN_HOST - * testsuite/quick2.sh: Enable PIE test for ARM - * testsuite: Use $CCLINK instead of $CC for tls tests - -2012-04-10 Maxim Kuvyrkov <maxim@codesourcery.com> - * src/rtld/rtld.c (find_lib_by_soname): Follow ld.so's behavior of - pulling its name from PT_INTERP. - -2012-05-29 Mark Hatle <mark.hatle@windriver.com> - * arch-x86_64.c: Fix R_X86_64_64 relocation - -2012-05-25 Mark Hatle <mark.hatle@windriver.com> - * Fix testsuite execution - -2012-04-04 Mark Hatle <mark.hatle@windriver.com> - * testsuite/ifunc1.sh, ifunc2.sh, ifunc3.sh: Add cross compilation - checks to a few of the test cases. - * testsuite/reloc4.sh, reloc5.sh: Fix linking problems with a linker - that does not automatically including referenced libraries. - -2012-03-19 Maxim Kuvyrkov <maxim@codesourcery.com> - * src/reloc.c (find_reloc_sections): Don't error due to a gap between - sections. - -2011-12-21 Mark Hatle <mark.hatle@windriver.com> - * src/arch-x86_64.c: Add support for x32 ABI - -2012-02-02 Mark Hatle <mark.hatle@windriver.com> - Integrate dwarf2 signal frame patch: - - 2010-05-10 Paul Brook <paul@codesourcery.com> - - * src/dwarf2.c (adjust_dwarf2_frame): Skip 'S' augmentation. - -2012-02-01 Mark Hatle <mark.hatle@windriver.com> - * configure.in: Fix enabling and disabling of SE Linux support - -2012-01-26 Mark Hatle <mark.hatle@windriver.com> - * elf.h, rtld/dl-lookupX.h, rtld/rtld.c: Sync to eglibc 2.15 - - Integrate R_ARM_TLS_DESC relocation support patch: - - 2011-04-13 Maciej W. Rozycki <macro@codesourcery.com> - - * src/prelink.h (DT_TLSDESC_PLT, R_ARM_TLS_DESC): New macros. - (DSO): Add info_DT_TLSDESC_PLT member. - (DT_TLSDESC_PLT_BIT): New macro. - * src/arch-arm.c (arm_prelink_rel, arm_prelink_rela): Handle - R_ARM_TLS_DESC relocation. - (arm_prelink_conflict_rel, arm_prelink_conflict_rela): Likewise. - (arm_rel_to_rela): Likewise. - (arm_undo_prelink_rel): Likewise. - (arm_reloc_class): Likewise. - * src/dso.c (read_dynamic): Handle DT_TLSDESC_PLT dynamic tag. - - * src/prelink.h: add missing prototypes for wrap_listxattr, - wrap_getxattr, wrap_setxattr - -2012-01-04 Mark Hatle <mark.hatle@windriver.com> - * exec.c: Check that a section is larger then 0 bytes when - determining the section to segment mapping. This matches - the behavior of elfutils - readelf. Otherwise an empty - PROGBITS section at the end of a segment will cause a - failure. - -2011-12-08 Mark Hatle <mark.hatle@windriver.com> - * rtld/rtld.c: Fix an issue where missing objects would trigger - an assert in dl-version.c - * rtld/rtld.h: Add _dl_new_object prototype - * rtld/rtld.c: Add support for $ORIGIN, $PLATFORM and $LIB. - Note: $PLATFORM = "" - -2011-10-26 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r196 - * Resolve merge conflicts with src/main.c - * Disable automatic detection of AMD Bulldozer for layout page size - Unclear why the default size is 32768 on AMD Bulldozer, assume - this is a performance issue. I suggest if you are targeting - that platform, you manually pass: - --layout-page-size=32768 - -2011-09-13 Mark Hatle <mark.hatle@windriver.com> - * Fix printf problem causing prelink-rtld issues on x86 (32-bit) - and arm - -2011-08-30 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r195 - * Update testsuite to work with explicit intermedite objects - -2011-08-26 Mark Hatle <mark.hatle@windriver.com> - * Rename ld-libs.c to rtld.c - * Sync to eglibc 2.13 ld.so code - * mips specific items from ports - * sync elf_machine_type_class macros for supports archs - * Add a special check for invalid GNU_HASH entries - -2011-08-18 Mark Hatle <mark.hatle@windriver.com> - * Resync src/elf.h to glibc 2.13 - * Move prelink-rtld specific components to src/rtld - -2011-06-24 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r190 - -2011-05-16 Akos PASZTORY <akos.pasztory@gmail.com> - - * wrap-file.c (wrap_setxattr, wrap_getxattr, wrap_listxattr): New. - (wrap_glob): Likewise new. - * dso.c (copy_xattrs): use wrap_*xattr - * gather.c (read_config, gather_config, blacklist_from_config): - use wrap_glob - -2011-05-16 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r189 (no conflicts) - -2011-04-04 Mark Hatle <mark.hatle@windriver.com> - Integrate patch from: - - 2011-03-24 Joseph Myers <joseph@codesourcery.com> - - * src/dso.c (allow_bad_textrel, dso_has_bad_textrel): New. - (check_dso): Check for text relocations. - * src/gather.c (gather_exec): Check for text relocations. - * src/main.c (options): Add --allow-textrel. - (parse_opt): Handle --allow-textrel. - * src/prelink.h (dso_has_bad_textrel, allow_bad_textrel): Declare. - -2011-04-01 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r188 (no conflicts) - -2011-01-12 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r187 - * Resolve merge conflict - -2010-07-23 Mark Hatle <mark.hatle@windriver.com> - * src/ld-libs.c: Handle MIPS64 TLS PLT relocs - -2010-07-22 Mark Hatle <mark.hatle@windriver.com> - * src/dso.c: Add DSO_READONLY conditionals - * src/dso-readonly.c: remove - * src/Makefile.am: switch RTLD dep to dso.c, pass DSO_READONLY - * configure.in: Add AM_PROG_CC_C_O - -2010-07-22 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r185 - * Resync dso-readonly.c from dso.c - -2010-06-18 Mark Hatle <mark.hatle@windriver.com> - - * Sync src/dso-readonly.c and ... - * Integrate patch from - - 2010-05-06 Andrew Stubbs <ams@codesourcery.com> - - * src/dso.c (adjust_dso): Support MIPS debug sections. - * src/prelink.h (SHT_MIPS_DWARF): New define. - -2009-06-15 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r184 - * Resync dso-readonly.c from dso.c - * Cleanup ChangeLog.cross - -2009-06-15 Mark Hatle <mark.hatle@windriver.com> - - * Integrate prelinker/cross-prelinking patches - - 2009-09-01 Maciej W. Rozycki <macro@codesourcery.com> - - Issue #5273 - * src/arch-mips.c (mips_prelink_reloc): Resolve - R_MIPS_TLS_DTPMOD32 and R_MIPS_TLS_DTPMOD64 relocations in - executables. - - 2009-04-27 Maciej W. Rozycki <macro@codesourcery.com> - - Issue #5165 - * src/ld-libs.c (load_ld_so_conf): Fix a buffer overrun. Don't - record empty paths. - - 2009-04-23 Maciej W. Rozycki <macro@codesourcery.com> - - Issue #5165 - * src/ld-lookup.c (rtld_elf_hash): Handle an initial NULL - character correctly. Reformat for consistency with - rtld_elf_gnu_hash() - - 2009-04-23 Maciej W. Rozycki <macro@codesourcery.com> - - Issue #5165 - * src/ld-do-lookup.h (FCT): Remove the hash argument and - calculate the value within the function. Call - do_lookup_get_first() and do_lookup_get_next() to iterate over - symbols. - * src/prelink.h (dynamic_info_is_set): Convert macro to a - function. Return 1 for success rather than the bit set. - * src/ld-libs.h (ldlibs_link_map): Add l_gnu_hash, l_maskword64, - l_nmaskwords, l_shift and l_maskwords members. - * src/ld-libs.c (create_ldlibs_link_map): Handle the GNU hash. - * src/ld-lookup.c (rtld_elf_gnu_hash): New function. - (rtld_elf_any_hash): Likewise. - (rtld_elf_hash): Move above "ld-do-lookup.h" inclusions. - (do_lookup_get_first, do_lookup_get_next): New functions. - (rtld_lookup_symbol): Remove hash calculation. - (rtld_lookup_symbol_versioned): Likewise. - - 2009-04-23 Maciej W. Rozycki <macro@codesourcery.com> - - Issue #5165 - * src/execle_open.c (execve_open): Add missing pid - initialisation. - -2010-06-15 Mark Hatle <mark.hatle@windriver.com> - * Merge to upstream r174 - * src/arch-mips.c, src/conflict.c, src/cxx.c, src/main.c, src/verify.c: - fix items missed in the merge - * Resync dso-readonly.c from dso.c - -2010-06-14 Mark Hatle <mark.hatle@windriver.com> - - * Integrate prelinker/cross-prelinking patches - - 2009-08-06 Joseph Myers <joseph@codesourcery.com> - - * src/dwarf2.c (dwarf2_write_le64, dwarf2_write_be64): Shift by 56 - not 58 for MSB. - - 2009-03-19 Joseph Myers <joseph@codesourcery.com> - - Issue #4626 - * src/cache.c, src/dso-readonly.c, src/dso.c, src/execstack.c, - src/gather.c, src/layout.c, src/mapfile.c, src/verify.c: fsync - file descriptors before closing them. - - 2008-09-23 Joseph Myers <joseph@codesourcery.com> - - * src/arch-arm.c (arm_prelink_conflict_rela): Correct - R_ARM_TLS_TPOFF32 handling. - - 2008-09-18 Joseph Myers <joseph@codesourcery.com> - - * src/ld-libs.c (reloc_type_class, determine_tlsoffsets): Handle - SPARC. - * src/arch-sparc64.c (sparc64_prelink_rela, - sparc64_prelink_conflict_rela, sparc64_undo_prelink_rela, - sparc64_reloc_class): Handle TLS relocations. - (PL_ARCH(sparc64)): Update mmap_base and mmap_end for - TASK_UNMAPPED_BASE change to 0xfffff80100000000. - - 2008-10-02 Maciej W. Rozycki <macro@codesourcery.com> - - * src/arch-mips.c (mips_prelink_reloc): Do not complain about - TLS_DTPMOD32 or TLS_DTPMOD64 relocations found in executables. - - 2008-09-03 Maciej W. Rozycki <macro@codesourcery.com> - - * src/prelink.h (Elf64_Byte): New definition. - (R_MIPS_TLS_DTPMOD64): New macro. - (R_MIPS_TLS_DTPREL64): Likewise. - (R_MIPS_TLS_TPREL64): Likewise. - (RSS_UNDEF): Likewise. - (PL_ARCH): Use plarch_##F as the name of the struct in all - variants. - * src/reloc-info.c: New file. - * src/reloc-info.h: Likewise. - * src/arch-mips.c (mips_buf_read_addr): New function. - (mips_buf_write_addr): Likewise. - (mips_arch_adjust): Replace calls to buf_read_une32() and - buf_write_ne32() with ones to mips_buf_read_addr() and - mips_buf_write_addr() respectively. - (mips_read_addend): Rename to... - (mips_read_32bit_addend): ... this. - (mips_write_addend): Rename to... - (mips_write_32bit_addend): ... this. - (mips_read_64bit_addend): New function. - (mips_write_64bit_addend): Likewise. - (mips_adjust_reloc): Handle 64-bit REL relocations. Use - reloc_r_sym() and reloc_r_type() in place of GELF_R_SYM() and - GELF_R_TYPE() respectively. - (mips_prelink_64bit_reloc): New function. - (mips_prelink_reloc): Handle 64-bit REL and GLOB_DAT relocations. - Handle TLS_DTPMOD64, TLS_DTPREL64 and TLS_TPREL64 relocations. - Use reloc_r_sym() and reloc_r_type(). - (mips_prelink_rel): Handle 64-bit REL relocations. Use - reloc_r_sym(), reloc_r_type() and reloc_r_info_ext() (replacing - GELF_R_INFO()). - (mips_prelink_conflict_reloc): Handle 64-bit REL relocations. - Handle TLS_DTPMOD64, TLS_DTPREL64 and TLS_TPREL64 relocations. - Use reloc_r_sym(), reloc_r_type() and reloc_r_info_ext(). - (mips_arch_prelink_conflict): Use mips_buf_read_addr(). Use - reloc_r_info_ext(). - (mips_apply_conflict_rela): Handle 64-bit REL relocations. Use - reloc_r_type(). Use mips_buf_read_addr() and - mips_buf_write_addr(). - (mips_apply_reloc): Handle 64-bit REL relocations. Use - reloc_r_sym() and reloc_r_type(). - (mips_rel_to_rela): Handle 64-bit REL relocations. Handle - TLS_DTPMOD64, TLS_DTPREL64 and TLS_TPREL64 relocations. Use - reloc_r_sym() and reloc_r_type(). - (mips_rela_to_rel): Handle 64-bit REL and GLOB_DAT relocations. - Handle TLS_DTPMOD64, TLS_DTPREL64 and TLS_TPREL64 relocations. - Use reloc_r_sym() and reloc_r_type(). - (mips_need_rel_to_rela): Use data obtained with gelfx_getshdr() to - determine the size of a relocation entry. Use gelfx_getrel() to - retrieve them. Handle 64-bit REL relocations. Handle - TLS_DTPMOD64, TLS_DTPREL64 and TLS_TPREL64 relocations. Use - reloc_r_sym() and reloc_r_type() instead of ELF32_R_SYM() and - ELF32_R_TYPE() respectively. - (mips_reloc_class): Handle TLS_DTPMOD64, TLS_DTPREL64 and - TLS_TPREL64 relocations. - (mips_arch_prelink): Use mips_buf_read_addr() and - mips_buf_write_addr(). - (mips_arch_undo_prelink): Likewise. - (mips_undo_prelink_rel): Handle 64-bit GLOB_DAT relocations. Use - reloc_r_sym(), reloc_r_type() and reloc_r_info_ext(). - (mips64): New PL_ARCH. - * src/prelink.c (prelink_prepare): Handle SHT_MIPS_OPTIONS. - * src/conflict.c (conflict_rela_cmp_dso): New variable. - (conflict_rela_cmp): Use conflict_rela_cmp_dso and reloc_r_sym(). - (get_relocated_mem): Use reloc_r_type(). - (prelink_add_copy_rel): Use reloc_r_sym() and reloc_r_type(). - (prelink_build_conflicts): Use reloc_r_sym(), reloc_r_type() and - reloc_r_info(). Pass dso to conflict_rela_cmp() through - conflict_rela_cmp_dso. - (prelink_find_copy_rela): Use reloc_r_type(). - * src/cxx.c (remove_redundant_cxx_conflicts): Use reloc_r_sym(), - reloc_r_type() and reloc_r_info(). - * src/ld-libs.c (do_rel_section): Use reloc_r_sym() and - reloc_r_type(). - * src/Makefile.am (common_SOURCES): Add reloc-info.c and - reloc-info.h. - (prelink_rtld_SOURCES): Likewise. - * src/Makefile.in: Regenerate. - * configure.in: Check for the Elf64_Byte type. Require autoconf - 2.50. - * configure: Regenerate. - - 2008-09-03 Maciej W. Rozycki <macro@codesourcery.com> - - * src/arch-mips.c (mips_undo_prelink_rel): Fix formatting. - - 2008-09-03 Maciej W. Rozycki <macro@codesourcery.com> - - * src/arch-mips.c (mips_init_local_got_iterator): Use ELF_T_ADDR - to determine the width of GOT entries. - (mips_init_global_got_iterator): Likewise. - - 2008-09-03 Maciej W. Rozycki <macro@codesourcery.com> - - * src/data.c (buf_read_une##nn): Fix the width of the data - transfer used. - - 2008-03-06 Daniel Jacobowitz <dan@codesourcery.com> - - * src/ld-do-lookup.h: Check for STO_MIPS_PLT on MIPS. - * src/ld-libs.c (reloc_type_class): Handle copy and PLT relocs. - * src/prelink.h (R_MIPS_TLS_DTPMOD32, R_MIPS_TLS_DTPREL32) - (R_MIPS_TLS_TPREL32, R_MIPS_GLOB_DAT): Remove duplicate definitions. - (R_MIPS_COPY, R_MIPS_JUMP_SLOT, STO_MIPS_PLT, DT_MIPS_PLTGOT) - (DT_MIPS_PLTNO, DT_MIPS_RWPLT): Define. - (DSO): Add info_DT_MIPS_PLTGOT. - * src/arch-mips.c (mips_prelink_reloc): Handle R_MIPS_JUMP_SLOT and - R_MIPS_COPY. - (mips_prelink_conflict_reloc): Handle R_MIPS_COPY. - (mips_apply_conflict_rela): Handle R_MIPS_JUMP_SLOT. - (mips_apply_reloc): Handle R_MIPS_JUMP_SLOT and R_MIPS_COPY. - (mips_rel_to_rela, mips_rela_to_rel): Handle R_MIPS_COPY. - (mips_need_rel_to_rela): Handle R_MIPS_COPY and R_MIPS_JUMP_SLOT. - Correct error message. - (mips_reloc_class): Handle R_MIPS_COPY and R_MIPS_JUMP_SLOT. Use - RTYPE_CLASS_VALID by default. - (mips_arch_prelink): Save .plt in gotplt[1]. - (mips_arch_undo_prelink): Clear gotplt[1]. - (mips_undo_prelink_rel): Undo R_MIPS_JUMP_SLOT relocations. - (PL_ARCH): Set R_COPY and R_JMP_SLOT. - * src/dso.c (read_dynamic): Save DT_MIPS_PLTGOT. - * src/dso-readonly.c (read_dynamic): ditto - - 2007-07-09 Daniel Jacobowitz <dan@codesourcery.com> - - Issue #1816 - * src/wrap-file.c (chroot_canon): Delete. - (sysroot_file_name): Use canon_filename. - (unsysroot_file_name): Make global. - (wrap_canonicalize_file_name): Delete. - * src/ld-libs.c (load_dsos): Use prelink_canonicalize. - * src/canonicalize.c (canon_filename): Make global. Add chroot, - allow_last_link, allow_missing arguments. Handle links inside - a chroot. Handle canonicalizing the current directory. Remove - debugging output. - (prelink_canonicalize): Update. Use unsysroot_file_name. - * src/prelink.h (wrap_canonicalize_file_name): Delete prototype. - - 2007-03-02 Sandra Loosemore <sandra@codesourcery.com> - - * doc/prelink.8: Copy edit. Add entry for --root option. Update - list of unsupported systems. - - 2007-02-16 Daniel Jacobowitz <dan@codesourcery.com> - - * src/prelink.h (sysroot_file_name): Declare. - * src/ld-libs.c (load_dsos): Take host_paths argument. Do not attempt - to canonicalize host filenames within the sysroot. Always set - canon_filename. - (process_one_dso): Update call to load_dsos. Do not redo call to - wrap_canonicalize_file_name. - - 2006-11-30 Mark Shinwell <shinwell@codesourcery.com> - - * configure.in: Recognize --with-pkgversion and ---with-bugurl. - * src/Makefile.am: Pass package version and bug URL through - AM_CFLAGS, together with the new EXECSTACK_PROG. - * src/main.c: Use PKGVERSION and REPORT_BUGS_TO. - * src/execstack.c: Likewise. Also use EXECSTACK_PROG. - - Mark Hatle <mark.hatle@windriver.com> - * src/ld-libs.c: Use PRELINK_RTLD_PROG, PKGVERSION and REPORT_BUGS_TO - * src/execstack.c: Use EXECSTACK_PROG in (argp_doc) - - 2006-11-30 Mark Shinwell <shinwell@codesourcery.com> - - * wrap-file.c (wrap_stat_body): New. - (wrap_lstat64, wrap_stat64): Use wrap_stat_body. - - 2006-11-28 Mark Shinwell <shinwell@codesourcery.com> - - * src/layout.c (layout_libs): Add assertion to check for buffer - overflow. - * src/ld-libs.c (find_lib_in_path): Add "machine" argument. - Skip libraries whose ELF machine type field does not match - that argument. - (find_lib_by_soname): Add "machine" argument. Pass it to - find_lib_in_path. - (load_dsos): Determine machine type of input DSO. Pass it - to find_lib_by_soname. - - 2006-11-28 Mark Shinwell <shinwell@codesourcery.com> - - * src/gather.c (maybe_pie): New. - (gather_func): Use it. - - 2006-11-28 Mark Shinwell <shinwell@codesourcery.com> - - * src/canonicalize.c: Add prelink.h include directive. - Use wrap_readlink and wrap_lstat64. - * src/prelink.h: Declare wrap_readlink. - * src/wrap-file.c (wrap_readlink): New. - - 2006-10-13 Daniel Jacobowitz <dan@codesourcery.com> - - * src/execle_open.c (execve_open): Add an error message if execve - fails. - - 2006-10-03 Richard Sandiford <richard@codesourcery.com> - - * configure.in (AC_CANONICAL_HOST): Remove in favour of... - (AC_CANONICAL_SYSTEM): ...this new directive. - (AC_ARG_PROGRAM): New directive. - * src/Makefile.am (AM_CFLAGS): Define PRELINK_PROG, PRELINK_RTLD_PROG - and EXEEXT. - (execstack_LDADD): Add -liberty. - * src/execstack.c (program_path, prelink_path): New variables. - (execstack_make_rdwr): Initialize prelink_path if it has not - been set yet. Use make_relative_prefix, PRELINK_PROG and EXEEXT - to get the full pathname of the prelink executable. Pass this path - to execl() as the name of executable file. - (main): Initialize program_path. - * src/main.c (argp_program_version, argp_doc): Use PRELINK_PROG as - the program name. - (main): Handle empty --rtld= arguments first. Always use - make_relative_prefix to work out the path of the defalt rtld - executable. Also use PRELINK_RTLD and EXEEXT for this purpose. - -2010-06-14 Mark Hatle <mark.hatle@windriver.com> - * configure.in: Add option to disable selinux - * src/Makefile.am: Stop static linking - -2007-08-08 Mark Hatle <mark.hatle@windriver.com> - - * src/arch-mips.c: add /lib32/ld.so.1 as an alternative 32-bit linker - * src/ld-libs.c: add a check for MIPS n32, and adjust ld_dirs as - necessary - -2007-10-11 Richard Sandiford <richard@codesourcery.com> - - * src/space.c (find_readonly_space): If a new PT_LOAD header is needed, - first try removing a PT_NULL header. - -2006-12-04 Mark Hatle <mark.hatle@windriver.com> - - * Merge code from: - - Richard Sandiford <richard@codesourcery.com> - * src/ld-libs.c (reloc_type_class): Handle EM_MIPS. - (do_mips_global_relocs): New function. - (handle_relocs_in_entry): Call it. - (determine_tlsoffsets): Handle EM_MIPS. - - Richard Sandiford <richard@codesourcery.com> - - * src/ld-libs.c (do_reloc): New function, split out from - do_rel_section. Take the symbol and relocation type as arguments. - (do_rel_section): Call it. - (handle_relocs_in_entry): New function. - (handle_relocs): Call it. - -2006-12-04 Mark Hatle <mark.hatle@windriver.com> - - * src/elf.h: Update to the latest version of elf.h for MIPS prelink - -2006-12-01 Mark Hatle <mark.hatle@windriver.com> - - * merge to 20061201 (r151) - * src/arch-arm.c: remove read_une32, write_ne32, buf_write_ne32, - buf_read_une32 - * src/dso-readonly.c: sync to changes in src/dso.c - -2006-08-18 Mark Hatle <mark.hatle@windriver.com> - - * arch-arm.c: remove prelink_conflict_rela - * arch-arm.c: Add big-endian arm support, based on arch-sh.c - -2006-08-17 Mark Hatle <mark.hatle@windriver.com> - - * data.c, dso.c, prelink.h: when using elfutils/libelf, we need - to byte swap only if the type is ELF_T_BYTE. - * dso-readonly.c: add get_data prototype change for byteswapping - * ld-libs.c: add get_data prototype change for byteswapping - -2006-08-10 Mark Hatle <mark.hatle@windriver.com> - - * testsuite/Makefile.in: Allow testsuite to run using cross prelink. - Disable the run-time tests, but keep all basic - prelink testing. - * testsuite/ccx1.sh, testsuite/cycle1.sh, testsuite/cycle2.sh - testsuite/deps1.sh, testsuite/deps2.sh, testuite/functions.sh - testuite/layout1.sh, testuite/layout2.sh, testsuite/movelibs.sh - testsuite/quick1.sh, testsuite/quick2.sh, testsuite/quick3.sh - testsuite/reloc1.sh, testsuite/reloc2.sh, testsuite/reloc3.sh - testsuite/reloc4.sh, testsuite/reloc5.sh, testsuite/reloc6.sh - testsuite/reloc7.sh, testsuite/reloc8.sh, testsuite/reloc9.sh - testsuite/reloc10.sh, testsuite/reloc11.sh, testsuite/shuffle1.sh - testsuite/shuffle2.c, testsuite/shuffle2.sh, testsuite/shuffle3.sh - testsuite/shuffle4.sh, testsuite/shuffle5.sh, testsuite/shuffle6.sh - testsuite/shuffle7.sh, testsuite/shuffle8.sh, testsuite/tls1.sh - testsuite/tls2.sh, testsuite/tls3.sh, testsuite/tls4.sh - testsuite/tls5.sh, testsuite/tls6.sh, testsuite/tls7.sh - testsuite/undo1.sh: ditto - -2006-08-09 Mark Hatle <mark.hatle@windriver.com> - - * execstack.c: add WR versioning - * ld-libs.c: add argp option processing and WR versioning - * main.c: add WR versioning - -2006-08-09 Mark Hatle <mark.hatle@windriver.com> - - * ld-libs.c: Add --root argument to prelink-rtld - -2006-08-09 Mark Hatle <mark.hatle@windriver.com> - - * cross-prelink code merged and upreved - original code from: - MontaVista Software, Inc. - CodeSourcery, LLC. - * Makefile.am: add prelink-rtld, libiberty - * dso-readonly.c: new file based on dso.c - * gather.c: use cross-rtld - * get.c: use cross-rtld - * ld-do-lookup.h: Add ld-do-lookup.h from glibc - * ld-libs.c: add cross-rtld functionality - * ld-libs.h: ditto - * ld-lookup.c: ditto - * ld-lookup64.c: ditto - * main.c: Add rtld option - * prelink.h: add extern rtld variable - -2006-08-09 CodeSourcery, LLC. - - * main.c: if we modified /sbin/init, re-run init - -2006-08-08 CodeSourcery, LLC. - - * arch-arm.c: add ARM EABI support, dynamic_linker_alt - * src/dso.c: STT_ARM_TFUNC support - * src/get.c: ld-linux.so.3 to the list of ldso names - -2006-08-08 CodeSourcery, LLC. - - * gather.c: add new dynamic_linker_alt - * prelink.h: ditto - -2006-08-08 MontaVista Software, Inc. - - * main.c: Add relative sysroot support - -2006-08-08 Montavista Software, Inc. - - * Makefile.am: Add function wrapper support for sysroots - * main.c: add --root option - * cache.c, doit.c, dso.c, execstack.c, gather.c, get.c, - prelink.h, undoall.c, verify.c: Add functional wrappers for sysroot - * wrap-file.c: add function wrapper definitions - -2006-07-28 Alexandre Oliva <aoliva@redhat.com> - - * src/cache.c: Avoid SEGFAULT when sorting cache entries (#197451) - -2006-07-21 MontaVista Software, Inc. - - * prelink.c: add PRELINK_TIMESTAMP support - -2006-07-21 MontaVista Software, Inc. - - * dso.c: Don't adjust reloc for debug info - -2006-06-30 Mark Hatle <mark.hatle@windriver.com> - - * src/elf.h: Make available the elf.h file from glibc 2.3.6 - -2006-06-10 MontaVista Software, Inc. - - * arch-sh.c: Fix R_SH_RELATIVE endian swap problem, - change max page size - diff --git a/trunk/Makefile.am b/trunk/Makefile.am deleted file mode 100644 index 5a50830..0000000 --- a/trunk/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu -MAINT_CHARSET = latin1 - -ACLOCAL_AMFLAGS = -I m4 - -SUBDIRS = gelfx gelfx32 gelf src patches doc testsuite - -# Tell version 3.79 and up of GNU make to not build goals in this -# directory in parallel. -.NOTPARALLEL: diff --git a/trunk/NEWS b/trunk/NEWS deleted file mode 100644 index c36e768..0000000 --- a/trunk/NEWS +++ /dev/null @@ -1 +0,0 @@ -No news yet. diff --git a/trunk/README b/trunk/README deleted file mode 100644 index b6dc3ba..0000000 --- a/trunk/README +++ /dev/null @@ -1 +0,0 @@ -ELF prelinking utility to speed up dynamic linking. diff --git a/trunk/README.cross b/trunk/README.cross deleted file mode 100644 index 5a4107f..0000000 --- a/trunk/README.cross +++ /dev/null @@ -1,28 +0,0 @@ -This version of the prelinker has a number of patches that enable cross -prelinking. Specific patches to address CPUs common to embedded -systems, that have not yet been merged upstream, also exist in this version. - -Please contact <mark.hatle@windriver.com> if you have a question about this -version. The original author, and open source maintainer is not responsible -for the modified version! - -Compilation ------------ - -In order to build this, you will need to regenerate the autotools files: -autoreconf -if - -Patch submission ----------------- - -When submitting patches to the cross-prelink project, please do the -following: - -To: mark.hatle@windriver.com -Cc: yocto@yoctoproject.org - -Subject: [prelink-cross] .... - -If the patch affects the upstream prelinker project, you should also consider -sending it to the prelink@sourceware.org list as well. - diff --git a/trunk/THANKS b/trunk/THANKS deleted file mode 100644 index 9f42254..0000000 --- a/trunk/THANKS +++ /dev/null @@ -1 +0,0 @@ -We'll see. diff --git a/trunk/TODO b/trunk/TODO deleted file mode 100644 index 0a3d072..0000000 --- a/trunk/TODO +++ /dev/null @@ -1,7 +0,0 @@ -- sparse files -- security audit: - - should we only limit prelinking in non-world writeable directories -- more ports -- hack support for multi-ABI arches -- more testing -- some more C++ optimizations diff --git a/trunk/configure.ac b/trunk/configure.ac deleted file mode 100644 index 4943932..0000000 --- a/trunk/configure.ac +++ /dev/null @@ -1,136 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -*-m4-*- -AC_INIT(src/prelink.c) -AC_CONFIG_HEADERS(config.h) -AC_PREREQ(2.50) dnl Minimum Autoconf version required. -AC_CANONICAL_SYSTEM -AC_ARG_PROGRAM - -AM_INIT_AUTOMAKE([prelink], [0.0]) - -ALL_LINGUAS= - -AC_PROG_CC -AM_PROG_CC_C_O -AC_PROG_CXX -AC_PROG_CPP -AC_PROG_GCC_TRADITIONAL -AM_PROG_LIBTOOL - -AC_ARG_ENABLE(64-bit, -[ --disable-64-bit only support 32-bit ELF], -[case "${enableval}" in - yes) want64=true ;; - no) want64=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for 64-bit option) ;; -esac],[want64=true])dnl - -AC_CHECK_HEADER(libelf.h,,[ - if test -f /usr/include/elfutils/libelf.h; then - CPPFLAGS="$CPPFLAGS -I /usr/include/elfutils" - elif test -f /usr/local/include/elfutils/libelf.h; then - CPPFLAGS="$CPPFLAGS -I /usr/local/include/elfutils" - elif test -f /usr/include/libelf/libelf.h; then - CPPFLAGS="$CPPFLAGS -I /usr/include/libelf" - elif test -f /usr/local/include/libelf/libelf.h; then - CPPFLAGS="$CPPFLAGS -I /usr/local/include/libelf" - else - AC_MSG_ERROR(libelf.h not found) - fi]) -LIBGELF="" -if test "$want64"x = falsex; then - GELFINCLUDE='-I$(top_srcdir)/gelfx32' -else - GELFINCLUDE='-I$(top_srcdir)/gelfx' - AC_CHECK_HEADER(gelf.h,,[ - GELFINCLUDE="$GELFINCLUDE "'-I$(top_srcdir)/gelf' - LIBGELF='../gelf/libgelf.la' - ]) -fi -AC_CHECK_LIB(elf,elf_begin) -AC_SUBST(GELFINCLUDE) -AC_SUBST(LIBGELF) - -dnl Now check what kind of libelf we will link against -AC_CHECK_FUNC(gelf_getvernaux,[newbu=true],[newbu=false]) - -dnl Check if FTW_ACTIONRETVAL is supported -AC_CACHE_CHECK([whether FTW_ACTIONRETVAL is supported], - [ac_cv_ftw_actionretval], [dnl - AC_EGREP_CPP([FTW supports ACTIONRETVAL], [ - #ifndef _GNU_SOURCE - #define _GNU_SOURCE 1 - #endif - #include <ftw.h> - #ifdef FTW_ACTIONRETVAL - FTW supports ACTIONRETVAL - #endif - ], ac_cv_ftw_actionretval=yes, ac_cv_ftw_actionretval=no)]) -if test "x$ac_cv_ftw_actionretval" = xyes; then - AC_DEFINE(HAVE_FTW_ACTIONRETVAL, 1, - [Define if FTW_ACTIONRETVAL is supported.]) -fi - -dnl SELinux checks -AC_ARG_ENABLE(selinux, - AS_HELP_STRING([--disable-selinux], - [Disable selinux support in the prelinker]), - [ enable_selinux="$enableval" ], - [ enable_selinux="yes" ]) - -if test "x$enable_selinux" != "xyes"; then - ac_cv_lib_selinux_is_selinux_enabled=no - ac_cv_header_selinux_selinux_h=no -fi - -AC_CHECK_LIB(selinux,is_selinux_enabled) -AC_CHECK_HEADERS(selinux/selinux.h) - -dnl This test must come as early as possible after the compiler configuration -dnl tests, because the choice of the file model can (in principle) affect -dnl whether functions and headers are available, whether they work, etc. -if test x"$newbu" = xtrue; then - # Don't use LFS for libelf-0.x - AC_SYS_LARGEFILE -fi - -AC_LIBELF_SXWORD - -dnl Elf64_Byte is specific to the 64-bit MIPS psABI and may not be defined. -AC_CHECK_TYPES([Elf64_Byte], [], [], [#include <libelf.h>]) - -# Package version. -AC_ARG_WITH(pkgversion, - AS_HELP_STRING([--with-pkgversion=PKG], - [Add PKG to the version string]), - [case "$withval" in - yes) AC_MSG_ERROR([package version not specified]) ;; - no) PKGVERSION= ;; - *) PKGVERSION=" ($withval)" ;; - esac], - PKGVERSION= -) -AC_SUBST(PKGVERSION) - -# The location to which bugs should be reported. -AC_ARG_WITH(bugurl, - AS_HELP_STRING([--with-bugurl=URL], - [Direct users to URL to report a bug]), - [case "$withval" in - yes) AC_MSG_ERROR([bug URL not specified]) ;; - no) REPORT_BUGS_TO="" ;; - *) REPORT_BUGS_TO="<URL:$withval>" ;; - esac], - REPORT_BUGS_TO="<mark.hatle@windriver.com>" -) -AC_SUBST(REPORT_BUGS_TO) - -AC_OUTPUT([Makefile - src/Makefile - src/rtld/Makefile - gelfx/Makefile - gelfx32/Makefile - gelf/Makefile - m4/Makefile - patches/Makefile - doc/Makefile - testsuite/Makefile]) diff --git a/trunk/doc/Makefile.am b/trunk/doc/Makefile.am deleted file mode 100644 index 45f4757..0000000 --- a/trunk/doc/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -man_MANS = prelink.8 execstack.8 -EXTRA_DIST = prelink.8 execstack.8 prelink.conf -PDFLATEXINPUTS = TEXINPUTS_pdflatex=.:$(srcdir):`kpsewhich --progname=pdflatex --show-path=cnf.pdflatex` -LATEXINPUTS = TEXINPUTS_latex=.:$(srcdir):`kpsewhich --progname=latex --show-path=cnf.latex` - -noinst_DATA = prelink.pdf -pics = gap bss basemove newseg dso1 dso2 dso3 - -prelink.pdf: prelink.tex $(pics:=.fig) linuxtag.sty \ - prelinklisting.sty lineno.sty glossary.conf - $(MAKE) $(pics:=.pdf) - $(PDFLATEXINPUTS) pdflatex $< - makeindex -s $(srcdir)/glossary.conf -o prelink.gls prelink.glo - if grep -q Rerun prelink.log; then $(PDFLATEXINPUTS) pdflatex $<; fi - thumbpdf $@ && $(PDFLATEXINPUTS) pdflatex $< - mv $@ prelinkin.pdf - pdfopt prelinkin.pdf $@ - rm prelinkin.pdf - -prelink.ps: prelink.dvi - dvips $< -o $@ - -prelink.dvi: prelink.tex $(pics:=.eps) - $(LATEXINPUTS) latex $< - if grep -q Rerun prelink.log; then $(LATEXINPUTS) latex $<; fi - -SUFFIXES = .fig .eps .pdf - -.fig.eps: - fig2dev -L eps $^ $@ - -.fig.pdf: - fig2dev -L pdf $^ $@ - -CLEANFILES = $(pics:=.eps) $(pics:=.pdf) prelink.aux prelink.dvi \ - prelink.log prelink.mtc prelink.mtc1 prelink.pdf prelink.ps \ - prelink.glo prelink.idx prelink.out prelink.tpt prelink.ilg \ - prelink.gls prelink.toc diff --git a/trunk/doc/basemove.fig b/trunk/doc/basemove.fig deleted file mode 100644 index 6fb1c02..0000000 --- a/trunk/doc/basemove.fig +++ /dev/null @@ -1,97 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 5925 2775 10275 3525 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 2850 7200 2850 7200 3450 6000 3450 6000 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 10200 2850 8025 2850 8025 3450 10200 3450 10200 2850 -4 0 0 50 0 0 12 0.0000 4 180 1125 6000 3225 .hash, .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 8100 3225 .gnu.version ... .eh_frame\001 --6 -6 5925 1125 10275 1875 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 1200 7200 1200 7200 1800 6000 1800 6000 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 10200 1200 8025 1200 8025 1800 10200 1800 10200 1200 -4 0 0 50 0 0 12 0.0000 4 180 1125 6000 1575 .hash, .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 8100 1575 .gnu.version ... .eh_frame\001 --6 -6 525 2775 2400 3525 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2325 2850 2325 3450 600 3450 600 2850 -4 0 0 50 0 0 12 0.0000 4 180 1605 675 3225 .interp, .note.ABI-tag\001 --6 -6 4200 1125 6075 1875 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4275 1200 6000 1200 6000 1800 4275 1800 4275 1200 -4 0 0 50 0 0 12 0.0000 4 180 1605 4350 1575 .interp, .note.ABI-tag\001 --6 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 2325 2850 3300 2850 3300 3450 2325 3450 2325 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4125 2850 3300 2850 3300 3450 4125 3450 4125 2850 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 4125 2850 5100 2850 5100 3450 4125 3450 4125 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 10200 2700 10200 3600 450 3600 450 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 10800 2850 11925 2850 11925 3450 10800 3450 10800 2850 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 11925 2700 11925 3600 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 11925 2850 12525 2850 12525 3450 11925 3450 11925 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 10800 1200 11925 1200 11925 1800 10800 1800 10800 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 10800 975 12525 975 12525 1950 10800 1950 10800 975 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 11925 975 11925 1950 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 11925 1200 12525 1200 12525 1800 11925 1800 11925 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 10800 2700 12525 2700 12525 3600 10800 3600 10800 2700 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 7200 1200 8025 1200 8025 1800 7200 1800 7200 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 10200 2700 10200 3600 450 3600 450 2700 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 4125 975 10200 975 10200 1950 4125 1950 4125 975 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 5025 1950 1350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 6600 1950 6600 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 9000 1950 9000 2025 9000 2100 9000 2175 9000 2250 9000 2325 - 9000 2400 9000 2475 9000 2550 9000 2625 9000 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 12 - 0 0 1.00 60.00 120.00 - 11400 1950 11400 2025 11400 2100 11400 2175 11400 2250 11400 2325 - 11400 2400 11400 2475 11400 2550 11400 2625 11400 2700 11400 2625 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 12225 1950 12225 2025 12225 2100 12225 2175 12225 2250 12225 2325 - 12225 2400 12225 2475 12225 2550 12225 2625 12225 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 8025 1950 3300 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 7200 1950 2325 2700 -4 0 0 50 0 0 12 0.0000 4 180 780 3300 3225 .gnu.liblist\001 -4 0 0 50 0 0 12 0.0000 4 180 930 4125 3225 .gnu.conflict\001 -4 0 0 50 0 0 12 0.0000 4 180 885 10950 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 12000 3225 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 885 10950 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 12000 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 525 7275 1575 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 525 2475 3225 .dynstr\001 diff --git a/trunk/doc/bss.fig b/trunk/doc/bss.fig deleted file mode 100644 index 2c9325f..0000000 --- a/trunk/doc/bss.fig +++ /dev/null @@ -1,74 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2175 1200 2175 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3225 1200 2175 1200 2175 1800 3225 1800 3225 1200 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1425 1950 1425 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2175 2850 2175 3450 600 3450 600 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3000 2850 2175 2850 2175 3450 3000 3450 3000 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 5400 2700 5400 3600 450 3600 450 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5400 2850 3225 2850 3225 3450 5400 3450 5400 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 5400 975 5400 1950 450 1950 450 975 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5400 1200 3225 1200 3225 1800 5400 1800 5400 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6000 1200 7125 1200 7125 1800 6000 1800 6000 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6000 2850 7125 2850 7125 3450 6000 3450 6000 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 975 7725 975 7725 1950 6000 1950 6000 975 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 6525 1950 6525 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 7350 1950 7350 2700 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7125 975 7125 1950 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 8925 2850 7725 2850 7725 3450 8925 3450 8925 2850 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 8925 2850 10050 2850 10050 3450 8925 3450 8925 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 2700 10050 2700 10050 3600 6000 3600 6000 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2175 1950 7725 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3225 1950 8925 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 3975 1950 3975 2025 3975 2100 3975 2175 3975 2250 3975 2325 - 3975 2400 3975 2475 3975 2550 3975 2625 3975 2700 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 7125 2850 7725 2850 7725 3450 7125 3450 7125 2850 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7125 1200 7725 1200 7725 1800 7125 1800 7125 1200 -4 0 0 50 0 0 12 0.0000 4 180 1335 750 1575 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 525 2325 1575 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 1335 750 3225 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 780 2175 3225 .gnu.liblist\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 3300 3225 .gnu.version ... .eh_frame\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 3300 1575 .gnu.version ... .eh_frame\001 -4 0 0 50 0 0 12 0.0000 4 180 885 6150 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 180 885 6150 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7200 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7275 3225 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 525 7950 3225 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 930 9000 3225 .gnu.conflict\001 diff --git a/trunk/doc/dso1.fig b/trunk/doc/dso1.fig deleted file mode 100644 index 0bd75f3..0000000 --- a/trunk/doc/dso1.fig +++ /dev/null @@ -1,81 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 6375 2625 8250 3675 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6450 2850 7575 2850 7575 3450 6450 3450 6450 2850 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7575 2700 7575 3600 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7575 2850 8175 2850 8175 3450 7575 3450 7575 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6450 2700 8175 2700 8175 3600 6450 3600 6450 2700 -4 0 0 50 0 0 12 0.0000 4 180 885 6600 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7650 3225 .bss\001 --6 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 4950 975 4950 1950 450 1950 450 975 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2100 1200 2100 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4950 1200 2775 1200 2775 1800 4950 1800 4950 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2100 2850 2100 3450 600 3450 600 2850 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 2100 1200 2775 1200 2775 1800 2100 1800 2100 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2100 2850 3075 2850 3075 3450 2100 3450 2100 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5250 2850 3075 2850 3075 3450 5250 3450 5250 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 5250 2700 5250 3600 450 3600 450 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6150 1200 7275 1200 7275 1800 6150 1800 6150 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6150 975 7875 975 7875 1950 6150 1950 6150 975 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7275 975 7275 1950 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7275 1200 7875 1200 7875 1800 7275 1800 7275 1200 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 4800 675 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 4800 750 4800 3825 -2 1 5 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 6000 675 6000 3750 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1350 1950 1350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2100 1950 2100 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2775 1950 3075 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 3375 1950 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3375 1950 3675 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 7050 1950 7350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 7575 1950 7875 2700 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 1575 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 1575 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 2850 1575 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 3225 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 3225 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 3225 3225 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 885 6300 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7350 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 3675 2475 page boundary\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 6075 2475 page boundary\001 diff --git a/trunk/doc/dso2.fig b/trunk/doc/dso2.fig deleted file mode 100644 index 73d0a14..0000000 --- a/trunk/doc/dso2.fig +++ /dev/null @@ -1,81 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 6225 2625 8100 3675 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6300 2850 7425 2850 7425 3450 6300 3450 6300 2850 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7425 2700 7425 3600 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7425 2850 8025 2850 8025 3450 7425 3450 7425 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6300 2700 8025 2700 8025 3600 6300 3600 6300 2700 -4 0 0 50 0 0 12 0.0000 4 180 885 6450 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7500 3225 .bss\001 --6 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 4950 975 4950 1950 450 1950 450 975 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2100 1200 2100 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4950 1200 2775 1200 2775 1800 4950 1800 4950 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2100 2850 2100 3450 600 3450 600 2850 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 2100 1200 2775 1200 2775 1800 2100 1800 2100 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2100 2850 3075 2850 3075 3450 2100 3450 2100 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5250 2850 3075 2850 3075 3450 5250 3450 5250 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 5250 2700 5250 3600 450 3600 450 2700 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 4800 675 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 4800 750 4800 3825 -2 1 5 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 6000 675 6000 3750 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1350 1950 1350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2100 1950 2100 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2775 1950 3075 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 3375 1950 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3375 1950 3675 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6000 1200 7125 1200 7125 1800 6000 1800 6000 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 975 7725 975 7725 1950 6000 1950 6000 975 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7125 975 7125 1950 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7125 1200 7725 1200 7725 1800 7125 1800 7125 1200 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 6900 1950 7200 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 7425 1950 7725 2700 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 1575 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 1575 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 2850 1575 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 3225 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 3225 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 3225 3225 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 3675 2475 page boundary\001 -4 0 0 50 0 0 12 0.0000 4 180 885 6150 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7200 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 6075 2475 page boundary\001 diff --git a/trunk/doc/dso3.fig b/trunk/doc/dso3.fig deleted file mode 100644 index ffdb9de..0000000 --- a/trunk/doc/dso3.fig +++ /dev/null @@ -1,110 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 375 4125 6900 5175 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 4350 2100 4350 2100 4950 600 4950 600 4350 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2100 4350 3075 4350 3075 4950 2100 4950 2100 4350 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4950 4350 3075 4350 3075 4950 4950 4950 4950 4350 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 4200 4950 4200 4950 5100 450 5100 450 4200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5100 4350 6225 4350 6225 4950 5100 4950 5100 4350 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 6225 4350 6825 4350 6825 4950 6225 4950 6225 4350 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 5100 4200 6825 4200 6825 5100 5100 5100 5100 4200 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 6225 4200 6225 5100 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 4725 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 4725 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 3150 4725 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 885 5250 4724 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 6300 4724 .bss\001 --6 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2100 1200 2100 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 2100 1200 2775 1200 2775 1800 2100 1800 2100 1200 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 4800 675 -2 1 5 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 6000 675 6000 5250 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1350 1950 1350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2100 1950 2100 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2775 1950 3075 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 0 0 1 - 3375 1950 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3375 1950 4500 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 5400 1950 6600 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 6300 1950 7500 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4650 1200 2775 1200 2775 1800 4650 1800 4650 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 4650 975 4650 1950 450 1950 450 975 -2 1 4 1 0 7 50 0 -1 4.000 0 0 -1 0 0 2 - 4800 750 4800 5250 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4800 1200 5925 1200 5925 1800 4800 1800 4800 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 4800 975 6525 975 6525 1950 4800 1950 4800 975 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 5925 975 5925 1950 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 5925 1200 6525 1200 6525 1800 5925 1800 5925 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2100 2850 2100 3450 600 3450 600 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 2100 2850 3075 2850 3075 3450 2100 3450 2100 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5850 2850 3975 2850 3975 3450 5850 3450 5850 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 5850 2700 5850 3600 450 3600 450 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 6000 2850 7125 2850 7125 3450 6000 3450 6000 2850 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 7125 2850 7725 2850 7725 3450 7125 3450 7125 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 6000 2700 7725 2700 7725 3600 6000 3600 6000 2700 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 7125 2700 7125 3600 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 5475 5400 5475 5175 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 5475 5400 4950 5250 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 1575 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 1575 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 2850 1575 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 3675 2475 page boundary\001 -4 0 0 50 0 0 12 0.0000 4 180 1095 6075 2475 page boundary\001 -4 0 0 50 0 0 12 0.0000 4 180 885 4950 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 6000 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 1155 675 3225 .hash ... .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 555 2175 3225 .rel.dyn\001 -4 0 0 50 0 0 12 0.0000 4 180 1440 4050 3225 .text ... ro_seg_end\001 -4 0 0 50 0 0 12 0.0000 4 180 885 6150 3224 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 7200 3224 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 3450 3675 5550 This page needs to be mapped from 2 sources\001 -4 0 0 50 0 0 12 0.0000 4 135 645 1125 4050 And not:\001 diff --git a/trunk/doc/execstack.8 b/trunk/doc/execstack.8 deleted file mode 100644 index e0e95fa..0000000 --- a/trunk/doc/execstack.8 +++ /dev/null @@ -1,92 +0,0 @@ -.TH execstack 8 "28 October 2003" -.SH NAME -execstack \- tool to set, clear, or query executable stack flag of ELF binaries and shared libraries -.SH SYNOPSIS -execstack -.RB [OPTION...]\ [FILES] -.SH DESCRIPTION -.B execstack -is a program which sets, clears, or queries executable stack flag of ELF -binaries and shared libraries. Linux has in the past allowed execution -of instructions on the stack and there are lots of binaries and shared -libraries assuming this behaviour. Furthermore, GCC trampoline code -for e.g. nested functions requires executable stack on many architectures. -To avoid breaking binaries and shared libraries which need executable stack, -ELF binaries and shared libraries now can be marked as requiring executable -stack or not requiring it. This marking is done through the p_flags field -in the PT_GNU_STACK program header entry. If the marking is missing, kernel -or dynamic linker need to assume it might need executable stack. -The marking is done automatically by recent GCC versions (objects using -trampolines on the stack are marked as requiring executable stack, -all other newly built objects are marked as not requiring it) and -linker collects these markings into marking of the whole binary -or shared library. The user can override this at assembly time -(through -.B \-\-execstack -or -.B \-\-noexecstack -assembler options), at link time (through -.B \-z execstack -or -.B \-z noexecstack -linker options) and using the -.B execstack -tool also on an already linker binary or shared library. -This tool is especially useful for third party shared libraries -where it is known that they don't need executable stack or testing proves -it. -.SH OPTIONS -.TP -.B \-s \-\-set\-execstack -Mark binary or shared library as requiring executable stack. -.TP -.B \-c \-\-clear\-execstack -Mark binary or shared library as not requiring executable stack. -.TP -.B \-q \-\-query -Query executable stack marking of binaries and shared libraries. -For each file it prints either -.B \- -when executable stack is not required, -.B X -when executable stack is required or -.B ? -when it is unknown whether the object requires or doesn't require -executable stack (the marking is missing). -.TP -.B \-V -Print -.B execstack -version and exit. -.TP -.B \-? \-\-help -Print help message. -.TP -.B \-\-usage -Print a short usage message. -.SH ARGUMENTS -Command line arguments should be names of ELF binaries and shared libraries -which should be modified or queried. -.SH EXAMPLES -.RS -# execstack -s ~/lib/libfoo.so.1 -.RE -will mark ~/lib/libfoo.so.1 as requiring executable stack. -.RS -# execstack -c ~/bin/bar -.RE -will mark ~/bin/bar as not requiring executable stack. -.RS -# execstack -q ~/lib/libfoo.so.1 ~/bin/bar -.RE -will query executable stack marking of the given files. -.SH SEE ALSO -.BR ld.so (8). -.SH BUGS -.LP -.B execstack -doesn't support yet marking of executables if they do not have -PT_GNU_STACK program header entry nor they have room for program segment -header table growth. -.SH AUTHORS -Jakub Jelinek <jakub@redhat.com>. diff --git a/trunk/doc/gap.fig b/trunk/doc/gap.fig deleted file mode 100644 index ced67c9..0000000 --- a/trunk/doc/gap.fig +++ /dev/null @@ -1,87 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2175 1200 2175 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4425 1200 3225 1200 3225 1800 4425 1800 4425 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3225 1200 2175 1200 2175 1800 3225 1800 3225 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 9225 975 9225 1950 450 1950 450 975 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 9225 1200 7425 1200 7425 1800 9225 1800 9225 1200 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1425 1950 1425 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2175 1950 4425 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3225 1950 5700 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 3750 1950 3750 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 8250 1950 8250 2025 8250 2100 8250 2175 8250 2250 8250 2325 - 8250 2400 8250 2475 8250 2550 8250 2625 8250 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 2850 2175 2850 2175 3450 600 3450 600 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 3000 2850 2175 2850 2175 3450 3000 3450 3000 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4425 2850 3225 2850 3225 3450 4425 3450 4425 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5700 2850 4425 2850 4425 3450 5700 3450 5700 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5700 2850 6900 2850 6900 3450 5700 3450 5700 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 7425 2850 9225 2850 9225 3450 7425 3450 7425 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 9225 2700 9225 3600 450 3600 450 2700 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 9825 1200 10950 1200 10950 1800 9825 1800 9825 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 9825 2850 10950 2850 10950 3450 9825 3450 9825 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 9825 975 11550 975 11550 1950 9825 1950 9825 975 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 9825 2700 11550 2700 11550 3600 9825 3600 9825 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 10350 1950 10350 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 11175 1950 11175 2700 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 10950 975 10950 1950 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 13 - 10950 2700 10950 2775 10950 2850 10950 2925 10950 3000 10950 3075 - 10950 3150 10950 3225 10950 3300 10950 3375 10950 3450 10950 3525 - 10950 3600 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 10950 1200 11550 1200 11550 1800 10950 1800 10950 1200 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 10950 2850 11550 2850 11550 3450 10950 3450 10950 2850 -4 0 0 50 0 0 12 0.0000 4 180 1335 750 1575 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 525 2325 1575 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 1005 3300 1575 .gnu.version*\001 -4 0 0 50 0 0 12 0.0000 4 180 1530 7575 1575 .rel.dyn ... .eh_frame\001 -4 0 0 50 0 0 12 0.0000 4 180 1335 750 3225 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 780 2175 3225 .gnu.liblist\001 -4 0 0 50 0 0 12 0.0000 4 180 1005 3300 3225 .gnu.version*\001 -4 0 0 50 0 0 12 0.0000 4 180 525 4575 3225 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 930 5775 3225 .gnu.conflict\001 -4 0 0 50 0 0 12 0.0000 4 180 1530 7575 3225 .rel.dyn ... .eh_frame\001 -4 0 0 50 0 0 12 0.0000 4 180 885 9975 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 180 885 9975 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 11025 1575 .bss\001 -4 0 0 50 0 0 12 0.0000 4 135 315 11100 3225 .bss\001 diff --git a/trunk/doc/glossary.conf b/trunk/doc/glossary.conf deleted file mode 100644 index 477b529..0000000 --- a/trunk/doc/glossary.conf +++ /dev/null @@ -1,3 +0,0 @@ -keyword "\\glossaryentry" -preamble "\n \\begin{theglossary}\n" -postamble "\n\n \\end{theglossary}\n" diff --git a/trunk/doc/lineno.sty b/trunk/doc/lineno.sty deleted file mode 100644 index 0805bcc..0000000 --- a/trunk/doc/lineno.sty +++ /dev/null @@ -1,1521 +0,0 @@ -\iffalse; awk '/S[H]ELL/' lineno.sty|sh;exit;\fi -%%% To pretty-print this file, feed it to a unix shell! -%%% -%%% $Id: lineno.sty,v 3.12 2003/01/14 21:11:53 stephan Exp $ -%%% -%%% Copyright 1995--2001 Stephan I. B"ottcher <stephan@nevis.columbia.edu> -%%% -%%% This program can be redistributed and/or modified under the terms -%%% of the LaTeX Project Public License Distributed from CTAN -%%% archives in directory macros/latex/base/lppl.txt; either -%%% version 1 of the License, or any later version. -%%% -% \documentclass[a4paper,12pt]{article}%D -% \usepackage{lineno}%D -% -% \title{ -% \texttt{\itshape -% lineno.sty \ v3.09 2003/01/14 -% }\\\ \\ -% A \LaTeX\ package to attach -% \\ Line numbers to paragraphs -% }\author{ -% Stephan I. B\"ottcher -% }\date{ -% boettcher@physik.uni-kiel.de -%% \\ stephan@nevis.columbia.edu -%% \\ Stephan.Boettcher@cern.ch -% \\} -% -% -% \def~{\verb~} -% \catcode`\<\catcode`\~ -% \def<#1>{$\langle${\itshape#1}\/$\rangle$} -% \catcode`\|\catcode`\~ -% \def|#1{{\ttfamily\string#1}} -% \newenvironment{code} -% {\par\runninglinenumbers -% \modulolinenumbers[1] -% \linenumbersep.3em -% \footnotesize -% \def\linenumberfont -% {\normalfont\tiny\itshape}} -% {} -% -% \begin{document}%D -%% \DocInput{lineno.doc}%D -% \pagewiselinenumbers -% \maketitle -% \tableofcontents -% \sloppy -% -% -% -% \section{ -% Introduction -% } -% This package provides line numbers on paragraphs. -% After \TeX\ has broken a paragraph into lines there will -% be line numbers attached to them, with the possibility to -% make references through the \LaTeX\ ~\ref~, ~\pageref~ -% cross reference mechanism. This includes four issues: -% \begin{itemize} -% \item attach a line number on each line, -% \item create references to a line number, -% \item control line numbering mode, -% \item count the lines and print the numbers. -% \end{itemize} -% The first two points are implemented through patches to -% the output routine. The third by redefining ~\par~, ~\@par~ -% and ~\@@par~. The counting is easy, as long as you want -% the line numbers run through the text. If they shall -% start over at the top of each page, the aux-file as well -% as \TeX s memory have to carry a load for each counted line. -% -% I wrote this package for my wife Petra, who needs it for -% transcriptions of interviews. This allows her to -% precisely refer to passages in the text. It works well -% together with ~\marginpar~s, but not to well with displaymath. -% ~\footnote~s are a problem, especially when they -% are split, but we may get there. -% -% lineno.sty works -% surprisingly well with other packages, for -% example, ~wrapfig.sty~. So please try if it -% works with whatever you need, and if it does, -% please tell me, and if it does not, tell me as -% well, so I can try to fix it. -% -% This style option is written for \LaTeXe, later than November 1994, -% since we need the ~\protected@write~ macro. - -\NeedsTeXFormat{LaTeX2e}[1994/11/04] -\ProvidesPackage{lineno} - [2003/01/14 line numbers on paragraphs v3.09] - -%% v1.00 1995/03/31 SIB: first release for Petras interview transcriptions -%% v1.01 1995/10/28 SIB: added ~pagewise~ mode -%% v1.02 1995/11/15 SIB: added ~modulo~ option -%% v1.03 1995/12/05 SIB: pagewise: try to reduce the hash-size requirements -%% v2.00 1995/12/06 SIB: .. it works, new user interface -%% v2.01 1996/09/17 SIB: put into CVS -%% v2.02 1997/03/17 SIB: add: \@reinserts, for footnotes -%% v2.04 1998/03/09 SIB: add: linenomath environment -%% v2.05 1998/04/26 SIB: add: prevgraf test -%% v2.06 1999/03/02 SIB: LPPL added -%% v3.00 1999/06/11 SiB: include the extension in the main file -%% v3.01 1999/08/28 SiB: \@reinserts -> \holdinginserts -%% v3.02 2000/03/10 SiB: \@LN@output -%% v3.03 2000/07/01 SiB: \@LN@ExtraLabelItems, hyperref -%% v3.04 2000/12/17 SiB: longtable compatibility. -%% v3.05 2001/01/02 SiB: [fleqn] detection. -%% v3.05a 2001/01/04 SiB: [fleqn] detection reverted for eqnarray. -%% v3.06 2001/01/17 SiB: [twocolumn] mode support. -%% v3.07 2001/07/30 SiB: [hyperref] option obsoleted. -%% v3.08 2001/08/02 SiB: linenomath wrapping for \[ \] -%% v3.08a 2001/08/04 SiB: linenomath wrapping for \[ \] fixed -%% v3.08b 2002/01/27 SiB: enquotation typo fix -%% v3.09 2003/01/14 SIB: hyperref detection fix -%% -%% Acknowledgements: -%% v3.06: Donald Arseneau, pointed to mparhack.sty. -%% v3.07+: Frank Mittelbach, points out inconsistencies in the -%% user interface. -% -% \section{ -% Put the line numbers to the lines -% } -% The line numbers have to be attached by the output -% routine. We simply set the ~\interlinepenalty~ to -100000. -% The output routine will be called after each line in the -% paragraph, except the last, where we trigger by ~\par~. -% The ~\linenopenalty~ is small enough to compensate a bunch of -% penalties (e.g., with ~\samepage~). -% -% (New v3.04) Longtable uses -% ~\penaly~-30000. The lineno penalty range was -% shrunk to $-188000 \dots -32000$. (/New v3.04) - -\newcount\linenopenalty\linenopenalty=-100000 -\mathchardef\linenopenaltypar=32000 - -% So let's make a hook to ~\output~, the direct way. The \LaTeX\ -% macro ~\@reinserts~ puts the footnotes back on the page. -% -% (New v3.01) ~\@reinserts~ badly -% screws up split footnotes. The bottom part is -% still on the recent contributions list, and the -% top part will be put back there after the bottom -% part. Thus, since lineno.sty does not play well -% with ~\inserts~ anyway, we can safely experiment -% with ~\holdinginserts~, without making things -% much worse. -% -% Or that's what I thought, but: Just activating -% ~\holdinginserts~ while doing the ~\par~ will -% not do the trick: The ~\output~ routine may be -% called for a real page break before all line -% numbers are done, and how can we get control -% over ~\holdinginserts~ at that point? -% -% Let's try this: When the ~\output~ routine is -% run with ~\holdinginserts=3~ for a real page -% break, then we reset ~\holdinginserts~ and -% restart ~\output~. -% -% Then, again, how do we keep the remaining -% ~\inserts~ while doing further line numbers? -% -% If we find ~\holdinginserts~=-3 we activate it again -% after doing ~\output~. (/New v3.01) -% -% (New v3.02) To work with -% multicol.sty, the original output routine is now -% called indirectly, instead of being replaced. -% When multicol.sty changes ~\output~, it is a -% toks register, not the real thing. (/New v3.02) - -\let\@LN@output\output -\newtoks\output -\output=\expandafter{\the\@LN@output} -\@LN@output={% - \LineNoTest - \if@tempswa - \LineNoHoldInsertsTest - \if@tempswa - \if@twocolumn\let\@makecol\@LN@makecol\fi - \the\output - \ifnum\holdinginserts=-3 - \global\holdinginserts 3 - \fi - \else - \global\holdinginserts-3 - \unvbox\@cclv - \ifnum\outputpenalty=10000\else - \penalty\outputpenalty - \fi - \fi - \else - \MakeLineNo - \fi - } - -% The float mechanism inserts ~\interlinepenalty~s during -% ~\output~. So carefully reset it before going on. Else -% we get doubled line numbers on every float placed in -% horizontal mode, e.g, from ~\linelabel~. -% -% Sorry, neither a ~\linelabel~ nor a ~\marginpar~ should -% insert a penalty, else the following linenumber -% could go to the next page. Nor should any other -% float. So let us suppress the ~\interlinepenalty~ -% altogether with the ~\@nobreak~ switch. -% -% Since (ltspace.dtx, v1.2p)[1996/07/26], the ~\@nobreaktrue~ does -% it's job globally. We need to do it locally here. - -\def\LineNoTest{% - \let\@@par\@@@par - \ifnum\interlinepenalty<-\linenopenaltypar - \advance\interlinepenalty-\linenopenalty - \my@nobreaktrue - \fi - \@tempswatrue - \ifnum\outputpenalty>-\linenopenaltypar\else - \ifnum\outputpenalty>-188000\relax - \@tempswafalse - \fi - \fi - } - -\def\my@nobreaktrue{\let\if@nobreak\iftrue} - -\def\LineNoHoldInsertsTest{% - \ifnum\holdinginserts=3\relax - \@tempswafalse - \fi - } - -% We have to return all the page to the current page, and -% add a box with the line number, without adding -% breakpoints, glue or space. The depth of our line number -% should be equal to the previous depth of the page, in -% case the page breaks here, and the box has to be moved up -% by that depth. -% -% The ~\interlinepenalty~ comes after the ~\vadjust~ from a -% ~\linelabel~, so we increment the line number \emph{after} -% printing it. The macro ~\makeLineNumber~ produces the -% text of the line number, see section \ref{appearance}. -% -% Finally we put in the natural ~\interlinepenalty~, except -% after the last line. - -\def\MakeLineNo{\@tempdima\dp\@cclv \unvbox\@cclv - \sbox\@tempboxa{\hbox to\z@{\makeLineNumber}}% - \stepcounter{linenumber}% - \dp\@tempboxa=\@tempdima\ht\@tempboxa=\z@ - \nointerlineskip\kern-\@tempdima\box\@tempboxa - \ifnum\outputpenalty=-\linenopenaltypar\else - \@tempcnta\outputpenalty - \advance\@tempcnta -\linenopenalty - \penalty\@tempcnta - \fi - } - -% -% -% \section{ -% Control line numbering -% } -% The line numbering is controlled via ~\par~. \LaTeX\ -% saved the \TeX-primitive ~\par~ in ~\@@par~. We push it -% one level further out, and redefine ~\@@par~ to insert -% the ~\interlinepenalty~ needed to trigger the -% line numbering. And we need to allow pagebreaks after a -% paragraph. -% -% New (2.05beta): the prevgraf test. A paragraph that ends with a -% displayed equation, a ~\noindent\par~ or ~wrapfig.sty~ produce empty -% paragraphs. These should not get a spurious line number via -% ~\linenopenaltypar~. - -\let\@@@par\@@par -\newcount\linenoprevgraf - -\def\linenumberpar{\ifvmode\@@@par\else\ifinner\@@@par\else - \advance\interlinepenalty \linenopenalty - \linenoprevgraf\prevgraf - \global\holdinginserts3% - \@@@par - \ifnum\prevgraf>\linenoprevgraf - \penalty-\linenopenaltypar - \fi - \kern\z@ - \global\holdinginserts0% - \advance\interlinepenalty -\linenopenalty - \fi\fi - } - -% The basic commands to enable and disable line numbers. -% ~\@par~ and ~\par~ are only touched, when they are ~\let~ -% to ~\@@@par~/~\linenumberpar~. The line number may be -% reset to 1 with the star-form, or set by an optional -% argument ~[~<number>~]~. - -\def\linenumbers{\let\@@par\linenumberpar - \ifx\@par\@@@par\let\@par\linenumberpar\fi - \ifx\par\@@@par\let\par\linenumberpar\fi - \@ifnextchar[{\resetlinenumber}%] - {\@ifstar{\resetlinenumber}{}}% - } - -\def\nolinenumbers{\let\@@par\@@@par - \ifx\@par\linenumberpar\let\@par\@@@par\fi - \ifx\par\linenumberpar\let\par\@@@par\fi - } - -% What happens with a display math? Since ~\par~ is not executed, -% when breaking the lines before a display, they will not get -% line numbers. Sorry, but I do not dare to change -% ~\interlinepenalty~ globally, nor do I want to redefine -% the display math environments here. -% \begin{displaymath} -% display \ math -% \end{displaymath} -% See the subsection below, for a wrapper enviroment to make -% it work. But that requires to wrap each and every display -% in your LaTeX source. -% -% The next two commands are provided to turn on line -% numbering in a specific mode. Please note the difference: -% for pagewise numbering, ~\linenumbers~ comes first to -% inhibit it from seeing optional arguments, since -% re-/presetting the counter is useless. - -\def\pagewiselinenumbers{\linenumbers\setpagewiselinenumbers} -\def\runninglinenumbers{\setrunninglinenumbers\linenumbers} - -% Finally, it is a \LaTeX\ style, so we provide for the use -% of environments, including the suppression of the -% following paragraph's indentation. - -%%% TO DO: add \par to \linenumbers, if called from an environment. -%%% To DO: add an \@endpe hack if \linenumbers are turned on -%%% in horizontal mode. {\par\parskip\z@\noindent} or -%%% something. - -\@namedef{linenumbers*}{\par\linenumbers*} -\@namedef{runninglinenumbers*}{\par\runninglinenumbers*} - -\def\endlinenumbers{\par\@endpetrue} -\let\endrunninglinenumbers\endlinenumbers -\let\endpagewiselinenumbers\endlinenumbers -\expandafter\let\csname endlinenumbers*\endcsname\endlinenumbers -\expandafter\let\csname endrunninglinenumbers*\endcsname\endlinenumbers -\let\endnolinenumbers\endlinenumbers - -% -% \subsection{ -% Display math -% } -% -% Now we tackle the problem to get display math working. -% There are different options. -% \begin{enumerate}\item[ -% 1.] Precede every display math with a ~\par~. -% Not too good. -% \item[ -% 2.] Change ~\interlinepenalty~ and associates globally. -% Unstable. -% \item[ -% 3.] Wrap each display math with a ~{linenomath}~ -% environment. -% \end{enumerate} -% We'll go for option 3. See if it works: -% \begin{linenomath} -% \begin{equation} -% display \ math -% \end{equation} -% \end{linenomath} -% The star form ~{linenomath*}~ should also number the lines -% of the display itself, -% \begin{linenomath*} -% \begin{eqnarray} -% multi && line \\ -% display && math \\ -% & -% \begin{array}{c} -% with \\ -% array -% \end{array} -% & -% \end{eqnarray} -% \end{linenomath*} -% including multline displays. -% -% First, here are two macros to turn -% on linenumbering on paragraphs preceeding displays, with -% numbering the lines of the display itself, or without. -% The ~\ifx..~ tests if line numbering is turned on. It -% does not harm to add these wrappers in sections that are -% not numbered. Nor does it harm to wrap a display -% twice, e.q, in case you have some ~{equation}~s wrapped -% explicitely, and later you redefine ~\equation~ to do it -% automatically. - -\newcommand\linenomathNonumbers{% - \ifx\@@par\@@@par\else - \ifnum\interlinepenalty>-\linenopenaltypar - \global\holdinginserts3% - \advance\interlinepenalty \linenopenalty - \advance\predisplaypenalty \linenopenalty - \fi - \fi - \ignorespaces - } - -\newcommand\linenomathWithnumbers{% - \ifx\@@par\@@@par\else - \ifnum\interlinepenalty>-\linenopenaltypar - \global\holdinginserts3% - \advance\interlinepenalty \linenopenalty - \advance\predisplaypenalty \linenopenalty - \advance\postdisplaypenalty \linenopenalty - \advance\interdisplaylinepenalty \linenopenalty - \fi - \fi - \ignorespaces - } - -% The ~{linenomath}~ environment has two forms, with and -% without a star. The following two macros define the -% environment, where the stared/non-stared form does/doesn't number the -% lines of the display or vice versa. - -\newcommand\linenumberdisplaymath{% - \def\linenomath{\linenomathWithnumbers}% - \@namedef{linenomath*}{\linenomathNonumbers}% - } - -\newcommand\nolinenumberdisplaymath{% - \def\linenomath{\linenomathNonumbers}% - \@namedef{linenomath*}{\linenomathWithnumbers}% - } - -\def\endlinenomath{% - \global\holdinginserts0 - \@ignoretrue -} -\expandafter\let\csname endlinenomath*\endcsname\endlinenomath - -% The default is not to number the lines of a display. But -% the package option ~mathlines~ may be used to switch -% that behavior. - -\nolinenumberdisplaymath - -% -% -% \section{ -% Line number references -% } -% The only way to get a label to a line number in a -% paragraph is to ask the output routine to mark it. -% -% We use the marginpar mechanism to hook to ~\output~ for a -% second time. Marginpars are floats with number $-1$, we -% fake marginpars with No $-2$. Originally, every negative -% numbered float was considered to be a marginpar. -% -% The float box number ~\@currbox~ is used to transfer the -% label name in a macro called ~\@LNL@~<box-number>. -% -% A ~\newlabel~ is written to the aux-file. The reference -% is to ~\theLineNumber~, \emph{not} ~\thelinenumber~. -% This allows to hook in, as done below for pagewise line -% numbering. -% -% (New v3.03) The ~\@LN@ExtraLabelItems~ are added for a hook -% to keep packages like ~{hyperref}~ happy. (/New v3.03) - -\let\@LN@addmarginpar\@addmarginpar -\def\@addmarginpar{% - \ifnum\count\@currbox>-2\relax - \expandafter\@LN@addmarginpar - \else - \@cons\@freelist\@currbox - \protected@write\@auxout{}{% - \string\newlabel - {\csname @LNL@\the\@currbox\endcsname}% - {{\theLineNumber}{\thepage}\@LN@ExtraLabelItems}}% - \fi} - -\let\@LN@ExtraLabelItems\@empty - -% \subsection{ -% The linelabel command -% } -% To refer to a place in line ~\ref{~<foo>~}~ at page -% ~\pageref{~<foo>~}~ you place a ~\linelabel{~<foo>~}~ at -% that place. -% -% \linelabel{demo} -% \marginpar{\tiny\raggedright -% See if it works: This paragraph -% starts on page \pageref{demo}, line -% \ref{demo}. -% }% -% If you use this command outside a ~\linenumbers~ -% paragraph, you will get references to some bogus -% line numbers, sorry. But we don't disable the command, -% because only the ~\par~ at the end of a paragraph may -% decides whether to print line numbers on this paragraph -% or not. A ~\linelabel~ may legally appear earlier than -% ~\linenumbers~. -% -% ~\linelabel~, via a fake float number $-2$, puts a -% ~\penalty~ into a ~\vadjust~, which triggers the -% pagebuilder after putting the current line to the main -% vertical list. A ~\write~ is placed on the main vertical -% list, which prints a reference to the current value of -% ~\thelinenumber~ and ~\thepage~ at the time of the -% ~\shipout~. -% -% A ~\linelabel~ is allowed only in outer horizontal mode. -% In outer vertical mode we start a paragraph, and ignore -% trailing spaces (by fooling ~\@esphack~). -% -% The argument of ~\linelabel~ is put into a macro with a -% name derived from the number of the allocated float box. -% Much of the rest is dummy float setup. - -\def\linelabel#1{% - \ifvmode - \ifinner \else - \leavevmode \@bsphack \@savsk\p@ - \fi - \else - \@bsphack - \fi - \ifhmode - \ifinner - \@parmoderr - \else - \@floatpenalty -\@Mii - \@next\@currbox\@freelist - {\global\count\@currbox-2% - \expandafter\gdef\csname @LNL@\the\@currbox\endcsname{#1}}% - {\@floatpenalty\z@ \@fltovf \def\@currbox{\@tempboxa}}% - \begingroup - \setbox\@currbox \color@vbox \vbox \bgroup \end@float - \endgroup - \@ignorefalse \@esphack - \fi - \else - \@parmoderr - \fi - } - -% \modulolinenumbers[3] -% \section{ -% The appearance of the line numbers -% }\label{appearance} -% The line numbers are set as ~\tiny\sffamily\arabic{linenumber}~, -% $10pt$ left of the text. With options to place it -% right of the text, or . . . -% -% . . . here are the hooks: - -\def\makeLineNumberLeft{\hss\linenumberfont\LineNumber\hskip\linenumbersep} - -\def\makeLineNumberRight{\linenumberfont\hskip\linenumbersep\hskip\columnwidth - \hbox to\linenumberwidth{\hss\LineNumber}\hss} - -\def\linenumberfont{\normalfont\tiny\sffamily} - -\newdimen\linenumbersep -\newdimen\linenumberwidth - -\linenumberwidth=10pt -\linenumbersep=10pt - -% Margin switching requires ~pagewise~ numbering mode, but -% choosing the left or right margin for the numbers always -% works. - -\def\switchlinenumbers{\@ifstar - {\let\makeLineNumberOdd\makeLineNumberRight - \let\makeLineNumberEven\makeLineNumberLeft}% - {\let\makeLineNumberOdd\makeLineNumberLeft - \let\makeLineNumberEven\makeLineNumberRight}% - } - -\def\setmakelinenumbers#1{\@ifstar - {\let\makeLineNumberRunning#1% - \let\makeLineNumberOdd#1% - \let\makeLineNumberEven#1}% - {\ifx\c@linenumber\c@runninglinenumber - \let\makeLineNumberRunning#1% - \else - \let\makeLineNumberOdd#1% - \let\makeLineNumberEven#1% - \fi}% - } - -\def\leftlinenumbers{\setmakelinenumbers\makeLineNumberLeft} -\def\rightlinenumbers{\setmakelinenumbers\makeLineNumberRight} - -\leftlinenumbers* - -% ~\LineNumber~ is a hook which is used for the modulo stuff. -% It is the command to use for the line number, when you -% customizes ~\makeLineNumber~. Use ~\thelinenumber~ to -% change the outfit of the digits. -% -% -% We will implement two modes of operation: -% \begin{itemize} -% \item numbers ~running~ through (parts of) the text -% \item ~pagewise~ numbers starting over with one on top of -% each page. -% \end{itemize} -% Both modes have their own count register, but only one is -% allocated as a \LaTeX\ counter, with the attached -% facilities serving both. - -\newcounter{linenumber} -\newcount\c@pagewiselinenumber -\let\c@runninglinenumber\c@linenumber - -% Only the running mode counter may be reset, or preset, -% for individual paragraphs. The pagewise counter must -% give a unique anonymous number for each line. - -\newcommand\resetlinenumber[1][1]{\c@runninglinenumber#1} - -% \subsection{ -% Running line numbers -% } -% Running mode is easy, ~\LineNumber~ and ~\theLineNumber~ -% produce ~\thelinenumber~, which defaults to -% ~\arabic{linenumber}~, using the ~\c@runninglinenumber~ -% counter. This is the default mode of operation. - -\def\makeRunningLineNumber{\makeLineNumberRunning} - -\def\setrunninglinenumbers{% - \def\theLineNumber{\thelinenumber}% - \let\c@linenumber\c@runninglinenumber - \let\makeLineNumber\makeRunningLineNumber - } - -\setrunninglinenumbers\resetlinenumber - -% -% -% \subsection{ -% Pagewise line numbers -% } -% Difficult, if you think about it. The number has to be -% printed when there is no means to know on which page it -% will end up, except through the aux-file. My solution -% is really expensive, but quite robust. -% -% With version ~v2.00~ the hashsize requirements are -% reduced, because we do not need one controlsequence for -% each line any more. But this costs some computation time -% to find out on which page we are. -% -% ~\makeLineNumber~ gets a hook to log the line and page -% number to the aux-file. Another hook tries to find out -% what the page offset is, and subtracts it from the counter -% ~\c@linenumber~. Additionally, the switch -% ~\ifoddNumberedPage~ is set true for odd numbered pages, -% false otherwise. - -\def\setpagewiselinenumbers{% - \let\theLineNumber\thePagewiseLineNumber - \let\c@linenumber\c@pagewiselinenumber - \let\makeLineNumber\makePagewiseLineNumber - } - -\def\makePagewiseLineNumber{\logtheLineNumber\getLineNumber - \ifoddNumberedPage - \makeLineNumberOdd - \else - \makeLineNumberEven - \fi - } - -% Each numbered line gives a line to the aux file -% \begin{verse} -% ~\@LN{~<line>~}{~<page>~}~ -% \end{verse} -% very similar to the ~\newlabel~ business, except that we need -% an arabic representation of the page number, not what -% there might else be in ~\thepage~. - -\def\logtheLineNumber{\protected@write\@auxout{}{% - \string\@LN{\the\c@linenumber}{\noexpand\the\c@page}}} - -% From the aux-file we get one macro ~\LN@P~<page> for each -% page with line numbers on it. This macro calls four other -% macros with one argument each. These macros are -% dynamically defined to do tests and actions, to find out -% on which page the current line number is located. -% -% We need sort of a pointer to the first page with line -% numbers, initiallized to point to nothing: - -\def\LastNumberedPage{first} -\def\LN@Pfirst{\nextLN\relax} - -% The four dynamic macros are initiallized to reproduce -% themselves in an ~\xdef~ - -\let\lastLN\relax % compare to last line on this page -\let\firstLN\relax % compare to first line on this page -\let\pageLN\relax % get the page number, compute the linenumber -\let\nextLN\relax % move to the next page - -% During the end-document run through the aux-files, we -% disable ~\@LN~. I may put in a check here later, to give -% a rerun recommendation. - -\AtEndDocument{\let\@LN\@gobbletwo} - -% Now, this is the tricky part. First of all, the whole -% definition of ~\@LN~ is grouped, to avoid accumulation -% on the save stack. Somehow ~\csname~<cs>~\endcsname~ pushes -% an entry, which stays after an ~\xdef~ to that <cs>. -% -% If ~\LN@P~<page> is undefined, initialize it with the -% current page and line number, with the -% \emph{pointer-to-the-next-page} pointing to nothing. And -% the macro for the previous page will be redefined to point -% to the current one. -% -% If the macro for the current page already exists, just -% redefine the \emph{last-line-number} entry. -% -% Finally, save the current page number, to get the pointer to the -% following page later. - -\def\@LN#1#2{{\expandafter\@@LN - \csname LN@P#2C\@LN@column\expandafter\endcsname - \csname LN@PO#2\endcsname - {#1}{#2}}} - -\def\@@LN#1#2#3#4{\ifx#1\relax - \ifx#2\relax\gdef#2{#3}\fi - \expandafter\@@@LN\csname LN@P\LastNumberedPage\endcsname#1 - \xdef#1{\lastLN{#3}\firstLN{#3}\pageLN{#4}{\@LN@column}{#2}\nextLN\relax}% - \else - \def\lastLN##1{\noexpand\lastLN{#3}}% - \xdef#1{#1}% - \fi - \xdef\LastNumberedPage{#4C\@LN@column}} - -% The previous page macro gets its pointer to the -% current one, replacing the ~\relax~ with the cs-token -% ~\LN@P~<page>. - -\def\@@@LN#1#2{{\def\nextLN##1{\noexpand\nextLN\noexpand#2}% - \xdef#1{#1}}} - -% Now, to print a line number, we need to find the page, -% where it resides. This will most probably be the page where -% the last one came from, or maybe the next page. However, it can -% be a completely different one. We maintain a cache, -% which is ~\let~ to the last page's macro. But for now -% it is initialized to expand ~\LN@first~, where the poiner -% to the first numbered page has been stored in. - -\def\NumberedPageCache{\LN@Pfirst} - -% To find out on which page the current ~\c@linenumber~ is, -% we define the four dynamic macros to do something usefull -% and execute the current cache macro. ~\lastLN~ is run -% first, testing if the line number in question may be on a -% later page. If so, disable ~\firstLN~, and go on to the -% next page via ~\nextLN~. - -\def\testLastNumberedPage#1{\ifnum#1<\c@linenumber - \let\firstLN\@gobble - \fi} - -% Else, if ~\firstLN~ finds out that we need an earlier -% page, we start over from the beginning. Else, ~\nextLN~ -% will be disabled, and ~\pageLN~ will run -% ~\gotNumberedPage~ with four arguments: the first line -% number on this column, the page number, the column -% number, and the first line on the page. - -\def\testFirstNumberedPage#1{\ifnum#1>\c@linenumber - \def\nextLN##1{\testNextNumberedPage\LN@Pfirst}% - \else - \let\nextLN\@gobble - \def\pageLN{\gotNumberedPage{#1}}% - \fi} - -% We start with ~\pageLN~ disabled and ~\nextLN~ defined to -% continue the search with the next page. - -\long\def \@gobblethree #1#2#3{} - -\def\testNumberedPage{% - \let\lastLN\testLastNumberedPage - \let\firstLN\testFirstNumberedPage - \let\pageLN\@gobblethree - \let\nextLN\testNextNumberedPage - \NumberedPageCache - } - -% When we switch to another page, we first have to make -% sure that it is there. If we are done with the last -% page, we probably need to run \TeX\ again, but for the -% rest of this run, the cache macro will just return four -% zeros. This saves a lot of time, for example if you have -% half of an aux-file from an aborted run, in the next run -% the whole page-list would be searched in vain again and -% again for the second half of the document. -% -% If there is another page, we iterate the search. - -\def\testNextNumberedPage#1{\ifx#1\relax - \global\def\NumberedPageCache{\gotNumberedPage0000}% - \PackageWarningNoLine{lineno}% - {Linenumber reference failed, - \MessageBreak rerun to get it right}% - \else - \global\let\NumberedPageCache#1% - \fi - \testNumberedPage - } - -% \linelabel{demo2} -% \marginpar{\tiny\raggedright -% Let's see if it finds the label -% on page \pageref{demo}, -% line \ref{demo}, and back here -% on page \pageref{demo2}, line -% \ref{demo2}. -% }% -% To separate the official hooks from the internals there is -% this equivalence, to hook in later for whatever purpose: - -\let\getLineNumber\testNumberedPage - -% So, now we got the page where the number is on. We -% establish if we are on an odd or even page, and calculate -% the final line number to be printed. - -\newif\ifoddNumberedPage -\newif\ifcolumnwiselinenumbers -\columnwiselinenumbersfalse - -\def\gotNumberedPage#1#2#3#4{\oddNumberedPagefalse - \ifodd \if@twocolumn #3\else #2\fi\relax\oddNumberedPagetrue\fi - \advance\c@linenumber 1\relax - \ifcolumnwiselinenumbers - \subtractlinenumberoffset{#1}% - \else - \subtractlinenumberoffset{#4}% - \fi - } - -% You might want to run the pagewise mode with running line -% numbers, or you might not. It's your choice: - -\def\runningpagewiselinenumbers{% - \let\subtractlinenumberoffset\@gobble - } - -\def\realpagewiselinenumbers{% - \def\subtractlinenumberoffset##1{\advance\c@linenumber-##1\relax}% - } - -\realpagewiselinenumbers - -% For line number references, we need a protected call to -% the whole procedure, with the requested line number stored -% in the ~\c@linenumber~ counter. This is what gets printed -% to the aux-file to make a label: - -\def\thePagewiseLineNumber{\protect - \getpagewiselinenumber{\the\c@linenumber}}% - -% And here is what happens when the label is refered to: - -\def\getpagewiselinenumber#1{{% - \c@linenumber #1\relax\testNumberedPage - \thelinenumber - }} - -% % -% A summary of all per line expenses: -% \begin{description}\item -% [CPU:] The ~\output~ routine is called for each line, -% and the page-search is done. -% \item -% [DISK:] One line of output to the aux-file for each -% numbered line -% \item -% [MEM:] One macro per page. Great improvement over v1.02, -% which had one control sequence per line in -% addition. It blew the hash table after some five -% thousand lines. -% \end{description} -% -% -% -% \subsection{ -% Twocolumn mode (New v3.06) -% } -% -% Twocolumn mode requires another patch to the ~\output~ -% routine, in order to print a column tag to the .aux -% file. - -\let\@LN@orig@makecol\@makecol -\def\@LN@makecol{% - \@LN@orig@makecol - \setbox\@outputbox \vbox{% - \boxmaxdepth \@maxdepth - \protected@write\@auxout{}{% - \string\@LN@col{\if@firstcolumn1\else2\fi}% - }% - \box\@outputbox - }% \vbox -} - -\def\@LN@col#1{\def\@LN@column{#1}} -\@LN@col{1} - -% -% -% -% \subsection{ -% Numbering modulo 5 -% } -% Most users want to have only one in five lines numbered. -% ~\LineNumber~ is supposed to produce the outfit of the -% line number attached to the line, while ~\thelinenumber~ -% is used also for references, which should appear even if -% they are not multiples of five. - -\newcount\c@linenumbermodulo - -\def\themodulolinenumber{{\@tempcnta\c@linenumber - \divide\@tempcnta\c@linenumbermodulo - \multiply\@tempcnta\c@linenumbermodulo - \ifnum\@tempcnta=\c@linenumber\thelinenumber\fi - }} - -% The user command to set the modulo counter: - -\newcommand\modulolinenumbers[1][0]{% - \let\LineNumber\themodulolinenumber - \ifnum#1>1\relax - \c@linenumbermodulo#1\relax - \else\ifnum#1=1\relax - \def\LineNumber{\thelinenumber}% - \fi\fi - } - -\setcounter{linenumbermodulo}{5} -\modulolinenumbers[1] - -% -% \switchlinenumbers -% \modulolinenumbers[1] -% \section{ -% Package options -% } -% There is a bunch of package options, all of them -% executing only user commands (see below). -% -% Options ~left~ (~right~) put the line numbers on the left -% (right) margin. This works in all modes. ~left~ is the -% default. - -\DeclareOption{left}{\leftlinenumbers*} - -\DeclareOption{right}{\rightlinenumbers*} - -% Option ~switch~ (~switch*~) puts the line numbers on the -% outer (inner) margin of the text. This requires running -% the pagewise mode, but we turn off the page offset -% subtraction, getting sort of running numbers again. The -% ~pagewise~ option may restore true pagewise mode later. - -\DeclareOption{switch}{\setpagewiselinenumbers - \switchlinenumbers - \runningpagewiselinenumbers} - -\DeclareOption{switch*}{\setpagewiselinenumbers - \switchlinenumbers*% - \runningpagewiselinenumbers} - -% In twocolumn mode, we can switch the line numbers to -% the outer margin, and/or start with number 1 in each -% column. Margin switching is covered by the ~switch~ -% options. - -\DeclareOption{columnwise}{\setpagewiselinenumbers - \columnwiselinenumberstrue - \realpagewiselinenumbers} - -% The options ~pagewise~ and ~running~ select the major -% linenumber mechanism. ~running~ line numbers refer to a real -% counter value, which can be reset for any paragraph, -% even getting multiple paragraphs on one page starting -% with line number one. ~pagewise~ line numbers get a -% unique hidden number within the document, but with the -% opportunity to establish the page on which they finally -% come to rest. This allows the subtraction of the page -% offset, getting the numbers starting with 1 on top of each -% page, and margin switching in twoside formats becomes -% possible. The default mode is ~running~. -% -% The order of declaration of the options is important here -% ~pagewise~ must come after ~switch~, to overide running -% pagewise mode. ~running~ comes last, to reset the running -% line number mode, e.g, after selecting margin switch mode -% for ~pagewise~ running. Once more, if you specify all -% three of the options ~[switch,pagewise,running]~, the -% result is almost nothing, but if you later say -% ~\pagewiselinenumbers~, you get margin switching, with -% real pagewise line numbers. -% -\DeclareOption{pagewise}{\setpagewiselinenumbers - \realpagewiselinenumbers} - -\DeclareOption{running}{\setrunninglinenumbers} - -% The option ~modulo~ causes only those linenumbers to be -% printed which are multiples of five. - -\DeclareOption{modulo}{\modulolinenumbers\relax} - -% The package option ~mathlines~ switches the behavior of -% the ~{linenomath}~ environment with its star-form. -% Without this option, the ~{linenomath}~ environment does -% not number the lines of the display, while the star-form -% does. With this option, its just the opposite. -% -%%% 1999-06-10: renamed ~displaymath~ to ~mathlines~. - -\DeclareOption{mathlines}{\linenumberdisplaymath} - -% ~displaymath~ now calls for wrappers of the standard -% LaTeX display math environment. This was previously -% done by ~mlineno.sty~. - -\let\do@mlineno\relax -\DeclareOption{displaymath}{\let\do@mlineno\@empty} - -% The ~hyperref~ package, via ~nameref~, requires three more -% groups in the second argment of a ~\newlabel~. Well, why -% shouldn't it get them? (New v3.07) The presencs of the -% ~nameref~ package is now detected automatically -% ~\AtBeginDocument~. (/New v3.07) (Fixed in v3.09) We try -% to be smart, and test ~\AtBeginDocument~ if the ~nameref~ -% package is loaded, but ~hyperref~ postpones the loading of -% ~nameref~ too, so this is all in vain. - -\DeclareOption{hyperref}{\PackageWarningNoLine{lineno}{% - Option [hyperref] is obsolete. - \MessageBreak The hyperref package is detected automatically.}} - -\AtBeginDocument{% - \@ifpackageloaded{nameref}{% - \def\@LN@ExtraLabelItems{{}{}{}}}{}} - -\ProcessOptions - -% \subsection{ -% Package Extensions -% } -% -% The extensions in this section were previously supplied -% in seperate ~.sty~ files. -% -% \subsubsection{ -% $display math$ -% } -% -% The standard \LaTeX\ display math environments are -% wrapped in a ~{linenomath}~ environment. -% -% (New 3.05) The ~[fleqn]~ option of the standard -% \LaTeX\ classes defines the display math -% environments such that line numbers appear just -% fine. Thus, we need not do any tricks when -% ~[fleqn]~ is loaded, as indicated by presents of -% the ~\mathindent~ register. (/New 3.05) -% -% (New 3.05a) for ~{eqnarray}~s we rather keep the -% old trick. (/New 3.05a) -% -% (New 3.08) Wrap ~\[~ and ~\]~ into ~{linenomath}~, -% instead of ~{displaymath}~. Also save the definition -% of ~\equation~, instead of replicating the current -% \LaTeX\ definition. (/New 3.08) - -\ifx\do@mlineno\@empty - \@ifundefined{mathindent}{ - - \let\LN@displaymath\[ - \let\LN@enddisplaymath\] - \renewcommand\[{\begin{linenomath}\LN@displaymath} - \renewcommand\]{\LN@enddisplaymath\end{linenomath}} - - \let\LN@equation\equation - \let\LN@endequation\endequation - \renewenvironment{equation} - {\linenomath\LN@equation} - {\LN@endequation\endlinenomath} - - }% \@ifundefined{mathindent} - - \let\LN@eqnarray\eqnarray - \let\LN@endeqnarray\endeqnarray - \renewenvironment{eqnarray} - {\linenomath\LN@eqnarray} - {\LN@endeqnarray\endlinenomath} - -\fi - -% \subsubsection{ -% Line numbers in internal vertical mode -% } -% -% The command ~\internallinenumbers~ adds line numbers in -% internal vertical mode, but with limitations: we assume -% fixed baseline skip. - -\def\internallinenumbers{\setrunninglinenumbers - \let\@@par\internallinenumberpar - \ifx\@par\@@@par\let\@par\internallinenumberpar\fi - \ifx\par\@@@par\let\par\internallinenumberpar\fi - \ifx\@par\linenumberpar\let\@par\internallinenumberpar\fi - \ifx\par\linenumberpar\let\par\internallinenumberpar\fi - \@ifnextchar[{\resetlinenumber}%] - {\@ifstar{\let\c@linenumber\c@internallinenumber - \c@linenumber\@ne}{}}% - } - -\let\endinternallinenumbers\endlinenumbers -\@namedef{internallinenumbers*}{\internallinenumbers*} -\expandafter\let\csname endinternallinenumbers*\endcsname\endlinenumbers - -\newcount\c@internallinenumber -\newcount\c@internallinenumbers - -\def\internallinenumberpar{\ifvmode\@@@par\else\ifinner\@@@par\else\@@@par - \begingroup - \c@internallinenumbers\prevgraf - \setbox\@tempboxa\hbox{\vbox{\makeinternalLinenumbers}}% - \dp\@tempboxa\prevdepth - \ht\@tempboxa\z@ - \nobreak\vskip-\prevdepth - \nointerlineskip\box\@tempboxa - \endgroup - \fi\fi - } - -\def\makeinternalLinenumbers{\ifnum\c@internallinenumbers>0\relax - \hbox to\z@{\makeLineNumber}\global\advance\c@linenumber\@ne - \advance\c@internallinenumbers\m@ne - \expandafter\makeinternalLinenumbers\fi - } - -% \subsubsection{ -% Line number references with offset -% } -% -% This extension defines macros to refer to line -% numbers with an offset, e.g., to refer to a line -% which cannot be labeled directly (display math). -% This was formerly knows as ~rlineno.sty~. -% -% To refer to a pagewise line number with offset: -% \begin{quote} -% ~\linerefp[~<OFFSET>~]{~<LABEL>~}~ -% \end{quote} -% To refer to a running line number with offset: -% \begin{quote} -% ~\linerefr[~<OFFSET>~]{~<LABEL>~}~ -% \end{quote} -% To refer to a line number labeled in the same mode as currently -% selected: -% \begin{quote} -% ~\lineref[~<OFFSET>~]{~<LABEL>~}~ -% \end{quote} - -\newcommand\lineref{% - \ifx\c@linenumner\c@runninglinenumner - \expandafter\linerefr - \else - \expandafter\linerefp - \fi -} - -\newcommand\linerefp[2][\z@]{{% - \let\@thelinenumber\thelinenumber - \edef\thelinenumber{\advance\c@linenumber#1\relax\noexpand\@thelinenumber}% - \ref{#2}% -}} - -% This goes deep into \LaTeX s internals. - -\newcommand\linerefr[2][\z@]{{% - \def\@@linerefadd{\advance\c@linenumber#1}% - \expandafter\@setref\csname r@#2\endcsname - \@linerefadd{#2}% -}} - -\newcommand\@linerefadd[2]{\c@linenumber=#1\@@linerefadd\relax - \thelinenumber} - -% \subsubsection{ -% Numbered quotation environments -% } -% -% The ~{numquote}~ and ~{numquotation}~ -% environments are like ~{quote}~ and -% ~{quotation}~, except there will be line -% numbers. -% -% An optional argument gives the number to count -% from. A star ~*~ (inside or outside the closing -% ~}~) prevent the reset of the line numbers. -% Default is to count from one. - -\newcommand\quotelinenumbers - {\@ifstar\linenumbers{\@ifnextchar[\linenumbers{\linenumbers*}}} - -\newdimen\quotelinenumbersep -\quotelinenumbersep=\linenumbersep -\let\quotelinenumberfont\linenumberfont - -\newcommand\numquotelist - {\leftlinenumbers - \linenumbersep\quotelinenumbersep - \let\linenumberfont\quotelinenumberfont - \addtolength{\linenumbersep}{-\@totalleftmargin}% - \quotelinenumbers - } - -\newenvironment{numquote} {\quote\numquotelist}{\endquote} -\newenvironment{numquotation} {\quotation\numquotelist}{\endquotation} -\newenvironment{numquote*} {\quote\numquotelist*}{\endquote} -\newenvironment{numquotation*}{\quotation\numquotelist*}{\endquotation} - -% \subsubsection{ -% Frame around a paragraph -% } -% -% The ~{bframe}~ environment draws a frame around -% some text, across page breaks, if necessary. -% -% This works only for plain text paragraphs, -% without special height lines. All lines must be -% ~\baselineskip~ apart, no display math. - -\newenvironment{bframe} - {\par - \@tempdima\textwidth - \advance\@tempdima 2\bframesep - \setbox\bframebox\hbox to\textwidth{% - \hskip-\bframesep - \vrule\@width\bframerule\@height\baselineskip\@depth\bframesep - \advance\@tempdima-2\bframerule - \hskip\@tempdima - \vrule\@width\bframerule\@height\baselineskip\@depth\bframesep - \hskip-\bframesep - }% - \hbox{\hskip-\bframesep - \vrule\@width\@tempdima\@height\bframerule\@depth\z@}% - \nointerlineskip - \copy\bframebox - \nobreak - \kern-\baselineskip - \runninglinenumbers - \def\makeLineNumber{\copy\bframebox\hss}% - } - {\par - \kern-\prevdepth - \kern\bframesep - \nointerlineskip - \@tempdima\textwidth - \advance\@tempdima 2\bframesep - \hbox{\hskip-\bframesep - \vrule\@width\@tempdima\@height\bframerule\@depth\z@}% - } - -\newdimen\bframerule -\bframerule=\fboxrule - -\newdimen\bframesep -\bframesep=\fboxsep - -\newbox\bframebox - -% \section{ -% The final touch -% } -% There is one deadcycle for each line number. - -\advance\maxdeadcycles 100 - -\endinput - -% \section{ -% The user commands -% } -% The user command to turn on and off line numbering -% are -% \begin{description}\item -% [|\linenumbers] \ \par -% Turn on line numbering in the current mode. -% \item -% [|\linenumbers*] \ \par$\qquad$ -% and reset the line number to 1. -% \def\NL{<number>]}\item -% [|\linenumbers[\NL] \ \par$\qquad$ -% and start with <number>. -% \item -% [|\nolinenumbers] \ \par -% Turn off line numbering. -% \item -% [|\runninglinenumbers*[\NL] \ \par -% Turn on ~running~ line numbers, with the same optional -% arguments as ~\linenumbers~. The numbers are running -% through the text over pagebreaks. When you turn -% numbering off and on again, the numbers will continue, -% except, of cause, if you ask to reset or preset the -% counter. -% \item -% [|\pagewiselinenumbers] \ \par -% Turn on ~pagewise~ line numbers. The lines on each -% page are numbered beginning with one at the first -% ~pagewise~ numbered line. -% \item -% [|\resetlinenumber[\NL] \ \par -% Reset ~[~Set~]~ the line number to 1 -% ~[~<number>~]~. -% \item -% [|\setrunninglinenumbers] \ \par -% Switch to ~running~ line number mode. Do \emph{not} -% turn it on or off. -% \item -% [|\setpagewiselinenumbers] \ \par -% Switch to ~pagewise~ line number mode. Do \emph{not} -% turn it on or off. -% \item -% [|\switchlinenumbers*] \ \par -% Causes margin switching in pagewise modes. With the -% star, put the line numbers on the inner margin. -% \item -% [|\leftlinenumbers*] \ \par -% \item -% [|\rightlinenumbers*] \ \par -% Set the line numbers in the left/right margin. With the -% star this works for both modes of operation, without -% the star only for the currently selected mode. -% \item -% [|\runningpagewiselinenumbers] \ \par -% When using the pagewise line number mode, do not -% subtract the page offset. This results in running -% line numbers again, but with the possibility to switch -% margins. Be careful when doing line number -% referencing, this mode status must be the same while -% setting the paragraph and during references. -% \item -% [|\realpagewiselinenumbers] \ \par -% Reverses the effect of ~\runningpagewiselinenumbers~. -% \item -% [|\modulolinenumbers[\NL] \ \par -% Give a number only to lines which are multiples of -% ~[~<number>~]~. If <number> is not specified, the -% current value in the counter ~linenumbermodulo~ is -% retained. <number>=1 turns this off without changing -% ~linenumbermodulo~. The counter is initialized to 5. -% \item -% [|\linenumberdisplaymath] \ \par -% Number the lines of a display math in a ~{linenomath}~ -% environment, but do not in a ~{linenomath*}~ -% environment. This is used by the package option -% ~[mathlines]~. -% \item -% [|\nolinenumberdisplaymath] \ \par -% Do not Number the lines of a display math in a -% ~{linenomath}~ environment, but do in a -% ~{linenomath*}~ environment. This is the default. -% \item -% [|\linelabel] \ \par -% Set a ~\linelabel{~<foo>~}~ to the line number where -% this commands is in. Refer to it with the \LaTeX\ -% referencing commands ~\ref{~<foo>~}~ and -% ~\pageref{~<foo>~}~. -% \end{description} -% The commands can be used globally, locally within groups -% or as environments. It is important to know that they -% take action only when the ~\par~ is executed. The -% ~\end{~<mode>~linenumbers}~ commands provide a ~\par~. -% Examples: -% \begin{verse} -% ~{\linenumbers~ <text> ~\par}~ \\ -% \ \\ -% ~\begin{linenumbers}~ \\ -% <text> \\ -% ~\end{linenumbers}~ \\ -% \ \\ -% <paragraph> ~{\linenumbers\par}~ \\ -% \ \\ -% ~\linenumbers~ \\ -% <text> ~\par~ \\ -% ~\nolinenumbers~ \\ -% \ \\ -% ~\linenumbers~ \\ -% <paragraph> ~{\nolinenumbers\par}~ \\ -% \end{verse} -% -% -% \subsection{ -% Customization hooks -% } -% There are several hooks to customize the appearance of the -% line numbers, and some low level hooks for special -% effects. -% \begin{description}\item -% [|\thelinenumber] \ \par -% This macro should give the representation of the line -% number in the \LaTeX-counter ~linenumber~. The -% default is provided by \LaTeX: \par$\qquad$ -% ~\arabic{linenumber}~ -% \item -% [|\makeLineNumberLeft] \ \par -% This macro is used to attach a line number to the left -% of the text page. This macro should fill an ~\hbox to 0pt~ -% which will be placed at the left margin of the -% page, with the reference point aligned to the line to -% which it should give a number. Please use the macro -% ~\LineNumber~ to refer to the line number. -% -% The default definition is \par$\qquad$ -% ~\hss\linenumberfont\LineNumber\hskip\linenumbersep~ -% \item -% [|\makeLineNumberRight] \ \par -% Like ~\makeLineNumberLeft~, but for line numbers on -% the right margin. -% -% The default definition is \par$\qquad$ -% ~\linenumberfont\hskip\linenumbersep\hskip\textwidth~ \par$\qquad$ -% ~\hbox to\linenumberwidth{\hss\LineNumber}\hss~ -% \item -% [|\linenumberfont] \ \par -% This macro is initialized to \par$\qquad$ -% ~\normalfont\tiny\sffamily~ -% \item -% [|\linenumbersep] \ \par -% This dimension register sets the separation of the -% linenumber to the text. Default value is ~10pt~. -% \item -% [|\linenumberwidth] \ \par -% This dimension register sets the width of the line -% number box on the right margin. The distance of the -% right edge of the text to the right edge of the line -% number is ~\linenumbersep~ + ~\linenumberwidth~. The -% default value is ~10pt~. -% \item -% [|\theLineNumber] (for wizards) \ \par -% This macro is called for printing a ~\newlabel~ entry -% to the aux-file. Its definition depends on the mode. -% For running line numbers it's just ~\thelinenumber~, -% while in pagewise mode, the page offset subtraction -% is done in here. -% \item -% [|\makeLineNumber] (for wizards) \ \par -% This macro produces the line numbers. The definition -% depends on the mode. In the running line numbers -% mode it just expands ~\makeLineNumberLeft~. -% \item -% [|\LineNumber] (for wizards) \ \par -% This macro is called by ~\makeLineNumber~ to typeset -% the line number. This hook is changed by the modulo -% mechanism. -% \end{description} -% \end{document}%D ------------------------------------------------------------------------------- - -echo "expect errors for unknown commands 'iffalse' and 'fi'";# SHELL -awk '/A[W]K/' lineno.sty | awk -f - lineno.sty >lineno.tex; # SHELL -latex lineno; latex lineno; latex lineno; latex lineno; # SHELL - -awk '/DOC A [W] K/' lineno.sty | awk -f - lineno.sty >lineno.doc; # DOC SH - -BEGIN{DOC=-1; # AWK DOC A W K - BEGINCODE = "\\begin{code}\\begin{verbatim}"; # AWK - ENDCODE = "\\end{verbatim}\n\\end{code}"; } # AWK - BEGINCODE = "% \\begin{macrocode}"; # DOC A W K - ENDCODE = "% \\end{macrocode}"; } # DOC A W K -/^[ \t]*$/ { ECNT++; next; } # AWK DOC A W K -/\\documentclass/{ sub("article","ltxdoc") } # DOC A W K -/%D$/ { sub("^%* *",""); sub("%D$",""); # DOC A W K - print > "lineno.drv"; next } # DOC A W K -/^%%/ { next; } # AWK DOC A W K -/^%/ { if (!DOC) { print ENDCODE; } # AWK DOC A W K - DOC=1; ECNT=0; # AWK DOC A W K - sub("^% *",""); # AWK - sub("^% *","% "); # DOC A W K - print; next; } # AWK DOC A W K -DOC<0 { next } # AWK DOC A W K -/^-+-$/ { if (!DOC) print ENDCODE; exit } # AWK DOC A W K -{ if (DOC) { ECNT=DOC=0; print BEGINCODE; } # AWK DOC A W K - while (ECNT>0) { print " "; ECNT--; } # AWK DOC A W K - print $0; } # AWK DOC A W K - diff --git a/trunk/doc/linuxtag.sty b/trunk/doc/linuxtag.sty deleted file mode 100644 index 3820886..0000000 --- a/trunk/doc/linuxtag.sty +++ /dev/null @@ -1,67 +0,0 @@ -% Modified for european a4 paper size and font size requirements for LT2K++ -% -% TEMPLATE for Usenix papers, specifically to meet requirements of -% TCL97 committee. -% originally a template for producing IEEE-format articles using LaTeX. -% written by Matthew Ward, CS Department, Worcester Polytechnic Institute. -% adapted by David Beazley for his excellent SWIG paper in Proceedings, -% Tcl 96 -% turned into a smartass generic template by De Clarke, with thanks to -% both the above pioneers -% use at your own risk. Complaints to /dev/null. -% make it two column with no page numbering, default is 10 point - -% include following in document. -%\documentclass[a4paper,10pt]{article} -%\usepackage{twocolumn,times} -%\pagestyle{empty} - -% force european A4 paper format -\setlength{\textwidth}{16.6cm} % width of main text -\setlength{\textheight}{25cm} % height of main text -\setlength{\topmargin}{-1.7in} % Subtract default offset -\addtolength{\topmargin}{2.2cm} % Topmargin -\setlength{\topskip}{0pt} % between header and text -\setlength{\headheight}{10pt} % no header -\setlength{\headsep}{10pt} % -\setlength{\oddsidemargin}{-1in} % Subtract default offset -\addtolength{\oddsidemargin}{2.2cm} % odd page left margin -\setlength{\evensidemargin}{-1in} % Subtract default offset -\addtolength{\evensidemargin}{2.2cm} % odd page left margin - -% set dimensions of columns, gap between columns, and space between paragraphs -\setlength{\columnsep}{0.25in} -\setlength{\parindent}{0pt} -\setlength{\parskip}{\baselineskip} - -% started out with art10.sty and modified params to conform to IEEE format -% further mods to conform to Usenix standard - -\makeatletter -%as Latex considers descenders in its calculation of interline spacing, -%to get 12 point spacing for normalsize text, must set it to 10 points -\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt -\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip -\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt -minus3pt\let\@listi\@listI} - -%need a 12 pt font size for subsection and abstract headings -\def\subsize{\@setsize\subsize{12pt}\xipt\@xipt} - -%make section titles bold and 12 point, 2 blank lines before, 1 after -\def\section{\@startsection {section}{1}{\z@}{18pt plus 2pt minus 2pt} -{2pt plus 2pt minus 2pt}{\large\bf}} - -%make subsection titles bold and 11 point, 1 blank line before, 1 after -\def\subsection{\@startsection {subsection}{2}{\z@}{12pt plus 2pt minus 2pt} -{12pt plus 2pt minus 2pt}{\subsize\bf}} - -\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt} -\renewcommand\tiny{\@setfontsize\tiny\@vpt\@vipt} -\renewcommand\large{\@setfontsize\large\@xiipt{12}} -\renewcommand\Large{\@setfontsize\Large\@xivpt{14}} -\renewcommand\LARGE{\@setfontsize\LARGE\@xviipt{18}} -\renewcommand\huge{\@setfontsize\huge\@xxpt{24}} -\renewcommand\Huge{\@setfontsize\Huge\@xxvpt{28}} - -\makeatother diff --git a/trunk/doc/newseg.fig b/trunk/doc/newseg.fig deleted file mode 100644 index 4a2f7ea..0000000 --- a/trunk/doc/newseg.fig +++ /dev/null @@ -1,84 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 5550 900 7425 3675 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5625 2850 6750 2850 6750 3450 5625 3450 5625 2850 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 6750 2700 6750 3600 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 6750 2850 7350 2850 7350 3450 6750 3450 6750 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 5625 1200 6750 1200 6750 1800 5625 1800 5625 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 5625 975 7350 975 7350 1950 5625 1950 5625 975 -2 1 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 2 - 6750 975 6750 1950 -2 2 0 2 0 7 50 0 44 0.000 0 0 -1 0 0 5 - 6750 1200 7350 1200 7350 1800 6750 1800 6750 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 5625 2700 7350 2700 7350 3600 5625 3600 5625 2700 -4 0 0 50 0 0 12 0.0000 4 180 885 5775 3225 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 6825 3225 .bss\001 -4 0 0 50 0 0 12 0.0000 4 180 885 5775 1575 .data ... .got\001 -4 0 0 50 0 0 12 0.0000 4 135 315 6825 1575 .bss\001 --6 -6 7950 2775 10875 3525 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 8025 2850 9000 2850 9000 3450 8025 3450 8025 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 9825 2850 9000 2850 9000 3450 9825 3450 9825 2850 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 9825 2850 10800 2850 10800 3450 9825 3450 9825 2850 -4 0 0 50 0 0 12 0.0000 4 180 780 9000 3225 .gnu.liblist\001 -4 0 0 50 0 0 12 0.0000 4 180 930 9825 3225 .gnu.conflict\001 -4 0 0 50 0 0 12 0.0000 4 180 525 8175 3225 .dynstr\001 --6 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 600 1200 2100 1200 2100 1800 600 1800 600 1200 -2 2 0 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 2100 1200 2775 1200 2775 1800 2100 1800 2100 1200 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4950 1200 2775 1200 2775 1800 4950 1800 4950 1200 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 2700 4950 2700 4950 3600 450 3600 450 2700 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 450 975 4950 975 4950 1950 450 1950 450 975 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 4950 2850 2775 2850 2775 3450 4950 3450 4950 2850 -2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 - 750 2850 2250 2850 2250 3450 750 3450 750 2850 -2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 - 8025 2700 10800 2700 10800 3600 8025 3600 8025 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 1350 1950 1500 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 3975 1950 3975 2025 3975 2100 3975 2175 3975 2250 3975 2325 - 3975 2400 3975 2475 3975 2550 3975 2625 3975 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 6150 1950 6150 2025 6150 2100 6150 2175 6150 2250 6150 2325 - 6150 2400 6150 2475 6150 2550 6150 2625 6150 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 11 - 0 0 1.00 60.00 120.00 - 6975 1950 6975 2025 6975 2100 6975 2175 6975 2250 6975 2325 - 6975 2400 6975 2475 6975 2550 6975 2625 6975 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2100 1950 8025 2700 -2 1 0 1 0 7 50 0 -1 4.000 0 0 -1 1 0 2 - 0 0 1.00 60.00 120.00 - 2775 1950 9000 2700 -4 0 0 50 0 0 12 0.0000 4 180 1335 675 1575 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 525 2175 1575 .dynstr\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 2850 1575 .gnu.version ... .eh_frame\001 -4 0 0 50 0 0 12 0.0000 4 180 1335 825 3225 .interp ... .dynsym\001 -4 0 0 50 0 0 12 0.0000 4 180 1890 2850 3225 .gnu.version ... .eh_frame\001 diff --git a/trunk/doc/prelink.8 b/trunk/doc/prelink.8 deleted file mode 100644 index 215445e..0000000 --- a/trunk/doc/prelink.8 +++ /dev/null @@ -1,333 +0,0 @@ -.TH prelink 8 "19 July 2013" -.SH NAME -prelink \- prelink ELF shared libraries and binaries to speed up startup time -.SH SYNOPSIS -prelink -.RB [OPTION...]\ [FILES] -.SH DESCRIPTION -.B prelink -is a program that modifies ELF shared libraries and ELF dynamically linked -binaries in such a way that the time needed for the dynamic linker to -perform relocations at startup significantly decreases. -Due to fewer relocations, the -run-time memory consumption decreases as well (especially the -number of unshareable pages). -The prelinking information is only used at startup time if none of the -dependent libraries have changed since prelinking; otherwise programs are -relocated normally. -.PP -.B prelink -first collects ELF binaries to be prelinked and all the ELF shared -libraries they depend on. Then it assigns a unique virtual address space -slot to each library and relinks the shared library to that base address. -When the dynamic linker attempts to load such a library, unless that virtual -address space slot is already occupied, it maps the library into the given -slot. -After this is done, -.BR prelink , -with the help of dynamic linker, resolves all relocations in the binary or -library against its dependent libraries and stores the relocations into the -ELF object. -It also stores a list of all dependent libraries together with their -checksums into the binary or library. -For binaries, it also computes a list of -.IR conflicts -(relocations that resolve differently in the binary's symbol search scope -than in the smaller search scope in which the dependent library was -resolved) and stores it into a special ELF section. -.PP -At runtime, the dynamic linker first checks whether all dependent libraries -were successfully mapped into their designated address space slots, and -whether they have not changed since the prelinking was done. -If all checks are successful, the dynamic linker just replays the list of -conflicts (which is usually significantly shorter than total number of -relocations) instead of relocating each library. -.SH OPTIONS -.TP -.B \-v\ \-\-verbose -Verbose mode. -Print the virtual address slots assigned to libraries and what binary -or library is currently being prelinked. -.TP -.B \-n\ \-\-dry\-run -Don't actually prelink anything; just collect the binaries/libraries, assign -them addresses, and with -.B \-v -print what would be prelinked. -.TP -.B \-a \-\-all -Prelink all binaries and dependent libraries found in directory hierarchies -specified in -.IR /etc/prelink.conf . -Normally, only binaries specified on the command line and their dependent -libraries are prelinked. -.TP -.B \-m \-\-conserve\-memory -When assigning addresses to libraries, allow overlap of address space slots -provided that the two libraries are not present together in any of the -binaries or libraries. This results in a smaller virtual address space range -used for libraries. On the other hand, if -.B prelink -sees a binary during incremental prelinking -which puts together two libraries which were not present -together in any other binary and were given the same virtual address space -slots, then the binary cannot be prelinked. -Without this option, -each library is assigned a unique virtual address space slot. -.TP -.B \-R \-\-random -When assigning addresses to libraries, start with a random address within -the architecture-dependent virtual address space range. -This can make some buffer overflow attacks slightly harder to exploit, -because libraries are not present on the same addresses across different -machines. -Normally, assigning virtual addresses starts at the bottom of the -architecture-dependent range. -.TP -.B \-r \-\-reloc\-only=ADDRESS -Instead of prelinking, just relink given shared libraries to the specified -base address. -.TP -.B \-N \-\-no\-update\-cache -Don't save the cache file after prelinking. -Normally, the list of libraries (and with -.B \-m -binaries also) is stored into the -.I /etc/prelink.cache -file together with their given address space slots and dependencies, so -the cache can be used during incremental prelinking (prelinking without -.B \-a -option). -.TP -.B \-c \-\-config\-file=CONFIG -Specify an alternate config file instead of default -.IR /etc/prelink.conf . -.TP -.B \-C \-\-cache\-file=CACHE -Specify an alternate cache file instead of default -.IR /etc/prelink.cache . -.TP -.B \-f \-\-force -Force re-prelinking even for already prelinked objects whose -dependencies are unchanged. -This option causes new virtual address space slots to -be assigned to all libraries. -Normally, only binaries or libraries which are either not prelinked yet, or -whose dependencies have changed, are prelinked. -.TP -.B \-q \-\-quick -Run prelink in quick mode. This mode checks just mtime and ctime timestamps -of libraries and binaries stored in the cache file. If they are unchanged -from the last prelink run, it is assumed that the library in question did -not change, without parsing or verifying its ELF headers. -.TP -.B \-p \-\-print\-cache -Print the contents of the cache file (normally -.IR /etc/prelink.cache ) -and exit. -.TP -.B \-\-dynamic\-linker=LDSO -Specify an alternate dynamic linker instead of the default. -.TP -.B \-\-ld\-library\-path=PATH -Specify a special -.IR LD_LIBRARY_PATH -to be used when -.B prelink -queries the dynamic linker about symbol resolution details. -.TP -.B \-\-ld\-preload=PATH -Specify a special -.IR LD_PRELOAD -to be used when processing the executables. Up to 20 libraries may be -added for preloading, separated by colons ( -.B : -). Using this option allows -.B prelink -to optimize the memory map for executables that use preloaded libraries. -Note: The order of libraries loaded should match the runtime environment. -.TP -.B \-\-layout\-page\-size=SIZE -Layout start of libraries at given boundary. -.TP -.B \-\-libs\-only -Only prelink ELF shared libraries, don't prelink any binaries. -.TP -.B \-h \-\-dereference -When processing command line directory arguments, follow symbolic links when -walking directory hierarchies. -.TP -.B \-l \-\-one\-file\-system -When processing command line directory arguments, limit directory tree walk -to a single file system. -.TP -.B \-\-root=PATHNAME -In a cross-compilation environment, this specifies the path to the root of -the target's file system. All other pathnames processed by -.B prelink -are relative to this root, including the name of the configuration file -as well as its contents and pathnames supplied on the command line. -.TP -.B \-u \-\-undo -Revert binaries and libraries to their original content before they were -prelinked. -Without the -.I \-a -option, this causes only the binaries and libraries specified on the command -line to be reverted to their original state (and e.g. not their -dependencies). If used together with the -.I \-a -option, all binaries and libraries from command line, all their dependencies, -all binaries found in directories specified on command line and in the config -file, and all their dependencies are undone. -.TP -.B \-y \-\-verify -Verifies a prelinked binary or library. -This option can be used only on a single binary or library. It first applies -an -.I \-\-undo -operation on the file, then prelinks just that file again and compares this -with the original file. If both are identical, it prints the file after -.I \-\-undo -operation on standard output and exits with zero status. Otherwise it exits -with error status. -Thus if -.I \-\-verify -operation returns zero exit status and its standard output is -equal to the content of the binary or library before prelinking, you can be -sure that nobody modified the binaries or libraries after prelinking. -Similarly with message digests and checksums (unless you trigger the -improbable case of modified file and original file having the same digest -or checksum). -.TP -.B \-\-md5 -This is similar to -.I \-\-verify -option, except instead of outputting the content of the binary or library -before prelinking to standard output, MD5 digest is printed. -See -.BR md5sum (1). -.TP -.B \-\-sha -This is similar to -.I \-\-verify -option, except instead of outputting the content of the binary or library -before prelinking to standard output, SHA1 digest is printed. -See -.BR sha1sum (1). -.TP -.B \-\-exec\-shield \-\-no\-exec\-shield -On IA-32, if the kernel supports Exec-Shield, prelink attempts to lay libraries -out similarly to how the kernel places them (i.e. if possible below the binary, -most widely used into the ASCII armor zone). These switches allow overriding -prelink detection of whether Exec-Shield is supported or not. -.TP -.B \-b \-\-black\-list=PATH -This option allows blacklisting certain paths, libraries or binaries. -Prelink will not touch them during prelinking. -.TP -.B \-o \-\-undo\-output=FILE -When performing an -.B \-\-undo -operation, don't overwrite the prelinked binary or library with its -original content (before it was prelinked), but save that into the specified -file. -.TP -.B \-V \-\-version -Print version and exit. -.TP -.B \-? \-\-help -Print short help and exit. -.TP -.B \-\-usage -Print short usage message. -.SH ARGUMENTS -Command-line arguments should be either directory hierarchies (in which case -.I \-l -and -.I \-h -options apply), or particular ELF binaries or shared libraries. -Specifying a shared library -explicitly on the command line causes it to be prelinked even if no binary -is linked against it. Otherwise, binaries are collected together and only -the libraries they depend on are prelinked with them. -.SH EXAMPLES -.RS -# /usr/sbin/prelink -avmR -.RE -prelinks all binaries found in directories specified in -.I /etc/prelink.conf -and all their dependent libraries, assigning libraries unique virtual -address space slots only if they ever appear together, and starts -assigning libraries at a random address. -.RS -# /usr/sbin/prelink -vm ~/bin/progx -.RE -prelinks ~/bin/progx program and all its dependent libraries (unless -they were prelinked already e.g. during -.I prelink \-a -invocation). -.RS -# /usr/sbin/prelink -au -.RE -reverts all binaries and libraries to their original content. -.RS -# /usr/sbin/prelink -y /bin/prelinked_prog > /tmp/original_prog; echo $? -verifies whether /bin/prelinked_prog is unchanged. -.SH FILES -.PD 0 -.TP 20 -.B /etc/prelink.cache -Binary file containing a list of prelinked libraries and/or binaries together -with their assigned virtual address space slots and dependencies. -You can run -.I /usr/sbin/prelink -p -to see what is stored in there. -.TP 20 -.B /etc/prelink.conf -Configuration file containing a list of directory hierarchies that -contain ELF shared libraries or binaries which should be prelinked. -This configuration file is used in -.B \-a -mode to find binaries which should be prelinked and also, no matter whether -.B \-a -is given or not, to limit which dependent shared libraries should be -prelinked. If -.B prelink -finds a dependent library of some binary or other library which is not -present in any of the directories specified either in -.B /etc/prelink.conf -or on the command line, then it cannot be prelinked. -Each line of the config file should be either a comment starting with -.BR # , -or a directory name, or a blacklist specification. Directory names can be prefixed -by the -.B \-l -switch, meaning the tree walk of the given directory is only limited to one -file system; or the -.B \-h -switch, meaning the tree walk of the given directory follows symbolic links. -A blacklist specification should be prefixed by -.B \-b -and optionally also -.B \-l -or -.B \-h -if needed. A blacklist entry can be either an absolute directory name -(in that case all files in that directory hierarchy are ignored by the -prelinker); -an absolute filename -(then that particular library or binary is skipped); -or a glob pattern without a -.B / -character in it (then all files matching that glob in any directory -are ignored). -.SH SEE ALSO -.BR ldd (1), -.BR ld.so (8). -.SH BUGS -.LP -.B prelink -Some architectures, including HPPA, are not yet supported. -.SH AUTHORS -Jakub Jelinek <jakub@redhat.com>. diff --git a/trunk/doc/prelink.conf b/trunk/doc/prelink.conf deleted file mode 100644 index 0b0e8ca..0000000 --- a/trunk/doc/prelink.conf +++ /dev/null @@ -1,35 +0,0 @@ -# This config file contains a list of directories both with binaries -# and libraries prelink should consider by default. -# If a directory name is prefixed with `-l ', the directory hierarchy -# will be walked as long as filesystem boundaries are not crossed. -# If a directory name is prefixed with `-h ', symbolic links in a -# directory hierarchy are followed. -# Directories or files with `-b ' prefix will be blacklisted. --b *.la --b *.png --b *.py --b *.pl --b *.pm --b *.sh --b *.xml --b *.xslt --b *.a --b *.js --b /lib/modules --b /usr/lib/locale --b /usr/X11R6/lib{,64}/X11/xfig --l /bin --l /usr/bin --l /sbin --l /usr/sbin --l /usr/X11R6/bin --l /usr/kerberos/bin --l /usr/games --l /usr/libexec --l /var/ftp/bin --l /lib{,64} --l /usr/lib{,64} --l /usr/X11R6/lib{,64} --l /usr/kerberos/lib{,64} --l /usr/X11R6/LessTif --l /var/ftp/lib{,64} diff --git a/trunk/doc/prelink.pdf b/trunk/doc/prelink.pdf Binary files differdeleted file mode 100644 index 0783007..0000000 --- a/trunk/doc/prelink.pdf +++ /dev/null diff --git a/trunk/doc/prelink.tex b/trunk/doc/prelink.tex deleted file mode 100644 index 5075030..0000000 --- a/trunk/doc/prelink.tex +++ /dev/null @@ -1,3643 +0,0 @@ -\documentclass[twoside]{article} - -\def\docversion{0.7} -% timezone: +01 == CET -\def\timezone{+01} -% Uncomment for draft print. -\def\isdraft{1} - -\newif\ifpdf -\ifx\pdfoutput\undefined - \pdffalse % we are not running PDFLaTeX -\else - \pdfoutput=1 % we are running PDFLaTeX - \pdftrue -\fi - -\usepackage{linuxtag} -\usepackage{times} -\usepackage{makeidx} -\usepackage{nomencl} -\usepackage[square]{natbib} -\usepackage{marvosym} -\usepackage{longtable} -\renewcommand\bibsection{\chapter{\bibname}} - -\ifpdf - \usepackage[pdftex]{graphics} - \usepackage{type1cm} - \usepackage{thumbpdf} - \pdfcompresslevel9 - \pdfinfo{/CreationDate (D:20030924012900\timezone'00')} - % The following code to set /ModDate comes from Heiko Oberdiek's paper - % one PDF & hyperref. I only added the \timezone stuff. - \begingroup - \def\twodigits#1{\ifnum#1<10 0\fi\the#1}% - \count0=\time \divide\count0 by 60 - \edef\x{\twodigits{\count0}}% - \multiply\count0 by 60 - \count1=\time \advance\count1 by -\count0 - \edef\x{\x\twodigits{\count1}}% - \edef\x{/ModDate (D:\the\year \twodigits\month \twodigits\day \x 00\timezone'00')}% - \expandafter\endgroup - \expandafter\pdfinfo\expandafter{\x}% - \input pdfcolor - - %% For a "Draft" mark on the pages uncomment the following: - \ifx\isdraft\undefined - \relax - \else - \usepackage{eso-pic} - \usepackage{color} - \makeatletter - \AddToShipoutPicture{\rm% - \setlength{\@tempdimb}{.5\paperwidth}% - \setlength{\@tempdimc}{.5\paperheight}% - \setlength{\unitlength}{1pt}% - \put(\strip@pt\@tempdimb,\strip@pt\@tempdimc){% - \makebox(0,0){\rotatebox{45}{\textcolor[gray]{0.9}{\fontsize{5cm}{5cm}\selectfont{Draft}}}} - } - } - \makeatother - \fi -\else - \usepackage[dvips]{graphics} -\fi - -\def\titlecolor{NavyBlue} -\makeatletter -\def\@sect#1#2#3#4#5#6[#7]#8{% - \ifnum #2>\c@secnumdepth - \let\@svsec\@empty - \else - \refstepcounter{#1}% - \protected@edef\@svsec{\@seccntformat{#1}\relax}% - \fi - \@tempskipa #5\relax - \ifdim \@tempskipa>\z@ - \begingroup - \hbox{\expandafter\csname\titlecolor\endcsname#6{% - \@hangfrom{\hskip #3\relax\@svsec}% - \interlinepenalty \@M #8\@@par}\Black}% - \endgroup - \csname #1mark\endcsname{#7}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7}% - \else - \def\@svsechd{% - \hbox{\expandafter\csname\titlecolor\endcsname#6{\hskip #3\relax - \@svsec #8}% - \csname #1mark\endcsname{#7}\Black}% - \addcontentsline{toc}{#1}{% - \ifnum #2>\c@secnumdepth \else - \protect\numberline{\csname the#1\endcsname}% - \fi - #7}}% - \fi - \@xsect{#5}} -\def\@ssect#1#2#3#4#5{% - \@tempskipa #3\relax - \ifdim \@tempskipa>\z@ - \begingroup - \expandafter\csname\titlecolor\endcsname#4{% - \@hangfrom{\hskip #1}% - \interlinepenalty \@M #5\@@par}\Black% - \endgroup - \else - \def\@svsechd{\expandafter\csname\titlecolor\endcsname#4{\hskip #1\relax #5}\Black}% - \fi - \@xsect{#3}} -\makeatother - -\usepackage{fancyheadings} -\pagestyle{fancy} -\rhead{} -\chead{} -\lhead{} -\rfoot[\sl Prelink]{\thepage} -\lfoot[\thepage]{\sl Jakub Jel\'\i nek} -\ifx\isdraft\undefined -\cfoot{Version \docversion} -\else -\cfoot{Draft \docversion} -\fi -\renewcommand{\headrulewidth}{0.4pt} -\renewcommand{\footrulewidth}{0.4pt} - -\ifx\isdraft\undefined -\relax -\else -\usepackage[mathlines]{lineno} -\fi - -\usepackage{graphicx} -\usepackage{hyperref} -\hypersetup{ - bookmarksnumbered, - bookmarksopen=true, - pdfpagemode=UseOutlines, - pdfkeywords={Prelink, ELF, DSO, Shared Library, Dynamic Linking, Linux} -} -\usepackage{prelinklisting} - -\def\tts#1{\texttt{\small #1}} - -\setcounter{dbltopnumber}{3} - - -\makeatletter -\newcommand{\annotate}[2][]{% - \marginpar{% - \pdfstringdef\x@title{#1}% - \edef\r{\string\r}% - \pdfstringdef\x@contents{#2}% - \pdfannot - width 50em%\linewidth - height .5\baselineskip - depth 2.5\baselineskip - { - /Subtype /Text - /T (\x@title) - /Contents (\x@contents) - }% - } - } -\makeatother - -\makeglossary -\makeindex - -\begin{document} - - \makeatletter - \newcommand\orgmaketitle{} - \let\orgmaketitle\maketitle - \def\maketitle{% - \hypersetup{ - pdftitle={\@title}, - pdfsubject={Description of prelink tool}, - pdfauthor={\@author} - }% - \orgmaketitle - } - \makeatother - -\title{Prelink} -\author{Jakub Jel\'\i nek\\ -Red Hat, Inc.\\ -{\small\tt\href{mailto:jakub@redhat.com}{jakub@redhat.com}}} - -%\maketitle - -%\tableofcontents -%\vfil\break -%\listoftables -%\vfil\break -%\listofprelinklistings -%\vfil\break -%\listoffigures -%\vfil\break - -\maketitle - -\begin{center} -\begin{abstract} -\vspace*{.5\baselineskip} -\parbox{0.8\textwidth}{% -Prelink is a tool designed to speed up dynamic linking of ELF -programs on various Linux architectures. -It speeds up start up of OpenOffice.org 1.1 by 1.8s from 5.5s on 651MHz Pentium III.} -\end{abstract} -\end{center} - -\ifx\isdraft\undefined - \relax -\else - \linenumbers - \linenumbersep4pt -\fi - -\section{Preface} - -In 1995, Linux changed its binary format from \tts{a.out} to \tts{ELF}. -The \tts{a.out} binary format was very inflexible and shared libraries -were pretty hard to build. Linux's shared libraries in \tts{a.out} are position -dependent and each had to be given a unique virtual address space slot -at link time. Maintaining these assignments was pretty hard even when -there were just a few shared libraries, there used to be a central address -registry maintained by humans in form of a text file, but it is certainly -impossible to do these days when there are thousands of different shared libraries -and their size, version and exported symbols are constantly changing. -On the other side, there was just minimum amount of work the dynamic -linker had to do in order to load these shared libraries, as relocation -handling and symbol lookup was only done at link time. The dynamic linker -used the \tts{uselib} system call which just mapped the named library -into the address space (with no segment or section protection differences, -the whole mapping was writable and executable). - -The \href{http://www.caldera.com/developers/devspecs/gabi41.pdf}% -{\tts{ELF}} -\footnote{As described in generic ABI document [1] and various processor -specific ABI supplements [2], [3], [4], [5], [6], [7], [8].} -binary format is one of the most flexible binary formats, -its shared libraries are easy to build and there is no need for a central -assignment of virtual address space slots. Shared libraries are position -independent and relocation handling and symbol lookup are done partly -at the time the executable is created and partly at runtime. Symbols in shared -libraries can be overridden at runtime by preloading a new shared -library defining those symbols or without relinking an executable by adding -symbols to a shared library which is searched up earlier during symbol -lookup or by adding new dependent shared libraries to a library used by the -program. All these improvements have their price, which is a slower -program startup, more non-shareable memory per process and runtime cost -associated with position independent code in shared libraries. - -Program startup of \tts{ELF} programs is slower than startup of \tts{a.out} -programs with shared libraries, because the dynamic linker has much more work -to do before calling program's entry point. The cost of loading libraries -is just slightly bigger, as \tts{ELF} shared libraries have typically -separate read-only and writable segments, so the dynamic linker -has to use different memory protection for each segment. -The main difference is in relocation handling and associated symbol lookup. -In the \tts{a.out} format there was no relocation handling or symbol lookup at runtime. -In \tts{ELF}, this cost is much more important today than it used to be -during \tts{a.out} to \tts{ELF} transition in Linux, as especially GUI -programs keep constantly growing and start to use more and more shared -libraries. 5 years ago programs using more than 10 shared libraries -were very rare, these days most of the GUI programs link against around -40 or more shared and in extreme cases programs use even more than 90 -shared libraries. Every shared library adds its set of dynamic relocations -to the cost and enlarges symbol search scope, -\nomenclature{Symbol Search Scope}{The sequence of \tts{ELF} objects in -which a symbol is being looked up. When a symbol definition is found, -the searching stops and the found symbol is returned. Each program -has a global search scope, which starts by the executable, is typically -followed by the immediate dependencies of the executable and then their -dependencies in breadth search order (where only first occurrence -of each shared library is kept). If \tts{DT\_FILTER} -or \tts{DT\_AUXILIARY} dynamic tags are used the order is slightly -different. Each shared library loaded with \tts{dlopen} has its -own symbol search scope which contains that shared library and -its dependencies. \tts{Prelink} operates also with natural -symbol search scope of each shared library, which is the global -symbol search scope the shared library would have if it were started -as the main program} -so in addition to doing more symbol lookups, each symbol -lookup the application has to perform is on average more expensive. -Another factor increasing the cost is the length of symbol names -which have to be compared when finding symbol in the symbol hash table of -a shared library. C++ libraries tend to have extremely long symbol -names and unfortunately the new \href{http://www.codesourcery.com/cxx-abi/}% -{C++ ABI} puts namespaces and class names first and method names last -in the mangled names, so often symbol names differ only in last -few bytes of very long names. - -Every time a relocation is applied the entire memory page -\nomenclature{Page}{Memory block of fixed size which virtual memory -subsystem deals with as a unit. The size of the page depends on -the addressing hardware of the processor, typically pages are 4K or 8K, -in some cases bigger} -containing the address which is written to must be loaded into memory. -The operating system does a copy-on-write operation which also has the -consequence that the physical memory of the memory page cannot anymore -be shared with other processes. -With \tts{ELF}, typically all of program's Global Offset Table, -\nomenclature{Global Offset Table (\tts{GOT})}{When position independent -code needs to build address which requires dynamic relocation, instead -of building it as constant in registers and applying a dynamic relocation -against the read-only segment (which would mean that any pages of the -read-only segment where relocations are applied cannot be shared between -processes anymore), it loads the address from an offset table -private to each shared library, which is created by the linker. -The table is in writable segment and relocations are applied against it. -Position independent code uses on most architectures a special \tts{PIC} -register which points to the start of the Global Offset Table} -constants and variables containing pointers to objects in shared libraries, etc. -are written into before the dynamic linker passes control over to the program. - -On most architectures (with some exceptions like \tts{AMD64} architecture) -position independent code requires that one register needs to be dedicated as -\tts{PIC} register and thus cannot be used in the functions for other purposes. -This especially degrades performance on register-starved -architectures like \tts{IA-32}. Also, there needs to be some code to -set up the \tts{PIC} register, either invoked as part of function prologues, -or when using function descriptors in the calling sequence. - -\tts{Prelink} is a tool which (together with corresponding dynamic linker -and linker changes) attempts to bring back some of the \tts{a.out} -advantages (such as the speed and less COW'd pages) to the \tts{ELF} -binary format while retaining all of its flexibility. In a limited way -it also attempts to decrease number of non-shareable pages created by -relocations. -\tts{Prelink} works closely with the dynamic linker in the GNU C library, -but probably it wouldn't be too hard to port it to some other \tts{ELF} -using platforms where the dynamic linker can be modified in similar -ways. - -\section{Caching of symbol lookup results} - -Program startup can be speeded up by caching of symbol lookup -results\footnote{Initially, this has been implemented in the \tts{prelink} -tool and \tts{glibc} dynamic linker, where \tts{prelink} was sorting -relocation sections of existing executables and shared libraries. -When this has been implemented in the linker as well and most executables -and shared libraries are already built with \tts{-z combreloc}, -the code from \tts{prelink} has been removed, as it was no longer -needed for most objects and just increasing the tool's complexity.}. -Many shared libraries need more than one lookup of a particular symbol. -This is especially true for C++ shared libraries, where e.g. the same method -is present in multiple virtual tables or {\sl RTTI} data structures. -\nomenclature{RTTI}{C++ runtime type identification} -Traditionally, each \tts{ELF} section which needs dynamic relocations has an -associated \tts{.rela*} or \tts{.rel*} section (depending on whether -the architecture is defined to use \tts{RELA} or \tts{REL} relocations). -\nomenclature{RELA}{Type of relocation structure which includes offset, -relocation type, symbol against which the relocation is and an integer -addend which is added to the symbol. Memory at offset is not supposed -to be used by the relocation. Some architectures got this implemented -incorrectly and memory at offset is for some relocation types used -by the relocation, either in addition to addend or addend is not used -at all. \tts{RELA} relocations are generally better for \tts{prelink}, -since when \tts{prelink} stores a pre-computed value into the memory location -at offset, the addend value is not lost} -\nomenclature{REL}{Type of relocation structure which includes just offset, -relocation type and symbol. Addend is taken from memory location at -offset} -The relocations in those sections are typically sorted by ascending -\tts{r\_offset} values. -Symbol lookups are usually the most expensive operation during program -startup, so caching the symbol lookups has potential to decrease time -spent in the dynamic linker. -One way to decrease the cost of symbol lookups is to create a table with the -size equal to number of entries -in dynamic symbol table (\tts{.dynsym}) in the dynamic linker when resolving -a particular shared library, but that would in some cases need a lot of -memory and some time spent in initializing the table. Another option -would be to use a hash table with chained lists, but that needs both -extra memory and would also take extra time for computation of the hash value -and walking up the chains when doing new lookups. -Fortunately, neither of this is really necessary if we modify the linker -to sort relocations so that relocations against the same symbol -are adjacent. This has been done first in the \tts{Sun} linker and dynamic -linker, so the GNU linker and dynamic linker use the same \tts{ELF} extensions -and linker flags. Particularly, the following new \tts{ELF} dynamic tags have been introduced: - -\tts{\#define DT\_RELACOUNT 0x6ffffff9}\\ -\tts{\#define DT\_RELCOUNT 0x6ffffffa} - -New options \tts{-z combreloc} and \tts{-z nocombreloc} have been -added to the linker. The latter causes the previous linker behavior, -i.e. each section requiring relocations has a corresponding relocation section, -which is sorted by ascending \tts{r\_offset}. \tts{-z combreloc} -\footnote{\tts{-z combreloc} is the default in GNU linker versions -2.13 and later.} instructs the linker to create just one relocation -section for dynamic relocations other than symbol jump table (\tts{PLT}) -relocations. -\nomenclature{PLT}{Process Linkage Table. Stubs in \tts{ELF} shared -libraries and executables which allow lazy relocations of function calls. -They initially point to code which will do the symbol lookup. The -result of this symbol lookup is then stored in the Process Linkage Table -and control transfered to the address symbol lookup returned. All -following calls to the \tts{PLT} slot just branch to the already looked -up address directly, no further symbol lookup is needed} -This single relocation section (either \tts{.rela.dyn} or \tts{.rel.dyn}) -is sorted, so that relative relocations come first (sorted by ascending -\tts{r\_offset}), followed by other relocations, sorted again by ascending -\tts{r\_offset}. If more relocations are against the same -symbol, they immediately follow the first relocation against that symbol -with lowest \tts{r\_offset}. -\footnote{In fact the sorting needs to take into account also the type of -lookup. Most of the relocations will resolve to a \tts{PLT} slot in the executable -if there is one for the lookup symbol, because the executable might have a -pointer against that symbol without any dynamic relocations. But e.g. -relocations used for the \tts{PLT} slots must avoid these.}. -\nomenclature{relative relocation}{Relocation, which doesn't need a symbol -lookup, just adds a shared library load offset to certain memory location -(or locations)} -The number of relative relocations at the beginning of the section -is stored in the \tts{DT\_RELACOUNT} resp. \tts{DT\_RELCOUNT} dynamic tag. - -The dynamic linker can use the new dynamic tag for two purposes. -If the shared library is successfully mapped at the same address -as the first \tts{PT\_LOAD} segment's virtual address, the load offset -is zero and the dynamic linker can avoid all the relative relocations which -would just add zero to various memory locations. Normally shared libraries are -linked with first \tts{PT\_LOAD} segment's virtual address set to zero, so -the load offset is non-zero. This can be changed through a linker script or by -using a special \tts{prelink} option \tts{--reloc-only} to change -the base address of a shared library. All prelinked shared libraries -have non-zero base address as well. If the load offset is non-zero, the -dynamic linker can still make use of this dynamic tag, as relative -relocation handling is typically way simpler than handling other -relocations (since symbol lookup is not necessary) and thus it can -handle all relative relocations in a tight loop in one place and -then handle the remaining relocations with the fully featured -relocation handling routine. The second and more important point is -that if relocations against the same symbol are adjacent, the dynamic -linker can use a cache with single entry. - -The dynamic linker in \tts{glibc}, if it sees \tts{statistics} -as part of the \tts{LD\_DEBUG} environment variable, displays statistics -which can show how useful this optimization is. -Let's look at some big C++ application, e.g. konqueror. -If not using the cache, the statistics looks like this: - -\noindent{\small\begin{verbatim} -18000: runtime linker statistics: -18000: total startup time in dynamic loader: 270886059 clock cycles -18000: time needed for relocation: 266364927 clock cycles (98.3%) -18000: number of relocations: 79067 -18000: number of relocations from cache: 0 -18000: number of relative relocations: 31169 -18000: time needed to load objects: 4203631 clock cycles (1.5%) -\end{verbatim}} - -This program run is with hot caches, on non-prelinked system, with lazy -binding. -\nomenclature{Lazy Binding}{A way to postpone symbol lookups for calls until -a function is called for the first time in particular shared library. -This decreases number of symbol lookups done during startup and symbols -which are never called don't need to be looked up at all. Calls requiring -relocations jump into \tts{PLT}, which is initially set up so that a -function in the dynamic linker is called to do symbol lookup. The looked -up address is then stored either into the \tts{PLT} slot directly -(if \tts{PLT} is writable) or into \tts{GOT} entry corresponding -to the \tts{PLT slot} and any subsequent calls already go directly to that -address. Lazy binding can be turned off by setting \tts{LD\_BIND\_NOW=1} -in the environment. Prelinked programs never use lazy binding for the -executable or any shared libraries not loaded using \tts{dlopen}} -The numbers show that the dynamic linker spent most of its time -in relocation handling and especially symbol lookups. If using symbol -lookup cache, the numbers look different: - -\noindent{\small\begin{verbatim} -18013: total startup time in dynamic loader: 132922001 clock cycles -18013: time needed for relocation: 128399659 clock cycles (96.5%) -18013: number of relocations: 25473 -18013: number of relocations from cache: 53594 -18013: number of relative relocations: 31169 -18013: time needed to load objects: 4202394 clock cycles (3.1%) -\end{verbatim}} - -On average, for one real symbol lookup there were two cache hits and total -time spent in the dynamic linker decreased by 50\%. - -\section{Prelink design} - -\tts{Prelink} was designed, so that it requires as few \tts{ELF} extensions -as possible. It should not be tied to a particular architecture, but -should work on all \tts{ELF} architectures. During program startup it -should avoid all symbol lookups which, as has been shown above, are -very expensive. It needs to work in an environment where shared -libraries and executables are changing from time to time, whether it is -because of security updates or feature enhancements. It should avoid big code -duplication between the dynamic linker and the tool. And prelinked -shared libraries need to be usable even in non-prelinked executables, -or when one of the shared libraries is upgraded and the prelinking of the -executable has not been updated. - -To minimize the number of performed relocations during startup, -the shared libraries (and executables) need to be relocated -already as much as possible. For relative relocations this means the library -needs to be loaded always at the same base address, for other relocations -this means all shared libraries with definitions those relocations resolve -to (often this includes all shared libraries the library or executable depends on) -must always be loaded at the same addresses. \tts{ELF} executables -(with the exception of {\sl Position Independent Executables}) -\nomenclature{Position Independent Executable}{A hybrid between -classical \tts{ELF} executables and \tts{ELF} shared libraries. -It has a form of a \tts{ET\_DYN} object like shared libraries and should -contain position independent code, so that the kernel can load -the executable starting at random address to make certain security attacks -harder. Unlike shared libraries it contains \tts{DT\_DEBUG} dynamic -tag, must have \tts{PT\_INTERP} segment with dynamic linker's path, -must have meaningful code at its \tts{e\_entry} and can use symbol -lookup assumptions normal executables can make, particularly that -no symbol defined in the executable can be overridden by a shared -library symbol} have their load address fixed already during linking. -For shared libraries, \tts{prelink} needs something similar to \tts{a.out} -registry of virtual address space slots. Maintaining such registry -across all installations wouldn't scale well, so \tts{prelink} instead -assigns these virtual address space slots on the fly after looking at -all executables it is supposed to speed up and all their dependent shared -libraries. The next step is to actually relocate shared libraries -to the assigned base address. - -When this is done, the actual prelinking of shared libraries can be done. -First, all dependent shared libraries need to be prelinked (\tts{prelink} -doesn't support circular dependencies between shared libraries, will just -warn about them instead of prelinking the libraries in the cycle), then for each -relocation in the shared library \tts{prelink} needs to look up the symbol -in natural symbol search scope of the shared library (the shared library -itself first, then breadth first search of all dependent shared libraries) and -apply the relocation to the symbol's target section. The symbol lookup code -in the dynamic linker is quite complex and big, so to avoid duplicating all -this, \tts{prelink} has chosen to use dynamic linker to do the symbol lookups. -Dynamic linker is told via a special environment variable it should print -all performed symbol lookups and their type and \tts{prelink} reads this -output through a pipe. As one of the requirements was that -prelinked shared libraries must be usable even for non-prelinked executables -(duplicating all shared libraries so that there are pristine and prelinked -copies would be very unfriendly to RAM usage), \tts{prelink} has to ensure -that by applying the relocation no information is lost and thus relocation -processing can be cheaply done at startup time of non-prelinked executables. -For \tts{RELA} architectures this is easier, because the content -of the relocation's target memory is not needed when processing the relocation. -\footnote{Relative relocations on certain \tts{RELA} architectures use -relocation target's memory, either alone or together with \tts{r\_addend} -field.} For \tts{REL} architectures this is not the case. -\tts{prelink} attempts some tricks described -later and if they fail, needs to convert the \tts{REL} relocation section -to \tts{RELA} format where addend is stored in the relocation section -instead of relocation target's memory. - -When all shared libraries an executable (directly or indirectly) depends on -are prelinked, relocations in the executable are handled similarly to -relocations in shared libraries. Unfortunately, not all symbols resolve the -same when looked up in a shared library's natural symbol search scope -(i.e. as it is done at the time the shared library is prelinked) and when -looked up in application's global symbol search scope. Such symbols are -herein called {\sl conflicts} and the relocations against those symbols -{\sl conflicting relocations}. Conflicts depend on the executable, all its -shared libraries and their respective order. They are only computable -for the shared libraries linked to the executable (libraries mentioned in -\tts{DT\_NEEDED} dynamic tags and shared libraries they transitively need). -The set of shared libraries loaded via \tts{dlopen(3)} cannot be predicted -by \tts{prelink}, neither can the order in which this happened, nor the time -when they are unloaded. When the dynamic linker prints symbol lookups -done in the executable, it also prints conflicts. \tts{Prelink} then -takes all relocations against those symbols and builds a special -\tts{RELA} section with conflict fixups and stores it into the -prelinked executable. Also a list of all dependent shared libraries -in the order they appear in the symbol search scope, together -with their checksums and times of prelinking is stored in another special -section. - -The dynamic linker first checks if it is itself prelinked. If yes, -it can avoid its preliminary relocation processing (this one is done -with just the dynamic linker itself in the search scope, so that -all routines in the dynamic linker can be used easily without too many -limitations). When it is about to start a program, it first looks -at the library list section created by \tts{prelink} (if any) and -checks whether they are present in symbol search scope in the same -order, none have been modified since prelinking and that there aren't any -new shared libraries loaded either. If all these conditions are -satisfied, prelinking can be used. In that case the dynamic linker -processes the fixup section and skips all normal relocation handling. -If one or more of the conditions are not met, the dynamic linker continues -with normal relocation processing in the executable and all shared libraries. - -\section{Collecting executables and libraries which should be prelinked} - -Before the actual work can start the \tts{prelink} tool needs to collect the -filenames of executables and libraries it is supposed to prelink. -It doesn't make any sense to prelink a shared library if no executable is -linked against it because the prelinking information will not be used anyway. -Furthermore, when \tts{prelink} needs to do a \tts{REL} to \tts{RELA} -conversion of relocation sections in the shared library (see later) -or when it needs to convert \tts{SHT\_NOBITS} \tts{PLT} section to -\tts{SHT\_PROGBITS}, a prelinked shared library might grow in size and so -prelinking is only desirable if it will speed up startup of some -program. The only change which might be useful even for shared libraries -which are never linked against, only loaded using \tts{dlopen}, is -relocating to a unique address. This is useful if there are many relative -relocations and there are pages in the shared library's writable segment -which are never written into with the exception of those relative -relocations. Such shared libraries are rare, so \tts{prelink} doesn't -handle these automatically, instead the administrator or developer can -use \tts{prelink --reloc-only={\sl ADDRESS}} to relocate it manually. -Prelinking an executable requires all shared libraries it is linked against -to be prelinked already. - -\tts{Prelink} has two main modes in which it collects filenames. -One is {\sl incremental prelinking}, where \tts{prelink} is invoked without -the \tts{-a} option. In this mode, \tts{prelink} queues for prelinking -all executables and shared libraries given on the command line, all executables -in directory trees specified on the command line, and all shared libraries -those executables and shared libraries are linked against. -For the reasons mentioned earlier a shared library is queued only if a -program is linked with it or the user tells the tool to do it anyway -by explicitly mentioning it on the command line. -The second mode is {\sl full prelinking}, where the \tts{-a} option is -given on the command line. This in addition to incremental prelinking -queues all executables found in directory trees specified in \tts{prelink.conf} -(which typically includes all or most directories where system executables -are found). For each directory subtree in the config file the user -can specify whether symbolic links to places outside of the tree are to be followed -or not and whether searching should continue even across filesystem -boundaries. - -There is also an option to blacklist some executables or directory trees -so that the executables or anything in the directory trees will not -be prelinked. This can be specified either on the command line or in -the config file. - -\tts{Prelink} will not attempt to change executables which use a non-standard -dynamic linker -\footnote{Standard dynamic linker path is hardcoded in the executable for each -architecture. It can be overridden from the command line, but only with -one dynamic linker name (normally, multiple standard dynamic linkers are -used when prelinking mixed architecture systems).} -for security reasons, because it actually needs to execute the dynamic -linker for symbol lookup and it needs to avoid executing some random -unknown executable with the permissions with which \tts{prelink} is run -(typically \tts{root}, with the permissions at least for changing all -executables and shared libraries in the system). The administrator should -ensure that \tts{prelink.conf} doesn't contain world-writable directories -and such directories are not given to the tool on the command line either, -but the tool should be distrustful of the objects nevertheless. - -Also, \tts{prelink} will not change shared libraries which are not specified -directly on the command line or located in the directory trees specified on the -command line or in the config file. This is so that -e.g. \tts{prelink} doesn't try to change shared libraries on shared -networked filesystems, or at least it is possible to configure the tool -so that it doesn't do it. - -For each executable and shared library it collects, \tts{prelink} executes -the dynamic linker to list all shared libraries it depends on, checks if -it is already prelinked and whether any of its dependencies changed. -Objects which are already prelinked and have no dependencies which changed -don't have to be prelinked again (with the exception when e.g. virtual -address space layout code finds out it needs to assign new virtual address space slots -for the shared library or one of its dependencies). Running the dynamic -linker to get the symbol lookup information is a quite costly -operation especially on systems with many executables and shared libraries -installed, so \tts{prelink} offers a faster \tts{-q} mode. In all modes, -\tts{prelink} stores modification and change times of each shared library -and executable together with all object dependencies and other information -into \tts{prelink.cache} file. When prelinking in \tts{-q} mode, it -just compares modification and change times of the executables and shared -libraries (and all their dependencies). Change time is needed because -\tts{prelink} preserves modification time when prelinking (as well as -permissions, owner and group). If the times match, it assumes the -file has not changed since last prelinking. Therefore the file can be -skipped if it is already prelinked and none of the dependencies changed. -If any time changed or one of the dependencies changed, it invokes the -dynamic linker the same way as in normal mode to find out real dependencies, -whether it has been prelinked or not etc. The collecting phase in normal -mode can take a few minutes, while in quick mode usually takes just a few -seconds, as the only operation it does is it calls just lots of \tts{stat} -system calls. - -\section{Assigning virtual address space slots} - -\tts{Prelink} has to ensure at least that for all successfully prelinked -executables all shared libraries they are (transitively) linked against -have non-overlapping virtual address space slots (furthermore they -cannot overlap with the virtual address space range used by the executable -itself, its \tts{brk} area, typical stack location and \tts{ld.so.cache} -and other files mmaped by the dynamic linker in early stages of dynamic -linking (before all dependencies are mmaped). If there were any overlaps, -the dynamic linker (which mmaps the shared libraries at the desired location -without \tts{MAP\_FIXED} mmap flag so that it is only soft requirement) would -not manage to mmap them at the assigned locations and the prelinking -information would be invalidated (the dynamic linker would have to do all -normal relocation handling and symbol lookups). Executables are linked against -very wide variety of shared library combinations and that has to be taken -into account. - -The simplest approach is to sort shared libraries by descending -usage count (so that most often used shared libraries like the dynamic -linker, \tts{libc.so} etc. are close to each other) and assign them -consecutive slots starting at some architecture specific base address -(with a page or two in between the shared libraries to allow for a limited -growth of shared libraries without having to reposition them). -\tts{Prelink} has to find out which shared libraries will need -a \tts{REL} to \tts{RELA} conversion of relocation sections -and for those which will need the conversion count with the increased size -of the library's loadable segments. This is \tts{prelink} behavior without -\tts{-m} and \tts{-R} options. - -The architecture specific base address is best located a few megabytes above -the location where \tts{mmap} with \tts{NULL} first argument and without -\tts{MAP\_FIXED} starts allocating memory areas (in Linux this is the value -of \tts{TASK\_UNMAPPED\_BASE} macro). -\footnote{\tts{TASK\_UNMAPPED\_BASE} has been chosen -on each platform so that there is enough virtual memory for both the -\tts{brk} area (between executable's end and this memory address) and \tts{mmap} -area (between this address and bottom of stack).} The reason for not -starting to assign addresses in \tts{prelink} immediately at -\tts{TASK\_UNMAPPED\_BASE} is that \tts{ld.so.cache} and other mappings by -the dynamic linker will end up in the same range and could overlap with -the shared libraries. Also, if some application uses \tts{dlopen} to load -a shared library which has been prelinked, -\footnote{Typically this is because some other executable is linked against that -shared library directly.} -those few megabytes above \tts{TASK\_UNMAPPED\_BASE} increase the probability -that the stack slot will be still unused (it can clash with e.g. -non-prelinked shared libraries loaded by \tts{dlopen} earlier -\footnote{If shared libraries have first \tts{PT\_LOAD} segment's virtual -address zero, the kernel typically picks first empty slot above -\tts{TASK\_UNMAPPED\_BASE} big enough for the mapping.} or other kinds -of mmap calls with \tts{NULL} first argument like \tts{malloc} allocating -big chunks of memory, mmaping of locale database, etc.). - -This simplest approach is unfortunately problematic on 32-bit (or 31-bit) -architectures where the total virtual address space for a process is -somewhere between 2GB (S/390) and almost 4GB (Linux IA-32 4GB/4GB kernel -split, AMD64 running 32-bit processes, etc.). Typical installations these -days contain thousands of shared libraries and if each of them is given a -unique address space slot, on average executables will have pretty sparse -mapping of its shared libraries and there will be less contiguous virtual -memory for application's own use -\footnote{Especially databases look these days for every byte of virtual -address space on 32-bit architectures.}. - -\tts{Prelink} has a special mode, turned on with \tts{-m} option, in which -it computes what shared libraries are ever loaded together in some executable -(not considering \tts{dlopen}). If two shared libraries are ever loaded -together, \tts{prelink} assigns them different virtual address space slots, -but if they never appear together, it can give them overlapping addresses. -For example applications using \tts{KDE} toolkit link typically against many -\tts{KDE} shared libraries, programs written using the \tts{Gtk+} toolkit -link typically against many \tts{Gtk+} shared libraries, but there are just -very few programs which link against both \tts{KDE} and \tts{Gtk+} shared -libraries, and even if they do, they link against very small subset of those -shared libraries. So all \tts{KDE} shared libraries not in that subset can -use overlapping addresses with all \tts{Gtk+} shared libraries but the -few exceptions. This leads to considerably smaller virtual address space -range used by all prelinked shared libraries, but it has its own -disadvantages too. It doesn't work too well with incremental prelinking, -because then not all executables are investigated, just those which are given -on \tts{prelink}'s command line. \tts{Prelink} also considers executables -in \tts{prelink.cache}, but it has no information about executables which have -not been prelinked yet. If a new executable, which links against some shared -libraries which never appeared together before, is prelinked later, -\tts{prelink} has to assign them new, non-overlapping addresses. -This means that any executables, which linked against the library -that has been moved and re-prelinked, need to be prelinked again. -If this happened during incremental prelinking, \tts{prelink} will -fix up only the executables given on the command line, leaving other -executables untouched. The untouched executables would not be able to -benefit from prelinking anymore. - -Although with the above two layout schemes shared library addresses can -vary slightly between different hosts running the same distribution -(depending on the exact set of installed executables and libraries), especially -the most often used shared libraries will have identical base addresses -on different computers. This is often not desirable for security reasons, -because it makes it slightly easier for various exploits to jump to routines -they want. Standard Linux kernels assign always the same addresses to -shared libraries loaded by the application at each run, so with these -kernels \tts{prelink} doesn't make things worse. But there are kernel -patches, such as Red Hat's \tts{Exec-Shield}, which randomize memory -mappings on each run. If shared libraries are prelinked, they cannot -be assigned different addresses on each run (prelinking information can -be only used to speed up startup if they are mapped at the base addresses -which was used during prelinking), which -means prelinking might not be desirable on some edge servers. -\tts{Prelink} can assign different addresses on different hosts though, -which is almost the same as assigning random addresses on each run -for long running processes such as daemons. Furthermore, the administrator -can force full prelinking and assignment of new random addresses every few -days (if he is also willing to restart the services, so that the old -shared libraries and executables don't have to be kept in memory). - -To assign random addresses \tts{prelink} has the \tts{-R} option. -This causes a random starting address somewhere in the architecture specific -range in which shared libraries are assigned, and minor random reshuffling -in the queue of shared libraries which need address assignment (normally -it is sorted by descending usage count, with randomization shared libraries -which are not very far away from each other in the sorted list can be -swapped). The \tts{-R} option should work orthogonally to the \tts{-m} -option. - -Some architectures have special further requirements on shared library -address assignment. On 32-bit PowerPC, if shared libraries are located -close to the executable, so that everything fits into 32MB area, \tts{PLT} -slots resolving to those shared libraries can use the branch relative -instruction instead of more expensive sequences involving memory load -and indirect branch. If shared libraries are located in the -first 32MB of address space, \tts{PLT} slots resolving to those shared -libraries can use the branch absolute instruction (but already \tts{PLT} -slots in those shared libraries resolving to addresses in the executable -cannot be done cheaply). This means for optimization \tts{prelink} -should assign addresses from a 24MB region below the executable first, assuming -most of the executables are smaller than those remaining 8MB. -\tts{prelink} assigns these from higher to lower addresses. When this -region is full, \tts{prelink} starts from address 0x40000 -\footnote{To leave some pages unmapped to catch \tts{NULL} pointer -dereferences.} up till the bottom of the first area. Only when -all these areas are full, \tts{prelink} starts picking addresses high above -the executable, so that sufficient space is left in between to leave room -for \tts{brk}. -When \tts{-R} option is specified, \tts{prelink} needs to honor it, but -in a way which doesn't totally kill this optimization. So it picks up -a random start base within each of the 3 regions separately, splitting -them into 6 regions. - -Another architecture which needs to be handled specially is IA-32 -when using \tts{Exec-Shield}. The IA-32 architecture doesn't have an -bit to disable execution for each page, only for each segment. All readable -pages are normally executable. This means the stack is usually executable, -as is memory allocated by \tts{malloc}. This is undesirable for security reasons, -exploits can then overflow a buffer on the stack to transfer control -to code it creates on the stack. -Only very few programs actually need an executable stack. For example -programs using GCC trampolines for nested functions need it or when -an application itself creates executable code on the stack and calls it. -\tts{Exec-Shield} works around this IA-32 architecture deficiency -by using a separate code segment, which starts at address 0 and spans -address space until its limit, highest page which needs to -be executable. This is dynamically changed when some page with higher -address than the limit needs to be executable (either because of \tts{mmap} -with \tts{PROT\_EXEC} bit set, or \tts{mprotect} with \tts{PROT\_EXEC} -of an existing mapping). This kind of protection is of course only -effective if the limit is as low as possible. The kernel tries to -put all new mappings with \tts{PROT\_EXEC} set and \tts{NULL} address low. -If possible into {\sl ASCII Shield area} (first 16MB of address space) -\nomenclature{ASCII Shield area}{First 16MB of address space on 32-bit -architectures. These addresses have zeros in upper 8 bits, -which on little endian architectures are stored as last byte of the address -and on big endian architectures as first byte of the address. -A zero byte terminates string, so it is hard to control the exact -arguments of a function if they are placed on the stack above the -address. On big endian machines, it is even hard to control the -low 24 bits of the address}, if not, at least below the executable. -If \tts{prelink} detects \tts{Exec-Shield}, it tries to do the same as -kernel when assigning addresses, i.e. prefers to assign addresses in -{\sl ASCII Shield area} and continues with other addresses below -the program. It needs to leave first 1MB plus 4KB of address space -unallocated though, because that range is often used by programs -using \tts{vm86} system call. - -\section{Relocation of libraries} - -When a shared library has a base address assigned, it needs to be relocated -so that the base address is equal to the first \tts{PT\_LOAD} segment's -\tts{p\_vaddr}. The effect of this operation should be bitwise identical -as if the library were linked with that base address originally. -That is, the following scripts should produce identical output: - -\noindent{{\small\begin{verbatim} -$ gcc -g -shared -o libfoo.so.1.0.0 -Wl,-h,libfoo.so.1 \ - input1.o input2.o somelib.a -$ prelink --reloc-only=0x54321000 libfoo.so.1.0.0 -\end{verbatim} -\prelinklistingcaption{Script to relocate a shared library after linking using \tts{prelink}}} - -and: -\noindent{\small\begin{verbatim} -$ gcc -shared -Wl,--verbose 2>&1 > /dev/null \ - | sed -e '/^======/,/^======/!d' \ - -e '/^======/d;s/0\( + SIZEOF_HEADERS\)/0x54321000\1/' \ - > libfoo.so.lds -$ gcc -Wl,-T,libfoo.so.lds -g -shared -o libfoo.so.1.0.0 \ - -Wl,-h,libfoo.so.1 input1.o input2.o somelib.a -\end{verbatim}} -\prelinklistingcaption{Script to link a shared library at non-standard base}} - -The first script creates a normal shared library with the default -base address 0 and then uses \tts{prelink}'s special mode when it just -relocates a library to a given address. The second script first modifies -a built-in GNU linker script for linking of shared libraries, so that -the base address is the one given instead of zero and stores it into a -temporary file. Then it creates a shared library using that linker script. - -The relocation operation involves mostly adding the difference between -old and new base address to all \tts{ELF} fields which contain values -representing virtual addresses of the shared library -(or in the program header table also representing physical addresses). -File offsets need to be unmodified. Most places where the adjustments -need to be done are clear, \tts{prelink} just has to watch \tts{ELF} spec -to see which fields contain virtual addresses. - -One problem is with absolute symbols. \tts{Prelink} has no way to find -out if an absolute symbol in a shared library is really meant as -absolute and thus not changing during relocation, or if it is an address -of some place in the shared library outside of any section or on their -edge. For instance symbols created in the GNU linker's script outside -of section directives have all \tts{SHN\_ABS} section, yet they can be -location in the library (e.g. \tts{symbolfoo~=~.}) or they can be absolute -(e.g. \tts{symbolbar~=~0x12345000}). This distinction is lost at link -time. But the dynamic linker when looking up symbols doesn't make any -distinction between them, all addresses during dynamic lookup have the -load offset added to it. \tts{Prelink} chooses to relocate any absolute -symbols with value bigger than zero, that way \tts{prelink --reloc-only} -gets bitwise identical output with linking directly at the different base -in almost all real-world cases. Thread Local Storage symbols (those with -\tts{STT\_TLS} type) are never relocated, as their values are relative -to start of shared library's thread local area. - -When relocating the dynamic section there are no bits which tell if -a particular dynamic tag uses \tts{d\_un.d\_ptr} (which needs to -be adjusted) or \tts{d\_un.d\_val} (which needs to be left as is). -So \tts{prelink} has to hardcode a list of well known architecture -independent dynamic tags which need adjusting and have a hook for -architecture specific dynamic tag adjustment. Sun came up with -\tts{DT\_ADDRRNGLO} to \tts{DT\_ADDRRNGHI} and \tts{DT\_VALRNGLO} -to \tts{DT\_VALRNGHI} dynamic tag number ranges, so at least as -long as these ranges are used for new dynamic tags \tts{prelink} -can relocate correctly even without listing them all explicitly. - -When relocating \tts{.rela.*} or \tts{.rel.*} sections, which is -done in architecture specific code, relative relocations and on \tts{.got.plt} -using architectures also \tts{PLT} relocations typically need an -adjustment. The adjustment needs to be done in either \tts{r\_addend} field -of the \tts{ElfNN\_Rela} structure, in the memory pointed by \tts{r\_offset}, -or in both locations. -On some architectures what needs adjusting is not even the same for all relative relocations. -Relative relocations against some sections need to have \tts{r\_addend} -adjusted while others need to have memory adjusted. -On many architectures, first few words in \tts{GOT} are special and some -of them need adjustment. - -The hardest part of the adjustment is handling the debugging sections. -These are non-allocated sections which typically have no corresponding -relocation section associated with them. \tts{Prelink} has to match the various -debuggers in what fields it adjusts and what are skipped. -As of this writing \tts{prelink} should handle -\href{http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf}% -{\tts{DWARF 2} [15]} standard as corrected (and extended) by -\href{http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf}% -{\tts{DWARF 3 draft} [16]}, -\href{http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/doc/stabs.texinfo?cvsroot=src}% -{\tts{Stabs} [17]} with GCC extensions and Alpha or MIPS \tts{Mdebug}. - -\tts{DWARF 2} debugging information involves many separate sections, -each of them with a unique format which needs to be relocated differently. -For relocation of the \tts{.debug\_info} section compilation units \tts{prelink} has to -parse the corresponding part of the \tts{.debug\_abbrev} section, adjust all -values of attributes that are using the \tts{DW\_FORM\_addr} form and adjust embedded -location lists. \tts{.debug\_ranges} and \tts{.debug\_loc} section -portions depend on the exact place in \tts{.debug\_info} section from -which they are referenced, so that \tts{prelink} can keep track of their -base address. \tts{DWARF} debugging format is very extendable, so -\tts{prelink} needs to be very conservative when it sees unknown extensions. -It needs to fail prelinking instead of silently break debugging information -if it sees an unknown \tts{.debug\_*} section, unknown attribute form -or unknown attribute with one of the \tts{DW\_FORM\_block*} forms, as -they can potentially embed addresses which would need adjustment. - -For \tts{stabs} \tts{prelink} tried to match GDB behavior. For -\tts{N\_FUN}, it needs to differentiate between function start and -function address which are both encoded with this type, the rest of types -either always need relocating or never. And similarly to \tts{DWARF 2} -handling, it needs to reject unknown types. - -The relocation code in \tts{prelink} is a little bit more generic -than what is described above, as it is used also by other parts of -\tts{prelink}, when growing sections in a middle of the shared library -during \tts{REL} to \tts{RELA} conversion. All adjustment functions -get passed both the offset it should add to virtual addresses and -a start address. Adjustment is only done if the old virtual address -was bigger or equal than the start address. - -\section{REL to RELA conversion} - -On architectures which normally use the \tts{REL} format for relocations instead -of \tts{RELA} (IA-32, ARM and MIPS), if certain relocation types use the -memory \tts{r\_offset} points to during relocation, \tts{prelink} has to -either convert them to a different relocation type which doesn't use -the memory value, or the whole \tts{.rel.dyn} section needs to be converted -to \tts{RELA} format. Let's describe it on an example on IA-32 architecture: - -\noindent{{\small\begin{verbatim} -$ cat > test1.c <<EOF -extern int i[4]; -int *j = i + 2; -EOF -$ cat > test2.c <<EOF -int i[4]; -EOF -$ gcc -nostdlib -shared -fpic -s -o test2.so test2.c -$ gcc -nostdlib -shared -fpic -o test1.so test1.c ./test2.so -$ readelf -l test1.so | grep LOAD | head -1 - LOAD 0x000000 0x00000000 0x00000000 0x002b8 0x002b8 R E 0x1000 -$ readelf -l test2.so | grep LOAD | head -1 - LOAD 0x000000 0x00000000 0x00000000 0x00244 0x00244 R E 0x1000 -$ readelf -r test1.so - -Relocation section '.rel.dyn' at offset 0x2b0 contains 1 entries: - Offset Info Type Sym.Value Sym. Name -000012b8 00000d01 R_386_32 00000000 i -$ objdump -s -j .data test1.so - -test1.so: file format elf32-i386 - -Contents of section .data: - 12b8 08000000 .... -$ readelf -s test2.so | grep i\$ - 11: 000012a8 16 OBJECT GLOBAL DEFAULT 8 i -$ prelink -N ./test1.so ./test2.so -$ readelf -l test1.so | grep LOAD | head -1 - LOAD 0x000000 0x04dba000 0x04dba000 0x002bc 0x002bc R E 0x1000 -$ readelf -l test2.so | grep LOAD | head -1 - LOAD 0x000000 0x04db6000 0x04db6000 0x00244 0x00244 R E 0x1000 -$ readelf -r test1.so - -Relocation section '.rel.dyn' at offset 0x2b0 contains 1 entries: - Offset Info Type Sym.Value Sym. Name + Addend -04dbb2bc 00000d01 R_386_32 00000000 i + 8 -$ objdump -s -j .data test1.so - -test1.so: file format elf32-i386 - -Contents of section .data: - 4dbb2bc b072db04 .r.. -$ readelf -s test2.so | grep i\$ - 11: 04db72a8 16 OBJECT GLOBAL DEFAULT 8 i -\end{verbatim}} -\prelinklistingcaption{\tts{REL} to \tts{RELA} conversion example}} - -This relocation is against {\sl i + 8}, where the addend is stored at the memory -location pointed by \tts{r\_offset}. \tts{Prelink} assigned base address -0x4dba000 to \tts{test1.so} and 0x4db6000 to \tts{test2.so}. -\tts{Prelink} above converted the \tts{REL} section in \tts{test1.so} to -\tts{RELA}, but let's assume it did not. All output containing {\sl 2bc} -above would change to {\sl 2b8} (that changed above only because \tts{.rel.dyn} -section grew up by 4 bytes during the conversion to \tts{RELA} format), -the rest would stay unchanged. -When some program linked against \tts{test1.so} was prelinked, -the (only) relocation in \tts{test1.so} would not be used and {\sl j} would -contain the right value, 0x4db72b0 (address of {\sl i + 8}; note that IA-32 -is little endian, so the values in .data section are harder to read -for a human). Now, let's assume one of the shared libraries the executable -is linked against is upgraded. This means prelink information cannot -be used, as it is out of date. Let's assume it was a library other -than \tts{test2.so}. Normal relocation processing for \tts{test1.so} -needs to happen. Standard \tts{R\_386\_32} calculation is \tts{S~+~A}, -in this case 0x4db72a8 + 0x4db72b0 = 0x9b6e558 and {\sl j} contains wrong -value. Either \tts{test2.so} could change and now the {\sl i} variable would -have different address, or some other shared library linked to the executable -could overload symbol {\sl i}. Without additional information the dynamic -linker cannot find out the addend is 8. - -The original value of a symbol could perhaps be stored in some special -allocated section and the dynamic linker could do some magic to locate it, -but it would mean standard relocation handling code in the dynamic linker -cannot be used for relocation processing of prelinked shared libraries -where prelinking information cannot be used. -So \tts{prelink} in this case converts the whole \tts{.rel.dyn} section -into the \tts{RELA} format, the addend is stored in \tts{r\_addend} field -and when doing relocation processing, it really doesn't matter what -value is at the memory location pointed by \tts{r\_offset}. -The disadvantage of this is that the relocation section -grew by 50\%. If prelinking information can be used, it shouldn't matter much, -since the section is never loaded at runtime because it is not accessed. -If prelinking cannot be used, whether because it is out of date or -because the shared library has been -loaded by \tts{dlopen}, it will increase memory footprint, but it is read-only -memory which is typically not used after startup and can be discarded -as it is backed out by the file containing the shared library. - -At least on IA-32, \tts{REL} to \tts{RELA} conversion is not always -necessary. If \tts{R\_386\_32} added is originally 0, \tts{prelink} -can instead change its type to \tts{R\_386\_GLOB\_DAT}, which is a -similar dynamic relocation, but calculated as \tts{S} instead of -\tts{S~+~A}. There is no similar conversion for \tts{R\_386\_PC32} -possible though, on the other side this relocation type should never -appear in position independent shared libraries, only in position -dependent code. On ARM, the situation is the same, just using -different relocation names (\tts{R\_ARM\_32}, \tts{R\_ARM\_GLOB\_DAT} -and \tts{R\_ARM\_PC24}). - -The \tts{.rel.plt} section doesn't have to be converted to \tts{RELA} -format on either of these architectures, if the conversion is needed, -all other \tts{.rel.*} allocated sections, which have to be adjacent -as they are pointed to by \tts{DT\_REL} and \tts{DT\_RELSZ} dynamic tags, -have to be converted together. The conversion itself is fairly easy, -some architecture specific code just has to fetch the original addend -from memory pointed by the relocation and store it into \tts{r\_addend} -field (or clear \tts{r\_addend} if the particular relocation type -never uses the addend). The main problem is that when the conversion -happens, the \tts{.rel.dyn} section grows by 50\% and there needs to be -room for that in the read-only loadable segment of the shared library. - -In shared libraries it is always possible to grow the first read-only -\tts{PT\_LOAD} segment by adding the additional data at the beginning -of the read-only segment, as the shared library is relocatable. -\tts{Prelink} can relocate the whole shared library to a higher address -than it has assigned for it. The file offsets of all sections -and the section header table file offset need to be increased, -but the \tts{ELF} header and program headers need to stay at the beginning -of the file. The relocation section can then be moved to the newly created -space between the end of the program header table and the first section. - -Moving the section from the old location to the newly created space -would leave often very big gap in virtual address space as well as in -the file at the old location of the relocation section. Fortunately the -linker typically puts special \tts{ELF} sections including allocated -relocation section before the code section and other read-only sections -under user's control. These special sections are intended for dynamic -linking only. Their addresses are stored just in the \tts{.dynamic} section -and \tts{prelink} can easily adjust them there. There is no need for -a shared library to store address of one of the special sections -into its code or data sections and existing linkers in fact don't create -such references. When growing the relocation section, \tts{prelink} -checks whether all sections before the relocation section are -special -\footnote{As special sections \tts{prelink} considers sections with -\tts{SHT\_NOTE}, \tts{SHT\_HASH}, \tts{SHT\_DYNSYM}, \tts{SHT\_STRTAB}, -\tts{SHT\_GNU\_verdef}, \tts{SHT\_GNU\_verneed}, \tts{SHT\_GNU\_versym}, -\tts{SHT\_REL} or \tts{SHT\_RELA} type or the \tts{.interp} section.} -and if they are, just moves them to lower addresses, so that the -newly created space is right above the relocation section. -The advantage is that instead of moving all sections by the size of -the new relocation section they can be adjusted ideally just by the -difference between old and new relocation section size. - -There are two factors which can increase the necessary adjustment of -all higher sections. The first is required section alignment of any -allocated section above the relocation section. \tts{Prelink} needs -to find the highest section alignment among those sections and -increase the adjustment from the difference between old and new -relocation section up to the next multiple of that alignment. - -The second factor is only relevant to shared libraries where linker -optimized the data segment placement. Traditionally linker assigned -the end address of the read-only segment plus the architecture's -maximum \tts{ELF} page size as the start address of the read-write -segment. While this created smallest file sizes of the shared libraries, -it often wasted one page in the read-write segment because of partial -pages. When linker optimizes such that less space is wasted in partial -pages, the distance between read-only and read-write segments can be -smaller than architecture specific maximum \tts{ELF} page size. -\tts{Prelink} has to take this into account, so that when adjusting -the sections the read-only and read-write segment don't end up on the -same page. Unfortunately \tts{prelink} cannot increase or decrease -the distance between the read-only and read-write segments, since -it is possible that the shared library has relative addresses of -any allocated code, data or \tts{.bss} sections -stored in its sections without any relocations which would allow -\tts{prelink} to change them. \tts{Prelink} has to move all sections -starting with the first allocated \tts{SHT\_PROGBITS} section other -than \tts{.interp} up to the last allocated \tts{SHT\_PROGBITS} or -\tts{SHT\_NOBITS} section as a block and thus needs to increase -the adjustment in steps of the highest section alignment as many times -times as needed so that the segments end up in different pages. -Below are 3 examples: - -\noindent{{\small\begin{verbatim} -$ cat > test1.c <<EOF -int i[2] __attribute__((aligned (32))); -#define J1(N) int *j##N = &i[1]; -#define J2(N) J1(N##0) J1(N##1) J1(N##2) J1(N##3) J1(N##4) -#define J3(N) J2(N##0) J2(N##1) J2(N##2) J2(N##3) J2(N##4) -#define J4(N) J3(N##0) J3(N##1) J3(N##2) J3(N##3) J3(N##4) -J4(0) J4(1) J3(2) J3(3) J1(4) -const int l[256] = { [10] = 1 }; -/* Put a zero sized section at the end of read-only segment, - so that the end address of the segment is printed. */ -asm (".section ro_seg_end, \"a\"; .previous"); -EOF -$ gcc -shared -O2 -nostdlib -fpic -o test1.so test1.c -$ readelf -S test1.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 000000b4 0000b4 000930 04 A 2 0 4 - [ 2] .dynsym DYNSYM 000009e4 0009e4 001430 10 A 3 d 4 - [ 3] .dynstr STRTAB 00001e14 001e14 000735 00 A 0 0 1 - [ 4] .rel.dyn REL 0000254c 00254c 000968 08 A 2 0 4 - [ 5] .text PROGBITS 00002eb4 002eb4 000000 00 AX 0 0 4 - [ 6] .rodata PROGBITS 00002ec0 002ec0 000400 00 A 0 0 32 - [ 7] ro_seg_end PROGBITS 000032c0 0032c0 000000 00 A 0 0 1 - [ 8] .data PROGBITS 000042c0 0032c0 0004b4 00 WA 0 0 4 - [ 9] .dynamic DYNAMIC 00004774 003774 000070 08 WA 3 0 4 - [10] .got PROGBITS 000047e4 0037e4 00000c 04 WA 0 0 4 - [11] .bss NOBITS 00004800 003800 000008 00 WA 0 0 32 - [12] .comment PROGBITS 00000000 003800 000033 00 0 0 1 - [13] .shstrtab STRTAB 00000000 003833 000075 00 0 0 1 - [14] .symtab SYMTAB 00000000 003b28 001470 10 15 11 4 - [15] .strtab STRTAB 00000000 004f98 000742 00 0 0 1 -$ readelf -l test1.so | grep LOAD - LOAD 0x000000 0x00000000 0x00000000 0x032c0 0x032c0 R E 0x1000 - LOAD 0x0032c0 0x000042c0 0x000042c0 0x00530 0x00548 RW 0x1000 -$ prelink -N ./test1.so -$ readelf -l test1.so | grep LOAD - LOAD 0x000000 0x02000000 0x02000000 0x03780 0x03780 R E 0x1000 - LOAD 0x003780 0x02004780 0x02004780 0x00530 0x00548 RW 0x1000 -$ readelf -S test1.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 020000b4 0000b4 000930 04 A 2 0 4 - [ 2] .dynsym DYNSYM 020009e4 0009e4 001430 10 A 3 d 4 - [ 3] .dynstr STRTAB 02001e14 001e14 000735 00 A 0 0 1 - [ 4] .rel.dyn RELA 0200254c 00254c 000e1c 0c A 2 0 4 - [ 5] .text PROGBITS 02003374 003374 000000 00 AX 0 0 4 - [ 6] .rodata PROGBITS 02003380 003380 000400 00 A 0 0 32 - [ 7] ro_seg_end PROGBITS 02003780 003780 000000 00 A 0 0 1 - [ 8] .data PROGBITS 02004780 003780 0004b4 00 WA 0 0 4 - [ 9] .dynamic DYNAMIC 02004c34 003c34 000070 08 WA 3 0 4 - [10] .got PROGBITS 02004ca4 003ca4 00000c 04 WA 0 0 4 - [11] .bss NOBITS 02004cc0 003cc0 000008 00 WA 0 0 32 - [12] .comment PROGBITS 00000000 003cc0 000033 00 0 0 1 - [13] .gnu.liblist GNU_LIBLIST 00000000 003cf3 000000 14 14 0 4 - [14] .gnu.libstr STRTAB 00000000 003cf3 000000 00 0 0 1 - [15] .gnu.prelink_undo PROGBITS 00000000 003cf4 00030c 01 0 0 4 - [16] .shstrtab STRTAB 00000000 004003 0000a0 00 0 0 1 - [17] .symtab SYMTAB 00000000 0043a0 001470 10 18 11 4 - [18] .strtab STRTAB 00000000 005810 000742 00 0 0 1 -\end{verbatim}} -\prelinklistingcaption{Growing read-only segment with segment distance one page}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=0.8\textwidth]{dso1} -\caption{Growing read-only segment with segment distance one page} -\end{figure} - -In this example the read-write segment starts at address \tts{0x42c0}, which -is one page above the end of read-only segment. \tts{Prelink} needs to grow -the read-only \tts{PT\_LOAD} segment by 50\% of \tts{.rel.dyn} size, i.e. -\tts{0x4b4} bytes. \tts{Prelink} just needs to round that up for the -highest alignment (32 bytes required by \tts{.rodata} or \tts{.bss} -sections) and moves all sections above \tts{.rel.dyn} by \tts{0x4c0} bytes. - -\noindent{{\small\begin{verbatim} -$ cat > test2.c <<EOF -int i[2] __attribute__((aligned (32))); -#define J1(N) int *j##N = &i[1]; -#define J2(N) J1(N##0) J1(N##1) J1(N##2) J1(N##3) J1(N##4) -#define J3(N) J2(N##0) J2(N##1) J2(N##2) J2(N##3) J2(N##4) -#define J4(N) J3(N##0) J3(N##1) J3(N##2) J3(N##3) J3(N##4) -J4(0) J4(1) J3(2) J3(3) J1(4) -const int l[256] = { [10] = 1 }; -int k[670]; -asm (".section ro_seg_end, \"a\"; .previous"); -EOF -$ gcc -shared -O2 -nostdlib -fpic -o test2.so test2.c -$ readelf -S test2.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 000000b4 0000b4 000934 04 A 2 0 4 - [ 2] .dynsym DYNSYM 000009e8 0009e8 001440 10 A 3 d 4 - [ 3] .dynstr STRTAB 00001e28 001e28 000737 00 A 0 0 1 - [ 4] .rel.dyn REL 00002560 002560 000968 08 A 2 0 4 - [ 5] .text PROGBITS 00002ec8 002ec8 000000 00 AX 0 0 4 - [ 6] .rodata PROGBITS 00002ee0 002ee0 000400 00 A 0 0 32 - [ 7] ro_seg_end PROGBITS 000032e0 0032e0 000000 00 A 0 0 1 - [ 8] .data PROGBITS 00004000 004000 0004b4 00 WA 0 0 4 - [ 9] .dynamic DYNAMIC 000044b4 0044b4 000070 08 WA 3 0 4 - [10] .got PROGBITS 00004524 004524 00000c 04 WA 0 0 4 - [11] .bss NOBITS 00004540 004540 000a88 00 WA 0 0 32 - [12] .comment PROGBITS 00000000 004540 000033 00 0 0 1 - [13] .shstrtab STRTAB 00000000 004573 000075 00 0 0 1 - [14] .symtab SYMTAB 00000000 004868 001480 10 15 11 4 - [15] .strtab STRTAB 00000000 005ce8 000744 00 0 0 1 -$ readelf -l test2.so | grep LOAD - LOAD 0x000000 0x00000000 0x00000000 0x032e0 0x032e0 R E 0x1000 - LOAD 0x004000 0x00004000 0x00004000 0x00530 0x00fc8 RW 0x1000 -$ prelink -N ./test2.so -$ readelf -l test2.so | grep LOAD - LOAD 0x000000 0x02000000 0x02000000 0x037a0 0x037a0 R E 0x1000 - LOAD 0x0044c0 0x020044c0 0x020044c0 0x00530 0x00fc8 RW 0x1000 -$ readelf -S test2.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 020000b4 0000b4 000934 04 A 2 0 4 - [ 2] .dynsym DYNSYM 020009e8 0009e8 001440 10 A 3 d 4 - [ 3] .dynstr STRTAB 02001e28 001e28 000737 00 A 0 0 1 - [ 4] .rel.dyn RELA 02002560 002560 000e1c 0c A 2 0 4 - [ 5] .text PROGBITS 02003388 003388 000000 00 AX 0 0 4 - [ 6] .rodata PROGBITS 020033a0 0033a0 000400 00 A 0 0 32 - [ 7] ro_seg_end PROGBITS 020037a0 0037a0 000000 00 A 0 0 1 - [ 8] .data PROGBITS 020044c0 0044c0 0004b4 00 WA 0 0 4 - [ 9] .dynamic DYNAMIC 02004974 004974 000070 08 WA 3 0 4 - [10] .got PROGBITS 020049e4 0049e4 00000c 04 WA 0 0 4 - [11] .bss NOBITS 02004a00 004a00 000a88 00 WA 0 0 32 - [12] .comment PROGBITS 00000000 004a00 000033 00 0 0 1 - [13] .gnu.liblist GNU_LIBLIST 00000000 004a33 000000 14 14 0 4 - [14] .gnu.libstr STRTAB 00000000 004a33 000000 00 0 0 1 - [15] .gnu.prelink_undo PROGBITS 00000000 004a34 00030c 01 0 0 4 - [16] .shstrtab STRTAB 00000000 004d43 0000a0 00 0 0 1 - [17] .symtab SYMTAB 00000000 0050e0 001480 10 18 11 4 - [18] .strtab STRTAB 00000000 006560 000744 00 0 0 1 -\end{verbatim}} -\prelinklistingcaption{Growing read-only segment not requiring additional padding}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=0.8\textwidth]{dso2} -\caption{Growing read-only segment not requiring additional padding} -\end{figure} - -In the second example \tts{prelink} can grow by just \tts{0x4c0} bytes as -well, eventhough the distance between read-write and read-only segment -is just \tts{0xd20} bytes. With this distance, hypothetical adjustment -by any size less than \tts{0xd21} bytes (modulo 4096) would need just -rounding up to the next multiple of 32 bytes, while adjustments -from \tts{0xd21} up to \tts{0xfe0} would require adjustments in -multiples of 4096 bytes. - -\noindent{{\small\begin{verbatim} -$ cat > test3.c <<EOF -int i[2] __attribute__((aligned (32))); -#define J1(N) int *j##N = &i[1]; -#define J2(N) J1(N##0) J1(N##1) J1(N##2) J1(N##3) J1(N##4) -#define J3(N) J2(N##0) J2(N##1) J2(N##2) J2(N##3) J2(N##4) -#define J4(N) J3(N##0) J3(N##1) J3(N##2) J3(N##3) J3(N##4) -J4(0) J4(1) J3(2) J3(3) J1(4) -int k[670]; -asm (".section ro_seg_end, \"a\"; .previous"); -EOF -$ gcc -shared -O2 -nostdlib -fpic -o test3.so test3.c -$ readelf -S test3.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 000000b4 0000b4 00092c 04 A 2 0 4 - [ 2] .dynsym DYNSYM 000009e0 0009e0 001420 10 A 3 c 4 - [ 3] .dynstr STRTAB 00001e00 001e00 000735 00 A 0 0 1 - [ 4] .rel.dyn REL 00002538 002538 000968 08 A 2 0 4 - [ 5] .text PROGBITS 00002ea0 002ea0 000000 00 AX 0 0 4 - [ 6] ro_seg_end PROGBITS 00002ea0 002ea0 000000 00 A 0 0 1 - [ 7] .data PROGBITS 00003000 003000 0004b4 00 WA 0 0 4 - [ 8] .dynamic DYNAMIC 000034b4 0034b4 000070 08 WA 3 0 4 - [ 9] .got PROGBITS 00003524 003524 00000c 04 WA 0 0 4 - [10] .bss NOBITS 00003540 003540 000a88 00 WA 0 0 32 - [11] .comment PROGBITS 00000000 003540 000033 00 0 0 1 - [12] .shstrtab STRTAB 00000000 003573 00006d 00 0 0 1 - [13] .symtab SYMTAB 00000000 003838 001460 10 14 10 4 - [14] .strtab STRTAB 00000000 004c98 000742 00 0 0 1 -$ readelf -l test3.so | grep LOAD - LOAD 0x000000 0x00000000 0x00000000 0x02ea0 0x02ea0 R E 0x1000 - LOAD 0x003000 0x00003000 0x00003000 0x00530 0x00fc8 RW 0x1000 -$ prelink -N ./test3.so -$ readelf -l test3.so | grep LOAD - LOAD 0x000000 0x02000000 0x02000000 0x03ea0 0x03ea0 R E 0x1000 - LOAD 0x004000 0x02004000 0x02004000 0x00530 0x00fc8 RW 0x1000 -$ readelf -S test3.so | grep '^ \[' - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .hash HASH 020000b4 0000b4 00092c 04 A 2 0 4 - [ 2] .dynsym DYNSYM 020009e0 0009e0 001420 10 A 3 c 4 - [ 3] .dynstr STRTAB 02001e00 001e00 000735 00 A 0 0 1 - [ 4] .rel.dyn RELA 02002538 002538 000e1c 0c A 2 0 4 - [ 5] .text PROGBITS 02003ea0 003ea0 000000 00 AX 0 0 4 - [ 6] ro_seg_end PROGBITS 02003ea0 003ea0 000000 00 A 0 0 1 - [ 7] .data PROGBITS 02004000 004000 0004b4 00 WA 0 0 4 - [ 8] .dynamic DYNAMIC 020044b4 0044b4 000070 08 WA 3 0 4 - [ 9] .got PROGBITS 02004524 004524 00000c 04 WA 0 0 4 - [10] .bss NOBITS 02004540 004540 000a88 00 WA 0 0 32 - [11] .comment PROGBITS 00000000 004540 000033 00 0 0 1 - [12] .gnu.liblist GNU_LIBLIST 00000000 004573 000000 14 13 0 4 - [13] .gnu.libstr STRTAB 00000000 004573 000000 00 0 0 1 - [14] .gnu.prelink_undo PROGBITS 00000000 004574 0002e4 01 0 0 4 - [15] .shstrtab STRTAB 00000000 00485b 000098 00 0 0 1 - [16] .symtab SYMTAB 00000000 004bc8 001460 10 17 10 4 - [17] .strtab STRTAB 00000000 006028 000742 00 0 0 1 -\end{verbatim}} -\prelinklistingcaption{Growing read-only segment if page padding needed}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=0.8\textwidth]{dso3} -\caption{Growing read-only segment if page padding needed} -\end{figure} - -In the last example the distance between \tts{PT\_LOAD} segments is very -small, just \tts{0x160} bytes and the adjustment had to be done by 4096 -bytes. - -% Fortunately, shared libraries are position independent, so all absolute -% values in them are either stored in well known \tts{ELF} structures, -% or have corresponding dynamic relocations. The only problem might be -% with relative relocations, which are resolved at link time. -% The start of read-only \tts{PT\_LOAD} segment of shared libraries is -% typically used by special sections used by the dynamic linker -% (\tts{.hash}, \tts{.dynsym}, \tts{.dynstr}, \tts{.gnu.version*}, -% \tts{.rel*}, \tts{.note*}). It makes no sense for a shared library to -% have relocations against these sections or some addresses inside of them, -% furthermore it is impossible to do it without specially crafted -% linker script. So \tts{prelink} makes the assumption that it can grow -% freely the shared library after \tts{.rel.dyn} section, as long -% as only sections mentioned above come before \tts{.rel.dyn} (it actually -% checks section types, not names). \tts{Prelink} certainly can grow the shared library -% size in multiplies of \tts{ELF} architecture specific maximum page size, -% but usually it can do better. Particularly, \tts{prelink} can grow by the 50\% size -% of \tts{.rel.dyn} section rounded up to the largest section alignment -% in all sections following it, but it has to make sure that two -% different \tts{PT\_LOAD} segments (typically the read-only and read-write) -% will not share the same page, otherwise it needs to grow it more in -% multiplies of the maximum section alignment until they are on different -% pages. Growing is done by using the shared library relocation code with -% start address set to end of \tts{.rel.dyn} section. \tts{.rel.plt} -% section is then moved right to the end of \tts{.rel.dyn} section, -% \tts{.dynamic} section needs updating all addresses, type of -% relocation section, segment table needs to be adjusted accordingly -% and file offsets in section header table as well. - -\section{Conflicts} - -As said earlier, if symbol lookup of some symbol in particular shared -library results in different values when that shared library's natural -search scope is used and when using search scope of the application the -DSO is used in, this is considered a {\sl conflict}. -Here is an example of a conflict on IA-32: - -\noindent{{\small\begin{verbatim} -$ cat > test1.c <<EOF -int i; -int *j = &i; -int *foo (void) { return &i; } -EOF -$ cat > test2.c <<EOF -int i; -int *k = &i; -int *bar (void) { return &i; } -EOF -$ cat > test.c <<EOF -#include <stdio.h> -extern int i, *j, *k, *foo (void), bar (void); -int main (void) -{ -#ifdef PRINT_I - printf ("%p\n", &i); -#endif - printf ("%p %p %p %p\n", j, k, foo (), bar ()); -} -EOF -$ gcc -nostdlib -shared -fpic -s -o test1.so test1.c -$ gcc -nostdlib -shared -fpic -o test2.so test2.c ./test1.so -$ gcc -o test test.c ./test2.so ./test1.so -$ ./test -0x16137c 0x16137c 0x16137c 0x16137c -$ readelf -r ./test1.so - -Relocation section '.rel.dyn' at offset 0x2bc contains 2 entries: - Offset Info Type Sym.Value Sym. Name -000012e4 00000d01 R_386_32 00001368 i -00001364 00000d06 R_386_GLOB_DAT 00001368 i -$ prelink -N ./test ./test1.so ./test2.so -$ LD_WARN= LD_TRACE_PRELINKING=1 LD_BIND_NOW=1 /lib/ld-linux.so.2 ./test1.so - ./test1.so => ./test1.so (0x04db6000, 0x00000000) -$ LD_WARN= LD_TRACE_PRELINKING=1 LD_BIND_NOW=1 /lib/ld-linux.so.2 ./test2.so - ./test2.so => ./test2.so (0x04dba000, 0x00000000) - ./test1.so => ./test1.so (0x04db6000, 0x00000000) -$ LD_WARN= LD_TRACE_PRELINKING=1 LD_BIND_NOW=1 /lib/ld-linux.so.2 ./test \ - | sed 's/^[[:space:]]*/ /' - ./test => ./test (0x08048000, 0x00000000) - ./test2.so => ./test2.so (0x04dba000, 0x00000000) - ./test1.so => ./test1.so (0x04db6000, 0x00000000) - libc.so.6 => /lib/tls/libc.so.6 (0x00b22000, 0x00000000) TLS(0x1, 0x00000028) - /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00b0a000, 0x00000000) -$ readelf -S ./test1.so | grep '\.data\|\.got' - [ 6] .data PROGBITS 04db72e4 0002e4 000004 00 WA 0 0 4 - [ 8] .got PROGBITS 04db7358 000358 000010 04 WA 0 0 4 -$ readelf -r ./test1.so - -Relocation section '.rel.dyn' at offset 0x2bc contains 2 entries: - Offset Info Type Sym.Value Sym. Name -04db72e4 00000d06 R_386_GLOB_DAT 04db7368 i -04db7364 00000d06 R_386_GLOB_DAT 04db7368 i -$ objdump -s -j .got -j .data test1.so - -test1.so: file format elf32-i386 - -Contents of section .data: - 4db72e4 6873db04 hs.. -Contents of section .got: - 4db7358 e8120000 00000000 00000000 6873db04 ............hs.. -$ readelf -r ./test | sed '/\.gnu\.conflict/,$!d' -Relocation section '.gnu.conflict' at offset 0x7ac contains 18 entries: - Offset Info Type Sym.Value Sym. Name + Addend -04db72e4 00000001 R_386_32 04dbb37c -04db7364 00000001 R_386_32 04dbb37c -00c56874 00000001 R_386_32 fffffff0 -00c56878 00000001 R_386_32 00000001 -00c568bc 00000001 R_386_32 fffffff4 -00c56900 00000001 R_386_32 ffffffec -00c56948 00000001 R_386_32 ffffffdc -00c5695c 00000001 R_386_32 ffffffe0 -00c56980 00000001 R_386_32 fffffff8 -00c56988 00000001 R_386_32 ffffffe4 -00c569a4 00000001 R_386_32 ffffffd8 -00c569c4 00000001 R_386_32 ffffffe8 -00c569d8 00000001 R_386_32 080485b8 -00b1f510 00000007 R_386_JUMP_SLOT 00b91460 -00b1f514 00000007 R_386_JUMP_SLOT 00b91080 -00b1f518 00000007 R_386_JUMP_SLOT 00b91750 -00b1f51c 00000007 R_386_JUMP_SLOT 00b912c0 -00b1f520 00000007 R_386_JUMP_SLOT 00b91200 -$ ./test -0x4dbb37c 0x4dbb37c 0x4dbb37c 0x4dbb37c -\end{verbatim}} -\prelinklistingcaption{Conflict example}} - -In the example, among some conflicts caused by the dynamic linker and the C library, -\footnote{Particularly in the example, the 5 \tts{R\_386\_JUMP\_SLOT} fixups -are \tts{PLT} slots in the dynamic linker for memory allocator functions -resolving to C library functions instead of dynamic linker's own trivial -implementation. First 10 \tts{R\_386\_32} fixups at offsets 0xc56874 -to 0xc569c4 are Thread Local Storage fixups in the C library and -the fixup at 0xc569d8 is for {\sl \_IO\_stdin\_used} weak undefined symbol -in the C library, resolving to a symbol with the same name in the executable.} -there is a conflict for the symbol {\sl i} in \tts{test1.so} shared library. -\tts{test1.so} has just itself in its natural symbol lookup scope (as proved -by - -\tts{LD\_WARN= LD\_TRACE\_PRELINKING=1 LD\_BIND\_NOW=1 /lib/ld-linux.so.2 ./test1.so} - -command output), so when looking up symbol {\sl i} in this -scope the definition in \tts{test1.so} is chosen. \tts{test1.so} has two -relocations against the symbol {\sl i}, one \tts{R\_386\_32} against \tts{.data} -section and one \tts{R\_386\_GLOB\_DAT} against \tts{.got} section. When -prelinking \tts{test1.so} library, the dynamic linker stores the address of -{\sl i} (0x4db7368) into both locations (at offsets 0x4db72e4 and 0x4db7364). -The global symbol search scope in \tts{test} executable contains the executable -itself, \tts{test2.so} and \tts{test1.so} libraries, \tts{libc.so.6} and -the dynamic linker in the listed order. -When doing symbol lookup for symbol {\sl i} -in \tts{test1.so} when doing relocation processing of the whole executable, -address of {\sl i} in \tts{test2.so} is returned as that symbol comes earlier -in the global search scope. So, when none of the libraries nor the executable -is prelinked, the program prints 4 identical addresses. If prelink didn't -create conflict fixups for the two relocations against the symbol {\sl i} -in \tts{test1.so}, prelinked executable (which bypasses normal relocation -processing on startup) would print instead of the desired - -\tts{0x4dbb37c 0x4dbb37c 0x4dbb37c 0x4dbb37c} - -different addresses, - -\tts{0x4db7368 0x4dbb37c 0x4db7368 0x4dbb37c} - -That is a functionality change that \tts{prelink} cannot be permitted to -make, so instead it fixes up the two locations by storing the desired -value in there. In this case \tts{prelink} really cannot avoid that -- \tts{test1.so} shared library could be also used without \tts{test2.so} -in some other executable's symbol search scope. -Or there could be some executable linked with: - -\noindent{{\small\begin{verbatim} -$ gcc -o test2 test.c ./test1.so ./test2.so -\end{verbatim}} -\prelinklistingcaption{Conflict example with swapped order of libraries}} - -where {\sl i} lookup in \tts{test1.so} and \tts{test2.so} is supposed -to resolve to {\sl i} in \tts{test1.so}. - -Now consider what happens if the executable is linked with \tts{-DPRINT\_I}: - -\noindent{{\small\begin{verbatim} -$ gcc -DPRINT_I -o test3 test.c ./test2.so ./test1.so -$ ./test3 -0x804972c -0x804972c 0x804972c 0x804972c 0x804972c -$ prelink -N ./test3 ./test1.so ./test2.so -$ readelf -S ./test2.so | grep '\.data\|\.got' - [ 6] .data PROGBITS 04dbb2f0 0002f0 000004 00 WA 0 0 4 - [ 8] .got PROGBITS 04dbb36c 00036c 000010 04 WA 0 0 4 -$ readelf -r ./test2.so - -Relocation section '.rel.dyn' at offset 0x2c8 contains 2 entries: - Offset Info Type Sym.Value Sym. Name -04dbb2f0 00000d06 R_386_GLOB_DAT 04dbb37c i -04dbb378 00000d06 R_386_GLOB_DAT 04dbb37c i -$ objdump -s -j .got -j .data test2.so - -test2.so: file format elf32-i386 - -Contents of section .data: - 4dbb2f0 7cb3db04 |... -Contents of section .got: - 4dbb36c f4120000 00000000 00000000 7cb3db04 ............|... -$ readelf -r ./test3 - -Relocation section '.rel.dyn' at offset 0x370 contains 4 entries: - Offset Info Type Sym.Value Sym. Name -08049720 00000e06 R_386_GLOB_DAT 00000000 __gmon_start__ -08049724 00000105 R_386_COPY 08049724 j -08049728 00000305 R_386_COPY 08049728 k -0804972c 00000405 R_386_COPY 0804972c i - -Relocation section '.rel.plt' at offset 0x390 contains 4 entries: - Offset Info Type Sym.Value Sym. Name -08049710 00000607 R_386_JUMP_SLOT 080483d8 __libc_start_main -08049714 00000707 R_386_JUMP_SLOT 080483e8 printf -08049718 00000807 R_386_JUMP_SLOT 080483f8 foo -0804971c 00000c07 R_386_JUMP_SLOT 08048408 bar - -Relocation section '.gnu.conflict' at offset 0x7f0 contains 20 entries: - Offset Info Type Sym.Value Sym. Name + Addend -04dbb2f0 00000001 R_386_32 0804972c -04dbb378 00000001 R_386_32 0804972c -04db72e4 00000001 R_386_32 0804972c -04db7364 00000001 R_386_32 0804972c -00c56874 00000001 R_386_32 fffffff0 -00c56878 00000001 R_386_32 00000001 -00c568bc 00000001 R_386_32 fffffff4 -00c56900 00000001 R_386_32 ffffffec -00c56948 00000001 R_386_32 ffffffdc -00c5695c 00000001 R_386_32 ffffffe0 -00c56980 00000001 R_386_32 fffffff8 -00c56988 00000001 R_386_32 ffffffe4 -00c569a4 00000001 R_386_32 ffffffd8 -00c569c4 00000001 R_386_32 ffffffe8 -00c569d8 00000001 R_386_32 080485f0 -00b1f510 00000007 R_386_JUMP_SLOT 00b91460 -00b1f514 00000007 R_386_JUMP_SLOT 00b91080 -00b1f518 00000007 R_386_JUMP_SLOT 00b91750 -00b1f51c 00000007 R_386_JUMP_SLOT 00b912c0 -00b1f520 00000007 R_386_JUMP_SLOT 00b91200 -$ ./test3 -0x804972c -0x804972c 0x804972c 0x804972c 0x804972c -\end{verbatim}} -\prelinklistingcaption{Conflict example with COPY relocation for conflicting symbol}} - -Because the executable is not compiled as position independent code and -\tts{main} function takes address of {\sl i} variable, the object -file for \tts{test3.c} contains a \tts{R\_386\_32} relocation against -{\sl i}. The linker cannot make dynamic relocations against read-only -segment in the executable, so the address of {\sl i} must be constant. -This is accomplished by creating a new object {\sl i} in the executable's -\tts{.dynbss} section and creating a dynamic \tts{R\_386\_COPY} relocation -for it. The relocation ensures that during startup the content of -{\sl i} object earliest in the search scope without the executable -is copied to this {\sl i} object in executable. Now, unlike \tts{test} -executable, in \tts{test3} executable {\sl i} lookups in both \tts{test1.so} -and \tts{test2.so} libraries result in address of {\sl i} in the executable -(instead of \tts{test2.so}). This means that two conflict fixups -are needed again for \tts{test1.so} (but storing 0x804972c instead of -0x4dbb37c) and two new fixups are needed for \tts{test2.so}. - -If the executable is compiled as position independent code, - -\noindent{{\small\begin{verbatim} -$ gcc -fpic -DPRINT_I -o test4 test.c ./test2.so ./test1.so -$ ./test4 -0x4dbb37c -0x4dbb37c 0x4dbb37c 0x4dbb37c 0x4dbb37c -\end{verbatim}} -\prelinklistingcaption{Conflict example with position independent code in the executable}} - -the address of {\sl i} is stored in executable's \tts{.got} section, -which is writable and thus can have dynamic relocation against it. -So the linker creates a \tts{R\_386\_GLOB\_DAT} relocation against -the \tts{.got} section, the symbol {\sl i} is undefined in the executable -and no copy relocations are needed. In this case, only \tts{test1.so} -will need 2 fixups, \tts{test2.so} will not need any. - -There are various reasons for conflicts: -\begin{itemize} -\item Improperly linked shared libraries. If a shared library always needs -symbols from some particular shared library, it should be linked against -that library, usually by adding \tts{-lLIBNAME} to \tts{gcc -shared} command -line used during linking of the shared library. This both reduces conflict -fixups in \tts{prelink} and makes the library easier to load using -\tts{dlopen}, because applications don't have to remember that they have -to load some other library first. The best place to record the dependency -is in the shared library itself. Another reason is if the needed library -uses symbol versioning for its symbols. Not linking against that library -can result in malfunctioning shared library. \tts{Prelink} issues a warning for -such libraries - \tts{Warning: {\sl library} has undefined non-weak symbols}. -When linking a shared library, the \tts{-Wl,-z,defs} option can be used to -ensure there are no such undefined non-weak symbols. There are exceptions, -when undefined non-weak symbols in shared libraries are desirable. -One exception is when there are multiple shared libraries providing the -same functionality, and a shared library doesn't care which one is used. -An example can be e.g. \tts{libreadline.so.4}, which needs some terminal -handling functions, which are provided be either \tts{libtermcap.so.2}, -or \tts{libncurses.so.5}. Another exception is with plugins or other -shared libraries which expect some symbols to be resolved to symbols -defined in the executable. -\item A library overriding functionality of some other library. One example -is e.g. C library and POSIX thread library. Older versions of the GNU C library -did not provide cancelable entry points required by the standard. This is -not needed for non-threaded applications. So only the \tts{libpthread.so.0} shared -library which provides POSIX threading support then overrode the -cancellation entry points required by the standard by wrapper functions -which provided the required functionality. Although most recent versions -of the GNU C library handle cancellation even in entry points in \tts{libc.so.6} -(this was needed for cases when \tts{libc.so.6} comes earlier before -\tts{libpthread.so.0} in symbol search scope and used to be worked around -by non-standard handling of weak symbols in the dynamic linker), because -of symbol versioning the symbols had to stay in \tts{libpthread.so.0} -as well as in \tts{libc.so.6}. This means every program using POSIX -threads on Linux will have a couple of conflict fixups because of this. -\item Programs which need copy relocations. Although \tts{prelink} will -resolve the copy relocations at prelinking time, if any shared library -has relocations against the symbol which needed copy relocation, all such -relocations will need conflict fixups. Generally, it is better to not -export variables from shared libraries in their APIs, instead provide -accessor functions. -\item Function pointer equality requirement for functions called from -executables. When address of some global function is taken, at least -C and C++ require that this pointer is the same in the whole program. -Executables typically contain position dependent code, so when code in the -executable takes address of some function not defined in the executable itself, -that address must be link time constant. Linker accomplishes this by -creating a \tts{PLT} slot for the function unless there was one already -and resolving to the address of \tts{PLT} slot. The symbol for the function -is created with \tts{st\_value} equal to address of the \tts{PLT} slot, -but \tts{st\_shndx} set to \tts{SHN\_UNDEF}. Such symbols are treated -specially by the dynamic linker, in that \tts{PLT} relocations -resolve to first symbol in the global search scope after the executable, -while symbol lookups for all other relocation types return the -address of the symbol in the executable. Unfortunately, GNU linker doesn't -differentiate between taking address of a function in an executable (especially -one for which no dynamic relocation is possible in case it is in read-only -segment) and just calling the function, but never taking its address. -If it cleared the \tts{st\_value} field of the \tts{SHN\_UNDEF} function symbols -in case nothing in the executable takes the function's address, several \tts{prelink} -conflict could disappear (\tts{SHN\_UNDEF} symbols with \tts{st\_value} set -to 0 are treated always as real undefined symbols by the dynamic linker). -\item \tts{COMDAT} code and data in C++. C++ language has several places where -it may need to emit some code or data without a clear unique -compilation unit owning it. Examples include taking address of an -\tts{inline} function, local static variable in \tts{inline} functions, -virtual tables for some classes (this depends on \tts{\#pragma interface} -or \tts{\#pragma implementation} presence, presence of non-inline -non-pure-virtual member function in the class, etc.), {\sl RTTI} info for them. -Compilers and linkers handle these using various \tts{COMDAT} schemes, -e.g. GNU linker's \tts{.gnu.linkonce*} special sections or using -\tts{SHT\_GROUP}. Unfortunately, all these duplicate merging schemes -work only during linking of shared libraries or executables, no duplicate -removal is done across shared libraries. Shared libraries typically -have relocations against their \tts{COMDAT} code or data objects (otherwise -they wouldn't be at least in most cases emitted at all), so if there are -\tts{COMDAT} duplicates across shared libraries or the executable, they -lead to conflict fixups. The linker theoretically could try to -merge \tts{COMDAT} duplicates across shared libraries if specifically -requested by the user (if a \tts{COMDAT} symbol is already present in -one of the dependent shared libraries and is \tts{STB\_WEAK}, the linker -could skip it). Unfortunately, this only works as long as the user has -full control over the dependent shared libraries, because the \tts{COMDAT} -symbol could be exported from them just as a side effect of their -implementation (e.g. they use some class internally). When such libraries -are rebuilt even with minor changes in their implementation (unfortunately -with C++ shared libraries it is usually not very clear what part is exported -ABI and what is not), some of those \tts{COMDAT} symbols in them could go -away (e.g. because suddenly they use a different class internally and -the previously used class is not referenced anywhere). When \tts{COMDAT} -objects are not merged across shared libraries, this makes no problems, -as each library which needs the \tts{COMDAT} has its own copy. But with -\tts{COMDAT} duplicate removal between shared libraries there could suddenly -be unresolved references and the shared libraries would need to be relinked. -The only place where this could work safely is when a single package -includes several C++ shared libraries which depend on each other. They are -then shipped always together and when one changes, all others need changing -too. -\end{itemize} - -\section{Prelink optimizations to reduce number of conflict fixups} - -\tts{Prelink} can optimize out some conflict fixups if it can prove that -the changes are not observable by the application at runtime (opening its -executable and reading it doesn't count). If there is a data object in some -shared library with a symbol that is overridden by a symbol in a different -shared library earlier in global symbol lookup scope or in the executable, then -that data object is likely never referenced and it shouldn't matter what it -contains. Examine the following example: - -\noindent{{\small\begin{verbatim} -$ cat > test1.c <<EOF -int i, j, k; -struct A { int *a; int *b; int *c; } x = { &i, &j, &k }; -struct A *y = &x; -EOF -$ cat > test2.c <<EOF -int i, j, k; -struct A { int *a; int *b; int *c; } x = { &i, &j, &k }; -struct A *z = &x; -EOF -$ cat > test.c <<EOF -#include <stdio.h> -extern struct A { int *a; int *b; int *c; } *y, *z; -int main (void) -{ - printf ("%p: %p %p %p\n", y, y->a, y->b, y->c); - printf ("%p: %p %p %p\n", z, z->a, z->b, z->c); -} -EOF -$ gcc -nostdlib -shared -fpic -s -o test1.so test1.c -$ gcc -nostdlib -shared -fpic -o test2.so test2.c ./test1.so -$ gcc -o test test.c ./test2.so ./test1.so -$ ./test -0xaf3314: 0xaf33b0 0xaf33a8 0xaf33ac -0xaf3314: 0xaf33b0 0xaf33a8 0xaf33ac -\end{verbatim}} -\prelinklistingcaption{C example where conflict fixups could be optimized out}} - -In this example there are 3 conflict fixups pointing into the 12 byte -long {\sl x} object in \tts{test1.so} shared library (among other -conflicts). And nothing in the program can poke at {\sl x} content -in \tts{test1.so}, simply because it has to look at it through -{\sl x} symbol which resolves to \tts{test2.so}. So in this -case \tts{prelink} could skip those 3 conflicts. Unfortunately -it is not that easy: - -\noindent{{\small\begin{verbatim} -$ cat > test3.c <<EOF -int i, j, k; -static struct A { int *a; int *b; int *c; } local = { &i, &j, &k }; -extern struct A x; -struct A *y = &x; -struct A *y2 = &local; -extern struct A x __attribute__((alias ("local"))); -EOF -$ cat > test4.c <<EOF -#include <stdio.h> -extern struct A { int *a; int *b; int *c; } *y, *y2, *z; -int main (void) -{ - printf ("%p: %p %p %p\n", y, y->a, y->b, y->c); - printf ("%p: %p %p %p\n", y2, y2->a, y2->b, y2->c); - printf ("%p: %p %p %p\n", z, z->a, z->b, z->c); -} -EOF -$ gcc -nostdlib -shared -fpic -s -o test3.so test3.c -$ gcc -nostdlib -shared -fpic -o test4.so test2.c ./test3.so -$ gcc -o test4 test4.c ./test4.so ./test3.so -$ ./test4 -0x65a314: 0x65a3b0 0x65a3a8 0x65a3ac -0xbd1328: 0x65a3b0 0x65a3a8 0x65a3ac -0x65a314: 0x65a3b0 0x65a3a8 0x65a3ac -\end{verbatim}} -\prelinklistingcaption{Modified C example where conflict fixups cannot be removed}} - -In this example, there are again 3 conflict fixups pointing into the -12 byte long {\sl x} object in \tts{test3.so} shared library. -The fact that variable local is located at the same 12 bytes -is totally invisible to prelink, as local is a \tts{STB\_LOCAL} -symbol which doesn't show up in \tts{.dynsym} section. But if those -3 conflict fixups are removed, then suddenly program's observable -behavior changes (the last 3 addresses on second line would be -different than those on first or third line). - -Fortunately, there are at least some objects where \tts{prelink} -can be reasonably sure they will never be referenced through some -local alias. Those are various compiler generated objects with -well defined meaning which is \tts{prelink} able to identify -in shared libraries. The most important ones are C++ virtual tables -and {\sl RTTI} data. They are emitted as COMDAT data by the compiler, -in GCC into \tts{.gnu.linkonce.d.*} sections. Data or code in these -sections can be accessed only through global symbols, otherwise linker -might create unexpected results when two or more of these sections -are merged together (all but one deleted). When \tts{prelink} is checking -for such data, it first checks whether the shared library in question -is linked against \tts{libstdc++.so}. If not, it is not a C++ library -(or incorrectly built one) and thus it makes no sense to search any further. -It looks only in \tts{.data} section, for \tts{STB\_WEAK} \tts{STT\_OBJECT} -symbols whose names start with certain prefixes -\footnote{\tts{\_\_vt\_} for GCC 2.95.x and 2.96-RH virtual tables, -\tts{\_ZTV} for GCC 3.x virtual tables and \tts{\_ZTI} for GCC 3.x {\sl RTTI} data.} -and where no other symbols (in dynamic symbol table) point into the objects. -If these objects are unused because there is a conflict on their symbol, -all conflict fixups pointing into the virtual table or {\sl RTTI} structure -can be discarded. - -Another possible optimization is again related to C++ virtual tables. -Function addresses in them are not intended for pointer comparisons. -C++ code only loads them from the virtual tables and calls through -the pointer. Pointers to member functions are handled differently. -As pointer equivalence is the only reason why all function pointers -resolve to \tts{PLT} slots in the executable even when the executable doesn't -include implementation of the function (i.e. has \tts{SHN\_UNDEF} symbol -with non-zero \tts{st\_value} pointing at the \tts{PLT} slot in the -executable), \tts{prelink} can resolve method addresses in virtual tables -to the actual method implementation. In many cases this is in the same -library as the virtual table (or in one of libraries in its natural -symbol lookup scope), so a conflict fixup is unnecessary. -This optimization speeds up programs also after control is transfered -to the application and not just the time to start up the application, -although just a few cycles per method call. - -The conflict fixup reduction is quite big on some programs. -Below is statistics for \tts{kmail} program on completely unprelinked box: - -\noindent{{\small\begin{verbatim} -$ LD_DEBUG=statistics /usr/bin/kmail 2>&1 | sed '2,8!d;s/^ *//' -10621: total startup time in dynamic loader: 240724867 clock cycles -10621: time needed for relocation: 234049636 clock cycles (97.2%) -10621: number of relocations: 34854 -10621: number of relocations from cache: 74364 -10621: number of relative relocations: 35351 -10621: time needed to load objects: 6241678 clock cycles (2.5%) -$ ls -l /usr/bin/kmail --rwxr-xr-x 1 root root 2149084 Oct 2 12:05 /usr/bin/kmail -$ ( Xvfb :3 & ) >/dev/null 2>&1 </dev/null; sleep 20 -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10; killall kmail -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10 -$ cat /proc/`/sbin/pidof kmail`/statm -4164 4164 3509 224 33 3907 655 -$ killall Xvfb kdeinit kmail -\end{verbatim}} -\prelinklistingcaption{Statistics for unprelinked \tts{kmail}}} - -\tts{statm} special file for a process contains its memory statistics. -The numbers in it mean in order total number of used pages (on IA-32 -Linux a page is 4KB), number of resident pages (i.e. not swapped out), -number of shared pages, number of text pages, number of library pages, -number of stack and other pages and number of dirty pages used by the -process. Distinction between text and library pages is very rough, -so those numbers aren't that much useful. Of interest are mainly -first number, third number and last number. - -Statistics for \tts{kmail} on completely prelinked box: - -\noindent{{\small\begin{verbatim} -$ LD_DEBUG=statistics /usr/bin/kmail 2>&1 | sed '2,8!d;s/^ *//' -14864: total startup time in dynamic loader: 8409504 clock cycles -14864: time needed for relocation: 3024720 clock cycles (35.9%) -14864: number of relocations: 0 -14864: number of relocations from cache: 8961 -14864: number of relative relocations: 0 -14864: time needed to load objects: 4897336 clock cycles (58.2%) -$ ls -l /usr/bin/kmail --rwxr-xr-x 1 root root 2269500 Oct 2 12:05 /usr/bin/kmail -$ ( Xvfb :3 & ) >/dev/null 2>&1 </dev/null; sleep 20 -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10; killall kmail -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10 -$ cat /proc/`/sbin/pidof kmail`/statm -3803 3803 3186 249 33 3521 617 -$ killall Xvfb kdeinit kmail -\end{verbatim}} -\prelinklistingcaption{Statistics for prelinked \tts{kmail}}} - -Statistics for \tts{kmail} on completely prelinked box with C++ conflict fixup -optimizations turned off: - -\noindent{{\small\begin{verbatim} -$ LD_DEBUG=statistics /usr/bin/kmail 2>&1 | sed '2,8!d;s/^ *//' -20645: total startup time in dynamic loader: 9704168 clock cycles -20645: time needed for relocation: 4734715 clock cycles (48.7%) -20645: number of relocations: 0 -20645: number of relocations from cache: 59871 -20645: number of relative relocations: 0 -20645: time needed to load objects: 4487971 clock cycles (46.2%) -ls -l /usr/bin/kmail --rwxr-xr-x 1 root root 2877360 Oct 2 12:05 /usr/bin/kmail -$ ( Xvfb :3 & ) >/dev/null 2>&1 </dev/null; sleep 20 -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10; killall kmail -$ ( DISPLAY=:3 kmail& ) >/dev/null 2>&1 </dev/null; sleep 10 -$ cat /proc/`/sbin/pidof kmail`/statm -3957 3957 3329 398 33 3526 628 -$ killall Xvfb kdeinit kmail -\end{verbatim}} -\prelinklistingcaption{Statistics for prelinked \tts{kmail} without conflict fixup reduction}} - -On this application, C++ conflict fixup optimizations saved 50910 unneeded -conflict fixups, speeded up startup by 13.3\% and decreased number of dirty -pages by 11, which means the application needs 44KB less memory per-process. - -\section{Thread Local Storage support} - -Thread Local Storage ([12], [13], [14]) support has been recently added to -GCC, GNU binutils and GNU C Library. \tts{TLS} support is a set of new -relocations which together with dynamic linker and POSIX thread library -additions provide faster and easier to use alternative to traditional -POSIX thread local data API (\tts{pthread\_getspecific}, -\tts{pthread\_setspecific}, \tts{pthread\_key\_*}). - -\tts{TLS} necessitated several changes to \tts{prelink}. Thread Local -symbols (with type \tts{STT\_TLS}) must not be relocated, as they are -relative to the start of \tts{PT\_TLS} segment and thus not virtual -addresses. The dynamic linker had to be enhanced so that it tells -\tts{prelink} at \tts{LD\_TRACE\_PRELINKING} time what \tts{TLS} module -IDs have been assigned and what addresses relative to start of \tts{TLS} -block have been given to \tts{PT\_TLS} segment of each library or executable. -There are 3 classes of new \tts{TLS} dynamic relocations \tts{prelink} -is interested in (with different names on different architectures). - -In first class are module ID relocations, which are used for \tts{TLS} -Global Dynamic and Local Dynamic models (for Global Dynamic model -they are supposed to resolve to module ID of the executable or shared library -of particular \tts{STT\_TLS} symbol, for Local Dynamic model this -resolves to module ID of the containing shared library). These -relocations are hard to prelink in any useful way without moving -\tts{TLS} module ID assignment from the dynamic linker to \tts{prelink}. -Although \tts{prelink} can find out what shared library will contain -particular \tts{STT\_TLS} symbol unless there will be conflicts -for that symbol, it doesn't know how many shared libraries with -\tts{PT\_TLS} segment will precede it or whether executable will or -will not have \tts{PT\_TLS} segment. Until \tts{TLS} is widely -deployed by many libraries, \tts{prelink} could guess that -only \tts{libc.so} will have \tts{PT\_TLS} and store 1 (first module ID -the dynamic linker assigns), but given that \tts{libc.so} uses just -one such relocation it is not probably worth doing this when soon other -shared libraries besides \tts{libc.so} and \tts{libGL.so} start using -it heavily. Because of this \tts{prelink} doesn't do anything special -when prelinking shared libraries with these relocations and for each -relocations in this class creates one conflict fixup. - -In second class are relocations which resolve to \tts{st\_value} -of some \tts{STT\_TLS} symbol. These relocations are used in -Global Dynamic \tts{TLS} model (in Local Dynamic they are resolved -at link time already) and from \tts{prelink} point of view they are -much more similar to normal relocations than the other two classes. -When the \tts{STT\_TLS} symbol is looked up successfully in shared library's -natural search scope, \tts{prelink} just stores its \tts{st\_value} -into the relocation. The chances there will be a conflict are even -smaller than with normal symbol lookups, since overloading \tts{TLS} -symbols means wasted memory in each single thread and thus library -writers will try to avoid it if possible. - -The third class includes relocations which resolve to offsets within -program's initial \tts{TLS} block -\footnote{Negative on architectures which have -\tts{TLS} block immediately below thread pointer (e.g. IA-32, AMD64, -SPARC, S/390) and positive on architectures which have \tts{TLS} block -at thread pointer or a few bytes above it (e.g. PowerPC, Alpha, IA-64, -SuperH).} -Relocation in this class are used in Initial Exec \tts{TLS} model -(or in Local Exec model if this model is supported in shared libraries). -These offsets are even harder to predict than module IDs and unlike -module IDs it wouldn't be very helpful if they were assigned by -\tts{prelink} instead of dynamic linker (which would just read them -from some dynamic tag). That's because \tts{TLS} block needs to be -packed tightly and any assignments in \tts{prelink} couldn't take -into account other shared libraries linked into the same executable -and the executable itself. Similarly to module ID relocations, -\tts{prelink} doesn't do anything about them when prelinking shared -libraries and for each such relocation creates a conflict fixup. - -\section{Prelinking of executables and shared libraries} - -Rewriting of executables is harder than for shared libraries, both because -there are more changes necessary and because shared libraries are -relocatable and thus have dynamic relocations for all absolute addresses. - -After collecting all information from the dynamic linker and assigning -virtual address space slots to all shared libraries, prelinking of shared -libraries involves following steps: -\begin{itemize} -\item Relocation of the shared library to the assigned base address. -\item \tts{REL} to \tts{RELA} conversion if needed (the only step which -changes sizes of allocated sections in the middle). -\item On architectures which have \tts{SHT\_NOBITS} \tts{.plt} sections, -before relocations are applied the section needs to be converted to -\tts{SHT\_PROGBITS}. As the section needs to be at the end (or after it) -of file backed part of some \tts{PT\_LOAD} segment, this just means that -the file backed up part needs to be enlarged, the file filled with zeros -and all following section file offsets or program header entry file -offsets adjusted. All \tts{SHT\_NOBITS} sections in the same \tts{PT\_LOAD} -segment with virtual addresses lower than the \tts{.plt} start address -need to be converted from \tts{SHT\_NOBITS} to \tts{SHT\_PROGBITS} too. -Without making the section \tts{SHT\_PROGBITS}, \tts{prelink} cannot -apply relocations against it as such sections contain only zeros. -Architectures with \tts{SHT\_NOBITS} \tts{.plt} section supported by -\tts{prelink} are PowerPC and PowerPC64. -\item Applying relocations. For each dynamic relocation in the shared -library, address of relocation's symbol looked up in natural symbol lookup -search scope of the shared library (or 0 if the symbol is not found in -that search scope) is stored in an architecture and relocation type -dependent way to memory pointed by \tts{r\_offset} field of the relocation. -This step uses symbol lookup information provided by dynamic linker. -\item Addition or modification of \tts{DT\_CHECKSUM} and -\tts{DT\_GNU\_PRELINKED} dynamic tags. -\footnote{\tts{Prelink} is not able to grow \tts{.dynamic} section, so it -needs some spare dynamic tags (DT\_NULL) at the end of \tts{.dynamic} -section. GNU linker versions released after August 2001 leave space by -default.} The former is set to checksum of allocated sections in the -shared library, the latter to time of prelinking. -\item On architectures which don't use writable \tts{.plt}, but instead use -\tts{.got.plt} (this section is merged during linking into \tts{.got}) -section, \tts{prelink} typically stores address into the first PLT slot -in \tts{.plt} section to the reserved second word of \tts{.got} section. -On these architectures, the dynamic linker has to initialize \tts{.plt} -section if lazy binding. On non-prelinked executables or shared libraries -this typically means adding load offset to the values in \tts{.got.plt} -section, for prelinked shared libraries or executables if prelinking -information cannot be used it needs to compute the right values in -\tts{.got.plt} section without looking at this section's content -(since it contains prelinking information). The second word in \tts{.got} -section is used for this computation. -\item Addition of \tts{.gnu\_prelink\_undo} unallocated section if not -present yet. This section is used by \tts{prelink} internally during -undo operation. -\item Addition of \tts{.gnu\_liblist} and \tts{.gnu\_libstr} unallocated -sections or, if they are already present, their update including possible -growing or shrinking. These sections are used only by \tts{prelink} to -compare the dependent libraries (and their order) at the time when the -shared library was prelinked against current dependencies. If a shared -library has no dependencies (e.g. dynamic linker), these sections are not -present. -\end{itemize} - -Adding or resizing unallocated section needs just file offsets of following -unallocated sections recomputed (ensuring proper alignment), growing section -header table and \tts{.shstrtab} and adding new section names to that section. - -Prelinking of executables involves following steps: -\begin{itemize} -\item \tts{REL} to \tts{RELA} conversion if needed. -\item \tts{SHT\_NOBITS} to \tts{SHT\_PROGBITS} conversion of \tts{.plt} section -if needed. -\item Applying relocations. -\item Addition or resizing of allocated \tts{.gnu.conflict} section containing -list of conflict fixups. -\item Addition or resizing of allocated \tts{.gnu.liblist} section which is used -by the dynamic linker at runtime to see if none of the dependencies changed -or were reordered. If they were, it continues normal relocation processing, -otherwise they can be skipped and only conflict fixups applied. -\item Growing of allocated \tts{.dynstr} section, where strings referenced from -\tts{.gnu.liblist} section need to be added. -\item If there are any COPY relocations (which \tts{prelink} wants to handle -rather than deferring them as conflict fixups to runtime), they need to be applied. -\item Modifying second word in \tts{.got} section for \tts{.got.plt} using -architectures. -\item Addition or adjusting of dynamic tags which allow the dynamic linker -to find the \tts{.gnu.liblist} and \tts{.gnu.conflict} sections and their -sizes. \tts{DT\_GNU\_CONFLICT} and \tts{DT\_GNU\_CONFLICTSZ} should be present -if there are any conflict fixups. It should contain the virtual address of -the \tts{.gnu.conflict} section start resp. its size in bytes. -\tts{DT\_GNU\_LIBLIST} and \tts{DT\_GNU\_LIBLISTSZ} need to be present in -all prelinked executables and must be equal the to virtual address of -the \tts{.gnu.liblist} section and its size in bytes. -\item Addition of \tts{.gnu\_prelink\_undo} unallocated section if not present. -\end{itemize} - -Executables can have absolute relocations already applied (and without a -dynamic relocation) to virtually any allocated \tts{SHT\_PROGBITS} section -\footnote{One exception is \tts{.interp} special section. It shouldn't have -relocations applied to it, nor any other section should reference it.}, -against almost all allocated \tts{SHT\_PROGBITS} and \tts{SHT\_NOBITS} -sections. This means that when growing, adding or shrinking allocated -sections in executables, all \tts{SHT\_PROGBITS} and \tts{SHT\_NOBITS} section -must keep their original virtual addresses and sizes -\footnote{With a notable exception of splitting one section into two -covering the same virtual address range.}. \tts{Prelink} tries various -places where to put allocated sections which were added or grew: -\begin{itemize} -\item In the unlikely case if there is already some gap between -sections in read-only \tts{PT\_LOAD} segment where the section fits. -\item If the \tts{SHT\_NOBITS} sections are small enough to fit -into a page together with the preceding \tts{SHT\_PROGBITS} section and there -is still some space in the page after the \tts{SHT\_NOBITS} sections. -In this case, \tts{prelink} converts the \tts{SHT\_NOBITS} sections into -\tts{SHT\_PROGBITS} sections, fills them with zeros and adds the new section -after it. This doesn't increase number of \tts{PT\_LOAD} segments, but -unfortunately those added sections are writable. This doesn't matter -much for e.g. \tts{.gnu.conflict} section which is only used before control -is transfered to the program, but could matter for \tts{.dynstr} which is -used even during \tts{dlopen}. -\item On IA-32, executables have for historical reasons base address 0x8048000. -The reason for this was that when stack was put immediately below executables, -stack and the executable could coexist in the same second level page table. -Linux puts the stack typically at the end of virtual address space and so -keeping this exact base address is not really necessary. \tts{Prelink} can -decrease the base address and thus increase size of read-only \tts{PT\_LOAD} -segment while \tts{SHT\_PROGBITS} and \tts{SHT\_NOBITS} section can stay -at their previous addresses. Just their file offsets need to be increased. -All these segment header adjustments need to be done in multiplies of -\tts{ELF} page sizes, so even if \tts{prelink} chose to do similar things -on architectures other than IA-32 which typically start executables on some address -which is a power of 2, it would be only reasonable if \tts{ELF} page size -on that architecture (which can be much bigger than page size used by the -operating system) is very small. -\item Last possibility is to create a new \tts{PT\_LOAD} segment. -\footnote{Linux kernels before 2.4.10 loaded executables which had middle \tts{PT\_LOAD} -segment with \tts{p\_memsz} bigger than \tts{p\_filesz} incorrectly, so -\tts{prelink} should be only used on systems with 2.4.10 or later kernels.} -Section immediately above program header table (typically \tts{.interp}) -has to be moved somewhere else, but if possible close to the beginning -of the executable. The new \tts{PT\_LOAD} segment is then added after the -last \tts{PT\_LOAD} segment. The segment has to be writable even when -all the sections in it are read-only, unless it ends exactly on a page -boundary, because \tts{brk} area starts immediately after the end of last -\tts{PT\_LOAD} segment and the executable expects it to be writable. -\end{itemize} - -So that verification works properly, if there is \tts{.gnu.prelink\_undo} -section in the executable, \tts{prelink} first reshuffles the sections and -segments for the purpose of finding places for the sections to the original -sequence as recorded in the \tts{.gnu.prelink\_undo} section. -Examples of the above mentioned cases: - -\noindent{{\small\begin{verbatim} -$ SEDCMD='s/^.* \.plt.*$/.../;/\[.*\.text/,/\[.*\.got/d' -$ SEDCMD2='/Section to Segment/,$d;/^Key to/,/^Program/d;/^[A-Z]/d;/^ *$/d' -$ cat > test1.c <<EOF -int main (void) { return 0; } -EOF -$ gcc -Wl,--verbose 2>&1 \ - | sed '/^===/,/^===/!d;/^===/d;s/\.rel\.dyn/. += 512; &/' > test1.lds -$ gcc -s -O2 -o test1 test1.c -Wl,-T,test1.lds -$ readelf -Sl ./test1 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08048148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0804816c 00016c 000040 10 A 5 1 4 - [ 5] .dynstr STRTAB 080481ac 0001ac 000045 00 A 0 0 1 - [ 6] .gnu.version VERSYM 080481f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080481fc 0001fc 000020 00 A 5 1 4 - [ 8] .rel.dyn REL 0804841c 00041c 000008 08 A 4 0 4 - [ 9] .rel.plt REL 08048424 000424 000008 08 A 4 b 4 - [10] .init PROGBITS 0804842c 00042c 000017 00 AX 0 0 4 -... - [22] .bss NOBITS 080496f8 0006f8 000004 00 WA 0 0 4 - [23] .comment PROGBITS 00000000 0006f8 000132 00 0 0 1 - [24] .shstrtab STRTAB 00000000 00082a 0000be 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08048000 0x08048000 0x005fc 0x005fc R E 0x1000 - LOAD 0x0005fc 0x080495fc 0x080495fc 0x000fc 0x00100 RW 0x1000 - DYNAMIC 0x000608 0x08049608 0x08049608 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -$ prelink -N ./test1 -$ readelf -Sl ./test1 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08048148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0804816c 00016c 000040 10 A 8 1 4 - [ 5] .gnu.liblist GNU_LIBLIST 080481ac 0001ac 000028 14 A 8 0 4 - [ 6] .gnu.version VERSYM 080481f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080481fc 0001fc 000020 00 A 8 1 4 - [ 8] .dynstr STRTAB 0804821c 00021c 000058 00 A 0 0 1 - [ 9] .gnu.conflict RELA 08048274 000274 0000c0 0c A 4 0 4 - [10] .rel.dyn REL 0804841c 00041c 000008 08 A 4 0 4 - [11] .rel.plt REL 08048424 000424 000008 08 A 4 d 4 - [12] .init PROGBITS 0804842c 00042c 000017 00 AX 0 0 4 -... - [24] .bss NOBITS 080496f8 0006f8 000004 00 WA 0 0 4 - [25] .comment PROGBITS 00000000 0006f8 000132 00 0 0 1 - [26] .gnu.prelink_undo PROGBITS 00000000 00082c 0004d4 01 0 0 4 - [27] .shstrtab STRTAB 00000000 000d00 0000eb 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08048000 0x08048000 0x005fc 0x005fc R E 0x1000 - LOAD 0x0005fc 0x080495fc 0x080495fc 0x000fc 0x00100 RW 0x1000 - DYNAMIC 0x000608 0x08049608 0x08049608 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -\end{verbatim}} -\prelinklistingcaption{Reshuffling of an executable with a gap between sections}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=\textwidth]{gap} -\caption{Reshuffling of an executable with a gap between sections} -\end{figure} - -In the above sample, there was enough space between sections (particularly -between the end of the \tts{.gnu.version\_r} section and the start of \tts{.rel.dyn}) -that the new sections could be added there. - -\noindent{{\small\begin{verbatim} -$ SEDCMD='s/^.* \.plt.*$/.../;/\[.*\.text/,/\[.*\.got/d' -$ SEDCMD2='/Section to Segment/,$d;/^Key to/,/^Program/d;/^[A-Z]/d;/^ *$/d' -$ cat > test2.c <<EOF -int main (void) { return 0; } -EOF -$ gcc -s -O2 -o test2 test2.c -$ readelf -Sl ./test2 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08048148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0804816c 00016c 000040 10 A 5 1 4 - [ 5] .dynstr STRTAB 080481ac 0001ac 000045 00 A 0 0 1 - [ 6] .gnu.version VERSYM 080481f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080481fc 0001fc 000020 00 A 5 1 4 - [ 8] .rel.dyn REL 0804821c 00021c 000008 08 A 4 0 4 - [ 9] .rel.plt REL 08048224 000224 000008 08 A 4 b 4 - [10] .init PROGBITS 0804822c 00022c 000017 00 AX 0 0 4 -... - [22] .bss NOBITS 080494f8 0004f8 000004 00 WA 0 0 4 - [23] .comment PROGBITS 00000000 0004f8 000132 00 0 0 1 - [24] .shstrtab STRTAB 00000000 00062a 0000be 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08048000 0x08048000 0x003fc 0x003fc R E 0x1000 - LOAD 0x0003fc 0x080493fc 0x080493fc 0x000fc 0x00100 RW 0x1000 - DYNAMIC 0x000408 0x08049408 0x08049408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -$ prelink -N ./test2 -$ readelf -Sl ./test2 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08048148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0804816c 00016c 000040 10 A 23 1 4 - [ 5] .gnu.liblist GNU_LIBLIST 080481ac 0001ac 000028 14 A 23 0 4 - [ 6] .gnu.version VERSYM 080481f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080481fc 0001fc 000020 00 A 23 1 4 - [ 8] .rel.dyn REL 0804821c 00021c 000008 08 A 4 0 4 - [ 9] .rel.plt REL 08048224 000224 000008 08 A 4 b 4 - [10] .init PROGBITS 0804822c 00022c 000017 00 AX 0 0 4 -... - [22] .bss PROGBITS 080494f8 0004f8 000004 00 WA 0 0 4 - [23] .dynstr STRTAB 080494fc 0004fc 000058 00 A 0 0 1 - [24] .gnu.conflict RELA 08049554 000554 0000c0 0c A 4 0 4 - [25] .comment PROGBITS 00000000 000614 000132 00 0 0 1 - [26] .gnu.prelink_undo PROGBITS 00000000 000748 0004d4 01 0 0 4 - [27] .shstrtab STRTAB 00000000 000c1c 0000eb 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08048000 0x08048000 0x003fc 0x003fc R E 0x1000 - LOAD 0x0003fc 0x080493fc 0x080493fc 0x00218 0x00218 RW 0x1000 - DYNAMIC 0x000408 0x08049408 0x08049408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -\end{verbatim}} -\prelinklistingcaption{Reshuffling of an executable with small \tts{.bss}}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=\textwidth]{bss} -\caption{Reshuffling of an executable with small \tts{.bss}} -\end{figure} - -In this case \tts{.bss} section was small enough that \tts{prelink} -converted it to \tts{SHT\_PROGBITS}. - -\noindent{{\small\begin{verbatim} -$ SEDCMD='s/^.* \.plt.*$/.../;/\[.*\.text/,/\[.*\.got/d' -$ SEDCMD2='/Section to Segment/,$d;/^Key to/,/^Program/d;/^[A-Z]/d;/^ *$/d' -$ cat > test3.c <<EOF -int foo [4096]; -int main (void) { return 0; } -EOF -$ gcc -s -O2 -o test3 test3.c -$ readelf -Sl ./test3 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08048114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08048128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08048148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0804816c 00016c 000040 10 A 5 1 4 - [ 5] .dynstr STRTAB 080481ac 0001ac 000045 00 A 0 0 1 - [ 6] .gnu.version VERSYM 080481f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080481fc 0001fc 000020 00 A 5 1 4 - [ 8] .rel.dyn REL 0804821c 00021c 000008 08 A 4 0 4 - [ 9] .rel.plt REL 08048224 000224 000008 08 A 4 b 4 - [10] .init PROGBITS 0804822c 00022c 000017 00 AX 0 0 4 -... - [22] .bss NOBITS 08049500 000500 004020 00 WA 0 0 32 - [23] .comment PROGBITS 00000000 000500 000132 00 0 0 1 - [24] .shstrtab STRTAB 00000000 000632 0000be 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08048000 0x08048000 0x003fc 0x003fc R E 0x1000 - LOAD 0x0003fc 0x080493fc 0x080493fc 0x000fc 0x04124 RW 0x1000 - DYNAMIC 0x000408 0x08049408 0x08049408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -$ prelink -N ./test3 -$ readelf -Sl ./test3 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08047114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08047128 000128 000020 00 A 0 0 4 - [ 3] .dynstr STRTAB 08047148 000148 000058 00 A 0 0 1 - [ 4] .gnu.liblist GNU_LIBLIST 080471a0 0001a0 000028 14 A 3 0 4 - [ 5] .gnu.conflict RELA 080471c8 0001c8 0000c0 0c A 7 0 4 - [ 6] .hash HASH 08048148 001148 000024 04 A 7 0 4 - [ 7] .dynsym DYNSYM 0804816c 00116c 000040 10 A 3 1 4 - [ 8] .gnu.version VERSYM 080481f2 0011f2 000008 02 A 7 0 2 - [ 9] .gnu.version_r VERNEED 080481fc 0011fc 000020 00 A 3 1 4 - [10] .rel.dyn REL 0804821c 00121c 000008 08 A 7 0 4 - [11] .rel.plt REL 08048224 001224 000008 08 A 7 d 4 - [12] .init PROGBITS 0804822c 00122c 000017 00 AX 0 0 4 -... - [24] .bss NOBITS 08049500 0014f8 004020 00 WA 0 0 32 - [25] .comment PROGBITS 00000000 0014f8 000132 00 0 0 1 - [26] .gnu.prelink_undo PROGBITS 00000000 00162c 0004d4 01 0 0 4 - [27] .shstrtab STRTAB 00000000 001b00 0000eb 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08047034 0x08047034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08047114 0x08047114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08047000 0x08047000 0x013fc 0x013fc R E 0x1000 - LOAD 0x0013fc 0x080493fc 0x080493fc 0x000fc 0x04124 RW 0x1000 - DYNAMIC 0x001408 0x08049408 0x08049408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08047128 0x08047128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -\end{verbatim}} -\prelinklistingcaption{Reshuffling of an executable with decreasing of base address}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=\textwidth]{basemove} -\caption{Reshuffling of an executable with decreasing of the base address} -\end{figure} - -In \tts{test3} the base address of the executable was decreased by one page and -the new sections added there. - -\noindent{{\small\begin{verbatim} -$ SEDCMD='s/^.* \.plt.*$/.../;/\[.*\.text/,/\[.*\.got/d' -$ SEDCMD2='/Section to Segment/,$d;/^Key to/,/^Program/d;/^[A-Z]/d;/^ *$/d' -$ cat > test4.c <<EOF -int foo [4096]; -int main (void) { return 0; } -EOF -$ gcc -Wl,--verbose 2>&1 \ - | sed '/^===/,/^===/!d;/^===/d;s/0x08048000/0x08000000/' > test4.lds -$ gcc -s -O2 -o test4 test4.c -Wl,-T,test4.lds -$ readelf -Sl ./test4 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08000114 000114 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08000128 000128 000020 00 A 0 0 4 - [ 3] .hash HASH 08000148 000148 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0800016c 00016c 000040 10 A 5 1 4 - [ 5] .dynstr STRTAB 080001ac 0001ac 000045 00 A 0 0 1 - [ 6] .gnu.version VERSYM 080001f2 0001f2 000008 02 A 4 0 2 - [ 7] .gnu.version_r VERNEED 080001fc 0001fc 000020 00 A 5 1 4 - [ 8] .rel.dyn REL 0800021c 00021c 000008 08 A 4 0 4 - [ 9] .rel.plt REL 08000224 000224 000008 08 A 4 b 4 - [10] .init PROGBITS 0800022c 00022c 000017 00 AX 0 0 4 -... - [22] .bss NOBITS 08001500 000500 004020 00 WA 0 0 32 - [23] .comment PROGBITS 00000000 000500 000132 00 0 0 1 - [24] .shstrtab STRTAB 00000000 000632 0000be 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08000034 0x08000034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000114 0x08000114 0x08000114 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08000000 0x08000000 0x003fc 0x003fc R E 0x1000 - LOAD 0x0003fc 0x080013fc 0x080013fc 0x000fc 0x04124 RW 0x1000 - DYNAMIC 0x000408 0x08001408 0x08001408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000128 0x08000128 0x08000128 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -$ prelink -N ./test4 -$ readelf -Sl ./test4 | sed -e "$SEDCMD" -e "$SEDCMD2" - [Nr] Name Type Addr Off Size ES Flg Lk Inf Al - [ 0] NULL 00000000 000000 000000 00 0 0 0 - [ 1] .interp PROGBITS 08000134 000134 000013 00 A 0 0 1 - [ 2] .note.ABI-tag NOTE 08000148 000148 000020 00 A 0 0 4 - [ 3] .hash HASH 08000168 000168 000024 04 A 4 0 4 - [ 4] .dynsym DYNSYM 0800018c 00018c 000040 10 A 22 1 4 - [ 5] .gnu.version VERSYM 080001f2 0001f2 000008 02 A 4 0 2 - [ 6] .gnu.version_r VERNEED 080001fc 0001fc 000020 00 A 22 1 4 - [ 7] .rel.dyn REL 0800021c 00021c 000008 08 A 4 0 4 - [ 8] .rel.plt REL 08000224 000224 000008 08 A 4 a 4 - [ 9] .init PROGBITS 0800022c 00022c 000017 00 AX 0 0 4 -... - [21] .bss NOBITS 08001500 0004f8 004020 00 WA 0 0 32 - [22] .dynstr STRTAB 080064f8 0004f8 000058 00 A 0 0 1 - [23] .gnu.liblist GNU_LIBLIST 08006550 000550 000028 14 A 22 0 4 - [24] .gnu.conflict RELA 08006578 000578 0000c0 0c A 4 0 4 - [25] .comment PROGBITS 00000000 000638 000132 00 0 0 1 - [26] .gnu.prelink_undo PROGBITS 00000000 00076c 0004d4 01 0 0 4 - [27] .shstrtab STRTAB 00000000 000c40 0000eb 00 0 0 1 - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - PHDR 0x000034 0x08000034 0x08000034 0x000e0 0x000e0 R E 0x4 - INTERP 0x000134 0x08000134 0x08000134 0x00013 0x00013 R 0x1 - [Requesting program interpreter: /lib/ld-linux.so.2] - LOAD 0x000000 0x08000000 0x08000000 0x003fc 0x003fc R E 0x1000 - LOAD 0x0003fc 0x080013fc 0x080013fc 0x000fc 0x04124 RW 0x1000 - LOAD 0x0004f8 0x080064f8 0x080064f8 0x00140 0x00140 RW 0x1000 - DYNAMIC 0x000408 0x08001408 0x08001408 0x000c8 0x000c8 RW 0x4 - NOTE 0x000148 0x08000148 0x08000148 0x00020 0x00020 R 0x4 - STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -\end{verbatim}} -\prelinklistingcaption{Reshuffling of an executable with addition of a new segment}} - -\begin{figure}[!ht] -\centering -\includegraphics[width=\textwidth]{newseg} -\caption{Reshuffling of an executable with addition of a new segment} -\end{figure} - -In the last example, base address was not decreased but instead a new -\tts{PT\_LOAD} segment has been added. - -\tts{R\_<arch>\_COPY} relocations are typically against first part of the -\tts{SHT\_NOBITS} \tts{.bss} section. So that \tts{prelink} can apply them, -it needs to first change their section to \tts{SHT\_PROGBITS}, but as \tts{.bss} -section typically occupies much larger part of memory, it is not desirable -to convert \tts{.bss} section into \tts{SHT\_PROGBITS} as whole. A section -cannot be partly \tts{SHT\_PROGBITS} and partly \tts{SHT\_NOBITS}, so \tts{prelink} -first splits the section into two parts, first \tts{.dynbss} which covers area -from the start of \tts{.bss} section up to highest byte to which some COPY -relocation is applied and then the old \tts{.bss}. The first is converted -to \tts{SHT\_PROGBITS} and its size is decreased, the latter stays \tts{SHT\_NOBITS} -and its start address and file offset are adjusted as well as its size decreased. -The dynamic linker handles relocations in the executable last, so \tts{prelink} -cannot just copy memory from the shared library where the symbol of the COPY -relocation has been looked up in. There might be relocations applied by the -dynamic linker in normal relocation processing to the objects, so \tts{prelink} -has to first process the relocations against that memory area. Relocations -which don't need conflict fixups are already applied, so \tts{prelink} just -needs to apply conflict fixups against the memory area, then copy it -to the newly created \tts{.dynbss} section. - -Here is an example which shows various things which COPY relocation handling -in \tts{prelink} needs to deal with: - -\noindent{{\small\begin{verbatim} -$ cat > test1.c <<EOF -struct A { char a; struct A *b; int *c; int *d; }; -int bar, baz; -struct A foo = { 1, &foo, &bar, &baz }; -int *addr (void) { return &baz; } -EOF -$ cat > test.c <<EOF -#include <stdio.h> -struct A { char a; struct A *b; int *c; int *d; }; -int bar, *addr (void), big[8192]; -extern struct A foo; -int main (void) -{ - printf ("%p: %d %p %p %p %p %p\n", &foo, foo.a, foo.b, foo.c, foo.d, - &bar, addr ()); -} -EOF -$ gcc -nostdlib -shared -fpic -s -o test1.so test1.c -$ gcc -s -o test test.c ./test1.so -$ ./test -0x80496c0: 1 0x80496c0 0x80516e0 0x4833a4 0x80516e0 0x4833a4 -$ readelf -r test | sed '/\.rel\.dyn/,/\.rel\.plt/!d;/^0/!d' -080496ac 00000c06 R_386_GLOB_DAT 00000000 __gmon_start__ -080496c0 00000605 R_386_COPY 080496c0 foo -$ readelf -S test | grep bss - [22] .bss NOBITS 080496c0 0006c0 008024 00 WA 0 0 32 -$ prelink -N ./test ./test1.so -$ readelf -s test | grep foo - 6: 080496c0 16 OBJECT GLOBAL DEFAULT 25 foo -$ readelf -s test1.so | grep foo - 15: 004a9314 16 OBJECT GLOBAL DEFAULT 6 foo -$ readelf -r test | sed '/.gnu.conflict/,/\.rel\.dyn/!d;/^0/!d' -004a9318 00000001 R_386_32 080496c0 -004a931c 00000001 R_386_32 080516e0 -005f9874 00000001 R_386_32 fffffff0 -005f9878 00000001 R_386_32 00000001 -005f98bc 00000001 R_386_32 fffffff4 -005f9900 00000001 R_386_32 ffffffec -005f9948 00000001 R_386_32 ffffffdc -005f995c 00000001 R_386_32 ffffffe0 -005f9980 00000001 R_386_32 fffffff8 -005f9988 00000001 R_386_32 ffffffe4 -005f99a4 00000001 R_386_32 ffffffd8 -005f99c4 00000001 R_386_32 ffffffe8 -005f99d8 00000001 R_386_32 08048584 -004c2510 00000007 R_386_JUMP_SLOT 00534460 -004c2514 00000007 R_386_JUMP_SLOT 00534080 -004c2518 00000007 R_386_JUMP_SLOT 00534750 -004c251c 00000007 R_386_JUMP_SLOT 005342c0 -004c2520 00000007 R_386_JUMP_SLOT 00534200 -$ objdump -s -j .dynbss test - -test: file format elf32-i386 - -Contents of section .dynbss: - 80496c0 01000000 c0960408 e0160508 a4934a00 ..............J. -$ objdump -s -j .data test1.so - -test1.so: file format elf32-i386 - -Contents of section .data: - 4a9314 01000000 14934a00 a8934a00 a4934a00 ......J...J...J. -$ readelf -S test | grep bss - [24] .dynbss PROGBITS 080496c0 0016c0 000010 00 WA 0 0 32 - [25] .bss NOBITS 080496d0 0016d0 008014 00 WA 0 0 32 -$ sed 's/8192/1/' test.c > test2.c -$ gcc -s -o test2 test2.c ./test1.so -$ readelf -S test2 | grep bss - [22] .bss NOBITS 080496b0 0006b0 00001c 00 WA 0 0 8 -$ prelink -N ./test2 ./test1.so -$ readelf -S test2 | grep bss - [22] .dynbss PROGBITS 080496b0 0006b0 000010 00 WA 0 0 8 - [23] .bss PROGBITS 080496c0 0006c0 00000c 00 WA 0 0 8 -\end{verbatim}} -\prelinklistingcaption{Relocation handling of \tts{.dynbss} objects}} - -Because \tts{test.c} executable is not compiled as position independent code and -takes address of {\sl foo} variable, a COPY relocation is needed to avoid -dynamic relocation against executable's read-only \tts{PT\_LOAD} segment. -The {\sl foo} object in \tts{test1.so} has one field with no relocations -applied at all, one relocation against the variable itself, one relocation -which needs a conflict fixup (as it is overridden by the variable in the -executable) and one with relocation which doesn't need any fixups. -The first and last field contain already the right values in prelinked -\tts{test1.so}, while second and third one need to be changed for symbol -addresses in the executable (as shown in the \tts{objdump} output). -The conflict fixups against {\sl foo} in \tts{test1.so} need to stay -(unless it is a C++ virtual table or {\sl RTTI} data, i.e. not in this testcase). -In \tts{test}, \tts{prelink} changed \tts{.dynbss} to \tts{SHT\_PROGBITS} -and kept \tts{SHT\_NOBITS} \tts{.bss}, while in slightly modified testcase -(\tts{test2}) the size of \tts{.bss} was small enough that \tts{prelink} -chose to make it \tts{SHT\_PROGBITS} too and grow the read-write -\tts{PT\_LOAD} segment and put \tts{.dynstr} and \tts{.gnu.conflict} -sections after it. - -\section{Prelink undo operation} - -Prelinking of shared libraries and executables is designed to be reversible, -so that prelink operation followed by undo operation generates bitwise -identical file to the original before prelinking. For this operation -\tts{prelink} stores the original \tts{ELF} header, all the program and -all section headers into a \tts{.gnu.prelink\_undo} section before it starts prelinking -an unprelinked executable or shared library. When undoing the modifications, -\tts{prelink} has to convert \tts{RELA} back to \tts{REL} first if \tts{REL} -to \tts{RELA} conversion was done during prelinking and all allocated -sections above it relocated down to adjust for the section shrink. -Relocation types which were changed when trying to avoid \tts{REL} to -\tts{RELA} conversion need to be changed back (e.g. on IA-32, it is -assumed \tts{R\_386\_GLOB\_DAT} relocations should be only those -against \tts{.got} section and \tts{R\_386\_32} relocations in the -remaining places). On \tts{RELA} architectures, the memory pointed -by \tts{r\_offset} field of the relocations needs to be reinitialized -to the values stored there by the linker originally. -For \tts{prelink} it doesn't matter much what this value is (e.g. -always 0, copy of \tts{r\_addend}, etc.), as long as it is computable -from the information \tts{prelink} has during undo operation -\footnote{Such as relocation type, \tts{r\_addend} value, -type, binding, flags or other attributes of relocation's symbol, -what section the relocation points into or the offset within -section it points to.}. The GNU linker had to be changed on several -architectures, so that it stores there such a value, as in several places -the value e.g. depended on original addend before final link (which is -not available anywhere after final link time, since \tts{r\_addend} -field could be adjusted during the final link). -If second word of \tts{.got} section has been modified, it needs -to be reverted back to the original value (on most architectures zero). -In executables, sections which were moved during prelinking need to be -put back and segments added while prelinking must be removed. - -There are 3 different ways how an undo operation can be performed: -\begin{itemize} -\item Undoing individual executables or shared libraries specified on the -command line in place (i.e. when the undo operation is successful, -the prelinked executable or library is atomically replaced with the -undone object). -\item With \tts{-o} option, only a single executable or shared library -given on the command line is undone and stored to the file specified -as \tts{-o} option's argument. -\item With \tts{-ua} options, \tts{prelink} builds a list of executables -in paths written in its config file (plus directories and executables -or libraries from command line) and all shared libraries these executables -depend on. All executables and libraries in the list are then unprelinked. -This option is used to unprelink the whole system. It is not perfect -and needs to be worked on, since e.g. if some executable uses some shared -library which no other executable links against, this executable (and shared -library) is prelinked, then the executable is removed (e.g. uninstalled) -but the shared library is kept, then the shared library is not -unprelinked unless specifically mentioned on the command line. -\end{itemize} - -\section{Verification of prelinked files} - -As \tts{prelink} needs to modify executables and shared libraries installed -on a system, it complicates system integrity verification (e.g. \tts{rpm -V}, -TripWire). These systems store checksums of installed files into some -database and during verification compute them again and compare to the -values stored in the database. On a prelinked system most of the executables -and shared libraries would be reported as modified. \tts{Prelink} offers -a special mode for these systems, in which it verifies that unprelinking -the executable or shared library followed by immediate prelinking (with the -same base address) creates bitwise identical output with the executable -or shared library that's being verified. Furthermore, depending on -other \tts{prelink} options, it either writes the unprelinked image -to its standard output or computes MD5 or SHA1 digest from this unprelinked -image. Mere undo operation to a file and checksumming it is not good -enough, since an intruder could have modified e.g. conflict fixups or -memory which relocations point at, changing a behavior of the program -while file after unprelinking would be unmodified. - -During verification, both \tts{prelink} executable and the dynamic linker -are used, so a proper system integrity verification first checks whether -\tts{prelink} executable (which is statically linked for this reason) hasn't -been modified, then uses \tts{prelink --verify} to verify the dynamic linker -(when verificating \tts{ld.so} the dynamic linker is not executed) -followed by verification of other executables and libraries. - -Verification requires all dependencies of checked object to be unmodified -since last prelinking. If some dependency has been changed or is missing, -\tts{prelink} will report it and return with non-zero exit status. -This is because prelinking depends on their content and so if they are -modified, the executable or shared library might be different to one after -unprelinking followed by prelinking again. In the future, perhaps it -would be possible to even verify executables or shared libraries without -unmodified dependencies, under the assumption that in such case the prelink -information will not be used. It would just need to verify that nothing -else but the information only used when dependencies are up to date -has changed between the executable or library on the filesystem and file -after unprelink followed by prelink cycle. The prelink operation -would need to be modified in this case, so that no information is -collected from the dynamic linker, the list of dependencies is assumed -to be the one stored in the executable and expect it to have identical -number of conflict fixups. - -\section{Measurements} - -There are two areas where \tts{prelink} can speed things up noticeably. -The primary is certainly startup time of big GUI applications where the -dynamic linker spends from 100ms up to a few seconds before giving control -to the application. Another area is when lots of small programs are started -up, but their execution time is rather short, so the startup time which -\tts{prelink} optimizes is a noticeable fraction of the total time. -This is typical for shell scripting. - -First numbers are from \tts{lmbench} benchmark, version 3.0-a3. -Most of the benchmarks in \tts{lmbench} suite measure kernel speed, -so it doesn't matter much whether \tts{prelink} is used or not. -Only in \tts{lat\_proc} benchmark \tts{prelink} shows up visibly. -This benchmark measures 3 different things: -\begin{itemize} -\item {\sl fork proc}, which is \tts{fork()} followed by immediate -\tts{exit(1)} in the child and \tts{wait(0)} in the parent. The results -are (as expected) about the same between unprelinked and prelinked systems. -\item {\sl exec proc}, i.e. \tts{fork()} followed by immediate -\tts{close(1)} and \tts{execve()} of a simple hello world program (this -program is compiled and linked during the benchmark into a temporary -directory and is never prelinked). The numbers are 160$\mu$s to 200$\mu$s -better on prelinked systems, because there is no relocation processing needed -initially in the dynamic linker and because all relative relocations -in \tts{libc.so.6} can be skipped. -\item {\sl sh proc}, i.e. \tts{fork()} followed by immediate \tts{close(1)} -and \tts{execlp("/bin/sh", "sh", "-c", "/tmp/hello", 0)}. Although -the hello world program is not prelinked in this case either, the shell is, -so out of the 900$\mu$s to 1000$\mu$s speedup less than 200$\mu$s can be -accounted on the speed up of the hello world program as in {\sl exec proc} -benchmark and the rest to the speedup of shell startup. -\end{itemize} - -First 4 rows are from running the benchmark on a fully unprelinked system, -the last 4 rows on the same system, but fully prelinked. - -\noindent{{\small\begin{verbatim} - L M B E N C H 3 . 0 S U M M A R Y - ------------------------------------ - (Alpha software, do not distribute) - -Processor, Processes - times in microseconds - smaller is better -------------------------------------------------------------------------- -Host OS Mhz null null open slct sig sig fork exec sh - call I/O stat clos TCP inst hndl proc proc proc ----- ------------ ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- -pork Linux 2.4.22 651 0.53 0.97 6.20 8.10 41.2 1.44 4.30 276. 1497 5403 -pork Linux 2.4.22 651 0.53 0.95 6.14 7.91 37.8 1.43 4.34 274. 1486 5391 -pork Linux 2.4.22 651 0.56 0.94 6.18 8.09 43.4 1.41 4.30 251. 1507 5423 -pork Linux 2.4.22 651 0.53 0.94 6.12 8.09 41.0 1.43 4.40 256. 1497 5385 -pork Linux 2.4.22 651 0.56 0.94 5.79 7.58 39.1 1.41 4.30 271. 1319 4460 -pork Linux 2.4.22 651 0.56 0.92 5.76 7.40 38.9 1.41 4.30 253. 1304 4417 -pork Linux 2.4.22 651 0.56 0.95 6.20 7.83 37.7 1.41 4.37 248. 1323 4481 -pork Linux 2.4.22 651 0.56 1.01 6.04 7.77 37.9 1.43 4.32 256. 1324 4457 -\end{verbatim}} -\prelinklistingcaption{\tts{lmbench} results without and with prelinking}} - -Below is a sample timing of a 239K long configure shell script from GCC -on both unprelinked and prelinked system. Preparation step was following: - -\noindent{{\small\begin{verbatim} -cd; cvs -d :pserver:anoncvs@subversions.gnu.org:/cvsroot/gcc login -# Empty password -cvs -d :pserver:anoncvs@subversions.gnu.org:/cvsroot/gcc -z3 co -D20031103 gcc -mkdir ~/gcc/obj -cd ~/gcc/obj; ../configure i386-redhat-linux; make configure-gcc -\end{verbatim}} -\prelinklistingcaption{Preparation script for shell script tests}} - -On an unprelinked system, the results were: - -\noindent{{\small\begin{verbatim} -cd ~/gcc/obj/gcc -for i in 1 2; do ./config.status --recheck > /dev/null 2>&1; done -for i in 1 2 3 4; do time ./config.status --recheck > /dev/null 2>&1; done - -real 0m4.436s -user 0m1.730s -sys 0m1.260s - -real 0m4.409s -user 0m1.660s -sys 0m1.340s - -real 0m4.431s -user 0m1.810s -sys 0m1.300s - -real 0m4.432s -user 0m1.670s -sys 0m1.210s -\end{verbatim}} -\prelinklistingcaption{Shell script test results on unprelinked system}} - -and on a fully prelinked system: - -\noindent{{\small\begin{verbatim} -cd ~/gcc/obj/gcc -for i in 1 2; do ./config.status --recheck > /dev/null 2>&1; done -for i in 1 2 3 4; do time ./config.status --recheck > /dev/null 2>&1; done - -real 0m4.126s -user 0m1.590s -sys 0m1.240s - -real 0m4.151s -user 0m1.620s -sys 0m1.230s - -real 0m4.161s -user 0m1.600s -sys 0m1.190s - -real 0m4.122s -user 0m1.570s -sys 0m1.230s -\end{verbatim}} -\prelinklistingcaption{Shell script test results on prelinked system}} - -Now timing of a few big GUI programs. All timings were done without X -server running and with \tts{DISPLAY} environment variable not set -(so that when control is transfered to the application, it very soon -finds out there is no X server it can talk to and bail out). The -measurements are done by the dynamic linker in ticks on a 651MHz -dual Pentium III machine, i.e. ticks have to be divided by 651000000 -to get times in seconds. Each application has been run 4 times -and the results with smallest total time spent in the dynamic -linker was chosen. Epiphany WWW browser and Evolution mail client -were chosen as examples of \tts{Gtk+} applications (typically they use -really many shared libraries, but many of them are quite small, -there aren't really many relocations nor conflict fixups and most -of the libraries are written in C) and Konqueror WWW browser and -KWord word processor were chosen as examples of \tts{KDE} applications -(typically they use slightly fewer shared libraries, though -still a lot, most of the shared libraries are written in C++, -have many relocations and cause many conflict fixups, especially -without C++ conflict fixup optimizations in \tts{prelink}). -On non-prelinked system, the timings are done with lazy binding, -i.e. without \tts{LD\_BIND\_NOW=1} set in the environment. -This is because that's how people generally run programs, on the other -side it is not exact apples to apples comparison, since on prelinked -system there is no lazy binding with the exception of shared libraries -loaded through \tts{dlopen}. So when control is passed to the application, -prelinked programs should be slightly faster for a while since non-prelinked -programs will have to do symbol lookups and processing relocations -(and on various architectures flushing instruction caches) whenever -they call some function they haven't called before in particular shared -library or in the executable. - -\noindent{{\small\begin{verbatim} -$ ldd `which epiphany-bin` | wc -l - 64 -$ # Unprelinked system -$ LD_DEBUG=statistics epiphany-bin 2>&1 | sed 's/^ *//' -18960: -18960: runtime linker statistics: -18960: total startup time in dynamic loader: 67336593 clock cycles -18960: time needed for relocation: 58119983 clock cycles (86.3%) -18960: number of relocations: 6999 -18960: number of relocations from cache: 4770 -18960: number of relative relocations: 31494 -18960: time needed to load objects: 8696104 clock cycles (12.9%) - -(epiphany-bin:18960): Gtk-WARNING **: cannot open display: -18960: -18960: runtime linker statistics: -18960: final number of relocations: 7692 -18960: final number of relocations from cache: 4770 -$ # Prelinked system -$ LD_DEBUG=statistics epiphany-bin 2>&1 | sed 's/^ *//' -25697: -25697: runtime linker statistics: -25697: total startup time in dynamic loader: 7313721 clock cycles -25697: time needed for relocation: 565680 clock cycles (7.7%) -25697: number of relocations: 0 -25697: number of relocations from cache: 1205 -25697: number of relative relocations: 0 -25697: time needed to load objects: 6179467 clock cycles (84.4%) - -(epiphany-bin:25697): Gtk-WARNING **: cannot open display: -25697: -25697: runtime linker statistics: -25697: final number of relocations: 31 -25697: final number of relocations from cache: 1205 - -$ ldd `which evolution` | wc -l - 68 -$ # Unprelinked system -$ LD_DEBUG=statistics evolution 2>&1 | sed 's/^ *//' -19042: -19042: runtime linker statistics: -19042: total startup time in dynamic loader: 54382122 clock cycles -19042: time needed for relocation: 43403190 clock cycles (79.8%) -19042: number of relocations: 3452 -19042: number of relocations from cache: 2885 -19042: number of relative relocations: 34957 -19042: time needed to load objects: 10450142 clock cycles (19.2%) - -(evolution:19042): Gtk-WARNING **: cannot open display: -19042: -19042: runtime linker statistics: -19042: final number of relocations: 4075 -19042: final number of relocations from cache: 2885 -$ # Prelinked system -$ LD_DEBUG=statistics evolution 2>&1 | sed 's/^ *//' -25723: -25723: runtime linker statistics: -25723: total startup time in dynamic loader: 9176140 clock cycles -25723: time needed for relocation: 203783 clock cycles (2.2%) -25723: number of relocations: 0 -25723: number of relocations from cache: 525 -25723: number of relative relocations: 0 -25723: time needed to load objects: 8405157 clock cycles (91.5%) - -(evolution:25723): Gtk-WARNING **: cannot open display: -25723: -25723: runtime linker statistics: -25723: final number of relocations: 31 -25723: final number of relocations from cache: 525 - -$ ldd `which konqueror` | wc -l - 37 -$ # Unprelinked system -$ LD_DEBUG=statistics konqueror 2>&1 | sed 's/^ *//' -18979: -18979: runtime linker statistics: -18979: total startup time in dynamic loader: 131985703 clock cycles -18979: time needed for relocation: 127341077 clock cycles (96.4%) -18979: number of relocations: 25473 -18979: number of relocations from cache: 53594 -18979: number of relative relocations: 31171 -18979: time needed to load objects: 4318803 clock cycles (3.2%) -konqueror: cannot connect to X server -18979: -18979: runtime linker statistics: -18979: final number of relocations: 25759 -18979: final number of relocations from cache: 53594 -$ # Prelinked system -$ LD_DEBUG=statistics konqueror 2>&1 | sed 's/^ *//' -25733: -25733: runtime linker statistics: -25733: total startup time in dynamic loader: 5533696 clock cycles -25733: time needed for relocation: 1941489 clock cycles (35.0%) -25733: number of relocations: 0 -25733: number of relocations from cache: 2066 -25733: number of relative relocations: 0 -25733: time needed to load objects: 3217736 clock cycles (58.1%) -konqueror: cannot connect to X server -25733: -25733: runtime linker statistics: -25733: final number of relocations: 0 -25733: final number of relocations from cache: 2066 - -$ ldd `which kword` | wc -l - 40 -$ # Unprelinked system -$ LD_DEBUG=statistics kword 2>&1 | sed 's/^ *//' -19065: -19065: runtime linker statistics: -19065: total startup time in dynamic loader: 153684591 clock cycles -19065: time needed for relocation: 148255294 clock cycles (96.4%) -19065: number of relocations: 26231 -19065: number of relocations from cache: 55833 -19065: number of relative relocations: 30660 -19065: time needed to load objects: 5068746 clock cycles (3.2%) -kword: cannot connect to X server -19065: -19065: runtime linker statistics: -19065: final number of relocations: 26528 -19065: final number of relocations from cache: 55833 -$ # Prelinked system -$ LD_DEBUG=statistics kword 2>&1 | sed 's/^ *//' -25749: -25749: runtime linker statistics: -25749: total startup time in dynamic loader: 6516635 clock cycles -25749: time needed for relocation: 2106856 clock cycles (32.3%) -25749: number of relocations: 0 -25749: number of relocations from cache: 2130 -25749: number of relative relocations: 0 -25749: time needed to load objects: 4008585 clock cycles (61.5%) -kword: cannot connect to X server -25749: -25749: runtime linker statistics: -25749: final number of relocations: 0 -25749: final number of relocations from cache: 2130 -\end{verbatim}} -\prelinklistingcaption{Dynamic linker statistics for unprelinked and prelinked GUI programs}} - -In the case of above mentioned \tts{Gtk+} applications, the original startup -time spent in the dynamic linker decreased into 11\% to 17\% of the original -times, with \tts{KDE} applications it decreased even into around 4.2\% of original -times. - -The startup time reported by the dynamic linker is only part of the total -startup time of a GUI program. Unfortunately it cannot be measured very -accurately without patching each application separately, so that it would -print current process CPU time at the point when all windows are painted and -the process starts waiting for user input. The following table contains -values reported by \tts{time(1)} command on each of the 4 GUI programs -running under X, both on unprelinked and fully prelinked system. -As soon as each program painted its windows, it was killed by -application's quit hot key -\footnote{\tts{Ctrl+W} for Epiphany, \tts{Ctrl+Q} for Evolution and -Konqueror and \tts{Enter} in Kword's document type choice dialog.}. -Especially the \tts{real} time values depend also on the speed of -human reactions, so each measurement was repeated 10 times. All timings -were done with hot caches, after running the applications two times -before measurement. - -\noindent{\small\begin{center} -\begin{longtable}{l|llllllllll|ll} -{\bf Type} & \multicolumn{10}{l|}{\bf Values (in seconds)} & {\bf Average} & {\bf Std.Dev.} \\ -\hline -\endhead -& \multicolumn{10}{l|}{unprelinked epiphany} && \\ -\hline -{real} & {3.053} & {2.84} & {2.996} & {2.901} & {3.019} & {2.929} & {2.883} & {2.975} & {2.922} & {3.026} & {2.954} & {0.0698} \\ -{user} & {2.33} & {2.31} & {2.28} & {2.32} & {2.44} & {2.37} & {2.29} & {2.35} & {2.34} & {2.41} & {2.344} & {0.0508} \\ -{sys} & {0.2} & {0.23} & {0.23} & {0.19} & {0.19} & {0.12} & {0.25} & {0.16} & {0.14} & {0.14} & {0.185} & {0.0440} \\ -\hline -& \multicolumn{10}{l|}{prelinked epiphany} && \\ -\hline -{real} & {2.773} & {2.743} & {2.833} & {2.753} & {2.753} & {2.644} & {2.717} & {2.897} & {2.68} & {2.761} & {2.755} & {0.0716} \\ -{user} & {2.18} & {2.17} & {2.17} & {2.12} & {2.23} & {2.26} & {2.13} & {2.17} & {2.15} & {2.15} & {2.173} & {0.0430} \\ -{sys} & {0.13} & {0.15} & {0.18} & {0.15} & {0.11} & {0.04} & {0.18} & {0.14} & {0.1} & {0.15} & {0.133} & {0.0416} \\ -\hline -& \multicolumn{10}{l|}{unprelinked evolution} && \\ -\hline -{real} & {2.106} & {1.886} & {1.828} & {2.12} & {1.867} & {1.871} & {2.242} & {1.871} & {1.862} & {2.241} & {1.989} & {0.1679} \\ -{user} & {1.12} & {1.09} & {1.15} & {1.19} & {1.17} & {1.23} & {1.15} & {1.11} & {1.17} & {1.14} & {1.152} & {0.0408} \\ -{sys} & {0.1} & {0.11} & {0.13} & {0.07} & {0.1} & {0.05} & {0.11} & {0.11} & {0.09} & {0.08} & {0.095} & {0.0232} \\ -\hline -& \multicolumn{10}{l|}{prelinked evolution} && \\ -\hline -{real} & {1.684} & {1.621} & {1.686} & {1.72} & {1.694} & {1.691} & {1.631} & {1.697} & {1.668} & {1.535} & {1.663} & {0.0541} \\ -{user} & {0.92} & {0.87} & {0.92} & {0.95} & {0.79} & {0.86} & {0.94} & {0.87} & {0.89} & {0.86} & {0.887} & {0.0476} \\ -{sys} & {0.06} & {0.1} & {0.06} & {0.05} & {0.11} & {0.08} & {0.07} & {0.1} & {0.12} & {0.07} & {0.082} & {0.0239} \\ -\hline -& \multicolumn{10}{l|}{unprelinked kword} && \\ -\hline -{real} & {2.111} & {1.414} & {1.36} & {1.356} & {1.259} & {1.383} & {1.28} & {1.321} & {1.252} & {1.407} & {1.414} & {0.2517} \\ -{user} & {1.04} & {0.9} & {0.93} & {0.88} & {0.89} & {0.89} & {0.87} & {0.89} & {0.9} & {0.8} & {0.899} & {0.0597} \\ -{sys} & {0.07} & {0.04} & {0.06} & {0.05} & {0.06} & {0.1} & {0.09} & {0.08} & {0.08} & {0.12} & {0.075} & {0.0242} \\ -\hline -& \multicolumn{10}{l|}{prelinked kword} && \\ -\hline -{real} & {1.59} & {1.052} & {0.972} & {1.064} & {1.106} & {1.087} & {1.066} & {1.087} & {1.065} & {1.005} & {1.109} & {0.1735} \\ -{user} & {0.61} & {0.53} & {0.58} & {0.6} & {0.6} & {0.58} & {0.59} & {0.61} & {0.57} & {0.6} & {0.587} & {0.0241} \\ -{sys} & {0.08} & {0.08} & {0.06} & {0.06} & {0.03} & {0.07} & {0.06} & {0.03} & {0.06} & {0.04} & {0.057} & {0.0183} \\ -\hline -& \multicolumn{10}{l|}{unprelinked konqueror} && \\ -\hline -{real} & {1.306} & {1.386} & {1.27} & {1.243} & {1.227} & {1.286} & {1.262} & {1.322} & {1.345} & {1.332} & {1.298} & {0.0495} \\ -{user} & {0.88} & {0.86} & {0.88} & {0.9} & {0.87} & {0.83} & {0.83} & {0.86} & {0.86} & {0.89} & {0.866} & {0.0232} \\ -{sys} & {0.07} & {0.11} & {0.12} & {0.1} & {0.12} & {0.08} & {0.13} & {0.12} & {0.09} & {0.08} & {0.102} & {0.0210} \\ -\hline -& \multicolumn{10}{l|}{prelinked konqueror} && \\ -\hline -{real} & {1.056} & {0.962} & {0.961} & {0.906} & {0.927} & {0.923} & {0.933} & {0.958} & {0.955} & {1.142} & {0.972} & {0.0722} \\ -{user} & {0.56} & {0.6} & {0.56} & {0.52} & {0.57} & {0.58} & {0.5} & {0.57} & {0.61} & {0.55} & {0.562} & {0.0334} \\ -{sys} & {0.1} & {0.13} & {0.08} & {0.15} & {0.07} & {0.09} & {0.09} & {0.09} & {0.1} & {0.08} & {0.098} & {0.0244} \\ -\hline -\multicolumn{13}{l}{} \\ -\caption{GUI program start up times without and with prelinking} \\ -\end{longtable} -\end{center}} - -\tts{OpenOffice.org} is probably the largest program these days in Linux, -mostly written in C++. In \tts{OpenOffice.org} 1.1, the main executable, -\tts{soffice.bin}, links directly against 34 shared libraries, but typically -during startup it loads using \tts{dlopen} many others. As has been -mentioned earlier, \tts{prelink} cannot speed up loading shared libraries -using \tts{dlopen}, since it cannot predict in which order and what -shared libraries will be loaded (and thus cannot compute conflict fixups). -The \tts{soffice.bin} is typically started through a wrapper script -and depending on what arguments are passed to it, different -\tts{OpenOffice.org} application is started. With no options, it starts -just empty window with menu from which the applications can be started, -with say \tts{private:factory/swriter} argument it starts -a word processor, with \tts{private:factory/scalc} it starts a spreadsheet -etc. When \tts{soffice.bin} is already running, if you start another -copy of it, it just instructs the already running copy to pop up a new -window and exits. - -In an experiment, \tts{soffice.bin} has been invoked 7 times against running -X server, with no arguments, \tts{private:factory/swriter}, -\tts{private:factory/scalc}, \tts{private:factory/sdraw}, -\tts{private:factory/simpress}, \tts{private:factory/smath} arguments -(in all these cases nothing was pressed at all) and last with -the \tts{private:factory/swriter} argument where the menu item \tts{New Presentation} -was selected and the word processor window closed. -In all these cases, \tts{/proc/`pidof soffice.bin`/maps} file was -captured and the application then killed. This file contains among -other things list of all shared libraries mmapped by the process at -the point where it started waiting for user input after loading up. -These lists were then summarized, to get number of the runs in -which particular shared library was loaded up out of the total 7 -runs. There were 38 shared libraries shipped as part of \tts{OpenOffice.org} -package which have been loaded in all 7 times, another 3 shared -libraries included in \tts{OpenOffice.org} (and also one shared -library shipped in another package, \tts{libdb\_cxx-4.1.so}) -which were loaded 6 times. -\footnote{In all runs but when ran without -arguments. But when the application is started without any -arguments, it cannot do any useful work, so one loads one of the -applications afterward anyway.} There was one shared library -loaded in 5 runs, but was locale specific and thus not worth -considering. Inspecting \tts{OpenOffice.org} source, these shared -libraries are never unloaded with \tts{dlclose}, so \tts{soffice.bin} -can be made much more \tts{prelink} friendly and thus save substantial -amount of startup time by linking against all those 76 shared libraries -instead of just 34 shared libraries it is linked against. -In the timings below, \tts{soffice1.bin} is the original \tts{soffice.bin} -as created by the \tts{OpenOffice.org} makefiles and \tts{soffice3.bin} is -the same executable linked dynamically against additional 42 shared libraries. -The ordering of those 42 shared libraries matters for the number of conflict -fixups, unfortunately with large C++ shared libraries there is no obvious rule -for ordering them as sometimes it is more useful when a shared library precedes -its dependency and sometimes vice versa, so a few different orderings were -tried in several steps and always the one with smallest number of conflict -fixups was chosen. Still, the number of conflict fixups is quite high -and big part of the fixups are storing addresses of \tts{PLT} slots in -the executable into various places in shared libraries -\footnote{This might get better when the linker is modified to handle -calls without ever taking address of the function in executables specially, -but only testing it will actually show it up.} -\tts{soffice2.bin} is another experiment, where the executable itself is empty -source file, all objects which were originally in \tts{soffice.bin} -executable with the exception of start files were recompiled as position independent -code and linked into a new shared library. This reduced number of conflicts -a lot and speeded up start up times against \tts{soffice3.bin} when caches -are hot. It is a little bit slower than \tts{soffice3.bin} when running -with cold caches (e.g. for the first time after bootup), as there is one -more shared library to load etc. - -In the timings below, numbers for \tts{soffice1.bin} and \tts{soffice2.bin} -resp. \tts{soffice3.bin} cannot be easily compared, as \tts{soffice1.bin} -loads less than half of the needed shared libraries which the remaining -two executables load and the time to load those shared libraries doesn't -show up there. Still, when it is prelinked it takes just slightly more -than two times longer to load \tts{soffice2.bin} than \tts{soffice1.bin} -and the times are still less than 7\% of how long it takes to load -just the initial 34 shared libraries when not prelinking. - -\noindent{{\small\begin{verbatim} -$ S='s/^ *//' -$ ldd /usr/lib/openoffice/program/soffice1.bin | wc -l - 34 -$ # Unprelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice1.bin 2>&1 | sed "$S" -19095: -19095: runtime linker statistics: -19095: total startup time in dynamic loader: 159833582 clock cycles -19095: time needed for relocation: 155464174 clock cycles (97.2%) -19095: number of relocations: 31136 -19095: number of relocations from cache: 31702 -19095: number of relative relocations: 18284 -19095: time needed to load objects: 3919645 clock cycles (2.4%) -/usr/lib/openoffice/program/soffice1.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -19095: -19095: runtime linker statistics: -19095: final number of relocations: 31715 -19095: final number of relocations from cache: 31702 -$ # Prelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice1.bin 2>&1 | sed "$S" -25759: -25759: runtime linker statistics: -25759: total startup time in dynamic loader: 4252397 clock cycles -25759: time needed for relocation: 1189840 clock cycles (27.9%) -25759: number of relocations: 0 -25759: number of relocations from cache: 2142 -25759: number of relative relocations: 0 -25759: time needed to load objects: 2604486 clock cycles (61.2%) -/usr/lib/openoffice/program/soffice1.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -25759: -25759: runtime linker statistics: -25759: final number of relocations: 24 -25759: final number of relocations from cache: 2142 -$ ldd /usr/lib/openoffice/program/soffice2.bin | wc -l - 77 -$ # Unprelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice2.bin 2>&1 | sed "$S" -19115: -19115: runtime linker statistics: -19115: total startup time in dynamic loader: 947793670 clock cycles -19115: time needed for relocation: 936895741 clock cycles (98.8%) -19115: number of relocations: 69164 -19115: number of relocations from cache: 94502 -19115: number of relative relocations: 59374 -19115: time needed to load objects: 10046486 clock cycles (1.0%) -/usr/lib/openoffice/program/soffice2.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -19115: -19115: runtime linker statistics: -19115: final number of relocations: 69966 -19115: final number of relocations from cache: 94502 -$ # Prelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice2.bin 2>&1 | sed "$S" -25777: -25777: runtime linker statistics: -25777: total startup time in dynamic loader: 10952099 clock cycles -25777: time needed for relocation: 3254518 clock cycles (29.7%) -25777: number of relocations: 0 -25777: number of relocations from cache: 5309 -25777: number of relative relocations: 0 -25777: time needed to load objects: 6805013 clock cycles (62.1%) -/usr/lib/openoffice/program/soffice2.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -25777: -25777: runtime linker statistics: -25777: final number of relocations: 24 -25777: final number of relocations from cache: 5309 -$ ldd /usr/lib/openoffice/program/soffice3.bin | wc -l - 76 -$ # Unprelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice3.bin 2>&1 | sed "$S" -19131: -19131: runtime linker statistics: -19131: total startup time in dynamic loader: 852275754 clock cycles -19131: time needed for relocation: 840996859 clock cycles (98.6%) -19131: number of relocations: 68362 -19131: number of relocations from cache: 89213 -19131: number of relative relocations: 55831 -19131: time needed to load objects: 10170207 clock cycles (1.1%) -/usr/lib/openoffice/program/soffice3.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -19131: -19131: runtime linker statistics: -19131: final number of relocations: 69177 -19131: final number of relocations from cache: 89213 -$ # Prelinked system -$ LD_DEBUG=statistics /usr/lib/openoffice/program/soffice3.bin 2>&1 | sed "$S" -25847: -25847: runtime linker statistics: -25847: total startup time in dynamic loader: 12277407 clock cycles -25847: time needed for relocation: 4232915 clock cycles (34.4%) -25847: number of relocations: 0 -25847: number of relocations from cache: 8961 -25847: number of relative relocations: 0 -25847: time needed to load objects: 6925023 clock cycles (56.4%) -/usr/lib/openoffice/program/soffice3.bin X11 error: Can't open display: -Set DISPLAY environment variable, use -display option -or check permissions of your X-Server -(See "man X" resp. "man xhost" for details) -25847: -25847: runtime linker statistics: -25847: final number of relocations: 24 -25847: final number of relocations from cache: 8961 -\end{verbatim}} -\prelinklistingcaption{Dynamic linker statistics for unprelinked and prelinked OpenOffice.org}} - -Below are measurement using \tts{time(1)} for each of the \tts{soffice.bin} -variants, prelinked and unprelinked. \tts{OpenOffice.org} was killed -immediately after painting \tts{Writer}'s window using \tts{Ctrl+Q}. - -\noindent{\small\begin{center} -\begin{longtable}{l|llllllllll|ll} -{\bf Type} & \multicolumn{10}{l|}{\bf Values (in seconds)} & {\bf Average} & {\bf Std.Dev.} \\ -\hline -\endhead -& \multicolumn{10}{l|}{unprelinked soffice1.bin private:factory/swriter} && \\ -\hline -{real} & {5.569} & {5.149} & {5.547} & {5.559} & {5.549} & {5.139} & {5.55} & {5.559} & {5.598} & {5.559} & {5.478} & {0.1765} \\ -{user} & {4.65} & {4.57} & {4.62} & {4.64} & {4.57} & {4.55} & {4.65} & {4.49} & {4.52} & {4.46} & {4.572} & {0.0680} \\ -{sys} & {0.29} & {0.24} & {0.19} & {0.21} & {0.21} & {0.21} & {0.25} & {0.25} & {0.27} & {0.26} & {0.238} & {0.0319} \\ -\hline -& \multicolumn{10}{l|}{prelinked soffice1.bin private:factory/swriter} && \\ -\hline -{real} & {4.946} & {4.899} & {5.291} & {4.879} & {4.879} & {4.898} & {5.299} & {4.901} & {4.887} & {4.901} & {4.978} & {0.1681} \\ -{user} & {4.23} & {4.27} & {4.18} & {4.24} & {4.17} & {4.22} & {4.15} & {4.25} & {4.26} & {4.31} & {4.228} & {0.0494} \\ -{sys} & {0.22} & {0.22} & {0.24} & {0.26} & {0.3} & {0.26} & {0.29} & {0.17} & {0.21} & {0.23} & {0.24} & {0.0389} \\ -\hline -& \multicolumn{10}{l|}{unprelinked soffice2.bin private:factory/swriter} && \\ -\hline -{real} & {5.575} & {5.166} & {5.592} & {5.149} & {5.571} & {5.559} & {5.159} & {5.157} & {5.569} & {5.149} & {5.365} & {0.2201} \\ -{user} & {4.59} & {4.5} & {4.57} & {4.37} & {4.47} & {4.57} & {4.56} & {4.41} & {4.63} & {4.5} & {4.517} & {0.0826} \\ -{sys} & {0.24} & {0.24} & {0.21} & {0.34} & {0.27} & {0.19} & {0.19} & {0.27} & {0.19} & {0.29} & {0.243} & {0.0501} \\ -\hline -& \multicolumn{10}{l|}{prelinked soffice2.bin private:factory/swriter} && \\ -\hline -{real} & {3.69} & {3.66} & {3.658} & {3.661} & {3.639} & {3.638} & {3.649} & {3.659} & {3.65} & {3.659} & {3.656} & {0.0146} \\ -{user} & {2.93} & {2.88} & {2.88} & {2.9} & {2.84} & {2.63} & {2.89} & {2.85} & {2.77} & {2.83} & {2.84} & {0.0860} \\ -{sys} & {0.22} & {0.18} & {0.23} & {0.2} & {0.18} & {0.29} & {0.22} & {0.23} & {0.24} & {0.22} & {0.221} & {0.0318} \\ -\hline -& \multicolumn{10}{l|}{unprelinked soffice3.bin private:factory/swriter} && \\ -\hline -{real} & {5.031} & {5.02} & {5.009} & {5.028} & {5.019} & {5.019} & {5.019} & {5.052} & {5.426} & {5.029} & {5.065} & {0.1273} \\ -{user} & {4.31} & {4.35} & {4.34} & {4.3} & {4.38} & {4.29} & {4.45} & {4.37} & {4.38} & {4.44} & {4.361} & {0.0547} \\ -{sys} & {0.27} & {0.25} & {0.26} & {0.27} & {0.27} & {0.31} & {0.18} & {0.17} & {0.16} & {0.15} & {0.229} & {0.0576} \\ -\hline -& \multicolumn{10}{l|}{prelinked soffice3.bin private:factory/swriter} && \\ -\hline -{real} & {3.705} & {3.669} & {3.659} & {3.669} & {3.66} & {3.659} & {3.659} & {3.661} & {3.668} & {3.649} & {3.666} & {0.0151} \\ -{user} & {2.86} & {2.88} & {2.85} & {2.84} & {2.83} & {2.86} & {2.84} & {2.91} & {2.86} & {2.8} & {2.853} & {0.0295} \\ -{sys} & {0.26} & {0.19} & {0.27} & {0.25} & {0.24} & {0.23} & {0.28} & {0.21} & {0.21} & {0.27} & {0.241} & {0.0303} \\ -\hline -\multicolumn{13}{l}{} \\ -\caption{OpenOffice.org start up times without and with prelinking} \\ -\end{longtable} -\end{center}} - -\section{Similar tools on other ELF using Operating Systems} - -Something similar to \tts{prelink} is available on other \tts{ELF} -platforms. On Irix there is \tts{QUICKSTART} and on Solaris \tts{crle}. - -SGI \tts{QUICKSTART} is much closer to \tts{prelink} from these two. -The \tts{rqs} program relocates libraries to (if possible) unique -virtual address space slot. The base address is either specified -on the command line with the \tts{-l} option, or \tts{rqs} uses -a \tts{so\_locations} registry with \tts{-c} or \tts{-u} options -and finds a not yet occupied slot. This is similar to how \tts{prelink} -lays out libraries without the \tts{-m} option. - -\tts{QUICKSTART} uses the same data structure for library lists -(\tts{ElfNN\_Lib}) as \tts{prelink}, but uses more fields in it -(\tts{prelink} doesn't use \tts{l\_version} and \tts{l\_flags} fields at -the moment) and uses different dynamic tags and section type for -it. Another difference is that \tts{QUICKSTART} makes all liblist -section \tts{SHF\_ALLOC}, whether in shared libraries or executables. -\tts{prelink} only needs liblist section in the executable be allocated, -liblist sections in shared libraries are not allocated and used -at \tts{prelink} time only. - -The biggest difference between \tts{QUICKSTART} and \tts{prelink} -is in how conflicts are encoded. SGI stores them in a very compact -format, as array of \tts{.dynsym} section indexes for symbols which -are conflicting. There is no information publicly available -what exactly SGI dynamic linker does when it is resolving the conflicts, -so this is just a guess. Given that the conflicts can be stored -in a shared library or executable different to the shared library with the -relocations against the conflicting symbol and different to the shared -library which the symbol was originally resolved to, there doesn't seem -to be an obvious way how to handle the conflicts very cheaply. -The dynamic linker probably collects list of all conflicting symbol -names, for each such symbol computes \tts{ELF} hash and walks hash buckets -for this hash of all shared libraries, looking for the symbol. -Every time it finds the symbol, all relocations against it need to be -redone. Unlike this, \tts{prelink} stores conflicts as an array of -\tts{ElfNN\_Rela} structures, with one entry for each shared relocation -against conflicting symbol in some shared library. This guarantees -that there are no symbol lookups during program startup (provided -that shared libraries have not been changed after prelinking), while -with \tts{QUICKSTART} will do some symbol lookups if there are any -conflicts. \tts{QUICKSTART} puts conflict sections into the executable -and every shared library where \tts{rqs} determines conflicts while -\tts{prelink} stores them in the executable only (but the array is typically -much bigger). Disk space requirements for prelinked executables are certainly -bigger than for requickstarted executables, but which one has bigger runtime -memory requirements is unclear. If prelinking can be used, all \tts{.rela*} -and \tts{.rel*} sections in the executable and all shared libraries are skipped, -so they will not need to be paged in during whole program's life (with the -exception of first and last pages in the relocation sections which can be -paged in because of other sections on the same page), but whole -\tts{.gnu.conflict} section needs to be paged in (read-only) and processed. -With \tts{QUICKSTART}, probably all (much smaller) conflict sections need -to be paged in and also likely for each conflict whole relocation sections -of each library which needs the conflict to be applied against. - -In \tts{QUICKSTART} documentation, SGI says that conflicts are very costly -and that developers should avoid them. Unfortunately, this is sometimes quite -hard, especially with C++ shared libraries. It is unclear whether \tts{rqs} -does any optimizations to trim down the number of conflicts. - -Sun took completely different approach. The dynamic linker provides a -\tts{dldump (const char *ipath, const char *opath, int flags);} function. -{\sl ipath} is supposed to be a path to an \tts{ELF} object loaded already in -the current process. This function creates a new \tts{ELF} object at -{\sl opath}, which is like the {\sl ipath} object, but relocated to the -base address which it has actually been mapped at in the current process -and with some relocations (specified in {\sl flags} bitmask) applied as -they have been resolved in the current process. Relocations, which have -been applied, are overwritten in the relocation sections with -\tts{R\_*\_NONE} relocations. The \tts{crle} executable, in addition to other -functions not related to startup times, with some specific options uses the -\tts{dldump} function to dump all shared libraries a particular executable -uses (and the executable itself) into a new directory, with selected -relocation classes being already applied. The main disadvantage of this -approach is that such alternate shared libraries are at least for -most relocation classes not shareable across different programs at all -(and for those where they could be shareable a little bit there will -be many relocations left for the dynamic linker, so the speed gains will -be small). Another disadvantage is that all relocation sections need to -be paged into the memory, just to find out that most of the relocations -are \tts{R\_*\_NONE}. - -\section{ELF extensions for prelink} - -\tts{Prelink} needs a few \tts{ELF} extensions for its data structures -in \tts{ELF} objects. For list of dependencies at the time of prelinking, -a new section type \tts{SHT\_GNU\_LIBLIST} is defined: - -\noindent{{\small\begin{verbatim} -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ - -typedef struct -{ - Elf32_Word l_name; /* Name (string table index) */ - Elf32_Word l_time_stamp; /* Timestamp */ - Elf32_Word l_checksum; /* Checksum */ - Elf32_Word l_version; /* Unused, should be zero */ - Elf32_Word l_flags; /* Unused, should be zero */ -} Elf32_Lib; - -typedef struct -{ - Elf64_Word l_name; /* Name (string table index) */ - Elf64_Word l_time_stamp; /* Timestamp */ - Elf64_Word l_checksum; /* Checksum */ - Elf64_Word l_version; /* Unused, should be zero */ - Elf64_Word l_flags; /* Unused, should be zero */ -} Elf64_Lib; -\end{verbatim}} -\prelinklistingcaption{New structures and section type constants used by \tts{prelink}}} - -Introduces a few new special sections: - -\noindent{\begin{center} -\begin{longtable}{l|lc} -{\bf Name} & {\bf Type} & {\bf Attributes} \\ -\hline -& {\sl In shared libraries} & \\ -{.gnu.liblist} & {SHT\_GNU\_LIBLIST} & {0} \\ -{.gnu.libstr} & {SHT\_STRTAB} & {0} \\ -{.gnu.prelink\_undo} & {SHT\_PROGBITS} & {0} \\ -\hline -& {\sl In executables} & \\ -{.gnu.liblist} & {SHT\_GNU\_LIBLIST} & {SHF\_ALLOC} \\ -{.gnu.conflict} & {SHT\_RELA} & {SHF\_ALLOC} \\ -{.gnu.prelink\_undo} & {SHT\_PROGBITS} & {0} \\ -\multicolumn{3}{l}{} \\ -\caption{Special sections introduced by \tts{prelink}} \\ -\end{longtable} -\end{center}} - -\begin{description} -\item[\tts{.gnu.liblist}] This section contains one \tts{ElfNN\_Lib} structure -for each shared library which the object has been prelinked against, -in the order in which they appear in symbol search scope. -Section's \tts{sh\_link} value should contain section index of \tts{.gnu.libstr} -for shared libraries and section index of \tts{.dynsym} for executables. -\tts{l\_name} field contains the dependent library's name as index -into the section pointed by\tts{sh\_link} field. \tts{l\_time\_stamp} -resp. \tts{l\_checksum} should contain copies of \tts{DT\_GNU\_PRELINKED} -resp. \tts{DT\_CHECKSUM} values of the dependent library. - -\item[\tts{.gnu.conflict}] This section contains one \tts{ElfNN\_Rela} -structure for each needed \tts{prelink} conflict fixup. \tts{r\_offset} -field contains the absolute address at which the fixup needs to be applied, -\tts{r\_addend} the value that needs to be stored at that location. -\tts{ELFNN\_R\_SYM} of \tts{r\_info} field should be zero, -\tts{ELFNN\_R\_TYPE} of \tts{r\_info} field should be architecture -specific relocation type which should be handled the same as -for \tts{.rela.*} sections on the architecture. For \tts{EM\_ALPHA} machine, -all types with \tts{R\_ALPHA\_JMP\_SLOT} in lowest 8 bits of \tts{ELF64\_R\_TYPE} -should be handled as \tts{R\_ALPHA\_JMP\_SLOT} relocation, the upper -24 bits contains index in original \tts{.rela.plt} section of the -\tts{R\_ALPHA\_JMP\_SLOT} relocation the fixup was created for. - -\item[\tts{.gnu.libstr}] This section contains strings for \tts{.gnu.liblist} -section in shared libraries where \tts{.gnu.liblist} section is not -allocated. - -\item[\tts{.gnu.prelink\_undo}] This section contains \tts{prelink} private -data used for \tts{prelink --undo} operation. This data includes the -original \tts{ElfNN\_Ehdr} of the object before prelinking and all its -original \tts{ElfNN\_Phdr} and \tts{ElfNN\_Shdr} headers. -\end{description} - -\tts{Prelink} also defines 6 new dynamic tags: - -\noindent{{\small\begin{verbatim} -#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -#define DT_CHECKSUM 0x6ffffdf8 /* Library checksum */ - -#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -\end{verbatim}} -\prelinklistingcaption{\tts{Prelink} dynamic tags}} - -\tts{DT\_GNU\_PRELINKED} and \tts{DT\_CHECKSUM} dynamic tags must -be present in prelinked shared libraries. The corresponding -\tts{d\_un.d\_val} fields should contain time when the library -has been prelinked (in seconds since January, 1st, 1970, 00:00 UTC) -resp. \tts{CRC32} checksum of all sections with one of -\tts{SHF\_ALLOC}, \tts{SHF\_WRITE} or \tts{SHF\_EXECINSTR} bit set -whose type is not \tts{SHT\_NOBITS}, in the order they appear in the -shared library's section header table, with \tts{DT\_GNU\_PRELINKED} -and \tts{DT\_CHECKSUM} \tts{d\_un.v\_val} values set to 0 for -the time of checksum computation. - -The \tts{DT\_GNU\_LIBLIST} and \tts{DT\_GNU\_LIBLISTSZ} dynamic tags -must be present in all prelinked executables. The \tts{d\_un.d\_ptr} value of -the \tts{DT\_GNU\_LIBLIST} dynamic tag contains the virtual address -of the \tts{.gnu.liblist} section in the executable and \tts{d\_un.d\_val} -of \tts{DT\_GNU\_LIBLISTSZ} tag contains its size in bytes. - -\tts{DT\_GNU\_CONFLICT} and \tts{DT\_GNU\_CONFLICTSZ} dynamic tags -may be present in prelinked executables. \tts{d\_un.d\_ptr} of -\tts{DT\_GNU\_CONFLICT} dynamic tag contains the virtual address -of \tts{.gnu.conflict} section in the executable (if present) -and \tts{d\_un.d\_val} of \tts{DT\_GNU\_CONFLICTSZ} tag contains -its size in bytes. - -\begin{appendix} - -\section{Glossary} -\printglossary - -\section{References} - -\begin{description} -\item[\textrm{[1]}] -\href{http://www.caldera.com/developers/devspecs/gabi41.pdf}% -{\sl System V Application Binary Interface, Edition 4.1}. - -\item[\textrm{[2]}] -\href{http://www.caldera.com/developers/devspecs/abi386-4.pdf}% -{\sl System V Application Binary Interface, Intel 386 Architecture Processor -Supplement}. - -\item[\textrm{[3]}] -\href{http://www.x86-64.org/cgi-bin/cvsweb.cgi/x86-64-ABI/}% -{\sl System V Application Binary Interface, AMD64 Architecture Processor -Supplement}. - -\item[\textrm{[4]}] -\href{http://refspecs.freestandards.org/elf/IA64-SysV-psABI.pdf}% -{{\sl System V Application Binary Interface, Intel Itanium Architecture Processor -Supplement}, Intel Corporation, 2001}. - -\item[\textrm{[5]}] -\href{http://refspecs.freestandards.org/elf/elfspec_ppc.pdf}% -{Steve Zucker, Kari Karhi, {\sl System V Application Binary Interface, -PowerPC Architecture Processor Supplement}, SunSoft, IBM, 1995}. - -\item[\textrm{[6]}] -\href{ftp://ftp.linuxppc64.org/pub/people/amodra/PPC-elf64abi.txt.gz}% -{\sl System V Application Binary Interface, PowerPC64 Architecture Processor -Supplement}. - -\item[\textrm{[7]}] -\href{http://www.arm.com/support/566FHT/$File/ARMELF.pdf}% -{\sl System V Application Binary Interface, ARM Architecture Processor -Supplement}. - -\item[\textrm{[8]}] -\href{http://www.sparc.com/standards/SCD.2.4.1.ps.Z}% -{{\sl SPARC Compliance Definition, Version 2.4.1}, -SPARC International, Inc., 1999}. - -\item[\textrm{[9]}] -\href{http://people.redhat.com/drepper/dsohowto.pdf}% -{Ulrich Drepper, {\sl How To Write Shared Libraries}, Red Hat, Inc., 2003}. - -\item[\textrm{[10]}] -\href{http://docs.sun.com/db/doc/816-1386}% -{{\sl Linker And Library Guide}, Sun Microsystems, 2002}. - -\item[\textrm{[11]}] -\href{http://www.gzlinux.org/docs/category/dev/c/linkerandloader.pdf}% -{John R. Levine, {\sl Linkers and Loaders}, 1999}. - -\item[\textrm{[12]}] -\href{http://people.redhat.com/drepper/tls.pdf}% -{Ulrich Drepper, {\sl ELF Handling For Thread-Local Storage}, Red Hat, Inc., -2003}. - -\item[\textrm{[13]}] -\href{ftp://ftp.linuxppc64.org/pub/people/amodra/ppc32tls.txt.gz}% -{Alan Modra, {\sl PowerPC Specific Thread Local Storage ABI}, 2003}. - -\item[\textrm{[14]}] -\href{ftp://ftp.linuxppc64.org/pub/people/amodra/ppc64tls.txt.gz}% -{Alan Modra, {\sl PowerPC64 Specific Thread Local Storage ABI}, 2003}. - -\item[\textrm{[15]}] -\href{http://www.eagercon.com/dwarf/dwarf-2.0.0.pdf}% -{\sl DWARF Debugging Information Format Version 2}. - -\item[\textrm{[16]}] -\href{http://reality.sgiweb.org/davea/dwarf3-draft8-011125.pdf}% -{{\sl DWARF Debugging Information Format Version 3}, Draft, 2001}. - -\item[\textrm{[17]}] -\href{http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/doc/stabs.texinfo?cvsroot=src}% -{\sl The "stabs" debugging information format}. -\end{description} - - -\section{Revision History} - -\begin{description} -\item[2003-11-03] First draft. - - -\end{description} - -\end{appendix} - -\end{document} diff --git a/trunk/doc/prelinklisting.sty b/trunk/doc/prelinklisting.sty deleted file mode 100644 index f0aff06..0000000 --- a/trunk/doc/prelinklisting.sty +++ /dev/null @@ -1,41 +0,0 @@ -\NeedsTeXFormat{LaTeX2e}[2003/12/06] -\ProvidesPackage{prelinklisting}[] -\newcounter{prelinklisting} -\renewcommand\theprelinklisting{\@arabic\c@prelinklisting} -\newcommand\prelinklistingname{Listing} -\newcommand\listprelinklistingname{List of Listings} -\def\fps@prelinklisting{tbp} -\def\ftype@prelinklisting{5} -\def\ext@prelinklisting{lol} -\def\fnum@prelinklisting{\prelinklistingname~\theprelinklisting} -\newcommand\listofprelinklistings{% -\begingroup -\csname lol@parskip\endcsname -\@ifundefined{chapter}{\section}{\chapter}*{\listprelinklistingname - \@mkboth{\MakeUppercase\listprelinklistingname}% - {\MakeUppercase\listprelinklistingname}}% - \@starttoc{\ext@prelinklisting}% -\endgroup - } -\newcommand*\l@prelinklisting{\@dottedtocline{1}{1.5em}{2.3em}} -\def\JJ@caption{% - \bgroup - \@ifnextchar[{\egroup\JJ@c@ption\@firstofone}\JJ@capti@n} -\def\JJ@capti@n{% - \@ifstar - {\egroup\JJ@c@ption\@gobble[]}% - {\egroup\@xdblarg{\JJ@c@ption\@firstofone}}} -\def\JJ@c@ption#1[#2]#3{% - \JJ@makecaption#1\fnum@prelinklisting{#3}% - \def\@tempa{#2}% - \ifx\@tempa\@empty\else - {\let\\\space - \hyperdef{prelinklisting}{\theprelinklisting}{} - \let\theHprelinklisting\theprelinklisting - \hyper@makecurrent{prelinklisting} - \addcontentsline{lol}{prelinklisting}{\protect\numberline{\theprelinklisting}{#2}}% - \addtocounter{prelinklisting}{1}}% - \fi} -\def\JJ@makecaption#1#2#3{{#1{#2: }#3\endgraf\vskip\baselineskip}} -\let\prelinklistingcaption\JJ@caption -\endinput diff --git a/trunk/gelf/Makefile.am b/trunk/gelf/Makefile.am deleted file mode 100644 index f6320fa..0000000 --- a/trunk/gelf/Makefile.am +++ /dev/null @@ -1,13 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall -AM_CFLAGS = -Wall -INCLUDES = @GELFINCLUDE@ - -noinst_LTLIBRARIES = libgelf.la - -libgelf_la_SOURCES = gelf.c - -noinst_HEADERS = gelf.h diff --git a/trunk/gelf/gelf.c b/trunk/gelf/gelf.c deleted file mode 100644 index 915cf5b..0000000 --- a/trunk/gelf/gelf.c +++ /dev/null @@ -1,573 +0,0 @@ -/* Generic ELF wrapper for libelf which does not support gelf_ API. - Copyright (C) 2001, 2002, 2004 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <elf.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include "gelf.h" - -inline int -gelf_getclass (Elf *elf) -{ - size_t size; - char *e_ident = elf_getident (elf, &size); - - if (e_ident == NULL) - return ELFCLASSNONE; - switch (e_ident [EI_CLASS]) - { - case ELFCLASS32: - case ELFCLASS64: - return e_ident [EI_CLASS]; - default: - return ELFCLASSNONE; - } -} - -size_t -gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int ver) -{ - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - return elf32_fsize (type, count, ver); - case ELFCLASS64: - return elf64_fsize (type, count, ver); - default: - return 0; - } -} - -GElf_Ehdr * -gelf_getehdr (Elf *elf, GElf_Ehdr *dst) -{ - Elf32_Ehdr *ehdr32; - Elf64_Ehdr *ehdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - ehdr32 = elf32_getehdr (elf); - if (ehdr32 != NULL) - { - memcpy (dst->e_ident, ehdr32->e_ident, EI_NIDENT); - dst->e_type = ehdr32->e_type; - dst->e_machine = ehdr32->e_machine; - dst->e_version = ehdr32->e_version; - dst->e_entry = ehdr32->e_entry; - dst->e_phoff = ehdr32->e_phoff; - dst->e_shoff = ehdr32->e_shoff; - dst->e_flags = ehdr32->e_flags; - dst->e_ehsize = ehdr32->e_ehsize; - dst->e_phentsize = ehdr32->e_phentsize; - dst->e_phnum = ehdr32->e_phnum; - dst->e_shentsize = ehdr32->e_shentsize; - dst->e_shnum = ehdr32->e_shnum; - dst->e_shstrndx = ehdr32->e_shstrndx; - return dst; - } - break; - case ELFCLASS64: - ehdr64 = elf64_getehdr (elf); - if (ehdr64 != NULL) - { - memcpy (dst, ehdr64, sizeof (Elf64_Ehdr)); - return dst; - } - } - return NULL; -} - -int -gelf_update_ehdr (Elf *elf, GElf_Ehdr *src) -{ - Elf32_Ehdr *ehdr32; - Elf64_Ehdr *ehdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - ehdr32 = elf32_getehdr (elf); - if (ehdr32 == NULL) - return 0; - memcpy (ehdr32->e_ident, src->e_ident, EI_NIDENT); - ehdr32->e_type = src->e_type; - ehdr32->e_machine = src->e_machine; - ehdr32->e_version = src->e_version; - ehdr32->e_entry = src->e_entry; - ehdr32->e_phoff = src->e_phoff; - ehdr32->e_shoff = src->e_shoff; - ehdr32->e_flags = src->e_flags; - ehdr32->e_ehsize = src->e_ehsize; - ehdr32->e_phentsize = src->e_phentsize; - ehdr32->e_phnum = src->e_phnum; - ehdr32->e_shentsize = src->e_shentsize; - ehdr32->e_shnum = src->e_shnum; - ehdr32->e_shstrndx = src->e_shstrndx; - return 1; - case ELFCLASS64: - ehdr64 = elf64_getehdr (elf); - if (ehdr64 != NULL) - { - memcpy (ehdr64, src, sizeof (Elf64_Ehdr)); - return 1; - } - default: - break; - } - return 0; -} - -unsigned long -gelf_newehdr (Elf *elf, int class) -{ - switch (class) - { - case ELFCLASS32: - return (unsigned long) elf32_newehdr (elf); - case ELFCLASS64: - return (unsigned long) elf64_newehdr (elf); - default: - return 0; - } -} - -GElf_Phdr * -gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst) -{ - Elf32_Ehdr *ehdr32; - Elf64_Ehdr *ehdr64; - Elf32_Phdr *phdr32; - Elf64_Phdr *phdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - phdr32 = elf32_getphdr (elf); - if (phdr32 == NULL) - return NULL; - ehdr32 = elf32_getehdr (elf); - if (ehdr32 == NULL) - return NULL; - if (ndx >= ehdr32->e_phnum) - return NULL; - phdr32 += ndx; - dst->p_type = phdr32->p_type; - dst->p_offset = phdr32->p_offset; - dst->p_vaddr = phdr32->p_vaddr; - dst->p_paddr = phdr32->p_paddr; - dst->p_filesz = phdr32->p_filesz; - dst->p_memsz = phdr32->p_memsz; - dst->p_flags = phdr32->p_flags; - dst->p_align = phdr32->p_align; - return dst; - case ELFCLASS64: - phdr64 = elf64_getphdr (elf); - if (phdr64 == NULL) - return NULL; - ehdr64 = elf64_getehdr (elf); - if (ehdr64 == NULL) - return NULL; - if (ndx >= ehdr64->e_phnum) - return NULL; - memcpy (dst, phdr64 + ndx, sizeof (Elf64_Phdr)); - return dst; - default: - return NULL; - } -} - -int -gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) -{ - Elf32_Ehdr *ehdr32; - Elf64_Ehdr *ehdr64; - Elf32_Phdr *phdr32; - Elf64_Phdr *phdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - phdr32 = elf32_getphdr (elf); - if (phdr32 == NULL) - return 0; - ehdr32 = elf32_getehdr (elf); - if (ehdr32 == NULL) - return 0; - if (ndx >= ehdr32->e_phnum) - return 0; - phdr32 += ndx; - phdr32->p_type = src->p_type; - phdr32->p_offset = src->p_offset; - phdr32->p_vaddr = src->p_vaddr; - phdr32->p_paddr = src->p_paddr; - phdr32->p_filesz = src->p_filesz; - phdr32->p_memsz = src->p_memsz; - phdr32->p_flags = src->p_flags; - phdr32->p_align = src->p_align; - return 1; - case ELFCLASS64: - phdr64 = elf64_getphdr (elf); - if (phdr64 == NULL) - return 0; - ehdr64 = elf64_getehdr (elf); - if (ehdr64 == NULL) - return 0; - if (ndx >= ehdr64->e_phnum) - return 0; - memcpy (phdr64 + ndx, src, sizeof (Elf64_Phdr)); - return 1; - default: - return 0; - } -} - -unsigned long -gelf_newphdr (Elf *elf, size_t phnum) -{ - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - return (unsigned long) elf32_newphdr (elf, phnum); - case ELFCLASS64: - return (unsigned long) elf64_newphdr (elf, phnum); - default: - return 0; - } -} - -GElf_Shdr * -gelfx_getshdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *dst) -{ - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - shdr32 = elf32_getshdr (scn); - if (shdr32 == NULL) - return NULL; - dst->sh_name = shdr32->sh_name; - dst->sh_type = shdr32->sh_type; - dst->sh_flags = shdr32->sh_flags; - dst->sh_addr = shdr32->sh_addr; - dst->sh_offset = shdr32->sh_offset; - dst->sh_size = shdr32->sh_size; - dst->sh_link = shdr32->sh_link; - dst->sh_info = shdr32->sh_info; - dst->sh_addralign = shdr32->sh_addralign; - dst->sh_entsize = shdr32->sh_entsize; - return dst; - case ELFCLASS64: - shdr64 = elf64_getshdr (scn); - if (shdr64 == NULL) - return NULL; - memcpy (dst, shdr64, sizeof (Elf64_Shdr)); - return dst; - default: - return NULL; - } -} - -int -gelfx_update_shdr (Elf *elf, Elf_Scn *scn, GElf_Shdr *src) -{ - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - shdr32 = elf32_getshdr (scn); - if (shdr32 == NULL) - return 0; - shdr32->sh_name = src->sh_name; - shdr32->sh_type = src->sh_type; - shdr32->sh_flags = src->sh_flags; - shdr32->sh_addr = src->sh_addr; - shdr32->sh_offset = src->sh_offset; - shdr32->sh_size = src->sh_size; - shdr32->sh_link = src->sh_link; - shdr32->sh_info = src->sh_info; - shdr32->sh_addralign = src->sh_addralign; - shdr32->sh_entsize = src->sh_entsize; - return 1; - case ELFCLASS64: - shdr64 = elf64_getshdr (scn); - if (shdr64 == NULL) - return 0; - memcpy (shdr64, src, sizeof (Elf64_Shdr)); - return 1; - default: - return 0; - } -} - -Elf_Data * -gelf_xlatetom (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) -{ - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - return elf32_xlatetom (dst, src, encode); - case ELFCLASS64: - return elf64_xlatetom (dst, src, encode); - default: - return NULL; - } -} - -Elf_Data * -gelf_xlatetof (Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) -{ - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - return elf32_xlatetof (dst, src, encode); - case ELFCLASS64: - return elf64_xlatetof (dst, src, encode); - default: - return NULL; - } -} - -GElf_Sym *gelfx_getsym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *dst) -{ - Elf32_Sym *sym32; - - if (data->d_type != ELF_T_SYM) - return NULL; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size) - return NULL; - sym32 = &((Elf32_Sym *) data->d_buf)[ndx]; - dst->st_name = sym32->st_name; - dst->st_info = sym32->st_info; - dst->st_other = sym32->st_other; - dst->st_shndx = sym32->st_shndx; - dst->st_value = sym32->st_value; - dst->st_size = sym32->st_size; - return dst; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size) - return NULL; - *dst = ((GElf_Sym *) data->d_buf)[ndx]; - return dst; - default: - return NULL; - } -} - -int gelfx_update_sym (Elf *elf, Elf_Data *data, int ndx, GElf_Sym *src) -{ - Elf32_Sym *sym32; - - if (data->d_type != ELF_T_SYM) - return 0; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Sym) > data->d_size) - return 0; - sym32 = &((Elf32_Sym *) data->d_buf)[ndx]; - sym32->st_name = src->st_name; - sym32->st_info = src->st_info; - sym32->st_other = src->st_other; - sym32->st_shndx = src->st_shndx; - sym32->st_value = src->st_value; - sym32->st_size = src->st_size; - return 1; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Sym) > data->d_size) - return 0; - ((GElf_Sym *) data->d_buf)[ndx] = *src; - return 1; - default: - return 0; - } -} - -GElf_Dyn *gelfx_getdyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *dst) -{ - Elf32_Dyn *dyn32; - - if (data->d_type != ELF_T_DYN) - return NULL; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) - return NULL; - dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx]; - dst->d_tag = dyn32->d_tag; - dst->d_un.d_val = dyn32->d_un.d_val; - return dst; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size) - return NULL; - *dst = ((GElf_Dyn *) data->d_buf)[ndx]; - return dst; - default: - return NULL; - } -} - -int gelfx_update_dyn (Elf *elf, Elf_Data *data, int ndx, GElf_Dyn *src) -{ - Elf32_Dyn *dyn32; - - if (data->d_type != ELF_T_DYN) - return 0; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) - return 0; - dyn32 = &((Elf32_Dyn *) data->d_buf)[ndx]; - dyn32->d_tag = src->d_tag; - dyn32->d_un.d_val = src->d_un.d_val; - return 1; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Dyn) > data->d_size) - return 0; - ((GElf_Dyn *) data->d_buf)[ndx] = *src; - return 1; - default: - return 0; - } -} - -GElf_Rel *gelfx_getrel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *dst) -{ - Elf32_Rel *rel32; - - if (data->d_type != ELF_T_REL) - return NULL; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size) - return NULL; - rel32 = &((Elf32_Rel *) data->d_buf)[ndx]; - dst->r_offset = rel32->r_offset; - dst->r_info = GELF_R_INFO (ELF32_R_SYM (rel32->r_info), - ELF32_R_TYPE (rel32->r_info)); - return dst; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size) - return NULL; - *dst = ((GElf_Rel *) data->d_buf)[ndx]; - return dst; - default: - return NULL; - } -} - -int gelfx_update_rel (Elf *elf, Elf_Data *data, int ndx, GElf_Rel *src) -{ - Elf32_Rel *rel32; - - if (data->d_type != ELF_T_REL) - return 0; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Rel) > data->d_size) - return 0; - rel32 = &((Elf32_Rel *) data->d_buf)[ndx]; - rel32->r_offset = src->r_offset; - rel32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), - GELF_R_TYPE (src->r_info)); - return 1; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Rel) > data->d_size) - return 0; - ((GElf_Rel *) data->d_buf)[ndx] = *src; - return 1; - default: - return 0; - } -} - -GElf_Rela *gelfx_getrela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *dst) -{ - Elf32_Rela *rela32; - - if (data->d_type != ELF_T_RELA) - return NULL; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size) - return NULL; - rela32 = &((Elf32_Rela *) data->d_buf)[ndx]; - dst->r_offset = rela32->r_offset; - dst->r_info = GELF_R_INFO (ELF32_R_SYM (rela32->r_info), - ELF32_R_TYPE (rela32->r_info)); - dst->r_addend = rela32->r_addend; - return dst; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size) - return NULL; - *dst = ((GElf_Rela *) data->d_buf)[ndx]; - return dst; - default: - return NULL; - } -} - -int gelfx_update_rela (Elf *elf, Elf_Data *data, int ndx, GElf_Rela *src) -{ - Elf32_Rela *rela32; - - if (data->d_type != ELF_T_RELA) - return 0; - - switch (gelf_getclass (elf)) - { - case ELFCLASS32: - if ((ndx + 1) * sizeof (Elf32_Rela) > data->d_size) - return 0; - rela32 = &((Elf32_Rela *) data->d_buf)[ndx]; - rela32->r_offset = src->r_offset; - rela32->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info), - GELF_R_TYPE (src->r_info)); - rela32->r_addend = src->r_addend; - return 1; - case ELFCLASS64: - if ((ndx + 1) * sizeof (Elf64_Rela) > data->d_size) - return 0; - ((GElf_Rela *) data->d_buf)[ndx] = *src; - return 1; - default: - return 0; - } -} diff --git a/trunk/gelf/gelf.h b/trunk/gelf/gelf.h deleted file mode 100644 index 6b76a15..0000000 --- a/trunk/gelf/gelf.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Generic ELF wrapper for libelf which does not support gelf_ API. - Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef GELF_H -#define GELF_H - -typedef Elf64_Half GElf_Half; -typedef Elf64_Word GElf_Word; -typedef Elf64_Sword GElf_Sword; -typedef Elf64_Xword GElf_Xword; -typedef Elf64_Sxword GElf_Sxword; -typedef Elf64_Addr GElf_Addr; -typedef Elf64_Off GElf_Off; -typedef Elf64_Ehdr GElf_Ehdr; -typedef Elf64_Shdr GElf_Shdr; -typedef Elf64_Section GElf_Section; -typedef Elf64_Sym GElf_Sym; -typedef Elf64_Rel GElf_Rel; -typedef Elf64_Rela GElf_Rela; -typedef Elf64_Phdr GElf_Phdr; -typedef Elf64_Dyn GElf_Dyn; -#define GELF_ST_BIND ELF64_ST_BIND -#define GELF_ST_TYPE ELF64_ST_TYPE -#define GELF_ST_INFO ELF64_ST_INFO -#define GELF_ST_VISIBILITY ELF64_ST_VISIBILITY -#define GELF_R_SYM ELF64_R_SYM -#define GELF_R_TYPE ELF64_R_TYPE -#define GELF_R_INFO ELF64_R_INFO - -extern int gelf_getclass (Elf *); -extern size_t gelf_fsize (Elf *, Elf_Type, size_t, unsigned); -extern GElf_Ehdr *gelf_getehdr (Elf *, GElf_Ehdr *); -extern int gelf_update_ehdr (Elf *, GElf_Ehdr *); -extern unsigned long gelf_newehdr (Elf *, int); -extern GElf_Phdr *gelf_getphdr (Elf *, int, GElf_Phdr *); -extern int gelf_update_phdr (Elf *, int, GElf_Phdr *); -extern unsigned long gelf_newphdr (Elf *, size_t); -extern Elf_Data *gelf_xlatetom (Elf *, Elf_Data *, const Elf_Data *, unsigned); -extern Elf_Data *gelf_xlatetof (Elf *, Elf_Data *, const Elf_Data *, unsigned); -/* The gelf_ equivalents of these functions only provide Elf_Scn resp. - Elf_Data pointers, without changing the underlying libelf implementation - it is either impossible to get Elf * pointer from that or it requires - internal knowledge about the libelf implementation. */ -extern GElf_Shdr *gelfx_getshdr (Elf *, Elf_Scn *, GElf_Shdr *); -extern int gelfx_update_shdr (Elf *, Elf_Scn *, GElf_Shdr *); -extern GElf_Sym *gelfx_getsym (Elf *, Elf_Data *, int, GElf_Sym *); -extern int gelfx_update_sym (Elf *, Elf_Data *, int, GElf_Sym *); -extern GElf_Dyn *gelfx_getdyn (Elf *, Elf_Data *, int, GElf_Dyn *); -extern int gelfx_update_dyn (Elf *, Elf_Data *, int, GElf_Dyn *); -extern GElf_Rel *gelfx_getrel (Elf *, Elf_Data *, int, GElf_Rel *); -extern GElf_Rela *gelfx_getrela (Elf *, Elf_Data *, int, GElf_Rela *); -extern int gelfx_update_rel (Elf *, Elf_Data *, int, GElf_Rel *); -extern int gelfx_update_rela (Elf *, Elf_Data *, int, GElf_Rela *); - -#define HAVE_GELFX_GETSHDR 1 - -#endif /* GELF_H */ diff --git a/trunk/gelfx/Makefile.am b/trunk/gelfx/Makefile.am deleted file mode 100644 index ae51b93..0000000 --- a/trunk/gelfx/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -noinst_HEADERS = gelfx.h diff --git a/trunk/gelfx/gelfx.h b/trunk/gelfx/gelfx.h deleted file mode 100644 index c011a57..0000000 --- a/trunk/gelfx/gelfx.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Generic ELF wrapper for libelf which does not support gelf_ API. - Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef GELFX_H -#define GELFX_H - -#include <libelf.h> -#include <gelf.h> - -#ifndef HAVE_GELFX_GETSHDR - -#define gelfx_getshdr(elf,scn,shdr) gelf_getshdr(scn,shdr) -#define gelfx_update_shdr(elf,scn,shdr) gelf_update_shdr(scn,shdr) -#define gelfx_getsym(elf,data,ndx,x) gelf_getsym(data,ndx,x) -#define gelfx_update_sym(elf,data,ndx,x) gelf_update_sym(data,ndx,x) -#define gelfx_getdyn(elf,data,ndx,x) gelf_getdyn(data,ndx,x) -#define gelfx_update_dyn(elf,data,ndx,x) gelf_update_dyn(data,ndx,x) -#define gelfx_getrel(elf,data,ndx,x) gelf_getrel(data,ndx,x) -#define gelfx_update_rel(elf,data,ndx,x) gelf_update_rel(data,ndx,x) -#define gelfx_getrela(elf,data,ndx,x) gelf_getrela(data,ndx,x) -#define gelfx_update_rela(elf,data,ndx,x) gelf_update_rela(data,ndx,x) - -#endif - -#endif /* GELFX_H */ diff --git a/trunk/gelfx32/Makefile.am b/trunk/gelfx32/Makefile.am deleted file mode 100644 index ae51b93..0000000 --- a/trunk/gelfx32/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -noinst_HEADERS = gelfx.h diff --git a/trunk/gelfx32/gelfx.h b/trunk/gelfx32/gelfx.h deleted file mode 100644 index 7668a84..0000000 --- a/trunk/gelfx32/gelfx.h +++ /dev/null @@ -1,227 +0,0 @@ -/* gelf API which supports ELFCLASS32 only. - Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef GELFX_H -#define GELFX_H - -#include <error.h> -#include <libelf.h> -#include <stdlib.h> -#include <string.h> - -typedef Elf32_Half GElf_Half; -typedef Elf32_Word GElf_Word; -typedef Elf32_Sword GElf_Sword; -typedef Elf32_Xword GElf_Xword; -typedef Elf32_Sxword GElf_Sxword; -typedef Elf32_Addr GElf_Addr; -typedef Elf32_Off GElf_Off; -typedef Elf32_Ehdr GElf_Ehdr; -typedef Elf32_Shdr GElf_Shdr; -typedef Elf32_Section GElf_Section; -typedef Elf32_Sym GElf_Sym; -typedef Elf32_Rel GElf_Rel; -typedef Elf32_Rela GElf_Rela; -typedef Elf32_Phdr GElf_Phdr; -typedef Elf32_Dyn GElf_Dyn; -#define GELF_ST_BIND ELF32_ST_BIND -#define GELF_ST_TYPE ELF32_ST_TYPE -#define GELF_ST_INFO ELF32_ST_INFO -#define GELF_R_SYM ELF32_R_SYM -#define GELF_R_TYPE ELF32_R_TYPE -#define GELF_R_INFO ELF32_R_INFO - -extern inline int -gelf_getclass (Elf *elf) -{ - size_t size; - char *e_ident = elf_getident (elf, &size); - if (e_ident [EI_CLASS] == ELFCLASS64) - error (EXIT_FAILURE, 0, "64-bit ELF not supported"); - return e_ident [EI_CLASS] == ELFCLASS32 ? ELFCLASS32 : ELFCLASSNONE; -} - -#define gelf_fsize(e,t,c,v) elf32_fsize(t,c,v) - -extern inline GElf_Ehdr *gelf_getehdr (Elf *elf, GElf_Ehdr *dst) -{ - Elf32_Ehdr *ehdr = elf32_getehdr (elf); - if (ehdr == NULL) - return NULL; - return memcpy (dst, ehdr, sizeof (Elf32_Ehdr)); -} - -extern inline int -gelf_update_ehdr (Elf *elf, GElf_Ehdr *src) -{ - Elf32_Ehdr *ehdr = elf32_getehdr (elf); - if (ehdr == NULL) - return 0; - memcpy (ehdr, src, sizeof (Elf32_Ehdr)); - return 1; -} - -extern inline unsigned long -gelf_newehdr (Elf *elf, int class) -{ - if (class != ELFCLASS32) - return 0; - return (unsigned long) elf32_newehdr (elf); -} - -extern inline GElf_Phdr * -gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst) -{ - Elf32_Ehdr *ehdr = elf32_getehdr (elf); - Elf32_Phdr *phdr = elf32_getphdr (elf); - if (ehdr == NULL || phdr == NULL || ndx >= ehdr->e_phnum) - return NULL; - return memcpy (dst, phdr + ndx, sizeof (Elf32_Phdr)); -} - -extern inline int -gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) -{ - Elf32_Ehdr *ehdr = elf32_getehdr (elf); - Elf32_Phdr *phdr = elf32_getphdr (elf); - if (ehdr == NULL || phdr == NULL || ndx >= ehdr->e_phnum) - return 0; - memcpy (phdr + ndx, src, sizeof (Elf32_Phdr)); - return 1; -} - -extern inline unsigned long -gelf_newphdr (Elf *elf, size_t phnum) -{ - return (unsigned long) elf32_newphdr (elf, phnum); -} - -#define gelf_xlatetom(e,d,s,n) elf32_xlatetom(e,d,s,n) -#define gelf_xlatetof(e,d,s,n) elf32_xlatetof(e,d,s,n) - -extern inline GElf_Shdr * -gelf_getshdr (Elf_Scn *scn, GElf_Shdr *dst) -{ - Elf32_Shdr *shdr = elf32_getshdr (scn); - if (shdr == NULL) - return NULL; - return memcpy (dst, shdr, sizeof (Elf32_Shdr)); -} - -extern inline int -gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src) -{ - Elf32_Shdr *shdr = elf32_getshdr (scn); - if (shdr == NULL) - return 0; - memcpy (shdr, src, sizeof (Elf32_Shdr)); - return 1; -} - -extern inline GElf_Sym * -gelf_getsym (Elf_Data *data, int ndx, GElf_Sym *dst) -{ - if (data->d_type != ELF_T_SYM - || (ndx + 1) * sizeof (Elf32_Sym) > data->d_size) - return NULL; - *dst = ((GElf_Sym *) data->d_buf)[ndx]; - return dst; -} - -extern inline int -gelf_update_sym (Elf_Data *data, int ndx, GElf_Sym *src) -{ - if (data->d_type != ELF_T_SYM - || (ndx + 1) * sizeof (Elf32_Sym) > data->d_size) - return 0; - ((GElf_Sym *) data->d_buf)[ndx] = *src; - return 1; -} - -extern inline GElf_Dyn * -gelf_getdyn (Elf_Data *data, int ndx, GElf_Dyn *dst) -{ - if (data->d_type != ELF_T_DYN - || (ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) - return NULL; - *dst = ((GElf_Dyn *) data->d_buf)[ndx]; - return dst; -} - -extern inline int -gelf_update_dyn (Elf_Data *data, int ndx, GElf_Dyn *src) -{ - if (data->d_type != ELF_T_DYN - || (ndx + 1) * sizeof (Elf32_Dyn) > data->d_size) - return 0; - ((GElf_Dyn *) data->d_buf)[ndx] = *src; - return 1; -} - -extern inline GElf_Rel * -gelf_getrel (Elf_Data *data, int ndx, GElf_Rel *dst) -{ - if (data->d_type != ELF_T_REL - || (ndx + 1) * sizeof (Elf32_Rel) > data->d_size) - return NULL; - *dst = ((GElf_Rel *) data->d_buf)[ndx]; - return dst; -} - -extern inline int -gelf_update_rel (Elf_Data *data, int ndx, GElf_Rel *src) -{ - if (data->d_type != ELF_T_REL - || (ndx + 1) * sizeof (Elf32_Rel) > data->d_size) - return 0; - ((GElf_Rel *) data->d_buf)[ndx] = *src; - return 1; -} - -extern inline GElf_Rela * -gelf_getrela (Elf_Data *data, int ndx, GElf_Rela *dst) -{ - if (data->d_type != ELF_T_RELA - || (ndx + 1) * sizeof (Elf32_Rela) > data->d_size) - return NULL; - *dst = ((GElf_Rela *) data->d_buf)[ndx]; - return dst; -} - -extern inline int -gelf_update_rela (Elf_Data *data, int ndx, GElf_Rela *src) -{ - if (data->d_type != ELF_T_RELA - || (ndx + 1) * sizeof (Elf32_Rela) > data->d_size) - return 0; - ((GElf_Rela *) data->d_buf)[ndx] = *src; - return 1; -} - -#define gelfx_getshdr(elf,scn,shdr) gelf_getshdr(scn,shdr) -#define gelfx_update_shdr(elf,scn,shdr) gelf_update_shdr(scn,shdr) -#define gelfx_getsym(elf,data,ndx,x) gelf_getsym(data,ndx,x) -#define gelfx_update_sym(elf,data,ndx,x) gelf_update_sym(data,ndx,x) -#define gelfx_getdyn(elf,data,ndx,x) gelf_getdyn(data,ndx,x) -#define gelfx_update_dyn(elf,data,ndx,x) gelf_update_dyn(data,ndx,x) -#define gelfx_getrel(elf,data,ndx,x) gelf_getrel(data,ndx,x) -#define gelfx_update_rel(elf,data,ndx,x) gelf_update_rel(data,ndx,x) -#define gelfx_getrela(elf,data,ndx,x) gelf_getrela(data,ndx,x) -#define gelfx_update_rela(elf,data,ndx,x) gelf_update_rela(data,ndx,x) - -#endif /* GELFX_H */ diff --git a/trunk/m4/Makefile.am b/trunk/m4/Makefile.am deleted file mode 100644 index d9fab43..0000000 --- a/trunk/m4/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -## Process this file with automake to produce Makefile.in -*-Makefile-*- - -##m4-files-begin -EXTRA_DIST = libelf.m4 diff --git a/trunk/m4/libelf.m4 b/trunk/m4/libelf.m4 deleted file mode 100644 index 88f061b..0000000 --- a/trunk/m4/libelf.m4 +++ /dev/null @@ -1,120 +0,0 @@ -#serial 7 - -dnl Some libelf versions have bugs in Elf64_Sxword conversions. -dnl Detect it. - -dnl Written by Jakub Jelinek <jakub@redhat.com>. - -AC_DEFUN(AC_LIBELF_SXWORD, - [AC_TRY_RUN([ -#include <errno.h> -#include <fcntl.h> -#include <elf.h> -#include <libelf.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -static unsigned char sparc64_elf[] = { -0x7f,0x45,0x4c,0x46,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x01,0x00,0x2b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78, -0x00,0x00,0x00,0x02,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x08,0x00,0x05, -0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x2e,0x73,0x79,0x6d,0x74,0x61,0x62, -0x00,0x2e,0x73,0x74,0x72,0x74,0x61,0x62,0x00,0x2e,0x73,0x68,0x73,0x74,0x72,0x74, -0x61,0x62,0x00,0x2e,0x74,0x65,0x78,0x74,0x00,0x2e,0x64,0x61,0x74,0x61,0x00,0x2e, -0x62,0x73,0x73,0x00,0x66,0x6f,0x6f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x03, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78, -0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x03, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x02,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x02, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x04, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00 }; - -int main (void) -{ - Elf *elf; - int fd; - Elf64_Ehdr *ehdr; - Elf64_Addr val; - Elf_Scn *scn; - - fd = open ("conflibelftest", O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd == -1) exit (1); - unlink ("conflibelftest"); - if (write (fd, sparc64_elf, sizeof(sparc64_elf)) != sizeof(sparc64_elf)) - exit (1); - if (lseek (fd, 0, SEEK_SET) != 0) exit (1); - elf_version (EV_CURRENT); - elf = elf_begin (fd, ELF_C_RDWR, NULL); if (elf == NULL) exit (2); - if ((ehdr = elf64_getehdr (elf)) == NULL) exit (3); - scn = NULL; - while ((scn = elf_nextscn (elf, scn)) != NULL) - { - char *name = NULL; - Elf64_Shdr *shdr; - Elf_Data *src, *dst; - - if ((shdr = elf64_getshdr (scn)) - && (name = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name)) - && !strcmp (name, "foo")) - { - src = elf_rawdata (scn, NULL); - if (shdr->sh_size != 8 || src->d_off || src->d_size != 8) exit (4); - if (src == NULL || elf_rawdata (scn, src) != NULL) exit (5); - if ((dst = elf_newdata (scn)) == NULL) exit (6); - dst->d_buf = &val; - dst->d_size = 8; - dst->d_off = 0; - dst->d_type = ELF_T_SXWORD; - src->d_type = ELF_T_SXWORD; - if (elf64_xlatetom (dst, src, ELFDATA2MSB) == NULL) exit (7); - if (val != 0x7fff0000000) - exit (42); - elf_end (elf); - exit (0); - } - } - exit (8); -} - ],,[AC_MSG_ERROR([libelf does not properly convert Elf64_Sxword quantities. -If you are using libelf-0.7.0, please use patches/libelf-0.7.0.patch.])], -[AC_MSG_WARN([Could not test whether libelf properly converts Elf64_Sxword quantities. -If you are using libelf-0.7.0 and your libelf is buggy, please use -patches/libelf-0.7.0.patch.])]) - ]) diff --git a/trunk/patches/Makefile.am b/trunk/patches/Makefile.am deleted file mode 100644 index efe5d40..0000000 --- a/trunk/patches/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -EXTRA_DIST = libelf-0.7.0.patch libelf-0.7.0-hash.patch linux-2.4.10.patch diff --git a/trunk/patches/libelf-0.7.0-hash.patch b/trunk/patches/libelf-0.7.0-hash.patch deleted file mode 100644 index 7fcf7f3..0000000 --- a/trunk/patches/libelf-0.7.0-hash.patch +++ /dev/null @@ -1,20 +0,0 @@ -2002-06-14 Jakub Jelinek <jakub@redhat.com> - - * update.c (_elf64_layout): Don't overwrite sh_entsize - unconditionally for ELF64 - some platforms use - 64 bit DT_HASH entries. - ---- libelf-0.7.0/lib/update.c.jj Fri Jun 12 15:42:39 1998 -+++ libelf-0.7.0/lib/update.c Fri Jun 14 10:22:19 2002 -@@ -317,7 +317,10 @@ _elf64_layout(Elf *elf, unsigned *flag) - - entsize = scn_entsize(elf, version, shdr->sh_type); - if (entsize > 1) { -- rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); -+ /* Some architectures use 64-bit hash entries. */ -+ if (shdr->sh_type != SHT_HASH -+ || shdr->sh_entsize != _fsize(elf->e_class, version, ELF_T_ADDR)) -+ rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags); - } - - if (layout) { diff --git a/trunk/patches/libelf-0.7.0.patch b/trunk/patches/libelf-0.7.0.patch deleted file mode 100644 index 1e9e57a..0000000 --- a/trunk/patches/libelf-0.7.0.patch +++ /dev/null @@ -1,16 +0,0 @@ -2001-09-26 Jakub Jelinek <jakub@redhat.com> - - * lib/64.xlatetof.c (__load_i64M): Don't blow away upper 32 bits - if 31th bit is set. - ---- libelf-0.7.0/lib/64.xlatetof.c.jj Tue Aug 25 17:22:24 1998 -+++ libelf-0.7.0/lib/64.xlatetof.c Wed Sep 26 15:00:18 2001 -@@ -42,7 +42,7 @@ __load_i64L(const unsigned char *from) { - - static __libelf_i64_t - __load_i64M(const unsigned char *from) { -- return ((__libelf_u64_t)__load_u32M(from) << 32) | (__libelf_i64_t)__load_i32M(from + 4); -+ return ((__libelf_i64_t)__load_i32M(from) << 32) | (__libelf_u64_t)__load_u32M(from + 4); - } - - static void diff --git a/trunk/patches/linux-2.4.10.patch b/trunk/patches/linux-2.4.10.patch deleted file mode 100644 index dbd6702..0000000 --- a/trunk/patches/linux-2.4.10.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- linux/fs/binfmt_elf.c.jj Thu Sep 6 16:12:04 2001 -+++ linux/fs/binfmt_elf.c Mon Oct 1 08:22:06 2001 -@@ -400,7 +400,6 @@ static int load_elf_binary(struct linux_ - int load_addr_set = 0; - char * elf_interpreter = NULL; - unsigned int interpreter_type = INTERPRETER_NONE; -- mm_segment_t old_fs; - unsigned long error; - struct elf_phdr * elf_ppnt, *elf_phdata; - unsigned long elf_bss, k, elf_brk; -@@ -574,8 +573,6 @@ static int load_elf_binary(struct linux_ - the image should be loaded at fixed address, not at a variable - address. */ - -- old_fs = get_fs(); -- set_fs(get_ds()); - for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { - int elf_prot = 0, elf_flags; - unsigned long vaddr; -@@ -583,6 +580,22 @@ static int load_elf_binary(struct linux_ - if (elf_ppnt->p_type != PT_LOAD) - continue; - -+ if (unlikely (elf_brk > elf_bss)) { -+ unsigned long nbyte; -+ -+ /* There was a PT_LOAD segment with p_memsz > p_filesz -+ before this one. Map anonymous pages, if needed, -+ and clear the area. */ -+ set_brk (elf_bss + load_bias, elf_brk + load_bias); -+ nbyte = ELF_PAGEOFFSET(elf_bss); -+ if (nbyte) { -+ nbyte = ELF_MIN_ALIGN - nbyte; -+ if (nbyte > elf_brk - elf_bss) -+ nbyte = elf_brk - elf_bss; -+ clear_user((void *) elf_bss + elf_bias, nbyte); -+ } -+ } -+ - if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; - if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; - if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; -@@ -626,7 +639,6 @@ static int load_elf_binary(struct linux_ - if (k > elf_brk) - elf_brk = k; - } -- set_fs(old_fs); - - elf_entry += load_bias; - elf_bss += load_bias; diff --git a/trunk/src/Makefile.am b/trunk/src/Makefile.am deleted file mode 100644 index 7372fc1..0000000 --- a/trunk/src/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -SUBDIRS = rtld - -PKGVERSION = "\"@PKGVERSION@\"" -REPORT_BUGS_TO = "\"@REPORT_BUGS_TO@\"" - -DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall -Wno-pointer-sign -AM_CFLAGS = -Wall -Wno-pointer-sign -AM_CPPFLAGS = -DSBINDIR='"@sbindir@"' -DBINDIR='"@bindir@"' \ - -DEXECSTACK_PROG="\"`echo execstack | sed '$(transform)'`\"" \ - -DPRELINK_PROG="\"`echo prelink | sed '$(transform)'`\"" \ - -DPRELINK_RTLD_PROG="\"`echo prelink-rtld | \ - sed '$(transform)'`\"" \ - -DEXEEXT='"$(EXEEXT)"' \ - -DPKGVERSION=$(PKGVERSION) \ - -DREPORT_BUGS_TO=$(REPORT_BUGS_TO) -INCLUDES = @GELFINCLUDE@ - -sbin_PROGRAMS = prelink -bin_PROGRAMS = execstack - -arch_SOURCES = arch-i386.c arch-alpha.c arch-ppc.c arch-ppc64.c \ - arch-sparc.c arch-sparc64.c arch-x86_64.c arch-mips.c \ - arch-s390.c arch-s390x.c arch-arm.c arch-sh.c arch-ia64.c -common_SOURCES = checksum.c data.c dso.c dwarf2.c dwarf2.h fptr.c fptr.h \ - hashtab.c hashtab.h mdebug.c prelink.h stabs.c crc32.c \ - wrap-file.c canonicalize.c reloc-info.c reloc-info.h -prelink_SOURCES = cache.c conflict.c cxx.c doit.c exec.c execle_open.c get.c \ - gather.c layout.c main.c prelink.c \ - prelinktab.h reloc.c reloc.h space.c undo.c undoall.c \ - verify.c md5.c md5.h sha.c sha.h \ - $(common_SOURCES) $(arch_SOURCES) -prelink_LDADD = @LIBGELF@ -liberty -prelink_LDFLAGS = - -execstack_SOURCES = execstack.c $(common_SOURCES) $(arch_SOURCES) -execstack_LDADD = -liberty -execstack_LDFLAGS = - -extra_DIST = makecrc.c diff --git a/trunk/src/arch-alpha.c b/trunk/src/arch-alpha.c deleted file mode 100644 index 7802a3e..0000000 --- a/trunk/src/arch-alpha.c +++ /dev/null @@ -1,505 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -alpha_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - return 0; -} - -static int -alpha_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: Alpha doesn't support REL relocs", dso->filename); - return 1; -} - -static int -alpha_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if (GELF_R_TYPE (rela->r_info) == R_ALPHA_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_ALPHA_JMP_SLOT) - { - GElf_Addr val = read_ule64 (dso, rela->r_offset); - - if (val >= start) - { - write_le64 (dso, rela->r_offset, val + adjust); - if (val == rela->r_addend) - rela->r_addend += adjust; - } - } - else if (GELF_R_TYPE (rela->r_info) == R_ALPHA_GLOB_DAT) - { - GElf_Addr val = read_ule64 (dso, rela->r_offset) - rela->r_addend; - - if (val && val >= start) - write_le64 (dso, rela->r_offset, val + adjust + rela->r_addend); - } - return 0; -} - -static int -alpha_prelink_rel (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: Alpha doesn't support REL relocs", info->dso->filename); - return 1; -} - -static void -alpha_fixup_plt (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr, - GElf_Addr value) -{ - Elf64_Sxword disp; - Elf64_Addr plt; - - relaaddr -= dso->info[DT_JMPREL]; - relaaddr /= sizeof (Elf64_Rela); - relaaddr *= 12; - plt = dso->info[DT_PLTGOT] + 32 + relaaddr; - disp = ((Elf64_Sxword) (value - plt - 12)) / 4; - if (disp >= -0x100000 && disp < 0x100000) - { - int32_t hi, lo; - - hi = value - plt; - lo = (int16_t) hi; - hi = (hi - lo) >> 16; - - /* ldah $27,hi($27) - lda $27,lo($27) - br $31,value */ - write_le32 (dso, plt, 0x277b0000 | (hi & 0xffff)); - write_le32 (dso, plt + 4, 0x237b0000 | (lo & 0xffff)); - write_le32 (dso, plt + 8, 0xc3e00000 | (disp & 0x1fffff)); - } - else - { - int32_t hi, lo; - - hi = rela->r_offset - plt; - lo = (int16_t) hi; - hi = (hi - lo) >> 16; - - /* ldah $27,hi($27) - ldq $27,lo($27) - jmp $31,($27) */ - write_le32 (dso, plt, 0x277b0000 | (hi & 0xffff)); - write_le32 (dso, plt + 4, 0xa77b0000 | (lo & 0xffff)); - write_le32 (dso, plt + 8, 0x6bfb0000); - } -} - -static int -alpha_is_indirect_plt (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - Elf64_Addr pltaddr; - uint32_t plt[3]; - int32_t hi, lo; - - relaaddr -= dso->info[DT_JMPREL]; - relaaddr /= sizeof (Elf64_Rela); - relaaddr *= 12; - pltaddr = dso->info[DT_PLTGOT] + 32 + relaaddr; - hi = rela->r_offset - pltaddr; - lo = (int16_t) hi; - hi = (hi - lo) >> 16; - plt[0] = read_ule32 (dso, pltaddr); - plt[1] = read_ule32 (dso, pltaddr + 4); - plt[2] = read_ule32 (dso, pltaddr + 8); - if (plt[0] == (0x277b0000 | (hi & 0xffff)) - && plt[1] == (0xa77b0000 | (lo & 0xffff)) - && plt[2] == 0x6bfb0000) - return 1; - return 0; -} - -static int -alpha_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_ALPHA_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_ALPHA_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ALPHA_GLOB_DAT: - case R_ALPHA_REFQUAD: - case R_ALPHA_DTPREL64: - write_le64 (dso, rela->r_offset, value); - break; - case R_ALPHA_JMP_SLOT: - write_le64 (dso, rela->r_offset, value); - alpha_fixup_plt (dso, rela, relaaddr, value); - break; - /* DTPMOD64 and TPREL64 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_ALPHA_DTPMOD64: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_ALPHA_DTPMOD64 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_ALPHA_TPREL64: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_le64 (dso, rela->r_offset, value + info->resolvetls->offset); - break; - default: - error (0, 0, "%s: Unknown alpha relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -alpha_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - switch (GELF_R_TYPE (rela->r_info) & 0xff) - { - case R_ALPHA_GLOB_DAT: - case R_ALPHA_REFQUAD: - case R_ALPHA_JMP_SLOT: - buf_write_le64 (buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -alpha_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: Alpha doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -alpha_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ALPHA_NONE: - break; - case R_ALPHA_GLOB_DAT: - case R_ALPHA_REFQUAD: - case R_ALPHA_JMP_SLOT: - buf_write_le64 (buf, value + rela->r_addend); - break; - case R_ALPHA_RELATIVE: - error (0, 0, "%s: R_ALPHA_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -alpha_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: Alpha doesn't support REL relocs", dso->filename); - return 1; -} - -static int -alpha_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_ALPHA_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_ALPHA_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - if (info->curtls == NULL) - return 0; - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD64 and TPREL64 relocs need conflicts. */ - case R_ALPHA_DTPMOD64: - case R_ALPHA_TPREL64: - break; - default: - return 0; - } - value = 0; - } - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on Alpha yet", - dso->filename); - return 1; - } - else - { - /* DTPREL64 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_ALPHA_DTPREL64 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ALPHA_GLOB_DAT: - case R_ALPHA_REFQUAD: - ret->r_addend = value + rela->r_addend; - break; - case R_ALPHA_JMP_SLOT: - ret->r_addend = value + rela->r_addend; - if (alpha_is_indirect_plt (dso, rela, relaaddr)) - ret->r_info = GELF_R_INFO (0, R_ALPHA_GLOB_DAT); - else - { - relaaddr -= dso->info[DT_JMPREL]; - relaaddr /= sizeof (Elf64_Rela); - if (relaaddr > 0xffffff) - { - error (0, 0, "%s: Cannot create R_ALPHA_JMP_SLOT conflict against .rel.plt with more than 16M entries", - dso->filename); - return 1; - } - ret->r_info = GELF_R_INFO (0, (relaaddr << 8) | R_ALPHA_JMP_SLOT); - } - break; - case R_ALPHA_DTPMOD64: - case R_ALPHA_DTPREL64: - case R_ALPHA_TPREL64: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_ALPHA_GLOB_DAT); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ALPHA_DTPMOD64: - ret->r_addend = tls->modid; - break; - case R_ALPHA_DTPREL64: - ret->r_addend = value + rela->r_addend; - break; - case R_ALPHA_TPREL64: - ret->r_addend = value + rela->r_addend + tls->offset; - break; - } - break; - default: - error (0, 0, "%s: Unknown Alpha relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -alpha_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: Alpha doesn't support REL relocs", dso->filename); - return 1; -} - -static int -alpha_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -alpha_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - - /* Correct sh_entsize on .plt sections. */ - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT] + 16); - assert (sec != -1); - if (dso->shdr[sec].sh_type == SHT_PROGBITS - && dso->shdr[sec].sh_entsize == 32) - dso->shdr[sec].sh_entsize = 0; - } - return 0; -} - -static int -alpha_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - Elf_Scn *scn; - Elf_Data *data; - GElf_Sym sym; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ALPHA_NONE: - case R_ALPHA_RELATIVE: - break; - case R_ALPHA_JMP_SLOT: - relaaddr -= dso->info[DT_JMPREL]; - relaaddr /= sizeof (Elf64_Rela); - relaaddr *= 12; - relaaddr += dso->info[DT_PLTGOT] + 32; - /* br at,.plt */ - write_le32 (dso, relaaddr, - 0xc39fffff - (relaaddr - dso->info[DT_PLTGOT]) / 4); - write_le64 (dso, relaaddr + 4, 0); - write_le64 (dso, rela->r_offset, relaaddr); - break; - case R_ALPHA_GLOB_DAT: - /* This is ugly. Linker doesn't clear memory at r_offset of GLOB_DAT - reloc, but instead puts in sym.st_value + addend. */ - sec = addr_to_sec (dso, relaaddr); - assert (sec != -1); - sec = dso->shdr[sec].sh_link; - assert (sec > 0 && sec < dso->ehdr.e_shnum); - scn = dso->scn[sec]; - data = elf_getdata (scn, NULL); - assert (data != NULL && elf_getdata (scn, data) == NULL); - assert (GELF_R_SYM (rela->r_info) - <= dso->shdr[sec].sh_size / sizeof (Elf64_Sym)); - gelfx_getsym (dso->elf, data, GELF_R_SYM (rela->r_info), &sym); - write_le64 (dso, rela->r_offset, sym.st_value + rela->r_addend); - break; - case R_ALPHA_REFQUAD: - case R_ALPHA_DTPMOD64: - case R_ALPHA_DTPREL64: - case R_ALPHA_TPREL64: - write_le64 (dso, rela->r_offset, 0); - break; - default: - error (0, 0, "%s: Unknown alpha relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -alpha_reloc_size (int reloc_type) -{ - return 8; -} - -static int -alpha_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_ALPHA_JMP_SLOT: - return RTYPE_CLASS_PLT; - case R_ALPHA_DTPMOD64: - case R_ALPHA_DTPREL64: - case R_ALPHA_TPREL64: - return RTYPE_CLASS_TLS; - default: - return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(alpha) = { - .name = "Alpha", - .class = ELFCLASS64, - .machine = EM_ALPHA, - .alternate_machine = { EM_FAKE_ALPHA }, - .R_JMP_SLOT = R_ALPHA_JMP_SLOT, - .R_COPY = -1, - .R_RELATIVE = R_ALPHA_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux.so.2", - .adjust_dyn = alpha_adjust_dyn, - .adjust_rel = alpha_adjust_rel, - .adjust_rela = alpha_adjust_rela, - .prelink_rel = alpha_prelink_rel, - .prelink_rela = alpha_prelink_rela, - .prelink_conflict_rel = alpha_prelink_conflict_rel, - .prelink_conflict_rela = alpha_prelink_conflict_rela, - .apply_conflict_rela = alpha_apply_conflict_rela, - .apply_rel = alpha_apply_rel, - .apply_rela = alpha_apply_rela, - .rel_to_rela = alpha_rel_to_rela, - .need_rel_to_rela = alpha_need_rel_to_rela, - .reloc_size = alpha_reloc_size, - .reloc_class = alpha_reloc_class, - .max_reloc_size = 8, - .arch_prelink = alpha_arch_prelink, - .undo_prelink_rela = alpha_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x0000020000000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x0000020001000000LL, - .mmap_end = 0x0000020100000000LL, - .max_page_size = 0x10000, - .page_size = 0x02000 -}; diff --git a/trunk/src/arch-arm.c b/trunk/src/arch-arm.c deleted file mode 100644 index c8febcd..0000000 --- a/trunk/src/arch-arm.c +++ /dev/null @@ -1,950 +0,0 @@ -/* Copyright (C) 2001, 2002, 2004, 2009, 2011, 2013 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -#ifndef R_ARM_TLS_DTPMOD32 -#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -#endif - -static int -arm_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf32_Addr data; - - if (sec == -1) - return 0; - - data = read_une32 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_ne32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_une32 (dso, dyn->d_un.d_ptr + 4); - /* If .got.plt[1] points to .plt, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_ne32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - break; - } - } - } - return 0; -} - -static int -arm_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_RELATIVE: - case R_ARM_JUMP_SLOT: - case R_ARM_IRELATIVE: - data = read_une32 (dso, rel->r_offset); - if (data >= start) - write_ne32 (dso, rel->r_offset, data + adjust); - break; - } - return 0; -} - -static int -arm_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_RELATIVE: - case R_ARM_IRELATIVE: - if ((Elf32_Addr) rela->r_addend >= start) - { - rela->r_addend += (Elf32_Sword) adjust; - /* Write it to the memory location as well. - Not necessary, but we can do it. */ - write_ne32 (dso, rela->r_offset, rela->r_addend); - } - break; - case R_ARM_JUMP_SLOT: - data = read_une32 (dso, rela->r_offset); - if (data >= start) - write_ne32 (dso, rela->r_offset, data + adjust); - break; - break; - } - return 0; -} - -static int -arm_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - DSO *dso; - GElf_Addr value; - Elf32_Sword val; - - if (GELF_R_TYPE (rel->r_info) == R_ARM_RELATIVE - || GELF_R_TYPE (rel->r_info) == R_ARM_IRELATIVE - || GELF_R_TYPE (rel->r_info) == R_ARM_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - write_ne32 (dso, rel->r_offset, value); - break; - case R_ARM_ABS32: - { - if (read_une32 (dso, rel->r_offset)) - { - error (0, 0, "%s: R_ARM_ABS32 relocs with non-zero addend should not be present in prelinked REL sections", - dso->filename); - return 1; - } - rel->r_info = GELF_R_INFO (GELF_R_SYM (rel->r_info), R_ARM_GLOB_DAT); - write_ne32 (dso, rel->r_offset, value); - /* Tell prelink_rel routine *rel has changed. */ - return 2; - } - case R_ARM_PC24: - error (0, 0, "%s: R_ARM_PC24 relocs with non-zero addend should not be present in prelinked REL sections", - dso->filename); - return 1; - case R_ARM_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_ARM_COPY reloc in shared library?", dso->filename); - return 1; - case R_ARM_TLS_DTPOFF32: - write_ne32 (dso, rel->r_offset, value); - break; - /* DTPMOD32 and TPOFF32 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_ARM_TLS_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_ARM_TLS_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_ARM_TLS_TPOFF32: - if (dso->ehdr.e_type == ET_EXEC) - error (0, 0, "%s: R_ARM_TLS_TPOFF32 relocs should not be present in " - "prelinked ET_EXEC REL sections", - dso->filename); - break; - case R_ARM_TLS_DESC: - if (!dso->info_DT_TLSDESC_PLT) - { - error (0, 0, - "%s: Unsupported R_ARM_TLS_DESC relocation in non-lazily bound object.", - dso->filename); - return 1; - } - val = read_une32 (dso, rel->r_offset + 4); - if (val != 0 && !dynamic_info_is_set (dso, DT_GNU_PRELINKED_BIT)) - { - error (0, 0, - "%s: Unexpected non-zero value (0x%x) in R_ARM_TLS_DESC?", - dso->filename, val); - return 1; - } - write_ne32 (dso, rel->r_offset + 4, dso->info_DT_TLSDESC_PLT); - break; - default: - error (0, 0, "%s: Unknown arm relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -arm_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - Elf32_Sword val; - - if (GELF_R_TYPE (rela->r_info) == R_ARM_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_ARM_IRELATIVE - || GELF_R_TYPE (rela->r_info) == R_ARM_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - write_ne32 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_ARM_ABS32: - write_ne32 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_ARM_PC24: - val = value + rela->r_addend - rela->r_offset; - val >>= 2; - if ((Elf32_Word) val + 0x800000 >= 0x1000000) - { - error (0, 0, "%s: R_ARM_PC24 overflow", dso->filename); - return 1; - } - val &= 0xffffff; - write_ne32 (dso, rela->r_offset, - (read_une32 (dso, rela->r_offset) & 0xff000000) | val); - break; - case R_ARM_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_ARM_COPY reloc in shared library?", dso->filename); - return 1; - case R_ARM_TLS_DTPOFF32: - write_ne32 (dso, rela->r_offset, value + rela->r_addend); - break; - /* DTPMOD32 and TPOFF32 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_ARM_TLS_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_ARM_TLS_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_ARM_TLS_TPOFF32: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_ne32 (dso, rela->r_offset, - value + rela->r_addend + info->resolvetls->offset); - break; - case R_ARM_TLS_DESC: - if (!dso->info_DT_TLSDESC_PLT) - { - error (0, 0, - "%s: Unsupported R_ARM_TLS_DESC relocation in non-lazily bound object.", - dso->filename); - return 1; - } - val = read_une32 (dso, rela->r_offset + 4); - if (val != 0 && !dynamic_info_is_set (dso, DT_GNU_PRELINKED_BIT)) - { - error (0, 0, - "%s: Unexpected non-zero value (0x%x) in R_ARM_TLS_DESC?", - dso->filename, val); - return 1; - } - write_ne32 (dso, rela->r_offset + 4, dso->info_DT_TLSDESC_PLT); - break; - default: - error (0, 0, "%s: Unknown arm relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -arm_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - case R_ARM_ABS32: - buf_write_ne32 (info->dso, buf, rela->r_addend); - break; - case R_ARM_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -arm_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - GElf_Addr value; - Elf32_Sword val; - - value = info->resolve (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_NONE: - break; - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - buf_write_ne32 (info->dso, buf, value); - break; - case R_ARM_ABS32: - buf_write_ne32 (info->dso, buf, value + read_une32 (info->dso, rel->r_offset)); - break; - case R_ARM_PC24: - val = value + rel->r_offset; - value = read_une32 (info->dso, rel->r_offset) << 8; - value = ((Elf32_Sword) value) >> 6; - val += value; - val >>= 2; - if ((Elf32_Word) val + 0x800000 >= 0x1000000) - { - error (0, 0, "%s: R_ARM_PC24 overflow", info->dso->filename); - return 1; - } - val &= 0xffffff; - buf_write_ne32 (info->dso, buf, (buf_read_une32 (info->dso, buf) & 0xff000000) | val); - break; - case R_ARM_COPY: - abort (); - case R_ARM_RELATIVE: - error (0, 0, "%s: R_ARM_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -arm_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - Elf32_Sword val; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_NONE: - break; - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - case R_ARM_ABS32: - buf_write_ne32 (info->dso, buf, value + rela->r_addend); - break; - case R_ARM_PC24: - val = value + rela->r_addend - rela->r_offset; - val >>= 2; - if ((Elf32_Word) val + 0x800000 >= 0x1000000) - { - error (0, 0, "%s: R_ARM_PC24 overflow", info->dso->filename); - return 1; - } - val &= 0xffffff; - buf_write_ne32 (info->dso, buf, (buf_read_une32 (info->dso, buf) & 0xff000000) | val); - break; - case R_ARM_COPY: - abort (); - case R_ARM_RELATIVE: - error (0, 0, "%s: R_ARM_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -arm_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rel->r_info) == R_ARM_RELATIVE - || GELF_R_TYPE (rel->r_info) == R_ARM_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rel->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_TPOFF32: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_ARM_IRELATIVE: - break; - /* Likewise TLS_DESC. */ - case R_ARM_TLS_DESC: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF32 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rel->r_info) == R_ARM_TLS_DTPOFF32 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rel->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - ret->r_addend = (Elf32_Sword) value; - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); - break; - case R_ARM_IRELATIVE: - ret->r_addend = (Elf32_Sword) read_une32 (dso, rel->r_offset); - break; - case R_ARM_ABS32: - case R_ARM_PC24: - error (0, 0, "%s: R_ARM_%s relocs should not be present in prelinked REL sections", - dso->filename, GELF_R_TYPE (rel->r_info) == R_ARM_ABS32 ? "ABS32" : "PC24"); - return 1; - case R_ARM_COPY: - error (0, 0, "R_ARM_COPY should not be present in shared libraries"); - return 1; - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_DTPOFF32: - case R_ARM_TLS_TPOFF32: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_ARM_ABS32); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_TLS_DTPMOD32: - ret->r_addend = tls->modid; - break; - case R_ARM_TLS_DTPOFF32: - ret->r_addend = value + read_une32 (dso, rel->r_offset); - break; - case R_ARM_TLS_TPOFF32: - ret->r_addend = (value + read_une32 (dso, rel->r_offset) - + tls->offset); - break; - } - break; - case R_ARM_TLS_DESC: - /* Nothing to do. */ - break; - default: - error (0, 0, "%s: Unknown arm relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -arm_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - Elf32_Sword val; - - if (GELF_R_TYPE (rela->r_info) == R_ARM_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_ARM_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - - if (conflict == NULL) - { - if (info->curtls == NULL) - return 0; - - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_TPOFF32: - break; - /* Likewise TLS_DESC. */ - case R_ARM_TLS_DESC: - break; - default: - return 0; - } - value = 0; - } - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on ARM yet", - dso->filename); - return 1; - } - else - { - /* DTPOFF32 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_ARM_TLS_DTPOFF32 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_GLOB_DAT: - case R_ARM_JUMP_SLOT: - case R_ARM_ABS32: - case R_ARM_IRELATIVE: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend); - if (conflict && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_ARM_IRELATIVE); - break; - case R_ARM_PC24: - val = value + rela->r_addend - rela->r_offset; - val >>= 2; - if ((Elf32_Word) val + 0x800000 >= 0x1000000) - { - error (0, 0, "%s: R_ARM_PC24 overflow", dso->filename); - return 1; - } - value = read_une32 (dso, rela->r_offset) & 0xff000000; - ret->r_addend = (Elf32_Sword) (value | (val & 0xffffff)); - ret->r_info = GELF_R_INFO (0, R_ARM_ABS32); - break; - case R_ARM_COPY: - error (0, 0, "R_ARM_COPY should not be present in shared libraries"); - return 1; - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_DTPOFF32: - case R_ARM_TLS_TPOFF32: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_ARM_ABS32); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_ARM_TLS_DTPMOD32: - ret->r_addend = tls->modid; - break; - case R_ARM_TLS_DTPOFF32: - ret->r_addend = value + rela->r_addend; - break; - case R_ARM_TLS_TPOFF32: - ret->r_addend = value + rela->r_addend + tls->offset; - break; - } - break; - case R_ARM_TLS_DESC: - /* Nothing to do. */ - break; - default: - error (0, 0, "%s: Unknown arm relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -arm_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - rela->r_offset = rel->r_offset; - rela->r_info = rel->r_info; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_JUMP_SLOT: - /* We should be never converting .rel.plt into .rela.plt. */ - abort (); - case R_ARM_RELATIVE: - case R_ARM_IRELATIVE: - case R_ARM_ABS32: - case R_ARM_TLS_TPOFF32: - case R_ARM_TLS_DTPOFF32: - rela->r_addend = (Elf32_Sword) read_une32 (dso, rel->r_offset); - break; - case R_ARM_PC24: - rela->r_addend = read_une32 (dso, rel->r_offset) << 8; - rela->r_addend = ((Elf32_Sword) rela->r_addend) >> 6; - break; - case R_ARM_COPY: - case R_ARM_GLOB_DAT: - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_DESC: - rela->r_addend = 0; - break; - } - return 0; -} - -static int -arm_rela_to_rel (DSO *dso, GElf_Rela *rela, GElf_Rel *rel) -{ - rel->r_offset = rela->r_offset; - rel->r_info = rela->r_info; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_JUMP_SLOT: - /* We should be never converting .rel.plt into .rela.plt - and thus never .rela.plt back to .rel.plt. */ - abort (); - case R_ARM_RELATIVE: - case R_ARM_IRELATIVE: - case R_ARM_ABS32: - case R_ARM_TLS_TPOFF32: - case R_ARM_TLS_DTPOFF32: - write_ne32 (dso, rela->r_offset, rela->r_addend); - break; - case R_ARM_PC24: - write_ne32 (dso, rela->r_offset, - (read_une32 (dso, rela->r_offset) & 0xff000000) - | ((rela->r_addend >> 2) & 0xffffff)); - break; - case R_ARM_GLOB_DAT: - case R_ARM_TLS_DTPMOD32: - write_ne32 (dso, rela->r_offset, 0); - break; - } - return 0; -} - -static int -arm_need_rel_to_rela (DSO *dso, int first, int last) -{ - Elf_Data *data; - Elf_Scn *scn; - Elf32_Rel *rel, *relend; - unsigned int val; - - while (first <= last) - { - data = NULL; - scn = dso->scn[first++]; - while ((data = elf_getdata (scn, data)) != NULL) - { - rel = (Elf32_Rel *) data->d_buf; - relend = rel + data->d_size / sizeof (Elf32_Rel); - for (; rel < relend; rel++) - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_ARM_ABS32: - val = read_une32 (dso, rel->r_offset); - /* R_ARM_ABS32 with addend 0 can be converted - to R_ARM_GLOB_DAT and we don't have to convert - to RELA because of that. */ - if (val == 0) - break; - /* FALLTHROUGH */ - case R_ARM_PC24: - return 1; - case R_ARM_TLS_TPOFF32: - /* In shared libraries TPOFF is changed always into - conflicts, for executables we need to preserve - original addend. */ - if (dso->ehdr.e_type == ET_EXEC) - return 1; - case R_ARM_TLS_DTPOFF32: - /* We can prelink these fields, and the addend is relative - to the symbol value. A RELA entry is needed. */ - return 1; - - break; - } - } - } - return 0; -} - -static int -arm_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt into got[1]. - .plt is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr; - write_ne32 (dso, dso->info[DT_PLTGOT] + 4, data); - } - - return 0; -} - -static int -arm_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_une32 (dso, dso->info[DT_PLTGOT] + 4); - if (data == dso->shdr[i].sh_addr) - write_ne32 (dso, dso->info[DT_PLTGOT] + 4, 0); - } - - return 0; -} - -static int -arm_undo_prelink_rel (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rel->r_info)) - { - case R_ARM_RELATIVE: - case R_ARM_IRELATIVE: - case R_ARM_NONE: - break; - case R_ARM_JUMP_SLOT: - sec = addr_to_sec (dso, rel->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_ARM_JMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf32_Addr data = read_une32 (dso, dso->shdr[sec].sh_addr + 4); - - assert (rel->r_offset >= dso->shdr[sec].sh_addr + 12); - assert (((rel->r_offset - dso->shdr[sec].sh_addr) & 3) == 0); - write_ne32 (dso, rel->r_offset, data); - } - break; - case R_ARM_GLOB_DAT: - sec = addr_to_sec (dso, rel->r_offset); - - write_ne32 (dso, rel->r_offset, 0); - if (sec != -1) - { - if (strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[sec].sh_name), - ".got")) - { - rel->r_info = GELF_R_INFO (GELF_R_SYM (rel->r_info), R_ARM_ABS32); - return 2; - } - } - break; - case R_ARM_ABS32: - case R_ARM_PC24: - error (0, 0, "%s: R_ARM_%s relocs should not be present in prelinked REL sections", - GELF_R_TYPE (rel->r_info) == R_ARM_ABS32 ? "ABS32" : "PC24", - dso->filename); - return 1; - case R_ARM_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_ARM_COPY reloc in shared library?", dso->filename); - return 1; - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_DTPOFF32: - write_ne32 (dso, rel->r_offset, 0); - break; - case R_ARM_TLS_TPOFF32: - break; - case R_ARM_TLS_DESC: - write_ne32 (dso, rel->r_offset + 4, 0); - break; - default: - error (0, 0, "%s: Unknown arm relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -arm_reloc_size (int reloc_type) -{ - assert (reloc_type != R_ARM_COPY); - return 4; -} - -static int -arm_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_ARM_COPY: return RTYPE_CLASS_COPY; - case R_ARM_JUMP_SLOT: return RTYPE_CLASS_PLT; - case R_ARM_TLS_DTPMOD32: - case R_ARM_TLS_DTPOFF32: - case R_ARM_TLS_TPOFF32: - case R_ARM_TLS_DESC: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(arm) = { - .name = "ARM", - .class = ELFCLASS32, - .machine = EM_ARM, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_ARM_JUMP_SLOT, - .R_COPY = R_ARM_COPY, - .R_RELATIVE = R_ARM_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux.so.3", - .dynamic_linker_alt = "/lib/ld-linux-armhf.so.3", - .adjust_dyn = arm_adjust_dyn, - .adjust_rel = arm_adjust_rel, - .adjust_rela = arm_adjust_rela, - .prelink_rel = arm_prelink_rel, - .prelink_rela = arm_prelink_rela, - .prelink_conflict_rel = arm_prelink_conflict_rel, - .prelink_conflict_rela = arm_prelink_conflict_rela, - .apply_conflict_rela = arm_apply_conflict_rela, - .apply_rel = arm_apply_rel, - .apply_rela = arm_apply_rela, - .rel_to_rela = arm_rel_to_rela, - .rela_to_rel = arm_rela_to_rel, - .need_rel_to_rela = arm_need_rel_to_rela, - .reloc_size = arm_reloc_size, - .reloc_class = arm_reloc_class, - .max_reloc_size = 4, - .arch_prelink = arm_arch_prelink, - .arch_undo_prelink = arm_arch_undo_prelink, - .undo_prelink_rel = arm_undo_prelink_rel, - /* Although TASK_UNMAPPED_BASE is 0x40000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x41000000, - .mmap_end = 0x50000000, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-cris.c b/trunk/src/arch-cris.c deleted file mode 100644 index 3272779..0000000 --- a/trunk/src/arch-cris.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Copyright (C) 2001, 2002, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -cris_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf32_Addr data; - - if (sec == -1) - return 0; - - data = read_ule32 (dso, dyn->d_un.d_ptr); - /* If .got[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_le32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ule32 (dso, dyn->d_un.d_ptr + 4); - /* If .got[1] points to .plt + 28, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 28 - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_le32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - break; - } - } - } - return 0; -} - -static int -cris_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: CRIS doesn't support REL relocs", dso->filename); - return 1; -} - -static int -cris_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_CRIS_RELATIVE: - if ((Elf32_Addr) rela->r_addend >= start) - rela->r_addend += (Elf32_Sword) adjust; - break; - case R_CRIS_JUMP_SLOT: - data = read_ule32 (dso, rela->r_offset); - if (data >= start) - write_le32 (dso, rela->r_offset, data + adjust); - break; - break; - } - return 0; -} - -static int -cris_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: CRIS doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -cris_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - dso = info->dso; - if (GELF_R_TYPE (rela->r_info) == R_CRIS_NONE) - /* Fast path: nothing to do. */ - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_CRIS_RELATIVE) - { - write_le32 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_CRIS_GLOB_DAT: - case R_CRIS_JUMP_SLOT: - case R_CRIS_32: - write_le32 (dso, rela->r_offset, value); - break; - case R_CRIS_16: - write_le16 (dso, rela->r_offset, value); - break; - case R_CRIS_8: - write_8 (dso, rela->r_offset, value); - break; - case R_CRIS_32_PCREL: - write_le32 (dso, rela->r_offset, value - rela->r_offset - 4); - break; - case R_CRIS_16_PCREL: - write_le16 (dso, rela->r_offset, value - rela->r_offset - 2); - break; - case R_CRIS_8_PCREL: - write_8 (dso, rela->r_offset, value - rela->r_offset - 1); - break; - case R_CRIS_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_CRIS_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown cris relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -cris_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - switch (GELF_R_TYPE (rela->r_info)) - { - case R_CRIS_GLOB_DAT: - case R_CRIS_JUMP_SLOT: - case R_CRIS_32: - buf_write_le32 (buf, rela->r_addend); - break; - case R_CRIS_16: - buf_write_le16 (buf, rela->r_addend); - break; - case R_CRIS_8: - buf_write_8 (buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -cris_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: CRIS doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -cris_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_CRIS_NONE: - break; - case R_CRIS_GLOB_DAT: - case R_CRIS_JUMP_SLOT: - case R_CRIS_32: - buf_write_le32 (buf, value); - break; - case R_CRIS_16: - buf_write_le16 (buf, value); - break; - case R_CRIS_8: - buf_write_8 (buf, value); - break; - case R_CRIS_32_PCREL: - buf_write_le32 (buf, value - rela->r_offset - 4); - break; - case R_CRIS_16_PCREL: - buf_write_le16 (buf, value - rela->r_offset - 2); - break; - case R_CRIS_8: - buf_write_8 (buf, value - rela->r_offset - 1); - break; - case R_CRIS_COPY: - abort (); - case R_CRIS_RELATIVE: - error (0, 0, "%s: R_CRIS_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -cris_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: CRIS doesn't support REL relocs", dso->filename); - return 1; -} - -static int -cris_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_CRIS_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_CRIS_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - return 0; - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on CRIS yet", - dso->filename); - return 1; - } - value = conflict_lookup_value (conflict); - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_CRIS_GLOB_DAT: - case R_CRIS_JUMP_SLOT: - case R_CRIS_32: - case R_CRIS_16: - case R_CRIS_8: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend); - break; - case R_CRIS_32_PCREL: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend - - rela->r_offset - 4); - ret->r_info = GELF_R_INFO (0, R_CRIS_32); - break; - case R_CRIS_16_PCREL: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend - - rela->r_offset - 2); - ret->r_info = GELF_R_INFO (0, R_CRIS_16); - break; - case R_CRIS_8_PCREL: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend - - rela->r_offset - 1); - ret->r_info = GELF_R_INFO (0, R_CRIS_8); - break; - case R_CRIS_COPY: - error (0, 0, "R_CRIS_COPY should not be present in shared libraries"); - return 1; - default: - error (0, 0, "%s: Unknown cris relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -cris_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - return 0; -} - -static int -cris_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -cris_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 28 into got[1]. - .plt + 28 is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - assert (i < dso->ehdr.e_shnum); - data = dso->shdr[i].sh_addr + 28; - write_le32 (dso, dso->info[DT_PLTGOT] + 4, data); - } - - return 0; -} - -static int -cris_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_CRIS_16: - case R_CRIS_16_PCREL: - return 2; - case R_CRIS_8: - case R_CRIS_8_PCREL: - return 1; - default: - return 4; - } -} - -static int -cris_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_CRIS_COPY: return RTYPE_CLASS_COPY; - case R_CRIS_JUMP_SLOT: return RTYPE_CLASS_PLT; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(cris) = { - .name = "CRIS", - .class = ELFCLASS32, - .machine = EM_CRIS, - .alternate_machine = { EM_NONE }, - .R_JUMP_SLOT = R_CRIS_JUMP_SLOT, - .R_COPY = R_CRIS_COPY, - .R_RELATIVE = R_CRIS_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld.so.1", - .adjust_dyn = cris_adjust_dyn, - .adjust_rel = cris_adjust_rel, - .adjust_rela = cris_adjust_rela, - .prelink_rel = cris_prelink_rel, - .prelink_rela = cris_prelink_rela, - .prelink_conflict_rel = cris_prelink_conflict_rel, - .prelink_conflict_rela = cris_prelink_conflict_rela, - .apply_conflict_rela = cris_apply_conflict_rela, - .apply_rel = cris_apply_rel, - .apply_rela = cris_apply_rela, - .rel_to_rela = cris_rel_to_rela, - .need_rel_to_rela = cris_need_rel_to_rela, - .reloc_size = cris_reloc_size, - .reloc_class = cris_reloc_class, - .max_reloc_size = 4, - .arch_prelink = cris_arch_prelink, - /* Although TASK_UNMAPPED_BASE is 0x3aaaa000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x3c000000, - .mmap_end = 0x48000000, - .max_page_size = 0x2000, - .page_size = 0x2000 -}; diff --git a/trunk/src/arch-i386.c b/trunk/src/arch-i386.c deleted file mode 100644 index a1e0fcc..0000000 --- a/trunk/src/arch-i386.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009, 2011 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" -#include "layout.h" - -static int -i386_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf32_Addr data; - - if (sec == -1) - return 0; - - data = read_ule32 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_le32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ule32 (dso, dyn->d_un.d_ptr + 4); - /* If .got.plt[1] points to .plt + 0x16, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 0x16 - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_le32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - break; - } - } - } - return 0; -} - -static int -i386_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_RELATIVE: - case R_386_JMP_SLOT: - case R_386_IRELATIVE: - data = read_ule32 (dso, rel->r_offset); - if (data >= start) - write_le32 (dso, rel->r_offset, data + adjust); - break; - } - return 0; -} - -static int -i386_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_RELATIVE: - case R_386_IRELATIVE: - if ((Elf32_Addr) rela->r_addend >= start) - { - rela->r_addend += (Elf32_Sword) adjust; - /* Write it to the memory location as well. - Not necessary, but we can do it. */ - write_le32 (dso, rela->r_offset, rela->r_addend); - } - break; - case R_386_JMP_SLOT: - data = read_ule32 (dso, rela->r_offset); - if (data >= start) - write_le32 (dso, rela->r_offset, data + adjust); - break; - break; - } - return 0; -} - -static int -i386_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - DSO *dso; - GElf_Addr value; - - if (GELF_R_TYPE (rel->r_info) == R_386_RELATIVE - || GELF_R_TYPE (rel->r_info) == R_386_IRELATIVE - || GELF_R_TYPE (rel->r_info) == R_386_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - write_le32 (dso, rel->r_offset, value); - break; - case R_386_32: - { - if (read_ule32 (dso, rel->r_offset)) - { - error (0, 0, "%s: R_386_32 relocs with non-zero addend should not be present in prelinked REL sections", - dso->filename); - return 1; - } - rel->r_info = GELF_R_INFO (GELF_R_SYM (rel->r_info), R_386_GLOB_DAT); - write_le32 (dso, rel->r_offset, value); - /* Tell prelink_rel routine *rel has changed. */ - return 2; - } - case R_386_PC32: - error (0, 0, "%s: R_386_PC32 relocs should not be present in prelinked REL sections", - dso->filename); - return 1; - case R_386_TLS_DTPOFF32: - write_le32 (dso, rel->r_offset, value); - break; - /* DTPMOD32 and TPOFF{32,} is impossible to predict unless prelink - sets the rules. Also for TPOFF{32,} there is REL->RELA problem. */ - case R_386_TLS_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_386_TLS_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - if (dso->ehdr.e_type == ET_EXEC) - error (0, 0, "%s: R_386_TLS_TPOFF relocs should not be present in prelinked ET_EXEC REL sections", - dso->filename); - break; - case R_386_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_386_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown i386 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -i386_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_386_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_386_IRELATIVE - || GELF_R_TYPE (rela->r_info) == R_386_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - write_le32 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_386_32: - write_le32 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_386_PC32: - write_le32 (dso, rela->r_offset, value + rela->r_addend - rela->r_offset); - break; - case R_386_TLS_DTPOFF32: - write_le32 (dso, rela->r_offset, value + rela->r_addend); - break; - /* DTPMOD32 and TPOFF{32,} is impossible to predict unless prelink - sets the rules. */ - case R_386_TLS_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_386_TLS_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_386_TLS_TPOFF32: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_le32 (dso, rela->r_offset, - -(value + rela->r_addend - info->resolvetls->offset)); - break; - case R_386_TLS_TPOFF: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_le32 (dso, rela->r_offset, - value + rela->r_addend - info->resolvetls->offset); - break; - case R_386_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_386_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown i386 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -i386_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - case R_386_32: - buf_write_le32 (buf, rela->r_addend); - break; - case R_386_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_386_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -i386_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_NONE: - break; - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - buf_write_le32 (buf, value); - break; - case R_386_32: - buf_write_le32 (buf, value + read_ule32 (info->dso, rel->r_offset)); - break; - case R_386_PC32: - buf_write_le32 (buf, value + read_ule32 (info->dso, rel->r_offset) - - rel->r_offset); - break; - case R_386_COPY: - abort (); - case R_386_RELATIVE: - error (0, 0, "%s: R_386_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -i386_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_NONE: - break; - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - case R_386_32: - buf_write_le32 (buf, value + rela->r_addend); - break; - case R_386_PC32: - buf_write_le32 (buf, value + rela->r_addend - rela->r_offset); - break; - case R_386_COPY: - abort (); - case R_386_RELATIVE: - error (0, 0, "%s: R_386_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -i386_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rel->r_info) == R_386_RELATIVE - || GELF_R_TYPE (rel->r_info) == R_386_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rel->r_info), - GELF_R_TYPE (rel->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rel->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_386_TLS_DTPMOD32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_386_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF32 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rel->r_info) == R_386_TLS_DTPOFF32 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rel->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rel->r_info)); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_GLOB_DAT: - ret->r_info = GELF_R_INFO (0, R_386_32); - /* FALLTHROUGH */ - case R_386_JMP_SLOT: - ret->r_addend = (Elf32_Sword) value; - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_386_IRELATIVE); - break; - case R_386_IRELATIVE: - ret->r_addend = (Elf32_Sword) read_ule32 (dso, rel->r_offset); - break; - case R_386_32: - case R_386_PC32: - error (0, 0, "%s: R_386_%s32 relocs should not be present in prelinked REL sections", - dso->filename, GELF_R_TYPE (rel->r_info) == R_386_32 ? "" : "PC"); - return 1; - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: R_386_TLS not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_386_32); - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_TLS_DTPMOD32: - ret->r_addend = tls->modid; - break; - case R_386_TLS_DTPOFF32: - ret->r_addend = value; - break; - case R_386_TLS_TPOFF32: - ret->r_addend = -(value + read_ule32 (dso, rel->r_offset) - - tls->offset); - break; - case R_386_TLS_TPOFF: - ret->r_addend = value + read_ule32 (dso, rel->r_offset) - - tls->offset; - } - break; - case R_386_COPY: - error (0, 0, "R_386_COPY should not be present in shared libraries"); - return 1; - default: - error (0, 0, "%s: Unknown i386 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -i386_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_386_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_386_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_386_TLS_DTPMOD32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_386_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF32 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_386_TLS_DTPOFF32 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_GLOB_DAT: - ret->r_info = GELF_R_INFO (0, R_386_32); - /* FALLTHROUGH */ - case R_386_JMP_SLOT: - case R_386_IRELATIVE: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend); - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_386_IRELATIVE); - break; - case R_386_32: - value += rela->r_addend; - ret->r_addend = (Elf32_Sword) value; - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_386_IRELATIVE); - break; - case R_386_PC32: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend - rela->r_offset); - ret->r_info = GELF_R_INFO (0, R_386_32); - break; - case R_386_COPY: - error (0, 0, "R_386_COPY should not be present in shared libraries"); - return 1; - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: R_386_TLS not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_386_32); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_386_TLS_DTPMOD32: - ret->r_addend = tls->modid; - break; - case R_386_TLS_DTPOFF32: - ret->r_addend += value; - break; - case R_386_TLS_TPOFF32: - ret->r_addend = -(value + rela->r_addend - tls->offset); - break; - case R_386_TLS_TPOFF: - ret->r_addend = value + rela->r_addend - tls->offset; - break; - } - break; - default: - error (0, 0, "%s: Unknown i386 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -i386_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - rela->r_offset = rel->r_offset; - rela->r_info = rel->r_info; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_JMP_SLOT: - /* We should be never converting .rel.plt into .rela.plt. */ - abort (); - case R_386_RELATIVE: - case R_386_IRELATIVE: - case R_386_32: - case R_386_PC32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - rela->r_addend = (Elf32_Sword) read_ule32 (dso, rel->r_offset); - break; - case R_386_COPY: - case R_386_GLOB_DAT: - case R_386_TLS_DTPOFF32: - case R_386_TLS_DTPMOD32: - rela->r_addend = 0; - break; - } - return 0; -} - -static int -i386_need_rel_to_rela (DSO *dso, int first, int last) -{ - Elf_Data *data; - Elf_Scn *scn; - Elf32_Rel *rel, *relend; - unsigned int val; - - while (first <= last) - { - data = NULL; - scn = dso->scn[first++]; - while ((data = elf_getdata (scn, data)) != NULL) - { - rel = (Elf32_Rel *) data->d_buf; - relend = rel + data->d_size / sizeof (Elf32_Rel); - for (; rel < relend; rel++) - switch (ELF32_R_TYPE (rel->r_info)) - { - case R_386_32: - val = read_ule32 (dso, rel->r_offset); - /* R_386_32 with addend 0 can be converted - to R_386_GLOB_DAT and we don't have to convert - to RELA because of that. */ - if (val == 0) - break; - /* FALLTHROUGH */ - case R_386_PC32: - return 1; - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - /* In shared libraries TPOFF is changed always into - conflicts, for executables we need to preserve - original addend. */ - if (dso->ehdr.e_type == ET_EXEC) - return 1; - break; - } - } - } - return 0; -} - -static int -i386_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 0x16 into got[1]. - .plt + 0x16 is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr + 0x16; - write_le32 (dso, dso->info[DT_PLTGOT] + 4, data); - } - - return 0; -} - -static int -i386_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt + 0x16. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_ule32 (dso, dso->info[DT_PLTGOT] + 4); - if (data == dso->shdr[i].sh_addr + 0x16) - write_le32 (dso, dso->info[DT_PLTGOT] + 4, 0); - } - - return 0; -} - -static int -i386_undo_prelink_rel (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_NONE: - case R_386_RELATIVE: - case R_386_IRELATIVE: - break; - case R_386_JMP_SLOT: - sec = addr_to_sec (dso, rel->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_386_JMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf32_Addr data = read_ule32 (dso, dso->shdr[sec].sh_addr + 4); - - assert (rel->r_offset >= dso->shdr[sec].sh_addr + 12); - assert (((rel->r_offset - dso->shdr[sec].sh_addr) & 3) == 0); - write_le32 (dso, rel->r_offset, - 4 * (rel->r_offset - dso->shdr[sec].sh_addr - 12) - + data); - } - break; - case R_386_GLOB_DAT: - sec = addr_to_sec (dso, rel->r_offset); - - write_le32 (dso, rel->r_offset, 0); - if (sec != -1) - { - if (strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[sec].sh_name), - ".got")) - { - rel->r_info = GELF_R_INFO (GELF_R_SYM (rel->r_info), R_386_32); - return 2; - } - } - break; - case R_386_32: - case R_386_PC32: - error (0, 0, "%s: R_386_%s32 relocs should not be present in prelinked REL sections", - GELF_R_TYPE (rel->r_info) == R_386_32 ? "" : "PC", dso->filename); - return 1; - case R_386_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_386_COPY reloc in shared library?", dso->filename); - return 1; - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - write_le32 (dso, rel->r_offset, 0); - break; - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - break; - default: - error (0, 0, "%s: Unknown i386 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rel->r_info)); - return 1; - } - return 0; -} - -static int -i386_rela_to_rel (DSO *dso, GElf_Rela *rela, GElf_Rel *rel) -{ - rel->r_offset = rela->r_offset; - rel->r_info = rela->r_info; - switch (GELF_R_TYPE (rel->r_info)) - { - case R_386_JMP_SLOT: - /* We should be never converting .rel.plt into .rela.plt - and thus never .rela.plt back to .rel.plt. */ - abort (); - case R_386_RELATIVE: - case R_386_IRELATIVE: - case R_386_32: - case R_386_PC32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - write_le32 (dso, rela->r_offset, rela->r_addend); - break; - case R_386_COPY: - case R_386_GLOB_DAT: - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - write_le32 (dso, rela->r_offset, 0); - break; - } - return 0; -} - -static int -i386_reloc_size (int reloc_type) -{ - assert (reloc_type != R_386_COPY); - return 4; -} - -static int -i386_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_386_COPY: return RTYPE_CLASS_COPY; - case R_386_JMP_SLOT: return RTYPE_CLASS_PLT; - case R_386_TLS_DTPMOD32: - case R_386_TLS_DTPOFF32: - case R_386_TLS_TPOFF32: - case R_386_TLS_TPOFF: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -/* Library memory regions if --exec-shield in order of precedence: - 0x00101000 + (rand % 0x00cff000) .. 0x00e00000 bottom to top - 0x00101000 .. 0x00101000 + (rand % 0x00cff000) bottom to top - 0x02000000 + (rand % 0x06000000) .. 0x08000000 bottom to top - 0x02000000 .. 0x02000000 + (rand % 0x06000000) bottom to top - 0x41000000 + (rand % 0x0f000000) .. 0x50000000 bottom to top - 0x41000000 .. 0x41000000 + (rand % 0x0f000000) bottom to top */ - -#define REG0S 0x00101000 -#define REG0E 0x00e00000 -#define REG1S 0x02000000 -#define REG1E 0x08000000 -#define REG2S 0x41000000 -#define REG2E 0x50000000 - -struct i386_layout_data -{ - struct prelink_entry e[6]; - Elf32_Addr addrs[12]; -}; - -static inline void -list_append (struct prelink_entry *x, struct prelink_entry *e) -{ - x->prev->next = e; - e->prev = x->prev; - e->next = NULL; - x->prev = e; -} - -static inline void -list_merge (struct prelink_entry *x, struct prelink_entry *e) -{ - struct prelink_entry *end = e->prev; - x->prev->next = e; - e->prev = x->prev; - x->prev = end; -} - -static int -i386_layout_libs_init (struct layout_libs *l) -{ - if (exec_shield) - { - int i; - struct prelink_entry *e; - Elf32_Addr reg0s; - - if (l->max_page_size > 0x200000) - error (EXIT_FAILURE, 0, "--layout-page-size too large"); - - reg0s = (REG0S + l->max_page_size - 1) & ~(l->max_page_size - 1); - l->mmap_base = reg0s; - l->mmap_end = REG2E; - /* Don't allow this to be overridden. */ - mmap_reg_start = ~(GElf_Addr) 0; - mmap_reg_end = ~(GElf_Addr) 0; - for (i = 0; i < l->nlibs; ++i) - { - e = l->libs[i]; - if (e->done == 0) - continue; - if (e->base < reg0s - || (e->base < REG1S && e->layend > REG0E) - || (e->base < REG2S && e->layend > REG1E) - || e->layend > REG2E) - e->done = 0; - } - } - else - { - l->mmap_base = REG2S; - l->mmap_end = REG2E; - } - return 0; -} - -static void -i386_find_free_addr (struct layout_libs *l, Elf32_Addr *ret, - Elf32_Addr beg, Elf32_Addr end, Elf32_Addr start) -{ - struct prelink_entry *e; - Elf32_Addr low, hi; - - ret[0] = beg; - ret[3] = end; - for (e = l->list; e != NULL; e = e->next) - if (e->base >= start) - break; - if (e == l->list) - { - ret[1] = ret[2] = start; - return; - } - - if (e == NULL) - e = l->list; - low = start; - for (e = e->prev; ; e = e->prev) - { - if (e->base < beg) - break; - if (e->layend > low) - low = e->base; - if (e == l->list) - break; - } - - if (low == start) - { - ret[1] = ret[2] = start; - return; - } - - hi = start; - for (; e; e = e->next) - { - if (e->base >= end) - break; - if (e->base >= hi) - break; - if (e->layend > hi) - hi = e->layend; - } - - assert (low >= beg && hi <= end); - - if (hi - start > start - low) - start = low; - else - start = hi; - - ret[1] = ret[2] = start; -} - -static int -i386_layout_libs_pre (struct layout_libs *l) -{ - Elf32_Addr mmap_start, virt, reg0s; - struct prelink_entry *e, *next; - struct i386_layout_data *pld; - int i; - - if (!exec_shield) - { - l->mmap_fin = l->mmap_end; - l->fake = NULL; - l->fakecnt = 0; - return 0; - } - - pld = calloc (sizeof (*pld), 1); - if (pld == NULL) - error (EXIT_FAILURE, ENOMEM, "Cannot lay libraries out"); - - l->arch_data = pld; - reg0s = (REG0S + l->max_page_size - 1) & ~(l->max_page_size - 1); - - mmap_start = l->mmap_start - reg0s; - /* Unless not randomizing, try not to make the first region - too small, because otherwise it is likely libc.so as first - big library would often end up at reg0s. */ - virt = mmap_start % (REG0E - reg0s - 0x200000); - i386_find_free_addr (l, pld->addrs + 0, reg0s, REG0E, reg0s + virt); - virt = mmap_start % (REG1E - REG1S - 0x200000); - i386_find_free_addr (l, pld->addrs + 4, REG1S, REG1E, REG1S + virt); - virt = mmap_start % (REG2E - REG2S - 0x200000); - i386_find_free_addr (l, pld->addrs + 8, REG2S, REG2E, REG2S + virt); - i = 0; - virt = pld->addrs[3] - pld->addrs[2]; - pld->e[0].u.tmp = -1; - pld->e[0].base = virt; - pld->e[0].end = pld->e[0].base; - pld->e[0].layend = pld->e[0].end; - pld->e[0].prev = &pld->e[0]; - next = NULL; - for (e = l->list; e != NULL; e = next) - { - next = e->next; - while (i < 5 - && (e->base >= pld->addrs[2 * i + 1] - || pld->addrs[2 * i] == pld->addrs[2 * i + 1])) - { - ++i; - pld->e[i].u.tmp = -1; - if (i & 1) - virt -= pld->addrs[2 * i + 1] - pld->addrs[2 * i]; - else - { - virt += pld->addrs[2 * i - 1] - pld->addrs[2 * i - 4]; - virt += pld->addrs[2 * i + 3] - pld->addrs[2 * i + 2]; - } - pld->e[i].base = virt; - pld->e[i].end = pld->e[i].base; - pld->e[i].layend = pld->e[i].end; - pld->e[i].prev = &pld->e[i]; - } - e->base += (Elf32_Sword) (virt - pld->addrs[2 * i]); - e->end += (Elf32_Sword) (virt - pld->addrs[2 * i]); - e->layend += (Elf32_Sword) (virt - pld->addrs[2 * i]); - list_append (&pld->e[i], e); - } - while (i < 5) - { - ++i; - pld->e[i].u.tmp = -1; - if (i & 1) - virt -= pld->addrs[2 * i + 1] - pld->addrs[2 * i]; - else - { - virt += pld->addrs[2 * i - 1] - pld->addrs[2 * i - 4]; - virt += pld->addrs[2 * i + 3] - pld->addrs[2 * i + 2]; - } - pld->e[i].base = virt; - pld->e[i].end = pld->e[i].base; - pld->e[i].layend = pld->e[i].end; - pld->e[i].prev = &pld->e[i]; - } - l->list = &pld->e[1]; - list_merge (&pld->e[1], &pld->e[0]); - list_merge (&pld->e[1], &pld->e[3]); - list_merge (&pld->e[1], &pld->e[2]); - list_merge (&pld->e[1], &pld->e[5]); - list_merge (&pld->e[1], &pld->e[4]); - - l->mmap_start = 0; - l->mmap_base = 0; - l->mmap_fin = virt + pld->addrs[2 * i + 1] - pld->addrs[2 * i]; - l->mmap_end = l->mmap_fin; - l->fakecnt = 6; - l->fake = pld->e; - - return 0; -} - -static int -i386_layout_libs_post (struct layout_libs *l) -{ - struct prelink_entry *e; - struct i386_layout_data *pld = (struct i386_layout_data *) l->arch_data; - Elf32_Sword adj = 0; - int i; - - if (!exec_shield) - return 0; - - for (i = 0, e = l->list; e != NULL; e = e->next) - { - if (e == &pld->e[i ^ 1]) - { - adj = pld->addrs[2 * (i ^ 1)] - e->base; - ++i; - } - else - { - e->base += adj; - e->end += adj; - e->layend += adj; - } - } - - free (l->arch_data); - return 0; -} - -PL_ARCH(i386) = { - .name = "i386", - .class = ELFCLASS32, - .machine = EM_386, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_386_JMP_SLOT, - .R_COPY = R_386_COPY, - .R_RELATIVE = R_386_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux.so.2", - .adjust_dyn = i386_adjust_dyn, - .adjust_rel = i386_adjust_rel, - .adjust_rela = i386_adjust_rela, - .prelink_rel = i386_prelink_rel, - .prelink_rela = i386_prelink_rela, - .prelink_conflict_rel = i386_prelink_conflict_rel, - .prelink_conflict_rela = i386_prelink_conflict_rela, - .apply_conflict_rela = i386_apply_conflict_rela, - .apply_rel = i386_apply_rel, - .apply_rela = i386_apply_rela, - .rel_to_rela = i386_rel_to_rela, - .rela_to_rel = i386_rela_to_rel, - .need_rel_to_rela = i386_need_rel_to_rela, - .reloc_size = i386_reloc_size, - .reloc_class = i386_reloc_class, - .max_reloc_size = 4, - .arch_prelink = i386_arch_prelink, - .arch_undo_prelink = i386_arch_undo_prelink, - .undo_prelink_rel = i386_undo_prelink_rel, - .layout_libs_init = i386_layout_libs_init, - .layout_libs_pre = i386_layout_libs_pre, - .layout_libs_post = i386_layout_libs_post, - /* Although TASK_UNMAPPED_BASE is 0x40000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = REG2S, - .mmap_end = REG2E, - .max_page_size = 0x1000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-ia64.c b/trunk/src/arch-ia64.c deleted file mode 100644 index 6039115..0000000 --- a/trunk/src/arch-ia64.c +++ /dev/null @@ -1,533 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" -#include "fptr.h" - -static int -ia64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_IA_64_PLT_RESERVE) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf64_Addr data; - - if (sec != -1) - { - data = read_ule64 (dso, dyn->d_un.d_ptr + 8); - - /* If .got[1] points to .plt + 0x30, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 0x30 - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_le64 (dso, dyn->d_un.d_ptr + 8, data + adjust); - break; - } - } - } - - if (dyn->d_un.d_ptr >= start) - dyn->d_un.d_ptr += adjust; - return 1; - } - - return 0; -} - -static int -ia64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: IA-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ia64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_REL32MSB - && rela->r_addend >= start) - { - rela->r_addend += adjust; - switch (GELF_R_TYPE (rela->r_info) & 3) - { - case 0: write_be32 (dso, rela->r_offset, rela->r_addend); break; - case 1: write_le32 (dso, rela->r_offset, rela->r_addend); break; - case 2: write_be64 (dso, rela->r_offset, rela->r_addend); break; - case 3: write_le64 (dso, rela->r_offset, rela->r_addend); break; - } - } - else if ((GELF_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - { - GElf_Addr val, gp; - - if (GELF_R_TYPE (rela->r_info) & 1) - { - val = read_ule64 (dso, rela->r_offset); - gp = read_ule64 (dso, rela->r_offset + 8); - } - else - { - val = read_ube64 (dso, rela->r_offset); - gp = read_ube64 (dso, rela->r_offset + 8); - } - if (gp == dso->info[DT_PLTGOT]) - { - if (val >= start) - val += adjust; - if (gp >= start) - gp += adjust; - } - if (GELF_R_TYPE (rela->r_info) & 1) - { - write_le64 (dso, rela->r_offset, val); - write_le64 (dso, rela->r_offset + 8, gp); - } - else - { - write_le64 (dso, rela->r_offset, val); - write_le64 (dso, rela->r_offset + 8, gp); - } - } - return 0; -} - -static int -ia64_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: IA-64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -ia64_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_REL32MSB - || GELF_R_TYPE (rela->r_info) == R_IA64_NONE) - /* Fast path: nothing to do. */ - return 0; - dso = info->dso; - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_DIR32MSB) - { - /* Nothing to do. */ - } - else if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_PCREL32MSB) - { - value -= rela->r_offset & -16; - } - else if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_FPTR32MSB) - { - /* FIXME */ - } - else if ((GELF_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - { - GElf_Addr gp = info->resolveent->pltgot; - - if (GELF_R_TYPE (rela->r_info) & 1) - { - write_le64 (dso, rela->r_offset, value); - write_le64 (dso, rela->r_offset + 8, gp); - } - else - { - write_be64 (dso, rela->r_offset, value); - write_be64 (dso, rela->r_offset + 8, gp); - } - - return 0; - } - else - { - error (0, 0, "%s: Unknown ia64 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - - switch (GELF_R_TYPE (rela->r_info) & 3) - { - case 0: write_be32 (dso, rela->r_offset, value); break; - case 1: write_le32 (dso, rela->r_offset, value); break; - case 2: write_be64 (dso, rela->r_offset, value); break; - case 3: write_le64 (dso, rela->r_offset, value); break; - } - return 0; -} - -static int -ia64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - if ((GELF_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - { - GElf_Addr gp = 0; - int i; - - for (i = 0; i < info->ent->ndepends; ++i) - if (info->ent->depends[i]->base <= rela->r_addend - && info->ent->depends[i]->end > rela->r_addend) - { - gp = info->ent->depends[i]->pltgot; - break; - } - - if (i == info->ent->ndepends) - abort (); - - if (GELF_R_TYPE (rela->r_info) & 1) - { - buf_write_le64 (buf, rela->r_addend); - buf_write_le64 (buf + 8, gp); - } - else - { - buf_write_be64 (buf, rela->r_addend); - buf_write_be64 (buf + 8, gp); - } - return 0; - } - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_IA64_DIR32MSB: buf_write_be32 (buf, rela->r_addend); break; - case R_IA64_DIR32LSB: buf_write_le32 (buf, rela->r_addend); break; - case R_IA64_DIR64MSB: buf_write_be64 (buf, rela->r_addend); break; - case R_IA64_DIR64LSB: buf_write_le64 (buf, rela->r_addend); break; - default: - abort (); - } - return 0; -} - -static int -ia64_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: IA-64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -ia64_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_DIR32MSB) - { - /* Nothing to do. */ - } - else if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_PCREL32MSB) - { - value -= rela->r_offset & -16; - } - else if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_FPTR32MSB) - { - /* FIXME */ - } - else if ((GELF_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - { - GElf_Addr gp = info->resolveent->pltgot; - - if (GELF_R_TYPE (rela->r_info) & 1) - { - buf_write_le64 (buf, value); - buf_write_le64 (buf + 8, gp); - } - else - { - buf_write_be64 (buf, value); - buf_write_be64 (buf + 8, gp); - } - return 0; - } - else - return 1; - - switch (GELF_R_TYPE (rela->r_info) & 3) - { - case 0: buf_write_be32 (buf, value); break; - case 1: buf_write_le32 (buf, value); break; - case 2: buf_write_be64 (buf, value); break; - case 3: buf_write_le64 (buf, value); break; - } - return 0; -} - -static int -ia64_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: IA-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ia64_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - GElf_Rela *ret; - - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_REL32MSB - || GELF_R_TYPE (rela->r_info) == R_IA64_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - return 0; - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on IA-64 yet", - dso->filename); - return 1; - } - value = conflict_lookup_value (conflict); - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_DIR32MSB - || (GELF_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - { - ret->r_addend = value + rela->r_addend; - return 0; - } - else if ((GELF_R_TYPE (rela->r_info) & ~3) == R_IA64_PCREL32MSB) - { - ret->r_addend = value + rela->r_addend - (rela->r_offset & -16); - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info) - + R_IA64_DIR32MSB - R_IA64_PCREL32MSB); - return 0; - } - else if (GELF_R_TYPE (rela->r_info) == R_IA64_COPY) - { - error (0, 0, "R_IA64_COPY should not be present in shared libraries"); - return 1; - } - error (0, 0, "%s: Unknown ia64 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; -} - -static int -ia64_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: IA-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ia64_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static GElf_Addr -ia64_create_opd (struct prelink_info *info, int first, int last, int plt) -{ - Elf_Data *d; - Elf_Scn *scn; - Elf64_Rela *rela, *relaend; - DSO *dso = info->dso; - int sec; - - if (opd_init (info)) - return -1; - - if (plt) - info->ent->opd->plt_start = dso->shdr[dso->shdr[plt].sh_info].sh_addr; - else - info->ent->opd->plt_start = dso->shdr[dso->dynamic].sh_addr; - sec = first; - while (sec <= last) - { - d = NULL; - scn = dso->scn[sec++]; - while ((d = elf_getdata (scn, d)) != NULL) - { - rela = (Elf64_Rela *) d->d_buf; - relaend = rela + d->d_size / sizeof (Elf64_Rela); - for (; rela < relaend; rela++) - if ((ELF64_R_TYPE (rela->r_info) & ~3) == R_IA64_FPTR32MSB - && opd_add (info, ELF64_R_SYM (rela->r_info), - R_IA64_FPTR64LSB)) - return -1; - } - } - - sec = first; - while (sec) - { - d = NULL; - if (sec == plt) - break; - scn = dso->scn[sec++]; - if (sec == last + 1) - sec = plt; - while ((d = elf_getdata (scn, d)) != NULL) - { - rela = (Elf64_Rela *) d->d_buf; - relaend = rela + d->d_size / sizeof (Elf64_Rela); - for (; rela < relaend; rela++) - if ((ELF64_R_TYPE (rela->r_info) & ~1) == R_IA64_IPLTMSB) - opd_note_plt (info, ELF64_R_SYM (rela->r_info), R_IA64_IPLTLSB, - rela->r_offset); - } - } - - return opd_size (info, 16); -} - -static int -ia64_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int plt = -1, got = -1, i; - const char *name; - - /* Write address of .plt + 0x30 into .got[1]. - .plt + 0x30 is what .IA_64.pltoff[0] contains unless prelinking. */ - - dso = info->dso; - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS) - { - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name); - if (! strcmp (name, ".got")) - { - if (got != -1) - { - error (0, 0, "%s: More than one .got section", dso->filename); - return 1; - } - got = i; - } - else if (! strcmp (name, ".plt")) - { - if (plt != -1) - { - error (0, 0, "%s: More than one .plt section", dso->filename); - return 1; - } - plt = i; - } - } - - if (plt == -1) - return 0; - - if (got == -1) - { - error (0, 0, "%s: Has .plt section but not .got section", dso->filename); - return 1; - } - - write_le64 (dso, dso->shdr[got].sh_addr + 8, dso->shdr[plt].sh_addr + 0x30); - return 0; -} - -static int -ia64_reloc_size (int reloc_type) -{ - if ((reloc_type & ~1) == R_IA64_IPLTMSB) - return 16; - return (reloc_type & 2) ? 8 : 4; -} - -static int -ia64_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_IA64_IPLTLSB: - case R_IA64_IPLTMSB: - return RTYPE_CLASS_PLT; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(ia64) = { - .name = "IA-64", - .class = ELFCLASS64, - .machine = EM_IA_64, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_IA64_IPLTLSB, - .R_COPY = -1, - .R_RELATIVE = R_IA64_REL64LSB, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux-ia64.so.2", - .adjust_dyn = ia64_adjust_dyn, - .adjust_rel = ia64_adjust_rel, - .adjust_rela = ia64_adjust_rela, - .prelink_rel = ia64_prelink_rel, - .prelink_rela = ia64_prelink_rela, - .prelink_conflict_rel = ia64_prelink_conflict_rel, - .prelink_conflict_rela = ia64_prelink_conflict_rela, - .apply_conflict_rela = ia64_apply_conflict_rela, - .apply_rel = ia64_apply_rel, - .apply_rela = ia64_apply_rela, - .rel_to_rela = ia64_rel_to_rela, - .need_rel_to_rela = ia64_need_rel_to_rela, - .create_opd = ia64_create_opd, - .reloc_size = ia64_reloc_size, - .reloc_class = ia64_reloc_class, - .max_reloc_size = 16, - .arch_prelink = ia64_arch_prelink, - /* Although TASK_UNMAPPED_BASE is 0x2000000000000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x2000000010000000LL, - .mmap_end = 0x4000000000000000LL, - .max_page_size = 0x10000, - /* The kernel can be configured for 4K, 8K, 16K and 64K, - but most kernels have at least 8K. */ - .page_size = 0x02000 -}; diff --git a/trunk/src/arch-mips.c b/trunk/src/arch-mips.c deleted file mode 100644 index ccb1834..0000000 --- a/trunk/src/arch-mips.c +++ /dev/null @@ -1,1444 +0,0 @@ -/* Copyright (C) 2006, 2008 CodeSourcery. - Written by Richard Sandiford <richard@codesourcery.com>, 2006 - Updated by Maciej W. Rozycki <macro@codesourcery.com>, 2008. - - 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, 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. */ - -/* GENERAL NOTES - - The psABI defines R_MIPS_REL32 as A - EA + S, where the value of EA - depends on the symbol index. If the index is less than DT_MIPS_GOTSYM, - EA is the symbol's st_value "plus displacement". If the index is greater - than or equal to DT_MIPS_GOTSYM, EA is the original value of the - associated GOT entry. - - However, glibc's dynamic linker implements a different definition. - If the index is less than DT_MIPS_GOTSYM, the dynamic linker adds the - symbol's st_value and the base address to the addend. If the index - is greater than or equal to DT_MIPS_GOTSYM, the dynamic linker adds - the final symbol value to the addend. - - MIPS GOTs are divided into three parts: - - - Reserved entries (of which GNU objects have 2) - - Local entries - - Global entries - - DT_MIPS_LOCAL_GOTNO gives the total number of reserved and local - entries. The local entries all hold virtual addresses and the - dynamic linker will add the base address to each one. - - Unlike most other architectures, the MIPS ABI does not use - relocations to initialize the global GOT entries. Instead, global - GOT entry X is mapped to dynamic symbol DT_MIPS_GOTSYM + X, and there - are a total of DT_MIPS_SYMTABNO - DT_MIPS_GOTSYM global GOT entries. - - The interpretation of a global GOT entry depends on the symbol entry - and the initial GOT contents. The psABI lists the following cases: - - st_shndx st_type st_value initial GOT value - -------- ------- -------- ----------------- - A: SHN_UNDEF STT_FUNC 0 st_value (== 0) / QS - B: SHN_UNDEF STT_FUNC stub address st_value / QS - C: SHN_UNDEF all others 0 st_value (== 0) / QS - D: SHN_COMMON any alignment 0 / QS - E: all others STT_FUNC value st_value / stub address - F: all others all others value st_value - - (wording slightly modified from the psABI table). Here, QS denotes - Quickstart values. - - The dynamic linker treats each case as follows: - - - [A, B when not binding lazily, C, D, E when not binding lazily, F] - Resolve the symbol and store its value in the GOT. - - - [B when binding lazily] Set the GOT entry to the st_value plus - the base address. - - - [E when binding lazily] If the GOT entry is different from the st_value, - add the base addreess to the GOT entry. Otherwise resolve the symbol - and store its value in the GOT (as for A, C, etc). - - As the table shows, we can install Quickstart values for types A-D. - Installing Quickstart values for type F should be a no-op, because the - GOT should already hold the desired value. Installing Quickstart values - for type E would either be a no-op (if the GOT entry already contains - st_value) or would lose the address of the lazy binding stub. */ - -#include <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" -#include "layout.h" -#include "reloc-info.h" - -/* The thread pointer points 0x7000 past the first static TLS block. */ -#define TLS_TP_OFFSET 0x7000 - -/* Dynamic thread vector pointers point 0x8000 past the start of each - TLS block. */ -#define TLS_DTV_OFFSET 0x8000 - -/* The number of reserved entries at the beginning of the GOT. - The dynamic linker points entry 0 to the resolver function - and entry 1 to the link_map. */ -#define RESERVED_GOTNO 2 - -/* A structure for iterating over local GOT entries. */ -struct mips_local_got_iterator { - /* The DSO containing the GOT. */ - DSO *dso; - - /* The size of a GOT entry. */ - GElf_Word entry_size; - - /* The index of the current GOT entry. */ - GElf_Word got_index; - - /* A pointer to the current GOT entry. */ - unsigned char *got_entry; - - /* True if we failed to read an entry correctly. */ - int failed; - - /* Used internally to obtain GOT_ENTRY. */ - struct data_iterator got_iterator; -}; - -/* Read native-endian address-type data. */ - -static uint64_t -mips_buf_read_addr (DSO *dso, unsigned char *data) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64) - return buf_read_une64 (dso, data); - else - return buf_read_une32 (dso, data); -} - -/* Write native-endian address-type data. */ - -static void -mips_buf_write_addr (DSO *dso, unsigned char *data, uint64_t val) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64) - buf_write_ne64 (dso, data, val); - else - buf_write_ne32 (dso, data, val); -} - -/* Set up LGI to iterate over DSO's local GOT. The caller should use - mips_get_local_got_entry to read the first entry. */ - -static inline void -mips_init_local_got_iterator (struct mips_local_got_iterator *lgi, DSO *dso) -{ - lgi->dso = dso; - lgi->entry_size = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - lgi->got_index = RESERVED_GOTNO - 1; - lgi->failed = 0; - init_data_iterator (&lgi->got_iterator, dso, - dso->info[DT_PLTGOT] - + (lgi->got_index + 1) * lgi->entry_size); -} - -/* Return true if LGI has not reached the end of the GOT and if the next - entry can be accessed. When returning true, use LGI's fields to - describe the next entry. */ - -static inline int -mips_get_local_got_entry (struct mips_local_got_iterator *lgi) -{ - lgi->got_index++; - if (lgi->got_index >= lgi->dso->info_DT_MIPS_LOCAL_GOTNO) - return 0; - - lgi->got_entry = get_data_from_iterator (&lgi->got_iterator, - lgi->entry_size); - if (lgi->got_entry == NULL) - { - error (0, 0, "%s: Malformed local GOT\n", lgi->dso->filename); - lgi->failed = 1; - return 0; - } - - return 1; -} - -/* A structure for iterating over global GOT entries. */ -struct mips_global_got_iterator { - /* The DSO containing the GOT. */ - DSO *dso; - - /* The size of a GOT entry. */ - GElf_Word entry_size; - - /* The virtual address of the current GOT entry. */ - GElf_Addr got_addr; - - /* The index of the associated entry in the dynamic symbol table. */ - GElf_Word sym_index; - - /* A pointer to the current GOT entry. */ - unsigned char *got_entry; - - /* The symbol associated with the current GOT entry. */ - GElf_Sym sym; - - /* True if we failed to read an entry correctly. */ - int failed; - - /* Used internally to obtain GOT_ENTRY and SYM. */ - struct data_iterator got_iterator; - struct data_iterator sym_iterator; -}; - -/* Set up GGI to iterate over DSO's global GOT. The caller should use - mips_get_global_got_entry to read the first entry. */ - -static inline void -mips_init_global_got_iterator (struct mips_global_got_iterator *ggi, DSO *dso) -{ - GElf_Word sym_size; - - ggi->dso = dso; - ggi->entry_size = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - ggi->got_addr = (dso->info[DT_PLTGOT] - + (dso->info_DT_MIPS_LOCAL_GOTNO - 1) * ggi->entry_size); - ggi->sym_index = dso->info_DT_MIPS_GOTSYM - 1; - ggi->failed = 0; - - sym_size = gelf_fsize (dso->elf, ELF_T_SYM, 1, EV_CURRENT); - init_data_iterator (&ggi->got_iterator, dso, - ggi->got_addr + ggi->entry_size); - init_data_iterator (&ggi->sym_iterator, dso, - dso->info[DT_SYMTAB] + (ggi->sym_index + 1) * sym_size); -} - -/* Return true if GGI has not reached the end of the GOT and if the next - entry can be accessed. When returning true, use GGI's fields to - describe the next entry. */ - -static inline int -mips_get_global_got_entry (struct mips_global_got_iterator *ggi) -{ - ggi->sym_index++; - ggi->got_addr += ggi->entry_size; - if (ggi->sym_index >= ggi->dso->info_DT_MIPS_SYMTABNO) - return 0; - - ggi->got_entry = get_data_from_iterator (&ggi->got_iterator, - ggi->entry_size); - if (ggi->got_entry == NULL - || !get_sym_from_iterator (&ggi->sym_iterator, &ggi->sym)) - { - error (0, 0, "%s: Malformed global GOT\n", ggi->dso->filename); - ggi->failed = 1; - return 0; - } - - return 1; -} - -static int -mips_arch_adjust (DSO *dso, GElf_Addr start, GElf_Addr adjust) -{ - struct mips_local_got_iterator lgi; - struct mips_global_got_iterator ggi; - GElf_Addr value; - - if (dso->info[DT_PLTGOT] == 0) - return 0; - - /* Adjust every local GOT entry by ADJUST. Every adjustment moves - the code and data, so we do not need to check START here. */ - mips_init_local_got_iterator (&lgi, dso); - while (mips_get_local_got_entry (&lgi)) - { - value = mips_buf_read_addr (dso, lgi.got_entry); - mips_buf_write_addr (dso, lgi.got_entry, value + adjust); - } - - /* Adjust every global GOT entry. Referring to the table above: - - For [A, B, C]: Adjust the GOT entry if it contains st_value - and if the symbol's value will be adjusted. - - For [D]: Do nothing. SHN_COMMON entries never need adjusting. - - For [E, F]: Adjust the GOT entry if it does not contain st_value - -- in other words, if it is a type E entry that points to a lazy - binding stub -- or if the symbol's value will also be adjusted. */ - mips_init_global_got_iterator (&ggi, dso); - while (mips_get_global_got_entry (&ggi)) - { - value = mips_buf_read_addr (dso, ggi.got_entry); - if (ggi.sym.st_shndx != SHN_COMMON - && value >= start - && (value == ggi.sym.st_value - ? adjust_symbol_p (dso, &ggi.sym) - : ggi.sym.st_shndx != SHN_UNDEF)) - mips_buf_write_addr (dso, ggi.got_entry, value + adjust); - } - - return lgi.failed || ggi.failed; -} - -static int -mips_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - switch (dyn->d_tag) - { - case DT_MIPS_TIME_STAMP: - case DT_MIPS_ICHECKSUM: - case DT_MIPS_IVERSION: - case DT_MIPS_CONFLICT: - case DT_MIPS_CONFLICTNO: - case DT_MIPS_LIBLIST: - case DT_MIPS_LIBLISTNO: - error (0, 0, "%s: File contains QuickStart information", dso->filename); - return 1; - - case DT_MIPS_BASE_ADDRESS: - case DT_MIPS_RLD_MAP: - case DT_MIPS_OPTIONS: - if (dyn->d_un.d_ptr >= start) - dyn->d_un.d_ptr += adjust; - return 1; - - case DT_MIPS_LOCAL_GOTNO: - case DT_MIPS_UNREFEXTNO: - case DT_MIPS_SYMTABNO: - case DT_MIPS_HIPAGENO: - case DT_MIPS_GOTSYM: - /* We don't change the layout of the GOT or symbol table. */ - return 1; - - case DT_MIPS_RLD_VERSION: - case DT_MIPS_FLAGS: - /* We don't change these properties. */ - return 1; - } - return 0; -} - -/* Read the addend for a relocation in DSO. If RELA is nonnull, - use its r_addend, otherwise read a 32-bit in-place addend from - address R_OFFSET. */ - -static inline uint32_t -mips_read_32bit_addend (DSO *dso, GElf_Addr r_offset, GElf_Rela *rela) -{ - return rela ? rela->r_addend : read_une32 (dso, r_offset); -} - -/* Like mips_read_32bit_addend, but change the addend to VALUE. */ - -static inline void -mips_write_32bit_addend (DSO *dso, GElf_Addr r_offset, GElf_Rela *rela, - uint32_t value) -{ - if (rela) - rela->r_addend = (int32_t) value; - else - write_ne32 (dso, r_offset, value); -} - -/* Like mips_read_32bit_addend, but 64-bit. */ - -static inline uint64_t -mips_read_64bit_addend (DSO *dso, GElf_Addr r_offset, GElf_Rela *rela) -{ - return rela ? rela->r_addend : read_une64 (dso, r_offset); -} - -/* Like mips_read_64bit_addend, but change the addend to VALUE. */ - -static inline void -mips_write_64bit_addend (DSO *dso, GElf_Addr r_offset, GElf_Rela *rela, - uint64_t value) -{ - if (rela) - rela->r_addend = value; - else - write_ne64 (dso, r_offset, value); -} - -/* There is a relocation of type R_INFO against address R_OFFSET in DSO. - Adjust it so that virtual addresses >= START are increased by ADJUST - If the relocation is in a RELA section, RELA points to the relocation, - otherwise it is null. */ - -static int -mips_adjust_reloc (DSO *dso, GElf_Addr r_offset, GElf_Xword r_info, - GElf_Addr start, GElf_Addr adjust, GElf_Rela *rela) -{ - GElf_Addr value; - GElf_Word r_sym; - - if (reloc_r_type (dso, r_info) == R_MIPS_REL32) - { - r_sym = reloc_r_sym (dso, r_info); - if (r_sym < dso->info_DT_MIPS_GOTSYM) - { - /* glibc's dynamic linker adds the symbol's st_value and the - base address to the addend. It therefore treats all symbols - as being relative, even if they would normally be considered - absolute. For example, the special null symbol should always - have the value zero, even when the base address is nonzero, - but R_MIPS_REL32 relocations against the null symbol must - nevertheles be adjusted as if that symbol were relative. - The same would apply to SHN_ABS symbols too. - - Thus the result of the relocation calculation must always - be adjusted by ADJUST. (We do not need to check START because - every adjustment requested by the caller will affect all - legitimate local relocation values.) This means that we - should add ADJUST to the addend if and only if the symbol's - value is not being adjusted. - - In general, we can only check whether a symbol's value is - being adjusted by reading its entry in the dynamic symbol - table and then querying adjust_symbol_p. However, this - generality is fortunately not needed. Modern versions - of binutils will never generate R_MIPS_REL32 relocations - against symbols in the range [1, DT_MIPS_GOTSYM), so we - only need to handle relocations against the null symbol. */ - if (r_sym != 0) - { - error (0, 0, "%s: The prelinker does not support R_MIPS_REL32" - " relocs against local symbols", dso->filename); - return 1; - } - if (reloc_r_type2 (dso, r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, r_info) == RSS_UNDEF); - value = mips_read_64bit_addend (dso, r_offset, rela); - mips_write_64bit_addend (dso, r_offset, rela, value + adjust); - } - else - { - value = mips_read_32bit_addend (dso, r_offset, rela); - mips_write_32bit_addend (dso, r_offset, rela, value + adjust); - } - } - } - return 0; -} - -static int -mips_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, GElf_Addr adjust) -{ - return mips_adjust_reloc (dso, rel->r_offset, rel->r_info, - start, adjust, NULL); -} - -static int -mips_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, GElf_Addr adjust) -{ - return mips_adjust_reloc (dso, rela->r_offset, rela->r_info, - start, adjust, rela); -} - -/* Calculate relocation RELA as A + VALUE and store the result in DSO. */ - -static void -mips_prelink_32bit_reloc (DSO *dso, GElf_Rela *rela, GElf_Addr value) -{ - assert (rela != NULL); - write_ne32 (dso, rela->r_offset, value + rela->r_addend); -} - -static void -mips_prelink_64bit_reloc (DSO *dso, GElf_Rela *rela, GElf_Addr value) -{ - assert (rela != NULL); - write_ne64 (dso, rela->r_offset, value + rela->r_addend); -} - -/* There is a relocation of type R_INFO against address R_OFFSET in DSO. - Prelink the relocation field, using INFO to look up symbol values. - If the relocation is in a RELA section, RELA points to the relocation, - otherwise it is null. */ - -static int -mips_prelink_reloc (struct prelink_info *info, GElf_Addr r_offset, - GElf_Xword r_info, GElf_Rela *rela) -{ - DSO *dso; - GElf_Addr value; - GElf_Word r_sym; - int r_type; - - dso = info->dso; - r_sym = reloc_r_sym (dso, r_info); - r_type = reloc_r_type (dso, r_info); - switch (r_type) - { - case R_MIPS_NONE: - break; - - case R_MIPS_REL32: - /* An in-place R_MIPS_REL32 relocation against symbol 0 needs no - adjustment. */ - if (rela != NULL || r_sym != 0) - { - value = info->resolve (info, r_sym, r_type); - if (reloc_r_type2 (dso, r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, r_info) == RSS_UNDEF); - mips_prelink_64bit_reloc (dso, rela, value); - } - else - mips_prelink_32bit_reloc (dso, rela, value); - } - break; - - case R_MIPS_GLOB_DAT: - if (reloc_r_type2 (dso, r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, r_info) == RSS_UNDEF); - write_ne64 (dso, r_offset, info->resolve (info, r_sym, r_type)); - } - else - write_ne32 (dso, r_offset, info->resolve (info, r_sym, r_type)); - break; - - case R_MIPS_JUMP_SLOT: - write_ne32 (dso, r_offset, info->resolve (info, r_sym, r_type)); - break; - - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - /* Relocations in a shared library will be resolved using a conflict. - We need not change the relocation field here. */ - if (dso->ehdr.e_type == ET_EXEC) - { - struct prelink_tls *tls = info->symbols[r_sym].u.tls; - - if (tls == NULL) - break; - value = tls->modid; - if (r_type == R_MIPS_TLS_DTPMOD32) - mips_prelink_32bit_reloc (dso, rela, value); - else - mips_prelink_64bit_reloc (dso, rela, value); - } - break; - - case R_MIPS_TLS_DTPREL32: - case R_MIPS_TLS_DTPREL64: - value = info->resolve (info, r_sym, r_type); - if (r_type == R_MIPS_TLS_DTPREL32) - mips_prelink_32bit_reloc (dso, rela, value - TLS_DTV_OFFSET); - else - mips_prelink_64bit_reloc (dso, rela, value - TLS_DTV_OFFSET); - break; - - case R_MIPS_TLS_TPREL32: - case R_MIPS_TLS_TPREL64: - /* Relocations in a shared library will be resolved using a conflict. - We need not change the relocation field here. */ - if (dso->ehdr.e_type == ET_EXEC) - { - value = info->resolve (info, r_sym, r_type); - value += info->resolvetls->offset - TLS_TP_OFFSET; - if (r_type == R_MIPS_TLS_TPREL32) - mips_prelink_32bit_reloc (dso, rela, value); - else - mips_prelink_64bit_reloc (dso, rela, value); - } - break; - - case R_MIPS_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_MIPS_COPY reloc in shared library?", dso->filename); - return 1; - - default: - error (0, 0, "%s: Unknown MIPS relocation type %d", - dso->filename, (int) reloc_r_type (dso, r_info)); - return 1; - } - return 0; -} - -static int -mips_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - GElf_Xword r_info; - GElf_Word r_sym; - int r_type; - DSO *dso; - - /* Convert R_MIPS_REL32 relocations against global symbols into - R_MIPS_GLOB_DAT if the addend is zero. */ - dso = info->dso; - r_sym = reloc_r_sym (dso, rel->r_info); - r_type = reloc_r_type (dso, rel->r_info); - if (r_type == R_MIPS_REL32 && r_sym >= dso->info_DT_MIPS_GOTSYM) - { - r_type = R_MIPS_GLOB_DAT; - r_info = reloc_r_info_ext (dso, r_sym, reloc_r_ssym (dso, rel->r_info), - r_type, - reloc_r_type2 (dso, rel->r_info), - reloc_r_type3 (dso, rel->r_info)); - if (reloc_r_type2 (dso, rel->r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, rel->r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, rel->r_info) == RSS_UNDEF); - if (read_une64 (dso, rel->r_offset) == 0) - { - rel->r_info = r_info; - write_ne64 (dso, rel->r_offset, - info->resolve (info, r_sym, r_type)); - return 2; - } - } - else if (read_une32 (dso, rel->r_offset) == 0) - { - rel->r_info = r_info; - write_ne32 (dso, rel->r_offset, info->resolve (info, r_sym, r_type)); - return 2; - } - } - return mips_prelink_reloc (info, rel->r_offset, rel->r_info, NULL); -} - -static int -mips_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - return mips_prelink_reloc (info, rela->r_offset, rela->r_info, rela); -} - -/* CONFLICT is a conflict returned by prelink_conflict for a symbol - belonging to DSO. Set *TLS_OUT to the associated TLS information. - Return 1 on failure. */ - -static int -mips_get_tls (DSO *dso, struct prelink_conflict *conflict, - struct prelink_tls **tls_out) -{ - if (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL) - { - error (0, 0, "%s: R_MIPS_TLS not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - - *tls_out = conflict->lookup.tls; - return 0; -} - -/* There is a relocation of type R_INFO against address R_OFFSET in DSO. - See if the relocation field must be adjusted by a conflict when DSO - is used in the context described by INFO. Add a conflict entry if so. - If the relocation is in a RELA section, RELA points to the relocation, - otherwise it is null. */ - -static int -mips_prelink_conflict_reloc (DSO *dso, struct prelink_info *info, - GElf_Addr r_offset, GElf_Xword r_info, - GElf_Rela *rela) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls = NULL; - GElf_Rela *entry; - GElf_Word r_sym; - int r_type; - - if (info->dso == dso) - return 0; - - r_sym = reloc_r_sym (dso, r_info); - r_type = reloc_r_type (dso, r_info); - conflict = prelink_conflict (info, r_sym, r_type); - if (conflict == NULL) - { - switch (r_type) - { - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - case R_MIPS_TLS_TPREL32: - case R_MIPS_TLS_TPREL64: - tls = info->curtls; - if (tls == NULL) - return 0; - /* A relocation against symbol 0. A shared library cannot - know what the final module IDs or TP-relative offsets are, - so the executable must always have a conflict for them. */ - value = 0; - break; - default: - return 0; - } - } - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on MIPS yet", - dso->filename); - return 1; - } - else - { - /* DTPREL32/DTPREL64 relocations just involve the symbol value; - no other TLS information is needed. Ignore conflicts created - from a lookup of type RTYPE_CLASS_TLS if no real conflict - exists. */ - if ((r_type == R_MIPS_TLS_DTPREL32 || r_type == R_MIPS_TLS_DTPREL64) - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - /* VALUE now contains the final symbol value. Change it to the - value we want to store at R_OFFSET. */ - switch (r_type) - { - case R_MIPS_REL32: - if (reloc_r_type2 (dso, r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, r_info) == RSS_UNDEF); - value += mips_read_64bit_addend (dso, r_offset, rela); - } - else - value += mips_read_32bit_addend (dso, r_offset, rela); - break; - - case R_MIPS_GLOB_DAT: - break; - - case R_MIPS_COPY: - error (0, 0, "R_MIPS_COPY should not be present in shared libraries"); - return 1; - - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - if (conflict != NULL && mips_get_tls (dso, conflict, &tls) == 1) - return 1; - value = tls->modid; - break; - - case R_MIPS_TLS_DTPREL32: - value += mips_read_32bit_addend (dso, r_offset, rela) - TLS_DTV_OFFSET; - break; - case R_MIPS_TLS_DTPREL64: - value += mips_read_64bit_addend (dso, r_offset, rela) - TLS_DTV_OFFSET; - break; - - case R_MIPS_TLS_TPREL32: - case R_MIPS_TLS_TPREL64: - if (conflict != NULL && mips_get_tls (dso, conflict, &tls) == 1) - return 1; - if (r_type == R_MIPS_TLS_TPREL32) - value += mips_read_32bit_addend (dso, r_offset, rela); - else - value += mips_read_64bit_addend (dso, r_offset, rela); - value += tls->offset - TLS_TP_OFFSET; - break; - - default: - error (0, 0, "%s: Unknown MIPS relocation type %d", dso->filename, - r_type); - return 1; - } - /* Create and initialize a conflict entry. */ - entry = prelink_conflict_add_rela (info); - if (entry == NULL) - return 1; - entry->r_offset = r_offset; - entry->r_info = reloc_r_info_ext (dso, 0, RSS_UNDEF, - R_MIPS_REL32, R_MIPS_64, R_MIPS_NONE); - if (reloc_r_type2 (dso, entry->r_info) == R_MIPS_64) - entry->r_addend = value; - else - entry->r_addend = (int32_t) value; - return 0; -} - -static int -mips_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - return mips_prelink_conflict_reloc (dso, info, rel->r_offset, - rel->r_info, NULL); -} - -static int -mips_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - return mips_prelink_conflict_reloc (dso, info, rela->r_offset, - rela->r_info, rela); -} - -static int -mips_arch_prelink_conflict (DSO *dso, struct prelink_info *info) -{ - struct mips_global_got_iterator ggi; - GElf_Addr value; - struct prelink_conflict *conflict; - GElf_Rela *entry; - - if (info->dso == dso || dso->info[DT_PLTGOT] == 0) - return 0; - - /* Add a conflict for every global GOT entry that does not hold the - right value, either because of a conflict, or because the DSO has - a lazy binding stub for a symbol that it also defines. */ - mips_init_global_got_iterator (&ggi, dso); - while (mips_get_global_got_entry (&ggi)) - { - conflict = prelink_conflict (info, ggi.sym_index, R_MIPS_REL32); - if (conflict != NULL) - value = conflict_lookup_value (conflict); - else if (ggi.sym.st_shndx != SHN_UNDEF - && ggi.sym.st_shndx != SHN_COMMON) - value = ggi.sym.st_value; - else - continue; - if (mips_buf_read_addr (dso, ggi.got_entry) != value) - { - entry = prelink_conflict_add_rela (info); - if (entry == NULL) - return 1; - entry->r_offset = ggi.got_addr; - entry->r_info = reloc_r_info_ext (dso, 0, RSS_UNDEF, - R_MIPS_REL32, R_MIPS_64, - R_MIPS_NONE); - if (reloc_r_type2 (dso, entry->r_info) == R_MIPS_64) - entry->r_addend = value; - else - entry->r_addend = (int32_t) value; - } - } - - return ggi.failed; -} - -static int -mips_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - DSO *dso; - - dso = info->dso; - switch (reloc_r_type (dso, rela->r_info)) - { - case R_MIPS_REL32: - if (reloc_r_type2 (dso, rela->r_info) == R_MIPS_64) - { - assert (reloc_r_ssym (dso, rela->r_info) == RSS_UNDEF); - assert (reloc_r_type3 (dso, rela->r_info) == R_MIPS_NONE); - buf_write_ne64 (info->dso, buf, rela->r_addend); - } - else - buf_write_ne32 (info->dso, buf, rela->r_addend); - break; - - case R_MIPS_JUMP_SLOT: - buf_write_ne32 (info->dso, buf, rela->r_addend); - break; - - default: - abort (); - } - return 0; -} - -/* BUF points to a 32-bit field in DSO that is subject to relocation. - If the relocation is in a RELA section, RELA points to the relocation, - otherwise it is null. Add the addend to ADJUSTMENT and install the - result. */ - -static inline void -mips_apply_adjustment (DSO *dso, GElf_Rela *rela, char *buf, - GElf_Addr adjustment) -{ - if (rela) - adjustment += rela->r_addend; - else - adjustment += mips_buf_read_addr (dso, buf); - mips_buf_write_addr (dso, buf, adjustment); -} - -static int -mips_apply_reloc (struct prelink_info *info, GElf_Xword r_info, - GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - GElf_Word r_sym; - int r_type; - DSO *dso; - - dso = info->dso; - r_sym = reloc_r_sym (dso, r_info); - r_type = reloc_r_type (dso, r_info); - value = info->resolve (info, r_sym, r_type); - switch (r_type) - { - case R_MIPS_NONE: - break; - - case R_MIPS_JUMP_SLOT: - buf_write_ne32 (info->dso, buf, value); - break; - - case R_MIPS_COPY: - abort (); - - case R_MIPS_REL32: - if (reloc_r_type2 (dso, r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, r_info) == RSS_UNDEF); - } - mips_apply_adjustment (dso, rela, buf, value); - break; - - default: - return 1; - } - return 0; -} - -static int -mips_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - return mips_apply_reloc (info, rel->r_info, NULL, buf); -} - -static int -mips_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - return mips_apply_reloc (info, rela->r_info, rela, buf); -} - -static int -mips_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - GElf_Word r_sym; - int r_type; - - r_sym = reloc_r_sym (dso, rel->r_info); - r_type = reloc_r_type (dso, rel->r_info); - rela->r_offset = rel->r_offset; - rela->r_info = rel->r_info; - switch (r_type) - { - case R_MIPS_REL32: - /* This relocation has an in-place addend. */ - if (reloc_r_type2 (dso, rel->r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, rel->r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, rel->r_info) == RSS_UNDEF); - rela->r_addend = read_une64 (dso, rel->r_offset); - } - else - rela->r_addend = (int32_t) read_une32 (dso, rel->r_offset); - break; - - case R_MIPS_TLS_DTPREL32: - case R_MIPS_TLS_TPREL32: - /* These relocations have an in-place addend. */ - rela->r_addend = (int32_t) read_une32 (dso, rel->r_offset); - break; - case R_MIPS_TLS_DTPREL64: - case R_MIPS_TLS_TPREL64: - /* These relocations have an in-place addend. */ - rela->r_addend = read_une64 (dso, rel->r_offset); - break; - - case R_MIPS_NONE: - case R_MIPS_COPY: - case R_MIPS_GLOB_DAT: - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - /* These relocations have no addend. */ - rela->r_addend = 0; - break; - - default: - error (0, 0, "%s: Unknown MIPS relocation type %d", dso->filename, - r_type); - return 1; - } - return 0; -} - -static int -mips_rela_to_rel (DSO *dso, GElf_Rela *rela, GElf_Rel *rel) -{ - GElf_Sxword r_addend; - GElf_Word r_sym; - int r_type; - - r_sym = reloc_r_sym (dso, rela->r_info); - r_type = reloc_r_type (dso, rela->r_info); - r_addend = rela->r_addend; - rel->r_offset = rela->r_offset; - rel->r_info = rela->r_info; - switch (r_type) - { - case R_MIPS_NONE: - case R_MIPS_COPY: - break; - - case R_MIPS_GLOB_DAT: - /* This relocation has no addend. */ - r_addend = 0; - /* FALLTHROUGH */ - case R_MIPS_REL32: - /* This relocation has an in-place addend. */ - if (reloc_r_type2 (dso, rel->r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, rel->r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, rel->r_info) == RSS_UNDEF); - write_ne64 (dso, rela->r_offset, rela->r_addend); - } - else - write_ne32 (dso, rela->r_offset, rela->r_addend); - break; - - case R_MIPS_TLS_DTPMOD32: - /* This relocation has no addend. */ - r_addend = 0; - /* FALLTHROUGH */ - case R_MIPS_TLS_DTPREL32: - case R_MIPS_TLS_TPREL32: - /* These relocations have an in-place addend. */ - write_ne32 (dso, rela->r_offset, rela->r_addend); - break; - case R_MIPS_TLS_DTPMOD64: - /* This relocation has no addend. */ - r_addend = 0; - /* FALLTHROUGH */ - case R_MIPS_TLS_DTPREL64: - case R_MIPS_TLS_TPREL64: - /* These relocations have an in-place addend. */ - write_ne64 (dso, rela->r_offset, rela->r_addend); - break; - break; - - default: - error (0, 0, "%s: Unknown MIPS relocation type %d", dso->filename, - r_type); - return 1; - } - return 0; -} - -static int -mips_need_rel_to_rela (DSO *dso, int first, int last) -{ - Elf_Data *data; - Elf_Scn *scn; - GElf_Shdr shdr; - GElf_Rel rel; - GElf_Word r_sym; - int r_type; - int count; - int i; - int n; - - for (n = first; n <= last; n++) - { - data = NULL; - scn = dso->scn[n]; - gelfx_getshdr (dso->elf, scn, &shdr); - while ((data = elf_getdata (scn, data)) != NULL) - { - count = data->d_size / shdr.sh_entsize; - for (i = 0; i < count; i++) - { - gelfx_getrel (dso->elf, data, i, &rel); - r_type = reloc_r_type (dso, rel.r_info); - r_sym = reloc_r_sym (dso, rel.r_info); - switch (r_type) - { - case R_MIPS_NONE: - case R_MIPS_COPY: - case R_MIPS_JUMP_SLOT: - break; - - case R_MIPS_REL32: - /* The SVR4 definition was designed to allow exactly the - sort of prelinking we want to do here, in combination - with Quickstart. Unfortunately, glibc's definition - makes it impossible for relocations against anything - other than the null symbol. We get around this for - zero addends by using a R_MIPS_GLOB_DAT relocation - instead, where R_MIPS_GLOB_DAT is a GNU extension - added specifically for this purpose. */ - if (r_sym != 0) - { - if (r_sym < dso->info_DT_MIPS_GOTSYM) - return 1; - if (reloc_r_type2 (dso, rel.r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, rel.r_info) - == R_MIPS_NONE); - assert (reloc_r_ssym (dso, rel.r_info) - == RSS_UNDEF); - if (read_une64 (dso, rel.r_offset) != 0) - return 1; - } - else if (read_une32 (dso, rel.r_offset) != 0) - return 1; - } - break; - - case R_MIPS_GLOB_DAT: - /* This relocation has no addend. */ - break; - - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - /* The relocation will be resolved using a conflict. */ - break; - - case R_MIPS_TLS_DTPREL32: - case R_MIPS_TLS_DTPREL64: - /* We can prelink these fields, and the addend is relative - to the symbol value. A RELA entry is needed. */ - return 1; - - case R_MIPS_TLS_TPREL32: - case R_MIPS_TLS_TPREL64: - /* Relocations in shared libraries will be resolved by a - conflict. Relocations in executables will not, and the - addend is relative to the symbol value. */ - if (dso->ehdr.e_type == ET_EXEC) - return 1; - break; - - default: - error (0, 0, "%s: Unknown MIPS relocation type %d", - dso->filename, r_type); - return 1; - } - } - } - } - return 0; -} - -static int -mips_reloc_size (int reloc_type) -{ - return 4; -} - -static int -mips_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_MIPS_COPY: - return RTYPE_CLASS_COPY; - case R_MIPS_JUMP_SLOT: - return RTYPE_CLASS_PLT; - case R_MIPS_TLS_DTPMOD32: - case R_MIPS_TLS_DTPMOD64: - case R_MIPS_TLS_DTPREL32: - case R_MIPS_TLS_DTPREL64: - case R_MIPS_TLS_TPREL32: - case R_MIPS_TLS_TPREL64: - return RTYPE_CLASS_TLS; - default: - return RTYPE_CLASS_VALID; - } -} - -static int -mips_arch_prelink (struct prelink_info *info) -{ - struct mips_global_got_iterator ggi; - DSO *dso; - GElf_Addr value; - int i; - - dso = info->dso; - - if (dso->info_DT_MIPS_PLTGOT) - { - /* Write address of .plt into gotplt[1]. This is in each - normal gotplt entry unless prelinking. */ - int sec = addr_to_sec (dso, dso->info_DT_MIPS_PLTGOT); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr; - write_ne32 (dso, dso->info_DT_MIPS_PLTGOT + 4, data); - } - - if (dso->info[DT_PLTGOT] == 0) - return 0; - - /* Install Quickstart values for all global GOT entries of type A-D - in the table above. */ - mips_init_global_got_iterator (&ggi, dso); - while (mips_get_global_got_entry (&ggi)) - { - value = info->resolve (info, ggi.sym_index, R_MIPS_REL32); - if (ggi.sym.st_shndx == SHN_UNDEF - || ggi.sym.st_shndx == SHN_COMMON) - mips_buf_write_addr (dso, ggi.got_entry, value); - else - { - /* Type E and F in the table above. We cannot install Quickstart - values for type E, but we should never need to in executables, - because an executable should not use lazy binding stubs for - symbols it defines itself. Although we could in theory just - discard any such stub address, it goes against the principle - that prelinking should be reversible. - - When type E entries occur in shared libraries, we can fix - them up using conflicts. - - Type F entries should never need a Quickstart value -- the - current value should already be correct. However, the conflict - code will cope correctly with malformed type F entries in - shared libraries, so we only complain about executables here. */ - if (dso->ehdr.e_type == ET_EXEC - && value != mips_buf_read_addr (dso, ggi.got_entry)) - { - error (0, 0, "%s: The global GOT entries for defined symbols" - " do not match their st_values\n", dso->filename); - return 1; - } - } - } - return ggi.failed; -} - -static int -mips_arch_undo_prelink (DSO *dso) -{ - struct mips_global_got_iterator ggi; - int i; - - if (dso->info_DT_MIPS_PLTGOT) - { - /* Clear gotplt[1] if it contains the address of .plt. */ - int sec = addr_to_sec (dso, dso->info_DT_MIPS_PLTGOT); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_une32 (dso, dso->info_DT_MIPS_PLTGOT + 4); - if (data == dso->shdr[i].sh_addr) - write_ne32 (dso, dso->info_DT_MIPS_PLTGOT + 4, 0); - } - - if (dso->info[DT_PLTGOT] == 0) - return 0; - - mips_init_global_got_iterator (&ggi, dso); - while (mips_get_global_got_entry (&ggi)) - if (ggi.sym.st_shndx == SHN_UNDEF) - /* Types A-C in the table above. */ - mips_buf_write_addr (dso, ggi.got_entry, ggi.sym.st_value); - else if (ggi.sym.st_shndx == SHN_COMMON) - /* Type D in the table above. */ - mips_buf_write_addr (dso, ggi.got_entry, 0); - return ggi.failed; -} - -static int -mips_undo_prelink_rel (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr) -{ - int sec; - const char *name; - GElf_Word r_sym; - int r_type; - - /* Convert R_MIPS_GLOB_DAT relocations back into R_MIPS_REL32 - relocations. Ideally we'd have some mechanism for recording - these changes in the undo section, but in the absence of that, - it's better to assume that the original relocation was - R_MIPS_REL32; R_MIPS_GLOB_DAT was added specifically for the - prelinker and shouldn't be used in non-prelinked binaries. */ - r_sym = reloc_r_sym (dso, rel->r_info); - r_type = reloc_r_type (dso, rel->r_info); - if (r_type == R_MIPS_GLOB_DAT) - { - if (reloc_r_type2 (dso, rel->r_info) == R_MIPS_64) - { - assert (reloc_r_type3 (dso, rel->r_info) == R_MIPS_NONE); - assert (reloc_r_ssym (dso, rel->r_info) == RSS_UNDEF); - write_ne64 (dso, rel->r_offset, 0); - } - else - write_ne32 (dso, rel->r_offset, 0); - rel->r_info = reloc_r_info_ext (dso, - r_sym, reloc_r_ssym (dso, rel->r_info), - R_MIPS_REL32, - reloc_r_type2 (dso, rel->r_info), - reloc_r_type3 (dso, rel->r_info)); - return 2; - } - else if (r_type == R_MIPS_JUMP_SLOT) - { - sec = addr_to_sec (dso, rel->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || strcmp (name, ".got.plt")) - { - error (0, 0, - "%s: R_MIPS_JUMP_SLOT not pointing into .got.plt section", - dso->filename); - return 1; - } - else - { - Elf32_Addr data = read_une32 (dso, dso->shdr[sec].sh_addr + 4); - - assert (rel->r_offset >= dso->shdr[sec].sh_addr + 8); - assert (((rel->r_offset - dso->shdr[sec].sh_addr) & 3) == 0); - write_ne32 (dso, rel->r_offset, data); - } - } - - return 0; -} - -PL_ARCH(mips) = { - .name = "MIPS", - .class = ELFCLASS32, - .machine = EM_MIPS, - .max_reloc_size = 4, - .dynamic_linker = "/lib/ld.so.1", - .dynamic_linker_alt = "/lib32/ld.so.1", - .R_COPY = R_MIPS_COPY, - .R_JMP_SLOT = R_MIPS_JUMP_SLOT, - /* R_MIPS_REL32 relocations against symbol 0 do act as relative relocs, - but those against other symbols don't. */ - .R_RELATIVE = ~0U, - .rtype_class_valid = RTYPE_CLASS_VALID, - .arch_adjust = mips_arch_adjust, - .adjust_dyn = mips_adjust_dyn, - .adjust_rel = mips_adjust_rel, - .adjust_rela = mips_adjust_rela, - .prelink_rel = mips_prelink_rel, - .prelink_rela = mips_prelink_rela, - .prelink_conflict_rel = mips_prelink_conflict_rel, - .prelink_conflict_rela = mips_prelink_conflict_rela, - .arch_prelink_conflict = mips_arch_prelink_conflict, - .apply_conflict_rela = mips_apply_conflict_rela, - .apply_rel = mips_apply_rel, - .apply_rela = mips_apply_rela, - .rel_to_rela = mips_rel_to_rela, - .rela_to_rel = mips_rela_to_rel, - .need_rel_to_rela = mips_need_rel_to_rela, - .reloc_size = mips_reloc_size, - .reloc_class = mips_reloc_class, - .arch_prelink = mips_arch_prelink, - .arch_undo_prelink = mips_arch_undo_prelink, - .undo_prelink_rel = mips_undo_prelink_rel, - /* Although TASK_UNMAPPED_BASE is 0x2aaa8000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x2c000000, - .mmap_end = 0x3c000000, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; - -PL_ARCH(mips64) = { - .name = "MIPS64", - .class = ELFCLASS64, - .machine = EM_MIPS, - .max_reloc_size = 8, - .dynamic_linker = "/lib/ld.so.1", - .dynamic_linker_alt = "/lib64/ld.so.1", - .R_COPY = R_MIPS_COPY, - .R_JMP_SLOT = R_MIPS_JUMP_SLOT, - /* R_MIPS_REL32 relocations against symbol 0 do act as relative relocs, - but those against other symbols don't. */ - .R_RELATIVE = ~0U, - .rtype_class_valid = RTYPE_CLASS_VALID, - .arch_adjust = mips_arch_adjust, - .adjust_dyn = mips_adjust_dyn, - .adjust_rel = mips_adjust_rel, - .adjust_rela = mips_adjust_rela, - .prelink_rel = mips_prelink_rel, - .prelink_rela = mips_prelink_rela, - .prelink_conflict_rel = mips_prelink_conflict_rel, - .prelink_conflict_rela = mips_prelink_conflict_rela, - .arch_prelink_conflict = mips_arch_prelink_conflict, - .apply_conflict_rela = mips_apply_conflict_rela, - .apply_rel = mips_apply_rel, - .apply_rela = mips_apply_rela, - .rel_to_rela = mips_rel_to_rela, - .rela_to_rel = mips_rela_to_rel, - .need_rel_to_rela = mips_need_rel_to_rela, - .reloc_size = mips_reloc_size, - .reloc_class = mips_reloc_class, - .arch_prelink = mips_arch_prelink, - .arch_undo_prelink = mips_arch_undo_prelink, - .undo_prelink_rel = mips_undo_prelink_rel, - /* Although TASK_UNMAPPED_BASE is 0x5555556000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x5800000000LL, - .mmap_end = 0x9800000000LL, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-ppc.c b/trunk/src/arch-ppc.c deleted file mode 100644 index e22e5d5..0000000 --- a/trunk/src/arch-ppc.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009, 2011 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" -#include "layout.h" - -#ifndef DT_PPC_GOT -# define DT_PPC_GOT (DT_LOPROC + 0) -#endif - -#define DT_PPC_GOT_BIT DT_LOPROC_BIT - -static int -ppc_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PPC_GOT) - { - Elf32_Addr data; - - data = read_ube32 (dso, dyn->d_un.d_ptr); - /* DT_PPC_GOT[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_be32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ube32 (dso, dyn->d_un.d_ptr + 4); - /* DT_PPC_GOT[1] points to .glink in prelinked libs. */ - if (data && data >= start) - write_be32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - - if (dyn->d_un.d_ptr >= start) - { - dyn->d_un.d_ptr += adjust; - return 1; - } - } - else if (dyn->d_tag == DT_PLTGOT - && !dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".got") - && dso->shdr[i].sh_size >= 16) - { - Elf32_Addr data, addr; - int step; - - /* If .got[1] points to _DYNAMIC, it needs to be adjusted. - Other possible locations of the .got header are at the - end of .got or around offset 32768 in it. */ - for (addr = dso->shdr[i].sh_addr, step = 0; step < 18; step++) - { - if (read_ube32 (dso, addr) == 0x4e800021 - && (data = read_ube32 (dso, addr + 4)) - == dso->shdr[n].sh_addr - && data >= start - && read_ube32 (dso, addr + 8) == 0 - && read_ube32 (dso, addr + 12) == 0) - { - /* Probably should use here a check that neither of - the 4 addresses contains a dynamic relocation against - it. */ - write_be32 (dso, addr + 4, data + adjust); - break; - } - if (step == 0) - addr = dso->shdr[i].sh_addr + dso->shdr[i].sh_size - 16; - else if (step == 1) - { - if (dso->shdr[i].sh_size >= 32768 - 32) - addr = dso->shdr[i].sh_addr + 32768 - 32 - 16; - else - break; - } - else - { - addr += 4; - if (addr + 16 - > dso->shdr[i].sh_addr + dso->shdr[i].sh_size) - break; - } - } - break; - } - } - - return 0; -} - -static int -ppc_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: PowerPC doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if (GELF_R_TYPE (rela->r_info) == R_PPC_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_PPC_IRELATIVE) - { - if ((Elf32_Word) rela->r_addend >= start) - rela->r_addend += (Elf32_Sword) adjust; - } - if (GELF_R_TYPE (rela->r_info) == R_PPC_JMP_SLOT - && dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - { - Elf32_Addr data = read_ube32 (dso, rela->r_offset); - if (data >= start) - write_be32 (dso, rela->r_offset, data + adjust); - } - return 0; -} - -static int -ppc_prelink_rel (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: PowerPC doesn't support REL relocs", info->dso->filename); - return 1; -} - -static void -ppc_fixup_plt (DSO *dso, GElf_Rela *rela, GElf_Addr value) -{ - Elf32_Sword disp = value - rela->r_offset; - - if (disp >= -0x2000000 && disp < 0x2000000) - { - /* b value */ - write_be32 (dso, rela->r_offset, 0x48000000 | (disp & 0x3fffffc)); - } - else if ((Elf32_Addr) value >= -0x2000000 || value < 0x2000000) - { - /* ba value */ - write_be32 (dso, rela->r_offset, 0x48000002 | (value & 0x3fffffc)); - } - else - { - Elf32_Addr plt = dso->info[DT_PLTGOT]; - - if (rela->r_offset - plt < (8192 * 2 + 18) * 4) - { - Elf32_Word index = (rela->r_offset - plt - 18 * 4) / (4 * 2); - Elf32_Word count = dso->info[DT_PLTRELSZ] / sizeof (Elf32_Rela); - Elf32_Addr data; - - data = plt + (18 + 2 * count - + (count > 8192 ? (count - 8192) * 2 : 0)) * 4; - write_be32 (dso, data + 4 * index, value); - /* li %r11, 4*index - b .plt+0 */ - write_be32 (dso, rela->r_offset, - 0x39600000 | ((index * 4) & 0xffff)); - write_be32 (dso, rela->r_offset + 4, - 0x48000000 | ((plt - rela->r_offset - 4) & 0x3fffffc)); - } - else - { - /* lis %r12, %hi(finaladdr) - addi %r12, %r12, %lo(finaladdr) - mtctr %r12 - bctr */ - write_be32 (dso, rela->r_offset, - 0x39800000 | (((value + 0x8000) >> 16) & 0xffff)); - write_be32 (dso, rela->r_offset + 4, 0x398c0000 | (value & 0xffff)); - write_be32 (dso, rela->r_offset + 8, 0x7d8903a6); - write_be32 (dso, rela->r_offset + 12, 0x4e800420); - } - } -} - -static int -ppc_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_PPC_NONE - || GELF_R_TYPE (rela->r_info) == R_PPC_IRELATIVE) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_PPC_RELATIVE) - { - write_be32 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_GLOB_DAT: - case R_PPC_ADDR32: - case R_PPC_UADDR32: - write_be32 (dso, rela->r_offset, value); - break; - case R_PPC_DTPREL32: - write_be32 (dso, rela->r_offset, value - 0x8000); - break; - case R_PPC_JMP_SLOT: - if (dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - write_be32 (dso, rela->r_offset, value); - else - ppc_fixup_plt (dso, rela, value); - break; - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_ADDR16_LO: - write_be16 (dso, rela->r_offset, value); - break; - case R_PPC_DTPREL16: - case R_PPC_DTPREL16_LO: - write_be16 (dso, rela->r_offset, value - 0x8000); - break; - case R_PPC_ADDR16_HI: - case R_PPC_DTPREL16_HA: - write_be16 (dso, rela->r_offset, value >> 16); - break; - case R_PPC_DTPREL16_HI: - write_be16 (dso, rela->r_offset, (value - 0x8000) >> 16); - break; - case R_PPC_ADDR16_HA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 16); - break; - case R_PPC_ADDR24: - write_be32 (dso, rela->r_offset, - (value & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003)); - break; - case R_PPC_ADDR14: - write_be32 (dso, rela->r_offset, - (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffff0003)); - break; - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - write_be32 (dso, rela->r_offset, - (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffdf0003) - | ((((GELF_R_TYPE (rela->r_info) == R_PPC_ADDR14_BRTAKEN) - << 21) - ^ (value >> 10)) & 0x00200000)); - break; - case R_PPC_REL24: - write_be32 (dso, rela->r_offset, - ((value - rela->r_offset) & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003)); - break; - case R_PPC_REL32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - /* DTPMOD32 and TPREL* is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_PPC_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_PPC_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_PPC_TPREL32: - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - case R_PPC_TPREL16_HI: - case R_PPC_TPREL16_HA: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - { - value += info->resolvetls->offset - 0x7000; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_TPREL32: - write_be32 (dso, rela->r_offset, value); - break; - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - write_be16 (dso, rela->r_offset, value); - break; - case R_PPC_TPREL16_HI: - write_be16 (dso, rela->r_offset, value >> 16); - break; - case R_PPC_TPREL16_HA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 16); - break; - } - } - break; - case R_PPC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_PPC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown ppc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -ppc_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_ADDR32: - case R_PPC_UADDR32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_PPC_ADDR16: - case R_PPC_UADDR16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_PPC_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_PPC_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -ppc_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: PowerPC doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -ppc_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_NONE: - break; - case R_PPC_GLOB_DAT: - case R_PPC_ADDR32: - case R_PPC_UADDR32: - buf_write_be32 (buf, value); - break; - case R_PPC_ADDR16_HA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC_ADDR16_HI: - value = value >> 16; - /* FALLTHROUGH */ - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_ADDR16_LO: - buf_write_be16 (buf, value); - break; - case R_PPC_ADDR24: - buf_write_be32 (buf, (value & 0x03fffffc) - | (buf_read_ube32 (buf) & 0xfc000003)); - break; - case R_PPC_ADDR14: - buf_write_be32 (buf, (value & 0xfffc) - | (buf_read_ube32 (buf) & 0xffff0003)); - break; - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - buf_write_be32 (buf, (value & 0xfffc) - | (buf_read_ube32 (buf) & 0xffdf0003) - | ((((GELF_R_TYPE (rela->r_info) - == R_PPC_ADDR14_BRTAKEN) << 21) - ^ (value >> 10)) & 0x00200000)); - break; - case R_PPC_REL24: - buf_write_be32 (buf, ((value - rela->r_offset) & 0x03fffffc) - | (buf_read_ube32 (buf) & 0xfc000003)); - break; - case R_PPC_REL32: - buf_write_be32 (buf, value - rela->r_offset); - break; - case R_PPC_RELATIVE: - error (0, 0, "%s: R_PPC_RELATIVE in ET_EXEC object?", - info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -ppc_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: PowerPC doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - int r_type; - - if (GELF_R_TYPE (rela->r_info) == R_PPC_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_PPC_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPREL relocs need conflicts. */ - case R_PPC_DTPMOD32: - case R_PPC_TPREL32: - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - case R_PPC_TPREL16_HI: - case R_PPC_TPREL16_HA: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_PPC_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPREL wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_DTPREL32: - case R_PPC_DTPREL16: - case R_PPC_DTPREL16_LO: - case R_PPC_DTPREL16_HI: - case R_PPC_DTPREL16_HA: - return 0; - } - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - value += rela->r_addend; - r_type = GELF_R_TYPE (rela->r_info); - switch (r_type) - { - case R_PPC_GLOB_DAT: - r_type = R_PPC_ADDR32; - case R_PPC_ADDR32: - case R_PPC_UADDR32: - case R_PPC_IRELATIVE: - if (conflict != NULL && conflict->ifunc) - r_type = R_PPC_IRELATIVE; - break; - case R_PPC_JMP_SLOT: - if (dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - { - r_type = R_PPC_ADDR32; - if (conflict != NULL && conflict->ifunc) - r_type = R_PPC_IRELATIVE; - } - break; - case R_PPC_ADDR16_HA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC_ADDR16_HI: - value = value >> 16; - /* FALLTHROUGH */ - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_ADDR16_LO: - if (r_type != R_PPC_UADDR16) - r_type = R_PPC_ADDR16; - value = ((value & 0xffff) ^ 0x8000) - 0x8000; - break; - case R_PPC_ADDR24: - r_type = R_PPC_ADDR32; - value = (value & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003); - break; - case R_PPC_ADDR14: - r_type = R_PPC_ADDR32; - value = (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffff0003); - break; - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - r_type = R_PPC_ADDR32; - value = (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffdf0003) - | ((((r_type == R_PPC_ADDR14_BRTAKEN) << 21) - ^ (value >> 10)) & 0x00200000); - break; - case R_PPC_REL24: - r_type = R_PPC_ADDR32; - value = ((value - rela->r_offset) & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003); - break; - case R_PPC_REL32: - r_type = R_PPC_ADDR32; - value -= rela->r_offset; - break; - case R_PPC_DTPMOD32: - case R_PPC_DTPREL32: - case R_PPC_DTPREL16: - case R_PPC_DTPREL16_LO: - case R_PPC_DTPREL16_HI: - case R_PPC_DTPREL16_HA: - case R_PPC_TPREL32: - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - case R_PPC_TPREL16_HI: - case R_PPC_TPREL16_HA: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - r_type = R_PPC_ADDR16; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_DTPMOD32: - r_type = R_PPC_ADDR32; - value = tls->modid; - break; - case R_PPC_DTPREL32: - r_type = R_PPC_ADDR32; - value -= 0x8000; - break; - case R_PPC_DTPREL16: - case R_PPC_DTPREL16_LO: - value -= 0x8000; - break; - case R_PPC_DTPREL16_HI: - value = (value - 0x8000) >> 16; - break; - case R_PPC_DTPREL16_HA: - value >>= 16; - break; - case R_PPC_TPREL32: - r_type = R_PPC_ADDR32; - value += tls->offset - 0x7000; - break; - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - value += tls->offset - 0x7000; - break; - case R_PPC_TPREL16_HI: - value = (value + tls->offset - 0x7000) >> 16; - break; - case R_PPC_TPREL16_HA: - value = (value + tls->offset - 0x7000 + 0x8000) >> 16; - break; - } - if (r_type == R_PPC_ADDR16) - value = ((value & 0xffff) ^ 0x8000) - 0x8000; - break; - default: - error (0, 0, "%s: Unknown PowerPC relocation type %d", dso->filename, - r_type); - return 1; - } - if (conflict != NULL && conflict->ifunc && r_type != R_PPC_IRELATIVE) - { - error (0, 0, "%s: relocation %d against IFUNC symbol", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - ret->r_info = GELF_R_INFO (0, r_type); - ret->r_addend = (Elf32_Sword) value; - return 0; -} - -static int -ppc_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: PowerPC doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -ppc_arch_pre_prelink (DSO *dso) -{ - Elf_Data *data = NULL; - Elf_Scn *scn; - GElf_Dyn dyn; - Elf32_Addr val; - int i; - - if (!dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - return 0; - - assert (dso->shdr[dso->dynamic].sh_type == SHT_DYNAMIC); - - scn = dso->scn[dso->dynamic]; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - - maxndx = data->d_size / dso->shdr[dso->dynamic].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - assert (dyn.d_tag != DT_NULL); - if (dyn.d_tag == DT_PPC_GOT) - break; - } - if (ndx < maxndx) - break; - } - - /* DT_PPC_GOT[1] should point to .glink in prelinked libs. */ - val = read_ube32 (dso, dyn.d_un.d_ptr + 4); - if (val) - return 0; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - - val = read_ube32 (dso, dso->shdr[i].sh_addr); - write_be32 (dso, dyn.d_un.d_ptr + 4, val); - - return 0; -} - -static int -ppc_arch_prelink (struct prelink_info *info) -{ - DSO *dso = info->dso; - Elf32_Addr plt = dso->info[DT_PLTGOT]; - - if (plt && !dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - { - Elf32_Word count = dso->info[DT_PLTRELSZ] / sizeof (Elf32_Rela); - Elf32_Addr data; - - data = plt + (18 + 2 * count - + (count > 8192 ? (count - 8192) * 2 : 0)) * 4; - - /* addis %r11, %r11, %hi(data) - lwz %r11, %r11, %lo(data) - mtctr %r11 - bctr */ - write_be32 (dso, plt, 0x3d6b0000 | (((data + 0x8000) >> 16) & 0xffff)); - write_be32 (dso, plt + 4, 0x816b0000 | (data & 0xffff)); - write_be32 (dso, plt + 8, 0x7d6903a6); - write_be32 (dso, plt + 12, 0x4e800420); - } - return 0; -} - -static int -ppc_arch_undo_prelink (DSO *dso) -{ - Elf_Data *data = NULL; - Elf_Scn *scn; - GElf_Dyn dyn; - Elf32_Addr val, addr, endaddr; - int i; - - if (!dynamic_info_is_set (dso, DT_PPC_GOT_BIT)) - return 0; - - assert (dso->shdr[dso->dynamic].sh_type == SHT_DYNAMIC); - - scn = dso->scn[dso->dynamic]; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - - maxndx = data->d_size / dso->shdr[dso->dynamic].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - assert (dyn.d_tag != DT_NULL); - if (dyn.d_tag == DT_PPC_GOT) - break; - } - if (ndx < maxndx) - break; - } - - /* DT_PPC_GOT[1] should point to .glink in prelinked libs. */ - val = read_ube32 (dso, dyn.d_un.d_ptr + 4); - if (!val) - return 0; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt")) - break; - - if (i == dso->ehdr.e_shnum || (dso->shdr[i].sh_size & 3)) - return 0; - - addr = dso->shdr[i].sh_addr; - endaddr = addr + dso->shdr[i].sh_size; - for (; addr < endaddr; addr += 4, val += 4) - write_be32 (dso, addr, val); - - write_be32 (dso, dyn.d_un.d_ptr + 4, 0); - - return 0; -} - - -static int -ppc_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC_NONE: - return 0; - case R_PPC_RELATIVE: - case R_PPC_GLOB_DAT: - case R_PPC_ADDR32: - case R_PPC_UADDR32: - case R_PPC_REL32: - case R_PPC_DTPMOD32: - case R_PPC_DTPREL32: - case R_PPC_TPREL32: - write_be32 (dso, rela->r_offset, 0); - break; - case R_PPC_JMP_SLOT: - /* .plt section will become SHT_NOBITS if DT_PPC_GOT is not present, - otherwise .plt section will be unprelinked in - ppc_arch_undo_prelink. */ - return 0; - case R_PPC_IRELATIVE: - /* .iplt section will become SHT_NOBITS. */ - return 0; - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_ADDR16_LO: - case R_PPC_ADDR16_HI: - case R_PPC_ADDR16_HA: - case R_PPC_DTPREL16: - case R_PPC_TPREL16: - case R_PPC_DTPREL16_LO: - case R_PPC_TPREL16_LO: - case R_PPC_DTPREL16_HI: - case R_PPC_TPREL16_HI: - case R_PPC_DTPREL16_HA: - case R_PPC_TPREL16_HA: - write_be16 (dso, rela->r_offset, 0); - break; - case R_PPC_ADDR24: - case R_PPC_REL24: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xfc000003); - break; - case R_PPC_ADDR14: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffff0003); - break; - case R_PPC_ADDR14_BRTAKEN: - case R_PPC_ADDR14_BRNTAKEN: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffdf0003); - break; - case R_PPC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_PPC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown ppc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -ppc_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_PPC_ADDR16: - case R_PPC_UADDR16: - case R_PPC_ADDR16_LO: - case R_PPC_ADDR16_HI: - case R_PPC_ADDR16_HA: - case R_PPC_DTPREL16: - case R_PPC_DTPREL16_LO: - case R_PPC_DTPREL16_HI: - case R_PPC_DTPREL16_HA: - case R_PPC_TPREL16: - case R_PPC_TPREL16_LO: - case R_PPC_TPREL16_HI: - case R_PPC_TPREL16_HA: - return 2; - default: - break; - } - return 4; -} - -static int -ppc_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_PPC_COPY: return RTYPE_CLASS_COPY; - case R_PPC_JMP_SLOT: return RTYPE_CLASS_PLT; - default: - if (reloc_type >= R_PPC_DTPMOD32 && reloc_type <= R_PPC_DTPREL32) - return RTYPE_CLASS_TLS; - return RTYPE_CLASS_VALID; - } -} - -/* Library memory regions in order of precedence: - 0xe800000 .. 0x10000000 top to bottom - 0x40000 .. 0xe800000 bottom to top - 0x18000000 .. 0x30000000 bottom to top */ - -#define REG0S 0x0e800000 -#define REG0E 0x10000000 -#define REG1S 0x00040000 -#define REG1E REG0S -#define REG2S 0x18000000 -#define REG2E 0x30000000 - -struct ppc_layout_data -{ - int cnt; - struct prelink_entry e[3]; - Elf32_Addr mmap_start, first_start, last_start; - struct - { - struct prelink_entry *e; - Elf32_Addr base, end, layend; - } ents[0]; -}; - -static inline void -list_append (struct prelink_entry *x, struct prelink_entry *e) -{ - x->prev->next = e; - e->prev = x->prev; - e->next = NULL; - x->prev = e; -} - -static int -addr_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - - if (a->base < b->base) - return -1; - else if (a->base > b->base) - return 1; - if (a->layend < b->layend) - return -1; - else if (a->layend > b->layend) - return 1; - return 0; -} - -static void -list_sort (struct prelink_entry *x) -{ - int cnt, i; - struct prelink_entry *e; - struct prelink_entry **a; - - if (x->next == NULL) - return; - for (cnt = 0, e = x->next; e != NULL; e = e->next) - ++cnt; - a = alloca (cnt * sizeof (*a)); - for (i = 0, e = x->next; e != NULL; e = e->next) - a[i++] = e; - qsort (a, cnt, sizeof (*a), addr_cmp); - x->next = NULL; - x->prev = x; - for (i = 0; i < cnt; ++i) - list_append (x, a[i]); -} - -static int -ppc_layout_libs_pre (struct layout_libs *l) -{ - Elf32_Addr mmap_start = l->mmap_start - REG1S; - Elf32_Addr first_start = REG0S, last_start = REG2S; - struct prelink_entry *e, e0, *next = NULL; - struct ppc_layout_data *pld; - int cnt; - - if (l->max_page_size > 0x10000) - error (EXIT_FAILURE, 0, "--layout-page-size too large"); - - mmap_start = REG0E - (mmap_start & 0xff0000); - for (cnt = 0, e = l->list; e != NULL; e = e->next, ++cnt) - { - if (e->base < mmap_start && e->layend > mmap_start) - mmap_start = (e->layend + 0xffff) & ~0xffff; - if (e->base < REG0S && e->layend > REG0S && first_start > e->base) - first_start = e->base; - if (e->base < REG0E && e->layend > REG2S && last_start < e->layend) - last_start = e->layend; - } - if (mmap_start > REG0E) - mmap_start = REG0E; - - pld = calloc (sizeof (*pld) + cnt * sizeof (pld->ents[0]), 1); - if (pld == NULL) - error (EXIT_FAILURE, ENOMEM, "Cannot lay libraries out"); - - l->arch_data = pld; - memset (&e0, 0, sizeof (e0)); - e0.prev = &e0; - pld->cnt = cnt; - pld->e[0].u.tmp = -1; - pld->e[0].base = REG1S + REG0E - mmap_start; - pld->e[0].end = pld->e[0].base; - pld->e[0].layend = pld->e[0].end; - pld->e[0].prev = &pld->e[0]; - pld->e[1].u.tmp = -1; - pld->e[1].base = pld->e[0].end + mmap_start - REG0S; - pld->e[1].end = pld->e[1].base; - pld->e[1].layend = pld->e[1].end; - pld->e[1].prev = &pld->e[1]; - pld->e[2].u.tmp = -1; - pld->e[2].base = pld->e[1].end + first_start - REG1S; - pld->e[2].end = pld->e[1].base; - pld->e[2].layend = pld->e[2].end; - pld->e[2].prev = &pld->e[2]; - for (cnt = 0, e = l->list; e != NULL; e = next, ++cnt) - { - next = e->next; - pld->ents[cnt].e = e; - pld->ents[cnt].base = e->base; - pld->ents[cnt].end = e->end; - pld->ents[cnt].layend = e->layend; - if (e->layend <= REG0S) - { - if (e->base < REG1S) - e->base = REG1S; - else if (e->base > first_start) - e->base = first_start; - if (e->layend < REG1S) - e->layend = REG1S; - else if (e->layend > first_start) - e->layend = first_start; - e->base += pld->e[1].end - REG1S; - e->layend += pld->e[1].end - REG1S; - list_append (&pld->e[1], e); - } - else if (e->base < mmap_start) - { - if (e->base < REG0S) - e->base = REG0S; - if (e->layend > mmap_start) - e->layend = mmap_start; - e->base = pld->e[0].end + mmap_start - e->layend; - e->layend = pld->e[0].layend + mmap_start - pld->ents[cnt].base; - list_append (&pld->e[0], e); - } - else if (e->base < REG0E) - { - if (e->layend > REG0E) - e->layend = REG0E; - e->base = REG1S + REG0E - e->layend; - e->layend = REG1S + REG0E - pld->ents[cnt].base; - list_append (&e0, e); - } - else if (e->layend >= last_start) - { - if (e->base < last_start) - e->base = last_start; - e->base += pld->e[2].end - last_start; - e->layend += pld->e[2].end - last_start; - list_append (&pld->e[2], e); - } - e->end = e->layend; - } - - list_sort (&pld->e[0]); - if (e0.next == NULL) - l->list = &pld->e[0]; - else - { - list_sort (&e0); - l->list = e0.next; - l->list->prev = pld->e[0].prev; - e0.prev->next = &pld->e[0]; - pld->e[0].prev = e0.prev; - } - - e0.prev = l->list->prev; - l->list->prev = pld->e[1].prev; - e0.prev->next = &pld->e[1]; - pld->e[1].prev = e0.prev; - - e0.prev = l->list->prev; - l->list->prev = pld->e[2].prev; - e0.prev->next = &pld->e[2]; - pld->e[2].prev = e0.prev; - - pld->mmap_start = mmap_start; - pld->first_start = first_start; - pld->last_start = last_start; - - l->mmap_start = REG1S; - l->mmap_fin = pld->e[2].end + REG2E - last_start; - l->mmap_end = l->mmap_fin; - l->fakecnt = 3; - l->fake = pld->e; - - return 0; -} - -static int -ppc_layout_libs_post (struct layout_libs *l) -{ - struct prelink_entry *e; - struct ppc_layout_data *pld = (struct ppc_layout_data *) l->arch_data; - Elf32_Addr base, end; - int i; - - /* First fix up base and end fields we saved. */ - for (i = 0; i < pld->cnt; ++i) - { - pld->ents[i].e->base = pld->ents[i].base; - pld->ents[i].e->layend = pld->ents[i].layend; - pld->ents[i].e->end = pld->ents[i].end; - pld->ents[i].e->done |= 0x40; - } - pld->e[0].done |= 0x40; - pld->e[1].done |= 0x40; - pld->e[2].done |= 0x40; - - /* Now fix up the newly created items. */ - for (e = l->list; e != NULL; e = e->next) - if (e->done & 0x40) - e->done &= ~0x40; - else - { - base = e->base; - end = e->layend; - if (e->base < pld->e[0].base) - { - e->base = REG1S + REG0E - end; - e->end += e->base - base; - e->layend = REG1S + REG0E - base; - } - else if (e->base < pld->e[1].base) - { - e->base = pld->e[0].end + pld->mmap_start - end; - e->end += e->base - base; - e->layend = pld->e[0].end + pld->mmap_start - base; - } - else if (e->base < pld->e[2].base) - { - e->base -= pld->e[1].end - REG1S; - e->end -= pld->e[1].end - REG1S; - e->layend -= pld->e[1].end - REG1S; - } - else - { - e->base -= pld->e[2].end - pld->last_start; - e->end -= pld->e[2].end - pld->last_start; - e->layend -= pld->e[2].end - pld->last_start; - } - } - - for (i = 0; i < pld->cnt; ++i) - pld->ents[i].e->done &= ~0x40; - - free (l->arch_data); - return 0; -} - -PL_ARCH(ppc) = { - .name = "PowerPC", - .class = ELFCLASS32, - .machine = EM_PPC, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_PPC_JMP_SLOT, - .R_COPY = R_PPC_COPY, - .R_RELATIVE = R_PPC_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld.so.1", - .adjust_dyn = ppc_adjust_dyn, - .adjust_rel = ppc_adjust_rel, - .adjust_rela = ppc_adjust_rela, - .prelink_rel = ppc_prelink_rel, - .prelink_rela = ppc_prelink_rela, - .prelink_conflict_rel = ppc_prelink_conflict_rel, - .prelink_conflict_rela = ppc_prelink_conflict_rela, - .apply_conflict_rela = ppc_apply_conflict_rela, - .apply_rel = ppc_apply_rel, - .apply_rela = ppc_apply_rela, - .rel_to_rela = ppc_rel_to_rela, - .need_rel_to_rela = ppc_need_rel_to_rela, - .reloc_size = ppc_reloc_size, - .reloc_class = ppc_reloc_class, - .max_reloc_size = 4, - .arch_pre_prelink = ppc_arch_pre_prelink, - .arch_prelink = ppc_arch_prelink, - .arch_undo_prelink = ppc_arch_undo_prelink, - .undo_prelink_rela = ppc_undo_prelink_rela, - .layout_libs_pre = ppc_layout_libs_pre, - .layout_libs_post = ppc_layout_libs_post, - /* This will need some changes in layout.c. - PowerPC prefers addresses right below REG0E - and can use the region above REG2S if libs don't fit. */ - .mmap_base = REG1S, - .mmap_end = REG2E, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-ppc64.c b/trunk/src/arch-ppc64.c deleted file mode 100644 index a764b99..0000000 --- a/trunk/src/arch-ppc64.c +++ /dev/null @@ -1,900 +0,0 @@ -/* Copyright (C) 2002, 2003, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2002. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" -#include "layout.h" - -struct opd_rec -{ - GElf_Addr fn, toc, chain; -}; - -struct opd_lib -{ - GElf_Addr start, size; - GElf_Addr table[1]; -}; - -static int -ppc64_adjust_section (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - if (dso->shdr[n].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[n].sh_name), ".got")) - { - Elf64_Addr data; - - /* .got[0]-0x8000 points to .got, it needs to be adjusted. */ - data = read_ube64 (dso, dso->shdr[n].sh_addr); - if (addr_to_sec (dso, data - 0x8000) == n - && data - 0x8000 == dso->shdr[n].sh_addr) - write_be64 (dso, dso->shdr[n].sh_addr, data + adjust); - } - return 0; -} - -static int -ppc64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PPC64_GLINK && dyn->d_un.d_ptr >= start) - { - dyn->d_un.d_ptr += adjust; - return 1; - } - - return 0; -} - -static int -ppc64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: PowerPC64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if (GELF_R_TYPE (rela->r_info) == R_PPC64_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_PPC64_IRELATIVE) - { - GElf_Addr val = read_ube64 (dso, rela->r_offset); - - if (val == rela->r_addend && val >= start) - write_be64 (dso, rela->r_offset, val + adjust); - if (rela->r_addend >= start) - rela->r_addend += adjust; - } - else if (GELF_R_TYPE (rela->r_info) == R_PPC64_JMP_IREL) - { - if (rela->r_addend >= start) - rela->r_addend += adjust; - } - return 0; -} - -static int -ppc64_prelink_rel (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: PowerPC64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -ppc64_fixup_plt (struct prelink_info *info, GElf_Rela *rela, GElf_Addr value) -{ - DSO *dso = info->dso; - int sec, i; - size_t n; - struct opd_rec rec; - - if (value == 0) - { - rec.fn = 0; - rec.toc = 0; - rec.chain = 0; - } - else if ((sec = addr_to_sec (dso, value)) != -1) - { - rec.fn = read_ube64 (dso, value); - rec.toc = read_ube64 (dso, value + 8); - rec.chain = read_ube64 (dso, value + 16); - } - else - { - for (i = 0; i < info->ent->ndepends; ++i) - if (info->ent->depends[i]->opd - && info->ent->depends[i]->opd->start <= value - && (info->ent->depends[i]->opd->start - + info->ent->depends[i]->opd->size) > value) - break; - - if (i == info->ent->ndepends) - { - error (0, 0, "%s: R_PPC64_JMP_SLOT doesn't resolve to an .opd address", - dso->filename); - return 1; - } - if ((value - info->ent->depends[i]->opd->start) % 8) - { - error (0, 0, "%s: R_PPC64_JMP_SLOT doesn't resolve to valid .opd section location", - dso->filename); - return 1; - } - n = (value - info->ent->depends[i]->opd->start) / 8; - rec.fn = info->ent->depends[i]->opd->table[n]; - rec.toc = info->ent->depends[i]->opd->table[n + 1]; - rec.chain = info->ent->depends[i]->opd->table[n + 2]; - } - write_be64 (dso, rela->r_offset, rec.fn); - write_be64 (dso, rela->r_offset + 8, rec.toc); - write_be64 (dso, rela->r_offset + 16, rec.chain); - return 0; -} - -static int -ppc64_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_PPC64_NONE - || GELF_R_TYPE (rela->r_info) == R_PPC64_IRELATIVE - || GELF_R_TYPE (rela->r_info) == R_PPC64_JMP_IREL) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_PPC64_RELATIVE) - { - write_be64 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_GLOB_DAT: - case R_PPC64_ADDR64: - case R_PPC64_UADDR64: - write_be64 (dso, rela->r_offset, value); - break; - case R_PPC64_DTPREL64: - write_be64 (dso, rela->r_offset, value - 0x8000); - break; - case R_PPC64_ADDR32: - case R_PPC64_UADDR32: - write_be32 (dso, rela->r_offset, value); - break; - case R_PPC64_JMP_SLOT: - return ppc64_fixup_plt (info, rela, value); - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - case R_PPC64_ADDR16_LO: - write_be16 (dso, rela->r_offset, value); - break; - case R_PPC64_DTPREL16: - case R_PPC64_DTPREL16_LO: - write_be16 (dso, rela->r_offset, value - 0x8000); - break; - case R_PPC64_ADDR16_HI: - case R_PPC64_DTPREL16_HA: - write_be16 (dso, rela->r_offset, value >> 16); - break; - case R_PPC64_DTPREL16_HI: - write_be16 (dso, rela->r_offset, (value - 0x8000) >> 16); - break; - case R_PPC64_ADDR16_HA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 16); - break; - case R_PPC64_ADDR16_HIGHER: - write_be16 (dso, rela->r_offset, value >> 32); - break; - case R_PPC64_ADDR16_HIGHERA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 32); - break; - case R_PPC64_ADDR16_HIGHEST: - write_be16 (dso, rela->r_offset, value >> 48); - break; - case R_PPC64_ADDR16_HIGHESTA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 48); - break; - case R_PPC64_ADDR16_LO_DS: - case R_PPC64_ADDR16_DS: - write_be16 (dso, rela->r_offset, - (value & 0xfffc) | read_ube16 (dso, rela->r_offset & 3)); - break; - case R_PPC64_ADDR24: - write_be32 (dso, rela->r_offset, - (value & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003)); - break; - case R_PPC64_ADDR14: - write_be32 (dso, rela->r_offset, - (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffff0003)); - break; - case R_PPC64_ADDR14_BRTAKEN: - case R_PPC64_ADDR14_BRNTAKEN: - write_be32 (dso, rela->r_offset, - (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffdf0003) - | ((((GELF_R_TYPE (rela->r_info) == R_PPC64_ADDR14_BRTAKEN) - << 21) - ^ (value >> 42)) & 0x00200000)); - break; - case R_PPC64_REL24: - write_be32 (dso, rela->r_offset, - ((value - rela->r_offset) & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003)); - break; - case R_PPC64_REL32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_PPC64_REL64: - write_be64 (dso, rela->r_offset, value - rela->r_offset); - break; - /* DTPMOD64 and TPREL* is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_PPC64_DTPMOD64: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_PPC64_DTPMOD64 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_PPC64_TPREL64: - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - case R_PPC64_TPREL16_HI: - case R_PPC64_TPREL16_HA: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - { - value += info->resolvetls->offset - 0x7000; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_TPREL64: - write_be64 (dso, rela->r_offset, value); - break; - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - write_be16 (dso, rela->r_offset, value); - break; - case R_PPC64_TPREL16_HI: - write_be16 (dso, rela->r_offset, value >> 16); - break; - case R_PPC64_TPREL16_HA: - write_be16 (dso, rela->r_offset, (value + 0x8000) >> 16); - break; - } - } - break; - case R_PPC64_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_PPC64_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown ppc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -ppc64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_ADDR64: - case R_PPC64_UADDR64: - buf_write_be64 (buf, rela->r_addend); - break; - case R_PPC64_ADDR32: - case R_PPC64_UADDR32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_PPC64_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_PPC64_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -ppc64_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: PowerPC64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -ppc64_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_NONE: - break; - case R_PPC64_GLOB_DAT: - case R_PPC64_ADDR64: - case R_PPC64_UADDR64: - buf_write_be64 (buf, value); - break; - case R_PPC64_ADDR32: - case R_PPC64_UADDR32: - buf_write_be32 (buf, value); - break; - case R_PPC64_ADDR16_HA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HI: - value = value >> 16; - /* FALLTHROUGH */ - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - case R_PPC64_ADDR16_LO: - buf_write_be16 (buf, value); - break; - case R_PPC64_ADDR16_HIGHERA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HIGHER: - buf_write_be16 (buf, value >> 32); - break; - case R_PPC64_ADDR16_HIGHESTA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HIGHEST: - buf_write_be16 (buf, value >> 48); - break; - case R_PPC64_ADDR16_LO_DS: - case R_PPC64_ADDR16_DS: - buf_write_be16 (buf, (value & 0xfffc) - | (buf_read_ube16 (buf) & 3)); - break; - case R_PPC64_ADDR24: - buf_write_be32 (buf, (value & 0x03fffffc) - | (buf_read_ube32 (buf) & 0xfc000003)); - break; - case R_PPC64_ADDR14: - buf_write_be32 (buf, (value & 0xfffc) - | (buf_read_ube32 (buf) & 0xffff0003)); - break; - case R_PPC64_ADDR14_BRTAKEN: - case R_PPC64_ADDR14_BRNTAKEN: - buf_write_be32 (buf, (value & 0xfffc) - | (buf_read_ube32 (buf) & 0xffdf0003) - | ((((GELF_R_TYPE (rela->r_info) - == R_PPC64_ADDR14_BRTAKEN) << 21) - ^ (value >> 42)) & 0x00200000)); - break; - case R_PPC64_REL24: - buf_write_be32 (buf, ((value - rela->r_offset) & 0x03fffffc) - | (buf_read_ube32 (buf) & 0xfc000003)); - break; - case R_PPC64_REL32: - buf_write_be32 (buf, value - rela->r_offset); - break; - case R_PPC64_REL64: - buf_write_be64 (buf, value - rela->r_offset); - break; - case R_PPC64_RELATIVE: - error (0, 0, "%s: R_PPC64_RELATIVE in ET_EXEC object?", - info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -ppc64_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: PowerPC64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc64_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - int r_type; - - if (GELF_R_TYPE (rela->r_info) == R_PPC64_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_PPC64_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPREL relocs need conflicts. */ - case R_PPC64_DTPMOD64: - case R_PPC64_TPREL64: - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - case R_PPC64_TPREL16_HI: - case R_PPC64_TPREL16_HA: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_PPC64_IRELATIVE: - case R_PPC64_JMP_IREL: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPREL wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_DTPREL64: - case R_PPC64_DTPREL16: - case R_PPC64_DTPREL16_LO: - case R_PPC64_DTPREL16_HI: - case R_PPC64_DTPREL16_HA: - return 0; - } - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - value += rela->r_addend; - r_type = GELF_R_TYPE (rela->r_info); - switch (r_type) - { - case R_PPC64_GLOB_DAT: - r_type = R_PPC64_ADDR64; - case R_PPC64_ADDR64: - case R_PPC64_UADDR64: - if (conflict != NULL && conflict->ifunc) - r_type = R_PPC64_IRELATIVE; - break; - case R_PPC64_IRELATIVE: - case R_PPC64_JMP_IREL: - break; - case R_PPC64_JMP_SLOT: - if (conflict != NULL && conflict->ifunc) - r_type = R_PPC64_JMP_IREL; - break; - case R_PPC64_ADDR32: - case R_PPC64_UADDR32: - value = (Elf32_Sword) value; - break; - case R_PPC64_ADDR16_HA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HI: - value = value >> 16; - /* FALLTHROUGH */ - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - case R_PPC64_ADDR16_LO: - if (r_type != R_PPC64_UADDR16) - r_type = R_PPC64_ADDR16; - value = ((value & 0xffff) ^ 0x8000) - 0x8000; - break; - case R_PPC64_ADDR16_HIGHERA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HIGHER: - r_type = R_PPC64_ADDR16; - value = (((value >> 32) & 0xffff) ^ 0x8000) - 0x8000; - break; - case R_PPC64_ADDR16_HIGHESTA: - value += 0x8000; - /* FALLTHROUGH */ - case R_PPC64_ADDR16_HIGHEST: - r_type = R_PPC64_ADDR16; - value = ((Elf64_Sxword) value) >> 48; - break; - case R_PPC64_ADDR16_LO_DS: - case R_PPC64_ADDR16_DS: - r_type = R_PPC64_ADDR16; - value = ((value & 0xffff) ^ 0x8000) - 0x8000; - value |= read_ube16 (dso, rela->r_offset) & 3; - break; - case R_PPC64_ADDR24: - r_type = R_PPC64_ADDR32; - value = (value & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003); - value = (Elf32_Sword) value; - break; - case R_PPC64_ADDR14: - r_type = R_PPC64_ADDR32; - value = (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffff0003); - value = (Elf32_Sword) value; - break; - case R_PPC64_ADDR14_BRTAKEN: - case R_PPC64_ADDR14_BRNTAKEN: - r_type = R_PPC64_ADDR32; - value = (value & 0xfffc) - | (read_ube32 (dso, rela->r_offset) & 0xffdf0003) - | ((((r_type == R_PPC64_ADDR14_BRTAKEN) << 21) - ^ (value >> 42)) & 0x00200000); - value = (Elf32_Sword) value; - break; - case R_PPC64_REL24: - r_type = R_PPC64_ADDR32; - value = ((value - rela->r_offset) & 0x03fffffc) - | (read_ube32 (dso, rela->r_offset) & 0xfc000003); - value = (Elf32_Sword) value; - break; - case R_PPC64_REL32: - r_type = R_PPC64_ADDR32; - value -= rela->r_offset; - value = (Elf32_Sword) value; - break; - case R_PPC64_REL64: - r_type = R_PPC64_ADDR64; - value -= rela->r_offset; - break; - case R_PPC64_DTPMOD64: - case R_PPC64_DTPREL64: - case R_PPC64_DTPREL16: - case R_PPC64_DTPREL16_LO: - case R_PPC64_DTPREL16_HI: - case R_PPC64_DTPREL16_HA: - case R_PPC64_TPREL64: - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - case R_PPC64_TPREL16_HI: - case R_PPC64_TPREL16_HA: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - r_type = R_PPC64_ADDR16; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_DTPMOD64: - r_type = R_PPC64_ADDR64; - value = tls->modid; - break; - case R_PPC64_DTPREL64: - r_type = R_PPC64_ADDR64; - value -= 0x8000; - break; - case R_PPC64_DTPREL16: - case R_PPC64_DTPREL16_LO: - value -= 0x8000; - break; - case R_PPC64_DTPREL16_HI: - value = (value - 0x8000) >> 16; - break; - case R_PPC64_DTPREL16_HA: - value >>= 16; - break; - case R_PPC64_TPREL64: - r_type = R_PPC64_ADDR64; - value += tls->offset - 0x7000; - break; - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - value += tls->offset - 0x7000; - break; - case R_PPC64_TPREL16_HI: - value = (value + tls->offset - 0x7000) >> 16; - break; - case R_PPC64_TPREL16_HA: - value = (value + tls->offset - 0x7000 + 0x8000) >> 16; - break; - } - if (r_type == R_PPC64_ADDR16) - value = ((value & 0xffff) ^ 0x8000) - 0x8000; - break; - default: - error (0, 0, "%s: Unknown PowerPC64 relocation type %d", dso->filename, - r_type); - return 1; - } - if (conflict != NULL && conflict->ifunc - && r_type != R_PPC64_IRELATIVE && r_type != R_PPC64_JMP_IREL) - { - error (0, 0, "%s: relocation %d against IFUNC symbol", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - ret->r_info = GELF_R_INFO (0, r_type); - ret->r_addend = value; - return 0; -} - -static int -ppc64_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: PowerPC64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -ppc64_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -ppc64_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - switch (GELF_R_TYPE (rela->r_info)) - { - case R_PPC64_NONE: - return 0; - case R_PPC64_JMP_SLOT: - /* .plt section will become SHT_NOBITS. */ - return 0; - case R_PPC64_JMP_IREL: - /* .iplt section will become SHT_NOBITS. */ - return 0; - case R_PPC64_RELATIVE: - case R_PPC64_ADDR64: - case R_PPC64_IRELATIVE: - write_be64 (dso, rela->r_offset, rela->r_addend); - break; - case R_PPC64_GLOB_DAT: - case R_PPC64_UADDR64: - case R_PPC64_DTPREL64: - case R_PPC64_TPREL64: - case R_PPC64_DTPMOD64: - case R_PPC64_REL64: - write_be64 (dso, rela->r_offset, 0); - break; - case R_PPC64_ADDR32: - case R_PPC64_UADDR32: - case R_PPC64_REL32: - write_be32 (dso, rela->r_offset, 0); - break; - case R_PPC64_ADDR16_HA: - case R_PPC64_DTPREL16_HA: - case R_PPC64_TPREL16_HA: - case R_PPC64_ADDR16_HI: - case R_PPC64_DTPREL16_HI: - case R_PPC64_TPREL16_HI: - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - case R_PPC64_ADDR16_LO: - case R_PPC64_DTPREL16: - case R_PPC64_TPREL16: - case R_PPC64_DTPREL16_LO: - case R_PPC64_TPREL16_LO: - case R_PPC64_ADDR16_HIGHERA: - case R_PPC64_ADDR16_HIGHER: - case R_PPC64_ADDR16_HIGHESTA: - case R_PPC64_ADDR16_HIGHEST: - case R_PPC64_ADDR16_LO_DS: - case R_PPC64_ADDR16_DS: - write_be16 (dso, rela->r_offset, 0); - break; - case R_PPC64_ADDR24: - case R_PPC64_REL24: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xfc000003); - break; - case R_PPC64_ADDR14: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffff0003); - break; - case R_PPC64_ADDR14_BRTAKEN: - case R_PPC64_ADDR14_BRNTAKEN: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffdf0003); - break; - case R_PPC64_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_PPC64_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown ppc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -ppc64_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_PPC64_ADDR16: - case R_PPC64_UADDR16: - case R_PPC64_ADDR16_LO: - case R_PPC64_ADDR16_HA: - case R_PPC64_ADDR16_HI: - case R_PPC64_ADDR16_LO_DS: - case R_PPC64_ADDR16_DS: - case R_PPC64_ADDR16_HIGHER: - case R_PPC64_ADDR16_HIGHERA: - case R_PPC64_ADDR16_HIGHEST: - case R_PPC64_ADDR16_HIGHESTA: - case R_PPC64_DTPREL16: - case R_PPC64_DTPREL16_LO: - case R_PPC64_DTPREL16_HI: - case R_PPC64_DTPREL16_HA: - case R_PPC64_TPREL16: - case R_PPC64_TPREL16_LO: - case R_PPC64_TPREL16_HI: - case R_PPC64_TPREL16_HA: - return 2; - case R_PPC64_GLOB_DAT: - case R_PPC64_ADDR64: - case R_PPC64_UADDR64: - case R_PPC64_REL64: - case R_PPC64_DTPMOD64: - case R_PPC64_DTPREL64: - case R_PPC64_TPREL64: - case R_PPC64_IRELATIVE: - return 8; - default: - break; - } - return 4; -} - -static int -ppc64_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_PPC64_COPY: return RTYPE_CLASS_COPY | RTYPE_CLASS_PLT; - default: - if (reloc_type >= R_PPC64_DTPMOD64 - && reloc_type <= R_PPC64_TPREL16_HIGHESTA) - return RTYPE_CLASS_TLS; - return RTYPE_CLASS_PLT; - } -} - -static int -ppc64_read_opd (DSO *dso, struct prelink_entry *ent) -{ - int opd; - GElf_Addr n, s; - - free (ent->opd); - ent->opd = NULL; - for (opd = 1; opd < dso->ehdr.e_shnum; ++opd) - if (dso->shdr[opd].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[opd].sh_name), ".opd")) - break; - if (opd == dso->ehdr.e_shnum) - return 0; - ent->opd = malloc (sizeof (struct opd_lib) + dso->shdr[opd].sh_size); - /* The error will happen only when we'll need the opd. */ - if (ent->opd == NULL) - return 0; - s = dso->shdr[opd].sh_addr; - for (n = 0; n < dso->shdr[opd].sh_size / 8; ++n, s += 8) - ent->opd->table[n] = read_ube64 (dso, s); - ent->opd->start = dso->shdr[opd].sh_addr; - ent->opd->size = dso->shdr[opd].sh_size; - return 0; -} - -static int -ppc64_free_opd (struct prelink_entry *ent) -{ - free (ent->opd); - ent->opd = NULL; - return 0; -} - -PL_ARCH(ppc64) = { - .name = "PowerPC", - .class = ELFCLASS64, - .machine = EM_PPC64, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_PPC64_JMP_SLOT, - .R_COPY = R_PPC64_COPY, - .R_RELATIVE = R_PPC64_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_PLT, - .dynamic_linker = "/lib64/ld64.so.1", - .adjust_section = ppc64_adjust_section, - .adjust_dyn = ppc64_adjust_dyn, - .adjust_rel = ppc64_adjust_rel, - .adjust_rela = ppc64_adjust_rela, - .prelink_rel = ppc64_prelink_rel, - .prelink_rela = ppc64_prelink_rela, - .prelink_conflict_rel = ppc64_prelink_conflict_rel, - .prelink_conflict_rela = ppc64_prelink_conflict_rela, - .apply_conflict_rela = ppc64_apply_conflict_rela, - .apply_rel = ppc64_apply_rel, - .apply_rela = ppc64_apply_rela, - .rel_to_rela = ppc64_rel_to_rela, - .need_rel_to_rela = ppc64_need_rel_to_rela, - .reloc_size = ppc64_reloc_size, - .reloc_class = ppc64_reloc_class, - .read_opd = ppc64_read_opd, - .free_opd = ppc64_free_opd, - .max_reloc_size = 8, - .undo_prelink_rela = ppc64_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x8000000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x8001000000LL, - .mmap_end = 0x8100000000LL, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-s390.c b/trunk/src/arch-s390.c deleted file mode 100644 index e5fe130..0000000 --- a/trunk/src/arch-s390.c +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009, 2010, 2013 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -s390_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf64_Addr data; - - if (sec == -1) - return 0; - - data = read_ube32 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_be32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ube32 (dso, dyn->d_un.d_ptr + 4); - /* If .got.plt[1] points to .plt + 0x2c, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 0x2c - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_be32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - break; - } - } - } - return 0; -} - -static int -s390_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr addr; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_RELATIVE: - if ((Elf32_Addr) rela->r_addend >= start) - { - addr = read_ube32 (dso, rela->r_offset); - if (addr == rela->r_addend) - write_be32 (dso, rela->r_offset, addr + adjust); - rela->r_addend += (Elf32_Sword) adjust; - } - break; - case R_390_IRELATIVE: - if (rela->r_addend >= start) - /* Adjust the resolver function address. */ - rela->r_addend += adjust; - /* FALLTHROUGH */ - case R_390_JMP_SLOT: - /* Adjust the address in the GOT slot. */ - addr = read_ube32 (dso, rela->r_offset); - if (addr >= start) - write_be32 (dso, rela->r_offset, addr + adjust); - break; - } - return 0; -} - -static int -s390_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -s390_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_390_NONE - || GELF_R_TYPE (rela->r_info) == R_390_IRELATIVE) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_390_RELATIVE) - { - write_be32 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - write_be32 (dso, rela->r_offset, value - rela->r_addend); - break; - case R_390_32: - write_be32 (dso, rela->r_offset, value); - break; - case R_390_PC32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - write_be32 (dso, rela->r_offset, - ((Elf32_Sword) (value - rela->r_offset)) >> 1); - break; - case R_390_16: - write_be16 (dso, rela->r_offset, value); - break; - case R_390_PC16: - write_be16 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - write_be16 (dso, rela->r_offset, - ((int16_t) (value - rela->r_offset)) >> 1); - break; - case R_390_8: - write_8 (dso, rela->r_offset, value); - break; - case R_390_TLS_DTPOFF: - write_be32 (dso, rela->r_offset, value); - break; - /* DTPMOD and TPOFF is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_390_TLS_DTPMOD: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_390_TLS_DTPMOD reloc in executable?", - dso->filename); - return 1; - } - break; - case R_390_TLS_TPOFF: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - value - info->resolvetls->offset); - break; - case R_390_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_390_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown S390 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -s390_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_390_16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_390_8: - buf_write_8 (buf, rela->r_addend); - break; - case R_390_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_390_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -s390_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -s390_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_NONE: - break; - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - buf_write_be32 (buf, value - rela->r_addend); - break; - case R_390_32: - buf_write_be32 (buf, value); - break; - case R_390_PC32: - buf_write_be32 (buf, value - rela->r_offset); - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - buf_write_be32 (buf, ((Elf32_Sword) (value - rela->r_offset)) >> 1); - break; - case R_390_16: - buf_write_be16 (buf, value); - break; - case R_390_PC16: - buf_write_be16 (buf, value - rela->r_offset); - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - buf_write_be16 (buf, ((int16_t) (value - rela->r_offset)) >> 1); - break; - case R_390_8: - buf_write_8 (buf, value); - break; - case R_390_COPY: - abort (); - case R_390_RELATIVE: - error (0, 0, "%s: R_390_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -s390_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_390_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_390_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_390_TLS_DTPMOD: - case R_390_TLS_TPOFF: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* IRELATIVE always need conflicts. */ - case R_390_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_390_TLS_DTPOFF - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, R_390_32); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - ret->r_addend = (Elf32_Sword) (value - rela->r_addend); - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_390_IRELATIVE); - break; - case R_390_32: - ret->r_addend = (Elf32_Sword) value; - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_390_IRELATIVE); - break; - case R_390_IRELATIVE: - ret->r_addend = (Elf32_Sword) value; - ret->r_info = GELF_R_INFO (0, R_390_IRELATIVE); - break; - case R_390_PC32: - ret->r_addend = (Elf32_Sword) (value - rela->r_offset); - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - ret->r_addend = ((Elf32_Sword) (value - rela->r_offset)) >> 1; - break; - case R_390_PC16: - value -= rela->r_offset; - case R_390_16: - ret->r_addend = (Elf32_Half) value; - ret->r_info = GELF_R_INFO (0, R_390_16); - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - ret->r_addend = (Elf32_Half) (((int16_t) (value - rela->r_offset)) >> 1); - ret->r_info = GELF_R_INFO (0, R_390_16); - break; - case R_390_8: - ret->r_addend = value & 0xff; - ret->r_info = GELF_R_INFO (0, R_390_8); - break; - case R_390_COPY: - error (0, 0, "R_390_COPY should not be present in shared libraries"); - return 1; - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_TLS_DTPMOD: - ret->r_addend = tls->modid; - break; - case R_390_TLS_DTPOFF: - ret->r_addend = value; - break; - case R_390_TLS_TPOFF: - ret->r_addend = value - tls->offset; - break; - } - break; - - default: - error (0, 0, "%s: Unknown S390 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -s390_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -s390_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 0x2c into got[1]. - .plt + 0x2c is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf64_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr + 0x2c; - write_be32 (dso, dso->info[DT_PLTGOT] + 4, data); - } - - return 0; -} - -static int -s390_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt + 0x2c. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_ube32 (dso, dso->info[DT_PLTGOT] + 4); - if (data == dso->shdr[i].sh_addr + 0x2c) - write_be32 (dso, dso->info[DT_PLTGOT] + 4, 0); - } - - return 0; -} - -static int -s390_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_NONE: - case R_390_RELATIVE: - case R_390_IRELATIVE: - break; - case R_390_JMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_390_JMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf32_Addr data = read_ube32 (dso, dso->shdr[sec].sh_addr + 4); - - assert (rela->r_offset >= dso->shdr[sec].sh_addr + 12); - assert (((rela->r_offset - dso->shdr[sec].sh_addr) & 3) == 0); - write_be32 (dso, rela->r_offset, - 8 * (rela->r_offset - dso->shdr[sec].sh_addr - 12) - + data); - } - break; - case R_390_GLOB_DAT: - case R_390_32: - case R_390_PC32: - case R_390_PC32DBL: - case R_390_PLT32DBL: - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - write_be32 (dso, rela->r_offset, 0); - break; - case R_390_16: - case R_390_PC16: - case R_390_PC16DBL: - case R_390_PLT16DBL: - write_be16 (dso, rela->r_offset, 0); - break; - case R_390_8: - write_8 (dso, rela->r_offset, 0); - break; - case R_390_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_390_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown s390 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -s390_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_390_16: - case R_390_PC16: - case R_390_PC16DBL: - case R_390_PLT16DBL: - return 2; - case R_390_8: - return 1; - default: - return 4; - } -} - -static int -s390_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_390_COPY: return RTYPE_CLASS_COPY; - case R_390_JMP_SLOT: return RTYPE_CLASS_PLT; - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(s390) = { - .name = "S390", - .class = ELFCLASS32, - .machine = EM_S390, - .alternate_machine = { 0xA390 }, - .R_JMP_SLOT = R_390_JMP_SLOT, - .R_COPY = R_390_COPY, - .R_RELATIVE = R_390_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld.so.1", - .adjust_dyn = s390_adjust_dyn, - .adjust_rel = s390_adjust_rel, - .adjust_rela = s390_adjust_rela, - .prelink_rel = s390_prelink_rel, - .prelink_rela = s390_prelink_rela, - .prelink_conflict_rel = s390_prelink_conflict_rel, - .prelink_conflict_rela = s390_prelink_conflict_rela, - .apply_conflict_rela = s390_apply_conflict_rela, - .apply_rel = s390_apply_rel, - .apply_rela = s390_apply_rela, - .rel_to_rela = s390_rel_to_rela, - .need_rel_to_rela = s390_need_rel_to_rela, - .reloc_size = s390_reloc_size, - .reloc_class = s390_reloc_class, - .max_reloc_size = 4, - .arch_prelink = s390_arch_prelink, - .arch_undo_prelink = s390_arch_undo_prelink, - .undo_prelink_rela = s390_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x40000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x41000000, - .mmap_end = 0x50000000, - .max_page_size = 0x1000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-s390x.c b/trunk/src/arch-s390x.c deleted file mode 100644 index e4d82f7..0000000 --- a/trunk/src/arch-s390x.c +++ /dev/null @@ -1,658 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009, 2013 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -s390x_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf64_Addr data; - - if (sec == -1) - return 0; - - data = read_ube64 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_be64 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ube64 (dso, dyn->d_un.d_ptr + 8); - /* If .got.plt[1] points to .plt + 0x2e, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 0x2e - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_be64 (dso, dyn->d_un.d_ptr + 8, data + adjust); - break; - } - } - } - return 0; -} - -static int -s390x_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390x_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf64_Addr addr; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_RELATIVE: - if (rela->r_addend >= start) - { - addr = read_ube64 (dso, rela->r_offset); - if (addr == rela->r_addend) - write_be64 (dso, rela->r_offset, addr + adjust); - rela->r_addend += adjust; - } - break; - case R_390_IRELATIVE: - if (rela->r_addend >= start) - /* Adjust the resolver function address. */ - rela->r_addend += adjust; - /* FALLTHROUGH */ - case R_390_JMP_SLOT: - /* Adjust the address in the GOT slot. */ - addr = read_ube64 (dso, rela->r_offset); - if (addr >= start) - write_be64 (dso, rela->r_offset, addr + adjust); - break; - } - return 0; -} - -static int -s390x_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -s390x_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_390_NONE - || GELF_R_TYPE (rela->r_info) == R_390_IRELATIVE) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_390_RELATIVE) - { - write_be64 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - case R_390_64: - write_be64 (dso, rela->r_offset, value); - break; - case R_390_PC64: - write_be64 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_390_32: - write_be32 (dso, rela->r_offset, value); - break; - case R_390_PC32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - write_be32 (dso, rela->r_offset, - ((Elf32_Sword) (value - rela->r_offset)) >> 1); - break; - case R_390_16: - write_be16 (dso, rela->r_offset, value); - break; - case R_390_PC16: - write_be16 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - write_be16 (dso, rela->r_offset, - ((int16_t) (value - rela->r_offset)) >> 1); - break; - case R_390_8: - write_8 (dso, rela->r_offset, value); - break; - case R_390_TLS_DTPOFF: - write_be64 (dso, rela->r_offset, value); - break; - /* DTPMOD and TPOFF is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_390_TLS_DTPMOD: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_390_TLS_DTPMOD reloc in executable?", - dso->filename); - return 1; - } - break; - case R_390_TLS_TPOFF: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be64 (dso, rela->r_offset, value - info->resolvetls->offset); - break; - case R_390_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_390_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown S390 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -s390x_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_64: - buf_write_be64 (buf, rela->r_addend); - break; - case R_390_32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_390_16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_390_8: - buf_write_8 (buf, rela->r_addend); - break; - case R_390_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_390_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - default: - abort (); - } - return 0; -} - -static int -s390x_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -s390x_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_NONE: - break; - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - case R_390_64: - buf_write_be64 (buf, value); - break; - case R_390_PC64: - buf_write_be64 (buf, value - rela->r_offset); - break; - case R_390_32: - buf_write_be32 (buf, value); - break; - case R_390_PC32: - buf_write_be32 (buf, value - rela->r_offset); - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - buf_write_be32 (buf, ((Elf32_Sword) (value - rela->r_offset)) >> 1); - break; - case R_390_16: - buf_write_be16 (buf, value); - break; - case R_390_PC16: - buf_write_be16 (buf, value - rela->r_offset); - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - buf_write_be16 (buf, ((int16_t) (value - rela->r_offset)) >> 1); - break; - case R_390_8: - buf_write_8 (buf, value); - break; - case R_390_COPY: - abort (); - case R_390_RELATIVE: - error (0, 0, "%s: R_390_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -s390x_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390x_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - int r_type; - - if (GELF_R_TYPE (rela->r_info) == R_390_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_390_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_390_TLS_DTPMOD: - case R_390_TLS_TPOFF: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* IRELATIVE always need conflicts. */ - case R_390_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_390_TLS_DTPOFF - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - r_type = GELF_R_TYPE (rela->r_info); - value += rela->r_addend; - switch (r_type) - { - case R_390_PC64: - value -= rela->r_offset; - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - r_type = R_390_64; - case R_390_64: - case R_390_IRELATIVE: - ret->r_addend = value; - if (conflict != NULL && conflict->ifunc) - r_type = R_390_IRELATIVE; - break; - case R_390_PC32: - value -= rela->r_offset; - case R_390_32: - ret->r_addend = (Elf32_Addr) value; - r_type = R_390_32; - break; - case R_390_PC32DBL: - case R_390_PLT32DBL: - ret->r_addend - = (Elf32_Addr) (((Elf32_Sword) (value - rela->r_offset)) >> 1); - r_type = R_390_32; - break; - case R_390_PC16: - value -= rela->r_offset; - case R_390_16: - ret->r_addend = (Elf32_Half) value; - r_type = R_390_16; - break; - case R_390_PC16DBL: - case R_390_PLT16DBL: - ret->r_addend = (Elf32_Half) (((int16_t) (value - rela->r_offset)) >> 1); - r_type = R_390_16; - break; - case R_390_8: - ret->r_addend = value & 0xff; - break; - case R_390_COPY: - error (0, 0, "R_390_COPY should not be present in shared libraries"); - return 1; - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - switch (r_type) - { - case R_390_TLS_DTPMOD: - ret->r_addend = tls->modid; - break; - case R_390_TLS_DTPOFF: - ret->r_addend = value; - break; - case R_390_TLS_TPOFF: - ret->r_addend = value - tls->offset; - break; - } - r_type = R_390_64; - break; - default: - error (0, 0, "%s: Unknown S390 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - ret->r_info = GELF_R_INFO (0, r_type); - return 0; -} - -static int -s390x_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: S390 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -s390x_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -s390x_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 0x2e into got[1]. - .plt + 0x2e is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf64_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr + 0x2e; - write_be64 (dso, dso->info[DT_PLTGOT] + 8, data); - } - - return 0; -} - -static int -s390x_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt + 0x2e. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf64_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_ube64 (dso, dso->info[DT_PLTGOT] + 8); - if (data == dso->shdr[i].sh_addr + 0x2e) - write_be64 (dso, dso->info[DT_PLTGOT] + 8, 0); - } - - return 0; -} - -static int -s390x_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_390_NONE: - case R_390_RELATIVE: - case R_390_IRELATIVE: - break; - case R_390_JMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_390_JMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf64_Addr data = read_ube64 (dso, dso->shdr[sec].sh_addr + 8); - - assert (rela->r_offset >= dso->shdr[sec].sh_addr + 24); - assert (((rela->r_offset - dso->shdr[sec].sh_addr) & 7) == 0); - write_be64 (dso, rela->r_offset, - 4 * (rela->r_offset - dso->shdr[sec].sh_addr - 24) - + data); - } - break; - case R_390_GLOB_DAT: - case R_390_64: - case R_390_PC64: - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - write_be64 (dso, rela->r_offset, 0); - break; - case R_390_32: - case R_390_PC32: - case R_390_PC32DBL: - case R_390_PLT32DBL: - write_be32 (dso, rela->r_offset, 0); - break; - case R_390_16: - case R_390_PC16: - case R_390_PC16DBL: - case R_390_PLT16DBL: - write_be16 (dso, rela->r_offset, 0); - break; - case R_390_8: - write_8 (dso, rela->r_offset, 0); - break; - case R_390_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_390_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown s390x relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -s390x_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_390_GLOB_DAT: - case R_390_JMP_SLOT: - case R_390_64: - case R_390_PC64: - case R_390_IRELATIVE: - return 8; - case R_390_32: - case R_390_PC32: - case R_390_PC32DBL: - case R_390_PLT32DBL: - default: - return 4; - case R_390_16: - case R_390_PC16: - case R_390_PC16DBL: - case R_390_PLT16DBL: - return 2; - case R_390_8: - return 1; - } -} - -static int -s390x_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_390_COPY: return RTYPE_CLASS_COPY; - case R_390_JMP_SLOT: return RTYPE_CLASS_PLT; - case R_390_TLS_DTPMOD: - case R_390_TLS_DTPOFF: - case R_390_TLS_TPOFF: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(s390x) = { - .name = "S390", - .class = ELFCLASS64, - .machine = EM_S390, - .alternate_machine = { 0xA390 }, - .R_JMP_SLOT = R_390_JMP_SLOT, - .R_COPY = R_390_COPY, - .R_RELATIVE = R_390_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld64.so.1", - .adjust_dyn = s390x_adjust_dyn, - .adjust_rel = s390x_adjust_rel, - .adjust_rela = s390x_adjust_rela, - .prelink_rel = s390x_prelink_rel, - .prelink_rela = s390x_prelink_rela, - .prelink_conflict_rel = s390x_prelink_conflict_rel, - .prelink_conflict_rela = s390x_prelink_conflict_rela, - .apply_conflict_rela = s390x_apply_conflict_rela, - .apply_rel = s390x_apply_rel, - .apply_rela = s390x_apply_rela, - .rel_to_rela = s390x_rel_to_rela, - .need_rel_to_rela = s390x_need_rel_to_rela, - .reloc_size = s390x_reloc_size, - .reloc_class = s390x_reloc_class, - .max_reloc_size = 8, - .arch_prelink = s390x_arch_prelink, - .arch_undo_prelink = s390x_arch_undo_prelink, - .undo_prelink_rela = s390x_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x4000000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x4010000000LL, - .mmap_end = 0x5000000000LL, - .max_page_size = 0x1000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-sh.c b/trunk/src/arch-sh.c deleted file mode 100644 index 1b11312..0000000 --- a/trunk/src/arch-sh.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -sh_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf32_Addr data; - - if (sec == -1) - return 0; - - data = read_une32 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_ne32 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_une32 (dso, dyn->d_un.d_ptr + 4); - /* If .got.plt[1] points to .plt + 36, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 36 - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_ne32 (dso, dyn->d_un.d_ptr + 4, data + adjust); - break; - } - } - } - return 0; -} - -static int -sh_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: SH doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sh_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf32_Addr data; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_RELATIVE: - if (rela->r_addend && (Elf32_Addr) rela->r_addend >= start) - { - rela->r_addend += (Elf32_Sword) adjust; - break; - } - /* FALLTHROUGH */ - case R_SH_JMP_SLOT: - data = read_une32 (dso, rela->r_offset); - if (data >= start) - write_ne32 (dso, rela->r_offset, data + adjust); - break; - break; - } - return 0; -} - -static int -sh_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: SH doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -sh_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - dso = info->dso; - if (GELF_R_TYPE (rela->r_info) == R_SH_NONE) - /* Fast path: nothing to do. */ - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_SH_RELATIVE) - { - if (rela->r_addend) - write_ne32 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_GLOB_DAT: - case R_SH_JMP_SLOT: - case R_SH_DIR32: - write_ne32 (dso, rela->r_offset, value); - break; - case R_SH_REL32: - write_ne32 (dso, rela->r_offset, value - rela->r_addend); - break; - case R_SH_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SH_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sh relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sh_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_GLOB_DAT: - case R_SH_JMP_SLOT: - case R_SH_DIR32: - buf_write_ne32 (info->dso, buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -sh_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: SH doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -sh_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_NONE: - break; - case R_SH_GLOB_DAT: - case R_SH_JMP_SLOT: - case R_SH_DIR32: - buf_write_ne32 (info->dso, buf, value); - break; - case R_SH_REL32: - buf_write_ne32 (info->dso, buf, value - rela->r_offset); - break; - case R_SH_COPY: - abort (); - case R_SH_RELATIVE: - error (0, 0, "%s: R_SH_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -sh_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: SH doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sh_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_SH_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_SH_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - return 0; - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on SuperH yet", - dso->filename); - return 1; - } - value = conflict_lookup_value (conflict); - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_REL32: - value -= rela->r_offset; - ret->r_info = GELF_R_INFO (0, R_SH_DIR32); - /* FALLTHROUGH */ - case R_SH_DIR32: - if ((rela->r_offset & 3) == 0) - ret->r_info = GELF_R_INFO (0, R_SH_GLOB_DAT); - /* FALLTHROUGH */ - case R_SH_GLOB_DAT: - case R_SH_JMP_SLOT: - ret->r_addend = (Elf32_Sword) (value + rela->r_addend); - break; - case R_SH_COPY: - error (0, 0, "R_SH_COPY should not be present in shared libraries"); - return 1; - default: - error (0, 0, "%s: Unknown sh relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sh_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - return 0; -} - -static int -sh_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -sh_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 36 into got[1]. - .plt + 36 is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = dso->shdr[i].sh_addr + 36; - write_ne32 (dso, dso->info[DT_PLTGOT] + 4, data); - } - - return 0; -} - -static int -sh_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt + 36. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf32_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_une32 (dso, dso->info[DT_PLTGOT] + 4); - if (data == dso->shdr[i].sh_addr + 36) - write_ne32 (dso, dso->info[DT_PLTGOT] + 4, 0); - } - - return 0; -} - -static int -sh_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SH_NONE: - break; - case R_SH_RELATIVE: - if (rela->r_addend) - write_ne32 (dso, rela->r_offset, 0); - break; - case R_SH_JMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_SH_JMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf32_Addr data = read_une32 (dso, dso->shdr[sec].sh_addr + 4); - - assert (rela->r_offset >= dso->shdr[sec].sh_addr + 12); - assert (((rela->r_offset - dso->shdr[sec].sh_addr) & 3) == 0); - write_ne32 (dso, rela->r_offset, - 7 * (rela->r_offset - dso->shdr[sec].sh_addr - 12) - + data); - } - break; - case R_SH_GLOB_DAT: - case R_SH_DIR32: - case R_SH_REL32: - write_ne32 (dso, rela->r_offset, 0); - break; - case R_SH_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SH_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sh relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sh_reloc_size (int reloc_type) -{ - return 4; -} - -static int -sh_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_SH_COPY: return RTYPE_CLASS_COPY; - case R_SH_JMP_SLOT: return RTYPE_CLASS_PLT; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(sh) = { - .name = "SuperH", - .class = ELFCLASS32, - .machine = EM_SH, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_SH_JMP_SLOT, - .R_COPY = R_SH_COPY, - .R_RELATIVE = R_SH_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux.so.2", - .adjust_dyn = sh_adjust_dyn, - .adjust_rel = sh_adjust_rel, - .adjust_rela = sh_adjust_rela, - .prelink_rel = sh_prelink_rel, - .prelink_rela = sh_prelink_rela, - .prelink_conflict_rel = sh_prelink_conflict_rel, - .prelink_conflict_rela = sh_prelink_conflict_rela, - .apply_conflict_rela = sh_apply_conflict_rela, - .apply_rel = sh_apply_rel, - .apply_rela = sh_apply_rela, - .rel_to_rela = sh_rel_to_rela, - .need_rel_to_rela = sh_need_rel_to_rela, - .reloc_size = sh_reloc_size, - .reloc_class = sh_reloc_class, - .max_reloc_size = 4, - .arch_prelink = sh_arch_prelink, - .arch_undo_prelink = sh_arch_undo_prelink, - .undo_prelink_rela = sh_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x29555000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x30000000, - .mmap_end = 0x40000000, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-sparc.c b/trunk/src/arch-sparc.c deleted file mode 100644 index e016a79..0000000 --- a/trunk/src/arch-sparc.c +++ /dev/null @@ -1,645 +0,0 @@ -/* Copyright (C) 2001, 2002, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -static int -sparc_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".got")) - { - Elf32_Addr data; - - data = read_ube32 (dso, dso->shdr[i].sh_addr); - /* .got[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_be32 (dso, dso->shdr[i].sh_addr, data + adjust); - break; - } - } - - return 0; -} - -static int -sparc_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE) - { - if (rela->r_addend) - { - if ((Elf32_Addr) rela->r_addend >= start) - rela->r_addend += (Elf32_Sword) adjust; - } - else - { - GElf_Addr val = read_ube32 (dso, rela->r_offset); - - if (val >= start) - write_be32 (dso, rela->r_offset, val + adjust); - } - } - return 0; -} - -static int -sparc_prelink_rel (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename); - return 1; -} - -static void -sparc_fixup_plt (DSO *dso, GElf_Rela *rela, GElf_Addr value) -{ - Elf32_Sword disp = value - rela->r_offset; - - if (disp >= -0x800000 && disp < 0x800000) - { - /* b,a value - nop - nop */ - write_be32 (dso, rela->r_offset, 0x30800000 | ((disp >> 2) & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, 0x01000000); - write_be32 (dso, rela->r_offset + 8, 0x01000000); - } - else - { - /* sethi %hi(value), %g1 - jmpl %g1 + %lo(value), %g0 - nop */ - write_be32 (dso, rela->r_offset, 0x03000000 | ((value >> 10) & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, 0x81c06000 | (value & 0x3ff)); - write_be32 (dso, rela->r_offset + 8, 0x01000000); - } -} - -static int -sparc_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (GELF_R_TYPE (rela->r_info) == R_SPARC_NONE) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE) - { - /* 32-bit SPARC handles RELATIVE relocs as - *(int *)rela->r_offset += l_addr + rela->r_addend. - RELATIVE relocs against .got traditionally used to have the - addend in memory pointed by r_offset and 0 r_addend, - other RELATIVE relocs and more recent .got RELATIVE relocs - too have 0 in memory and non-zero r_addend. For prelinking, - we need the value in memory to be already relocated for - l_addr == 0 case, so we have to make sure r_addend will be 0. */ - if (rela->r_addend == 0) - return 0; - value = read_ube32 (dso, rela->r_offset); - value += rela->r_addend; - rela->r_addend = 0; - write_be32 (dso, rela->r_offset, value); - /* Tell prelink_rela routine it should update the relocation. */ - return 2; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_GLOB_DAT: - case R_SPARC_32: - case R_SPARC_UA32: - write_be32 (dso, rela->r_offset, value); - break; - case R_SPARC_JMP_SLOT: - sparc_fixup_plt (dso, rela, value); - break; - case R_SPARC_8: - write_8 (dso, rela->r_offset, value); - break; - case R_SPARC_16: - case R_SPARC_UA16: - write_be16 (dso, rela->r_offset, value); - break; - case R_SPARC_LO10: - write_be32 (dso, rela->r_offset, - (value & 0x3ff) | (read_ube32 (dso, rela->r_offset) & ~0x3ff)); - break; - case R_SPARC_HI22: - write_be32 (dso, rela->r_offset, - ((value >> 10) & 0x3fffff) - | (read_ube32 (dso, rela->r_offset) & 0xffc00000)); - break; - case R_SPARC_DISP8: - write_8 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_DISP16: - write_be16 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_DISP32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_WDISP30: - write_be32 (dso, rela->r_offset, - (((value - rela->r_offset) >> 2) & 0x3fffffff) - | (read_ube32 (dso, rela->r_offset) & 0xc0000000)); - break; - case R_SPARC_TLS_DTPOFF32: - write_be32 (dso, rela->r_offset, value + rela->r_addend); - break; - /* DTPMOD32 and TPOFF32 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_SPARC_TLS_DTPMOD32: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_SPARC_TLS_DTPMOD32 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_SPARC_TLS_TPOFF32: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - value + rela->r_addend - info->resolvetls->offset); - break; - case R_SPARC_TLS_LE_HIX22: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | (((~(value + rela->r_addend - info->resolvetls->offset)) - >> 10) & 0x3fffff)); - break; - case R_SPARC_TLS_LE_LOX10: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00 - | ((value + rela->r_addend - info->resolvetls->offset) - & 0x3ff)); - break; - case R_SPARC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sparc_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_32: - case R_SPARC_UA32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_SPARC_16: - case R_SPARC_UA16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_SPARC_8: - buf_write_8 (buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -sparc_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -sparc_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_NONE: - break; - case R_SPARC_DISP32: - value -= rela->r_offset; - case R_SPARC_GLOB_DAT: - case R_SPARC_32: - case R_SPARC_UA32: - buf_write_be32 (buf, value); - break; - case R_SPARC_DISP16: - value -= rela->r_offset; - case R_SPARC_16: - case R_SPARC_UA16: - buf_write_be16 (buf, value); - break; - case R_SPARC_DISP8: - value -= rela->r_offset; - case R_SPARC_8: - buf_write_8 (buf, value); - break; - case R_SPARC_LO10: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x3ff) | (value & 0x3ff)); - break; - case R_SPARC_HI22: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xffc00000) - | ((value >> 10) & 0x3fffff)); - break; - case R_SPARC_WDISP30: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xc0000000) - | (((value - rela->r_offset) >> 2) & 0x3fffffff)); - break; - case R_SPARC_RELATIVE: - error (0, 0, "%s: R_SPARC_RELATIVE in ET_EXEC object?", - info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -sparc_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - int r_type; - - if (GELF_R_TYPE (rela->r_info) == R_SPARC_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_SPARC_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - if (info->curtls == NULL) - return 0; - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD32 and TPOFF32 relocs need conflicts. */ - case R_SPARC_TLS_DTPMOD32: - case R_SPARC_TLS_TPOFF32: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - break; - default: - return 0; - } - value = 0; - } - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on SPARC yet", - dso->filename); - return 1; - } - else - { - /* DTPOFF32 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_SPARC_TLS_DTPOFF32 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - value += rela->r_addend; - r_type = GELF_R_TYPE (rela->r_info); - switch (r_type) - { - case R_SPARC_DISP32: - value -= rela->r_offset; - case R_SPARC_GLOB_DAT: - case R_SPARC_32: - r_type = R_SPARC_32; - break; - case R_SPARC_DISP16: - value -= rela->r_offset; - case R_SPARC_16: - r_type = R_SPARC_16; - break; - case R_SPARC_DISP8: - value -= rela->r_offset; - case R_SPARC_8: - r_type = R_SPARC_8; - break; - /* Attempt to transform all reloc which read-modify-write into - simple writes. */ - case R_SPARC_LO10: - value = (read_ube32 (dso, rela->r_offset) & ~0x3ff) | (value & 0x3ff); - r_type = R_SPARC_32; - break; - case R_SPARC_HI22: - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | ((value >> 10) & 0x3fffff); - r_type = R_SPARC_32; - break; - case R_SPARC_WDISP30: - value = (read_ube32 (dso, rela->r_offset) & 0xc0000000) - | (((value - rela->r_offset) >> 2) & 0x3fffffff); - r_type = R_SPARC_32; - break; - case R_SPARC_UA16: - case R_SPARC_UA32: - case R_SPARC_JMP_SLOT: - break; - case R_SPARC_TLS_DTPMOD32: - case R_SPARC_TLS_DTPOFF32: - case R_SPARC_TLS_TPOFF32: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - r_type = R_SPARC_32; - tls = conflict ? conflict->lookup.tls : info->curtls; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_TLS_DTPMOD32: - value = tls->modid; - break; - case R_SPARC_TLS_DTPOFF32: - break; - case R_SPARC_TLS_TPOFF32: - value -= tls->offset; - break; - case R_SPARC_TLS_LE_HIX22: - value -= tls->offset; - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | (((~value) >> 10) & 0x3fffff); - break; - case R_SPARC_TLS_LE_LOX10: - value -= tls->offset; - value = (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00 - | (value & 0x3ff); - break; - } - break; - default: - error (0, 0, "%s: Unknown Sparc relocation type %d", dso->filename, - r_type); - return 1; - } - ret->r_info = GELF_R_INFO (0, r_type); - ret->r_addend = (Elf32_Sword) value; - return 0; -} - -static int -sparc_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -sparc_arch_prelink (struct prelink_info *info) -{ - return 0; -} - -static int -sparc_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_NONE: - return 0; - case R_SPARC_RELATIVE: - /* 32-bit SPARC handles RELATIVE relocs as - *(int *)rela->r_offset += l_addr + rela->r_addend. - RELATIVE relocs against .got traditionally used to have the - addend in memory pointed by r_offset and 0 r_addend, - other RELATIVE relocs and more recent RELATIVE relocs have 0 - in memory and non-zero r_addend. - Always store 0 to memory when doing undo. */ - assert (rela->r_addend == 0); - rela->r_addend = (Elf32_Sword) read_ube32 (dso, rela->r_offset); - write_be32 (dso, rela->r_offset, 0); - /* Tell undo_prelink_rela routine it should update the - relocation. */ - return 2; - case R_SPARC_GLOB_DAT: - case R_SPARC_32: - case R_SPARC_UA32: - case R_SPARC_DISP32: - case R_SPARC_TLS_DTPMOD32: - case R_SPARC_TLS_DTPOFF32: - case R_SPARC_TLS_TPOFF32: - write_be32 (dso, rela->r_offset, 0); - break; - case R_SPARC_JMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - if (sec != -1) - { - /* sethi .-.plt, %g1 - b,a .plt+0 */ - write_be32 (dso, rela->r_offset, - 0x03000000 - | ((rela->r_offset - dso->shdr[sec].sh_addr) - & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, - 0x30800000 - | (((dso->shdr[sec].sh_addr - rela->r_offset - 4) >> 2) - & 0x3fffff)); - } - break; - case R_SPARC_8: - case R_SPARC_DISP8: - write_8 (dso, rela->r_offset, 0); - break; - case R_SPARC_16: - case R_SPARC_UA16: - case R_SPARC_DISP16: - write_be16 (dso, rela->r_offset, 0); - break; - case R_SPARC_LO10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0x3ff); - break; - case R_SPARC_TLS_LE_LOX10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffffe000); - break; - case R_SPARC_HI22: - case R_SPARC_TLS_LE_HIX22: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffc00000); - break; - case R_SPARC_WDISP30: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xc0000000); - break; - case R_SPARC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sparc_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_SPARC_8: - case R_SPARC_DISP8: - return 1; - case R_SPARC_16: - case R_SPARC_DISP16: - case R_SPARC_UA16: - return 2; - default: - break; - } - return 4; -} - -static int -sparc_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_SPARC_COPY: return RTYPE_CLASS_COPY; - case R_SPARC_JMP_SLOT: return RTYPE_CLASS_PLT; - case R_SPARC_TLS_DTPMOD32: - case R_SPARC_TLS_DTPOFF32: - case R_SPARC_TLS_TPOFF32: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(sparc) = { - .name = "SPARC", - .class = ELFCLASS32, - .machine = EM_SPARC, - .alternate_machine = { EM_SPARC32PLUS }, - .R_JMP_SLOT = R_SPARC_JMP_SLOT, - .R_COPY = R_SPARC_COPY, - .R_RELATIVE = R_SPARC_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib/ld-linux.so.2", - .adjust_dyn = sparc_adjust_dyn, - .adjust_rel = sparc_adjust_rel, - .adjust_rela = sparc_adjust_rela, - .prelink_rel = sparc_prelink_rel, - .prelink_rela = sparc_prelink_rela, - .prelink_conflict_rel = sparc_prelink_conflict_rel, - .prelink_conflict_rela = sparc_prelink_conflict_rela, - .apply_conflict_rela = sparc_apply_conflict_rela, - .apply_rel = sparc_apply_rel, - .apply_rela = sparc_apply_rela, - .rel_to_rela = sparc_rel_to_rela, - .need_rel_to_rela = sparc_need_rel_to_rela, - .reloc_size = sparc_reloc_size, - .reloc_class = sparc_reloc_class, - .max_reloc_size = 4, - .arch_prelink = sparc_arch_prelink, - .undo_prelink_rela = sparc_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x70000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x71000000LL, - .mmap_end = 0x80000000LL, - .max_page_size = 0x10000, - .page_size = 0x1000 -}; diff --git a/trunk/src/arch-sparc64.c b/trunk/src/arch-sparc64.c deleted file mode 100644 index aee4601..0000000 --- a/trunk/src/arch-sparc64.c +++ /dev/null @@ -1,849 +0,0 @@ -/* Copyright (C) 2001, 2002, 2004, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -#define SPARC64_R_TYPE(info) (GELF_R_TYPE (info) & 0xff) - -static int -sparc64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".got")) - { - Elf64_Addr data; - - data = read_ube64 (dso, dso->shdr[i].sh_addr); - /* .got[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_be64 (dso, dso->shdr[i].sh_addr, data + adjust); - break; - } - } - - return 0; -} - -static int -sparc64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_RELATIVE) - { - if (rela->r_addend >= start) - rela->r_addend += adjust; - } - else if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_JMP_SLOT - && rela->r_addend) - { - /* .plt[32768+] r_addends are -some_address_in_plt_section. */ - if ((- rela->r_addend) >= start) - rela->r_addend -= adjust; - } - return 0; -} - -static int -sparc64_prelink_rel (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename); - return 1; -} - -static void -sparc64_fixup_plt (DSO *dso, GElf_Rela *rela, GElf_Addr value) -{ - Elf64_Sxword disp = value - rela->r_offset; - - if (rela->r_addend) - { - /* .plt[32768+] */ - write_be64 (dso, rela->r_offset, value); - } - else if (disp >= -0x800000 && disp < 0x800000) - { - /* b,a value - nop - nop */ - write_be32 (dso, rela->r_offset, 0x30800000 | ((disp >> 2) & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, 0x01000000); - write_be32 (dso, rela->r_offset + 8, 0x01000000); - } - else if (! (value >> 32)) - { - /* sethi %hi(value), %g1 - jmpl %g1 + %lo(value), %g0 - nop */ - write_be32 (dso, rela->r_offset, 0x03000000 | ((value >> 10) & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, 0x81c06000 | (value & 0x3ff)); - write_be32 (dso, rela->r_offset + 8, 0x01000000); - } - else if ((rela->r_offset + 4 > value - && ((rela->r_offset - value) >> 31) == 0) - || (value > rela->r_offset + 4 - && ((value - rela->r_offset - 4) >> 31) == 0)) - { - /* mov %o7, %g1 - call value - mov %g1, %o7 */ - write_be32 (dso, rela->r_offset, 0x8210000f); - write_be32 (dso, rela->r_offset + 4, 0x40000000 - | (((value - rela->r_offset - 4) >> 2) & 0x3fffffff)); - write_be32 (dso, rela->r_offset + 8, 0x9e100001); - } - else - { - unsigned int csts[4]; - int i = 0; - - /* sethi %hh(value), %g1 - sethi %lm(value), %g5 - or %g1, %hm(value), %g1 - or %g5, %lo(value), %g5 - sllx %g1, 32, %g1 - jmpl %g1 + %g5, %g0 - nop */ - - csts[0] = value >> 42; - csts[1] = (value >> 32) & 0x3ff; - csts[2] = (value >> 10) & 0x3fffff; - csts[3] = value & 0x3ff; - write_be32 (dso, rela->r_offset, 0x03000000 | csts[0]); - write_be32 (dso, rela->r_offset + 4, 0x0b000000 | csts[2]); - /* Sparc64 shared libs are often 0xfffff800XXXXXXXX, so optimize - for this common case. */ - if (csts[1] == 0) - write_be32 (dso, rela->r_offset + 8, 0x83287020); - else - write_be32 (dso, rela->r_offset + 8, 0x82106000 | csts[1]); - write_be32 (dso, rela->r_offset + 12, 0x8a116000 | csts[3]); - if (csts[1] != 0) - write_be32 (dso, rela->r_offset + 16, 0x83287020), i = 4; - write_be32 (dso, rela->r_offset + 16 + i, 0x81c04005); - write_be32 (dso, rela->r_offset + 20 + i, 0x01000000); - } -} - -static int -sparc64_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso = info->dso; - GElf_Addr value; - - if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_NONE) - return 0; - else if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_RELATIVE) - { - /* 64-bit SPARC handles RELATIVE relocs as - *(long *)rela->r_offset = l_addr + rela->r_addend, - so we must update the memory. */ - write_be64 (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - SPARC64_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (SPARC64_R_TYPE (rela->r_info)) - { - case R_SPARC_GLOB_DAT: - case R_SPARC_64: - case R_SPARC_UA64: - write_be64 (dso, rela->r_offset, value); - break; - case R_SPARC_32: - case R_SPARC_UA32: - write_be32 (dso, rela->r_offset, value); - break; - case R_SPARC_JMP_SLOT: - sparc64_fixup_plt (dso, rela, value); - break; - case R_SPARC_8: - write_8 (dso, rela->r_offset, value); - break; - case R_SPARC_16: - case R_SPARC_UA16: - write_be16 (dso, rela->r_offset, value); - break; - case R_SPARC_LO10: - write_be32 (dso, rela->r_offset, - (value & 0x3ff) | (read_ube32 (dso, rela->r_offset) & ~0x3ff)); - break; - case R_SPARC_LM22: - case R_SPARC_HI22: - write_be32 (dso, rela->r_offset, - ((value >> 10) & 0x3fffff) - | (read_ube32 (dso, rela->r_offset) & 0xffc00000)); - break; - case R_SPARC_DISP8: - write_8 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_DISP16: - write_be16 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_DISP32: - write_be32 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_DISP64: - write_be64 (dso, rela->r_offset, value - rela->r_offset); - break; - case R_SPARC_WDISP30: - write_be32 (dso, rela->r_offset, - (((value - rela->r_offset) >> 2) & 0x3fffffff) - | (read_ube32 (dso, rela->r_offset) & 0xc0000000)); - break; - case R_SPARC_TLS_DTPOFF64: - write_be64 (dso, rela->r_offset, value + rela->r_addend); - break; - /* DTPMOD64 and TPOFF64 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_SPARC_TLS_DTPMOD64: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_SPARC_TLS_DTPMOD64 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_SPARC_TLS_TPOFF64: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be64 (dso, rela->r_offset, - value + rela->r_addend - info->resolvetls->offset); - break; - case R_SPARC_TLS_LE_HIX22: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | (((~(value + rela->r_addend - info->resolvetls->offset)) - >> 10) & 0x3fffff)); - break; - case R_SPARC_TLS_LE_LOX10: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_be32 (dso, rela->r_offset, - (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00 - | ((value + rela->r_addend - info->resolvetls->offset) - & 0x3ff)); - break; - case R_SPARC_H44: - write_be32 (dso, rela->r_offset, - ((value >> 22) & 0x3fffff) - | (read_ube32 (dso, rela->r_offset) & 0xffc00000)); - break; - case R_SPARC_M44: - write_be32 (dso, rela->r_offset, - ((value >> 12) & 0x3ff) - | (read_ube32 (dso, rela->r_offset) & ~0x3ff)); - break; - case R_SPARC_L44: - write_be32 (dso, rela->r_offset, - (value & 0xfff) | (read_ube32 (dso, rela->r_offset) & ~0xfff)); - break; - case R_SPARC_HH22: - write_be32 (dso, rela->r_offset, - ((value >> 42) & 0x3fffff) - | (read_ube32 (dso, rela->r_offset) & 0xffc00000)); - break; - case R_SPARC_HM10: - write_be32 (dso, rela->r_offset, - ((value >> 32) & 0x3ff) - | (read_ube32 (dso, rela->r_offset) & ~0x3ff)); - break; - case R_SPARC_OLO10: - write_be32 (dso, rela->r_offset, - (((value & 0x3ff) + (GELF_R_TYPE (rela->r_info) >> 8)) & 0x1fff) - | (read_ube32 (dso, rela->r_offset) & ~0x1fff)); - break; - case R_SPARC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename, - (int) SPARC64_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sparc64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - switch (SPARC64_R_TYPE (rela->r_info)) - { - case R_SPARC_64: - case R_SPARC_UA64: - buf_write_be64 (buf, rela->r_addend); - break; - case R_SPARC_32: - case R_SPARC_UA32: - buf_write_be32 (buf, rela->r_addend); - break; - case R_SPARC_16: - case R_SPARC_UA16: - buf_write_be16 (buf, rela->r_addend); - break; - case R_SPARC_8: - buf_write_8 (buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -sparc64_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -sparc64_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - SPARC64_R_TYPE (rela->r_info)); - value += rela->r_addend; - switch (SPARC64_R_TYPE (rela->r_info)) - { - case R_SPARC_NONE: - break; - case R_SPARC_DISP64: - value -= rela->r_offset; - case R_SPARC_GLOB_DAT: - case R_SPARC_64: - case R_SPARC_UA64: - buf_write_be64 (buf, value); - break; - case R_SPARC_DISP32: - value -= rela->r_offset; - case R_SPARC_32: - case R_SPARC_UA32: - buf_write_be32 (buf, value); - break; - case R_SPARC_DISP16: - value -= rela->r_offset; - case R_SPARC_16: - case R_SPARC_UA16: - buf_write_be16 (buf, value); - break; - case R_SPARC_DISP8: - value -= rela->r_offset; - case R_SPARC_8: - buf_write_8 (buf, value); - break; - case R_SPARC_LO10: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x3ff) | (value & 0x3ff)); - break; - case R_SPARC_LM22: - case R_SPARC_HI22: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xffc00000) - | ((value >> 10) & 0x3fffff)); - break; - case R_SPARC_WDISP30: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xc0000000) - | (((value - rela->r_offset) >> 2) & 0x3fffffff)); - break; - case R_SPARC_H44: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xffc00000) - | ((value >> 22) & 0x3fffff)); - break; - case R_SPARC_M44: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x3ff) - | ((value >> 12) & 0x3ff)); - break; - case R_SPARC_L44: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0xfff) | (value & 0xfff)); - break; - case R_SPARC_HH22: - buf_write_be32 (buf, (buf_read_ube32 (buf) & 0xffc00000) - | ((value >> 42) & 0x3fffff)); - break; - case R_SPARC_HM10: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x3ff) - | ((value >> 32) & 0x3ff)); - break; - case R_SPARC_OLO10: - buf_write_be32 (buf, (buf_read_ube32 (buf) & ~0x1fff) - | (((value & 0x3ff) - + (GELF_R_TYPE (rela->r_info) >> 8)) & 0x1fff)); - break; - case R_SPARC_RELATIVE: - error (0, 0, "%s: R_SPARC_RELATIVE in ET_EXEC object?", - info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -sparc64_prelink_conflict_rel (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc64_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - int r_type; - - if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_RELATIVE - || SPARC64_R_TYPE (rela->r_info) == R_SPARC_NONE - || info->dso == dso) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - SPARC64_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - if (info->curtls == NULL) - return 0; - switch (SPARC64_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD64 and TPOFF64 relocs need conflicts. */ - case R_SPARC_TLS_DTPMOD64: - case R_SPARC_TLS_TPOFF64: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - break; - default: - return 0; - } - value = 0; - } - else if (conflict->ifunc) - { - error (0, 0, "%s: STT_GNU_IFUNC not handled on SPARC64 yet", - dso->filename); - return 1; - } - else - { - /* DTPOFF64 wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (SPARC64_R_TYPE (rela->r_info) == R_SPARC_TLS_DTPOFF64 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - value += rela->r_addend; - r_type = SPARC64_R_TYPE (rela->r_info); - switch (r_type) - { - case R_SPARC_DISP64: - value -= rela->r_offset; - case R_SPARC_GLOB_DAT: - case R_SPARC_64: - r_type = R_SPARC_64; - break; - case R_SPARC_DISP32: - value -= rela->r_offset; - case R_SPARC_32: - r_type = R_SPARC_32; - break; - case R_SPARC_DISP16: - value -= rela->r_offset; - case R_SPARC_16: - r_type = R_SPARC_16; - break; - case R_SPARC_DISP8: - value -= rela->r_offset; - case R_SPARC_8: - r_type = R_SPARC_8; - break; - /* Attempt to transform all reloc which read-modify-write into - simple writes. */ - case R_SPARC_LO10: - value = (read_ube32 (dso, rela->r_offset) & ~0x3ff) | (value & 0x3ff); - r_type = R_SPARC_32; - break; - case R_SPARC_LM22: - case R_SPARC_HI22: - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | ((value >> 10) & 0x3fffff); - r_type = R_SPARC_32; - break; - case R_SPARC_WDISP30: - value = (read_ube32 (dso, rela->r_offset) & 0xc0000000) - | (((value - rela->r_offset) >> 2) & 0x3fffffff); - r_type = R_SPARC_32; - break; - case R_SPARC_H44: - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | ((value >> 22) & 0x3fffff); - r_type = R_SPARC_32; - break; - case R_SPARC_M44: - value = (read_ube32 (dso, rela->r_offset) & ~0x3ff) - | ((value >> 12) & 0x3ff); - r_type = R_SPARC_32; - break; - case R_SPARC_L44: - value = (read_ube32 (dso, rela->r_offset) & ~0xfff) | (value & 0xfff); - r_type = R_SPARC_32; - break; - case R_SPARC_HH22: - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | ((value >> 42) & 0x3fffff); - r_type = R_SPARC_32; - break; - case R_SPARC_HM10: - value = (read_ube32 (dso, rela->r_offset) & ~0x3ff) - | ((value >> 32) & 0x3ff); - r_type = R_SPARC_32; - break; - case R_SPARC_OLO10: - value = (read_ube32 (dso, rela->r_offset) & ~0x1fff) - | (((value & 0x3ff) + (GELF_R_TYPE (rela->r_info) >> 8)) & 0x1fff); - r_type = R_SPARC_32; - break; - case R_SPARC_JMP_SLOT: - if (rela->r_addend) - r_type = R_SPARC_64; - break; - case R_SPARC_UA16: - case R_SPARC_UA32: - case R_SPARC_UA64: - break; - case R_SPARC_TLS_DTPMOD64: - case R_SPARC_TLS_DTPOFF64: - case R_SPARC_TLS_TPOFF64: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - switch (r_type) - { - case R_SPARC_TLS_DTPMOD64: - r_type = R_SPARC_64; - value = tls->modid; - break; - case R_SPARC_TLS_DTPOFF64: - r_type = R_SPARC_64; - break; - case R_SPARC_TLS_TPOFF64: - r_type = R_SPARC_64; - value -= tls->offset; - break; - case R_SPARC_TLS_LE_HIX22: - r_type = R_SPARC_32; - value -= tls->offset; - value = (read_ube32 (dso, rela->r_offset) & 0xffc00000) - | (((~value) >> 10) & 0x3fffff); - break; - case R_SPARC_TLS_LE_LOX10: - r_type = R_SPARC_32; - value -= tls->offset; - value = (read_ube32 (dso, rela->r_offset) & 0xffffe000) | 0x1c00 - | (value & 0x3ff); - break; - } - break; - default: - error (0, 0, "%s: Unknown Sparc relocation type %d", dso->filename, - r_type); - return 1; - } - ret->r_info = GELF_R_INFO (0, r_type); - ret->r_addend = value; - return 0; -} - -static int -sparc64_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: Sparc doesn't support REL relocs", dso->filename); - return 1; -} - -static int -sparc64_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -sparc64_arch_prelink (struct prelink_info *info) -{ - return 0; -} - -static int -sparc64_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_SPARC_NONE: - break; - case R_SPARC_JMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - if (sec != -1) - { - if (rela->r_addend == 0) - { - /* sethi .-.plt, %g1 - b,a %xcc, .plt+0x20 */ - write_be32 (dso, rela->r_offset, - 0x03000000 - | ((rela->r_offset - dso->shdr[sec].sh_addr) - & 0x3fffff)); - write_be32 (dso, rela->r_offset + 4, - 0x30680000 - | (((dso->shdr[sec].sh_addr + 32 - - rela->r_offset - 4) >> 2) - & 0x7ffff)); - write_be32 (dso, rela->r_offset + 8, 0x01000000); - write_be32 (dso, rela->r_offset + 12, 0x01000000); - write_be32 (dso, rela->r_offset + 16, 0x01000000); - write_be32 (dso, rela->r_offset + 20, 0x01000000); - write_be32 (dso, rela->r_offset + 24, 0x01000000); - write_be32 (dso, rela->r_offset + 28, 0x01000000); - } - else - { - GElf_Addr slot = ((rela->r_offset + 0x400 - - dso->shdr[sec].sh_addr) - / 0x1400) * 0x1400 - + dso->shdr[sec].sh_addr - 0x400; - /* slot+12 contains: ldx [%o7 + X], %g1 */ - GElf_Addr ptr = slot + (read_ube32 (dso, slot + 12) & 0xfff) + 4; - - write_be64 (dso, rela->r_offset, - dso->shdr[sec].sh_addr - - (slot + ((rela->r_offset - ptr) / 8) * 24 + 4)); - } - } - break; - case R_SPARC_RELATIVE: - case R_SPARC_GLOB_DAT: - case R_SPARC_64: - case R_SPARC_UA64: - case R_SPARC_DISP64: - case R_SPARC_TLS_DTPMOD64: - case R_SPARC_TLS_DTPOFF64: - case R_SPARC_TLS_TPOFF64: - write_be64 (dso, rela->r_offset, 0); - break; - case R_SPARC_32: - case R_SPARC_UA32: - case R_SPARC_DISP32: - write_be32 (dso, rela->r_offset, 0); - break; - case R_SPARC_8: - case R_SPARC_DISP8: - write_8 (dso, rela->r_offset, 0); - break; - case R_SPARC_16: - case R_SPARC_UA16: - case R_SPARC_DISP16: - write_be16 (dso, rela->r_offset, 0); - break; - case R_SPARC_LO10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0x3ff); - break; - case R_SPARC_LM22: - case R_SPARC_HI22: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffc00000); - break; - case R_SPARC_WDISP30: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xc0000000); - break; - case R_SPARC_H44: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffc00000); - break; - case R_SPARC_M44: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0x3ff); - break; - case R_SPARC_L44: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0xfff); - break; - case R_SPARC_HH22: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffc00000); - break; - case R_SPARC_HM10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0x3ff); - break; - case R_SPARC_OLO10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & ~0x1fff); - break; - case R_SPARC_TLS_LE_LOX10: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffffe000); - break; - case R_SPARC_TLS_LE_HIX22: - write_be32 (dso, rela->r_offset, - read_ube32 (dso, rela->r_offset) & 0xffc00000); - break; - case R_SPARC_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_SPARC_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown sparc relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -sparc64_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_SPARC_8: - case R_SPARC_DISP8: - return 1; - case R_SPARC_16: - case R_SPARC_DISP16: - case R_SPARC_UA16: - return 2; - case R_SPARC_RELATIVE: - case R_SPARC_64: - case R_SPARC_UA64: - case R_SPARC_GLOB_DAT: - return 8; - default: - break; - } - return 4; -} - -static int -sparc64_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_SPARC_COPY: return RTYPE_CLASS_COPY; - case R_SPARC_JMP_SLOT: return RTYPE_CLASS_PLT; - case R_SPARC_TLS_DTPMOD64: - case R_SPARC_TLS_DTPOFF64: - case R_SPARC_TLS_TPOFF64: - case R_SPARC_TLS_LE_HIX22: - case R_SPARC_TLS_LE_LOX10: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(sparc64) = { - .name = "SPARC", - .class = ELFCLASS64, - .machine = EM_SPARCV9, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_SPARC_JMP_SLOT, - .R_COPY = R_SPARC_COPY, - .R_RELATIVE = R_SPARC_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib64/ld-linux.so.2", - .adjust_dyn = sparc64_adjust_dyn, - .adjust_rel = sparc64_adjust_rel, - .adjust_rela = sparc64_adjust_rela, - .prelink_rel = sparc64_prelink_rel, - .prelink_rela = sparc64_prelink_rela, - .prelink_conflict_rel = sparc64_prelink_conflict_rel, - .prelink_conflict_rela = sparc64_prelink_conflict_rela, - .apply_conflict_rela = sparc64_apply_conflict_rela, - .apply_rel = sparc64_apply_rel, - .apply_rela = sparc64_apply_rela, - .rel_to_rela = sparc64_rel_to_rela, - .need_rel_to_rela = sparc64_need_rel_to_rela, - .reloc_size = sparc64_reloc_size, - .reloc_class = sparc64_reloc_class, - .max_reloc_size = 8, - .arch_prelink = sparc64_arch_prelink, - .undo_prelink_rela = sparc64_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0xfffff80100000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0xfffff80101000000LL, - /* If we need yet more space for shared libraries, we can of course - expand, but limiting all DSOs into 4 GB means stack overflows - jumping to shared library functions is much harder (there is - '\0' byte in the address before the bytes that matter). */ - .mmap_end = 0xfffff80200000000LL, - .max_page_size = 0x100000, - .page_size = 0x2000 -}; diff --git a/trunk/src/arch-x86_64.c b/trunk/src/arch-x86_64.c deleted file mode 100644 index dae66cd..0000000 --- a/trunk/src/arch-x86_64.c +++ /dev/null @@ -1,643 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - Copyright (C) 2011 Wind River Systems, Inc. - x32 support by Mark Hatle <mark.hatle@windriver.com> - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> - -#include "prelink.h" - -/* The x32 ABI: https://sites.google.com/site/x32abi/documents/abi.pdf - * documents a "class" value for specific reads and writes. All this - * indicates is that we should be using the ELFCLASS to determine if - * this should be a 32/64 bit read/write. (See table 4.9) - * - * We emulate this behavior below... - */ -#define read_uleclass(DSO, ADDR) \ -( gelf_getclass(DSO->elf) == ELFCLASS32 ? read_ule32(DSO, ADDR) : read_ule64(DSO, ADDR) ) - -#define write_leclass(DSO, ADDR, VAL) \ -( gelf_getclass(DSO->elf) == ELFCLASS32 ? write_le32(DSO, ADDR, VAL) : write_le64(DSO, ADDR, VAL) ) - -#define buf_write_leclass(DSO, BUF, VAL) \ -( gelf_getclass(DSO->elf) == ELFCLASS32 ? buf_write_le32(BUF, VAL) : buf_write_le64(BUF, VAL) ) - -static int -x86_64_adjust_dyn (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust) -{ - if (dyn->d_tag == DT_PLTGOT) - { - int sec = addr_to_sec (dso, dyn->d_un.d_ptr); - Elf64_Addr data; - - if (sec == -1) - return 0; - - data = read_ule64 (dso, dyn->d_un.d_ptr); - /* If .got.plt[0] points to _DYNAMIC, it needs to be adjusted. */ - if (data == dso->shdr[n].sh_addr && data >= start) - write_le64 (dso, dyn->d_un.d_ptr, data + adjust); - - data = read_ule64 (dso, dyn->d_un.d_ptr + 8); - /* If .got.plt[1] points to .plt + 0x16, it needs to be adjusted. */ - if (data && data >= start) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (data == dso->shdr[i].sh_addr + 0x16 - && dso->shdr[i].sh_type == SHT_PROGBITS - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), ".plt") == 0) - { - write_le64 (dso, dyn->d_un.d_ptr + 8, data + adjust); - break; - } - } - } - return 0; -} - -static int -x86_64_adjust_rel (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust) -{ - error (0, 0, "%s: X86-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -x86_64_adjust_rela (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust) -{ - Elf64_Addr addr; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_RELATIVE: - if (rela->r_addend >= start) - { - if (read_uleclass (dso, rela->r_offset) == rela->r_addend) - write_leclass (dso, rela->r_offset, rela->r_addend + adjust); - rela->r_addend += adjust; - } - break; - case R_X86_64_IRELATIVE: - if (rela->r_addend >= start) - rela->r_addend += adjust; - /* FALLTHROUGH */ - case R_X86_64_JUMP_SLOT: - addr = read_uleclass (dso, rela->r_offset); - if (addr >= start) - write_leclass (dso, rela->r_offset, addr + adjust); - break; - } - return 0; -} - -static int -x86_64_prelink_rel (struct prelink_info *info, GElf_Rel *rel, GElf_Addr reladdr) -{ - error (0, 0, "%s: X86-64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -x86_64_prelink_rela (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr) -{ - DSO *dso; - GElf_Addr value; - - dso = info->dso; - if (GELF_R_TYPE (rela->r_info) == R_X86_64_NONE - || GELF_R_TYPE (rela->r_info) == R_X86_64_IRELATIVE) - return 0; - else if (GELF_R_TYPE (rela->r_info) == R_X86_64_RELATIVE) - { - write_leclass (dso, rela->r_offset, rela->r_addend); - return 0; - } - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - write_leclass (dso, rela->r_offset, value + rela->r_addend); - break; - case R_X86_64_64: - write_le64 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_X86_64_32: - write_le32 (dso, rela->r_offset, value + rela->r_addend); - break; - case R_X86_64_PC32: - write_le32 (dso, rela->r_offset, value + rela->r_addend - rela->r_offset); - break; - case R_X86_64_DTPOFF64: - write_le64 (dso, rela->r_offset, value + rela->r_addend); - break; - /* DTPMOD64 and TPOFF64 is impossible to predict in shared libraries - unless prelink sets the rules. */ - case R_X86_64_DTPMOD64: - if (dso->ehdr.e_type == ET_EXEC) - { - error (0, 0, "%s: R_X86_64_DTPMOD64 reloc in executable?", - dso->filename); - return 1; - } - break; - case R_X86_64_TPOFF64: - if (dso->ehdr.e_type == ET_EXEC && info->resolvetls) - write_le64 (dso, rela->r_offset, - value + rela->r_addend - info->resolvetls->offset); - break; - case R_X86_64_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_X86_64_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown X86-64 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -x86_64_apply_conflict_rela (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr) -{ - GElf_Rela *ret; - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - buf_write_leclass (info->dso, buf, rela->r_addend); - break; - case R_X86_64_64: - buf_write_le64 (buf, rela->r_addend); - break; - case R_X86_64_IRELATIVE: - if (dest_addr == 0) - return 5; - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = dest_addr; - ret->r_info = GELF_R_INFO (0, R_X86_64_IRELATIVE); - ret->r_addend = rela->r_addend; - break; - case R_X86_64_32: - buf_write_le32 (buf, rela->r_addend); - break; - default: - abort (); - } - return 0; -} - -static int -x86_64_apply_rel (struct prelink_info *info, GElf_Rel *rel, char *buf) -{ - error (0, 0, "%s: X86-64 doesn't support REL relocs", info->dso->filename); - return 1; -} - -static int -x86_64_apply_rela (struct prelink_info *info, GElf_Rela *rela, char *buf) -{ - GElf_Addr value; - - value = info->resolve (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_NONE: - break; - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - buf_write_leclass (info->dso, buf, value + rela->r_addend); - break; - case R_X86_64_64: - buf_write_le64 (buf, value + rela->r_addend); - break; - case R_X86_64_32: - buf_write_le32 (buf, value + rela->r_addend); - break; - case R_X86_64_PC32: - buf_write_le32 (buf, value + rela->r_addend - rela->r_offset); - break; - case R_X86_64_COPY: - abort (); - case R_X86_64_RELATIVE: - error (0, 0, "%s: R_X86_64_RELATIVE in ET_EXEC object?", info->dso->filename); - return 1; - default: - return 1; - } - return 0; -} - -static int -x86_64_prelink_conflict_rel (DSO *dso, struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr) -{ - error (0, 0, "%s: X86-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -x86_64_prelink_conflict_rela (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr) -{ - GElf_Addr value; - struct prelink_conflict *conflict; - struct prelink_tls *tls; - GElf_Rela *ret; - - if (GELF_R_TYPE (rela->r_info) == R_X86_64_RELATIVE - || GELF_R_TYPE (rela->r_info) == R_X86_64_NONE) - /* Fast path: nothing to do. */ - return 0; - conflict = prelink_conflict (info, GELF_R_SYM (rela->r_info), - GELF_R_TYPE (rela->r_info)); - if (conflict == NULL) - { - switch (GELF_R_TYPE (rela->r_info)) - { - /* Even local DTPMOD and TPOFF relocs need conflicts. */ - case R_X86_64_DTPMOD64: - case R_X86_64_TPOFF64: - if (info->curtls == NULL || info->dso == dso) - return 0; - break; - /* Similarly IRELATIVE relocations always need conflicts. */ - case R_X86_64_IRELATIVE: - break; - default: - return 0; - } - value = 0; - } - else if (info->dso == dso && !conflict->ifunc) - return 0; - else - { - /* DTPOFF wants to see only real conflicts, not lookups - with reloc_class RTYPE_CLASS_TLS. */ - if (GELF_R_TYPE (rela->r_info) == R_X86_64_DTPOFF64 - && conflict->lookup.tls == conflict->conflict.tls - && conflict->lookupval == conflict->conflictval) - return 0; - - value = conflict_lookup_value (conflict); - } - ret = prelink_conflict_add_rela (info); - if (ret == NULL) - return 1; - ret->r_offset = rela->r_offset; - ret->r_info = GELF_R_INFO (0, GELF_R_TYPE (rela->r_info)); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_GLOB_DAT: - ret->r_info = GELF_R_INFO (0, (gelf_getclass (dso->elf) == ELFCLASS32 ? R_X86_64_32 : R_X86_64_64)); - /* FALLTHROUGH */ - case R_X86_64_JUMP_SLOT: - case R_X86_64_64: - case R_X86_64_IRELATIVE: - ret->r_addend = value + rela->r_addend; - if (conflict != NULL && conflict->ifunc) - ret->r_info = GELF_R_INFO (0, R_X86_64_IRELATIVE); - break; - case R_X86_64_32: - value += rela->r_addend; - ret->r_addend = value; - break; - case R_X86_64_PC32: - ret->r_addend = value + rela->r_addend - rela->r_offset; - ret->r_info = GELF_R_INFO (0, R_X86_64_32); - break; - case R_X86_64_COPY: - error (0, 0, "R_X86_64_COPY should not be present in shared libraries"); - return 1; - case R_X86_64_DTPMOD64: - case R_X86_64_DTPOFF64: - case R_X86_64_TPOFF64: - if (conflict != NULL - && (conflict->reloc_class != RTYPE_CLASS_TLS - || conflict->lookup.tls == NULL)) - { - error (0, 0, "%s: TLS reloc not resolving to STT_TLS symbol", - dso->filename); - return 1; - } - tls = conflict ? conflict->lookup.tls : info->curtls; - ret->r_info = GELF_R_INFO (0, R_X86_64_64); - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_DTPMOD64: - ret->r_addend = tls->modid; - break; - case R_X86_64_DTPOFF64: - ret->r_addend = value + rela->r_addend; - break; - case R_X86_64_TPOFF64: - ret->r_addend = value + rela->r_addend - tls->offset; - break; - } - break; - - default: - error (0, 0, "%s: Unknown X86-64 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -x86_64_rel_to_rela (DSO *dso, GElf_Rel *rel, GElf_Rela *rela) -{ - error (0, 0, "%s: X86-64 doesn't support REL relocs", dso->filename); - return 1; -} - -static int -x86_64_need_rel_to_rela (DSO *dso, int first, int last) -{ - return 0; -} - -static int -x86_64_arch_prelink (struct prelink_info *info) -{ - DSO *dso; - int i; - - dso = info->dso; - if (dso->info[DT_PLTGOT]) - { - /* Write address of .plt + 0x16 into got[1]. - .plt + 0x16 is what got[3] contains unless prelinking. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf64_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - assert (i < dso->ehdr.e_shnum); - data = dso->shdr[i].sh_addr + 0x16; - write_le64 (dso, dso->info[DT_PLTGOT] + 8, data); - } - - return 0; -} - -static int -x86_64_arch_undo_prelink (DSO *dso) -{ - int i; - - if (dso->info[DT_PLTGOT]) - { - /* Clear got[1] if it contains address of .plt + 0x16. */ - int sec = addr_to_sec (dso, dso->info[DT_PLTGOT]); - Elf64_Addr data; - - if (sec == -1) - return 1; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_PROGBITS - && ! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".plt")) - break; - - if (i == dso->ehdr.e_shnum) - return 0; - data = read_ule64 (dso, dso->info[DT_PLTGOT] + 8); - if (data == dso->shdr[i].sh_addr + 0x16) - write_le64 (dso, dso->info[DT_PLTGOT] + 8, 0); - } - - return 0; -} - -static int -x86_64_undo_prelink_rela (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr) -{ - int sec; - const char *name; - - switch (GELF_R_TYPE (rela->r_info)) - { - case R_X86_64_NONE: - case R_X86_64_RELATIVE: - case R_X86_64_IRELATIVE: - break; - case R_X86_64_JUMP_SLOT: - sec = addr_to_sec (dso, rela->r_offset); - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[sec].sh_name); - if (sec == -1 || (strcmp (name, ".got") && strcmp (name, ".got.plt"))) - { - error (0, 0, "%s: R_X86_64_JUMP_SLOT not pointing into .got section", - dso->filename); - return 1; - } - else - { - Elf64_Addr data = read_uleclass (dso, dso->shdr[sec].sh_addr + 8); - - assert (rela->r_offset >= dso->shdr[sec].sh_addr + 24); - assert (((rela->r_offset - dso->shdr[sec].sh_addr) & 7) == 0); - write_leclass (dso, rela->r_offset, - 2 * (rela->r_offset - dso->shdr[sec].sh_addr - 24) - + data); - } - break; - case R_X86_64_GLOB_DAT: - write_leclass (dso, rela->r_offset, 0); - break; - case R_X86_64_64: - case R_X86_64_DTPMOD64: - case R_X86_64_DTPOFF64: - case R_X86_64_TPOFF64: - write_le64 (dso, rela->r_offset, 0); - break; - case R_X86_64_32: - case R_X86_64_PC32: - write_le32 (dso, rela->r_offset, 0); - break; - case R_X86_64_COPY: - if (dso->ehdr.e_type == ET_EXEC) - /* COPY relocs are handled specially in generic code. */ - return 0; - error (0, 0, "%s: R_X86_64_COPY reloc in shared library?", dso->filename); - return 1; - default: - error (0, 0, "%s: Unknown X86-64 relocation type %d", dso->filename, - (int) GELF_R_TYPE (rela->r_info)); - return 1; - } - return 0; -} - -static int -x86_64_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - case R_X86_64_64: - case R_X86_64_IRELATIVE: - return 8; - default: - return 4; - } -} - -static int -x86_64_x32_reloc_size (int reloc_type) -{ - switch (reloc_type) - { - case R_X86_64_64: - return 8; - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: - case R_X86_64_IRELATIVE: - default: - return 4; - } -} - -static int -x86_64_reloc_class (int reloc_type) -{ - switch (reloc_type) - { - case R_X86_64_COPY: return RTYPE_CLASS_COPY; - case R_X86_64_JUMP_SLOT: return RTYPE_CLASS_PLT; - case R_X86_64_DTPMOD64: - case R_X86_64_DTPOFF64: - case R_X86_64_TPOFF64: - return RTYPE_CLASS_TLS; - default: return RTYPE_CLASS_VALID; - } -} - -PL_ARCH(x32) = { - .name = "x32", - .class = ELFCLASS32, - .machine = EM_X86_64, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_X86_64_JUMP_SLOT, - .R_COPY = R_X86_64_COPY, - .R_RELATIVE = R_X86_64_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/libx32/ld-linux-x32.so.2", - .adjust_dyn = x86_64_adjust_dyn, - .adjust_rel = x86_64_adjust_rel, - .adjust_rela = x86_64_adjust_rela, - .prelink_rel = x86_64_prelink_rel, - .prelink_rela = x86_64_prelink_rela, - .prelink_conflict_rel = x86_64_prelink_conflict_rel, - .prelink_conflict_rela = x86_64_prelink_conflict_rela, - .apply_conflict_rela = x86_64_apply_conflict_rela, - .apply_rel = x86_64_apply_rel, - .apply_rela = x86_64_apply_rela, - .rel_to_rela = x86_64_rel_to_rela, - .need_rel_to_rela = x86_64_need_rel_to_rela, - .reloc_size = x86_64_x32_reloc_size, - .reloc_class = x86_64_reloc_class, - .max_reloc_size = 8, - .arch_prelink = x86_64_arch_prelink, - .arch_undo_prelink = x86_64_arch_undo_prelink, - .undo_prelink_rela = x86_64_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x40000000, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x41000000, - .mmap_end = 0x50000000, - .max_page_size = 0x200000, - .page_size = 0x1000 -}; - -PL_ARCH(x86_64) = { - .name = "x86-64", - .class = ELFCLASS64, - .machine = EM_X86_64, - .alternate_machine = { EM_NONE }, - .R_JMP_SLOT = R_X86_64_JUMP_SLOT, - .R_COPY = R_X86_64_COPY, - .R_RELATIVE = R_X86_64_RELATIVE, - .rtype_class_valid = RTYPE_CLASS_VALID, - .dynamic_linker = "/lib64/ld-linux-x86-64.so.2", - .adjust_dyn = x86_64_adjust_dyn, - .adjust_rel = x86_64_adjust_rel, - .adjust_rela = x86_64_adjust_rela, - .prelink_rel = x86_64_prelink_rel, - .prelink_rela = x86_64_prelink_rela, - .prelink_conflict_rel = x86_64_prelink_conflict_rel, - .prelink_conflict_rela = x86_64_prelink_conflict_rela, - .apply_conflict_rela = x86_64_apply_conflict_rela, - .apply_rel = x86_64_apply_rel, - .apply_rela = x86_64_apply_rela, - .rel_to_rela = x86_64_rel_to_rela, - .need_rel_to_rela = x86_64_need_rel_to_rela, - .reloc_size = x86_64_reloc_size, - .reloc_class = x86_64_reloc_class, - .max_reloc_size = 8, - .arch_prelink = x86_64_arch_prelink, - .arch_undo_prelink = x86_64_arch_undo_prelink, - .undo_prelink_rela = x86_64_undo_prelink_rela, - /* Although TASK_UNMAPPED_BASE is 0x2a95555555, we leave some - area so that mmap of /etc/ld.so.cache and ld.so's malloc - does not take some library's VA slot. - Also, if this guard area isn't too small, typically - even dlopened libraries will get the slots they desire. */ - .mmap_base = 0x3000000000LL, - .mmap_end = 0x4000000000LL, - .max_page_size = 0x200000, - .page_size = 0x1000 -}; diff --git a/trunk/src/cache.c b/trunk/src/cache.c deleted file mode 100644 index abcec27..0000000 --- a/trunk/src/cache.c +++ /dev/null @@ -1,861 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2013 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/wait.h> -#include <sys/mman.h> -#include "prelinktab.h" - -htab_t prelink_devino_htab, prelink_filename_htab; - -int prelink_entry_count; - -static hashval_t -devino_hash (const void *p) -{ - struct prelink_entry *e = (struct prelink_entry *)p; - - return (e->dev << 2) ^ (e->ino) ^ (e->ino >> 20); -} - -static int -devino_eq (const void *p, const void *q) -{ - struct prelink_entry *e = (struct prelink_entry *)p; - struct prelink_entry *f = (struct prelink_entry *)q; - - return e->ino == f->ino && e->dev == f->dev; -} - -static hashval_t -filename_hash (const void *p) -{ - struct prelink_entry *e = (struct prelink_entry *)p; - const unsigned char *s = (const unsigned char *)e->filename; - hashval_t h = 0; - unsigned char c; - size_t len = 0; - - while ((c = *s++) != '\0') - { - h += c + (c << 17); - h ^= h >> 2; - ++len; - } - return h + len + (len << 17); -} - -static int -filename_eq (const void *p, const void *q) -{ - struct prelink_entry *e = (struct prelink_entry *)p; - struct prelink_entry *f = (struct prelink_entry *)q; - - return strcmp (e->filename, f->filename) == 0; -} - -int -prelink_init_cache (void) -{ - prelink_devino_htab = htab_try_create (100, devino_hash, devino_eq, NULL); - prelink_filename_htab = htab_try_create (100, filename_hash, filename_eq, - NULL); - if (prelink_devino_htab == NULL || prelink_filename_htab == NULL) - error (EXIT_FAILURE, ENOMEM, "Could not create hash table"); - return 0; -} - -struct prelink_entry * -prelink_find_entry (const char *filename, const struct stat64 *stp, - int insert) -{ - struct prelink_entry e, *ent = NULL; - void **filename_slot, *dummy = NULL; - void **devino_slot = NULL; - struct stat64 st; - char *canon_filename = NULL; - - e.filename = filename; - filename_slot = htab_find_slot (prelink_filename_htab, &e, - insert ? INSERT : NO_INSERT); - if (filename_slot == NULL) - { - if (insert) - goto error_out; - filename_slot = &dummy; - } - - if (*filename_slot != NULL) - return (struct prelink_entry *) *filename_slot; - - if (! stp) - { - canon_filename = prelink_canonicalize (filename, &st); - if (canon_filename == NULL && wrap_stat64 (filename, &st) < 0) - { - error (0, errno, "Could not stat %s", filename); - if (insert) - { - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - } - return NULL; - } - stp = &st; - } - - e.dev = stp->st_dev; - e.ino = stp->st_ino; - devino_slot = htab_find_slot (prelink_devino_htab, &e, - insert ? INSERT : NO_INSERT); - if (devino_slot == NULL) - { - if (insert) - goto error_out; - free (canon_filename); - return NULL; - } - - if (*devino_slot != NULL) - { - ent = (struct prelink_entry *) *devino_slot; - if (canon_filename == NULL) - canon_filename = prelink_canonicalize (filename, NULL); - if (canon_filename == NULL) - { - error (0, 0, "Could not canonicalize filename %s", filename); - goto error_out2; - } - - if (strcmp (canon_filename, ent->canon_filename) != 0) - { - struct prelink_link *hardlink; - - hardlink = (struct prelink_link *) - malloc (sizeof (struct prelink_link)); - if (hardlink == NULL) - { - error (0, ENOMEM, "Could not record hardlink %s to %s", - canon_filename, ent->canon_filename); - goto error_out2; - } - - hardlink->canon_filename = canon_filename; - hardlink->next = ent->hardlink; - ent->hardlink = hardlink; - } - else - free (canon_filename); - return ent; - } - - if (! insert) - { - if (canon_filename != NULL) - free (canon_filename); - return NULL; - } - - ent = (struct prelink_entry *) calloc (sizeof (struct prelink_entry), 1); - if (ent == NULL) - goto error_out; - - ent->filename = strdup (filename); - if (ent->filename == NULL) - goto error_out; - - if (canon_filename != NULL) - ent->canon_filename = canon_filename; - else - ent->canon_filename = prelink_canonicalize (filename, NULL); - if (ent->canon_filename == NULL) - { - error (0, 0, "Could not canonicalize filename %s", filename); - free ((char *) ent->filename); - free (ent); - goto error_out2; - } - - ent->dev = stp->st_dev; - ent->ino = stp->st_ino; - ent->ctime = stp->st_ctime; - ent->mtime = stp->st_mtime; - - *filename_slot = ent; - *devino_slot = ent; - ++prelink_entry_count; - return ent; - -error_out: - free (ent); - error (0, ENOMEM, "Could not insert %s into hash table", filename); -error_out2: - if (insert) - { - if (filename_slot != NULL) - { - assert (*filename_slot == NULL); - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - } - if (devino_slot != NULL && *devino_slot == NULL) - { - *devino_slot = &dummy; - htab_clear_slot (prelink_devino_htab, devino_slot); - } - } - free (canon_filename); - return NULL; -} - -static struct prelink_entry * -prelink_load_entry (const char *filename) -{ - struct prelink_entry e, *ent = NULL; - void **filename_slot, *dummy = NULL; - void **devino_slot = &dummy; - struct stat64 st; - uint32_t ctime = 0, mtime = 0; - char *canon_filename = NULL; - - e.filename = filename; - filename_slot = htab_find_slot (prelink_filename_htab, &e, INSERT); - if (filename_slot == NULL) - goto error_out; - - if (*filename_slot != NULL) - return (struct prelink_entry *) *filename_slot; - - canon_filename = prelink_canonicalize (filename, &st); - if (canon_filename == NULL) - goto error_out2; - if (strcmp (canon_filename, filename) != 0) - { - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - - e.filename = canon_filename; - filename_slot = htab_find_slot (prelink_filename_htab, &e, INSERT); - if (filename_slot == NULL) - goto error_out; - - if (*filename_slot != NULL) - { - free (canon_filename); - return (struct prelink_entry *) *filename_slot; - } - } - - if (! S_ISREG (st.st_mode)) - { - free (canon_filename); - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - return NULL; - } - else - { - e.dev = st.st_dev; - e.ino = st.st_ino; - ctime = (uint32_t) st.st_ctime; - mtime = (uint32_t) st.st_mtime; - devino_slot = htab_find_slot (prelink_devino_htab, &e, INSERT); - if (devino_slot == NULL) - goto error_out; - } - - if (*devino_slot != NULL) - { - free (canon_filename); - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - return (struct prelink_entry *) *devino_slot; - } - - ent = (struct prelink_entry *) calloc (sizeof (struct prelink_entry), 1); - if (ent == NULL) - goto error_out; - - ent->filename = strdup (filename); - if (ent->filename == NULL) - goto error_out; - - ent->canon_filename = canon_filename; - ent->dev = e.dev; - ent->ino = e.ino; - ent->ctime = ctime; - ent->mtime = mtime; - *filename_slot = ent; - *devino_slot = ent; - ++prelink_entry_count; - return ent; - -error_out: - free (ent); - error (0, ENOMEM, "Could not insert %s into hash table", filename); -error_out2: - if (filename_slot != NULL) - { - *filename_slot = &dummy; - htab_clear_slot (prelink_filename_htab, filename_slot); - } - if (devino_slot != NULL && devino_slot != &dummy) - { - *devino_slot = &dummy; - htab_clear_slot (prelink_devino_htab, devino_slot); - } - free (canon_filename); - return NULL; -} - -static int -deps_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - - if (a == NULL) - return (b != NULL); - if (a != NULL && b == NULL) - return -1; - - if (a->type == ET_NONE && b->type != ET_NONE) - return 1; - if (a->type != ET_NONE && b->type == ET_NONE) - return -1; - - /* Libraries with fewest dependencies first. */ - if (a->ndepends < b->ndepends) - return -1; - if (a->ndepends > b->ndepends) - return 1; - return 0; -} - -int -prelink_load_cache (void) -{ - int fd, i, j; - struct stat64 st; - struct prelink_cache *cache; - struct prelink_entry **ents; - size_t cache_size; - uint32_t string_start, *dep; - - fd = wrap_open (prelink_cache, O_RDONLY); - if (fd < 0) - return 0; /* The cache does not exist yet. */ - - if (fstat64 (fd, &st) < 0 - || st.st_size == 0) - { - close (fd); - return 0; - } - - cache = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (cache == MAP_FAILED) - error (EXIT_FAILURE, errno, "mmap of prelink cache file failed."); - cache_size = st.st_size; - if (memcmp (cache->magic, PRELINK_CACHE_MAGIC, - sizeof (PRELINK_CACHE_MAGIC) - 1)) - { - if (memcmp (cache->magic, PRELINK_CACHE_NAME, - sizeof (PRELINK_CACHE_NAME) - 1)) - error (EXIT_FAILURE, 0, "%s: is not prelink cache file", - prelink_cache); - munmap (cache, cache_size); - return 0; - } - dep = (uint32_t *) & cache->entry[cache->nlibs]; - string_start = ((long) dep) - ((long) cache) - + cache->ndeps * sizeof (uint32_t); - ents = (struct prelink_entry **) - alloca (cache->nlibs * sizeof (struct prelink_entry *)); - memset (ents, 0, cache->nlibs * sizeof (struct prelink_entry *)); - for (i = 0; i < cache->nlibs; i++) - { - /* Sanity checks. */ - if (cache->entry[i].filename < string_start - || cache->entry[i].filename >= string_start + cache->len_strings - || cache->entry[i].depends >= cache->ndeps) - error (EXIT_FAILURE, 0, "%s: bogus prelink cache file", - prelink_cache); - - ents[i] = prelink_load_entry (((char *) cache) - + cache->entry[i].filename); - } - - for (i = 0; i < cache->nlibs; i++) - { - if (ents[i] == NULL) - continue; - - if (ents[i]->type != ET_NONE) - continue; - - ents[i]->checksum = cache->entry[i].checksum; - ents[i]->base = cache->entry[i].base; - ents[i]->end = cache->entry[i].end; - ents[i]->type = (ents[i]->base == 0 && ents[i]->end == 0) - ? ET_CACHE_EXEC : ET_CACHE_DYN; - ents[i]->flags = cache->entry[i].flags; - - if (ents[i]->flags == PCF_UNPRELINKABLE) - ents[i]->type = (quick || print_cache) ? ET_UNPRELINKABLE : ET_NONE; - - /* If mtime is equal to ctime, assume the filesystem does not store - ctime. */ - if (quick - && ((ents[i]->ctime == ents[i]->mtime - && ents[i]->type != ET_UNPRELINKABLE) - || ents[i]->ctime != cache->entry[i].ctime - || ents[i]->mtime != cache->entry[i].mtime)) - ents[i]->type = ET_NONE; - - for (j = cache->entry[i].depends; dep[j] != i; ++j) - if (dep[j] >= cache->nlibs) - error (EXIT_FAILURE, 0, "%s: bogus prelink cache file", - prelink_cache); - else if (ents[dep[j]] == NULL) - ents[i]->type = ET_NONE; - - if (ents[i]->type == ET_NONE) - continue; - - ents[i]->ndepends = j - cache->entry[i].depends; - if (ents[i]->ndepends) - { - ents[i]->depends = - (struct prelink_entry **) - malloc (ents[i]->ndepends * sizeof (struct prelink_entry *)); - if (ents[i]->depends == NULL) - error (EXIT_FAILURE, ENOMEM, "Cannot read cache file %s", - prelink_cache); - - for (j = 0; j < ents[i]->ndepends; ++j) - ents[i]->depends[j] = ents[dep[cache->entry[i].depends + j]]; - } - } - - if (quick) - { - qsort (ents, cache->nlibs, sizeof (struct prelink_entry *), deps_cmp); - for (i = 0; i < cache->nlibs; ++i) - { - if (ents[i] == NULL || ents[i]->type == ET_NONE) - continue; - - for (j = 0; j < ents[i]->ndepends; ++j) - if (ents[i]->depends[j]->type == ET_NONE) - { - ents[i]->type = ET_NONE; - free (ents[i]->depends); - ents[i]->depends = NULL; - ents[i]->ndepends = 0; - break; - } - } - } - - munmap (cache, cache_size); - close (fd); - return 0; -} - -static int -prelink_print_cache_size (void **p, void *info) -{ - struct prelink_entry *e = * (struct prelink_entry **) p; - int *psize = (int *) info; - - if ((e->base & 0xffffffff) != e->base - || (e->end & 0xffffffff) != e->end) - { - *psize = 16; - return 0; - } - - return 1; -} - -static int -prelink_print_cache_object (void **p, void *info) -{ - struct prelink_entry *e = * (struct prelink_entry **) p; - int *psize = (int *) info, i; - - if (e->type == ET_UNPRELINKABLE) - { - printf ("%s (not prelinkable)%s\n", e->filename, e->ndepends ? ":" : ""); - for (i = 0; i < e->ndepends; i++) - if (e->depends[i]->type == ET_UNPRELINKABLE) - printf (" %s (not prelinkable)\n", e->depends[i]->filename); - else - printf (" %s [0x%08x]\n", e->depends[i]->filename, - e->depends[i]->checksum); - return 1; - } - - if (e->type == ET_CACHE_DYN) - printf ("%s [0x%08x] 0x%0*llx-0x%0*llx%s\n", e->filename, e->checksum, - *psize, (long long) e->base, *psize, (long long) e->end, - e->ndepends ? ":" : ""); - else - printf ("%s%s\n", e->filename, e->ndepends ? ":" : ""); - for (i = 0; i < e->ndepends; i++) - printf (" %s [0x%08x]\n", e->depends[i]->filename, - e->depends[i]->checksum); - return 1; -} - -int -prelink_print_cache (void) -{ - int size = 8; - - printf ("%d objects found in prelink cache `%s'\n", prelink_entry_count, - prelink_cache); - - htab_traverse (prelink_filename_htab, prelink_print_cache_size, &size); - htab_traverse (prelink_filename_htab, prelink_print_cache_object, &size); - return 0; -} - -struct collect_ents -{ - struct prelink_entry **ents; - size_t len_strings; - int nents; - int ndeps; -}; - -static int -prelink_save_cache_check (struct prelink_entry *ent) -{ - int i; - - for (i = 0; i < ent->ndepends; ++i) - switch (ent->depends[i]->type) - { - case ET_DYN: - if (ent->depends[i]->done < 2 - || (quick && (ent->depends[i]->flags & PCF_PRELINKED))) - return 1; - break; - case ET_CACHE_DYN: - if (prelink_save_cache_check (ent->depends[i])) - return 1; - break; - case ET_UNPRELINKABLE: - if (ent->type != ET_UNPRELINKABLE) - return 1; - if (prelink_save_cache_check (ent->depends[i])) - return 1; - break; - default: - return 1; - } - - return 0; -} - -static int -find_ents (void **p, void *info) -{ - struct collect_ents *l = (struct collect_ents *) info; - struct prelink_entry *e = * (struct prelink_entry **) p; - - if (((e->type == ET_DYN || e->type == ET_EXEC) && e->done == 2) - || ((e->type == ET_CACHE_DYN || e->type == ET_CACHE_EXEC - || e->type == ET_UNPRELINKABLE) - && ! prelink_save_cache_check (e))) - { - l->ents[l->nents++] = e; - l->ndeps += e->ndepends + 1; - l->len_strings += strlen (e->canon_filename) + 1; - } - return 1; -} - -int -prelink_save_cache (int do_warn) -{ - struct prelink_cache cache; - struct collect_ents l; - struct prelink_cache_entry *data; - uint32_t *deps, ndeps = 0, i, j, k; - char *strings; - int fd, len; - struct prelink_entry *ents_array[prelink_entry_count]; - - memset (&cache, 0, sizeof (cache)); - memcpy ((char *) & cache, PRELINK_CACHE_MAGIC, - sizeof (PRELINK_CACHE_MAGIC) - 1); - l.ents = ents_array; - l.nents = 0; - l.ndeps = 0; - l.len_strings = 0; - htab_traverse (prelink_filename_htab, find_ents, &l); - cache.nlibs = l.nents; - cache.ndeps = l.ndeps; - cache.len_strings = l.len_strings; - - len = cache.nlibs * sizeof (struct prelink_cache_entry) - + cache.ndeps * sizeof (uint32_t) + cache.len_strings; - char data_buf[len]; - data = (struct prelink_cache_entry *) data_buf; - deps = (uint32_t *) & data[cache.nlibs]; - strings = (char *) & deps[cache.ndeps]; - - for (i = 0; i < l.nents; ++i) - { - data[i].filename = (strings - (char *) data) + sizeof (cache); - strings = stpcpy (strings, l.ents[i]->canon_filename) + 1; - data[i].checksum = l.ents[i]->checksum; - data[i].flags = l.ents[i]->flags & ~PCF_PRELINKED; - data[i].ctime = l.ents[i]->ctime; - data[i].mtime = l.ents[i]->mtime; - if (l.ents[i]->type == ET_EXEC || l.ents[i]->type == ET_CACHE_EXEC) - { - data[i].base = 0; - data[i].end = 0; - } - else if (l.ents[i]->type == ET_UNPRELINKABLE) - { - data[i].base = 0; - data[i].end = 0; - data[i].checksum = 0; - data[i].flags = PCF_UNPRELINKABLE; - } - else - { - data[i].base = l.ents[i]->base; - data[i].end = l.ents[i]->end; - } - } - - for (i = 0; i < cache.nlibs; i++) - { - data[i].depends = ndeps; - for (j = 0; j < l.ents[i]->ndepends; j++) - { - for (k = 0; k < cache.nlibs; k++) - if (l.ents[k] == l.ents[i]->depends[j]) - break; - if (k == cache.nlibs) - abort (); - deps[ndeps++] = k; - } - deps[ndeps++] = i; - } - - size_t prelink_cache_len = strlen (prelink_cache); - char prelink_cache_tmp [prelink_cache_len + sizeof (".XXXXXX")]; - memcpy (mempcpy (prelink_cache_tmp, prelink_cache, prelink_cache_len), - ".XXXXXX", sizeof (".XXXXXX")); - fd = wrap_mkstemp (prelink_cache_tmp); - if (fd < 0) - { - error (0, errno, "Could not write prelink cache"); - return 1; - } - - if (write (fd, &cache, sizeof (cache)) != sizeof (cache) - || write (fd, data, len) != len - || fchmod (fd, 0644) - || fsync (fd) - || close (fd) - || wrap_rename (prelink_cache_tmp, prelink_cache)) - { - error (0, errno, "Could not write prelink cache"); - wrap_unlink (prelink_cache_tmp); - return 1; - } - return 0; -} - -#ifndef NDEBUG -static void -prelink_entry_dumpfn (FILE *f, const void *ptr) -{ - struct prelink_entry *e = (struct prelink_entry *) ptr; - struct prelink_link *l; - int i; - - fprintf (f, "%s|%s|%s|%x|%x|%llx|%llx|%llx|%llx|%llx|%d|%d|%d|%d|%d|%d|%d|", - e->filename, - strcmp (e->canon_filename, e->filename) ? e->canon_filename : "", - e->soname && strcmp (e->soname, e->filename) ? e->soname : "", - e->timestamp, e->checksum, - (long long) e->base, (long long) e->end, (long long) e->pltgot, - (long long) e->dev, (long long) e->ino, - e->type, e->done, e->ndepends, e->refs, e->flags, - e->prev ? e->prev->u.tmp : -1, e->next ? e->next->u.tmp : -1); - for (i = 0; i < e->ndepends; ++i) - fprintf (f, "%d-", e->depends [i]->u.tmp); - fputc ('|', f); - for (l = e->hardlink; l; l = l->next) - fprintf (f, "%s|", l->canon_filename); - fputs ("\n", f); -} - -void -prelink_entry_dump (htab_t htab, const char *filename) -{ - size_t i; - - for (i = 0; i < htab->size; ++i) - if (htab->entries [i] && htab->entries [i] != (void *) 1) - ((struct prelink_entry *) htab->entries [i])->u.tmp = i; - htab_dump (htab, filename, prelink_entry_dumpfn); -} - -static char *restore_line; -static size_t restore_size; - -static void * -prelink_entry_restorefn (FILE *f) -{ - struct prelink_entry *e; - struct prelink_link **plink; - char *p, *q, *s; - long long ll[5]; - int ii[5]; - int i; - - if (getline (&restore_line, &restore_size, f) < 0) - abort (); - e = (struct prelink_entry *) calloc (1, sizeof (struct prelink_entry)); - if (e == NULL) - abort (); - p = restore_line; - q = strchr (p, '|'); - s = malloc (q - p + 1); - memcpy (s, p, q - p); - s [q - p] = '\0'; - e->filename = s; - ++q; - p = q; - if (*p == '|') - e->canon_filename = strdup (e->filename); - else - { - q = strchr (p, '|'); - s = malloc (q - p + 1); - memcpy (s, p, q - p); - s [q - p] = '\0'; - e->canon_filename = s; - } - ++q; - p = q; - if (*p == '|') - e->soname = strdup (e->filename); - else - { - q = strchr (p, '|'); - s = malloc (q - p + 1); - memcpy (s, p, q - p); - s [q - p] = '\0'; - e->soname = s; - } - p = q + 1; - if (sscanf (p, "%x|%x|%llx|%llx|%llx|%llx|%llx|%d|%d|%d|%d|%d|%d|%d|%n", - ii, ii + 1, ll, ll + 1, ll + 2, ll + 3, ll + 4, - &e->type, &e->done, &e->ndepends, &e->refs, &e->flags, - ii + 2, ii + 3, ii + 4) < 14) - abort (); - e->timestamp = ii[0]; - e->checksum = ii[1]; - e->base = ll[0]; - e->end = ll[1]; - e->pltgot = ll[2]; - e->dev = ll[3]; - e->ino = ll[4]; - e->prev = (void *) (long) ii[2]; - e->next = (void *) (long) ii[3]; - e->depends = (struct prelink_entry **) - malloc (e->ndepends * sizeof (struct prelink_entry *)); - p += ii[4]; - for (i = 0; i < e->ndepends; ++i) - { - e->depends [i] = (void *) strtol (p, &q, 0); - if (p == q || *q != '-') - abort (); - p = q + 1; - } - if (*p++ != '|') - abort (); - plink = &e->hardlink; - while (*p != '\n') - { - struct prelink_link *link = (struct prelink_link *) - malloc (sizeof (struct prelink_link)); - q = strchr (p, '|'); - *plink = link; - plink = &link->next; - s = malloc (q - p + 1); - memcpy (s, p, q - p); - s [q - p] = '\0'; - e->soname = s; - link->canon_filename = s; - p = q + 1; - } - *plink = NULL; - ++prelink_entry_count; - return e; -} - -void -prelink_entry_restore (htab_t htab, const char *filename) -{ - size_t i, j; - struct prelink_entry *e; - - prelink_entry_count = 0; - htab_restore (htab, filename, prelink_entry_restorefn); - free (restore_line); - for (i = 0; i < htab->size; ++i) - if (htab->entries [i] && htab->entries [i] != (void *) 1) - { - e = (struct prelink_entry *) htab->entries [i]; - if (e->prev == (void *) -1) - e->prev = NULL; - else - e->prev = (struct prelink_entry *) - htab->entries [(long) e->prev]; - if (e->next == (void *) -1) - e->next = NULL; - else - e->next = (struct prelink_entry *) - htab->entries [(long) e->next]; - for (j = 0; j < e->ndepends; ++j) - { - e->depends [j] = (struct prelink_entry *) - htab->entries [(long) e->depends [j]]; - } - } -} -#endif diff --git a/trunk/src/canonicalize.c b/trunk/src/canonicalize.c deleted file mode 100644 index 717e991..0000000 --- a/trunk/src/canonicalize.c +++ /dev/null @@ -1,374 +0,0 @@ -/* Return the canonical absolute name of a given file. - Copyright (C) 1996-2002, 2004, 2005, 2006 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <limits.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <errno.h> -#include <stddef.h> - -#include "hashtab.h" -#include "prelink.h" - -htab_t prelink_dirname_htab; - -struct dirname_entry -{ - const char *dirname; - size_t dirname_len; - const char *canon_dirname; - size_t canon_dirname_len; -}; - -static hashval_t -dirname_hash (const void *p) -{ - struct dirname_entry *e = (struct dirname_entry *)p; - const unsigned char *s = (const unsigned char *)e->dirname; - hashval_t h = 0; - unsigned char c; - size_t len = e->dirname_len; - - while (len--) - { - c = *s++; - h += c + (c << 17); - h ^= h >> 2; - } - return h + e->dirname_len + (e->dirname_len << 17); -} - -static int -dirname_eq (const void *p, const void *q) -{ - struct dirname_entry *e = (struct dirname_entry *)p; - struct dirname_entry *f = (struct dirname_entry *)q; - - return (e->dirname_len == f->dirname_len - && memcmp (e->dirname, f->dirname, e->dirname_len) == 0); -} - -/* Return the canonical absolute name of file NAME. A canonical name - does not contain any `.', `..' components nor any repeated path - separators ('/') or symlinks. All path components must exist. - The result is malloc'd. */ - -char * -canon_filename (const char *name, int nested, struct stat64 *stp, - const char *chroot, int allow_last_link, - int allow_missing) -{ - char *rpath, *dest, *extra_buf = NULL, *rpath_root; - const char *start, *end, *rpath_limit; - long int path_max; - int num_links = 0; - int stp_initialized = 0; - int chroot_len; - - if (name == NULL) - { - errno = EINVAL; - return NULL; - } - - if (name[0] == '\0') - { - errno = ENOENT; - return NULL; - } - chroot_len = strlen (chroot); - if (chroot_len > 0 && chroot[chroot_len - 1] == '/') - chroot_len--; - -#ifdef PATH_MAX - path_max = PATH_MAX; -#else - path_max = pathconf (name, _PC_PATH_MAX); - if (path_max <= 0) - path_max = 1024; -#endif - - rpath = malloc (path_max + chroot_len + 1); - if (rpath == NULL) - return NULL; - rpath_limit = rpath + path_max; - - if (name[0] != '/') - { - if (!getcwd (rpath, path_max)) - { - rpath[0] = '\0'; - goto error; - } - if (chroot_len > 0) - { - struct stat64 st; - char *cwd = canon_filename (rpath, 1, &st, chroot, 0, 0); - if (cwd == NULL) - goto error; - if (memcmp (cwd, chroot, chroot_len) != 0) - goto error; - strcpy (rpath, cwd); - free (cwd); - rpath_root = rpath + chroot_len; - } - else - rpath_root = rpath; - - dest = strchr (rpath_root, '\0'); - } - else - { - if (chroot_len > 0) - rpath_root = (char *) mempcpy (rpath, chroot, chroot_len); - else - rpath_root = rpath; - - rpath_root[0] = '/'; - dest = rpath_root + 1; - - if (!nested) - { - if (prelink_dirname_htab == NULL) - prelink_dirname_htab = htab_try_create (100, dirname_hash, - dirname_eq, NULL); - if (prelink_dirname_htab == NULL) - nested = 1; - } - if (!nested) - { - struct dirname_entry e; - void **dirname_slot; - - end = strrchr (name, '/'); - - e.dirname = name; - e.dirname_len = end - name; - dirname_slot = htab_find_slot (prelink_dirname_htab, &e, INSERT); - if (*dirname_slot == NULL) - { - struct dirname_entry *ep = malloc (sizeof (struct dirname_entry) - + e.dirname_len + 1); - if (ep != NULL) - { - char *dirname = (char *) (ep + 1); - struct stat64 st; - - ep->dirname = (const char *) dirname; - ep->dirname_len = e.dirname_len; - memcpy (dirname, name, ep->dirname_len); - dirname[ep->dirname_len] = '\0'; - ep->canon_dirname = canon_filename (ep->dirname, 1, &st, - chroot, 0, 0); - if (ep->canon_dirname == NULL || !S_ISDIR (st.st_mode)) - free (ep); - else - { - ep->canon_dirname_len = strlen (ep->canon_dirname); - *dirname_slot = ep; - } - } - } - - if (*dirname_slot != NULL) - { - struct dirname_entry *ep = *dirname_slot; - - if (rpath + ep->canon_dirname_len + 1 >= rpath_limit) - { - size_t new_size, root_size; - char *new_rpath; - - new_size = rpath_limit - rpath; - root_size = rpath_root - rpath; - if (ep->canon_dirname_len + 1 > path_max) - new_size += ep->canon_dirname_len + 1; - else - new_size += path_max; - new_rpath = (char *) realloc (rpath, new_size); - if (new_rpath == NULL) - goto error; - rpath = new_rpath; - rpath_limit = rpath + new_size; - rpath_root = rpath + root_size; - } - dest = mempcpy (rpath, ep->canon_dirname, ep->canon_dirname_len); - *dest = '\0'; - name = end + 1; - } - } - } - - for (start = end = name; *start; start = end) - { - int n; - - /* Skip sequence of multiple path-separators. */ - while (*start == '/') - ++start; - - /* Find end of path component. */ - for (end = start; *end && *end != '/'; ++end) - /* Nothing. */; - - if (end - start == 0) - break; - else if (end - start == 1 && start[0] == '.') - /* nothing */; - else if (end - start == 2 && start[0] == '.' && start[1] == '.') - { - /* Back up to previous component, ignore if at root already. */ - if (dest > rpath_root + 1) - while ((--dest)[-1] != '/'); - stp_initialized = 0; - } - else - { - size_t new_size; - - if (dest[-1] != '/') - *dest++ = '/'; - - if (dest + (end - start) >= rpath_limit) - { - ptrdiff_t dest_offset = dest - rpath; - size_t root_size = rpath_root - rpath; - char *new_rpath; - - new_size = rpath_limit - rpath; - if (end - start + 1 > path_max) - new_size += end - start + 1; - else - new_size += path_max; - new_rpath = (char *) realloc (rpath, new_size); - if (new_rpath == NULL) - goto error; - rpath = new_rpath; - rpath_limit = rpath + new_size; - rpath_root = rpath + root_size; - - dest = rpath + dest_offset; - } - - dest = mempcpy (dest, start, end - start); - *dest = '\0'; - - if (allow_last_link && *end == '\0') - break; - - if (lstat64 (rpath, stp) < 0) - { - if (allow_missing && *end == '\0') - break; - goto error; - } - - stp_initialized = 1; - - if (S_ISLNK (stp->st_mode)) - { - char *buf = alloca (path_max); - size_t len; - - if (++num_links > MAXSYMLINKS) - { - errno = ELOOP; - goto error; - } - - n = readlink (rpath, buf, path_max); - if (n < 0) - { - if (allow_missing && *end == '\0') - break; - goto error; - } - buf[n] = '\0'; - - if (!extra_buf) - extra_buf = alloca (path_max); - - len = strlen (end); - if ((long int) (n + len) >= path_max) - { - errno = ENAMETOOLONG; - goto error; - } - - /* Careful here, end may be a pointer into extra_buf... */ - memmove (&extra_buf[n], end, len + 1); - name = end = memcpy (extra_buf, buf, n); - - if (buf[0] == '/') - dest = rpath_root + 1; /* It's an absolute symlink */ - else - /* Back up to previous component, ignore if at root already: */ - if (dest > rpath_root + 1) - while ((--dest)[-1] != '/'); - } - else if (!S_ISDIR (stp->st_mode) && *end != '\0') - { - errno = ENOTDIR; - goto error; - } - } - } - if (dest > rpath + 1 && dest[-1] == '/') - --dest; - *dest = '\0'; - - if (!stp_initialized && !allow_missing && !allow_last_link - && lstat64 (rpath, stp) < 0) - goto error; - - if (dest + 1 - rpath <= (rpath_limit - rpath) / 2) - { - char *new_rpath = realloc (rpath, dest + 1 - rpath); - - if (new_rpath != NULL) - return new_rpath; - } - return rpath; - -error: - free (rpath); - return NULL; -} - -char *unsysroot_file_name (const char *name); - -char * -prelink_canonicalize (const char *name, struct stat64 *stp) -{ - struct stat64 st; - char *canon, *final; - - canon = canon_filename (name, 0, stp ? stp : &st, - sysroot ? sysroot : "", 0, 0); - if (canon == NULL) - return NULL; - final = unsysroot_file_name (canon); - if (final != canon) - free (canon); - return final; -} diff --git a/trunk/src/checksum.c b/trunk/src/checksum.c deleted file mode 100644 index 20a23a0..0000000 --- a/trunk/src/checksum.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include "prelink.h" - -int -prelink_set_checksum (DSO *dso) -{ - extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len); - uint32_t crc; - int i, cvt; - - if (set_dynamic (dso, DT_CHECKSUM, 0, 1)) - return 1; - - if (dso->info_DT_GNU_PRELINKED - && set_dynamic (dso, DT_GNU_PRELINKED, 0, 1)) - return 1; - - /* Ensure any pending .mdebug/.dynsym/.dynstr etc. modifications - write_dso would do happen before checksumming. */ - if (prepare_write_dso (dso)) - return 1; - - cvt = ! ((__BYTE_ORDER == __LITTLE_ENDIAN - && dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) - || (__BYTE_ORDER == __BIG_ENDIAN - && dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)); - crc = 0; - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR))) - continue; - if (dso->shdr[i].sh_type != SHT_NOBITS && dso->shdr[i].sh_size) - { - Elf_Scn *scn = dso->scn[i]; - Elf_Data *d = NULL; - - /* Cannot use elf_rawdata here, since the image is not written - yet. */ - while ((d = elf_getdata (scn, d)) != NULL) - { - if (cvt && d->d_type != ELF_T_BYTE) - { - gelf_xlatetof (dso->elf, d, d, - dso->ehdr.e_ident[EI_DATA]); - crc = crc32 (crc, d->d_buf, d->d_size); - gelf_xlatetom (dso->elf, d, d, - dso->ehdr.e_ident[EI_DATA]); - } - else - crc = crc32 (crc, d->d_buf, d->d_size); - } - } - } - - if (set_dynamic (dso, DT_CHECKSUM, crc, 1)) - abort (); - if (dso->info_DT_GNU_PRELINKED - && set_dynamic (dso, DT_GNU_PRELINKED, dso->info_DT_GNU_PRELINKED, 1)) - abort (); - dso->info_DT_CHECKSUM = crc; - - return 0; -} diff --git a/trunk/src/conflict.c b/trunk/src/conflict.c deleted file mode 100644 index 9ae2ddb..0000000 --- a/trunk/src/conflict.c +++ /dev/null @@ -1,832 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2007, 2009 Red Hat, Inc. - Copyright (C) 2008 CodeSourcery. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - Updated by Maciej W. Rozycki <macro@codesourcery.com>, 2008. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" -#include "reloc-info.h" - -struct prelink_conflict * -prelink_conflict (struct prelink_info *info, GElf_Word r_sym, - int reloc_type) -{ - GElf_Word symoff = info->symtab_start + r_sym * info->symtab_entsize; - struct prelink_conflict *conflict; - int reloc_class = info->dso->arch->reloc_class (reloc_type); - size_t idx = 0; - - if (info->curconflicts->hash != &info->curconflicts->first) - idx = symoff % 251; - for (conflict = info->curconflicts->hash[idx]; conflict; - conflict = conflict->next) - if (conflict->symoff == symoff && conflict->reloc_class == reloc_class) - { - conflict->used = 1; - return conflict; - } - - return NULL; -} - -GElf_Rela * -prelink_conflict_add_rela (struct prelink_info *info) -{ - GElf_Rela *ret; - - if (info->conflict_rela_alloced == info->conflict_rela_size) - { - info->conflict_rela_alloced += 10; - info->conflict_rela = realloc (info->conflict_rela, - info->conflict_rela_alloced - * sizeof (GElf_Rela)); - if (info->conflict_rela == NULL) - { - error (0, ENOMEM, "Could not build .gnu.conflict section memory image"); - return NULL; - } - } - ret = info->conflict_rela + info->conflict_rela_size++; - ret->r_offset = 0; - ret->r_info = 0; - ret->r_addend = 0; - return ret; -} - -static int -prelink_conflict_rel (DSO *dso, int n, struct prelink_info *info) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rel rel; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrel (dso->elf, data, ndx, &rel); - sec = addr_to_sec (dso, rel.r_offset); - if (sec == -1) - continue; - - if (dso->arch->prelink_conflict_rel (dso, info, &rel, addr)) - return 1; - } - } - return 0; -} - -static int -prelink_conflict_rela (DSO *dso, int n, struct prelink_info *info) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rela rela; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrela (dso->elf, data, ndx, &rela); - sec = addr_to_sec (dso, rela.r_offset); - if (sec == -1) - continue; - - if (dso->arch->prelink_conflict_rela (dso, info, &rela, addr)) - return 1; - } - } - return 0; -} - -struct copy_relocs -{ - GElf_Rela *rela; - int alloced; - int count; -}; - -static int -prelink_add_copy_rel (DSO *dso, int n, GElf_Rel *rel, struct copy_relocs *cr) -{ - Elf_Data *data = NULL; - int symsec = dso->shdr[n].sh_link; - Elf_Scn *scn = dso->scn[symsec]; - GElf_Sym sym; - size_t entsize = dso->shdr[symsec].sh_entsize; - off_t off = reloc_r_sym (dso, rel->r_info) * entsize; - - while ((data = elf_getdata (scn, data)) != NULL) - { - if (data->d_off <= off && - data->d_off + data->d_size >= off + entsize) - { - gelfx_getsym (dso->elf, data, (off - data->d_off) / entsize, &sym); - if (sym.st_size == 0) - { - error (0, 0, "%s: Copy reloc against symbol with zero size", - dso->filename); - return 1; - } - - if (cr->alloced == cr->count) - { - cr->alloced += 10; - cr->rela = realloc (cr->rela, cr->alloced * sizeof (GElf_Rela)); - if (cr->rela == NULL) - { - error (0, ENOMEM, "%s: Could not build list of COPY relocs", - dso->filename); - return 1; - } - } - cr->rela[cr->count].r_offset = rel->r_offset; - cr->rela[cr->count].r_info = rel->r_info; - cr->rela[cr->count].r_addend = sym.st_size; - ++cr->count; - return 0; - } - } - - error (0, 0, "%s: Copy reloc against unknown symbol", dso->filename); - return 1; -} - -static int -prelink_find_copy_rel (DSO *dso, int n, struct copy_relocs *cr) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rel rel; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getrel (dso->elf, data, ndx, &rel); - sec = addr_to_sec (dso, rel.r_offset); - if (sec == -1) - continue; - - if (reloc_r_type (dso, rel.r_info) == dso->arch->R_COPY - && prelink_add_copy_rel (dso, n, &rel, cr)) - return 1; - } - } - return 0; -} - -static int -prelink_find_copy_rela (DSO *dso, int n, struct copy_relocs *cr) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - union { - GElf_Rel rel; - GElf_Rela rela; - } u; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getrela (dso->elf, data, ndx, &u.rela); - sec = addr_to_sec (dso, u.rela.r_offset); - if (sec == -1) - continue; - - if (reloc_r_type (dso, u.rela.r_info) == dso->arch->R_COPY) - { - if (u.rela.r_addend != 0) - { - error (0, 0, "%s: COPY reloc with non-zero addend?", - dso->filename); - return 1; - } - if (prelink_add_copy_rel (dso, n, &u.rel, cr)) - return 1; - } - } - } - return 0; -} - -static int -rela_cmp (const void *A, const void *B) -{ - GElf_Rela *a = (GElf_Rela *)A; - GElf_Rela *b = (GElf_Rela *)B; - - if (a->r_offset < b->r_offset) - return -1; - if (a->r_offset > b->r_offset) - return 1; - return 0; -} - -static DSO *conflict_rela_cmp_dso; - -static int -conflict_rela_cmp (const void *A, const void *B) -{ - DSO *dso = conflict_rela_cmp_dso; - GElf_Rela *a = (GElf_Rela *)A; - GElf_Rela *b = (GElf_Rela *)B; - - if (reloc_r_sym (dso, a->r_info) < reloc_r_sym (dso, b->r_info)) - return -1; - if (reloc_r_sym (dso, a->r_info) > reloc_r_sym (dso, b->r_info)) - return 1; - if (a->r_offset < b->r_offset) - return -1; - if (a->r_offset > b->r_offset) - return 1; - return 0; -} - -int -get_relocated_mem (struct prelink_info *info, DSO *dso, GElf_Addr addr, - char *buf, GElf_Word size, GElf_Addr dest_addr) -{ - int sec = addr_to_sec (dso, addr), j; - Elf_Scn *scn; - Elf_Data *data; - off_t off; - - if (sec == -1) - return 1; - - memset (buf, 0, size); - if (dso->shdr[sec].sh_type != SHT_NOBITS) - { - scn = dso->scn[sec]; - data = NULL; - off = addr - dso->shdr[sec].sh_addr; - while ((data = elf_rawdata (scn, data)) != NULL) - { - if (data->d_off < off + size - && data->d_off + data->d_size > off) - { - off_t off2 = off - data->d_off; - size_t len = size; - - if (off2 < 0) - { - len += off2; - off2 = 0; - } - if (off2 + len > data->d_size) - len = data->d_size - off2; - assert (off2 + len <= data->d_size); - assert (len <= size); - memcpy (buf + off2 - off, data->d_buf + off2, len); - } - } - } - - if (info->dso != dso) - { - /* This is tricky. We need to apply any conflicts - against memory area which we've copied to the COPY - reloc offset. */ - for (j = 0; j < info->conflict_rela_size; ++j) - { - int reloc_type, reloc_size, ret; - off_t off; - - if (info->conflict_rela[j].r_offset >= addr + size) - continue; - if (info->conflict_rela[j].r_offset + dso->arch->max_reloc_size - <= addr) - continue; - - reloc_type = reloc_r_type (dso, info->conflict_rela[j].r_info); - reloc_size = dso->arch->reloc_size (reloc_type); - if (info->conflict_rela[j].r_offset + reloc_size <= addr) - continue; - - off = info->conflict_rela[j].r_offset - addr; - - /* Check if whole relocation fits into the area. - Punt if not. */ - if (off < 0 || size - off < reloc_size) - return 2; - /* Note that apply_conflict_rela shouldn't rely on R_SYM - field of conflict to be 0. */ - ret - = dso->arch->apply_conflict_rela (info, info->conflict_rela + j, - buf + off, - dest_addr ? dest_addr + off : 0); - if (ret) - return ret; - } - } - else - { - int i, ndx, maxndx; - int reloc_type, reloc_size; - union { GElf_Rel rel; GElf_Rela rela; } u; - off_t off; - - if (addr + size > info->dynbss_base - && addr < info->dynbss_base + info->dynbss_size) - { - if (addr < info->dynbss_base - || addr + size > info->dynbss_base + info->dynbss_size) - return 4; - - memcpy (buf, info->dynbss + (addr - info->dynbss_base), size); - return 0; - } - - if (addr + size > info->sdynbss_base - && addr < info->sdynbss_base + info->sdynbss_size) - { - if (addr < info->sdynbss_base - || addr + size > info->sdynbss_base + info->sdynbss_size) - return 4; - - memcpy (buf, info->sdynbss + (addr - info->sdynbss_base), size); - return 0; - } - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - - if (! (dso->shdr[i].sh_flags & SHF_ALLOC)) - continue; - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".gnu.conflict")) - continue; - switch (dso->shdr[i].sh_type) - { - case SHT_REL: - case SHT_RELA: - break; - default: - continue; - } - scn = dso->scn[i]; - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[i].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - if (dso->shdr[i].sh_type == SHT_REL) - gelfx_getrel (dso->elf, data, ndx, &u.rel); - else - gelfx_getrela (dso->elf, data, ndx, &u.rela); - - if (u.rel.r_offset >= addr + size) - continue; - if (u.rel.r_offset + dso->arch->max_reloc_size <= addr) - continue; - - reloc_type = reloc_r_type (dso, u.rel.r_info); - reloc_size = dso->arch->reloc_size (reloc_type); - if (u.rel.r_offset + reloc_size <= addr) - continue; - - if (reloc_type == dso->arch->R_COPY) - return 3; - - off = u.rel.r_offset - addr; - - /* Check if whole relocation fits into the area. - Punt if not. */ - if (off < 0 || size - off < reloc_size) - return 2; - - if (dso->shdr[i].sh_type == SHT_REL) - dso->arch->apply_rel (info, &u.rel, buf + off); - else - dso->arch->apply_rela (info, &u.rela, buf + off); - } - } - } - } - - return 0; -} - -int -prelink_build_conflicts (struct prelink_info *info) -{ - int i, ndeps = info->ent->ndepends + 1; - struct prelink_entry *ent; - int ret = 0; - DSO *dso; - struct copy_relocs cr; - - info->dsos = alloca (sizeof (struct DSO *) * ndeps); - memset (info->dsos, 0, sizeof (struct DSO *) * ndeps); - memset (&cr, 0, sizeof (cr)); - info->dsos[0] = info->dso; - for (i = 1; i < ndeps; ++i) - { - ent = info->ent->depends[i - 1]; - if ((dso = open_dso (ent->filename)) == NULL) - goto error_out; - info->dsos[i] = dso; - /* Now check that the DSO matches what we recorded about it. */ - if (ent->timestamp != dso->info_DT_GNU_PRELINKED - || ent->checksum != dso->info_DT_CHECKSUM - || ent->base != dso->base) - { - error (0, 0, "%s: Library %s has changed since it has been prelinked", - info->dso->filename, ent->filename); - goto error_out; - } - } - - for (i = 0; i < ndeps; ++i) - { - int j, sec, first_conflict, maxidx; - struct prelink_conflict *conflict; - - dso = info->dsos[i]; - ent = i ? info->ent->depends[i - 1] : info->ent; - - /* Verify .gnu.liblist sections of all dependent libraries. */ - if (i && ent->ndepends > 0) - { - const char *name; - int nliblist; - Elf32_Lib *liblist; - Elf_Scn *scn; - Elf_Data *data; - - for (j = 1; j < dso->ehdr.e_shnum; ++j) - if (dso->shdr[j].sh_type == SHT_GNU_LIBLIST - && (name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[j].sh_name)) - && ! strcmp (name, ".gnu.liblist") - && (dso->shdr[j].sh_size % sizeof (Elf32_Lib)) == 0) - break; - - if (j == dso->ehdr.e_shnum) - { - error (0, 0, "%s: Library %s has dependencies, but doesn't contain .gnu.liblist section", - info->dso->filename, ent->filename); - goto error_out; - } - - nliblist = dso->shdr[j].sh_size / sizeof (Elf32_Lib); - scn = dso->scn[j]; - data = elf_getdata (scn, NULL); - if (data == NULL || elf_getdata (scn, data) - || data->d_buf == NULL || data->d_off - || data->d_size != dso->shdr[j].sh_size) - { - error (0, 0, "%s: Could not read .gnu.liblist section from %s", - info->dso->filename, ent->filename); - goto error_out; - } - - if (nliblist != ent->ndepends) - { - error (0, 0, "%s: Library %s has different number of libs in .gnu.liblist than expected", - info->dso->filename, ent->filename); - goto error_out; - } - liblist = (Elf32_Lib *) data->d_buf; - for (j = 0; j < nliblist; ++j) - if (liblist[j].l_time_stamp != ent->depends[j]->timestamp - || liblist[j].l_checksum != ent->depends[j]->checksum) - { - error (0, 0, "%s: .gnu.liblist in library %s is inconsistent with recorded dependencies", - info->dso->filename, ent->filename); - goto error_out; - } - - /* Extra check, maybe not needed. */ - for (j = 0; j < nliblist; ++j) - { - int k; - for (k = 0; k < info->ent->ndepends; ++k) - if (liblist[j].l_time_stamp == info->ent->depends[k]->timestamp - && liblist[j].l_checksum == info->ent->depends[k]->checksum) - break; - - if (k == info->ent->ndepends) - abort (); - } - } - - info->curconflicts = &info->conflicts[i]; - info->curtls = info->tls[i].modid ? info->tls + i : NULL; - first_conflict = info->conflict_rela_size; - sec = addr_to_sec (dso, dso->info[DT_SYMTAB]); - /* DT_SYMTAB should be found and should point to - start of .dynsym section. */ - if (sec == -1 || dso->info[DT_SYMTAB] != dso->shdr[sec].sh_addr) - { - error (0, 0, "Bad symtab"); - goto error_out; - } - info->symtab_start = dso->shdr[sec].sh_addr - dso->base; - info->symtab_end = info->symtab_start + dso->shdr[sec].sh_size; - for (j = 0; j < dso->ehdr.e_shnum; ++j) - { - if (! (dso->shdr[j].sh_flags & SHF_ALLOC)) - continue; - switch (dso->shdr[j].sh_type) - { - case SHT_REL: - if (i == 0 - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[j].sh_name), - ".gnu.conflict") == 0) - break; - if (prelink_conflict_rel (dso, j, info)) - goto error_out; - break; - case SHT_RELA: - if (i == 0 - && strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[j].sh_name), - ".gnu.conflict") == 0) - break; - if (prelink_conflict_rela (dso, j, info)) - goto error_out; - break; - } - } - - if (dso->arch->arch_prelink_conflict - && dso->arch->arch_prelink_conflict (dso, info)) - goto error_out; - - maxidx = 1; - if (info->curconflicts->hash != &info->curconflicts->first) - maxidx = 251; - for (j = 0; j < maxidx; j++) - for (conflict = info->curconflicts->hash[j]; conflict; - conflict = conflict->next) - if (! conflict->used && (i || conflict->ifunc)) - { - error (0, 0, "%s: Conflict %08llx (%s) not found in any relocation", - dso->filename, (unsigned long long) conflict->symoff, conflict->symname); - ret = 1; - } - - /* Record library's position in search scope into R_SYM field. */ - for (j = first_conflict; j < info->conflict_rela_size; ++j) - info->conflict_rela[j].r_info - = reloc_r_info (dso, i, - reloc_r_type (dso, info->conflict_rela[j].r_info)); - - if (dynamic_info_is_set (dso, DT_TEXTREL) - && info->conflict_rela_size > first_conflict) - { - /* We allow prelinking against non-PIC libraries, as long as - no conflict is against read-only segment. */ - int k; - - for (j = first_conflict; j < info->conflict_rela_size; ++j) - for (k = 0; k < dso->ehdr.e_phnum; ++k) - if (dso->phdr[k].p_type == PT_LOAD - && (dso->phdr[k].p_flags & PF_W) == 0 - && dso->phdr[k].p_vaddr - <= info->conflict_rela[j].r_offset - && dso->phdr[k].p_vaddr + dso->phdr[k].p_memsz - > info->conflict_rela[j].r_offset) - { - error (0, 0, "%s: Cannot prelink against non-PIC shared library %s", - info->dso->filename, dso->filename); - goto error_out; - } - } - } - - dso = info->dso; - for (i = 0; i < dso->ehdr.e_shnum; ++i) - { - if (! (dso->shdr[i].sh_flags & SHF_ALLOC)) - continue; - switch (dso->shdr[i].sh_type) - { - case SHT_REL: - if (prelink_find_copy_rel (dso, i, &cr)) - goto error_out; - break; - case SHT_RELA: - if (prelink_find_copy_rela (dso, i, &cr)) - goto error_out; - break; - } - } - - if (cr.count) - { - int bss1, bss2, firstbss2 = 0; - const char *name; - - qsort (cr.rela, cr.count, sizeof (GElf_Rela), rela_cmp); - bss1 = addr_to_sec (dso, cr.rela[0].r_offset); - bss2 = addr_to_sec (dso, cr.rela[cr.count - 1].r_offset); - if (bss1 != bss2) - { - for (i = 1; i < cr.count; ++i) - if (cr.rela[i].r_offset - >= dso->shdr[bss1].sh_addr + dso->shdr[bss1].sh_size) - break; - if (cr.rela[i].r_offset < dso->shdr[bss2].sh_addr) - { - error (0, 0, "%s: Copy relocs against 3 or more sections", - dso->filename); - goto error_out; - } - firstbss2 = i; - info->sdynbss_size = cr.rela[i - 1].r_offset - cr.rela[0].r_offset; - info->sdynbss_size += cr.rela[i - 1].r_addend; - info->sdynbss = calloc (info->sdynbss_size, 1); - info->sdynbss_base = cr.rela[0].r_offset; - if (info->sdynbss == NULL) - { - error (0, ENOMEM, "%s: Cannot build .sdynbss", dso->filename); - goto error_out; - } - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->shdr[bss1].sh_addr >= dso->phdr[i].p_vaddr - && dso->shdr[bss1].sh_addr - < dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - break; - if (i == dso->ehdr.e_phnum - || dso->shdr[bss2].sh_addr + dso->shdr[bss2].sh_size - > dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - { - error (0, 0, "%s: Copy relocs against more than one segment", - dso->filename); - goto error_out; - } - } - - info->dynbss_size = cr.rela[cr.count - 1].r_offset - - cr.rela[firstbss2].r_offset; - info->dynbss_size += cr.rela[cr.count - 1].r_addend; - info->dynbss = calloc (info->dynbss_size, 1); - info->dynbss_base = cr.rela[firstbss2].r_offset; - if (info->dynbss == NULL) - { - error (0, ENOMEM, "%s: Cannot build .dynbss", dso->filename); - goto error_out; - } - - /* emacs apparently has .rel.bss relocations against .data section, - crap. */ - if (dso->shdr[bss1].sh_type != SHT_NOBITS - && strcmp (name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[bss1].sh_name), - ".dynbss") != 0 - && strcmp (name, ".sdynbss") != 0) - { - error (0, 0, "%s: COPY relocations don't point into .bss or .sbss section", - dso->filename); - goto error_out; - } - if (bss1 != bss2 - && dso->shdr[bss2].sh_type != SHT_NOBITS - && strcmp (name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[bss2].sh_name), - ".dynbss") != 0 - && strcmp (name, ".sdynbss") != 0) - { - error (0, 0, "%s: COPY relocations don't point into .bss or .sbss section", - dso->filename); - goto error_out; - } - - for (i = 0; i < cr.count; ++i) - { - struct prelink_symbol *s; - DSO *ndso = NULL; - int j, reloc_class; - - reloc_class - = dso->arch->reloc_class (reloc_r_type (dso, cr.rela[i].r_info)); - - assert (reloc_class != RTYPE_CLASS_TLS); - - for (s = & info->symbols[reloc_r_sym (dso, cr.rela[i].r_info)]; s; - s = s->next) - if (s->reloc_class == reloc_class) - break; - - if (s == NULL || s->u.ent == NULL) - { - error (0, 0, "%s: Could not find symbol copy reloc is against", - dso->filename); - goto error_out; - } - - for (j = 1; j < ndeps; ++j) - if (info->ent->depends[j - 1] == s->u.ent) - { - ndso = info->dsos[j]; - break; - } - - assert (j < ndeps); - if (i < firstbss2) - j = get_relocated_mem (info, ndso, s->u.ent->base + s->value, - info->sdynbss + cr.rela[i].r_offset - - info->sdynbss_base, cr.rela[i].r_addend, - cr.rela[i].r_offset); - else - j = get_relocated_mem (info, ndso, s->u.ent->base + s->value, - info->dynbss + cr.rela[i].r_offset - - info->dynbss_base, cr.rela[i].r_addend, - cr.rela[i].r_offset); - - switch (j) - { - case 1: - error (0, 0, "%s: Could not find variable copy reloc is against", - dso->filename); - goto error_out; - case 2: - error (0, 0, "%s: Conflict partly overlaps with %08llx-%08llx area", - dso->filename, - (long long) cr.rela[i].r_offset, - (long long) (cr.rela[i].r_offset + cr.rela[i].r_addend)); - goto error_out; - } - } - } - - if (info->conflict_rela_size) - { - conflict_rela_cmp_dso = dso; - qsort (info->conflict_rela, info->conflict_rela_size, sizeof (GElf_Rela), - conflict_rela_cmp); - - /* Now make sure all conflict RELA's are against absolute 0 symbol. */ - for (i = 0; i < info->conflict_rela_size; ++i) - info->conflict_rela[i].r_info - = reloc_r_info (dso, 0, - reloc_r_type (dso, info->conflict_rela[i].r_info)); - - if (enable_cxx_optimizations && remove_redundant_cxx_conflicts (info)) - goto error_out; - } - - for (i = 1; i < ndeps; ++i) - if (info->dsos[i]) - close_dso (info->dsos[i]); - - info->dsos = NULL; - free (cr.rela); - return ret; - -error_out: - free (cr.rela); - free (info->dynbss); - free (info->sdynbss); - info->dynbss = NULL; - info->sdynbss = NULL; - for (i = 1; i < ndeps; ++i) - if (info->dsos[i]) - close_dso (info->dsos[i]); - return 1; -} diff --git a/trunk/src/crc32.c b/trunk/src/crc32.c deleted file mode 100644 index f36abb5..0000000 --- a/trunk/src/crc32.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <stdint.h> -#include <sys/types.h> - -/* Table computed with Mark Adler's makecrc.c utility. */ -static const uint32_t 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 -}; - -uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len) -{ - unsigned char *end; - - crc = ~crc; - for (end = buf + len; buf < end; ++buf) - crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); - return ~crc; -} diff --git a/trunk/src/cxx.c b/trunk/src/cxx.c deleted file mode 100644 index 4391ebe..0000000 --- a/trunk/src/cxx.c +++ /dev/null @@ -1,643 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2007, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <alloca.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/wait.h> -#include "prelink.h" -#include "reloc-info.h" - -static struct - { - const char *prefix; - unsigned char prefix_len, st_info, check_pltref; - } -specials[] = - { - /* G++ 3.0 ABI. */ - /* Virtual table. */ - { "_ZTV", 4, GELF_ST_INFO (STB_WEAK, STT_OBJECT), 1 }, - /* Typeinfo. */ - { "_ZTI", 4, GELF_ST_INFO (STB_WEAK, STT_OBJECT), 0 }, - /* G++ 2.96-RH ABI. */ - /* Virtual table. */ - { "__vt_", 5, GELF_ST_INFO (STB_WEAK, STT_OBJECT), 0 }, - { NULL, 0, 0, 0 } - }; - -struct find_cxx_sym_valsize -{ - GElf_Addr start; - GElf_Addr end; - unsigned int idx; - unsigned char mark; -}; - -struct find_cxx_sym_cache -{ - Elf_Data *symtab, *strtab; - int symsec, strsec, count; - struct find_cxx_sym_valsize vals[]; -}; - -struct find_cxx_sym -{ - DSO *dso; - int n; - struct find_cxx_sym_cache *cache; - struct prelink_entry *ent; - Elf_Data *symtab, *strtab; - int symsec, strsec; - int lastndx; - GElf_Sym sym; -}; - -static int -cachecmp (const void *a, const void *b) -{ - GElf_Addr va = ((const struct find_cxx_sym_valsize *) a)->start; - GElf_Addr vb = ((const struct find_cxx_sym_valsize *) b)->start; - - if (va < vb) - return -1; - if (va > vb) - return 1; - - va = ((const struct find_cxx_sym_valsize *) a)->end; - vb = ((const struct find_cxx_sym_valsize *) b)->end; - - if (va < vb) - return -1; - - return va > vb; -} - -static struct find_cxx_sym_cache * -create_cache (DSO *dso, int plt) -{ - Elf_Data *symtab, *strtab; - Elf_Scn *scn; - int symsec, strsec, ndx, dndx, maxndx; - struct find_cxx_sym_cache *cache; - GElf_Addr top; - - symsec = addr_to_sec (dso, dso->info[DT_SYMTAB]); - if (symsec == -1) - return (struct find_cxx_sym_cache *) -1UL; - scn = dso->scn[symsec]; - symtab = elf_getdata (scn, NULL); - assert (elf_getdata (scn, symtab) == NULL); - strsec = addr_to_sec (dso, dso->info[DT_STRTAB]); - if (strsec == -1) - return (struct find_cxx_sym_cache *) -1UL; - scn = dso->scn[strsec]; - strtab = elf_getdata (scn, NULL); - assert (elf_getdata (scn, strtab) == NULL); - maxndx = symtab->d_size / dso->shdr[symsec].sh_entsize; - - cache = malloc (sizeof (*cache) + sizeof (cache->vals[0]) * maxndx); - if (cache == NULL) - { - error (0, ENOMEM, "%s: Could load symbol table", dso->filename); - return NULL; - } - - cache->symsec = symsec; - cache->strsec = strsec; - cache->symtab = symtab; - cache->strtab = strtab; - for (ndx = 0, dndx = 0; ndx < maxndx; ++ndx) - { - GElf_Sym sym; - const char *name; - int k; - - gelfx_getsym (dso->elf, symtab, ndx, &sym); - if (plt) - { - if (sym.st_shndx != SHN_UNDEF || sym.st_value == 0) - continue; - } - else if (sym.st_shndx == SHN_UNDEF) - continue; - cache->vals[dndx].start = sym.st_value; - cache->vals[dndx].end = sym.st_value + sym.st_size; - cache->vals[dndx].idx = ndx; - cache->vals[dndx].mark = 0; - name = (const char *) strtab->d_buf + sym.st_name; - if (!plt && ELF32_ST_VISIBILITY (sym.st_other) == STV_DEFAULT) - for (k = 0; specials[k].prefix; ++k) - if (sym.st_info == specials[k].st_info - && strncmp (name, specials[k].prefix, - specials[k].prefix_len) == 0) - { - cache->vals[dndx].mark = 1; - break; - } - ++dndx; - } - - maxndx = dndx; - qsort (cache->vals, maxndx, sizeof (cache->vals[0]), cachecmp); - - if (!plt) - { - for (top = 0, ndx = 0; ndx < maxndx; ++ndx) - { - if (cache->vals[ndx].start < top - || (ndx < maxndx - 1 - && cache->vals[ndx].end > cache->vals[ndx + 1].start)) - cache->vals[ndx].mark = 0; - if (cache->vals[ndx].end > top) - top = cache->vals[ndx].end; - } - - for (ndx = dndx = 0; ndx < maxndx; ++ndx) - if (cache->vals[ndx].mark) - cache->vals[dndx++] = cache->vals[ndx]; - } - cache->count = dndx; - return cache; -} - -static int -find_cxx_sym (struct prelink_info *info, GElf_Addr addr, - struct find_cxx_sym *fcs, int reloc_size, - struct find_cxx_sym_cache **cache) -{ - int n, ndeps = info->ent->ndepends + 1; - unsigned int hi, lo, mid; - DSO *dso = NULL; - struct find_cxx_sym_cache *c; - - if (fcs->dso == NULL - || addr < fcs->dso->base - || addr >= fcs->dso->end) - { - for (n = 1; n < ndeps; ++n) - { - dso = info->dsos[n]; - if (addr >= dso->base - && addr < dso->end) - break; - } - - if (n == ndeps - && addr >= info->dso->base - && addr < info->dso->end) - { - n = 0; - dso = info->dso; - } - - assert (n < ndeps); - - if (cache[n] == NULL) - { - cache[n] = create_cache (dso, 0); - if (cache[n] == NULL) - return -2; - } - if (cache[n] == (struct find_cxx_sym_cache *) -1UL) - return -1; - - fcs->n = n; - fcs->ent = n ? info->ent->depends[n - 1] : info->ent; - fcs->dso = dso; - fcs->cache = cache[n]; - fcs->symsec = fcs->cache->symsec; - fcs->symtab = fcs->cache->symtab; - fcs->strsec = fcs->cache->strsec; - fcs->strtab = fcs->cache->strtab; - fcs->lastndx = -1; - } - else - dso = fcs->dso; - - c = fcs->cache; - lo = 0; - hi = c->count; - if (fcs->lastndx != -1) - { - if (c->vals[fcs->lastndx].start <= addr) - { - lo = fcs->lastndx; - if (hi - lo >= 16) - { - if (c->vals[lo + 2].start > addr) - hi = lo + 2; - else if (c->vals[lo + 15].start > addr) - hi = lo + 15; - } - } - else - { - hi = fcs->lastndx; - if (hi >= 15) - { - if (c->vals[hi - 2].start <= addr) - lo = hi - 2; - else if (c->vals[hi - 15].start <= addr) - lo = hi - 15; - } - } - } - while (lo < hi) - { - mid = (lo + hi) / 2; - if (c->vals[mid].start <= addr) - { - if (c->vals[mid].end >= addr + reloc_size) - { - gelfx_getsym (dso->elf, fcs->symtab, c->vals[mid].idx, - &fcs->sym); - fcs->lastndx = mid; - return c->vals[mid].idx; - } - lo = mid + 1; - } - else - hi = mid; - } - - return -1; -} - -/* The idea here is that C++ virtual tables are always emitted - in .gnu.linkonce.d.* sections as WEAK symbols and they - need to be the same. - We check if they are and if yes, remove conflicts against - virtual tables which will not be used. */ - -int -remove_redundant_cxx_conflicts (struct prelink_info *info) -{ - int i, j, k, n, o, state, removed = 0; - int ndx, sec; - unsigned int hi, lo, mid; - int reloc_type, reloc_size; - struct find_cxx_sym fcs1, fcs2; - char *mem1, *mem2; - const char *name = NULL, *secname = NULL; - GElf_Addr symtab_start; - GElf_Word symoff; - Elf_Data *binsymtab = NULL; - int binsymtabsec; - struct prelink_conflict *conflict; - struct find_cxx_sym_cache **cache; - struct find_cxx_sym_cache *binsymcache = NULL; - int ret = 0; - int rtype_class_valid; - - /* Don't bother doing this for non-C++ programs. */ - for (i = 0; i < info->ent->ndepends; ++i) - if (strstr (info->ent->depends[i]->canon_filename, "libstdc++")) - break; - if (i == info->ent->ndepends) - return 0; - - binsymtabsec = addr_to_sec (info->dso, info->dso->info[DT_SYMTAB]); - if (binsymtabsec != -1) - { - Elf_Scn *scn = info->dso->scn[binsymtabsec]; - - binsymtab = elf_getdata (scn, NULL); - assert (elf_getdata (scn, binsymtab) == NULL); - } - - rtype_class_valid = info->dso->arch->rtype_class_valid; - - state = 0; - memset (&fcs1, 0, sizeof (fcs1)); - memset (&fcs2, 0, sizeof (fcs2)); - cache = alloca (sizeof (struct find_cxx_sym_cache *) - * (info->ent->ndepends + 1)); - memset (cache, '\0', sizeof (struct find_cxx_sym_cache *) - * (info->ent->ndepends + 1)); - for (i = 0; i < info->conflict_rela_size; ++i) - { - size_t cidx; - - reloc_type = reloc_r_type (info->dso, info->conflict_rela[i].r_info); - reloc_size = info->dso->arch->reloc_size (reloc_type); - - if (reloc_r_sym (info->dso, info->conflict_rela[i].r_info) != 0) - continue; - - if (state - && fcs1.sym.st_value <= info->conflict_rela[i].r_offset - && fcs1.sym.st_value + fcs1.sym.st_size - >= info->conflict_rela[i].r_offset + reloc_size) - { - if (state == 3) - goto remove_noref; - if (state == 2) - goto check_pltref; - continue; - } - - n = find_cxx_sym (info, info->conflict_rela[i].r_offset, - &fcs1, reloc_size, cache); - - state = 0; - if (n == -1) - continue; - if (n == -2) - { - ret = 1; - goto out_free_cache; - } - state = 1; - sec = addr_to_sec (fcs1.dso, fcs1.sym.st_value); - if (sec == -1) - continue; - secname = strptr (fcs1.dso, fcs1.dso->ehdr.e_shstrndx, - fcs1.dso->shdr[sec].sh_name); - if (secname == NULL) - continue; - - name = (const char *) fcs1.strtab->d_buf + fcs1.sym.st_name; - - for (k = 0; specials[k].prefix; ++k) - if (ELF32_ST_VISIBILITY (fcs1.sym.st_other) == STV_DEFAULT - && fcs1.sym.st_info == specials[k].st_info - && strncmp (name, specials[k].prefix, specials[k].prefix_len) == 0) - break; - - if (specials[k].prefix == NULL) - continue; - - if (strcmp (secname, ".data") != 0 - && strcmp (secname, ".data.rel.ro") != 0 - && strcmp (secname, ".sdata") != 0) - continue; - - if (specials[k].check_pltref) - state = 2; - - symtab_start = fcs1.dso->shdr[fcs1.symsec].sh_addr - fcs1.dso->base; - symoff = symtab_start + n * fcs1.dso->shdr[fcs1.symsec].sh_entsize; - - cidx = 0; - if (info->conflicts[fcs1.n].hash != &info->conflicts[fcs1.n].first) - cidx = symoff % 251; - for (conflict = info->conflicts[fcs1.n].hash[cidx]; conflict; - conflict = conflict->next) - if (conflict->symoff == symoff - && conflict->reloc_class == rtype_class_valid) - break; - - if (conflict == NULL) - goto check_pltref; - - if (conflict->conflict.ent != fcs1.ent - || fcs1.dso->base + conflict->conflictval != fcs1.sym.st_value) - goto check_pltref; - - if (verbose > 4) - error (0, 0, "Possible C++ conflict removal from unreferenced table at %s:%s+%d", - fcs1.dso->filename, name, - (int) (info->conflict_rela[i].r_offset - fcs1.sym.st_value)); - - /* Limit size slightly. */ - if (fcs1.sym.st_size > 16384) - goto check_pltref; - - o = find_cxx_sym (info, conflict->lookup.ent->base + conflict->lookupval, - &fcs2, fcs1.sym.st_size, cache); - - if (o == -2) - { - ret = 1; - goto out_free_cache; - } - - if (o == -1 - || fcs1.sym.st_size != fcs2.sym.st_size - || fcs1.sym.st_info != fcs2.sym.st_info - || ELF32_ST_VISIBILITY (fcs2.sym.st_other) != STV_DEFAULT - || strcmp (name, (char *) fcs2.strtab->d_buf + fcs2.sym.st_name) != 0) - goto check_pltref; - - mem1 = malloc (fcs1.sym.st_size * 2); - if (mem1 == NULL) - { - error (0, ENOMEM, "%s: Could not compare %s arrays", - info->dso->filename, name); - ret = 1; - goto out_free_cache; - } - - mem2 = mem1 + fcs1.sym.st_size; - - if (get_relocated_mem (info, fcs1.dso, fcs1.sym.st_value, mem1, - fcs1.sym.st_size, 0) - || get_relocated_mem (info, fcs2.dso, fcs2.sym.st_value, mem2, - fcs1.sym.st_size, 0) - || memcmp (mem1, mem2, fcs1.sym.st_size) != 0) - { - free (mem1); - goto check_pltref; - } - - free (mem1); - - state = 3; - -remove_noref: - if (verbose > 3) - error (0, 0, "Removing C++ conflict from unreferenced table at %s:%s+%d", - fcs1.dso->filename, name, - (int) (info->conflict_rela[i].r_offset - fcs1.sym.st_value)); - - info->conflict_rela[i].r_info = - reloc_r_info (info->dso, 1, - reloc_r_type (info->dso, info->conflict_rela[i].r_info)); - ++removed; - continue; - -check_pltref: - /* If the binary calls directly (or takes its address) one of the - methods in a virtual table, but doesn't define it, there is no - need to leave conflicts in the virtual table which will only - slow down the code (as it has to hop through binary's .plt - back to the method). */ - if (state != 2 - || info->conflict_rela[i].r_addend < info->dso->base - || info->conflict_rela[i].r_addend >= info->dso->end - || binsymtab == NULL) - continue; - - if (binsymcache == NULL) - { - binsymcache = create_cache (info->dso, 1); - if (binsymcache == NULL) - { - ret = 1; - goto out_free_cache; - } - } - if (binsymcache == (struct find_cxx_sym_cache *) -1UL) - continue; - - lo = 0; - mid = 0; - hi = binsymcache->count; - while (lo < hi) - { - mid = (lo + hi) / 2; - if (binsymcache->vals[mid].start < info->conflict_rela[i].r_addend) - lo = mid + 1; - else if (binsymcache->vals[mid].start - > info->conflict_rela[i].r_addend) - hi = mid; - else - break; - } - if (lo >= hi) - continue; - - while (mid > 0 && binsymcache->vals[mid - 1].start - == info->conflict_rela[i].r_addend) - --mid; - - while (mid < binsymcache->count - && binsymcache->vals[mid].start - == info->conflict_rela[i].r_addend) - { - GElf_Sym sym; - - ndx = binsymcache->vals[mid].idx; - mid++; - gelfx_getsym (info->dso->elf, binsymtab, ndx, &sym); - assert (sym.st_value == info->conflict_rela[i].r_addend); - if (sym.st_shndx == SHN_UNDEF && sym.st_value) - { - struct prelink_symbol *s; - size_t maxidx, l; - - if (verbose > 4) - error (0, 0, "Possible C++ conflict removal due to reference to binary's .plt at %s:%s+%d", - fcs1.dso->filename, name, - (int) (info->conflict_rela[i].r_offset - - fcs1.sym.st_value)); - - for (s = &info->symbols[ndx]; s; s = s->next) - if (s->reloc_class == RTYPE_CLASS_PLT) - break; - - if (s == NULL) - break; - - maxidx = 1; - if (info->conflicts[fcs1.n].hash - != &info->conflicts[fcs1.n].first) - { - if (info->conflicts[fcs1.n].hash2 == NULL) - { - info->conflicts[fcs1.n].hash2 - = calloc (sizeof (struct prelink_conflict *), 251); - if (info->conflicts[fcs1.n].hash2 != NULL) - { - for (l = 0; l < 251; l++) - for (conflict = info->conflicts[fcs1.n].hash[l]; - conflict; conflict = conflict->next) - if (conflict->reloc_class == rtype_class_valid - && conflict->conflict.ent) - { - size_t ccidx - = (conflict->lookup.ent->base - + conflict->lookupval) % 251; - conflict->next2 - = info->conflicts[fcs1.n].hash2[ccidx]; - info->conflicts[fcs1.n].hash2[ccidx] - = conflict; - } - } - } - if (info->conflicts[fcs1.n].hash2 != NULL) - { - size_t ccidx = info->conflict_rela[i].r_addend % 251; - for (conflict = info->conflicts[fcs1.n].hash2[ccidx]; - conflict; conflict = conflict->next2) - if (conflict->lookup.ent->base + conflict->lookupval - == info->conflict_rela[i].r_addend - && (conflict->conflict.ent->base - + conflict->conflictval - == s->u.ent->base + s->value)) - goto pltref_remove; - break; - } - maxidx = 251; - } - - for (l = 0; l < maxidx; l++) - for (conflict = info->conflicts[fcs1.n].hash[l]; - conflict; conflict = conflict->next) - if (conflict->lookup.ent->base + conflict->lookupval - == info->conflict_rela[i].r_addend - && conflict->conflict.ent - && (conflict->conflict.ent->base - + conflict->conflictval == s->u.ent->base + s->value) - && conflict->reloc_class == rtype_class_valid) - { -pltref_remove: - if (verbose > 3) - error (0, 0, "Removing C++ conflict due to reference to binary's .plt at %s:%s+%d", - fcs1.dso->filename, name, - (int) (info->conflict_rela[i].r_offset - - fcs1.sym.st_value)); - - info->conflict_rela[i].r_info = - reloc_r_info (info->dso, 1, reloc_r_type (info->dso, info->conflict_rela[i].r_info)); - ++removed; - goto pltref_check_done; - } - -pltref_check_done: - break; - } - } - } - - if (removed) - { - for (i = 0, j = 0; i < info->conflict_rela_size; ++i) - if (reloc_r_sym (info->dso, info->conflict_rela[i].r_info) == 0) - { - if (i != j) - info->conflict_rela[j] = info->conflict_rela[i]; - ++j; - } - info->conflict_rela_size = j; - } - -out_free_cache: - for (i = 0; i < info->ent->ndepends + 1; i++) - if (cache[i] && cache[i] != (struct find_cxx_sym_cache *) -1UL) - free (cache[i]); - if (binsymcache && binsymcache != (struct find_cxx_sym_cache *) -1UL) - free (binsymcache); - return ret; -} diff --git a/trunk/src/data.c b/trunk/src/data.c deleted file mode 100644 index 751f96f..0000000 --- a/trunk/src/data.c +++ /dev/null @@ -1,339 +0,0 @@ -/* Copyright (C) 2001, 2002 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include "prelink.h" - -#define UREAD(le,nn) \ -uint##nn##_t \ -read_u##le##nn (DSO *dso, GElf_Addr addr) \ -{ \ - Elf_Type type; \ - unsigned char *data = get_data (dso, addr, NULL, &type); \ - \ - if (data == NULL) \ - return 0; \ - \ - if (type == ELF_T_BYTE) \ - return buf_read_u##le##nn (data); \ - else \ - return *(uint##nn##_t *)data; \ -} - -#define WRITE(le,nn) \ -int \ -write_##le##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val) \ -{ \ - int sec; \ - Elf_Type type; \ - unsigned char *data = get_data (dso, addr, &sec, &type); \ - \ - if (data == NULL) \ - return -1; \ - \ - if (type == ELF_T_BYTE) \ - buf_write_##le##nn (data, val); \ - else \ - *(uint##nn##_t *)data = val; \ - elf_flagscn (dso->scn[sec], ELF_C_SET, ELF_F_DIRTY); \ - return 0; \ -} - -#define BUFREADUNE(nn) \ -uint##nn##_t \ -buf_read_une##nn (DSO *dso, unsigned char *buf) \ -{ \ - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) \ - return buf_read_ule##nn (buf); \ - else \ - return buf_read_ube##nn (buf); \ -} - -#define READUNE(nn) \ -uint##nn##_t \ -read_une##nn (DSO *dso, GElf_Addr addr) \ -{ \ - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) \ - return read_ule##nn (dso, addr); \ - else \ - return read_ube##nn (dso, addr); \ -} - -#define WRITENE(nn) \ -void \ -write_ne##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val) \ -{ \ - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) \ - write_le##nn (dso, addr, val); \ - else \ - write_be##nn (dso, addr, val); \ -} - -#define BUFWRITENE(nn) \ -void \ -buf_write_ne##nn (DSO *dso, unsigned char *buf, \ - uint##nn##_t val) \ -{ \ - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) \ - buf_write_le##nn (buf, val); \ - else \ - buf_write_be##nn (buf, val); \ -} - -#define READWRITE(le,nn) UREAD(le,nn) WRITE(le,nn) -#define READWRITESIZE(nn) \ - READWRITE(le,nn) READWRITE(be,nn) \ - BUFREADUNE(nn) READUNE(nn) \ - WRITENE(nn) BUFWRITENE(nn) - -unsigned char * -get_data (DSO *dso, GElf_Addr addr, int *secp, Elf_Type *typep) -{ - int sec = addr_to_sec (dso, addr); - Elf_Data *data = NULL; - - if (sec == -1) - return NULL; - - if (secp) - *secp = sec; - - addr -= dso->shdr[sec].sh_addr; - while ((data = elf_getdata (dso->scn[sec], data)) != NULL) - if (data->d_off <= addr && data->d_off + data->d_size > addr) - { - if (typep) *typep = data->d_type; - return (unsigned char *) data->d_buf + (addr - data->d_off); - } - return NULL; -} - -/* Initialize IT so that the first byte it provides is address ADDR - of DSO. */ - -void -init_data_iterator (struct data_iterator *it, DSO *dso, GElf_Addr addr) -{ - it->dso = dso; - it->data = NULL; - it->addr = addr; -} - -/* Return a pointer to the next SIZE bytes pointed to by IT, and move - IT to the end of the returned block. Return null if the data could - not be read for some reason. */ - -unsigned char * -get_data_from_iterator (struct data_iterator *it, GElf_Addr size) -{ - unsigned char *ptr; - - /* If we're at the end of a data block, move onto the next. */ - if (it->data && it->data->d_off + it->data->d_size == it->sec_offset) - it->data = elf_getdata (it->dso->scn[it->sec], it->data); - - if (it->data == NULL) - { - /* Find out which section contains the next byte. */ - it->sec = addr_to_sec (it->dso, it->addr); - if (it->sec < 0) - return NULL; - - /* Fast-forward to the block that contains ADDR, if any. */ - it->sec_offset = it->addr - it->dso->shdr[it->sec].sh_addr; - do - it->data = elf_getdata (it->dso->scn[it->sec], it->data); - while (it->data && it->data->d_off + it->data->d_size <= it->sec_offset); - } - - /* Make sure that all the data we want is included in this block. */ - if (it->data == NULL - || it->data->d_off > it->sec_offset - || it->data->d_off + it->data->d_size < it->sec_offset + size) - return NULL; - - ptr = (unsigned char *) it->data->d_buf + (it->sec_offset - it->data->d_off); - it->sec_offset += size; - it->addr += size; - return ptr; -} - -/* Read the symbol pointed to by IT into SYM and move IT onto the - next symbol. Return true on success. */ - -int -get_sym_from_iterator (struct data_iterator *it, GElf_Sym *sym) -{ - GElf_Addr offset, size; - unsigned char *ptr; - - size = gelf_fsize (it->dso->elf, ELF_T_SYM, 1, EV_CURRENT); - ptr = get_data_from_iterator (it, size); - if (ptr != NULL) - { - offset = ptr - (unsigned char *) it->data->d_buf; - if (offset % size == 0) - { - gelfx_getsym (it->dso->elf, it->data, offset / size, sym); - return 1; - } - } - return 0; -} - -inline uint8_t -buf_read_u8 (unsigned char *data) -{ - return *data; -} - -inline uint16_t -buf_read_ule16 (unsigned char *data) -{ - return data[0] | (data[1] << 8); -} - -inline uint16_t -buf_read_ube16 (unsigned char *data) -{ - return data[1] | (data[0] << 8); -} - -inline uint32_t -buf_read_ule32 (unsigned char *data) -{ - return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); -} - -inline uint32_t -buf_read_ube32 (unsigned char *data) -{ - return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24); -} - -inline uint64_t -buf_read_ule64 (unsigned char *data) -{ - return (data[0] | (data[1] << 8) | (data[2] << 16)) - | (((uint64_t)data[3]) << 24) - | (((uint64_t)data[4]) << 32) - | (((uint64_t)data[5]) << 40) - | (((uint64_t)data[6]) << 48) - | (((uint64_t)data[7]) << 56); -} - -inline uint64_t -buf_read_ube64 (unsigned char *data) -{ - return (data[7] | (data[6] << 8) | (data[5] << 16)) - | (((uint64_t)data[4]) << 24) - | (((uint64_t)data[3]) << 32) - | (((uint64_t)data[2]) << 40) - | (((uint64_t)data[1]) << 48) - | (((uint64_t)data[0]) << 56); -} - -inline void -buf_write_8 (unsigned char *data, uint8_t val) -{ - *data = val; -} - -inline void -buf_write_le16 (unsigned char *data, uint16_t val) -{ - data[0] = val; - data[1] = val >> 8; -} - -inline void -buf_write_be16 (unsigned char *data, uint16_t val) -{ - data[1] = val; - data[0] = val >> 8; -} - -inline void -buf_write_le32 (unsigned char *data, uint32_t val) -{ - data[0] = val; - data[1] = val >> 8; - data[2] = val >> 16; - data[3] = val >> 24; -} - -inline void -buf_write_be32 (unsigned char *data, uint32_t val) -{ - data[3] = val; - data[2] = val >> 8; - data[1] = val >> 16; - data[0] = val >> 24; -} - -inline void -buf_write_le64 (unsigned char *data, uint64_t val) -{ - data[0] = val; - data[1] = val >> 8; - data[2] = val >> 16; - data[3] = val >> 24; - data[4] = val >> 32; - data[5] = val >> 40; - data[6] = val >> 48; - data[7] = val >> 56; -} - -inline void -buf_write_be64 (unsigned char *data, uint64_t val) -{ - data[7] = val; - data[6] = val >> 8; - data[5] = val >> 16; - data[4] = val >> 24; - data[3] = val >> 32; - data[2] = val >> 40; - data[1] = val >> 48; - data[0] = val >> 56; -} - -READWRITE(,8) -READWRITESIZE(16) -READWRITESIZE(32) -READWRITESIZE(64) - -const char * -strptr (DSO *dso, int sec, off_t offset) -{ - Elf_Scn *scn; - Elf_Data *data; - - scn = dso->scn[sec]; - if (offset >= 0 && offset < dso->shdr[sec].sh_size) - { - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - if (data->d_buf - && offset >= data->d_off - && offset < data->d_off + data->d_size) - return (const char *) data->d_buf + (offset - data->d_off); - } - } - - return NULL; -} diff --git a/trunk/src/doit.c b/trunk/src/doit.c deleted file mode 100644 index 6b07afb..0000000 --- a/trunk/src/doit.c +++ /dev/null @@ -1,256 +0,0 @@ -/* Copyright (C) 2001, 2003, 2004, 2005, 2007 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <alloca.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <time.h> -#include <unistd.h> -#include "prelinktab.h" - -struct collect_ents - { - struct prelink_entry **ents; - int nents; - }; - -static int -find_ents (void **p, void *info) -{ - struct collect_ents *l = (struct collect_ents *) info; - struct prelink_entry *e = * (struct prelink_entry **) p; - - e->u.tmp = 0; - if ((e->type == ET_DYN && e->done == 1) - || (e->type == ET_EXEC && e->done == 0 && ! libs_only)) - l->ents[l->nents++] = e; - - return 1; -} - -static void -prelink_ent (struct prelink_entry *ent) -{ - int i, j; - DSO *dso; - struct stat64 st; - struct prelink_link *hardlink; - char *move = NULL, *move_temp; - size_t movelen = 0; - - for (i = 0; i < ent->ndepends; ++i) - if (ent->depends[i]->done == 1) - prelink_ent (ent->depends[i]); - - for (i = 0; i < ent->ndepends; ++i) - if (ent->depends[i]->done != 2) - { - ent->done = 0; - if (! undo) - ent->type = ET_UNPRELINKABLE; - if (verbose) - error (0, 0, "Could not prelink %s because its dependency %s could not be prelinked", - ent->filename, ent->depends[i]->filename); - return; - } - - ent->u.tmp = 1; - for (i = 0; i < ent->ndepends; ++i) - ent->depends[i]->u.tmp = 1; - for (i = 0; i < ent->ndepends; ++i) - { - struct prelink_entry *dent = ent->depends[i]; - for (j = 0; j < dent->ndepends; ++j) - if (dent->depends[j]->u.tmp == 0) - { - ent->done = 0; - if (! undo) - ent->type = ET_UNPRELINKABLE; - if (verbose) - error (0, 0, "Could not prelink %s because it doesn't use %s, but one of its dependencies has been prelinked against it", - ent->filename, dent->depends[j]->filename); - ent->u.tmp = 0; - for (i = 0; i < ent->ndepends; ++i) - ent->depends[i]->u.tmp = 0; - return; - } - } - ent->u.tmp = 0; - for (i = 0; i < ent->ndepends; ++i) - ent->depends[i]->u.tmp = 0; - - if (verbose) - { - if (dry_run) - printf ("Would prelink %s\n", ent->canon_filename); - else - printf ("Prelinking %s\n", ent->canon_filename); - } - - dso = open_dso (ent->canon_filename); - if (dso == NULL) - goto error_out; - - if (fstat64 (dso->fd, &st) < 0) - { - error (0, errno, "%s changed during prelinking", ent->filename); - goto error_out; - } - - if (st.st_dev != ent->dev || st.st_ino != ent->ino) - { - error (0, 0, "%s changed during prelinking", ent->filename); - goto error_out; - } - - if (dry_run) - close_dso (dso); - else - { - if (prelink_prepare (dso)) - goto make_unprelinkable; - if (ent->type == ET_DYN && relocate_dso (dso, ent->base)) - goto make_unprelinkable; - if (prelink (dso, ent)) - goto make_unprelinkable; - if (update_dso (dso, NULL)) - { - dso = NULL; - goto error_out; - } - } - ent->done = 2; - ent->flags |= PCF_PRELINKED; - - /* Redo hardlinks. */ - for (hardlink = ent->hardlink; hardlink; hardlink = hardlink->next) - { - size_t len; - - if (wrap_lstat64 (hardlink->canon_filename, &st) < 0) - { - error (0, 0, "Could not stat %s (former hardlink to %s)", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (st.st_dev != ent->dev || st.st_ino != ent->ino) - { - error (0, 0, "%s is no longer hardlink to %s", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (verbose) - { - if (dry_run) - printf ("Would link %s to %s\n", hardlink->canon_filename, - ent->canon_filename); - else - printf ("Linking %s to %s\n", hardlink->canon_filename, - ent->canon_filename); - } - - if (dry_run) - continue; - - len = strlen (hardlink->canon_filename); - if (len + sizeof (".#prelink#") > movelen) - { - movelen = len + sizeof (".#prelink#"); - move_temp = move; - move = realloc (move, movelen); - if (move == NULL) - { - free(move_temp); - error (0, ENOMEM, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - movelen = 0; - continue; - } - } - - memcpy (mempcpy (move, hardlink->canon_filename, len), ".#prelink#", - sizeof (".#prelink#")); - if (wrap_rename (hardlink->canon_filename, move) < 0) - { - error (0, errno, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (wrap_link (ent->canon_filename, hardlink->canon_filename) < 0) - { - error (0, errno, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - - if (wrap_rename (move, hardlink->canon_filename) < 0) - { - error (0, errno, "Could not rename %s back to %s", - move, hardlink->canon_filename); - } - continue; - } - - if (wrap_unlink (move) < 0) - { - error (0, errno, "Could not unlink %s", move); - continue; - } - } - free (move); - - if (! dry_run && wrap_stat64 (ent->canon_filename, &st) >= 0) - { - ent->dev = st.st_dev; - ent->ino = st.st_ino; - ent->ctime = st.st_ctime; - ent->mtime = st.st_mtime; - } - return; - -make_unprelinkable: - if (! undo) - ent->type = ET_UNPRELINKABLE; -error_out: - ent->done = 0; - if (dso) - close_dso (dso); - return; -} - -void -prelink_all (void) -{ - struct collect_ents l; - int i; - - l.ents = - (struct prelink_entry **) alloca (prelink_entry_count - * sizeof (struct prelink_entry *)); - l.nents = 0; - htab_traverse (prelink_filename_htab, find_ents, &l); - - for (i = 0; i < l.nents; ++i) - if (l.ents[i]->done == 1 - || (l.ents[i]->done == 0 && l.ents[i]->type == ET_EXEC)) - prelink_ent (l.ents[i]); -} diff --git a/trunk/src/dso.c b/trunk/src/dso.c deleted file mode 100644 index 983f1d8..0000000 --- a/trunk/src/dso.c +++ /dev/null @@ -1,2013 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2010 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <time.h> -#include <unistd.h> -#include <utime.h> -#include "prelink.h" - -#if defined HAVE_LIBSELINUX && defined HAVE_SELINUX_SELINUX_H -#include <selinux/selinux.h> -#define USE_SELINUX -#endif - -#include <sys/xattr.h> - -#define RELOCATE_SCN(shf) \ - ((shf) & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)) - -#ifndef ELF_F_PERMISSIVE -# define ELF_F_PERMISSIVE 0 -#endif - -void -read_dynamic (DSO *dso) -{ - int i; - - memset (dso->info, 0, sizeof(dso->info)); - dso->info_set_mask = 0; - for (i = 0; i < dso->ehdr.e_shnum; i++) - if (dso->shdr[i].sh_type == SHT_DYNAMIC) - { - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[i]; - GElf_Dyn dyn; - - dso->dynamic = i; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - - maxndx = data->d_size / dso->shdr[i].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - if (dyn.d_tag == DT_NULL) - break; - else if ((GElf_Xword) dyn.d_tag < DT_NUM) - { - dso->info[dyn.d_tag] = dyn.d_un.d_val; - if (dyn.d_tag < 50) - dso->info_set_mask |= (1ULL << dyn.d_tag); - } - else if (dyn.d_tag == DT_CHECKSUM) - { - dso->info_DT_CHECKSUM = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_CHECKSUM_BIT); - } - else if (dyn.d_tag == DT_GNU_PRELINKED) - { - dso->info_DT_GNU_PRELINKED = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_GNU_PRELINKED_BIT); - } - else if (dyn.d_tag == DT_VERDEF) - { - dso->info_DT_VERDEF = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_VERDEF_BIT); - } - else if (dyn.d_tag == DT_VERNEED) - { - dso->info_DT_VERNEED = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_VERNEED_BIT); - } - else if (dyn.d_tag == DT_VERSYM) - { - dso->info_DT_VERSYM = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_VERSYM_BIT); - } - else if (dyn.d_tag == DT_FILTER) - dso->info_set_mask |= (1ULL << DT_FILTER_BIT); - else if (dyn.d_tag == DT_AUXILIARY) - dso->info_set_mask |= (1ULL << DT_AUXILIARY_BIT); - else if (dyn.d_tag == DT_LOPROC) - dso->info_set_mask |= (1ULL << DT_LOPROC_BIT); - else if (dyn.d_tag == DT_GNU_HASH) - { - dso->info_DT_GNU_HASH = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_GNU_HASH_BIT); - } - else if (dyn.d_tag == DT_TLSDESC_PLT) - { - dso->info_DT_TLSDESC_PLT = dyn.d_un.d_val; - dso->info_set_mask |= (1ULL << DT_TLSDESC_PLT_BIT); - } - if (dso->ehdr.e_machine == EM_MIPS) - { - if (dyn.d_tag == DT_MIPS_LOCAL_GOTNO) - dso->info_DT_MIPS_LOCAL_GOTNO = dyn.d_un.d_val; - else if (dyn.d_tag == DT_MIPS_GOTSYM) - dso->info_DT_MIPS_GOTSYM = dyn.d_un.d_val; - else if (dyn.d_tag == DT_MIPS_SYMTABNO) - dso->info_DT_MIPS_SYMTABNO = dyn.d_un.d_val; - else if (dyn.d_tag == DT_MIPS_PLTGOT) - dso->info_DT_MIPS_PLTGOT = dyn.d_un.d_val; - } - } - if (ndx < maxndx) - break; - } - } -} - -int -set_dynamic (DSO *dso, GElf_Word tag, GElf_Addr value, int fatal) -{ - Elf_Data *data; - Elf_Scn *scn; - GElf_Dyn dyn; - int ndx, maxndx; - uint64_t mask = dso->info_set_mask; - - assert (dso->shdr[dso->dynamic].sh_type == SHT_DYNAMIC); - - scn = dso->scn[dso->dynamic]; - - data = elf_getdata (scn, NULL); - assert (elf_getdata (scn, data) == NULL); - - switch (tag) - { - case DT_CHECKSUM: - mask |= (1ULL << DT_CHECKSUM_BIT); break; - case DT_GNU_PRELINKED: - mask |= (1ULL << DT_GNU_PRELINKED_BIT); break; - case DT_VERDEF: - mask |= (1ULL << DT_VERDEF_BIT); break; - case DT_VERNEED: - mask |= (1ULL << DT_VERNEED_BIT); break; - case DT_VERSYM: - mask |= (1ULL << DT_VERSYM_BIT); break; - default: - if (tag < DT_NUM && tag < 50) - mask |= (1ULL << tag); - break; - } - - maxndx = data->d_size / dso->shdr[dso->dynamic].sh_entsize; - for (ndx = 0; ndx < maxndx; ndx++) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - if (dyn.d_tag == DT_NULL) - break; - else if (dyn.d_tag == tag) - { - if (dyn.d_un.d_ptr != value) - { - dyn.d_un.d_ptr = value; - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - } - - return 0; - } - } - assert (ndx < maxndx); - - if (ndx + 1 < maxndx) - { - /* DT_NULL is not the last dynamic entry. */ - gelfx_update_dyn (dso->elf, data, ndx + 1, &dyn); - dyn.d_tag = tag; - dyn.d_un.d_ptr = value; - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - dso->info_set_mask = mask; - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - return 0; - } - - if (fatal) - error (0, 0, "%s: Not enough room to add .dynamic entry", - dso->filename); - return 1; -} - -int -check_dso (DSO *dso) -{ - int i, last = 1; - - /* FIXME: Several routines in prelink and in libelf-0.7.0 too - rely on sh_offset's monotonically increasing. */ - for (i = 2; i < dso->ehdr.e_shnum; ++i) - { - if (dso->shdr[last].sh_offset - + (dso->shdr[last].sh_type == SHT_NOBITS - ? 0 : dso->shdr[last].sh_size) > dso->shdr[i].sh_offset) - { - if (!dso->permissive - || RELOCATE_SCN (dso->shdr[last].sh_flags) - || RELOCATE_SCN (dso->shdr[i].sh_flags)) - { - error (0, 0, "%s: section file offsets not monotonically increasing", - dso->filename); - return 1; - } - } - if (!dso->permissive - || (dso->shdr[i].sh_type != SHT_NOBITS && dso->shdr[i].sh_size != 0)) - last = i; - } - -#ifndef DSO_READONLY - if (dso_has_bad_textrel (dso)) - { - error (0, 0, "%s has text relocations", dso->filename); - return 1; - } -#endif - - return 0; -} - -DSO * -open_dso (const char *name) -{ - int fd; - - fd = wrap_open (name, O_RDONLY); - if (fd == -1) - { - error (0, errno, "cannot open \"%s\"", name); - return NULL; - } - return fdopen_dso (fd, name); -} - -/* WARNING: If prelink is ever multi-threaded, this will not work - Other alternatives are: - 1) make section_cmp nested function - trampolines - vs. non-exec stack needs to be resolved for it though - 2) make the variable __thread - 3) use locking around the qsort - */ -static DSO *section_cmp_dso; - -static int -section_cmp (const void *A, const void *B) -{ - int *a = (int *) A; - int *b = (int *) B; - DSO *dso = section_cmp_dso; - - if (dso->shdr[*a].sh_offset < dso->shdr[*b].sh_offset) - return -1; - if (dso->shdr[*a].sh_offset > dso->shdr[*b].sh_offset) - return 1; - if (*a < *b) - return -1; - return *a > *b; -} - -DSO * -fdopen_dso (int fd, const char *name) -{ - Elf *elf = NULL; - GElf_Ehdr ehdr; - GElf_Addr last_off; - int i, j, k, last, *sections, *invsections; - DSO *dso = NULL; -#ifndef DSO_READONLY - struct PLArch *plarch; - extern struct PLArch __start_pl_arch[], __stop_pl_arch[]; -#endif /* DSO_READONLY */ - - elf = elf_begin (fd, ELF_C_READ, NULL); - if (elf == NULL) - { - error (0, 0, "cannot open ELF file: %s", elf_errmsg (-1)); - goto error_out; - } - - if (elf_kind (elf) != ELF_K_ELF) - { - error (0, 0, "\"%s\" is not an ELF file", name); - goto error_out; - } - - if (gelf_getehdr (elf, &ehdr) == NULL) - { - error (0, 0, "cannot get the ELF header: %s", - elf_errmsg (-1)); - goto error_out; - } - - if (ehdr.e_type != ET_DYN && ehdr.e_type != ET_EXEC) - { - error (0, 0, "\"%s\" is not a shared library", name); - goto error_out; - } - - if (ehdr.e_shnum == 0) - { - GElf_Phdr phdr; - - /* Check for UPX compressed executables. */ - if (ehdr.e_type == ET_EXEC - && ehdr.e_phnum > 0 - && (gelf_getphdr (elf, 0, &phdr), phdr.p_type == PT_LOAD) - && phdr.p_filesz >= 256 - && phdr.p_filesz <= 4096 - && phdr.p_offset == 0 - && ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize < phdr.p_filesz) - { - char *buf = alloca (phdr.p_filesz); - size_t start = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize; - - if (pread (fd, buf, phdr.p_filesz, 0) == phdr.p_filesz - && memmem (buf + start, phdr.p_filesz - start, - "UPX!", 4) != NULL) - { - error (0, 0, "\"%s\" is UPX compressed executable", name); - goto error_out; - } - } - error (0, 0, "\"%s\" has no section headers", name); - goto error_out; - } - - /* Allocate DSO structure. Leave place for additional 20 new section - headers. */ - dso = (DSO *) - malloc (sizeof(DSO) + (ehdr.e_shnum + 20) * sizeof(GElf_Shdr) - + (ehdr.e_phnum + 1) * sizeof(GElf_Phdr) - + (ehdr.e_shnum + 20) * sizeof(Elf_Scn *)); - if (!dso) - { - error (0, ENOMEM, "Could not open DSO"); - goto error_out; - } - - elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT | ELF_F_PERMISSIVE); - - memset (dso, 0, sizeof(DSO)); - dso->elf = elf; - dso->ehdr = ehdr; - dso->phdr = (GElf_Phdr *) &dso->shdr[ehdr.e_shnum + 20]; - dso->scn = (Elf_Scn **) &dso->phdr[ehdr.e_phnum + 1]; - switch (ehdr.e_ident[EI_CLASS]) - { - case ELFCLASS32: - dso->mask = 0xffffffff; break; - case ELFCLASS64: - dso->mask = 0xffffffffffffffffULL; break; - } - for (i = 0; i < ehdr.e_phnum; ++i) - gelf_getphdr (elf, i, dso->phdr + i); - dso->fd = fd; - - for (i = 0, j = 0; i < ehdr.e_shnum; ++i) - { - dso->scn[i] = elf_getscn (elf, i); - gelfx_getshdr (elf, dso->scn[i], dso->shdr + i); - if ((dso->shdr[i].sh_flags & SHF_ALLOC) && dso->shdr[i].sh_type != SHT_NOBITS) - j = 1; - } - if (j == 0) - { - /* If all ALLOC sections are SHT_NOBITS, then this is a - stripped-to-file debuginfo. Skip it silently. */ - goto error_out; - } - - sections = (int *) alloca (dso->ehdr.e_shnum * sizeof (int) * 2); - sections[0] = 0; - for (i = 1, j = 1, k = dso->ehdr.e_shnum, last = -1; - i < dso->ehdr.e_shnum; ++i) - if (RELOCATE_SCN (dso->shdr[i].sh_flags)) - { - last = i; - sections[j++] = i; - } - else - sections[--k] = i; - assert (j == k); - - section_cmp_dso = dso; - qsort (sections + k, dso->ehdr.e_shnum - k, sizeof (*sections), section_cmp); - invsections = sections + dso->ehdr.e_shnum; - invsections[0] = 0; - for (i = 1, j = 0; i < ehdr.e_shnum; ++i) - { - if (i != sections[i]) - { - j = 1; - dso->scn[i] = elf_getscn (elf, sections[i]); - gelfx_getshdr (elf, dso->scn[i], dso->shdr + i); - } - invsections[sections[i]] = i; - } - -#ifndef DSO_READONLY - if (j) - { - dso->move = init_section_move (dso); - if (dso->move == NULL) - goto error_out; - memcpy (dso->move->old_to_new, invsections, dso->ehdr.e_shnum * sizeof (int)); - memcpy (dso->move->new_to_old, sections, dso->ehdr.e_shnum * sizeof (int)); - } -#endif /* DSO_READONLY */ - - last_off = 0; - for (i = 1; i < ehdr.e_shnum; ++i) - { - if (dso->shdr[i].sh_link >= ehdr.e_shnum) - { - error (0, 0, "%s: bogus sh_link value %d", name, - dso->shdr[i].sh_link); - goto error_out; - } - dso->shdr[i].sh_link = invsections[dso->shdr[i].sh_link]; - if (dso->shdr[i].sh_type == SHT_REL - || dso->shdr[i].sh_type == SHT_RELA - || (dso->shdr[i].sh_flags & SHF_INFO_LINK)) - { - if (dso->shdr[i].sh_info >= ehdr.e_shnum) - { - error (0, 0, "%s: bogus sh_info value %d", name, - dso->shdr[i].sh_info); - goto error_out; - } - dso->shdr[i].sh_info = invsections[dso->shdr[i].sh_info]; - } - - /* Some linkers mess up sh_offset fields for empty or nobits - sections. */ - if (RELOCATE_SCN (dso->shdr[i].sh_flags) - && (dso->shdr[i].sh_size == 0 - || dso->shdr[i].sh_type == SHT_NOBITS)) - { - for (j = i + 1; j < ehdr.e_shnum; ++j) - if (! RELOCATE_SCN (dso->shdr[j].sh_flags)) - break; - else if (dso->shdr[j].sh_size != 0 - && dso->shdr[j].sh_type != SHT_NOBITS) - break; - dso->shdr[i].sh_offset = (last_off + dso->shdr[i].sh_addralign - 1) - & ~(dso->shdr[i].sh_addralign - 1); - if (j < ehdr.e_shnum - && dso->shdr[i].sh_offset > dso->shdr[j].sh_offset) - { - GElf_Addr k; - - for (k = dso->shdr[i].sh_addralign - 1; k; ) - { - k >>= 1; - dso->shdr[i].sh_offset = (last_off + k) & ~k; - if (dso->shdr[i].sh_offset <= dso->shdr[j].sh_offset) - break; - } - } - last_off = dso->shdr[i].sh_offset; - } - else - last_off = dso->shdr[i].sh_offset + dso->shdr[i].sh_size; - } - dso->ehdr.e_shstrndx = invsections[dso->ehdr.e_shstrndx]; - -#ifndef DSO_READONLY - for (plarch = __start_pl_arch; plarch < __stop_pl_arch; plarch++) - if (plarch->class == ehdr.e_ident[EI_CLASS] - && (plarch->machine == ehdr.e_machine - || plarch->alternate_machine[0] == ehdr.e_machine - || plarch->alternate_machine[1] == ehdr.e_machine - || plarch->alternate_machine[2] == ehdr.e_machine)) - break; - - if (plarch == __stop_pl_arch || ehdr.e_machine == EM_NONE) - { - error (0, 0, "\"%s\"'s architecture is not supported", name); - goto error_out; - } - - dso->arch = plarch; -#else - dso->arch = NULL; -#endif /* DSO_READONLY */ - - dso->base = ~(GElf_Addr) 0; - dso->align = 0; - dso->end = 0; - for (i = 0; i < dso->ehdr.e_phnum; i++) - if (dso->phdr[i].p_type == PT_LOAD) - { - GElf_Addr base, end; - - if (dso->phdr[i].p_align > dso->align) - dso->align = dso->phdr[i].p_align; - base = dso->phdr[i].p_vaddr & ~(dso->phdr[i].p_align - 1); - end = dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz; - if (base < dso->base) - dso->base = base; - if (end > dso->end) - dso->end = end; - } - - if (dso->base == ~(GElf_Addr) 0) - { - error (0, 0, "%s: cannot find loadable segment", name); - goto error_out; - } - - read_dynamic (dso); - - dso->filename = (const char *) strdup (name); - dso->soname = dso->filename; - if (dso->info[DT_STRTAB] && dso->info[DT_SONAME]) - { - const char *soname; - - soname = get_data (dso, dso->info[DT_STRTAB] + dso->info[DT_SONAME], - NULL, NULL); - if (soname && soname[0] != '\0') - dso->soname = (const char *) strdup (soname); - } - -#ifndef DSO_READONLY - if (dso->arch->machine == EM_ALPHA - || dso->arch->machine == EM_MIPS) - for (i = 1; i < ehdr.e_shnum; ++i) - { - if ((dso->shdr[i].sh_type == SHT_ALPHA_DEBUG - && dso->arch->machine == EM_ALPHA) - || (dso->shdr[i].sh_type == SHT_MIPS_DEBUG - && dso->arch->machine == EM_MIPS)) - { - const char *name - = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name); - if (! strcmp (name, ".mdebug")) - dso->mdebug_orig_offset = dso->shdr[i].sh_offset; - break; - } - } -#endif /* DSO_READONLY */ - - return dso; - -error_out: - if (dso) - { - free (dso->move); - if (dso->soname != dso->filename) - free ((char *) dso->soname); - free ((char *) dso->filename); - free (dso); - } - if (elf) - elf_end (elf); - if (fd != -1) - { - fsync (fd); - close (fd); - } - return NULL; -} - -#ifndef DSO_READONLY -static int -adjust_symtab_section_indices (DSO *dso, int n, int old_shnum, int *old_to_new) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Sym sym; - int changed = 0, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getsym (dso->elf, data, ndx, &sym); - if (sym.st_shndx > SHN_UNDEF && sym.st_shndx < SHN_LORESERVE) - { - if (sym.st_shndx >= old_shnum - || old_to_new[sym.st_shndx] == -1) - { - if (! sym.st_size && - sym.st_info == ELF32_ST_INFO (STB_LOCAL, STT_SECTION)) - { - sym.st_value = 0; - sym.st_shndx = SHN_UNDEF; - gelfx_update_sym (dso->elf, data, ndx, &sym); - changed = 1; - continue; - } - else - { - if (sym.st_shndx >= old_shnum) - { - error (0, 0, "%s: Symbol section index outside of section numbers", - dso->filename); - return 1; - } - error (0, 0, "%s: Section symbol points into has been removed", - dso->filename); - return 1; - } - } - if (old_to_new[sym.st_shndx] != sym.st_shndx) - { - changed = 1; - sym.st_shndx = old_to_new[sym.st_shndx]; - gelfx_update_sym (dso->elf, data, ndx, &sym); - } - } - } - } - - if (changed) - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - - return 0; -} - -static int -set_stt_section_values (DSO *dso, int n) -{ - Elf_Data *data; - Elf_Scn *scn = dso->scn[n]; - GElf_Sym sym; - int ndx, maxndx, sec; - char seen[dso->ehdr.e_shnum]; - - memset (seen, 0, dso->ehdr.e_shnum); - data = elf_getdata (scn, NULL); - assert (data != NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0); - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - gelfx_getsym (dso->elf, data, 0, &sym); - if (sym.st_info != ELF32_ST_INFO (STB_LOCAL, STT_NOTYPE) - || sym.st_size != 0 || sym.st_other != 0 - || sym.st_value != 0 || sym.st_shndx != SHN_UNDEF - || sym.st_name != 0) - return 0; - - for (ndx = 1; ndx < maxndx; ++ndx) - { - gelfx_getsym (dso->elf, data, ndx, &sym); - if (sym.st_info == ELF32_ST_INFO (STB_LOCAL, STT_SECTION) - && sym.st_size == 0 && sym.st_other == 0 - && sym.st_name == 0) - { - if (sym.st_shndx > SHN_UNDEF && sym.st_shndx < SHN_LORESERVE) - { - seen[sym.st_shndx] = 1; - sym.st_value = dso->shdr[sym.st_shndx].sh_addr; - gelfx_update_sym (dso->elf, data, ndx, &sym); - } - } - else - break; - } - - for (ndx = 1, sec = 1; ndx < maxndx; ++ndx) - { - gelfx_getsym (dso->elf, data, ndx, &sym); - if (sym.st_info == ELF32_ST_INFO (STB_LOCAL, STT_SECTION) - && sym.st_size == 0 && sym.st_other == 0 - && sym.st_name == 0) - { - if (sym.st_shndx == SHN_UNDEF) - { - while (sec < dso->ehdr.e_shnum && seen[sec]) - ++sec; - - if (sec >= dso->ehdr.e_shnum) - sym.st_value = 0; - else - sym.st_value = dso->shdr[sec].sh_addr; - sym.st_shndx = sec++; - gelfx_update_sym (dso->elf, data, ndx, &sym); - } - } - else - break; - } - - return 0; -} - -struct section_move * -init_section_move (DSO *dso) -{ - struct section_move *move; - int i; - - move = malloc (sizeof (struct section_move) - + (dso->ehdr.e_shnum * 2 + 20) * sizeof (int)); - if (move == NULL) - { - error (0, ENOMEM, "%s: Could not move sections", dso->filename); - return move; - } - move->old_shnum = dso->ehdr.e_shnum; - move->new_shnum = dso->ehdr.e_shnum; - move->old_to_new = (int *)(move + 1); - move->new_to_old = move->old_to_new + move->new_shnum; - for (i = 0; i < move->new_shnum; i++) - { - move->old_to_new[i] = i; - move->new_to_old[i] = i; - } - return move; -} - -void -add_section (struct section_move *move, int sec) -{ - int i; - - assert (move->new_shnum < move->old_shnum + 20); - assert (sec <= move->new_shnum); - - memmove (move->new_to_old + sec + 1, move->new_to_old + sec, - (move->new_shnum - sec) * sizeof (int)); - ++move->new_shnum; - move->new_to_old[sec] = -1; - for (i = 1; i < move->old_shnum; i++) - if (move->old_to_new[i] >= sec) - ++move->old_to_new[i]; -} - -void -remove_section (struct section_move *move, int sec) -{ - int i; - - assert (sec < move->new_shnum); - - memmove (move->new_to_old + sec, move->new_to_old + sec + 1, - (move->new_shnum - sec - 1) * sizeof (int)); - --move->new_shnum; - for (i = 1; i < move->old_shnum; i++) - if (move->old_to_new[i] == sec) - move->old_to_new[i] = -1; - else if (move->old_to_new[i] > sec) - --move->old_to_new[i]; -} - -int -reopen_dso (DSO *dso, struct section_move *move, const char *temp_base) -{ - char filename[strlen (temp_base ? temp_base : dso->filename) - + sizeof ("/dev/shm/.#prelink#.XXXXXX")]; - int adddel = 0; - int free_move = 0; - Elf *elf = NULL; - GElf_Ehdr ehdr; - char *e_ident; - int fd, i, j; - - if (move == NULL) - { - move = init_section_move (dso); - if (move == NULL) - return 1; - free_move = 1; - } - else - assert (dso->ehdr.e_shnum == move->old_shnum); - - if (temp_base == NULL) - temp_base = dso->filename; - sprintf (filename, "%s.#prelink#.XXXXXX", temp_base); - - fd = wrap_mkstemp (filename); - if (fd == -1) - { - strcpy (filename, "/tmp/#prelink#.XXXXXX"); - fd = wrap_mkstemp (filename); - if (fd == -1) - { - strcpy (filename, "/dev/shm/#prelink#.XXXXXX"); - fd = wrap_mkstemp (filename); - } - if (fd == -1) - { - error (0, errno, "Could not create temporary file %s", filename); - goto error_out; - } - } - - elf = elf_begin (fd, ELF_C_WRITE, NULL); - if (elf == NULL) - { - error (0, 0, "cannot open ELF file: %s", elf_errmsg (-1)); - goto error_out; - - } - - /* Some gelf_newehdr implementations don't return the resulting - ElfNN_Ehdr, so we have to do it the hard way instead of: - e_ident = (char *) gelf_newehdr (elf, gelf_getclass (dso->elf)); */ - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - e_ident = (char *) elf32_newehdr (elf); - break; - case ELFCLASS64: - e_ident = (char *) elf64_newehdr (elf); - break; - default: - e_ident = NULL; - break; - } - - if (e_ident == NULL - /* This is here just for the gelfx wrapper, so that gelf_update_ehdr - already has the correct ELF class. */ - || memcpy (e_ident, dso->ehdr.e_ident, EI_NIDENT) == NULL - || gelf_update_ehdr (elf, &dso->ehdr) == 0 - || gelf_newphdr (elf, dso->ehdr.e_phnum) == 0) - { - error (0, 0, "Could not create new ELF headers"); - goto error_out; - } - ehdr = dso->ehdr; - elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT | ELF_F_PERMISSIVE); - for (i = 0; i < ehdr.e_phnum; ++i) - gelf_update_phdr (elf, i, dso->phdr + i); - - for (i = 1; i < move->new_shnum; ++i) - { - Elf_Scn *scn; - Elf_Data data, *data1, *data2; - - if (move->new_to_old[i] == -1) - { - scn = elf_newscn (elf); - elf_newdata (scn); - } - else - { - j = move->new_to_old[i]; - scn = elf_newscn (elf); - gelfx_update_shdr (elf, scn, &dso->shdr[j]); - if (dso->shdr[j].sh_type == SHT_NOBITS) - { - data1 = elf_getdata (dso->scn[j], NULL); - data2 = elf_newdata (scn); - memcpy (data2, data1, sizeof (*data1)); - } - else - { - memset (&data, 0, sizeof data); - data.d_type = ELF_T_NUM; - data1 = NULL; - while ((data1 = elf_getdata (dso->scn[j], data1)) - != NULL) - { - if (data.d_type == ELF_T_NUM) - data = *data1; - else if (data.d_type != data1->d_type - || data.d_version != data1->d_version) - abort (); - else - { - if (data1->d_off < data.d_off) - { - data.d_size += data.d_off - data1->d_off; - data.d_off = data1->d_off; - } - if (data1->d_off + data1->d_size - > data.d_off + data.d_size) - data.d_size = data1->d_off + data1->d_size - - data.d_off; - if (data1->d_align > data.d_align) - data.d_align = data1->d_align; - } - } - if (data.d_type == ELF_T_NUM) - { - assert (dso->shdr[j].sh_size == 0); - continue; - } - if (data.d_size != 0) - { - data.d_buf = calloc (1, data.d_size); - if (data.d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not copy section", - dso->filename); - goto error_out; - } - } - else - data.d_buf = NULL; - data1 = NULL; - while ((data1 = elf_getdata (dso->scn[j], data1)) - != NULL) - memcpy (data.d_buf + data1->d_off - data.d_off, data1->d_buf, - data1->d_size); - data2 = elf_newdata (scn); - memcpy (data2, &data, sizeof (data)); - } - } - } - - ehdr.e_shnum = move->new_shnum; - dso->temp_filename = strdup (filename); - if (dso->temp_filename == NULL) - { - error (0, ENOMEM, "%s: Could not save temporary filename", dso->filename); - goto error_out; - } - dso->elfro = dso->elf; - dso->elf = elf; - dso->fdro = dso->fd; - dso->fd = fd; - dso->ehdr = ehdr; - dso->lastscn = 0; - elf = NULL; - fd = -1; - for (i = 1; i < move->old_shnum; i++) - if (move->old_to_new[i] != i) - { - adddel = 1; - break; - } - if (! adddel) - for (i = 1; i < move->new_shnum; i++) - if (move->new_to_old[i] != i) - { - adddel = 1; - break; - } - - for (i = 1; i < move->new_shnum; i++) - { - dso->scn[i] = elf_getscn (dso->elf, i); - gelfx_getshdr (dso->elf, dso->scn[i], dso->shdr + i); - if (move->new_to_old[i] == -1) - continue; - if (dso->move - && (dso->shdr[i].sh_type == SHT_SYMTAB - || dso->shdr[i].sh_type == SHT_DYNSYM)) - { - if (adjust_symtab_section_indices (dso, i, dso->move->old_shnum, - dso->move->old_to_new)) - goto error_out; - } - if (adddel) - { - if (dso->shdr[i].sh_link) - { - if (dso->shdr[i].sh_link >= move->old_shnum) - { - error (0, 0, "%s: bogus sh_link value %d", dso->filename, - dso->shdr[i].sh_link); - goto error_out; - } - if (move->old_to_new[dso->shdr[i].sh_link] == -1) - { - error (0, 0, "Section sh_link points to has been removed"); - goto error_out; - } - dso->shdr[i].sh_link = move->old_to_new[dso->shdr[i].sh_link]; - } - /* Only some section types use sh_info for section index. */ - if (dso->shdr[i].sh_info - && (dso->shdr[i].sh_type == SHT_REL - || dso->shdr[i].sh_type == SHT_RELA - || (dso->shdr[i].sh_flags & SHF_INFO_LINK))) - { - if (dso->shdr[i].sh_info >= move->old_shnum) - { - error (0, 0, "%s: bogus sh_info value %d", dso->filename, - dso->shdr[i].sh_info); - goto error_out; - } - if (move->old_to_new[dso->shdr[i].sh_info] == -1) - { - error (0, 0, "Section sh_info points to has been removed"); - goto error_out; - } - dso->shdr[i].sh_info = move->old_to_new[dso->shdr[i].sh_info]; - } - if (dso->shdr[i].sh_type == SHT_SYMTAB - || dso->shdr[i].sh_type == SHT_DYNSYM) - { - if (adjust_symtab_section_indices (dso, i, move->old_shnum, - move->old_to_new)) - goto error_out; - } - } - } - - free (dso->move); - dso->move = NULL; - - dso->ehdr.e_shstrndx = move->old_to_new[dso->ehdr.e_shstrndx]; - gelf_update_ehdr (dso->elf, &dso->ehdr); - - read_dynamic (dso); - - /* If shoff does not point after last section, we need to adjust the sections - after it if we added or removed some sections. */ - if (move->old_shnum != move->new_shnum - && adjust_dso_nonalloc (dso, 0, dso->ehdr.e_shoff + 1, - ((long) move->new_shnum - (long) move->old_shnum) - * gelf_fsize (dso->elf, ELF_T_SHDR, 1, - EV_CURRENT))) - goto error_out; - - if (free_move) - free (move); - return 0; - -error_out: - if (free_move) - free (move); - if (elf) - elf_end (elf); - if (fd != -1) - { - wrap_unlink (filename); - fsync (fd); - close (fd); - } - return 1; -} - -/* Return true if the value of symbol SYM, which belongs to DSO, - should be treated as an address within the DSO, and should - therefore track DSO's relocations. */ - -int -adjust_symbol_p (DSO *dso, GElf_Sym *sym) -{ - if (sym->st_shndx == SHN_ABS - && sym->st_value != 0 - && (GELF_ST_TYPE (sym->st_info) <= STT_FUNC - || (dso->ehdr.e_machine == EM_ARM - && GELF_ST_TYPE (sym->st_info) == STT_ARM_TFUNC))) - /* This is problematic. How do we find out if - we should relocate this? Assume we should. */ - return 1; - - /* If a MIPS object does not define a symbol, but has a lazy binding - stub for it, st_value will point to that stub. Note that unlike - other targets, these stub addresses never participate in symbol - lookup; the stubs can only be called by the object that defines them. - st_values are only used in this way so that the associated GOT entry - can store a Quickstart value without losing the original stub - address. */ - if (dso->ehdr.e_machine == EM_MIPS - && sym->st_shndx == SHN_UNDEF - && sym->st_value != 0) - return 1; - - return (sym->st_shndx > SHN_UNDEF - && sym->st_shndx < dso->ehdr.e_shnum - && ELF32_ST_TYPE (sym->st_info) != STT_TLS - && RELOCATE_SCN (dso->shdr[sym->st_shndx].sh_flags)); -} - -static int -adjust_symtab (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Sym sym; - int ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getsym (dso->elf, data, ndx, &sym); - if (adjust_symbol_p (dso, &sym) && sym.st_value >= start) - { - sym.st_value += adjust; - gelfx_update_sym (dso->elf, data, ndx, &sym); - } - } - } - - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - return 0; -} -#endif /* DSO_READONLY */ - -int -dso_is_rdwr (DSO *dso) -{ - return dso->elfro != NULL; -} - -#ifndef DSO_READONLY -GElf_Addr -adjust_old_to_new (DSO *dso, GElf_Addr addr) -{ - int i; - - if (dso->adjust == NULL) - return addr; /* Fast path. */ - - for (i = 0; i < dso->nadjust; i++) - if (addr >= dso->adjust[i].start) - { - addr += dso->adjust[i].adjust; - assert (dso->ehdr.e_ident[EI_CLASS] != ELFCLASS32 - || addr == (Elf32_Addr) addr); - return addr; - } - - return addr; -} - -GElf_Addr -adjust_new_to_old (DSO *dso, GElf_Addr addr) -{ - int i; - - if (dso->adjust == NULL) - return addr; /* Fast path. */ - - for (i = 0; i < dso->nadjust; i++) - if (addr >= dso->adjust[i].start + dso->adjust[i].adjust) - { - addr -= dso->adjust[i].adjust; - assert (dso->ehdr.e_ident[EI_CLASS] != ELFCLASS32 - || addr == (Elf32_Addr) addr); - return addr; - } - - return addr; -} - -static int -adjust_dynamic (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Dyn dyn; - int ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - if (dso->arch->adjust_dyn (dso, n, &dyn, start, adjust) == 0) - switch (dyn.d_tag) - { - case DT_REL: - case DT_RELA: - /* On some arches DT_REL* may be 0 indicating no relocations - (if DT_REL*SZ is also 0). Don't adjust it in that case. */ - if (dyn.d_un.d_ptr && dyn.d_un.d_ptr >= start) - { - dyn.d_un.d_ptr += adjust; - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - } - break; - default: - if (dyn.d_tag < DT_ADDRRNGLO || dyn.d_tag > DT_ADDRRNGHI) - break; - /* FALLTHROUGH */ - case DT_INIT: - case DT_FINI: - case DT_HASH: - case DT_STRTAB: - case DT_SYMTAB: - case DT_JMPREL: - case DT_INIT_ARRAY: - case DT_FINI_ARRAY: - case DT_PREINIT_ARRAY: - case DT_VERDEF: - case DT_VERNEED: - case DT_VERSYM: - case DT_PLTGOT: - if (dyn.d_un.d_ptr >= start) - { - dyn.d_un.d_ptr += adjust; - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - } - break; - } - else - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - } - } - - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - - /* Update the cached dynamic info as well. */ - read_dynamic (dso); - return 0; -} -#endif /* DSO_READONLY */ - -int -addr_to_sec (DSO *dso, GElf_Addr addr) -{ - GElf_Shdr *shdr; - int i; - - shdr = &dso->shdr[dso->lastscn]; - for (i = -1; i < dso->ehdr.e_shnum; shdr = &dso->shdr[++i]) - if (RELOCATE_SCN (shdr->sh_flags) - && shdr->sh_addr <= addr && shdr->sh_addr + shdr->sh_size > addr - && (shdr->sh_type != SHT_NOBITS || (shdr->sh_flags & SHF_TLS) == 0)) - { - if (i != -1) - dso->lastscn = i; - return dso->lastscn; - } - - return -1; -} - -#ifndef DSO_READONLY -static int -adjust_rel (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rel rel; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getrel (dso->elf, data, ndx, &rel); - sec = addr_to_sec (dso, rel.r_offset); - if (sec == -1) - continue; - - dso->arch->adjust_rel (dso, &rel, start, adjust); - addr_adjust (rel.r_offset, start, adjust); - gelfx_update_rel (dso->elf, data, ndx, &rel); - } - } - - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - return 0; -} - -static int -adjust_rela (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rela rela; - int sec, ndx, maxndx; - - while ((data = elf_getdata (scn, data)) != NULL) - { - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - { - gelfx_getrela (dso->elf, data, ndx, &rela); - sec = addr_to_sec (dso, rela.r_offset); - if (sec == -1) - continue; - - dso->arch->adjust_rela (dso, &rela, start, adjust); - addr_adjust (rela.r_offset, start, adjust); - gelfx_update_rela (dso->elf, data, ndx, &rela); - } - } - - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - return 0; -} - -int -adjust_nonalloc (DSO *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int first, - GElf_Addr start, GElf_Addr adjust) -{ - int i; - - for (i = 1; i < ehdr->e_shnum; i++) - { - if (RELOCATE_SCN (shdr[i].sh_flags) || shdr[i].sh_type == SHT_NULL) - continue; - - if ((shdr[i].sh_offset > start - || (shdr[i].sh_offset == start && i >= first)) - && (adjust & (shdr[i].sh_addralign - 1))) - adjust = (adjust + shdr[i].sh_addralign - 1) - & ~(shdr[i].sh_addralign - 1); - } - - if (ehdr->e_shoff >= start) - { - GElf_Addr shdralign = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - - if (adjust & (shdralign - 1)) - adjust = (adjust + shdralign - 1) & ~(shdralign - 1); - ehdr->e_shoff += adjust; - } - - for (i = 1; i < ehdr->e_shnum; i++) - { - if (RELOCATE_SCN (shdr[i].sh_flags) || shdr[i].sh_type == SHT_NULL) - continue; - - if (shdr[i].sh_offset > start - || (shdr[i].sh_offset == start && i >= first)) - shdr[i].sh_offset += adjust; - } - return 0; -} - -int -adjust_dso_nonalloc (DSO *dso, int first, GElf_Addr start, GElf_Addr adjust) -{ - return adjust_nonalloc (dso, &dso->ehdr, dso->shdr, first, start, adjust); -} - -/* Add ADJUST to all addresses above START. */ -int -adjust_dso (DSO *dso, GElf_Addr start, GElf_Addr adjust) -{ - int i; - - if (dso->arch->arch_adjust - && dso->arch->arch_adjust (dso, start, adjust)) - return 1; - - if (dso->ehdr.e_entry >= start) - { - dso->ehdr.e_entry += adjust; - gelf_update_ehdr (dso->elf, &dso->ehdr); - elf_flagehdr (dso->elf, ELF_C_SET, ELF_F_DIRTY); - } - - for (i = 0; i < dso->ehdr.e_phnum; i++) - { - /* Leave STACK segment alone, it has - p_vaddr == p_paddr == p_offset == p_filesz == p_memsz == 0. */ - if (dso->phdr[i].p_type == PT_GNU_STACK) - continue; - if (! start) - { - dso->phdr[i].p_vaddr += adjust; - dso->phdr[i].p_paddr += adjust; - } - else if (start <= dso->phdr[i].p_vaddr) - { - dso->phdr[i].p_vaddr += adjust; - dso->phdr[i].p_paddr += adjust; - dso->phdr[i].p_offset += adjust; - } - else if (start < dso->phdr[i].p_vaddr + dso->phdr[i].p_filesz) - { - dso->phdr[i].p_filesz += adjust; - dso->phdr[i].p_memsz += adjust; - } - else if (start < dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - dso->phdr[i].p_memsz += adjust; - else - continue; - if (dso->phdr[i].p_type == PT_LOAD - && (dso->phdr[i].p_vaddr - dso->phdr[i].p_offset) - % dso->phdr[i].p_align) - { - error (0, 0, "%s: PT_LOAD %08llx %08llx 0x%x would be not properly aligned", - dso->filename, (long long) dso->phdr[i].p_offset, - (long long) dso->phdr[i].p_vaddr, (int) dso->phdr[i].p_align); - return 1; - } - gelf_update_phdr (dso->elf, i, dso->phdr + i); - } - elf_flagphdr (dso->elf, ELF_C_SET, ELF_F_DIRTY); - - for (i = 1; i < dso->ehdr.e_shnum; i++) - { - const char *name; - - if (dso->arch->adjust_section) - { - int ret = dso->arch->adjust_section (dso, i, start, adjust); - - if (ret == 1) - return 1; - else if (ret) - continue; - } - switch (dso->shdr[i].sh_type) - { - case SHT_PROGBITS: - case SHT_MIPS_DWARF: - name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name); - if (strcmp (name, ".stab") == 0 - && adjust_stabs (dso, i, start, adjust)) - return 1; - if (strcmp (name, ".debug_info") == 0 - && adjust_dwarf2 (dso, i, start, adjust)) - return 1; - break; - case SHT_HASH: - case SHT_GNU_HASH: - case SHT_NOBITS: - case SHT_STRTAB: - break; - case SHT_SYMTAB: - case SHT_DYNSYM: - if (adjust_symtab (dso, i, start, adjust)) - return 1; - break; - case SHT_DYNAMIC: - if (adjust_dynamic (dso, i, start, adjust)) - return 1; - break; - case SHT_REL: - /* Don't adjust reloc sections for debug info. */ - if (dso->shdr[i].sh_flags & SHF_ALLOC) - if (adjust_rel (dso, i, start, adjust)) - return 1; - break; - case SHT_RELA: - if (dso->shdr[i].sh_flags & SHF_ALLOC) - if (adjust_rela (dso, i, start, adjust)) - return 1; - break; - } - if ((dso->arch->machine == EM_ALPHA - && dso->shdr[i].sh_type == SHT_ALPHA_DEBUG) - || (dso->arch->machine == EM_MIPS - && dso->shdr[i].sh_type == SHT_MIPS_DEBUG)) - if (adjust_mdebug (dso, i, start, adjust)) - return 1; - } - - for (i = 0; i < dso->ehdr.e_shnum; i++) - { - if (RELOCATE_SCN (dso->shdr[i].sh_flags)) - { - if (dso->shdr[i].sh_addr >= start) - { - Elf_Scn *scn = dso->scn[i]; - - dso->shdr[i].sh_addr += adjust; - if (start) - dso->shdr[i].sh_offset += adjust; - gelfx_update_shdr (dso->elf, scn, dso->shdr + i); - elf_flagshdr (scn, ELF_C_SET, ELF_F_DIRTY); - } - } - } - - addr_adjust (dso->base, start, adjust); - addr_adjust (dso->end, start, adjust); - - if (start) - { - start = adjust_new_to_old (dso, start); - for (i = 0; i < dso->nadjust; i++) - if (start < dso->adjust[i].start) - dso->adjust[i].adjust += adjust; - else - break; - if (i < dso->nadjust && start == dso->adjust[i].start) - dso->adjust[i].adjust += adjust; - else - { - dso->adjust = - realloc (dso->adjust, (dso->nadjust + 1) * sizeof (*dso->adjust)); - if (dso->adjust == NULL) - { - error (0, ENOMEM, "Cannot record the list of adjustements being made"); - return 1; - } - memmove (dso->adjust + i + 1, dso->adjust + i, dso->nadjust - i); - dso->adjust[i].start = start; - dso->adjust[i].adjust = adjust; - ++dso->nadjust; - } - } - - return start ? adjust_dso_nonalloc (dso, 0, 0, adjust) : 0; -} - -int -recompute_nonalloc_offsets (DSO *dso) -{ - int i, first_nonalloc, sec_before_shoff = 0; - GElf_Addr last_offset = 0; - GElf_Addr shdralign = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - GElf_Addr shdrsize = gelf_fsize (dso->elf, ELF_T_SHDR, 1, EV_CURRENT) - * dso->ehdr.e_shnum; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (RELOCATE_SCN (dso->shdr[i].sh_flags)) - { - if (dso->shdr[i].sh_type == SHT_NOBITS) - last_offset = dso->shdr[i].sh_offset; - else - last_offset = dso->shdr[i].sh_offset + dso->shdr[i].sh_size; - } - else - break; - - first_nonalloc = i; - if (dso->ehdr.e_shoff < dso->shdr[i].sh_offset) - { - dso->ehdr.e_shoff = (last_offset + shdralign - 1) & ~(shdralign - 1); - last_offset = dso->ehdr.e_shoff + shdrsize; - } - else - for (; i < dso->ehdr.e_shnum; ++i) - if (dso->shdr[i].sh_offset < dso->ehdr.e_shoff - && (i == dso->ehdr.e_shnum - 1 - || dso->shdr[i + 1].sh_offset > dso->ehdr.e_shoff)) - { - sec_before_shoff = i; - break; - } - - for (i = first_nonalloc; i < dso->ehdr.e_shnum; ++i) - { - assert (!RELOCATE_SCN (dso->shdr[i].sh_flags)); - assert (dso->shdr[i].sh_type != SHT_NOBITS); - dso->shdr[i].sh_offset = (last_offset + dso->shdr[i].sh_addralign - 1) - & ~(dso->shdr[i].sh_addralign - 1); - last_offset = dso->shdr[i].sh_offset + dso->shdr[i].sh_size; - if (i == sec_before_shoff) - { - dso->ehdr.e_shoff = (last_offset + shdralign - 1) & ~(shdralign - 1); - last_offset = dso->ehdr.e_shoff + shdrsize; - } - } - - return 0; -} - -int -strtabfind (DSO *dso, int strndx, const char *name) -{ - Elf_Scn *scn; - Elf_Data *data; - const char *p, *q, *r; - size_t len = strlen (name); - - if (dso->shdr[strndx].sh_type != SHT_STRTAB) - return 0; - - scn = dso->scn[strndx]; - data = elf_getdata (scn, NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0); - assert (data->d_size == dso->shdr[strndx].sh_size); - q = data->d_buf + data->d_size; - for (p = data->d_buf; p < q; p = r + 1) - { - r = strchr (p, '\0'); - if (r - p >= len && memcmp (r - len, name, len) == 0) - return (r - (const char *) data->d_buf) - len; - } - - return 0; -} - -int -shstrtabadd (DSO *dso, const char *name) -{ - Elf_Scn *scn; - Elf_Data *data; - GElf_Addr adjust; - const char *p, *q, *r; - size_t len = strlen (name), align; - int ret; - - scn = dso->scn[dso->ehdr.e_shstrndx]; - data = elf_getdata (scn, NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0); - assert (data->d_size == dso->shdr[dso->ehdr.e_shstrndx].sh_size); - q = data->d_buf + data->d_size; - for (p = data->d_buf; p < q; p = r + 1) - { - r = strchr (p, '\0'); - if (r - p >= len && memcmp (r - len, name, len) == 0) - return (r - (const char *) data->d_buf) - len; - } - - data->d_buf = realloc (data->d_buf, data->d_size + len + 1); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "Cannot add new section name %s", name); - return 0; - } - - memcpy (data->d_buf + data->d_size, name, len + 1); - ret = data->d_size; - data->d_size += len + 1; - align = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - adjust = (len + 1 + align - 1) & ~(align - 1); - if (adjust_dso_nonalloc (dso, 0, - dso->shdr[dso->ehdr.e_shstrndx].sh_offset - + dso->shdr[dso->ehdr.e_shstrndx].sh_size, - adjust)) - return 0; - dso->shdr[dso->ehdr.e_shstrndx].sh_size += len + 1; - return ret; -} - -int -relocate_dso (DSO *dso, GElf_Addr base) -{ - /* Check if it is already relocated. */ - if (dso->base == base) - return 0; - - if (! dso_is_rdwr (dso)) - { - if (reopen_dso (dso, NULL, NULL)) - return 1; - } - - return adjust_dso (dso, 0, base - dso->base); -} -#endif /* DSO_READONLY */ - -static int -close_dso_1 (DSO *dso) -{ - if (dso_is_rdwr (dso)) - { - int i; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - Elf_Scn *scn = dso->scn[i]; - Elf_Data *data = NULL; - - while ((data = elf_getdata (scn, data)) != NULL) - { - free (data->d_buf); - data->d_buf = NULL; - } - } - } - - elf_end (dso->elf); - fsync (dso->fd); - close (dso->fd); - if (dso->elfro) - { - elf_end (dso->elfro); - fsync (dso->fdro); - close (dso->fdro); - } - if (dso->filename != dso->soname) - free ((char *) dso->soname); - free ((char *) dso->filename); - free ((char *) dso->temp_filename); - free (dso->move); - free (dso->adjust); - free (dso->undo.d_buf); - free (dso); - return 0; -} - -int -close_dso (DSO *dso) -{ - int rdwr = dso_is_rdwr (dso); - - if (rdwr && dso->temp_filename != NULL) - wrap_unlink (dso->temp_filename); - close_dso_1 (dso); - return 0; -} - -#ifndef DSO_READONLY -int -prepare_write_dso (DSO *dso) -{ - int i; - - if (check_dso (dso) - || (dso->mdebug_orig_offset && finalize_mdebug (dso))) - return 1; - - gelf_update_ehdr (dso->elf, &dso->ehdr); - for (i = 0; i < dso->ehdr.e_phnum; ++i) - gelf_update_phdr (dso->elf, i, dso->phdr + i); - for (i = 0; i < dso->ehdr.e_shnum; ++i) - { - gelfx_update_shdr (dso->elf, dso->scn[i], dso->shdr + i); - if (dso->shdr[i].sh_type == SHT_SYMTAB - || dso->shdr[i].sh_type == SHT_DYNSYM) - set_stt_section_values (dso, i); - } - return 0; -} - -int -write_dso (DSO *dso) -{ - if (prepare_write_dso (dso)) - return 1; - - if (! dso->permissive && ELF_F_PERMISSIVE) - elf_flagelf (dso->elf, ELF_C_CLR, ELF_F_PERMISSIVE); - - if (elf_update (dso->elf, ELF_C_WRITE) == -1) - return 2; - return 0; -} - -static int -copy_xattrs (const char *temp_name, const char *name, int ignore_errors) -{ - ssize_t sz = wrap_listxattr (name, NULL, 0), valsz = 0; - char *list = NULL, *end, *p, *val = NULL, *newval; - - if (sz < 0) - { - if (errno == ENOSYS || errno == ENOTSUP) - return 0; - goto read_err; - } - list = malloc (sz + 1); - if (list == NULL) - goto read_err; - sz = wrap_listxattr (name, list, sz); - if (sz < 0) - goto read_err; - end = list + sz; - *end = '\0'; - for (p = list; p != end; p = strchr (p, '\0') + 1) - if (*p == '\0' || strcmp (p, "security.selinux") == 0) - continue; - else - { - sz = wrap_getxattr (name, p, val, valsz); - if (sz < 0) - { - if (errno != ERANGE) - goto read_err; - sz = wrap_getxattr (name, p, NULL, 0); - if (sz < 0) - goto read_err; - } - if (sz > valsz) - { - valsz = sz * 2; - if (valsz < 64) - valsz = 64; - newval = realloc (val, valsz); - if (newval == NULL) - goto read_err; - val = newval; - sz = wrap_getxattr (name, p, val, valsz); - if (sz < 0) - goto read_err; - } - if (wrap_setxattr (temp_name, p, val, sz, 0) < 0) - { - if (errno == ENOSYS || errno == ENOTSUP) - continue; - if (!ignore_errors) - { - int err = errno; - ssize_t newsz; - - newval = malloc (sz); - if (newval == NULL - || (newsz = wrap_getxattr (temp_name, p, newval, sz)) != sz - || memcmp (val, newval, sz) != 0) - { - error (0, err, "Could not set extended attributes for %s", - name); - free (newval); - free (val); - free (list); - return 1; - } - free (newval); - } - } - } - free (val); - free (list); - return 0; - -read_err: - error (0, errno, "Could not get extended attributes for %s", name); - free (val); - free (list); - return 1; -} - -static int -set_security_context (const char *temp_name, const char *name, - int ignore_errors) -{ -#ifdef USE_SELINUX - static int selinux_enabled = -1; - if (selinux_enabled == -1) - selinux_enabled = is_selinux_enabled (); - if (selinux_enabled > 0) - { - security_context_t scontext; - if (getfilecon (name, &scontext) < 0) - { - /* If the filesystem doesn't support extended attributes, - the original had no special security context and the - target cannot have one either. */ - if (errno == EOPNOTSUPP) - return 0; - - error (0, errno, "Could not get security context for %s", - name); - return 1; - } - if (setfilecon (temp_name, scontext) < 0 && !ignore_errors) - { - error (0, errno, "Could not set security context for %s", - name); - freecon (scontext); - return 1; - } - freecon (scontext); - } -#endif /* USE_SELINUX */ - return copy_xattrs (temp_name, name, ignore_errors); -} - -int -copy_fd_to_file (int fdin, const char *name, struct stat64 *st) -{ - struct stat64 stt; - off_t off = 0; - int err, fdout; - struct utimbuf u; - - if (strcmp (name, "-") == 0) - fdout = 1; - else - fdout = wrap_open (name, O_WRONLY | O_CREAT, 0600); - if (fdout != -1 - && fstat64 (fdin, &stt) >= 0 - && send_file (fdout, fdin, &off, stt.st_size) == stt.st_size) - { - if (fchown (fdout, st->st_uid, st->st_gid) >= 0) - fchmod (fdout, st->st_mode & 07777); - if (strcmp (name, "-") != 0) - { - set_security_context (name, name, 1); - u.actime = time (NULL); - u.modtime = st->st_mtime; - wrap_utime (name, &u); - close (fdout); - } - return 0; - } - else if (fdout != -1) - { - err = errno; - if (strcmp (name, "-") == 0) - close (fdout); - } - else - err = errno; - return err; -} - -int -update_dso (DSO *dso, const char *orig_name) -{ - int rdwr = dso_is_rdwr (dso); - - if (rdwr) - { - char *name1, *name2; - struct utimbuf u; - struct stat64 st; - int fdin; - - switch (write_dso (dso)) - { - case 2: - error (0, 0, "Could not write %s: %s", dso->filename, - elf_errmsg (-1)); - /* FALLTHROUGH */ - case 1: - close_dso (dso); - return 1; - case 0: - break; - } - - name1 = strdupa (dso->filename); - name2 = strdupa (dso->temp_filename); - if (fstat64 (dso->fdro, &st) < 0) - { - error (0, errno, "Could not stat %s", dso->filename); - close_dso (dso); - return 1; - } - if ((fchown (dso->fd, st.st_uid, st.st_gid) < 0 - || fchmod (dso->fd, st.st_mode & 07777) < 0) - && orig_name == NULL) - { - error (0, errno, "Could not set %s owner or mode", dso->filename); - close_dso (dso); - return 1; - } - if (orig_name != NULL) - fdin = dup (dso->fd); - else - fdin = -1; - close_dso_1 (dso); - u.actime = time (NULL); - u.modtime = st.st_mtime; - wrap_utime (name2, &u); - - if (set_security_context (name2, orig_name ? orig_name : name1, - orig_name != NULL)) - { - if (fdin != -1) - close (fdin); - wrap_unlink (name2); - return 1; - } - - if ((orig_name != NULL && strcmp (name1, "-") == 0) - || wrap_rename (name2, name1)) - { - if (fdin != -1) - { - int err = copy_fd_to_file (fdin, name1, &st); - - close (fdin); - wrap_unlink (name2); - if (err == 0) - return 0; - error (0, err, "Could not rename nor copy temporary to %s", - name1); - return 1; - } - wrap_unlink (name2); - error (0, errno, "Could not rename temporary to %s", name1); - return 1; - } - if (fdin != -1) - close (fdin); - } - else - close_dso_1 (dso); - - return 0; -} - -int allow_bad_textrel; - -int -dso_has_bad_textrel (DSO *dso) -{ - if (allow_bad_textrel) - return 0; - - switch (dso->arch->machine) - { - case EM_IA_64: - case EM_PPC: - case EM_PPC64: - case EM_X86_64: - case EM_ALPHA: - case EM_S390: - case EM_MIPS: - case EM_ARM: - return dynamic_info_is_set (dso, DT_TEXTREL); - - default: - return 0; - } -} -#endif /* DSO_READONLY */ diff --git a/trunk/src/dwarf2.c b/trunk/src/dwarf2.c deleted file mode 100644 index b9588b1..0000000 --- a/trunk/src/dwarf2.c +++ /dev/null @@ -1,1388 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2005, 2006, 2009, 2010, 2011, 2012 - Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <byteswap.h> -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <limits.h> -#include <string.h> -#include <sys/types.h> - -#include "dwarf2.h" -#include "hashtab.h" -#include "prelink.h" - -#define read_uleb128(ptr) ({ \ - unsigned int ret = 0; \ - unsigned int c; \ - int shift = 0; \ - do \ - { \ - c = *ptr++; \ - ret |= (c & 0x7f) << shift; \ - shift += 7; \ - } while (c & 0x80); \ - \ - if (shift >= 35) \ - ret = UINT_MAX; \ - ret; \ -}) - -static uint16_t (*do_read_16) (unsigned char *ptr); -static uint32_t (*do_read_32) (unsigned char *ptr); -static uint64_t (*do_read_32_64) (unsigned char *ptr); -static uint64_t (*do_read_64) (unsigned char *ptr); -static uint64_t (*do_read_ptr) (unsigned char *ptr); -static void (*write_32) (unsigned char *ptr, GElf_Addr val); -static void (*write_64) (unsigned char *ptr, GElf_Addr val); -static void (*write_ptr) (unsigned char *ptr, GElf_Addr val); - -static int ptr_size; - -#define read_1(ptr) *ptr++ - -#define read_16(ptr) ({ \ - uint16_t ret = do_read_16 (ptr); \ - ptr += 2; \ - ret; \ -}) - -#define read_32(ptr) ({ \ - uint32_t ret = do_read_32 (ptr); \ - ptr += 4; \ - ret; \ -}) - -#define read_64(ptr) ({ \ - uint64_t ret = do_read_64 (ptr); \ - ptr += 8; \ - ret; \ -}) - -#define read_ptr(ptr) ({ \ - uint64_t ret = do_read_ptr (ptr); \ - ptr += ptr_size; \ - ret; \ -}) - -static uint64_t -buf_read_ule32_64 (unsigned char *p) -{ - return buf_read_ule32 (p); -} - -static uint64_t -buf_read_ube32_64 (unsigned char *p) -{ - return buf_read_ube32 (p); -} - -static void -dwarf2_write_le32 (unsigned char *p, GElf_Addr val) -{ - uint32_t v = (uint32_t) val; - - p[0] = v; - p[1] = v >> 8; - p[2] = v >> 16; - p[3] = v >> 24; -} - -static void -dwarf2_write_le64 (unsigned char *p, GElf_Addr val) -{ - p[0] = val; - p[1] = val >> 8; - p[2] = val >> 16; - p[3] = val >> 24; - p[4] = val >> 32; - p[5] = val >> 40; - p[6] = val >> 48; - p[7] = val >> 56; -} - -static void -dwarf2_write_be32 (unsigned char *p, GElf_Addr val) -{ - uint32_t v = (uint32_t) val; - - p[3] = v; - p[2] = v >> 8; - p[1] = v >> 16; - p[0] = v >> 24; -} - -static void -dwarf2_write_be64 (unsigned char *p, GElf_Addr val) -{ - p[7] = val; - p[6] = val >> 8; - p[5] = val >> 16; - p[4] = val >> 24; - p[3] = val >> 32; - p[2] = val >> 40; - p[1] = val >> 48; - p[0] = val >> 56; -} - -static struct - { - const char *name; - unsigned char *data; - size_t size; - int sec; - } debug_sections[] = - { -#define DEBUG_INFO 0 -#define DEBUG_ABBREV 1 -#define DEBUG_LINE 2 -#define DEBUG_ARANGES 3 -#define DEBUG_PUBNAMES 4 -#define DEBUG_PUBTYPES 5 -#define DEBUG_MACINFO 6 -#define DEBUG_LOC 7 -#define DEBUG_STR 8 -#define DEBUG_FRAME 9 -#define DEBUG_RANGES 10 -#define DEBUG_TYPES 11 -#define DEBUG_MACRO 12 - { ".debug_info", NULL, 0, 0 }, - { ".debug_abbrev", NULL, 0, 0 }, - { ".debug_line", NULL, 0, 0 }, - { ".debug_aranges", NULL, 0, 0 }, - { ".debug_pubnames", NULL, 0, 0 }, - { ".debug_pubtypes", NULL, 0, 0 }, - { ".debug_macinfo", NULL, 0, 0 }, - { ".debug_loc", NULL, 0, 0 }, - { ".debug_str", NULL, 0, 0 }, - { ".debug_frame", NULL, 0, 0 }, - { ".debug_ranges", NULL, 0, 0 }, - { ".debug_types", NULL, 0, 0 }, - { ".debug_macro", NULL, 0, 0 }, - { NULL, NULL, 0 } - }; - -struct abbrev_attr - { - unsigned int attr; - unsigned int form; - }; - -struct abbrev_tag - { - unsigned int entry; - unsigned int tag; - int nattr; - struct abbrev_attr attr[0]; - }; - -struct cu_data - { - GElf_Addr cu_entry_pc; - GElf_Addr cu_low_pc; - unsigned char cu_version; - }; - -static hashval_t -abbrev_hash (const void *p) -{ - struct abbrev_tag *t = (struct abbrev_tag *)p; - - return t->entry; -} - -static int -abbrev_eq (const void *p, const void *q) -{ - struct abbrev_tag *t1 = (struct abbrev_tag *)p; - struct abbrev_tag *t2 = (struct abbrev_tag *)q; - - return t1->entry == t2->entry; -} - -static void -abbrev_del (void *p) -{ - free (p); -} - -static htab_t -read_abbrev (DSO *dso, unsigned char *ptr) -{ - htab_t h = htab_try_create (50, abbrev_hash, abbrev_eq, abbrev_del); - unsigned int attr, form; - struct abbrev_tag *t; - int size; - void **slot; - - if (h == NULL) - { -no_memory: - error (0, ENOMEM, "%s: Could not read .debug_abbrev", dso->filename); - if (h) - htab_delete (h); - return NULL; - } - - while ((attr = read_uleb128 (ptr)) != 0) - { - size = 10; - t = malloc (sizeof (*t) + size * sizeof (struct abbrev_attr)); - if (t == NULL) - goto no_memory; - t->entry = attr; - t->nattr = 0; - slot = htab_find_slot (h, t, INSERT); - if (slot == NULL) - { - free (t); - goto no_memory; - } - if (*slot != NULL) - { - error (0, 0, "%s: Duplicate DWARF abbreviation %d", dso->filename, - t->entry); - free (t); - htab_delete (h); - return NULL; - } - t->tag = read_uleb128 (ptr); - ++ptr; /* skip children flag. */ - while ((attr = read_uleb128 (ptr)) != 0) - { - if (t->nattr == size) - { - size += 10; - t = realloc (t, sizeof (*t) + size * sizeof (struct abbrev_attr)); - if (t == NULL) - goto no_memory; - } - form = read_uleb128 (ptr); - if (form == 2 - || (form > DW_FORM_flag_present - && form != DW_FORM_ref_sig8 - && form != DW_FORM_GNU_ref_alt - && form != DW_FORM_GNU_strp_alt)) - { - error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form); - htab_delete (h); - return NULL; - } - - t->attr[t->nattr].attr = attr; - t->attr[t->nattr++].form = form; - } - if (read_uleb128 (ptr) != 0) - { - error (0, 0, "%s: DWARF abbreviation does not end with 2 zeros", - dso->filename); - htab_delete (h); - return NULL; - } - *slot = t; - } - - return h; -} - -static int -adjust_location_list (DSO *dso, struct cu_data *cu, unsigned char *ptr, - size_t len, GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *end = ptr + len; - unsigned char op; - GElf_Addr addr; - - while (ptr < end) - { - op = *ptr++; - switch (op) - { - case DW_OP_addr: - addr = read_ptr (ptr); - if (addr >= start && addr_to_sec (dso, addr) != -1) - write_ptr (ptr - ptr_size, addr + adjust); - break; - case DW_OP_deref: - case DW_OP_dup: - case DW_OP_drop: - case DW_OP_over: - case DW_OP_swap: - case DW_OP_rot: - case DW_OP_xderef: - case DW_OP_abs: - case DW_OP_and: - case DW_OP_div: - case DW_OP_minus: - case DW_OP_mod: - case DW_OP_mul: - case DW_OP_neg: - case DW_OP_not: - case DW_OP_or: - case DW_OP_plus: - case DW_OP_shl: - case DW_OP_shr: - case DW_OP_shra: - case DW_OP_xor: - case DW_OP_eq: - case DW_OP_ge: - case DW_OP_gt: - case DW_OP_le: - case DW_OP_lt: - case DW_OP_ne: - case DW_OP_lit0 ... DW_OP_lit31: - case DW_OP_reg0 ... DW_OP_reg31: - case DW_OP_nop: - case DW_OP_push_object_address: - case DW_OP_form_tls_address: - case DW_OP_call_frame_cfa: - case DW_OP_stack_value: - case DW_OP_GNU_push_tls_address: - case DW_OP_GNU_uninit: - break; - case DW_OP_const1u: - case DW_OP_pick: - case DW_OP_deref_size: - case DW_OP_xderef_size: - case DW_OP_const1s: - ++ptr; - break; - case DW_OP_const2u: - case DW_OP_const2s: - case DW_OP_skip: - case DW_OP_bra: - case DW_OP_call2: - ptr += 2; - break; - case DW_OP_const4u: - case DW_OP_const4s: - case DW_OP_call4: - case DW_OP_GNU_parameter_ref: - ptr += 4; - break; - case DW_OP_call_ref: - if (cu == NULL) - { - error (0, 0, "%s: DWARF DW_OP_call_ref shouldn't appear" - " in .debug_frame", dso->filename); - return 1; - } - if (cu->cu_version == 2) - ptr += ptr_size; - else - ptr += 4; - break; - case DW_OP_const8u: - case DW_OP_const8s: - ptr += 8; - break; - case DW_OP_constu: - case DW_OP_plus_uconst: - case DW_OP_regx: - case DW_OP_piece: - case DW_OP_consts: - case DW_OP_breg0 ... DW_OP_breg31: - case DW_OP_fbreg: - case DW_OP_GNU_convert: - case DW_OP_GNU_reinterpret: - read_uleb128 (ptr); - break; - case DW_OP_bregx: - case DW_OP_bit_piece: - case DW_OP_GNU_regval_type: - read_uleb128 (ptr); - read_uleb128 (ptr); - break; - case DW_OP_implicit_value: - { - uint32_t leni = read_uleb128 (ptr); - ptr += leni; - } - break; - case DW_OP_GNU_implicit_pointer: - if (cu == NULL) - { - error (0, 0, "%s: DWARF DW_OP_GNU_implicit_pointer shouldn't" - " appear in .debug_frame", dso->filename); - return 1; - } - if (cu->cu_version == 2) - ptr += ptr_size; - else - ptr += 4; - read_uleb128 (ptr); - break; - case DW_OP_GNU_entry_value: - { - uint32_t leni = read_uleb128 (ptr); - if ((end - ptr) < leni) - { - error (0, 0, "%s: DWARF DW_OP_GNU_entry_value with too large" - " length", dso->filename); - return 1; - } - if (adjust_location_list (dso, cu, ptr, leni, start, adjust)) - return 1; - ptr += leni; - } - break; - case DW_OP_GNU_const_type: - read_uleb128 (ptr); - ptr += *ptr + 1; - break; - case DW_OP_GNU_deref_type: - ++ptr; - read_uleb128 (ptr); - break; - default: - error (0, 0, "%s: Unknown DWARF DW_OP_%d", dso->filename, op); - return 1; - } - } - return 0; -} - -static int -adjust_dwarf2_ranges (DSO *dso, GElf_Addr offset, GElf_Addr base, - GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *ptr, *endsec; - GElf_Addr low, high; - int adjusted_base; - - ptr = debug_sections[DEBUG_RANGES].data; - if (ptr == NULL) - { - error (0, 0, "%s: DW_AT_ranges attribute, yet no .debug_ranges section", - dso->filename); - return 1; - } - if (offset >= debug_sections[DEBUG_RANGES].size) - { - error (0, 0, - "%s: DW_AT_ranges offset %Ld outside of .debug_ranges section", - dso->filename, (long long) offset); - return 1; - } - endsec = ptr + debug_sections[DEBUG_RANGES].size; - ptr += offset; - adjusted_base = (base && base >= start && addr_to_sec (dso, base) != -1); - while (ptr < endsec) - { - low = read_ptr (ptr); - high = read_ptr (ptr); - if (low == 0 && high == 0) - break; - - if (low == ~ (GElf_Addr) 0 || (ptr_size == 4 && low == 0xffffffff)) - { - base = high; - adjusted_base = (base && base >= start - && addr_to_sec (dso, base) != -1); - if (adjusted_base) - write_ptr (ptr - ptr_size, base + adjust); - } - else if (! adjusted_base) - { - if (base + low >= start && addr_to_sec (dso, base + low) != -1) - { - write_ptr (ptr - 2 * ptr_size, low + adjust); - if (high == low) - write_ptr (ptr - ptr_size, high + adjust); - } - if (low != high && base + high >= start - && addr_to_sec (dso, base + high - 1) != -1) - write_ptr (ptr - ptr_size, high + adjust); - } - } - - elf_flagscn (dso->scn[debug_sections[DEBUG_RANGES].sec], ELF_C_SET, - ELF_F_DIRTY); - return 0; -} - -static int -adjust_dwarf2_loc (DSO *dso, struct cu_data *cu, GElf_Addr offset, - GElf_Addr base, GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *ptr, *endsec; - GElf_Addr low, high; - int adjusted_base; - size_t len; - - ptr = debug_sections[DEBUG_LOC].data; - if (ptr == NULL) - { - error (0, 0, "%s: loclistptr attribute, yet no .debug_loc section", - dso->filename); - return 1; - } - if (offset >= debug_sections[DEBUG_LOC].size) - { - error (0, 0, - "%s: loclistptr offset %Ld outside of .debug_loc section", - dso->filename, (long long) offset); - return 1; - } - endsec = ptr + debug_sections[DEBUG_LOC].size; - ptr += offset; - adjusted_base = (base && base >= start && addr_to_sec (dso, base) != -1); - while (ptr < endsec) - { - low = read_ptr (ptr); - high = read_ptr (ptr); - if (low == 0 && high == 0) - break; - - if (low == ~ (GElf_Addr) 0 || (ptr_size == 4 && low == 0xffffffff)) - { - base = high; - adjusted_base = (base && base >= start - && addr_to_sec (dso, base) != -1); - if (adjusted_base) - write_ptr (ptr - ptr_size, base + adjust); - continue; - } - len = read_16 (ptr); - assert (ptr + len <= endsec); - - if (adjust_location_list (dso, cu, ptr, len, start, adjust)) - return 1; - - ptr += len; - } - - elf_flagscn (dso->scn[debug_sections[DEBUG_LOC].sec], ELF_C_SET, - ELF_F_DIRTY); - return 0; -} - -static unsigned char * -adjust_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, - struct cu_data *cu, - GElf_Addr start, GElf_Addr adjust, htab_t offset_hash) -{ - int i; - GElf_Addr addr; - - for (i = 0; i < t->nattr; ++i) - { - uint32_t form = t->attr[i].form; - uint32_t len = 0; - - while (1) - { - switch (t->attr[i].attr) - { - case DW_AT_data_member_location: - /* In DWARF4+ DW_AT_data_member_location - with DW_FORM_data[48] is just very high - constant, rather than loclistptr. */ - if (cu->cu_version >= 4 && form != DW_FORM_sec_offset) - break; - /* FALLTHRU */ - case DW_AT_location: - case DW_AT_string_length: - case DW_AT_return_addr: - case DW_AT_frame_base: - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: - case DW_AT_vtable_elem_location: - case DW_AT_ranges: - if (form == DW_FORM_data4 || form == DW_FORM_sec_offset) - addr = read_32 (ptr), ptr -= 4; - else if (form == DW_FORM_data8) - addr = read_64 (ptr), ptr -= 8; - else - break; - { - GElf_Addr base; - - if (cu->cu_entry_pc != ~ (GElf_Addr) 0) - base = cu->cu_entry_pc; - else if (cu->cu_low_pc != ~ (GElf_Addr) 0) - base = cu->cu_low_pc; - else - base = 0; - if (t->attr[i].attr == DW_AT_ranges) - { - if (adjust_dwarf2_ranges (dso, addr, base, start, adjust)) - return NULL; - } - else - { - GElf_Addr *offsetp = malloc (sizeof (addr)); - void **slot; - if (offsetp == NULL) - return NULL; - *offsetp = addr; - slot = htab_find_slot (offset_hash, offsetp, INSERT); - if (slot == NULL) - { - free (offsetp); - return NULL; - } - if (*slot == NULL) - { - *slot = offsetp; - if (adjust_dwarf2_loc (dso, cu, addr, base, - start, adjust)) - return NULL; - } - else - free (offsetp); - } - } - break; - } - switch (form) - { - case DW_FORM_addr: - addr = read_ptr (ptr); - if (t->tag == DW_TAG_compile_unit - || t->tag == DW_TAG_partial_unit) - { - if (t->attr[i].attr == DW_AT_entry_pc) - cu->cu_entry_pc = addr; - else if (t->attr[i].attr == DW_AT_low_pc) - cu->cu_low_pc = addr; - if (addr == 0) - break; - } - if (addr >= start - && addr_to_sec (dso, - ((t->attr[i].attr == DW_AT_high_pc - && addr > start) - ? addr - 1 - : addr)) != -1) - write_ptr (ptr - ptr_size, addr + adjust); - break; - case DW_FORM_flag_present: - break; - case DW_FORM_ref1: - case DW_FORM_flag: - case DW_FORM_data1: - ++ptr; - break; - case DW_FORM_ref2: - case DW_FORM_data2: - ptr += 2; - break; - case DW_FORM_ref4: - case DW_FORM_GNU_ref_alt: - case DW_FORM_data4: - case DW_FORM_sec_offset: - ptr += 4; - break; - case DW_FORM_ref8: - case DW_FORM_data8: - case DW_FORM_ref_sig8: - ptr += 8; - break; - case DW_FORM_sdata: - case DW_FORM_ref_udata: - case DW_FORM_udata: - read_uleb128 (ptr); - break; - case DW_FORM_ref_addr: - if (cu->cu_version == 2) - ptr += ptr_size; - else - ptr += 4; - break; - case DW_FORM_strp: - case DW_FORM_GNU_strp_alt: - ptr += 4; - break; - case DW_FORM_string: - ptr = strchr (ptr, '\0') + 1; - break; - case DW_FORM_indirect: - form = read_uleb128 (ptr); - continue; - case DW_FORM_block1: - len = *ptr++; - break; - case DW_FORM_block2: - len = read_16 (ptr); - form = DW_FORM_block1; - break; - case DW_FORM_block4: - len = read_32 (ptr); - form = DW_FORM_block1; - break; - case DW_FORM_block: - len = read_uleb128 (ptr); - form = DW_FORM_block1; - assert (len < UINT_MAX); - break; - case DW_FORM_exprloc: - len = read_uleb128 (ptr); - assert (len < UINT_MAX); - break; - default: - error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, - form); - return NULL; - } - - if (form == DW_FORM_block1) - { - switch (t->attr[i].attr) - { - case DW_AT_frame_base: - case DW_AT_location: - case DW_AT_data_member_location: - case DW_AT_vtable_elem_location: - case DW_AT_byte_size: - case DW_AT_bit_offset: - case DW_AT_bit_size: - case DW_AT_string_length: - case DW_AT_lower_bound: - case DW_AT_return_addr: - case DW_AT_bit_stride: - case DW_AT_upper_bound: - case DW_AT_count: - case DW_AT_segment: - case DW_AT_static_link: - case DW_AT_use_location: - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_byte_stride: - 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 (adjust_location_list (dso, cu, ptr, len, start, adjust)) - return NULL; - break; - default: - if (t->attr[i].attr <= DW_AT_linkage_name - || (t->attr[i].attr >= DW_AT_MIPS_fde - && t->attr[i].attr <= DW_AT_MIPS_has_inlines) - || (t->attr[i].attr >= DW_AT_sf_names - && t->attr[i].attr <= DW_AT_body_end)) - break; - error (0, 0, "%s: Unknown DWARF DW_AT_%d with block DW_FORM", - dso->filename, t->attr[i].attr); - return NULL; - } - ptr += len; - } - else if (form == DW_FORM_exprloc) - { - if (adjust_location_list (dso, cu, ptr, len, start, adjust)) - return NULL; - ptr += len; - } - - break; - } - } - - return ptr; -} - -static int -adjust_dwarf2_line (DSO *dso, GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *ptr = debug_sections[DEBUG_LINE].data; - unsigned char *endsec = ptr + debug_sections[DEBUG_LINE].size; - unsigned char *endcu, *endprol; - unsigned char opcode_base, *opcode_lengths, op; - uint32_t value; - GElf_Addr addr; - int i; - - while (ptr < endsec) - { - endcu = ptr + 4; - endcu += read_32 (ptr); - if (endcu == ptr + 0xffffffff) - { - error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); - return 1; - } - - if (endcu > endsec) - { - error (0, 0, "%s: .debug_line CU does not fit into section", - dso->filename); - return 1; - } - - value = read_16 (ptr); - if (value != 2 && value != 3 && value != 4) - { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, - value); - return 1; - } - - endprol = ptr + 4; - endprol += read_32 (ptr); - if (endprol > endcu) - { - error (0, 0, "%s: .debug_line CU prologue does not fit into CU", - dso->filename); - return 1; - } - - opcode_base = ptr[4 + (value >= 4)]; - opcode_lengths = ptr + 4 + (value >= 4); - - ptr = endprol; - while (ptr < endcu) - { - op = *ptr++; - if (op >= opcode_base) - continue; - if (op == DW_LNS_extended_op) - { - unsigned int len = read_uleb128 (ptr); - - assert (len < UINT_MAX); - op = *ptr++; - switch (op) - { - case DW_LNE_set_address: - addr = read_ptr (ptr); - if (addr >= start && addr_to_sec (dso, addr) != -1) - write_ptr (ptr - ptr_size, addr + adjust); - break; - case DW_LNE_end_sequence: - case DW_LNE_define_file: - case DW_LNE_set_discriminator: - default: - ptr += len - 1; - break; - } - } - else if (op == DW_LNS_fixed_advance_pc) - ptr += 2; - else - for (i = 0; i < opcode_lengths[op]; ++i) - read_uleb128 (ptr); - } - } - - elf_flagscn (dso->scn[debug_sections[DEBUG_LINE].sec], ELF_C_SET, - ELF_F_DIRTY); - return 0; -} - -static int -adjust_dwarf2_aranges (DSO *dso, GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *ptr = debug_sections[DEBUG_ARANGES].data; - unsigned char *endsec = ptr + debug_sections[DEBUG_ARANGES].size; - unsigned char *endcu; - GElf_Addr addr, len; - uint32_t value; - - while (ptr < endsec) - { - endcu = ptr + 4; - endcu += read_32 (ptr); - if (endcu == ptr + 0xffffffff) - { - error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); - return 1; - } - - if (endcu > endsec) - { - error (0, 0, "%s: .debug_line CU does not fit into section", - dso->filename); - return 1; - } - - value = read_16 (ptr); - if (value != 2) - { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, - value); - return 1; - } - - ptr += 4; - if (ptr[0] != ptr_size || ptr[1]) - { - error (0, 0, "%s: Unsupported .debug_aranges address size %d or segment size %d", - dso->filename, ptr[0], ptr[1]); - return 1; - } - - ptr += 6; - while (ptr < endcu) - { - addr = read_ptr (ptr); - len = read_ptr (ptr); - if (addr == 0 && len == 0) - break; - if (addr >= start && addr_to_sec (dso, addr) != -1) - write_ptr (ptr - 2 * ptr_size, addr + adjust); - } - assert (ptr == endcu); - } - - elf_flagscn (dso->scn[debug_sections[DEBUG_LINE].sec], ELF_C_SET, - ELF_F_DIRTY); - return 0; -} - -static int -adjust_dwarf2_frame (DSO *dso, GElf_Addr start, GElf_Addr adjust) -{ - unsigned char *ptr = debug_sections[DEBUG_FRAME].data; - unsigned char *endsec = ptr + debug_sections[DEBUG_FRAME].size; - unsigned char *endie; - GElf_Addr addr, len; - uint32_t value; - - while (ptr < endsec) - { - endie = ptr + 4; - endie += read_32 (ptr); - if (endie == ptr + 0xffffffff) - { - error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); - return 1; - } - - if (endie > endsec) - { - error (0, 0, "%s: .debug_frame CIE/FDE does not fit into section", - dso->filename); - return 1; - } - - value = read_32 (ptr); - if (value == 0xffffffff) - { - /* CIE. */ - uint32_t version = *ptr++; - if (version != 1 && version != 3 && version != 4) - { - error (0, 0, "%s: unhandled .debug_frame version %d", - dso->filename, version); - return 1; - } - if (*ptr == 'S') - { - /* This is a signal frame. We don't care. */ - ptr++; - } - if (*ptr != '\0') - { - error (0, 0, "%s: .debug_frame unhandled augmentation \"%s\"", - dso->filename, ptr); - return 1; - } - ptr++; /* Skip augmentation. */ - if (version >= 4) - { - if (ptr[0] != ptr_size) - { - error (0, 0, "%s: .debug_frame unhandled pointer size %d", - dso->filename, ptr[0]); - return 1; - } - if (ptr[1] != 0) - { - error (0, 0, "%s: .debug_frame unhandled non-zero segment size", - dso->filename); - return 1; - } - ptr += 2; - } - read_uleb128 (ptr); /* Skip code_alignment factor. */ - read_uleb128 (ptr); /* Skip data_alignment factor. */ - if (version >= 3) - read_uleb128 (ptr); /* Skip return_address_register. */ - else - ptr++; - } - else - { - addr = read_ptr (ptr); - if (addr >= start && addr_to_sec (dso, addr) != -1) - write_ptr (ptr - ptr_size, addr + adjust); - read_ptr (ptr); /* Skip address range. */ - } - - while (ptr < endie) - { - unsigned char insn = *ptr++; - - if ((insn & 0xc0) == DW_CFA_advance_loc - || (insn & 0xc0) == DW_CFA_restore) - continue; - else if ((insn & 0xc0) == DW_CFA_offset) - { - read_uleb128 (ptr); - continue; - } - switch (insn) - { - case DW_CFA_nop: - case DW_CFA_remember_state: - case DW_CFA_restore_state: - case DW_CFA_GNU_window_save: - break; - case DW_CFA_offset_extended: - case DW_CFA_register: - case DW_CFA_def_cfa: - case DW_CFA_offset_extended_sf: - case DW_CFA_def_cfa_sf: - case DW_CFA_GNU_negative_offset_extended: - case DW_CFA_val_offset: - case DW_CFA_val_offset_sf: - read_uleb128 (ptr); - /* FALLTHROUGH */ - 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: - read_uleb128 (ptr); - break; - case DW_CFA_set_loc: - addr = read_ptr (ptr); - if (addr >= start && addr_to_sec (dso, addr) != -1) - write_ptr (ptr - ptr_size, addr + adjust); - break; - case DW_CFA_advance_loc1: - ptr++; - break; - case DW_CFA_advance_loc2: - ptr += 2; - break; - case DW_CFA_advance_loc4: - ptr += 4; - break; - case DW_CFA_expression: - case DW_CFA_val_expression: - read_uleb128 (ptr); - /* FALLTHROUGH */ - case DW_CFA_def_cfa_expression: - len = read_uleb128 (ptr); - if (adjust_location_list (dso, NULL, ptr, len, start, adjust)) - return 1; - ptr += len; - break; - default: - error (0, 0, "%s: Unhandled DW_CFA_%02x operation", - dso->filename, insn); - return 1; - } - } - } - - elf_flagscn (dso->scn[debug_sections[DEBUG_FRAME].sec], ELF_C_SET, - ELF_F_DIRTY); - return 0; -} - -static hashval_t -loclistoffset_hash (const void *p) -{ - GElf_Addr *offset = (GElf_Addr *)p; - - return *offset; -} - -static int -loclistoffset_eq (const void *p, const void *q) -{ - GElf_Addr *offset1 = (GElf_Addr *)p; - GElf_Addr *offset2 = (GElf_Addr *)q; - - return *offset1 = *offset2; -} - -static void -loclistoffset_del (void *p) -{ - free (p); -} - -static int -adjust_dwarf2_info (DSO *dso, GElf_Addr start, GElf_Addr adjust, int type) -{ - unsigned char *ptr, *endcu, *endsec; - uint32_t value; - htab_t abbrev; - struct abbrev_tag tag, *t; - struct cu_data cu; - htab_t offset_hash = htab_try_create (50, loclistoffset_hash, - loclistoffset_eq, loclistoffset_del); - - if (offset_hash == NULL) - { - error (0, ENOMEM, "%s: Could not create hash for attributes", - dso->filename); - return 1; - } - - memset (&cu, 0, sizeof(cu)); - ptr = debug_sections[type].data; - endsec = ptr + debug_sections[type].size; - while (ptr < endsec) - { - if (ptr + 11 > endsec) - { - error (0, 0, "%s: .debug_info CU header too small", dso->filename); - htab_delete (offset_hash); - return 1; - } - - endcu = ptr + 4; - endcu += read_32 (ptr); - if (endcu == ptr + 0xffffffff) - { - error (0, 0, "%s: 64-bit DWARF not supported", dso->filename); - htab_delete (offset_hash); - return 1; - } - - if (endcu > endsec) - { - error (0, 0, "%s: .debug_info too small", dso->filename); - htab_delete (offset_hash); - return 1; - } - - value = read_16 (ptr); - if (value != 2 && value != 3 && value != 4) - { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, value); - htab_delete (offset_hash); - return 1; - } - cu.cu_version = value; - - value = read_32 (ptr); - if (value >= debug_sections[DEBUG_ABBREV].size) - { - if (debug_sections[DEBUG_ABBREV].data == NULL) - error (0, 0, "%s: .debug_abbrev not present", dso->filename); - else - error (0, 0, "%s: DWARF CU abbrev offset too large", - dso->filename); - htab_delete (offset_hash); - return 1; - } - - if (ptr_size == 0) - { - ptr_size = read_1 (ptr); - if (ptr_size == 4) - { - do_read_ptr = do_read_32_64; - write_ptr = write_32; - } - else if (ptr_size == 8) - { - do_read_ptr = do_read_64; - write_ptr = write_64; - } - else - { - error (0, 0, "%s: Invalid DWARF pointer size %d", - dso->filename, ptr_size); - htab_delete (offset_hash); - return 1; - } - } - else if (read_1 (ptr) != ptr_size) - { - error (0, 0, "%s: DWARF pointer size differs between CUs", - dso->filename); - htab_delete (offset_hash); - return 1; - } - - abbrev = read_abbrev (dso, debug_sections[DEBUG_ABBREV].data + value); - if (abbrev == NULL) - { - htab_delete (offset_hash); - return 1; - } - - cu.cu_entry_pc = ~ (GElf_Addr) 0; - cu.cu_low_pc = ~ (GElf_Addr) 0; - - if (type == DEBUG_TYPES) - { - ptr += 8; /* Skip type_signature. */ - ptr += 4; /* Skip type_offset. */ - } - - while (ptr < endcu) - { - tag.entry = read_uleb128 (ptr); - if (tag.entry == 0) - continue; - t = htab_find_with_hash (abbrev, &tag, tag.entry); - if (t == NULL) - { - error (0, 0, "%s: Could not find DWARF abbreviation %d", - dso->filename, tag.entry); - htab_delete (abbrev); - htab_delete (offset_hash); - return 1; - } - - ptr = adjust_attributes (dso, ptr, t, &cu, start, adjust, - offset_hash); - if (ptr == NULL) - { - htab_delete (abbrev); - htab_delete (offset_hash); - return 1; - } - } - - htab_delete (abbrev); - } - htab_delete (offset_hash); - return 0; -} - -int -adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data; - Elf_Scn *scn; - int i, j; - - for (i = 0; debug_sections[i].name; ++i) - { - debug_sections[i].data = NULL; - debug_sections[i].size = 0; - debug_sections[i].sec = 0; - } - ptr_size = 0; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)) - && dso->shdr[i].sh_size) - { - const char *name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name); - - if (strncmp (name, ".debug_", sizeof (".debug_") - 1) == 0) - { - for (j = 0; debug_sections[j].name; ++j) - if (strcmp (name, debug_sections[j].name) == 0) - { - if (debug_sections[j].data) - { - error (0, 0, "%s: Found two copies of %s section", - dso->filename, name); - return 1; - } - - scn = dso->scn[i]; - data = elf_getdata (scn, NULL); - assert (data != NULL && data->d_buf != NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0); - assert (data->d_size == dso->shdr[i].sh_size); - debug_sections[j].data = data->d_buf; - debug_sections[j].size = data->d_size; - debug_sections[j].sec = i; - break; - } - - if (debug_sections[j].name == NULL) - { - error (0, 0, "%s: Unknown debugging section %s", - dso->filename, name); - return 1; - } - } - } - - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) - { - do_read_16 = buf_read_ule16; - do_read_32 = buf_read_ule32; - do_read_32_64 = buf_read_ule32_64; - do_read_64 = buf_read_ule64; - write_32 = dwarf2_write_le32; - write_64 = dwarf2_write_le64; - } - else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) - { - do_read_16 = buf_read_ube16; - do_read_32 = buf_read_ube32; - do_read_32_64 = buf_read_ube32_64; - do_read_64 = buf_read_ube64; - write_32 = dwarf2_write_be32; - write_64 = dwarf2_write_be64; - } - else - { - error (0, 0, "%s: Wrong ELF data enconding", dso->filename); - return 1; - } - - if (debug_sections[DEBUG_INFO].data != NULL - && adjust_dwarf2_info (dso, start, adjust, DEBUG_INFO)) - return 1; - - if (debug_sections[DEBUG_TYPES].data != NULL - && adjust_dwarf2_info (dso, start, adjust, DEBUG_TYPES)) - return 1; - - if (ptr_size == 0) - /* Should not happen. */ - ptr_size = dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4; - - if (debug_sections[DEBUG_LINE].data != NULL - && adjust_dwarf2_line (dso, start, adjust)) - return 1; - - if (debug_sections[DEBUG_ARANGES].data != NULL - && adjust_dwarf2_aranges (dso, start, adjust)) - return 1; - - if (debug_sections[DEBUG_FRAME].data != NULL - && adjust_dwarf2_frame (dso, start, adjust)) - return 1; - - /* .debug_abbrev requires no adjustement. */ - /* .debug_pubnames requires no adjustement. */ - /* .debug_pubtypes requires no adjustement. */ - /* .debug_macinfo requires no adjustement. */ - /* .debug_str requires no adjustement. */ - /* .debug_ranges adjusted for each DW_AT_ranges pointing into it. */ - /* .debug_loc adjusted for each loclistptr pointing into it. */ - - elf_flagscn (dso->scn[n], ELF_C_SET, ELF_F_DIRTY); - return 0; -} diff --git a/trunk/src/dwarf2.h b/trunk/src/dwarf2.h deleted file mode 100644 index b0c80b6..0000000 --- a/trunk/src/dwarf2.h +++ /dev/null @@ -1,570 +0,0 @@ -/* Copyright (C) 2001, 2002, 2009, 2010, 2011, 2012 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#define DW_TAG_padding 0x00 -#define DW_TAG_array_type 0x01 -#define DW_TAG_class_type 0x02 -#define DW_TAG_entry_point 0x03 -#define DW_TAG_enumeration_type 0x04 -#define DW_TAG_formal_parameter 0x05 -#define DW_TAG_imported_declaration 0x08 -#define DW_TAG_label 0x0a -#define DW_TAG_lexical_block 0x0b -#define DW_TAG_member 0x0d -#define DW_TAG_pointer_type 0x0f -#define DW_TAG_reference_type 0x10 -#define DW_TAG_compile_unit 0x11 -#define DW_TAG_string_type 0x12 -#define DW_TAG_structure_type 0x13 -#define DW_TAG_subroutine_type 0x15 -#define DW_TAG_typedef 0x16 -#define DW_TAG_union_type 0x17 -#define DW_TAG_unspecified_parameters 0x18 -#define DW_TAG_variant 0x19 -#define DW_TAG_common_block 0x1a -#define DW_TAG_common_inclusion 0x1b -#define DW_TAG_inheritance 0x1c -#define DW_TAG_inlined_subroutine 0x1d -#define DW_TAG_module 0x1e -#define DW_TAG_ptr_to_member_type 0x1f -#define DW_TAG_set_type 0x20 -#define DW_TAG_subrange_type 0x21 -#define DW_TAG_with_stmt 0x22 -#define DW_TAG_access_declaration 0x23 -#define DW_TAG_base_type 0x24 -#define DW_TAG_catch_block 0x25 -#define DW_TAG_const_type 0x26 -#define DW_TAG_constant 0x27 -#define DW_TAG_enumerator 0x28 -#define DW_TAG_file_type 0x29 -#define DW_TAG_friend 0x2a -#define DW_TAG_namelist 0x2b -#define DW_TAG_namelist_item 0x2c -#define DW_TAG_packed_type 0x2d -#define DW_TAG_subprogram 0x2e -#define DW_TAG_template_type_param 0x2f -#define DW_TAG_template_value_param 0x30 -#define DW_TAG_thrown_type 0x31 -#define DW_TAG_try_block 0x32 -#define DW_TAG_variant_part 0x33 -#define DW_TAG_variable 0x34 -#define DW_TAG_volatile_type 0x35 -#define DW_TAG_dwarf_procedure 0x36 -#define DW_TAG_restrict_type 0x37 -#define DW_TAG_interface_type 0x38 -#define DW_TAG_namespace 0x39 -#define DW_TAG_imported_module 0x3a -#define DW_TAG_unspecified_type 0x3b -#define DW_TAG_partial_unit 0x3c -#define DW_TAG_imported_unit 0x3d -#define DW_TAG_condition 0x3f -#define DW_TAG_shared_type 0x40 -#define DW_TAG_type_unit 0x41 -#define DW_TAG_rvalue_reference_type 0x42 -#define DW_TAG_template_alias 0x43 -#define DW_TAG_MIPS_loop 0x4081 -#define DW_TAG_format_label 0x4101 -#define DW_TAG_function_template 0x4102 -#define DW_TAG_class_template 0x4103 -#define DW_TAG_GNU_BINCL 0x4104 -#define DW_TAG_GNU_EINCL 0x4105 -#define DW_TAG_GNU_template_template_param 0x4106 -#define DW_TAG_GNU_template_parameter_pack 0x4107 -#define DW_TAG_GNU_formal_parameter_pack 0x4108 -#define DW_TAG_GNU_call_site 0x4109 -#define DW_TAG_GNU_call_site_parameter 0x410a -#define DW_TAG_lo_user 0x4080 -#define DW_TAG_hi_user 0xffff - -#define DW_children_no 0x0 -#define DW_children_yes 0x1 - -#define DW_FORM_addr 0x01 -#define DW_FORM_block2 0x03 -#define DW_FORM_block4 0x04 -#define DW_FORM_data2 0x05 -#define DW_FORM_data4 0x06 -#define DW_FORM_data8 0x07 -#define DW_FORM_string 0x08 -#define DW_FORM_block 0x09 -#define DW_FORM_block1 0x0a -#define DW_FORM_data1 0x0b -#define DW_FORM_flag 0x0c -#define DW_FORM_sdata 0x0d -#define DW_FORM_strp 0x0e -#define DW_FORM_udata 0x0f -#define DW_FORM_ref_addr 0x10 -#define DW_FORM_ref1 0x11 -#define DW_FORM_ref2 0x12 -#define DW_FORM_ref4 0x13 -#define DW_FORM_ref8 0x14 -#define DW_FORM_ref_udata 0x15 -#define DW_FORM_indirect 0x16 -#define DW_FORM_sec_offset 0x17 -#define DW_FORM_exprloc 0x18 -#define DW_FORM_flag_present 0x19 -#define DW_FORM_ref_sig8 0x20 -#define DW_FORM_GNU_ref_alt 0x1f20 -#define DW_FORM_GNU_strp_alt 0x1f21 - -#define DW_AT_sibling 0x01 -#define DW_AT_location 0x02 -#define DW_AT_name 0x03 -#define DW_AT_ordering 0x09 -#define DW_AT_subscr_data 0x0a -#define DW_AT_byte_size 0x0b -#define DW_AT_bit_offset 0x0c -#define DW_AT_bit_size 0x0d -#define DW_AT_element_list 0x0f -#define DW_AT_stmt_list 0x10 -#define DW_AT_low_pc 0x11 -#define DW_AT_high_pc 0x12 -#define DW_AT_language 0x13 -#define DW_AT_member 0x14 -#define DW_AT_discr 0x15 -#define DW_AT_discr_value 0x16 -#define DW_AT_visibility 0x17 -#define DW_AT_import 0x18 -#define DW_AT_string_length 0x19 -#define DW_AT_common_reference 0x1a -#define DW_AT_comp_dir 0x1b -#define DW_AT_const_value 0x1c -#define DW_AT_containing_type 0x1d -#define DW_AT_default_value 0x1e -#define DW_AT_inline 0x20 -#define DW_AT_is_optional 0x21 -#define DW_AT_lower_bound 0x22 -#define DW_AT_producer 0x25 -#define DW_AT_prototyped 0x27 -#define DW_AT_return_addr 0x2a -#define DW_AT_start_scope 0x2c -#define DW_AT_stride_size 0x2e -#define DW_AT_bit_stride 0x2e -#define DW_AT_upper_bound 0x2f -#define DW_AT_abstract_origin 0x31 -#define DW_AT_accessibility 0x32 -#define DW_AT_address_class 0x33 -#define DW_AT_artificial 0x34 -#define DW_AT_base_types 0x35 -#define DW_AT_calling_convention 0x36 -#define DW_AT_count 0x37 -#define DW_AT_data_member_location 0x38 -#define DW_AT_decl_column 0x39 -#define DW_AT_decl_file 0x3a -#define DW_AT_decl_line 0x3b -#define DW_AT_declaration 0x3c -#define DW_AT_discr_list 0x3d -#define DW_AT_encoding 0x3e -#define DW_AT_external 0x3f -#define DW_AT_frame_base 0x40 -#define DW_AT_friend 0x41 -#define DW_AT_identifier_case 0x42 -#define DW_AT_macro_info 0x43 -#define DW_AT_namelist_items 0x44 -#define DW_AT_priority 0x45 -#define DW_AT_segment 0x46 -#define DW_AT_specification 0x47 -#define DW_AT_static_link 0x48 -#define DW_AT_type 0x49 -#define DW_AT_use_location 0x4a -#define DW_AT_variable_parameter 0x4b -#define DW_AT_virtuality 0x4c -#define DW_AT_vtable_elem_location 0x4d -#define DW_AT_allocated 0x4e -#define DW_AT_associated 0x4f -#define DW_AT_data_location 0x50 -#define DW_AT_stride 0x51 -#define DW_AT_byte_stride 0x51 -#define DW_AT_entry_pc 0x52 -#define DW_AT_use_UTF8 0x53 -#define DW_AT_extension 0x54 -#define DW_AT_ranges 0x55 -#define DW_AT_trampoline 0x56 -#define DW_AT_call_column 0x57 -#define DW_AT_call_file 0x58 -#define DW_AT_call_line 0x59 -#define DW_AT_description 0x5a -#define DW_AT_binary_scale 0x5b -#define DW_AT_decimal_scale 0x5c -#define DW_AT_small 0x5d -#define DW_AT_decimal_sign 0x5e -#define DW_AT_digit_count 0x5f -#define DW_AT_picture_string 0x60 -#define DW_AT_mutable 0x61 -#define DW_AT_threads_scaled 0x62 -#define DW_AT_explicit 0x63 -#define DW_AT_object_pointer 0x64 -#define DW_AT_endianity 0x65 -#define DW_AT_elemental 0x66 -#define DW_AT_pure 0x67 -#define DW_AT_recursive 0x68 -#define DW_AT_signature 0x69 -#define DW_AT_main_subprogram 0x6a -#define DW_AT_data_bit_offset 0x6b -#define DW_AT_const_expr 0x6c -#define DW_AT_enum_class 0x6d -#define DW_AT_linkage_name 0x6e -#define DW_AT_MIPS_fde 0x2001 -#define DW_AT_MIPS_loop_begin 0x2002 -#define DW_AT_MIPS_tail_loop_begin 0x2003 -#define DW_AT_MIPS_epilog_begin 0x2004 -#define DW_AT_MIPS_loop_unroll_factor 0x2005 -#define DW_AT_MIPS_software_pipeline_depth 0x2006 -#define DW_AT_MIPS_linkage_name 0x2007 -#define DW_AT_MIPS_stride 0x2008 -#define DW_AT_MIPS_abstract_name 0x2009 -#define DW_AT_MIPS_clone_origin 0x200a -#define DW_AT_MIPS_has_inlines 0x200b -#define DW_AT_sf_names 0x2101 -#define DW_AT_src_info 0x2102 -#define DW_AT_mac_info 0x2103 -#define DW_AT_src_coords 0x2104 -#define DW_AT_body_begin 0x2105 -#define DW_AT_body_end 0x2106 -#define DW_AT_GNU_vector 0x2107 -#define DW_AT_GNU_guarded_by 0x2108 -#define DW_AT_GNU_pt_guarded_by 0x2109 -#define DW_AT_GNU_guarded 0x210a -#define DW_AT_GNU_pt_guarded 0x210b -#define DW_AT_GNU_locks_excluded 0x210c -#define DW_AT_GNU_exclusive_locks_required 0x210d -#define DW_AT_GNU_shared_locks_required 0x210e -#define DW_AT_GNU_odr_signature 0x210f -#define DW_AT_GNU_template_name 0x2110 -#define DW_AT_GNU_call_site_value 0x2111 -#define DW_AT_GNU_call_site_data_value 0x2112 -#define DW_AT_GNU_call_site_target 0x2113 -#define DW_AT_GNU_call_site_target_clobbered 0x2114 -#define DW_AT_GNU_tail_call 0x2115 -#define DW_AT_GNU_all_tail_call_sites 0x2116 -#define DW_AT_GNU_all_call_sites 0x2117 -#define DW_AT_GNU_all_source_call_sites 0x2118 -#define DW_AT_lo_user 0x2000 -#define DW_AT_hi_user 0x3ff0 - -#define DW_OP_addr 0x03 -#define DW_OP_deref 0x06 -#define DW_OP_const1u 0x08 -#define DW_OP_const1s 0x09 -#define DW_OP_const2u 0x0a -#define DW_OP_const2s 0x0b -#define DW_OP_const4u 0x0c -#define DW_OP_const4s 0x0d -#define DW_OP_const8u 0x0e -#define DW_OP_const8s 0x0f -#define DW_OP_constu 0x10 -#define DW_OP_consts 0x11 -#define DW_OP_dup 0x12 -#define DW_OP_drop 0x13 -#define DW_OP_over 0x14 -#define DW_OP_pick 0x15 -#define DW_OP_swap 0x16 -#define DW_OP_rot 0x17 -#define DW_OP_xderef 0x18 -#define DW_OP_abs 0x19 -#define DW_OP_and 0x1a -#define DW_OP_div 0x1b -#define DW_OP_minus 0x1c -#define DW_OP_mod 0x1d -#define DW_OP_mul 0x1e -#define DW_OP_neg 0x1f -#define DW_OP_not 0x20 -#define DW_OP_or 0x21 -#define DW_OP_plus 0x22 -#define DW_OP_plus_uconst 0x23 -#define DW_OP_shl 0x24 -#define DW_OP_shr 0x25 -#define DW_OP_shra 0x26 -#define DW_OP_xor 0x27 -#define DW_OP_bra 0x28 -#define DW_OP_eq 0x29 -#define DW_OP_ge 0x2a -#define DW_OP_gt 0x2b -#define DW_OP_le 0x2c -#define DW_OP_lt 0x2d -#define DW_OP_ne 0x2e -#define DW_OP_skip 0x2f -#define DW_OP_lit0 0x30 -#define DW_OP_lit1 0x31 -#define DW_OP_lit2 0x32 -#define DW_OP_lit3 0x33 -#define DW_OP_lit4 0x34 -#define DW_OP_lit5 0x35 -#define DW_OP_lit6 0x36 -#define DW_OP_lit7 0x37 -#define DW_OP_lit8 0x38 -#define DW_OP_lit9 0x39 -#define DW_OP_lit10 0x3a -#define DW_OP_lit11 0x3b -#define DW_OP_lit12 0x3c -#define DW_OP_lit13 0x3d -#define DW_OP_lit14 0x3e -#define DW_OP_lit15 0x3f -#define DW_OP_lit16 0x40 -#define DW_OP_lit17 0x41 -#define DW_OP_lit18 0x42 -#define DW_OP_lit19 0x43 -#define DW_OP_lit20 0x44 -#define DW_OP_lit21 0x45 -#define DW_OP_lit22 0x46 -#define DW_OP_lit23 0x47 -#define DW_OP_lit24 0x48 -#define DW_OP_lit25 0x49 -#define DW_OP_lit26 0x4a -#define DW_OP_lit27 0x4b -#define DW_OP_lit28 0x4c -#define DW_OP_lit29 0x4d -#define DW_OP_lit30 0x4e -#define DW_OP_lit31 0x4f -#define DW_OP_reg0 0x50 -#define DW_OP_reg1 0x51 -#define DW_OP_reg2 0x52 -#define DW_OP_reg3 0x53 -#define DW_OP_reg4 0x54 -#define DW_OP_reg5 0x55 -#define DW_OP_reg6 0x56 -#define DW_OP_reg7 0x57 -#define DW_OP_reg8 0x58 -#define DW_OP_reg9 0x59 -#define DW_OP_reg10 0x5a -#define DW_OP_reg11 0x5b -#define DW_OP_reg12 0x5c -#define DW_OP_reg13 0x5d -#define DW_OP_reg14 0x5e -#define DW_OP_reg15 0x5f -#define DW_OP_reg16 0x60 -#define DW_OP_reg17 0x61 -#define DW_OP_reg18 0x62 -#define DW_OP_reg19 0x63 -#define DW_OP_reg20 0x64 -#define DW_OP_reg21 0x65 -#define DW_OP_reg22 0x66 -#define DW_OP_reg23 0x67 -#define DW_OP_reg24 0x68 -#define DW_OP_reg25 0x69 -#define DW_OP_reg26 0x6a -#define DW_OP_reg27 0x6b -#define DW_OP_reg28 0x6c -#define DW_OP_reg29 0x6d -#define DW_OP_reg30 0x6e -#define DW_OP_reg31 0x6f -#define DW_OP_breg0 0x70 -#define DW_OP_breg1 0x71 -#define DW_OP_breg2 0x72 -#define DW_OP_breg3 0x73 -#define DW_OP_breg4 0x74 -#define DW_OP_breg5 0x75 -#define DW_OP_breg6 0x76 -#define DW_OP_breg7 0x77 -#define DW_OP_breg8 0x78 -#define DW_OP_breg9 0x79 -#define DW_OP_breg10 0x7a -#define DW_OP_breg11 0x7b -#define DW_OP_breg12 0x7c -#define DW_OP_breg13 0x7d -#define DW_OP_breg14 0x7e -#define DW_OP_breg15 0x7f -#define DW_OP_breg16 0x80 -#define DW_OP_breg17 0x81 -#define DW_OP_breg18 0x82 -#define DW_OP_breg19 0x83 -#define DW_OP_breg20 0x84 -#define DW_OP_breg21 0x85 -#define DW_OP_breg22 0x86 -#define DW_OP_breg23 0x87 -#define DW_OP_breg24 0x88 -#define DW_OP_breg25 0x89 -#define DW_OP_breg26 0x8a -#define DW_OP_breg27 0x8b -#define DW_OP_breg28 0x8c -#define DW_OP_breg29 0x8d -#define DW_OP_breg30 0x8e -#define DW_OP_breg31 0x8f -#define DW_OP_regx 0x90 -#define DW_OP_fbreg 0x91 -#define DW_OP_bregx 0x92 -#define DW_OP_piece 0x93 -#define DW_OP_deref_size 0x94 -#define DW_OP_xderef_size 0x95 -#define DW_OP_nop 0x96 -#define DW_OP_push_object_address 0x97 -#define DW_OP_call2 0x98 -#define DW_OP_call4 0x99 -#define DW_OP_call_ref 0x9a -#define DW_OP_form_tls_address 0x9b -#define DW_OP_call_frame_cfa 0x9c -#define DW_OP_bit_piece 0x9d -#define DW_OP_implicit_value 0x9e -#define DW_OP_stack_value 0x9f -#define DW_OP_GNU_push_tls_address 0xe0 -#define DW_OP_GNU_uninit 0xf0 -#define DW_OP_GNU_encoded_addr 0xf1 -#define DW_OP_GNU_implicit_pointer 0xf2 -#define DW_OP_GNU_entry_value 0xf3 -#define DW_OP_GNU_const_type 0xf4 -#define DW_OP_GNU_regval_type 0xf5 -#define DW_OP_GNU_deref_type 0xf6 -#define DW_OP_GNU_convert 0xf7 -#define DW_OP_GNU_reinterpret 0xf9 -#define DW_OP_GNU_parameter_ref 0xfa -#define DW_OP_lo_user 0xe0 -#define DW_OP_hi_user 0xff - -#define DW_ATE_void 0x0 -#define DW_ATE_address 0x1 -#define DW_ATE_boolean 0x2 -#define DW_ATE_complex_float 0x3 -#define DW_ATE_float 0x4 -#define DW_ATE_signed 0x5 -#define DW_ATE_signed_char 0x6 -#define DW_ATE_unsigned 0x7 -#define DW_ATE_unsigned_char 0x8 -#define DW_ATE_imaginary_float 0x9 -#define DW_ATE_packed_decimal 0xa -#define DW_ATE_numeric_string 0xb -#define DW_ATE_edited 0xc -#define DW_ATE_signed_fixed 0xd -#define DW_ATE_unsigned_fixed 0xe -#define DW_ATE_decimal_float 0xf -#define DW_ATE_lo_user 0x80 -#define DW_ATE_hi_user 0xff - -#define DW_ORD_row_major 0x0 -#define DW_ORD_col_major 0x1 - -#define DW_ACCESS_public 0x1 -#define DW_ACCESS_protected 0x2 -#define DW_ACCESS_private 0x3 - -#define DW_VIS_local 0x1 -#define DW_VIS_exported 0x2 -#define DW_VIS_qualified 0x3 - -#define DW_VIRTUALITY_none 0x0 -#define DW_VIRTUALITY_virtual 0x1 -#define DW_VIRTUALITY_pure_virtual 0x2 - -#define DW_ID_case_sensitive 0x0 -#define DW_ID_up_case 0x1 -#define DW_ID_down_case 0x2 -#define DW_ID_case_insensitive 0x3 - -#define DW_CC_normal 0x1 -#define DW_CC_program 0x2 -#define DW_CC_nocall 0x3 -#define DW_CC_lo_user 0x40 -#define DW_CC_hi_user 0xff - -#define DW_INL_not_inlined 0x0 -#define DW_INL_inlined 0x1 -#define DW_INL_declared_not_inlined 0x2 -#define DW_INL_declared_inlined 0x3 - -#define DW_DSC_label 0x0 -#define DW_DSC_range 0x1 - -#define DW_LNS_extended_op 0x0 -#define DW_LNS_copy 0x1 -#define DW_LNS_advance_pc 0x2 -#define DW_LNS_advance_line 0x3 -#define DW_LNS_set_file 0x4 -#define DW_LNS_set_column 0x5 -#define DW_LNS_negate_stmt 0x6 -#define DW_LNS_set_basic_block 0x7 -#define DW_LNS_const_add_pc 0x8 -#define DW_LNS_fixed_advance_pc 0x9 -#define DW_LNS_set_prologue_end 0xa -#define DW_LNS_set_epilogue_begin 0xb -#define DW_LNS_set_isa 0xc - -#define DW_LNE_end_sequence 0x1 -#define DW_LNE_set_address 0x2 -#define DW_LNE_define_file 0x3 -#define DW_LNE_set_discriminator 0x4 - -#define DW_CFA_advance_loc 0x40 -#define DW_CFA_offset 0x80 -#define DW_CFA_restore 0xc0 -#define DW_CFA_nop 0x00 -#define DW_CFA_set_loc 0x01 -#define DW_CFA_advance_loc1 0x02 -#define DW_CFA_advance_loc2 0x03 -#define DW_CFA_advance_loc4 0x04 -#define DW_CFA_offset_extended 0x05 -#define DW_CFA_restore_extended 0x06 -#define DW_CFA_undefined 0x07 -#define DW_CFA_same_value 0x08 -#define DW_CFA_register 0x09 -#define DW_CFA_remember_state 0x0a -#define DW_CFA_restore_state 0x0b -#define DW_CFA_def_cfa 0x0c -#define DW_CFA_def_cfa_register 0x0d -#define DW_CFA_def_cfa_offset 0x0e -#define DW_CFA_def_cfa_expression 0x0f -#define DW_CFA_expression 0x10 -#define DW_CFA_offset_extended_sf 0x11 -#define DW_CFA_def_cfa_sf 0x12 -#define DW_CFA_def_cfa_offset_sf 0x13 -#define DW_CFA_val_offset 0x14 -#define DW_CFA_val_offset_sf 0x15 -#define DW_CFA_val_expression 0x16 -#define DW_CFA_MIPS_advance_loc8 0x1d -#define DW_CFA_GNU_window_save 0x2d -#define DW_CFA_GNU_args_size 0x2e -#define DW_CFA_GNU_negative_offset_extended 0x2f - -#define DW_CIE_ID 0xffffffff -#define DW_CIE_VERSION 1 - -#define DW_CFA_extended 0 -#define DW_CFA_low_user 0x1c -#define DW_CFA_high_user 0x3f - -#define DW_CHILDREN_no 0x00 -#define DW_CHILDREN_yes 0x01 - -#define DW_ADDR_none 0 - -#define DW_LANG_C89 0x0001 -#define DW_LANG_C 0x0002 -#define DW_LANG_Ada83 0x0003 -#define DW_LANG_C_plus_plus 0x0004 -#define DW_LANG_Cobol74 0x0005 -#define DW_LANG_Cobol85 0x0006 -#define DW_LANG_Fortran77 0x0007 -#define DW_LANG_Fortran90 0x0008 -#define DW_LANG_Pascal83 0x0009 -#define DW_LANG_Modula2 0x000a -#define DW_LANG_Java 0x000b -#define DW_LANG_C99 0x000c -#define DW_LANG_Ada95 0x000d -#define DW_LANG_Fortran95 0x000e -#define DW_LANG_PLI 0x000f -#define DW_LANG_ObjC 0x0010 -#define DW_LANG_ObjC_plus_plus 0x0011 -#define DW_LANG_UPC 0x0012 -#define DW_LANG_D 0x0013 -#define DW_LANG_Python 0x0014 -#define DW_LANG_Mips_Assembler 0x8001 -#define DW_LANG_lo_user 0x8000 -#define DW_LANG_hi_user 0xffff - -#define DW_MACINFO_define 1 -#define DW_MACINFO_undef 2 -#define DW_MACINFO_start_file 3 -#define DW_MACINFO_end_file 4 -#define DW_MACINFO_vendor_ext 255 diff --git a/trunk/src/elf.h b/trunk/src/elf.h deleted file mode 100644 index fbadda4..0000000 --- a/trunk/src/elf.h +++ /dev/null @@ -1,3562 +0,0 @@ -/* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _ELF_H -#define _ELF_H 1 - -#include <features.h> - -__BEGIN_DECLS - -/* Standard ELF types. */ - -#include <stdint.h> - -/* Type for a 16-bit quantity. */ -typedef uint16_t Elf32_Half; -typedef uint16_t Elf64_Half; - -/* Types for signed and unsigned 32-bit quantities. */ -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; - -/* Types for signed and unsigned 64-bit quantities. */ -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -/* Type of addresses. */ -typedef uint32_t Elf32_Addr; -typedef uint64_t Elf64_Addr; - -/* Type of file offsets. */ -typedef uint32_t Elf32_Off; -typedef uint64_t Elf64_Off; - -/* Type for section indices, which are 16-bit quantities. */ -typedef uint16_t Elf32_Section; -typedef uint16_t Elf64_Section; - -/* Type for version symbol information. */ -typedef Elf32_Half Elf32_Versym; -typedef Elf64_Half Elf64_Versym; - - -/* The ELF file header. This appears at the start of every ELF file. */ - -#define EI_NIDENT (16) - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Architecture */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size in bytes */ - Elf64_Half e_phentsize; /* Program header table entry size */ - Elf64_Half e_phnum; /* Program header table entry count */ - Elf64_Half e_shentsize; /* Section header table entry size */ - Elf64_Half e_shnum; /* Section header table entry count */ - Elf64_Half e_shstrndx; /* Section header string table index */ -} Elf64_Ehdr; - -/* Fields in the e_ident array. The EI_* macros are indices into the - array. The macros under each EI_* macro are the values the byte - may have. */ - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -/* Conglomeration of the identification bytes, for easy testing as a word. */ -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define ELFCLASSNUM 3 - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATANONE 0 /* Invalid data encoding */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ -#define ELFDATANUM 3 - -#define EI_VERSION 6 /* File version byte index */ - /* Value must be EV_CURRENT */ - -#define EI_OSABI 7 /* OS ABI identification */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_SYSV 0 /* Alias. */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_NETBSD 2 /* NetBSD. */ -#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -#define ELFOSABI_AIX 7 /* IBM AIX. */ -#define ELFOSABI_IRIX 8 /* SGI Irix. */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define EI_ABIVERSION 8 /* ABI version */ - -#define EI_PAD 9 /* Byte index of padding bytes */ - -/* Legal values for e_type (object file type). */ - -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Relocatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_NUM 5 /* Number of defined types */ -#define ET_LOOS 0xfe00 /* OS-specific range start */ -#define ET_HIOS 0xfeff /* OS-specific range end */ -#define ET_LOPROC 0xff00 /* Processor-specific range start */ -#define ET_HIPROC 0xffff /* Processor-specific range end */ - -/* Legal values for e_machine (architecture). */ - -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ - -#define EM_PARISC 15 /* HPPA */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_S390 22 /* IBM S390 */ - -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH-32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ - -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ -#define EM_AARCH64 183 /* ARM AARCH64 */ -#define EM_TILEPRO 188 /* Tilera TILEPro */ -#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ -#define EM_TILEGX 191 /* Tilera TILE-Gx */ -#define EM_NUM 192 - -/* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the - chances of collision with official or non-GNU unofficial values. */ - -#define EM_ALPHA 0x9026 - -/* Legal values for e_version (version). */ - -#define EV_NONE 0 /* Invalid ELF version */ -#define EV_CURRENT 1 /* Current version */ -#define EV_NUM 2 - -/* Section header. */ - -typedef struct -{ - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ -} Elf32_Shdr; - -typedef struct -{ - Elf64_Word sh_name; /* Section name (string tbl index) */ - Elf64_Word sh_type; /* Section type */ - Elf64_Xword sh_flags; /* Section flags */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Section size in bytes */ - Elf64_Word sh_link; /* Link to another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ -} Elf64_Shdr; - -/* Special section indices. */ - -#define SHN_UNDEF 0 /* Undefined section */ -#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -#define SHN_BEFORE 0xff00 /* Order section before all others - (Solaris). */ -#define SHN_AFTER 0xff01 /* Order section after all others - (Solaris). */ -#define SHN_HIPROC 0xff1f /* End of processor-specific */ -#define SHN_LOOS 0xff20 /* Start of OS-specific */ -#define SHN_HIOS 0xff3f /* End of OS-specific */ -#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -#define SHN_XINDEX 0xffff /* Index is in extra table. */ -#define SHN_HIRESERVE 0xffff /* End of reserved indices */ - -/* Legal values for sh_type (section type). */ - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ - -/* Legal values for sh_flags (section flags). */ - -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MERGE (1 << 4) /* Might be merged */ -#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling - required */ -#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ -#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -#define SHF_ORDERED (1 << 30) /* Special ordering requirement - (Solaris). */ -#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless - referenced or allocated (Solaris).*/ - -/* Section compression header. Used when SHF_COMPRESSED is set. */ - -typedef struct -{ - Elf32_Word ch_type; /* Compression format. */ - Elf32_Word ch_size; /* Uncompressed data size. */ - Elf32_Word ch_addralign; /* Uncompressed data alignment. */ -} Elf32_Chdr; - -typedef struct -{ - Elf64_Word ch_type; /* Compression format. */ - Elf64_Word ch_reserved; - Elf64_Xword ch_size; /* Uncompressed data size. */ - Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ -} Elf64_Chdr; - -/* Legal values for ch_type (compression algorithm). */ -#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ -#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ -#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ -#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ -#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ - -/* Section group handling. */ -#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ - -/* Symbol table entry. */ - -typedef struct -{ - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ -} Elf32_Sym; - -typedef struct -{ - Elf64_Word st_name; /* Symbol name (string tbl index) */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf64_Section st_shndx; /* Section index */ - Elf64_Addr st_value; /* Symbol value */ - Elf64_Xword st_size; /* Symbol size */ -} Elf64_Sym; - -/* The syminfo section if available contains additional information about - every dynamic symbol. */ - -typedef struct -{ - Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf32_Half si_flags; /* Per symbol flags */ -} Elf32_Syminfo; - -typedef struct -{ - Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf64_Half si_flags; /* Per symbol flags */ -} Elf64_Syminfo; - -/* Possible values for si_boundto. */ -#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ - -/* Possible bitmasks for si_flags. */ -#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy - loaded */ -/* Syminfo version values. */ -#define SYMINFO_NONE 0 -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - - -/* How to extract and insert information held in the st_info field. */ - -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) - -/* Legal values for ST_BIND subfield of st_info (symbol binding). */ - -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ -#define STB_LOOS 10 /* Start of OS-specific */ -#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -#define STB_HIOS 12 /* End of OS-specific */ -#define STB_LOPROC 13 /* Start of processor-specific */ -#define STB_HIPROC 15 /* End of processor-specific */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol's name is file name */ -#define STT_COMMON 5 /* Symbol is a common data object */ -#define STT_TLS 6 /* Symbol is thread-local data object*/ -#define STT_NUM 7 /* Number of defined types. */ -#define STT_LOOS 10 /* Start of OS-specific */ -#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -#define STT_HIOS 12 /* End of OS-specific */ -#define STT_LOPROC 13 /* Start of processor-specific */ -#define STT_HIPROC 15 /* End of processor-specific */ - - -/* Symbol table indices are found in the hash buckets and chain table - of a symbol hash table section. This special index value indicates - the end of a chain, meaning no further symbols are found in that bucket. */ - -#define STN_UNDEF 0 /* End of a chain. */ - - -/* How to extract and insert information held in the st_other field. */ - -#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) - -/* For ELF64 the definitions are the same. */ -#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) - -/* Symbol visibility specification encoded in the st_other field. */ -#define STV_DEFAULT 0 /* Default symbol visibility rules */ -#define STV_INTERNAL 1 /* Processor specific hidden class */ -#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -#define STV_PROTECTED 3 /* Not preemptible, not exported */ - - -/* Relocation table entry without addend (in section of type SHT_REL). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ -} Elf32_Rel; - -/* I have seen two different definitions of the Elf64_Rel and - Elf64_Rela structures, so we'll leave them out until Novell (or - whoever) gets their act together. */ -/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; - -/* Relocation table entry with addend (in section of type SHT_RELA). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ - Elf32_Sword r_addend; /* Addend */ -} Elf32_Rela; - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ - Elf64_Sxword r_addend; /* Addend */ -} Elf64_Rela; - -/* How to extract and insert information held in the r_info field. */ - -#define ELF32_R_SYM(val) ((val) >> 8) -#define ELF32_R_TYPE(val) ((val) & 0xff) -#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) - -/* Program segment header. */ - -typedef struct -{ - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -} Elf32_Phdr; - -typedef struct -{ - Elf64_Word p_type; /* Segment type */ - Elf64_Word p_flags; /* Segment flags */ - Elf64_Off p_offset; /* Segment file offset */ - Elf64_Addr p_vaddr; /* Segment virtual address */ - Elf64_Addr p_paddr; /* Segment physical address */ - Elf64_Xword p_filesz; /* Segment size in file */ - Elf64_Xword p_memsz; /* Segment size in memory */ - Elf64_Xword p_align; /* Segment alignment */ -} Elf64_Phdr; - -/* Special value for e_phnum. This indicates that the real number of - program headers is too large to fit into e_phnum. Instead the real - value is in the field sh_info of section 0. */ - -#define PN_XNUM 0xffff - -/* Legal values for p_type (segment type). */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_TLS 7 /* Thread-local storage segment */ -#define PT_NUM 8 /* Number of defined types */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* End of OS-specific */ -#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -#define PT_HIPROC 0x7fffffff /* End of processor-specific */ - -/* Legal values for p_flags (segment flags). */ - -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ -#define PF_MASKOS 0x0ff00000 /* OS-specific */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific */ - -/* Legal values for note segment descriptor types for core files. */ - -#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -#define NT_AUXV 6 /* Contains copy of auxv array */ -#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -#define NT_ASRS 8 /* Contains copy of asrset struct */ -#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -#define NT_PRCRED 14 /* Contains copy of prcred struct */ -#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t, - size might increase */ -#define NT_FILE 0x46494c45 /* Contains information about mapped - files */ -#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ -#define NT_S390_TIMER 0x301 /* s390 timer register */ -#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ -#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ -#define NT_S390_CTRS 0x304 /* s390 control registers */ -#define NT_S390_PREFIX 0x305 /* s390 prefix register */ -#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ -#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ -#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ -#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ -#define NT_ARM_TLS 0x401 /* ARM TLS register */ -#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ -#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ - -/* Legal values for the note segment descriptor types for object files. */ - -#define NT_VERSION 1 /* Contains a version string. */ - - -/* Dynamic section entry. */ - -typedef struct -{ - Elf32_Sword d_tag; /* Dynamic entry type */ - union - { - Elf32_Word d_val; /* Integer value */ - Elf32_Addr d_ptr; /* Address value */ - } d_un; -} Elf32_Dyn; - -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; - -/* Legal values for d_tag (dynamic entry type). */ - -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_NEEDED 1 /* Name of needed library */ -#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -#define DT_PLTGOT 3 /* Processor defined value */ -#define DT_HASH 4 /* Address of symbol hash table */ -#define DT_STRTAB 5 /* Address of string table */ -#define DT_SYMTAB 6 /* Address of symbol table */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -#define DT_STRSZ 10 /* Size of string table */ -#define DT_SYMENT 11 /* Size of one symbol table entry */ -#define DT_INIT 12 /* Address of init function */ -#define DT_FINI 13 /* Address of termination function */ -#define DT_SONAME 14 /* Name of shared object */ -#define DT_RPATH 15 /* Library search path (deprecated) */ -#define DT_SYMBOLIC 16 /* Start symbol search here */ -#define DT_REL 17 /* Address of Rel relocs */ -#define DT_RELSZ 18 /* Total size of Rel relocs */ -#define DT_RELENT 19 /* Size of one Rel reloc */ -#define DT_PLTREL 20 /* Type of reloc in PLT */ -#define DT_DEBUG 21 /* For debugging; unspecified */ -#define DT_TEXTREL 22 /* Reloc might modify .text */ -#define DT_JMPREL 23 /* Address of PLT relocs */ -#define DT_BIND_NOW 24 /* Process relocations of object */ -#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -#define DT_RUNPATH 29 /* Library search path */ -#define DT_FLAGS 30 /* Flags for the object being loaded */ -#define DT_ENCODING 32 /* Start of encoded range */ -#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -#define DT_NUM 34 /* Number used */ -#define DT_LOOS 0x6000000d /* Start of OS-specific */ -#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ - -/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the - Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's - approach. */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -#define DT_CHECKSUM 0x6ffffdf8 -#define DT_PLTPADSZ 0x6ffffdf9 -#define DT_MOVEENT 0x6ffffdfa -#define DT_MOVESZ 0x6ffffdfb -#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting - the following DT_* entry. */ -#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -#define DT_VALRNGHI 0x6ffffdff -#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -#define DT_VALNUM 12 - -/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the - Dyn.d_un.d_ptr field of the Elf*_Dyn structure. - - If any adjustment is made to the ELF object after it has been - built these entries will need to be adjusted. */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -#define DT_TLSDESC_PLT 0x6ffffef6 -#define DT_TLSDESC_GOT 0x6ffffef7 -#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -#define DT_MOVETAB 0x6ffffefe /* Move table. */ -#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -#define DT_ADDRRNGHI 0x6ffffeff -#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -#define DT_ADDRNUM 11 - -/* The versioning entry types. The next are defined as part of the - GNU extension. */ -#define DT_VERSYM 0x6ffffff0 - -#define DT_RELACOUNT 0x6ffffff9 -#define DT_RELCOUNT 0x6ffffffa - -/* These were chosen by Sun. */ -#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -#define DT_VERDEF 0x6ffffffc /* Address of version definition - table */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* Address of table with needed - versions */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define DT_VERSIONTAGNUM 16 - -/* Sun added these machine-independent extensions in the "processor-specific" - range. Be compatible. */ -#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -#define DT_EXTRANUM 3 - -/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ - -/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 - entry in the dynamic section. */ -#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -#define DF_1_TRANS 0x00000200 -#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */ -#define DF_1_IGNMULDEF 0x00040000 -#define DF_1_NOKSYMS 0x00080000 -#define DF_1_NOHDR 0x00100000 -#define DF_1_EDITED 0x00200000 /* Object is modified after built. */ -#define DF_1_NORELOC 0x00400000 -#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ -#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ -#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ - -/* Flags for the feature selection in DT_FEATURE_1. */ -#define DTF_1_PARINIT 0x00000001 -#define DTF_1_CONFEXP 0x00000002 - -/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not - generally available. */ - -/* Version definition sections. */ - -typedef struct -{ - Elf32_Half vd_version; /* Version revision */ - Elf32_Half vd_flags; /* Version information */ - Elf32_Half vd_ndx; /* Version Index */ - Elf32_Half vd_cnt; /* Number of associated aux entries */ - Elf32_Word vd_hash; /* Version name hash value */ - Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf32_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf32_Verdef; - -typedef struct -{ - Elf64_Half vd_version; /* Version revision */ - Elf64_Half vd_flags; /* Version information */ - Elf64_Half vd_ndx; /* Version Index */ - Elf64_Half vd_cnt; /* Number of associated aux entries */ - Elf64_Word vd_hash; /* Version name hash value */ - Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf64_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf64_Verdef; - - -/* Legal values for vd_version (version revision). */ -#define VER_DEF_NONE 0 /* No version */ -#define VER_DEF_CURRENT 1 /* Current version */ -#define VER_DEF_NUM 2 /* Given version number */ - -/* Legal values for vd_flags (version information flags). */ -#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - -/* Versym symbol index values. */ -#define VER_NDX_LOCAL 0 /* Symbol is local. */ -#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ - -/* Auxialiary version information. */ - -typedef struct -{ - Elf32_Word vda_name; /* Version or dependency names */ - Elf32_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf32_Verdaux; - -typedef struct -{ - Elf64_Word vda_name; /* Version or dependency names */ - Elf64_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf64_Verdaux; - - -/* Version dependency section. */ - -typedef struct -{ - Elf32_Half vn_version; /* Version of structure */ - Elf32_Half vn_cnt; /* Number of associated aux entries */ - Elf32_Word vn_file; /* Offset of filename for this - dependency */ - Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf32_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf32_Verneed; - -typedef struct -{ - Elf64_Half vn_version; /* Version of structure */ - Elf64_Half vn_cnt; /* Number of associated aux entries */ - Elf64_Word vn_file; /* Offset of filename for this - dependency */ - Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf64_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf64_Verneed; - - -/* Legal values for vn_version (version revision). */ -#define VER_NEED_NONE 0 /* No version */ -#define VER_NEED_CURRENT 1 /* Current version */ -#define VER_NEED_NUM 2 /* Given version number */ - -/* Auxiliary needed version information. */ - -typedef struct -{ - Elf32_Word vna_hash; /* Hash value of dependency name */ - Elf32_Half vna_flags; /* Dependency specific information */ - Elf32_Half vna_other; /* Unused */ - Elf32_Word vna_name; /* Dependency name string offset */ - Elf32_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf32_Vernaux; - -typedef struct -{ - Elf64_Word vna_hash; /* Hash value of dependency name */ - Elf64_Half vna_flags; /* Dependency specific information */ - Elf64_Half vna_other; /* Unused */ - Elf64_Word vna_name; /* Dependency name string offset */ - Elf64_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf64_Vernaux; - - -/* Legal values for vna_flags. */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - - -/* Auxiliary vector. */ - -/* This vector is normally only used by the program interpreter. The - usual definition in an ABI supplement uses the name auxv_t. The - vector is not usually defined in a standard <elf.h> file, but it - can't hurt. We rename it to avoid conflicts. The sizes of these - types are an arrangement between the exec server and the program - interpreter, so we don't fully specify them here. */ - -typedef struct -{ - uint32_t a_type; /* Entry type */ - union - { - uint32_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf32_auxv_t; - -typedef struct -{ - uint64_t a_type; /* Entry type */ - union - { - uint64_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf64_auxv_t; - -/* Legal values for a_type (entry type). */ - -#define AT_NULL 0 /* End of vector */ -#define AT_IGNORE 1 /* Entry should be ignored */ -#define AT_EXECFD 2 /* File descriptor of program */ -#define AT_PHDR 3 /* Program headers for program */ -#define AT_PHENT 4 /* Size of program header entry */ -#define AT_PHNUM 5 /* Number of program headers */ -#define AT_PAGESZ 6 /* System page size */ -#define AT_BASE 7 /* Base address of interpreter */ -#define AT_FLAGS 8 /* Flags */ -#define AT_ENTRY 9 /* Entry point of program */ -#define AT_NOTELF 10 /* Program is not ELF */ -#define AT_UID 11 /* Real uid */ -#define AT_EUID 12 /* Effective uid */ -#define AT_GID 13 /* Real gid */ -#define AT_EGID 14 /* Effective gid */ -#define AT_CLKTCK 17 /* Frequency of times() */ - -/* Some more special a_type values describing the hardware. */ -#define AT_PLATFORM 15 /* String identifying platform. */ -#define AT_HWCAP 16 /* Machine-dependent hints about - processor capabilities. */ - -/* This entry gives some information about the FPU initialization - performed by the kernel. */ -#define AT_FPUCW 18 /* Used FPU control word. */ - -/* Cache block sizes. */ -#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ - -/* A special ignored value for PPC, used by the kernel to control the - interpretation of the AUXV. Must be > 16. */ -#define AT_IGNOREPPC 22 /* Entry should be ignored. */ - -#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ - -#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ - -#define AT_RANDOM 25 /* Address of 16 random bytes. */ - -#define AT_HWCAP2 26 /* More machine-dependent hints about - processor capabilities. */ - -#define AT_EXECFN 31 /* Filename of executable. */ - -/* Pointer to the global system page used for system calls and other - nice things. */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains - log2 of line size; mask those to get cache size. */ -#define AT_L1I_CACHESHAPE 34 -#define AT_L1D_CACHESHAPE 35 -#define AT_L2_CACHESHAPE 36 -#define AT_L3_CACHESHAPE 37 - -/* Note section contents. Each entry in the note section begins with - a header of a fixed form. */ - -typedef struct -{ - Elf32_Word n_namesz; /* Length of the note's name. */ - Elf32_Word n_descsz; /* Length of the note's descriptor. */ - Elf32_Word n_type; /* Type of the note. */ -} Elf32_Nhdr; - -typedef struct -{ - Elf64_Word n_namesz; /* Length of the note's name. */ - Elf64_Word n_descsz; /* Length of the note's descriptor. */ - Elf64_Word n_type; /* Type of the note. */ -} Elf64_Nhdr; - -/* Known names of notes. */ - -/* Solaris entries in the note section have this name. */ -#define ELF_NOTE_SOLARIS "SUNW Solaris" - -/* Note entries for GNU systems have this name. */ -#define ELF_NOTE_GNU "GNU" - - -/* Defined types of notes for Solaris. */ - -/* Value of descriptor (one word) is desired pagesize for the binary. */ -#define ELF_NOTE_PAGESIZE_HINT 1 - - -/* Defined note types for GNU systems. */ - -/* ABI information. The descriptor consists of words: - word 0: OS descriptor - word 1: major version of the ABI - word 2: minor version of the ABI - word 3: subminor version of the ABI -*/ -#define NT_GNU_ABI_TAG 1 -#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ - -/* Known OSes. These values can appear in word 0 of an - NT_GNU_ABI_TAG note section entry. */ -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 -#define ELF_NOTE_OS_FREEBSD 3 - -/* Synthetic hwcap information. The descriptor begins with two words: - word 0: number of entries - word 1: bitmask of enabled entries - Then follow variable-length entries, one byte followed by a - '\0'-terminated hwcap name string. The byte gives the bit - number to test if enabled, (1U << bit) & bitmask. */ -#define NT_GNU_HWCAP 2 - -/* Build ID bits as generated by ld --build-id. - The descriptor consists of any nonzero number of bytes. */ -#define NT_GNU_BUILD_ID 3 - -/* Version note generated by GNU gold containing a version string. */ -#define NT_GNU_GOLD_VERSION 4 - - -/* Move records. */ -typedef struct -{ - Elf32_Xword m_value; /* Symbol value. */ - Elf32_Word m_info; /* Size and index. */ - Elf32_Word m_poffset; /* Symbol offset. */ - Elf32_Half m_repeat; /* Repeat count. */ - Elf32_Half m_stride; /* Stride info. */ -} Elf32_Move; - -typedef struct -{ - Elf64_Xword m_value; /* Symbol value. */ - Elf64_Xword m_info; /* Size and index. */ - Elf64_Xword m_poffset; /* Symbol offset. */ - Elf64_Half m_repeat; /* Repeat count. */ - Elf64_Half m_stride; /* Stride info. */ -} Elf64_Move; - -/* Macro to construct move records. */ -#define ELF32_M_SYM(info) ((info) >> 8) -#define ELF32_M_SIZE(info) ((unsigned char) (info)) -#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) - -#define ELF64_M_SYM(info) ELF32_M_SYM (info) -#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) - - -/* Motorola 68k specific definitions. */ - -/* Values for Elf32_Ehdr.e_flags. */ -#define EF_CPU32 0x00810000 - -/* m68k relocs. */ - -#define R_68K_NONE 0 /* No reloc */ -#define R_68K_32 1 /* Direct 32 bit */ -#define R_68K_16 2 /* Direct 16 bit */ -#define R_68K_8 3 /* Direct 8 bit */ -#define R_68K_PC32 4 /* PC relative 32 bit */ -#define R_68K_PC16 5 /* PC relative 16 bit */ -#define R_68K_PC8 6 /* PC relative 8 bit */ -#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -#define R_68K_COPY 19 /* Copy symbol at runtime */ -#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -#define R_68K_RELATIVE 22 /* Adjust by program base */ -#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -#define R_68K_TLS_LE32 37 /* 32 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE16 38 /* 16 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE8 39 /* 8 bit offset relative to - static TLS block */ -#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -/* Keep this the last entry. */ -#define R_68K_NUM 43 - -/* Intel 80386 specific definitions. */ - -/* i386 relocs. */ - -#define R_386_NONE 0 /* No reloc */ -#define R_386_32 1 /* Direct 32 bit */ -#define R_386_PC32 2 /* PC relative 32 bit */ -#define R_386_GOT32 3 /* 32 bit GOT entry */ -#define R_386_PLT32 4 /* 32 bit PLT address */ -#define R_386_COPY 5 /* Copy symbol at runtime */ -#define R_386_GLOB_DAT 6 /* Create GOT entry */ -#define R_386_JMP_SLOT 7 /* Create PLT entry */ -#define R_386_RELATIVE 8 /* Adjust by program base */ -#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -#define R_386_32PLT 11 -#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS - block offset */ -#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block - offset */ -#define R_386_TLS_LE 17 /* Offset relative to static TLS - block */ -#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of - general dynamic thread local data */ -#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of - local dynamic thread local data - in LE code */ -#define R_386_16 20 -#define R_386_PC16 21 -#define R_386_8 22 -#define R_386_PC8 23 -#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic - thread local data */ -#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -#define R_386_TLS_GD_CALL 26 /* Relocation for call to - __tls_get_addr() */ -#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic - thread local data in LE code */ -#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -#define R_386_TLS_LDM_CALL 30 /* Relocation for call to - __tls_get_addr() in LDM code */ -#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS - block offset */ -#define R_386_TLS_LE_32 34 /* Negated offset relative to static - TLS block */ -#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -#define R_386_SIZE32 38 /* 32-bit symbol size */ -#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS - descriptor for - relaxation. */ -#define R_386_TLS_DESC 41 /* TLS descriptor containing - pointer to code and to - argument, returning the TLS - offset for the symbol. */ -#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -/* Keep this the last entry. */ -#define R_386_NUM 43 - -/* SUN SPARC specific definitions. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ - -/* Values for Elf64_Ehdr.e_flags. */ - -#define EF_SPARCV9_MM 3 -#define EF_SPARCV9_TSO 0 -#define EF_SPARCV9_PSO 1 -#define EF_SPARCV9_RMO 2 -#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -#define EF_SPARC_EXT_MASK 0xFFFF00 -#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ - -/* SPARC relocs. */ - -#define R_SPARC_NONE 0 /* No reloc */ -#define R_SPARC_8 1 /* Direct 8 bit */ -#define R_SPARC_16 2 /* Direct 16 bit */ -#define R_SPARC_32 3 /* Direct 32 bit */ -#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -#define R_SPARC_HI22 9 /* High 22 bit */ -#define R_SPARC_22 10 /* Direct 22 bit */ -#define R_SPARC_13 11 /* Direct 13 bit */ -#define R_SPARC_LO10 12 /* Truncated 10 bit */ -#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ - -/* Additional Sparc64 relocs. */ - -#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -#define R_SPARC_10 30 /* Direct 10 bit */ -#define R_SPARC_11 31 /* Direct 11 bit */ -#define R_SPARC_64 32 /* Direct 64 bit */ -#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -#define R_SPARC_7 43 /* Direct 7 bit */ -#define R_SPARC_5 44 /* Direct 5 bit */ -#define R_SPARC_6 45 /* Direct 6 bit */ -#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -#define R_SPARC_REGISTER 53 /* Global register usage */ -#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 -#define R_SPARC_GOTDATA_HIX22 80 -#define R_SPARC_GOTDATA_LOX10 81 -#define R_SPARC_GOTDATA_OP_HIX22 82 -#define R_SPARC_GOTDATA_OP_LOX10 83 -#define R_SPARC_GOTDATA_OP 84 -#define R_SPARC_H34 85 -#define R_SPARC_SIZE32 86 -#define R_SPARC_SIZE64 87 -#define R_SPARC_WDISP10 88 -#define R_SPARC_JMP_IREL 248 -#define R_SPARC_IRELATIVE 249 -#define R_SPARC_GNU_VTINHERIT 250 -#define R_SPARC_GNU_VTENTRY 251 -#define R_SPARC_REV32 252 -/* Keep this the last entry. */ -#define R_SPARC_NUM 253 - -/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ - -#define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - -/* MIPS R3000 specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */ -#define EF_MIPS_PIC 2 /* Contains PIC code. */ -#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */ -#define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 -#define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ -#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ -#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ - -/* Legal values for MIPS architecture level. */ - -#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ -#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ -#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */ -#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */ - -/* The following are unofficial names and should not be used. */ - -#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1 -#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2 -#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3 -#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4 -#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5 -#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32 -#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64 - -/* Special section indices. */ - -#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols. */ -#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */ -#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */ -#define SHT_MIPS_MSYM 0x70000001 -#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */ -#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */ -#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */ -#define SHT_MIPS_PACKAGE 0x70000007 -#define SHT_MIPS_PACKSYM 0x70000008 -#define SHT_MIPS_RELD 0x70000009 -#define SHT_MIPS_IFACE 0x7000000b -#define SHT_MIPS_CONTENT 0x7000000c -#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -#define SHT_MIPS_SHDR 0x70000010 -#define SHT_MIPS_FDESC 0x70000011 -#define SHT_MIPS_EXTSYM 0x70000012 -#define SHT_MIPS_DENSE 0x70000013 -#define SHT_MIPS_PDESC 0x70000014 -#define SHT_MIPS_LOCSYM 0x70000015 -#define SHT_MIPS_AUXSYM 0x70000016 -#define SHT_MIPS_OPTSYM 0x70000017 -#define SHT_MIPS_LOCSTR 0x70000018 -#define SHT_MIPS_LINE 0x70000019 -#define SHT_MIPS_RFDESC 0x7000001a -#define SHT_MIPS_DELTASYM 0x7000001b -#define SHT_MIPS_DELTAINST 0x7000001c -#define SHT_MIPS_DELTACLASS 0x7000001d -#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -#define SHT_MIPS_DELTADECL 0x7000001f -#define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -#define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 -#define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 -#define SHT_MIPS_EH_REGION 0x70000027 -#define SHT_MIPS_XLATE_OLD 0x70000028 -#define SHT_MIPS_PDR_EXCEPTION 0x70000029 - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */ -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 -#define SHF_MIPS_STRINGS 0x80000000 -#define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 - - -/* Symbol tables. */ - -/* MIPS specific values for `st_other'. */ -#define STO_MIPS_DEFAULT 0x0 -#define STO_MIPS_INTERNAL 0x1 -#define STO_MIPS_HIDDEN 0x2 -#define STO_MIPS_PROTECTED 0x3 -#define STO_MIPS_PLT 0x8 -#define STO_MIPS_SC_ALIGN_UNUSED 0xff - -/* MIPS specific values for `st_info'. */ -#define STB_MIPS_SPLIT_COMMON 13 - -/* Entries found in sections of type SHT_MIPS_GPTAB. */ - -typedef union -{ - struct - { - Elf32_Word gt_current_g_value; /* -G value used for compilation. */ - Elf32_Word gt_unused; /* Not used. */ - } gt_header; /* First entry in section. */ - struct - { - Elf32_Word gt_g_value; /* If this value were used for -G. */ - Elf32_Word gt_bytes; /* This many bytes would be used. */ - } gt_entry; /* Subsequent entries in section. */ -} Elf32_gptab; - -/* Entry found in sections of type SHT_MIPS_REGINFO. */ - -typedef struct -{ - Elf32_Word ri_gprmask; /* General registers used. */ - Elf32_Word ri_cprmask[4]; /* Coprocessor registers used. */ - Elf32_Sword ri_gp_value; /* $gp register value. */ -} Elf32_RegInfo; - -/* Entries found in sections of type SHT_MIPS_OPTIONS. */ - -typedef struct -{ - unsigned char kind; /* Determines interpretation of the - variable part of descriptor. */ - unsigned char size; /* Size of descriptor, including header. */ - Elf32_Section section; /* Section header index of section affected, - 0 for global options. */ - Elf32_Word info; /* Kind-specific information. */ -} Elf_Options; - -/* Values for `kind' field in Elf_Options. */ - -#define ODK_NULL 0 /* Undefined. */ -#define ODK_REGINFO 1 /* Register usage information. */ -#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -#define ODK_PAD 3 /* Section padding options. */ -#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -#define ODK_FILL 5 /* record the fill value used by the linker. */ -#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ - -/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ - -#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -#define OEX_PRECISEFP OEX_FPDBUG -#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ - -#define OEX_FPU_INVAL 0x10 -#define OEX_FPU_DIV0 0x08 -#define OEX_FPU_OFLO 0x04 -#define OEX_FPU_UFLO 0x02 -#define OEX_FPU_INEX 0x01 - -/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ - -#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ - -#define OPAD_PREFIX 0x1 -#define OPAD_POSTFIX 0x2 -#define OPAD_SYMBOL 0x4 - -/* Entry found in `.options' section. */ - -typedef struct -{ - Elf32_Word hwp_flags1; /* Extra flags. */ - Elf32_Word hwp_flags2; /* Extra flags. */ -} Elf_Options_Hw; - -/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ - -#define OHWA0_R4KEOP_CHECKED 0x00000001 -#define OHWA1_R4KEOP_CLEAN 0x00000002 - -/* MIPS relocs. */ - -#define R_MIPS_NONE 0 /* No reloc */ -#define R_MIPS_16 1 /* Direct 16 bit */ -#define R_MIPS_32 2 /* Direct 32 bit */ -#define R_MIPS_REL32 3 /* PC relative 32 bit */ -#define R_MIPS_26 4 /* Direct 26 bit shifted */ -#define R_MIPS_HI16 5 /* High 16 bit */ -#define R_MIPS_LO16 6 /* Low 16 bit */ -#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -#define R_MIPS_PC16 10 /* PC relative 16 bit */ -#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ - -#define R_MIPS_SHIFT5 16 -#define R_MIPS_SHIFT6 17 -#define R_MIPS_64 18 -#define R_MIPS_GOT_DISP 19 -#define R_MIPS_GOT_PAGE 20 -#define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 -#define R_MIPS_SUB 24 -#define R_MIPS_INSERT_A 25 -#define R_MIPS_INSERT_B 26 -#define R_MIPS_DELETE 27 -#define R_MIPS_HIGHER 28 -#define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 -#define R_MIPS_SCN_DISP 32 -#define R_MIPS_REL16 33 -#define R_MIPS_ADD_IMMEDIATE 34 -#define R_MIPS_PJUMP 35 -#define R_MIPS_RELGOT 36 -#define R_MIPS_JALR 37 -#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -#define R_MIPS_GLOB_DAT 51 -#define R_MIPS_COPY 126 -#define R_MIPS_JUMP_SLOT 127 -/* Keep this the last entry. */ -#define R_MIPS_NUM 128 - -/* Legal values for p_type field of Elf32_Phdr. */ - -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information. */ -#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -#define PT_MIPS_OPTIONS 0x70000002 -#define PT_MIPS_ABIFLAGS 0x70000003 /* FP mode requirement. */ - -/* Special program header types. */ - -#define PF_MIPS_LOCAL 0x10000000 - -/* Legal values for d_tag field of Elf32_Dyn. */ - -#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -#define DT_MIPS_MSYM 0x70000007 -#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in - DT_MIPS_DELTA_CLASS. */ -#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in - DT_MIPS_DELTA_INSTANCE. */ -#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in - DT_MIPS_DELTA_RELOC. */ -#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta - relocations refer to. */ -#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in - DT_MIPS_DELTA_SYM. */ -#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the - class declaration. */ -#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in - DT_MIPS_DELTA_CLASSSYM. */ -#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -#define DT_MIPS_PIXIE_INIT 0x70000023 -#define DT_MIPS_SYMBOL_LIB 0x70000024 -#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve - function stored in GOT. */ -#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added - by rld on dlopen() calls. */ -#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -/* The address of .got.plt in an executable using the new non-PIC ABI. */ -#define DT_MIPS_PLTGOT 0x70000032 -/* The base of the PLT in an executable using the new non-PIC ABI if that - PLT is writable. For a non-writable PLT, this is omitted or has a zero - value. */ -#define DT_MIPS_RWPLT 0x70000034 -/* An alternative description of the classic MIPS RLD_MAP that is usable - in a PIE as it stores a relative offset from the address of the tag - rather than an absolute address. */ -#define DT_MIPS_RLD_MAP_REL 0x70000035 -#define DT_MIPS_NUM 0x36 - -/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ - -#define RHF_NONE 0 /* No flags */ -#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -#define RHF_NO_MOVE (1 << 3) -#define RHF_SGI_ONLY (1 << 4) -#define RHF_GUARANTEE_INIT (1 << 5) -#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -#define RHF_GUARANTEE_START_INIT (1 << 7) -#define RHF_PIXIE (1 << 8) -#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -#define RHF_REQUICKSTART (1 << 10) -#define RHF_REQUICKSTARTED (1 << 11) -#define RHF_CORD (1 << 12) -#define RHF_NO_UNRES_UNDEF (1 << 13) -#define RHF_RLD_ORDER_SAFE (1 << 14) - -/* Entries found in sections of type SHT_MIPS_LIBLIST. */ - -typedef struct -{ - Elf32_Word l_name; /* Name (string table index) */ - Elf32_Word l_time_stamp; /* Timestamp */ - Elf32_Word l_checksum; /* Checksum */ - Elf32_Word l_version; /* Interface version */ - Elf32_Word l_flags; /* Flags */ -} Elf32_Lib; - -typedef struct -{ - Elf64_Word l_name; /* Name (string table index) */ - Elf64_Word l_time_stamp; /* Timestamp */ - Elf64_Word l_checksum; /* Checksum */ - Elf64_Word l_version; /* Interface version */ - Elf64_Word l_flags; /* Flags */ -} Elf64_Lib; - - -/* Legal values for l_flags. */ - -#define LL_NONE 0 -#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -#define LL_REQUIRE_MINOR (1 << 2) -#define LL_EXPORTS (1 << 3) -#define LL_DELAY_LOAD (1 << 4) -#define LL_DELTA (1 << 5) - -/* Entries found in sections of type SHT_MIPS_CONFLICT. */ - -typedef Elf32_Addr Elf32_Conflict; - -typedef struct -{ - /* Version of flags structure. */ - Elf32_Half version; - /* The level of the ISA: 1-5, 32, 64. */ - unsigned char isa_level; - /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise. */ - unsigned char isa_rev; - /* The size of general purpose registers. */ - unsigned char gpr_size; - /* The size of co-processor 1 registers. */ - unsigned char cpr1_size; - /* The size of co-processor 2 registers. */ - unsigned char cpr2_size; - /* The floating-point ABI. */ - unsigned char fp_abi; - /* Processor-specific extension. */ - Elf32_Word isa_ext; - /* Mask of ASEs used. */ - Elf32_Word ases; - /* Mask of general flags. */ - Elf32_Word flags1; - Elf32_Word flags2; -} Elf_MIPS_ABIFlags_v0; - -/* Values for the register size bytes of an abi flags structure. */ - -#define MIPS_AFL_REG_NONE 0x00 /* No registers. */ -#define MIPS_AFL_REG_32 0x01 /* 32-bit registers. */ -#define MIPS_AFL_REG_64 0x02 /* 64-bit registers. */ -#define MIPS_AFL_REG_128 0x03 /* 128-bit registers. */ - -/* Masks for the ases word of an ABI flags structure. */ - -#define MIPS_AFL_ASE_DSP 0x00000001 /* DSP ASE. */ -#define MIPS_AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */ -#define MIPS_AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ -#define MIPS_AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ -#define MIPS_AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */ -#define MIPS_AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */ -#define MIPS_AFL_ASE_MT 0x00000040 /* MT ASE. */ -#define MIPS_AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */ -#define MIPS_AFL_ASE_VIRT 0x00000100 /* VZ ASE. */ -#define MIPS_AFL_ASE_MSA 0x00000200 /* MSA ASE. */ -#define MIPS_AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */ -#define MIPS_AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */ -#define MIPS_AFL_ASE_XPA 0x00001000 /* XPA ASE. */ -#define MIPS_AFL_ASE_MASK 0x00001fff /* All ASEs. */ - -/* Values for the isa_ext word of an ABI flags structure. */ - -#define MIPS_AFL_EXT_XLR 1 /* RMI Xlr instruction. */ -#define MIPS_AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */ -#define MIPS_AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */ -#define MIPS_AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */ -#define MIPS_AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */ -#define MIPS_AFL_EXT_5900 6 /* MIPS R5900 instruction. */ -#define MIPS_AFL_EXT_4650 7 /* MIPS R4650 instruction. */ -#define MIPS_AFL_EXT_4010 8 /* LSI R4010 instruction. */ -#define MIPS_AFL_EXT_4100 9 /* NEC VR4100 instruction. */ -#define MIPS_AFL_EXT_3900 10 /* Toshiba R3900 instruction. */ -#define MIPS_AFL_EXT_10000 11 /* MIPS R10000 instruction. */ -#define MIPS_AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */ -#define MIPS_AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */ -#define MIPS_AFL_EXT_4120 14 /* NEC VR4120 instruction. */ -#define MIPS_AFL_EXT_5400 15 /* NEC VR5400 instruction. */ -#define MIPS_AFL_EXT_5500 16 /* NEC VR5500 instruction. */ -#define MIPS_AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */ -#define MIPS_AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */ - -/* Masks for the flags1 word of an ABI flags structure. */ -#define MIPS_AFL_FLAGS1_ODDSPREG 1 /* Uses odd single-precision registers. */ - -/* Object attribute values. */ -enum -{ - /* Not tagged or not using any ABIs affected by the differences. */ - Val_GNU_MIPS_ABI_FP_ANY = 0, - /* Using hard-float -mdouble-float. */ - Val_GNU_MIPS_ABI_FP_DOUBLE = 1, - /* Using hard-float -msingle-float. */ - Val_GNU_MIPS_ABI_FP_SINGLE = 2, - /* Using soft-float. */ - Val_GNU_MIPS_ABI_FP_SOFT = 3, - /* Using -mips32r2 -mfp64. */ - Val_GNU_MIPS_ABI_FP_OLD_64 = 4, - /* Using -mfpxx. */ - Val_GNU_MIPS_ABI_FP_XX = 5, - /* Using -mips32r2 -mfp64. */ - Val_GNU_MIPS_ABI_FP_64 = 6, - /* Using -mips32r2 -mfp64 -mno-odd-spreg. */ - Val_GNU_MIPS_ABI_FP_64A = 7, - /* Maximum allocated FP ABI value. */ - Val_GNU_MIPS_ABI_FP_MAX = 7 -}; - -/* HPPA specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch - prediction. */ -#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ - -/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ - -#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ - -/* Additional section indeces. */ - -#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared - symbols in ANSI C. */ -#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ - -#define STT_HP_OPAQUE (STT_LOOS + 0x1) -#define STT_HP_STUB (STT_LOOS + 0x2) - -/* HPPA relocs. */ - -#define R_PARISC_NONE 0 /* No reloc. */ -#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LORESERVE 128 -#define R_PARISC_COPY 128 /* Copy relocation. */ -#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_GNU_VTENTRY 232 -#define R_PARISC_GNU_VTINHERIT 233 -#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -#define R_PARISC_HIRESERVE 255 - -/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ - -#define PT_HP_TLS (PT_LOOS + 0x0) -#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -#define PT_HP_PARALLEL (PT_LOOS + 0x10) -#define PT_HP_FASTBIND (PT_LOOS + 0x11) -#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -#define PT_HP_STACK (PT_LOOS + 0x14) - -#define PT_PARISC_ARCHEXT 0x70000000 -#define PT_PARISC_UNWIND 0x70000001 - -/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ - -#define PF_PARISC_SBP 0x08000000 - -#define PF_HP_PAGE_SIZE 0x00100000 -#define PF_HP_FAR_SHARED 0x00200000 -#define PF_HP_NEAR_SHARED 0x00400000 -#define PF_HP_CODE 0x01000000 -#define PF_HP_MODIFY 0x02000000 -#define PF_HP_LAZYSWAP 0x04000000 -#define PF_HP_SBP 0x08000000 - - -/* Alpha specific definitions. */ - -/* Legal values for e_flags field of Elf64_Ehdr. */ - -#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ - -/* Legal values for sh_type field of Elf64_Shdr. */ - -/* These two are primerily concerned with ECOFF debugging info. */ -#define SHT_ALPHA_DEBUG 0x70000001 -#define SHT_ALPHA_REGINFO 0x70000002 - -/* Legal values for sh_flags field of Elf64_Shdr. */ - -#define SHF_ALPHA_GPREL 0x10000000 - -/* Legal values for st_other field of Elf64_Sym. */ -#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ - -/* Alpha relocs. */ - -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -#define R_ALPHA_TLS_GD_HI 28 -#define R_ALPHA_TLSGD 29 -#define R_ALPHA_TLS_LDM 30 -#define R_ALPHA_DTPMOD64 31 -#define R_ALPHA_GOTDTPREL 32 -#define R_ALPHA_DTPREL64 33 -#define R_ALPHA_DTPRELHI 34 -#define R_ALPHA_DTPRELLO 35 -#define R_ALPHA_DTPREL16 36 -#define R_ALPHA_GOTTPREL 37 -#define R_ALPHA_TPREL64 38 -#define R_ALPHA_TPRELHI 39 -#define R_ALPHA_TPRELLO 40 -#define R_ALPHA_TPREL16 41 -/* Keep this the last entry. */ -#define R_ALPHA_NUM 46 - -/* Magic values of the LITUSE relocation addend. */ -#define LITUSE_ALPHA_ADDR 0 -#define LITUSE_ALPHA_BASE 1 -#define LITUSE_ALPHA_BYTOFF 2 -#define LITUSE_ALPHA_JSR 3 -#define LITUSE_ALPHA_TLS_GD 4 -#define LITUSE_ALPHA_TLS_LDM 5 - -/* Legal values for d_tag of Elf64_Dyn. */ -#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -#define DT_ALPHA_NUM 1 - -/* PowerPC specific declarations */ - -/* Values for Elf32/64_Ehdr.e_flags. */ -#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ - -/* Cygnus local bits below */ -#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib - flag */ - -/* PowerPC relocations defined by the ABIs */ -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 /* 32bit absolute address */ -#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define R_PPC_ADDR16 3 /* 16bit absolute address */ -#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 /* PC relative 26 bit */ -#define R_PPC_REL14 11 /* PC relative 16 bit */ -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - -/* PowerPC relocations defined for the TLS access ABI. */ -#define R_PPC_TLS 67 /* none (sym+add)@tls */ -#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */ -#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */ - -/* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ - -/* Diab tool relocations. */ -#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ - -/* GNU extension to support local ifunc. */ -#define R_PPC_IRELATIVE 248 - -/* GNU relocs used in PIC code sequences. */ -#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ -#define R_PPC_TOC16 255 - -/* PowerPC specific values for the Dyn d_tag field. */ -#define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_OPT (DT_LOPROC + 1) -#define DT_PPC_NUM 2 - -/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */ -#define PPC_OPT_TLS 1 - -/* PowerPC64 relocations defined by the ABIs */ -#define R_PPC64_NONE R_PPC_NONE -#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -#define R_PPC64_GOT16 R_PPC_GOT16 -#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -#define R_PPC64_GOT16_HA R_PPC_GOT16_HA - -#define R_PPC64_COPY R_PPC_COPY -#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -#define R_PPC64_RELATIVE R_PPC_RELATIVE - -#define R_PPC64_UADDR32 R_PPC_UADDR32 -#define R_PPC64_UADDR16 R_PPC_UADDR16 -#define R_PPC64_REL32 R_PPC_REL32 -#define R_PPC64_PLT32 R_PPC_PLT32 -#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -#define R_PPC64_PLT16_HA R_PPC_PLT16_HA - -#define R_PPC64_SECTOFF R_PPC_SECTOFF -#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ - -#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ - -/* PowerPC64 relocations defined for the TLS access ABI. */ -#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */ -#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */ -#define R_PPC64_TOCSAVE 109 /* none */ - -/* Added when HA and HI relocs were changed to report overflows. */ -#define R_PPC64_ADDR16_HIGH 110 -#define R_PPC64_ADDR16_HIGHA 111 -#define R_PPC64_TPREL16_HIGH 112 -#define R_PPC64_TPREL16_HIGHA 113 -#define R_PPC64_DTPREL16_HIGH 114 -#define R_PPC64_DTPREL16_HIGHA 115 - -/* GNU extension to support local ifunc. */ -#define R_PPC64_JMP_IREL 247 -#define R_PPC64_IRELATIVE 248 -#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* e_flags bits specifying ABI. - 1 for original function descriptor using ABI, - 2 for revised ABI without function descriptors, - 0 for unspecified or not using any features affected by the differences. */ -#define EF_PPC64_ABI 3 - -/* PowerPC64 specific values for the Dyn d_tag field. */ -#define DT_PPC64_GLINK (DT_LOPROC + 0) -#define DT_PPC64_OPD (DT_LOPROC + 1) -#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -#define DT_PPC64_OPT (DT_LOPROC + 3) -#define DT_PPC64_NUM 4 - -/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ -#define PPC64_OPT_TLS 1 -#define PPC64_OPT_MULTI_TOC 2 - -/* PowerPC64 specific values for the Elf64_Sym st_other field. */ -#define STO_PPC64_LOCAL_BIT 5 -#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) -#define PPC64_LOCAL_ENTRY_OFFSET(other) \ - (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) - - -/* ARM specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 -#define EF_ARM_MAVERICK_FLOAT 0x800 - -#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */ -#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */ - - -/* Other constants defined in the ARM ELF spec. version B-01. */ -/* NB. These conflict with values defined above. */ -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0XFF000000 - -/* Constants defined in AAELF. */ -#define EF_ARM_BE8 0x00800000 -#define EF_ARM_LE8 0x00400000 - -#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -#define EF_ARM_EABI_UNKNOWN 0x00000000 -#define EF_ARM_EABI_VER1 0x01000000 -#define EF_ARM_EABI_VER2 0x02000000 -#define EF_ARM_EABI_VER3 0x03000000 -#define EF_ARM_EABI_VER4 0x04000000 -#define EF_ARM_EABI_VER5 0x05000000 - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - -/* ARM-specific values for sh_flags */ -#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined - in the input to a link step. */ - -/* ARM-specific program header flags */ -#define PF_ARM_SB 0x10000000 /* Segment contains the location - addressed by the static base. */ -#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ - - -/* AArch64 relocs. */ - -#define R_AARCH64_NONE 0 /* No relocation. */ - -/* ILP32 AArch64 relocs. */ -#define R_AARCH64_P32_ABS32 1 /* Direct 32 bit. */ -#define R_AARCH64_P32_COPY 180 /* Copy symbol at runtime. */ -#define R_AARCH64_P32_GLOB_DAT 181 /* Create GOT entry. */ -#define R_AARCH64_P32_JUMP_SLOT 182 /* Create PLT entry. */ -#define R_AARCH64_P32_RELATIVE 183 /* Adjust by program base. */ -#define R_AARCH64_P32_TLS_DTPMOD 184 /* Module number, 32 bit. */ -#define R_AARCH64_P32_TLS_DTPREL 185 /* Module-relative offset, 32 bit. */ -#define R_AARCH64_P32_TLS_TPREL 186 /* TP-relative offset, 32 bit. */ -#define R_AARCH64_P32_TLSDESC 187 /* TLS Descriptor. */ -#define R_AARCH64_P32_IRELATIVE 188 /* STT_GNU_IFUNC relocation. */ - -/* LP64 AArch64 relocs. */ -#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ -#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ -#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ -#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ -#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ -#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ -#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ -#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ -#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ -#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ -#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ -#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ -#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ -#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ -#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ -#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ -#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ -#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ -#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ -#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ -#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ -#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ -#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ -#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ -#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ -#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ -#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ -#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ -#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ -#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ -#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ -#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ -#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ -#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ -#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ -#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ -#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ -#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ -#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ -#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ -#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ -#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ -#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ -#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPMOD 1028 /* Module number, 64 bit. */ -#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset, 64 bit. */ -#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset, 64 bit. */ -#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ -#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ - -/* ARM relocs. */ - -#define R_ARM_NONE 0 /* No reloc */ -#define R_ARM_PC24 1 /* Deprecated PC relative 26 - bit branch. */ -#define R_ARM_ABS32 2 /* Direct 32 bit */ -#define R_ARM_REL32 3 /* PC relative 32 bit */ -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 /* Direct 16 bit */ -#define R_ARM_ABS12 6 /* Direct 12 bit */ -#define R_ARM_THM_ABS5 7 /* Direct & 0x7C (LDR, STR). */ -#define R_ARM_ABS8 8 /* Direct 8 bit */ -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 /* PC relative 24 bit (Thumb32 BL). */ -#define R_ARM_THM_PC8 11 /* PC relative & 0x3FC - (Thumb16 LDR, ADD, ADR). */ -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -#define R_ARM_THM_SWI8 14 /* Reserved. */ -#define R_ARM_XPC25 15 /* Reserved. */ -#define R_ARM_THM_XPC22 16 /* Reserved. */ -#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -#define R_ARM_COPY 20 /* Copy symbol at runtime */ -#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -#define R_ARM_RELATIVE 23 /* Adjust by program base */ -#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -#define R_ARM_PLT32 27 /* Deprecated, 32 bit PLT address. */ -#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */ -#define R_ARM_JUMP24 29 /* PC relative 24 bit - (B, BL<cond>). */ -#define R_ARM_THM_JUMP24 30 /* PC relative 24 bit (Thumb32 B.W). */ -#define R_ARM_BASE_ABS 31 /* Adjust by program base. */ -#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete. */ -#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete. */ -#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete. */ -#define R_ARM_LDR_SBREL_11_0 35 /* Deprecated, prog. base relative. */ -#define R_ARM_ALU_SBREL_19_12 36 /* Deprecated, prog. base relative. */ -#define R_ARM_ALU_SBREL_27_20 37 /* Deprecated, prog. base relative. */ -#define R_ARM_TARGET1 38 -#define R_ARM_SBREL31 39 /* Program base relative. */ -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 /* 32 bit PC relative. */ -#define R_ARM_MOVW_ABS_NC 43 /* Direct 16-bit (MOVW). */ -#define R_ARM_MOVT_ABS 44 /* Direct high 16-bit (MOVT). */ -#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */ -#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */ -#define R_ARM_THM_MOVW_ABS_NC 47 /* Direct 16 bit (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_ABS 48 /* Direct high 16 bit - (Thumb32 MOVT). */ -#define R_ARM_THM_MOVW_PREL_NC 49 /* PC relative 16 bit - (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_PREL 50 /* PC relative high 16 bit - (Thumb32 MOVT). */ -#define R_ARM_THM_JUMP19 51 /* PC relative 20 bit - (Thumb32 B<cond>.W). */ -#define R_ARM_THM_JUMP6 52 /* PC relative X & 0x7E - (Thumb16 CBZ, CBNZ). */ -#define R_ARM_THM_ALU_PREL_11_0 53 /* PC relative 12 bit - (Thumb32 ADR.W). */ -#define R_ARM_THM_PC12 54 /* PC relative 12 bit - (Thumb32 LDR{D,SB,H,SH}). */ -#define R_ARM_ABS32_NOI 55 /* Direct 32-bit. */ -#define R_ARM_REL32_NOI 56 /* PC relative 32-bit. */ -#define R_ARM_ALU_PC_G0_NC 57 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G0 58 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G1_NC 59 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G1 60 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G2 61 /* PC relative (ADD, SUB). */ -#define R_ARM_LDR_PC_G1 62 /* PC relative (LDR,STR,LDRB,STRB). */ -#define R_ARM_LDR_PC_G2 63 /* PC relative (LDR,STR,LDRB,STRB). */ -#define R_ARM_LDRS_PC_G0 64 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDRS_PC_G1 65 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDRS_PC_G2 66 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDC_PC_G0 67 /* PC relative (LDC, STC). */ -#define R_ARM_LDC_PC_G1 68 /* PC relative (LDC, STC). */ -#define R_ARM_LDC_PC_G2 69 /* PC relative (LDC, STC). */ -#define R_ARM_ALU_SB_G0_NC 70 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G0 71 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G1_NC 72 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G1 73 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G2 74 /* Program base relative (ADD,SUB). */ -#define R_ARM_LDR_SB_G0 75 /* Program base relative (LDR, - STR, LDRB, STRB). */ -#define R_ARM_LDR_SB_G1 76 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDR_SB_G2 77 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G0 78 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G1 79 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G2 80 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDC_SB_G0 81 /* Program base relative (LDC,STC). */ -#define R_ARM_LDC_SB_G1 82 /* Program base relative (LDC,STC). */ -#define R_ARM_LDC_SB_G2 83 /* Program base relative (LDC,STC). */ -#define R_ARM_MOVW_BREL_NC 84 /* Program base relative 16 - bit (MOVW). */ -#define R_ARM_MOVT_BREL 85 /* Program base relative high - 16 bit (MOVT). */ -#define R_ARM_MOVW_BREL 86 /* Program base relative 16 - bit (MOVW). */ -#define R_ARM_THM_MOVW_BREL_NC 87 /* Program base relative 16 - bit (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_BREL 88 /* Program base relative high - 16 bit (Thumb32 MOVT). */ -#define R_ARM_THM_MOVW_BREL 89 /* Program base relative 16 - bit (Thumb32 MOVW). */ -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 /* TLS relaxation. */ -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_PLT32_ABS 94 -#define R_ARM_GOT_ABS 95 /* GOT entry. */ -#define R_ARM_GOT_PREL 96 /* PC relative GOT entry. */ -#define R_ARM_GOT_BREL12 97 /* GOT entry relative to GOT - origin (LDR). */ -#define R_ARM_GOTOFF12 98 /* 12 bit, GOT entry relative - to GOT origin (LDR, STR). */ -#define R_ARM_GOTRELAX 99 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 /* PC relative & 0xFFE (Thumb16 B). */ -#define R_ARM_THM_PC9 103 /* PC relative & 0x1FE - (Thumb16 B/B<cond>). */ -#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic - thread local data */ -#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic - thread local data */ -#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS - block */ -#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of - static TLS block offset */ -#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static - TLS block */ -#define R_ARM_TLS_LDO12 109 /* 12 bit relative to TLS - block (LDR, STR). */ -#define R_ARM_TLS_LE12 110 /* 12 bit relative to static - TLS block (LDR, STR). */ -#define R_ARM_TLS_IE12GP 111 /* 12 bit GOT entry relative - to GOT origin (LDR). */ -#define R_ARM_ME_TOO 128 /* Obsolete. */ -#define R_ARM_THM_TLS_DESCSEQ 129 -#define R_ARM_THM_TLS_DESCSEQ16 129 -#define R_ARM_THM_TLS_DESCSEQ32 130 -#define R_ARM_THM_GOT_BREL12 131 /* GOT entry relative to GOT - origin, 12 bit (Thumb32 LDR). */ -#define R_ARM_IRELATIVE 160 -#define R_ARM_RXPC25 249 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS22 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 -/* Keep this the last entry. */ -#define R_ARM_NUM 256 - -/* IA-64 specific declarations. */ - -/* Processor specific flags for the Ehdr e_flags field. */ -#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) - -/* Processor specific flags for the Phdr p_flags field. */ -#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ - -/* Processor specific flags for the Shdr sh_flags field. */ -#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Dyn d_tag field. */ -#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -#define DT_IA_64_NUM 1 - -/* IA-64 relocations. */ -#define R_IA64_NONE 0x00 /* none */ -#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -#define R_IA64_COPY 0x84 /* copy relocation */ -#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ - -/* SH specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_SH_MACH_MASK 0x1f -#define EF_SH_UNKNOWN 0x0 -#define EF_SH1 0x1 -#define EF_SH2 0x2 -#define EF_SH3 0x3 -#define EF_SH_DSP 0x4 -#define EF_SH3_DSP 0x5 -#define EF_SH4AL_DSP 0x6 -#define EF_SH3E 0x8 -#define EF_SH4 0x9 -#define EF_SH2E 0xb -#define EF_SH4A 0xc -#define EF_SH2A 0xd -#define EF_SH4_NOFPU 0x10 -#define EF_SH4A_NOFPU 0x11 -#define EF_SH4_NOMMU_NOFPU 0x12 -#define EF_SH2A_NOFPU 0x13 -#define EF_SH3_NOMMU 0x14 -#define EF_SH2A_SH4_NOFPU 0x15 -#define EF_SH2A_SH3_NOFPU 0x16 -#define EF_SH2A_SH4 0x17 -#define EF_SH2A_SH3E 0x18 - -/* SH relocs. */ -#define R_SH_NONE 0 -#define R_SH_DIR32 1 -#define R_SH_REL32 2 -#define R_SH_DIR8WPN 3 -#define R_SH_IND12W 4 -#define R_SH_DIR8WPL 5 -#define R_SH_DIR8WPZ 6 -#define R_SH_DIR8BP 7 -#define R_SH_DIR8W 8 -#define R_SH_DIR8L 9 -#define R_SH_SWITCH16 25 -#define R_SH_SWITCH32 26 -#define R_SH_USES 27 -#define R_SH_COUNT 28 -#define R_SH_ALIGN 29 -#define R_SH_CODE 30 -#define R_SH_DATA 31 -#define R_SH_LABEL 32 -#define R_SH_SWITCH8 33 -#define R_SH_GNU_VTINHERIT 34 -#define R_SH_GNU_VTENTRY 35 -#define R_SH_TLS_GD_32 144 -#define R_SH_TLS_LD_32 145 -#define R_SH_TLS_LDO_32 146 -#define R_SH_TLS_IE_32 147 -#define R_SH_TLS_LE_32 148 -#define R_SH_TLS_DTPMOD32 149 -#define R_SH_TLS_DTPOFF32 150 -#define R_SH_TLS_TPOFF32 151 -#define R_SH_GOT32 160 -#define R_SH_PLT32 161 -#define R_SH_COPY 162 -#define R_SH_GLOB_DAT 163 -#define R_SH_JMP_SLOT 164 -#define R_SH_RELATIVE 165 -#define R_SH_GOTOFF 166 -#define R_SH_GOTPC 167 -/* Keep this the last entry. */ -#define R_SH_NUM 256 - -/* S/390 specific definitions. */ - -/* Valid values for the e_flags field. */ - -#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ - -/* Additional s390 relocs */ - -#define R_390_NONE 0 /* No reloc. */ -#define R_390_8 1 /* Direct 8 bit. */ -#define R_390_12 2 /* Direct 12 bit. */ -#define R_390_16 3 /* Direct 16 bit. */ -#define R_390_32 4 /* Direct 32 bit. */ -#define R_390_PC32 5 /* PC relative 32 bit. */ -#define R_390_GOT12 6 /* 12 bit GOT offset. */ -#define R_390_GOT32 7 /* 32 bit GOT offset. */ -#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -#define R_390_COPY 9 /* Copy symbol at runtime. */ -#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -#define R_390_RELATIVE 12 /* Adjust by program base. */ -#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -#define R_390_GOT16 15 /* 16 bit GOT offset. */ -#define R_390_PC16 16 /* PC relative 16 bit. */ -#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -#define R_390_64 22 /* Direct 64 bit. */ -#define R_390_PC64 23 /* PC relative 64 bit. */ -#define R_390_GOT64 24 /* 64 bit GOT offset. */ -#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -#define R_390_TLS_GDCALL 38 /* Tag for function call in general - dynamic TLS code. */ -#define R_390_TLS_LDCALL 39 /* Tag for function call in local - dynamic TLS code. */ -#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic - thread local data. */ -#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic - thread local data. */ -#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS - block. */ -#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS - block. */ -#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS - block. */ -#define R_390_20 57 /* Direct 20 bit. */ -#define R_390_GOT20 58 /* 20 bit GOT offset. */ -#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS - block offset. */ -#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -/* Keep this the last entry. */ -#define R_390_NUM 62 - - -/* CRIS relocations. */ -#define R_CRIS_NONE 0 -#define R_CRIS_8 1 -#define R_CRIS_16 2 -#define R_CRIS_32 3 -#define R_CRIS_8_PCREL 4 -#define R_CRIS_16_PCREL 5 -#define R_CRIS_32_PCREL 6 -#define R_CRIS_GNU_VTINHERIT 7 -#define R_CRIS_GNU_VTENTRY 8 -#define R_CRIS_COPY 9 -#define R_CRIS_GLOB_DAT 10 -#define R_CRIS_JUMP_SLOT 11 -#define R_CRIS_RELATIVE 12 -#define R_CRIS_16_GOT 13 -#define R_CRIS_32_GOT 14 -#define R_CRIS_16_GOTPLT 15 -#define R_CRIS_32_GOTPLT 16 -#define R_CRIS_32_GOTREL 17 -#define R_CRIS_32_PLT_GOTREL 18 -#define R_CRIS_32_PLT_PCREL 19 - -#define R_CRIS_NUM 20 - - -/* AMD x86-64 relocations. */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset - to two GOT entries for GD symbol */ -#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset - to two GOT entries for LD symbol */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset - to GOT entry for IE symbol */ -#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -#define R_X86_64_PC64 24 /* PC relative 64 bit */ -#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset - to GOT entry */ -#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset - to PLT entry */ -#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS - descriptor. */ -#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ - -#define R_X86_64_NUM 39 - - -/* AM33 relocations. */ -#define R_MN10300_NONE 0 /* No reloc. */ -#define R_MN10300_32 1 /* Direct 32 bit. */ -#define R_MN10300_16 2 /* Direct 16 bit. */ -#define R_MN10300_8 3 /* Direct 8 bit. */ -#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -#define R_MN10300_24 9 /* Direct 24 bit. */ -#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */ -#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */ -#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */ -#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block - offset. */ -#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block - offset. */ -#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS - block. */ -#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */ -#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */ -#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */ -#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed - by linker relaxation. */ -#define R_MN10300_ALIGN 34 /* Alignment requirement for linker - relaxation. */ -#define R_MN10300_NUM 35 - - -/* M32R relocs. */ -#define R_M32R_NONE 0 /* No reloc. */ -#define R_M32R_16 1 /* Direct 16 bit. */ -#define R_M32R_32 2 /* Direct 32 bit. */ -#define R_M32R_24 3 /* Direct 24 bit. */ -#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -#define R_M32R_LO16 9 /* Low 16 bit. */ -#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -#define R_M32R_GNU_VTINHERIT 11 -#define R_M32R_GNU_VTENTRY 12 -/* M32R relocs use SHT_RELA. */ -#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -#define R_M32R_RELA_GNU_VTINHERIT 43 -#define R_M32R_RELA_GNU_VTENTRY 44 -#define R_M32R_REL32 45 /* PC relative 32 bit. */ - -#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -#define R_M32R_COPY 50 /* Copy symbol at runtime */ -#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -#define R_M32R_RELATIVE 53 /* Adjust by program base */ -#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned - low */ -#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed - low */ -#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to - GOT with unsigned low */ -#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to - GOT with signed low */ -#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to - GOT */ -#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT - with unsigned low */ -#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT - with signed low */ -#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -#define R_M32R_NUM 256 /* Keep this the last entry. */ - -/* MicroBlaze relocations */ -#define R_MICROBLAZE_NONE 0 /* No reloc. */ -#define R_MICROBLAZE_32 1 /* Direct 32 bit. */ -#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */ -#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */ -#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */ -#define R_MICROBLAZE_64 5 /* Direct 64 bit. */ -#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */ -#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */ -#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */ -#define R_MICROBLAZE_64_NONE 9 /* No reloc. */ -#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */ -#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */ -#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */ -#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */ -#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */ -#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */ -#define R_MICROBLAZE_REL 16 /* Adjust by program base. */ -#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */ -#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */ -#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */ -#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */ -#define R_MICROBLAZE_COPY 21 /* Runtime copy. */ -#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */ -#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */ -#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */ -#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */ -#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */ -#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */ -#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */ -#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */ - -/* Legal values for d_tag (dynamic entry type). */ -#define DT_NIOS2_GP 0x70000002 /* Address of _gp. */ - -/* Nios II relocations. */ -#define R_NIOS2_NONE 0 /* No reloc. */ -#define R_NIOS2_S16 1 /* Direct signed 16 bit. */ -#define R_NIOS2_U16 2 /* Direct unsigned 16 bit. */ -#define R_NIOS2_PCREL16 3 /* PC relative 16 bit. */ -#define R_NIOS2_CALL26 4 /* Direct call. */ -#define R_NIOS2_IMM5 5 /* 5 bit constant expression. */ -#define R_NIOS2_CACHE_OPX 6 /* 5 bit expression, shift 22. */ -#define R_NIOS2_IMM6 7 /* 6 bit constant expression. */ -#define R_NIOS2_IMM8 8 /* 8 bit constant expression. */ -#define R_NIOS2_HI16 9 /* High 16 bit. */ -#define R_NIOS2_LO16 10 /* Low 16 bit. */ -#define R_NIOS2_HIADJ16 11 /* High 16 bit, adjusted. */ -#define R_NIOS2_BFD_RELOC_32 12 /* 32 bit symbol value + addend. */ -#define R_NIOS2_BFD_RELOC_16 13 /* 16 bit symbol value + addend. */ -#define R_NIOS2_BFD_RELOC_8 14 /* 8 bit symbol value + addend. */ -#define R_NIOS2_GPREL 15 /* 16 bit GP pointer offset. */ -#define R_NIOS2_GNU_VTINHERIT 16 /* GNU C++ vtable hierarchy. */ -#define R_NIOS2_GNU_VTENTRY 17 /* GNU C++ vtable member usage. */ -#define R_NIOS2_UJMP 18 /* Unconditional branch. */ -#define R_NIOS2_CJMP 19 /* Conditional branch. */ -#define R_NIOS2_CALLR 20 /* Indirect call through register. */ -#define R_NIOS2_ALIGN 21 /* Alignment requirement for - linker relaxation. */ -#define R_NIOS2_GOT16 22 /* 16 bit GOT entry. */ -#define R_NIOS2_CALL16 23 /* 16 bit GOT entry for function. */ -#define R_NIOS2_GOTOFF_LO 24 /* %lo of offset to GOT pointer. */ -#define R_NIOS2_GOTOFF_HA 25 /* %hiadj of offset to GOT pointer. */ -#define R_NIOS2_PCREL_LO 26 /* %lo of PC relative offset. */ -#define R_NIOS2_PCREL_HA 27 /* %hiadj of PC relative offset. */ -#define R_NIOS2_TLS_GD16 28 /* 16 bit GOT offset for TLS GD. */ -#define R_NIOS2_TLS_LDM16 29 /* 16 bit GOT offset for TLS LDM. */ -#define R_NIOS2_TLS_LDO16 30 /* 16 bit module relative offset. */ -#define R_NIOS2_TLS_IE16 31 /* 16 bit GOT offset for TLS IE. */ -#define R_NIOS2_TLS_LE16 32 /* 16 bit LE TP-relative offset. */ -#define R_NIOS2_TLS_DTPMOD 33 /* Module number. */ -#define R_NIOS2_TLS_DTPREL 34 /* Module-relative offset. */ -#define R_NIOS2_TLS_TPREL 35 /* TP-relative offset. */ -#define R_NIOS2_COPY 36 /* Copy symbol at runtime. */ -#define R_NIOS2_GLOB_DAT 37 /* Create GOT entry. */ -#define R_NIOS2_JUMP_SLOT 38 /* Create PLT entry. */ -#define R_NIOS2_RELATIVE 39 /* Adjust by program base. */ -#define R_NIOS2_GOTOFF 40 /* 16 bit offset to GOT pointer. */ -#define R_NIOS2_CALL26_NOAT 41 /* Direct call in .noat section. */ -#define R_NIOS2_GOT_LO 42 /* %lo() of GOT entry. */ -#define R_NIOS2_GOT_HA 43 /* %hiadj() of GOT entry. */ -#define R_NIOS2_CALL_LO 44 /* %lo() of function GOT entry. */ -#define R_NIOS2_CALL_HA 45 /* %hiadj() of function GOT entry. */ - -/* TILEPro relocations. */ -#define R_TILEPRO_NONE 0 /* No reloc */ -#define R_TILEPRO_32 1 /* Direct 32 bit */ -#define R_TILEPRO_16 2 /* Direct 16 bit */ -#define R_TILEPRO_8 3 /* Direct 8 bit */ -#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -#define R_TILEPRO_LO16 7 /* Low 16 bit */ -#define R_TILEPRO_HI16 8 /* High 16 bit */ -#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -#define R_TILEPRO_COPY 10 /* Copy relocation */ -#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -/* Relocs 56-59 are currently not defined. */ -#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ - -#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEPRO_NUM 130 - - -/* TILE-Gx relocations. */ -#define R_TILEGX_NONE 0 /* No reloc */ -#define R_TILEGX_64 1 /* Direct 64 bit */ -#define R_TILEGX_32 2 /* Direct 32 bit */ -#define R_TILEGX_16 3 /* Direct 16 bit */ -#define R_TILEGX_8 4 /* Direct 8 bit */ -#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -#define R_TILEGX_COPY 16 /* Copy relocation */ -#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -/* Relocs 90-91 are currently not defined. */ -#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -/* Relocs 104-105 are currently not defined. */ -#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ - -#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEGX_NUM 130 - - -__END_DECLS - -#endif /* elf.h */ diff --git a/trunk/src/exec.c b/trunk/src/exec.c deleted file mode 100644 index 22870c2..0000000 --- a/trunk/src/exec.c +++ /dev/null @@ -1,1074 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" -#include "space.h" - -int -update_dynamic_tags (DSO *dso, GElf_Shdr *shdr, GElf_Shdr *old_shdr, - struct section_move *move) -{ - int i, j; - - for (i = 1; i < move->new_shnum; ++i) - { - j = move->new_to_old[i]; - if (j == -1) - continue; - if ((dynamic_info_is_set (dso, DT_HASH) - && dso->info[DT_HASH] == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_HASH - && set_dynamic (dso, DT_HASH, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_SYMTAB) - && dso->info[DT_SYMTAB] == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_DYNSYM - && set_dynamic (dso, DT_SYMTAB, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_STRTAB) - && dso->info[DT_STRTAB] == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_STRTAB - && set_dynamic (dso, DT_STRTAB, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_VERDEF_BIT) - && dso->info_DT_VERDEF == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_GNU_verdef - && set_dynamic (dso, DT_VERDEF, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_VERNEED_BIT) - && dso->info_DT_VERNEED == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_GNU_verneed - && set_dynamic (dso, DT_VERNEED, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_VERSYM_BIT) - && dso->info_DT_VERSYM == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_GNU_versym - && set_dynamic (dso, DT_VERSYM, shdr[i].sh_addr, 1)) - || (dynamic_info_is_set (dso, DT_GNU_HASH_BIT) - && dso->info_DT_GNU_HASH == old_shdr[j].sh_addr - && old_shdr[j].sh_type == SHT_GNU_HASH - && set_dynamic (dso, DT_GNU_HASH, shdr[i].sh_addr, 1))) - return 1; - } - - return 0; -} - -int -prelink_exec (struct prelink_info *info) -{ - int i, j, ndeps = info->ent->ndepends + 1; - int dynstrndx, dynstrndxnew, growdynstr = 0, shstrndxnew; - int old_conflict = 0, old_liblist = 0; - int new_conflict = -1, new_liblist = -1; - int new_reloc = -1, new_plt = -1, new_dynstr = -1; - int old_dynbss = -1, old_bss = -1, new_dynbss = -1; - int old_sdynbss = -1, old_sbss = -1, new_sdynbss = -1; - int addcnt, undo, shnum_after_undo; - struct reloc_info rinfo, rinfonew; - DSO *dso = info->dso; - GElf_Ehdr ehdr; - GElf_Phdr phdr[dso->ehdr.e_phnum + 1]; - GElf_Shdr old_shdr[dso->ehdr.e_shnum], new_shdr[dso->ehdr.e_shnum + 20]; - GElf_Shdr shdr_after_undo[dso->ehdr.e_shnum + 20]; - GElf_Shdr *shdr; - Elf32_Lib *liblist = NULL; - struct readonly_adjust adjust; - struct section_move *move = NULL; - - if (prelink_build_conflicts (info)) - return 1; - - if (find_reloc_sections (dso, &rinfo)) - return 1; - - move = init_section_move (dso); - if (move == NULL) - return 1; - - ehdr = dso->ehdr; - memcpy (phdr, dso->phdr, dso->ehdr.e_phnum * sizeof (GElf_Phdr)); - memcpy (old_shdr, dso->shdr, dso->ehdr.e_shnum * sizeof (GElf_Shdr)); - shdr = new_shdr; - memcpy (shdr, dso->shdr, dso->ehdr.e_shnum * sizeof (GElf_Shdr)); - - for (undo = 1; undo < dso->ehdr.e_shnum; ++undo) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[undo].sh_name), - ".gnu.prelink_undo")) - break; - - if (undo < dso->ehdr.e_shnum) - { - Elf_Data *data; - - if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr)) - { -error_out: - free (liblist); - free (move); - return 1; - } - - data = elf_getdata (dso->scn[undo], NULL); - assert (data->d_buf != NULL); - assert (data->d_off == 0); - assert (data->d_size == dso->shdr[undo].sh_size); - dso->undo = *data; - dso->undo.d_buf = malloc (dso->undo.d_size); - if (dso->undo.d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not create .gnu.prelink_undo section", - dso->filename); - goto error_out; - } - memcpy (dso->undo.d_buf, data->d_buf, data->d_size); - ehdr.e_shstrndx = dso->ehdr.e_shstrndx; - } - undo = 0; - - memcpy (shdr_after_undo, shdr, ehdr.e_shnum * sizeof (GElf_Shdr)); - - for (dynstrndx = 1; dynstrndx < dso->ehdr.e_shnum; ++dynstrndx) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[dynstrndx].sh_name), - ".dynstr")) - break; - - if (dynstrndx == dso->ehdr.e_shnum) - { - error (0, 0, "%s: Could not find .dynstr section", dso->filename); - goto error_out; - } - - dynstrndxnew = move->old_to_new[dynstrndx]; - shstrndxnew = move->old_to_new[dso->ehdr.e_shstrndx]; - shnum_after_undo = move->new_shnum; - - if (ndeps > 1) - { - liblist = calloc (ndeps - 1, sizeof (Elf32_Lib)); - if (liblist == NULL) - { - error (0, ENOMEM, "%s: Cannot build .gnu.liblist section", - dso->filename); - goto error_out; - } - } - else - liblist = NULL; - - for (i = 0; i < ndeps - 1; ++i) - { - struct prelink_entry *ent = info->ent->depends[i]; - - liblist[i].l_name = strtabfind (dso, dynstrndx, info->sonames[i + 1]); - if (liblist[i].l_name >= shdr[dynstrndxnew].sh_size) - liblist[i].l_name = 0; - if (liblist[i].l_name == 0) - growdynstr += strlen (info->sonames[i + 1]) + 1; - liblist[i].l_time_stamp = ent->timestamp; - liblist[i].l_checksum = ent->checksum; - } - - if (info->dynbss) - { - old_bss = addr_to_sec (dso, info->dynbss_base); - assert (old_bss != -1); - if (move->old_to_new[old_bss] == -1) - ++old_bss; - assert (move->old_to_new[old_bss] != -1); - assert (shdr[move->old_to_new[old_bss]].sh_addr <= info->dynbss_base); - assert (shdr[move->old_to_new[old_bss]].sh_addr - + shdr[move->old_to_new[old_bss]].sh_size > info->dynbss_base); - } - if (info->sdynbss) - { - old_sbss = addr_to_sec (dso, info->sdynbss_base); - assert (old_sbss != -1); - if (move->old_to_new[old_sbss] == -1) - ++old_sbss; - assert (move->old_to_new[old_sbss] != -1); - assert (shdr[move->old_to_new[old_sbss]].sh_addr <= info->sdynbss_base); - assert (shdr[move->old_to_new[old_sbss]].sh_addr - + shdr[move->old_to_new[old_sbss]].sh_size > info->sdynbss_base); - } - - rinfonew = rinfo; - if (rinfo.first != -1) - { - rinfonew.first = move->old_to_new[rinfo.first]; - rinfonew.last = move->old_to_new[rinfo.last]; - if (shdr[rinfonew.first].sh_type == SHT_REL - && dso->shdr[rinfo.first].sh_type == SHT_RELA) - { - rinfonew.rel_to_rela = 1; - rinfonew.reldyn_rela = 0; - } - } - if (rinfo.plt != -1) - { - rinfonew.plt = move->old_to_new[rinfo.plt]; - if (shdr[rinfonew.plt].sh_type == SHT_REL - && dso->shdr[rinfo.plt].sh_type == SHT_RELA) - { - rinfonew.rel_to_rela_plt = 1; - rinfonew.plt_rela = 0; - } - } - - for (i = 1, j = 1; i < ehdr.e_shnum; ++i) - { - const char *name; - name = strptr (dso, dso->ehdr.e_shstrndx, shdr[i].sh_name); - if (! strcmp (name, ".dynbss")) - old_dynbss = move->new_to_old[j]; - else if (! strcmp (name, ".sdynbss")) - old_sdynbss = move->new_to_old[j]; - else if (! strcmp (name, ".gnu.prelink_undo")) - undo = -1; - if (! strcmp (name, ".gnu.conflict")) - { - old_conflict = move->new_to_old[j]; - remove_section (move, j); - } - else if (! strcmp (name, ".gnu.liblist")) - { - old_liblist = move->new_to_old[j]; - remove_section (move, j); - } - else if (rinfonew.rel_to_rela - && i >= rinfonew.first && i <= rinfonew.last) - remove_section (move, j); - else if (i == rinfonew.plt - && (rinfonew.rel_to_rela || rinfonew.rel_to_rela_plt)) - remove_section (move, j); - else if (i == dynstrndxnew && growdynstr) - remove_section (move, j); - else - shdr[j++] = shdr[i]; - } - assert (j == move->new_shnum); - ehdr.e_shnum = j; - - if (old_sdynbss != -1 && old_dynbss == -1) - { - old_dynbss = old_sdynbss; - old_sdynbss = -1; - } - - GElf_Shdr add[rinfo.last - rinfo.first + 5]; - int old[rinfo.last - rinfo.first + 5]; - int new[rinfo.last - rinfo.first + 5]; - memset (add, 0, sizeof (add)); - memset (old, 0, sizeof (old)); - memset (new, 0, sizeof (new)); - - i = 0; - if (rinfonew.rel_to_rela) - { - add[i] = shdr_after_undo[rinfonew.first]; - add[i].sh_size = shdr_after_undo[rinfonew.last].sh_addr - + shdr_after_undo[rinfonew.last].sh_size - - add[i].sh_addr; - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - add[i].sh_size = add[i].sh_size / 2 * 3; - old[i] = rinfo.first; - new_reloc = i++; - for (j = rinfo.first + 1; j <= rinfo.last; ++j) - { - add[i] = shdr_after_undo[rinfonew.first - rinfo.first + j]; - add[i].sh_size = add[i].sh_size / 2 * 3; - old[i++] = j; - } - if (rinfonew.plt) - { - add[i] = shdr_after_undo[rinfonew.plt]; - if (rinfonew.rel_to_rela_plt) - add[i].sh_size = add[i].sh_size / 2 * 3; - /* Temporarily merge them, so that they are allocated adjacently. */ - add[new_reloc].sh_size += add[i].sh_size; - old[i] = rinfo.plt; - new_plt = i++; - } - } - else if (rinfonew.rel_to_rela_plt) - { - add[i] = shdr_after_undo[rinfonew.plt]; - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - add[i].sh_size = add[i].sh_size / 2 * 3; - old[i] = rinfo.plt; - new_plt = i++; - } - if (growdynstr) - { - add[i] = shdr_after_undo[dynstrndxnew]; - add[i].sh_size += growdynstr; - old[i] = dynstrndx; - new_dynstr = i++; - } - add[i].sh_flags = SHF_ALLOC; - add[i].sh_type = SHT_GNU_LIBLIST; - add[i].sh_size = (ndeps - 1) * sizeof (Elf32_Lib); - add[i].sh_addralign = sizeof (GElf_Word); - add[i].sh_entsize = sizeof (Elf32_Lib); - old[i] = old_liblist; - new_liblist = i++; - if (info->conflict_rela_size) - { - add[i].sh_flags = SHF_ALLOC; - add[i].sh_type = SHT_RELA; - add[i].sh_entsize = gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - add[i].sh_size = info->conflict_rela_size * add[i].sh_entsize; - add[i].sh_addralign = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - old[i] = old_conflict; - new_conflict = i++; - } - addcnt = i; - memset (&adjust, 0, sizeof (adjust)); - adjust.new = new; - adjust.move = move; - - for (i = 0; i < addcnt; ++i) - { - new[i] = find_readonly_space (dso, add + i, &ehdr, phdr, shdr, &adjust); - if (new[i] == 0) - goto error_out; - add_section (move, new[i]); - ++adjust.newcount; - if (old[i]) - { - move->old_to_new[old[i]] = new[i]; - move->new_to_old[new[i]] = old[i]; - } - if (i == new_reloc) - { - int k, l = new[new_reloc]; - - j = rinfo.last - rinfo.first + (new_plt != -1); - shdr[l].sh_size = shdr_after_undo[rinfonew.first].sh_size / 2 * 3; - for (k = 1; k <= j; ++k) - { - insert_readonly_section (&ehdr, shdr, l + k, &adjust); - shdr[l + k] = add[new_reloc + k]; - shdr[l + k].sh_addr = shdr[l + k - 1].sh_addr - + shdr[l + k - 1].sh_size; - shdr[l + k].sh_offset = shdr[l + k - 1].sh_offset - + shdr[l + k - 1].sh_size; - new[++i] = l + k; - add_section (move, l + k); - move->old_to_new[rinfo.first + k] = l + k; - move->new_to_old[l + k] = rinfo.first + k; - ++adjust.newcount; - } - } - } - - if (info->sdynbss) - { - if (old_sdynbss == -1) - { - new_sdynbss = move->old_to_new[old_sbss]; - memmove (&shdr[new_sdynbss + 1], &shdr[new_sdynbss], - (ehdr.e_shnum - new_sdynbss) * sizeof (GElf_Shdr)); - shdr[new_sdynbss].sh_size = 0; - ++ehdr.e_shnum; - add_section (move, new_sdynbss); - for (i = 0; i < addcnt; ++i) - if (new[i] >= new_sdynbss) - ++new[i]; - } - else - new_sdynbss = move->old_to_new[old_sdynbss]; - } - - if (info->dynbss) - { - if (old_dynbss == -1) - { - new_dynbss = move->old_to_new[old_bss]; - memmove (&shdr[new_dynbss + 1], &shdr[new_dynbss], - (ehdr.e_shnum - new_dynbss) * sizeof (GElf_Shdr)); - shdr[new_dynbss].sh_size = 0; - ++ehdr.e_shnum; - add_section (move, new_dynbss); - for (i = 0; i < addcnt; ++i) - if (new[i] >= new_dynbss) - ++new[i]; - } - else - new_dynbss = move->old_to_new[old_dynbss]; - } - - if (undo != -1) - { - undo = move->old_to_new[dso->ehdr.e_shstrndx]; - memmove (&shdr[undo + 1], &shdr[undo], - (ehdr.e_shnum - undo) * sizeof (GElf_Shdr)); - memset (&shdr[undo], 0, sizeof (shdr[undo])); - shdr[undo].sh_type = SHT_PROGBITS; - shdr[undo].sh_addralign = dso->undo.d_align; - ++ehdr.e_shnum; - for (i = 0; i < addcnt; ++i) - if (new[i] >= undo) - ++new[i]; - add_section (move, undo); - } - - i = ehdr.e_shnum; - ehdr.e_shnum = dso->ehdr.e_shnum; - dso->ehdr = ehdr; - memcpy (dso->phdr, phdr, ehdr.e_phnum * sizeof (GElf_Phdr)); - if (reopen_dso (dso, move, NULL)) - goto error_out; - - assert (i == dso->ehdr.e_shnum); - - if (shnum_after_undo != move->new_shnum) - adjust_nonalloc (dso, &dso->ehdr, shdr, 0, - dso->ehdr.e_shoff + 1, - ((long) move->new_shnum - (long) shnum_after_undo) - * gelf_fsize (dso->elf, ELF_T_SHDR, 1, EV_CURRENT)); - - if (shdr_after_undo[shstrndxnew].sh_size - < dso->shdr[dso->ehdr.e_shstrndx].sh_size) - { - Elf_Data *data = elf_getdata (dso->scn[dso->ehdr.e_shstrndx], NULL); - - assert (elf_getdata (dso->scn[dso->ehdr.e_shstrndx], data) == NULL); - assert (data->d_off == 0); - assert (shdr_after_undo[shstrndxnew].sh_size - == shdr[dso->ehdr.e_shstrndx].sh_size); - assert (data->d_size == dso->shdr[dso->ehdr.e_shstrndx].sh_size); - data->d_size = shdr_after_undo[shstrndxnew].sh_size; - } - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (move->new_to_old[i] == -1) - dso->shdr[i] = shdr[i]; - else - { - if (shdr[i].sh_type == SHT_PROGBITS - && dso->shdr[i].sh_type == SHT_NOBITS) - { - Elf_Data *data = elf_getdata (dso->scn[i], NULL); - - assert (data->d_buf == NULL); - data->d_size = shdr[i].sh_size; - if (data->d_size) - { - data->d_buf = calloc (shdr[i].sh_size, 1); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", - dso->filename); - goto error_out; - } - } - data->d_type = ELF_T_BYTE; - } - dso->shdr[i].sh_type = shdr[i].sh_type; - dso->shdr[i].sh_addr = shdr[i].sh_addr; - dso->shdr[i].sh_size = shdr[i].sh_size; - dso->shdr[i].sh_offset = shdr[i].sh_offset; - } - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD) - { - GElf_Addr last_offset = dso->phdr[i].p_offset; - GElf_Addr adj = 0; - int sfirst = 0, slast = 0, last = 0; - - for (j = 1; j < dso->ehdr.e_shnum; ++j) - if ((dso->shdr[j].sh_size > 0 - || j == new_dynbss - || j == new_sdynbss) - && dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr - && dso->shdr[j].sh_addr + dso->shdr[j].sh_size - <= dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - { - if (dso->shdr[j].sh_type != SHT_NOBITS - || (dso->shdr[j].sh_flags & SHF_TLS)) - { - if (sfirst) - { - error (0, 0, "%s: NOBITS section followed by non-NOBITS section in the same segment", - dso->filename); - goto error_out; - } - continue; - } - - if (!sfirst) - sfirst = j; - if (strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[j].sh_name), ".plt") == 0) - slast = j + 1; - else if (j == new_dynbss || j == new_sdynbss) - slast = j; - } - - if (sfirst && slast) - { - for (j = sfirst; j < slast; ++j) - { - Elf_Data *data = elf_getdata (dso->scn[j], NULL); - - assert (data->d_size == dso->shdr[j].sh_size - || j == new_dynbss + 1 - || j == new_sdynbss + 1); - if (data->d_size) - { - data->d_buf = realloc (data->d_buf, data->d_size); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", - dso->filename); - goto error_out; - } - } - memset (data->d_buf, 0, data->d_size); - data->d_type = ELF_T_BYTE; - dso->shdr[j].sh_type = SHT_PROGBITS; - } - - adj = dso->shdr[slast - 1].sh_addr + dso->shdr[slast - 1].sh_size - - dso->phdr[i].p_vaddr; - - if (adj > dso->phdr[i].p_filesz) - { - adj -= dso->phdr[i].p_filesz; - for (j = slast; - j < dso->ehdr.e_shnum - && (dso->shdr[j].sh_flags - & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)); - ++j) - if (dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr - + dso->phdr[i].p_memsz) - adj = (adj + dso->shdr[j].sh_addralign - 1) - & ~(dso->shdr[j].sh_addralign - 1); - - dso->phdr[i].p_filesz += adj; - } - else - adj = 0; - } - - for (j = 1; j < dso->ehdr.e_shnum; ++j) - if ((dso->shdr[j].sh_size > 0 - || j == new_dynbss - || j == new_sdynbss) - && dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr - && dso->shdr[j].sh_addr + dso->shdr[j].sh_size - <= dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - { - last = j; - if (dso->shdr[j].sh_type == SHT_NOBITS) - { - last_offset += dso->shdr[j].sh_addralign - 1; - last_offset &= ~(dso->shdr[j].sh_addralign - 1); - if (last_offset > dso->phdr[i].p_offset - + dso->phdr[i].p_filesz) - last_offset = dso->phdr[i].p_offset - + dso->phdr[i].p_filesz; - dso->shdr[j].sh_offset = last_offset; - } - else if (dso->shdr[j].sh_addr + dso->shdr[j].sh_size - > dso->phdr[i].p_vaddr + dso->phdr[i].p_filesz) - { - error (0, 0, "%s: section spans beyond end of segment", - dso->filename); - goto error_out; - } - else - { - dso->shdr[j].sh_offset - = dso->phdr[i].p_offset + dso->shdr[j].sh_addr - - dso->phdr[i].p_vaddr; - last_offset = dso->shdr[j].sh_offset + dso->shdr[j].sh_size; - } - } - - if (adj) - { - for (j = i + 1; j < dso->ehdr.e_phnum; ++j) - if (dso->phdr[j].p_type == PT_LOAD - && dso->phdr[j].p_vaddr >= dso->shdr[slast - 1].sh_addr) - { - dso->phdr[j].p_vaddr += adj; - dso->phdr[j].p_paddr += adj; - dso->phdr[j].p_offset += adj; - } - - j = last + 1; - while (j < dso->ehdr.e_shnum - && (dso->shdr[j].sh_flags - & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR))) - { - dso->shdr[j].sh_offset += adj; - dso->shdr[j++].sh_addr += adj; - } - - if (adjust_dso_nonalloc (dso, last + 1, - dso->shdr[sfirst].sh_offset, - adj)) - goto error_out; - } - } - - /* Adjust .rel*.dyn (or .rel*.*) if necessary. */ - assert (new_reloc == -1 - || (rinfo.last - rinfo.first - == (move->old_to_new[rinfo.last] - - move->old_to_new[rinfo.first]))); - rinfo.first = move->old_to_new[rinfo.first]; - rinfo.last = move->old_to_new[rinfo.last]; - assert (new_reloc == -1 || rinfo.first == new[new_reloc]); - - if (rinfo.rel_to_rela) - { - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - assert (new_reloc != -1); - for (j = rinfo.first; j <= rinfo.last; ++j) - { - dso->shdr[j].sh_size - = dso->shdr[j].sh_size / 3 * 2; - if (convert_rel_to_rela (dso, j)) - goto error_out; - dso->shdr[j].sh_size = shdr[j].sh_size; - } - } - else if (rinfonew.rel_to_rela) - { - assert (new_reloc != -1); - for (j = rinfo.first; j <= rinfo.last; ++j) - { - dso->shdr[j].sh_entsize - = gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - dso->shdr[j].sh_type = SHT_RELA; - } - } - - /* Adjust .rel*.plt if necessary. */ - rinfo.plt = move->old_to_new[rinfo.plt]; - if (new_plt != -1) - { - assert (rinfo.plt == new[new_plt]); - if (rinfo.rel_to_rela_plt) - { - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - dso->shdr[rinfo.first].sh_size - = dso->shdr[rinfo.first].sh_size / 3 * 2; - if (convert_rel_to_rela (dso, rinfo.plt)) - goto error_out; - dso->shdr[rinfo.plt].sh_size = shdr[rinfo.plt].sh_size; - } - else if (rinfonew.rel_to_rela_plt) - { - dso->shdr[rinfo.plt].sh_entsize - = gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - dso->shdr[rinfo.plt].sh_type = SHT_RELA; - } - } - - /* Add new strings into .dynstr if necessary. */ - if (new_dynstr != -1) - { - Elf_Data *data; - char *ptr; - - i = new[new_dynstr]; - data = elf_getdata (dso->scn[i], NULL); - assert (data->d_off == 0); - data->d_buf = realloc (data->d_buf, dso->shdr[i].sh_size); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not append names needed for .gnu.liblist to .dynstr", - dso->filename); - goto error_out; - } - ptr = data->d_buf + shdr_after_undo[dynstrndxnew].sh_size; - data->d_size = dso->shdr[i].sh_size; - for (j = 0; j < ndeps - 1; ++j) - if (liblist[j].l_name == 0) - { - liblist[j].l_name = ptr - (char *) data->d_buf; - ptr = stpcpy (ptr, info->sonames[j + 1]) + 1; - } - assert (ptr == (char *) data->d_buf + data->d_size); - } - - /* Create or update .sdynbss if necessary. */ - if (new_sdynbss != -1) - { - Elf_Data *data; - - if (old_sdynbss == -1) - { - dso->shdr[new_sdynbss] = dso->shdr[new_sdynbss + 1]; - - dso->shdr[new_sdynbss].sh_name = shstrtabadd (dso, ".sdynbss"); - if (dso->shdr[new_sdynbss].sh_name == 0) - goto error_out; - - dso->shdr[new_sdynbss].sh_size = - info->sdynbss_base + info->sdynbss_size - - dso->shdr[new_sdynbss].sh_addr; - - dso->shdr[new_sdynbss + 1].sh_size - -= dso->shdr[new_sdynbss].sh_size; - dso->shdr[new_sdynbss + 1].sh_addr - += dso->shdr[new_sdynbss].sh_size; - dso->shdr[new_sdynbss + 1].sh_offset - += dso->shdr[new_sdynbss].sh_size; - dso->shdr[new_sdynbss].sh_type = SHT_PROGBITS; - } - else - { - if (dso->shdr[new_sdynbss].sh_type != SHT_PROGBITS - || dso->shdr[new_sdynbss].sh_addr > info->sdynbss_base - || dso->shdr[new_sdynbss].sh_addr - + dso->shdr[new_sdynbss].sh_size - < info->sdynbss_base + info->sdynbss_size) - { - error (0, 0, "%s: Copy relocs don't point into .sdynbss section", - dso->filename); - goto error_out; - } - } - data = elf_getdata (dso->scn[new_sdynbss], NULL); - free (data->d_buf); - data->d_buf = info->sdynbss; - info->sdynbss = NULL; - data->d_off = info->sdynbss_base - dso->shdr[new_sdynbss].sh_addr; - data->d_size = info->sdynbss_size; - data->d_type = ELF_T_BYTE; - if (old_sdynbss == -1) - { - data = elf_getdata (dso->scn[new_sdynbss + 1], NULL); - assert (dso->shdr[new_sdynbss + 1].sh_type != SHT_NOBITS - || data->d_buf == NULL); - if (data->d_size != dso->shdr[new_sdynbss + 1].sh_size) - { - assert (data->d_size == dso->shdr[new_sdynbss].sh_size - + dso->shdr[new_sdynbss + 1].sh_size); - data->d_size -= dso->shdr[new_sdynbss].sh_size; - } - } - } - - /* Create or update .dynbss if necessary. */ - if (new_dynbss != -1) - { - Elf_Data *data; - - if (old_dynbss == -1) - { - GElf_Addr adj; - - dso->shdr[new_dynbss] = dso->shdr[new_dynbss + 1]; - - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[new_dynbss + 1].sh_name), - ".sbss") - && new_sdynbss == -1) - dso->shdr[new_dynbss].sh_name = shstrtabadd (dso, ".sdynbss"); - else - dso->shdr[new_dynbss].sh_name = shstrtabadd (dso, ".dynbss"); - if (dso->shdr[new_dynbss].sh_name == 0) - goto error_out; - - dso->shdr[new_dynbss].sh_size = - info->dynbss_base + info->dynbss_size - - dso->shdr[new_dynbss].sh_addr; - - dso->shdr[new_dynbss + 1].sh_size - -= dso->shdr[new_dynbss].sh_size; - dso->shdr[new_dynbss + 1].sh_addr - += dso->shdr[new_dynbss].sh_size; - dso->shdr[new_dynbss + 1].sh_offset - += dso->shdr[new_dynbss].sh_size; - dso->shdr[new_dynbss].sh_type = SHT_PROGBITS; - - if (dso->shdr[new_dynbss + 1].sh_type == SHT_NOBITS) - { - GElf_Addr last_offset; - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->phdr[i].p_vaddr <= dso->shdr[new_dynbss].sh_addr - && dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz - >= info->dynbss_base + info->dynbss_size) - break; - assert (i < dso->ehdr.e_phnum); - - for (j = new_dynbss - 1; j; --j) - { - if (dso->shdr[j].sh_addr < dso->phdr[i].p_vaddr) - break; - if (dso->shdr[j].sh_type == SHT_NOBITS - && (dso->shdr[j].sh_flags & SHF_TLS) == 0) - { - error (0, 0, "%s: COPY relocs not present at start of first SHT_NOBITS section", - dso->filename); - goto error_out; - } - } - - if (dso->phdr[i].p_filesz - < info->dynbss_base + info->dynbss_size - - dso->phdr[i].p_vaddr) - { - dso->phdr[i].p_filesz = - info->dynbss_base + info->dynbss_size - - dso->phdr[i].p_vaddr; - assert (dso->phdr[i].p_filesz <= dso->phdr[i].p_memsz); - } - - adj = dso->phdr[i].p_offset + dso->shdr[new_dynbss].sh_addr - - dso->phdr[i].p_vaddr - dso->shdr[new_dynbss].sh_offset; - - dso->shdr[new_dynbss].sh_offset += adj; - dso->shdr[new_dynbss + 1].sh_offset += adj; - - adj += dso->shdr[new_dynbss].sh_size; - - for (j = new_dynbss + 2; - j < dso->ehdr.e_shnum - && (dso->shdr[j].sh_flags - & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)); - ++j) - if (dso->shdr[j].sh_addr >= dso->phdr[i].p_vaddr - + dso->phdr[i].p_memsz) - adj = (adj + dso->shdr[j].sh_addralign - 1) - & ~(dso->shdr[j].sh_addralign - 1); - - for (j = i + 1; j < dso->ehdr.e_phnum; ++j) - if (dso->phdr[j].p_type == PT_LOAD - && dso->phdr[j].p_vaddr >= dso->shdr[new_dynbss].sh_addr) - { - dso->phdr[j].p_vaddr += adj; - dso->phdr[j].p_paddr += adj; - dso->phdr[j].p_offset += adj; - } - - last_offset = dso->shdr[new_dynbss + 1].sh_offset; - for (j = new_dynbss + 2; j < dso->ehdr.e_shnum; ++j) - if (dso->shdr[j].sh_type != SHT_NOBITS - || dso->shdr[j].sh_addr < dso->phdr[i].p_vaddr - || dso->shdr[j].sh_addr + dso->shdr[j].sh_size - > dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz) - break; - else - { - last_offset += dso->shdr[j].sh_addralign - 1; - last_offset &= ~(dso->shdr[j].sh_addralign - 1); - if (last_offset > dso->phdr[i].p_offset - + dso->phdr[i].p_filesz) - last_offset = dso->phdr[i].p_offset - + dso->phdr[i].p_filesz; - dso->shdr[j].sh_offset = last_offset; - } - - while (j < dso->ehdr.e_shnum - && (dso->shdr[j].sh_flags - & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR))) - { - dso->shdr[j].sh_offset += adj; - dso->shdr[j++].sh_addr += adj; - } - - if (adjust_dso_nonalloc (dso, new_dynbss + 2, - dso->shdr[new_dynbss].sh_offset, - adj)) - goto error_out; - } - } - else - { - if (dso->shdr[new_dynbss].sh_type != SHT_PROGBITS - || dso->shdr[new_dynbss].sh_addr > info->dynbss_base - || dso->shdr[new_dynbss].sh_addr - + dso->shdr[new_dynbss].sh_size - < info->dynbss_base + info->dynbss_size) - { - error (0, 0, "%s: Copy relocs don't point into .dynbss section", - dso->filename); - goto error_out; - } - } - data = elf_getdata (dso->scn[new_dynbss], NULL); - free (data->d_buf); - data->d_buf = info->dynbss; - info->dynbss = NULL; - data->d_off = info->dynbss_base - dso->shdr[new_dynbss].sh_addr; - data->d_size = info->dynbss_size; - data->d_type = ELF_T_BYTE; - if (old_dynbss == -1) - { - data = elf_getdata (dso->scn[new_dynbss + 1], NULL); - if (dso->shdr[new_dynbss + 1].sh_type == SHT_NOBITS - && data->d_buf != NULL) - { -#ifndef NDEBUG - char *buf_start = data->d_buf; - char *buf_end = buf_start + data->d_size; - - while (buf_start < buf_end) - if (*buf_start++) - break; - assert (buf_start == buf_end); -#endif - free (data->d_buf); - data->d_buf = NULL; - } - if (data->d_size != dso->shdr[new_dynbss + 1].sh_size) - { - assert (data->d_size == dso->shdr[new_dynbss].sh_size - + dso->shdr[new_dynbss + 1].sh_size); - data->d_size -= dso->shdr[new_dynbss].sh_size; - } - } - } - - /* Create the liblist. */ - i = new[new_liblist]; - dso->shdr[i].sh_flags = shdr[i].sh_flags; - dso->shdr[i].sh_addralign = shdr[i].sh_addralign; - dso->shdr[i].sh_entsize = shdr[i].sh_entsize; - dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.liblist"); - if (dso->shdr[i].sh_name == 0) - goto error_out; - else - { - Elf_Data *data; - - dso->shdr[i].sh_link - = new_dynstr != -1 ? new[new_dynstr] : move->old_to_new[dynstrndx]; - data = elf_getdata (dso->scn[i], NULL); - data->d_type = ELF_T_WORD; - data->d_size = (ndeps - 1) * sizeof (Elf32_Lib); - free (data->d_buf); - data->d_buf = liblist; - liblist = NULL; - data->d_off = 0; - data->d_align = sizeof (GElf_Word); - data->d_version = EV_CURRENT; - if (set_dynamic (dso, DT_GNU_LIBLIST, dso->shdr[i].sh_addr, 1)) - goto error_out; - if (set_dynamic (dso, DT_GNU_LIBLISTSZ, dso->shdr[i].sh_size, 1)) - goto error_out; - } - - /* Create the conflict list if necessary. */ - if (new_conflict != -1) - { - Elf_Data *data; - - i = new[new_conflict]; - data = elf_getdata (dso->scn[i], NULL); - data->d_type = ELF_T_RELA; - data->d_size = info->conflict_rela_size - * gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - data->d_off = 0; - data->d_align = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - data->d_version = EV_CURRENT; - if (data->d_size) - { - data->d_buf = realloc (data->d_buf, data->d_size); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not build .gnu.conflict section", - dso->filename); - goto error_out; - } - } - else - { - free (data->d_buf); - data->d_buf = NULL; - } - for (j = 0; j < info->conflict_rela_size; ++j) - gelfx_update_rela (dso->elf, data, j, info->conflict_rela + j); - free (info->conflict_rela); - info->conflict_rela = NULL; - - dso->shdr[i].sh_flags = shdr[i].sh_flags; - dso->shdr[i].sh_addralign = shdr[i].sh_addralign; - dso->shdr[i].sh_entsize = shdr[i].sh_entsize; - for (j = 1; j < dso->ehdr.e_shnum; ++j) - if (dso->shdr[j].sh_type == SHT_DYNSYM) - break; - assert (j < dso->ehdr.e_shnum); - dso->shdr[i].sh_link = j; - dso->shdr[i].sh_name = shstrtabadd (dso, ".gnu.conflict"); - if (dso->shdr[i].sh_name == 0) - goto error_out; - if (set_dynamic (dso, DT_GNU_CONFLICT, dso->shdr[i].sh_addr, 1)) - goto error_out; - if (set_dynamic (dso, DT_GNU_CONFLICTSZ, dso->shdr[i].sh_size, 1)) - goto error_out; - } - - if (undo != -1) - { - Elf_Scn *scn; - Elf_Data *data; - GElf_Addr newoffset; - - dso->shdr[undo].sh_name = shstrtabadd (dso, ".gnu.prelink_undo"); - if (dso->shdr[undo].sh_name == 0) - return 1; - dso->shdr[undo].sh_offset = dso->shdr[undo - 1].sh_offset; - if (dso->shdr[undo - 1].sh_type != SHT_NOBITS) - dso->shdr[undo].sh_offset += dso->shdr[undo - 1].sh_size; - dso->shdr[undo].sh_entsize = 1; - dso->shdr[undo].sh_size = dso->undo.d_size; - newoffset = dso->shdr[undo].sh_offset + dso->undo.d_align - 1; - newoffset &= ~(dso->shdr[undo].sh_addralign - 1); - if (adjust_dso_nonalloc (dso, undo + 1, dso->shdr[undo].sh_offset, - dso->undo.d_size + newoffset - - dso->shdr[undo].sh_offset)) - return 1; - dso->shdr[undo].sh_offset = newoffset; - scn = dso->scn[undo]; - data = elf_getdata (scn, NULL); - assert (data != NULL && elf_getdata (scn, data) == NULL); - free (data->d_buf); - *data = dso->undo; - dso->undo.d_buf = NULL; - } - - recompute_nonalloc_offsets (dso); - - if (update_dynamic_tags (dso, dso->shdr, old_shdr, move)) - goto error_out; - - if (update_dynamic_rel (dso, &rinfo)) - goto error_out; - - free (move); - return 0; -} diff --git a/trunk/src/execle_open.c b/trunk/src/execle_open.c deleted file mode 100644 index 2ee5cbc..0000000 --- a/trunk/src/execle_open.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <errno.h> -#include <error.h> -#include <stdio.h> -#include <sys/wait.h> -#include <unistd.h> - -static pid_t pid; - -int -execve_close (FILE *f) -{ - pid_t p; - int status; - - if (f != NULL) - fclose (f); - while ((p = waitpid (pid, &status, 0)) == -1 && errno == EINTR); - if (p == -1 || ! WIFEXITED (status)) - return -1; - return WEXITSTATUS (status); -} - -FILE * -execve_open (const char *path, char *const argv[], char *const envp[]) -{ - int p[2]; - FILE *f; - - if (pipe (p) < 0) - { - error (0, errno, "Could not run %s", path); - return NULL; - } - - switch (pid = vfork ()) - { - case -1: - error (0, errno, "Could not run %s", path); - return NULL; - case 0: - close (p[0]); - if (p[1] != 1) - { - dup2 (p[1], 1); - close (p[1]); - } - dup2 (1, 2); - execve (path, argv, envp); - error (0, errno, "Could not run %s", path); - _exit (127); - } - - close (p[1]); - - f = fdopen (p[0], "r"); - if (f == NULL) - { - close (p[0]); - execve_close (NULL); - } - - return f; -} diff --git a/trunk/src/execstack.c b/trunk/src/execstack.c deleted file mode 100644 index dda6bc7..0000000 --- a/trunk/src/execstack.c +++ /dev/null @@ -1,483 +0,0 @@ -/* Copyright (C) 2003, 2005, 2010 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2003. - - 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, 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 <config.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/wait.h> - -#include "prelink.h" - -int set; -int execflag; - -const char *argp_program_version = EXECSTACK_PROG PKGVERSION " 1.0"; - -const char *argp_program_bug_address = REPORT_BUGS_TO; - -static char argp_doc[] = EXECSTACK_PROG " -- program to query or set executable stack flag"; - -static struct argp_option options[] = { - {"set-execstack", 's', 0, 0, "Set executable stack flag bit" }, - {"execstack", 's', 0, OPTION_HIDDEN, "" }, - {"clear-execstack", 'c', 0, 0, "Clear executable stack flag bit" }, - {"noexecstack", 'c', 0, OPTION_HIDDEN, "" }, - {"query", 'q', 0, 0, "Query executable stack flag bit" }, - { 0 } -}; - -/* The cached value of argv[0]. */ -const char *program_path; - -/* The full pathname of the prelink tool, or NULL if it hasn't been - computed yet. */ -const char *prelink_path; - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case 's': - set = 1; - execflag = 1; - break; - case 'c': - set = 1; - execflag = 0; - break; - case 'q': - set = 0; - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { options, parse_opt, 0, argp_doc }; - -static int execstack_set (DSO *dso, int flag); - -static void -execstack_fill_phdr (DSO *dso, int i, int flag) -{ - memset (&dso->phdr[i], 0, sizeof (dso->phdr[i])); - dso->phdr[i].p_type = PT_GNU_STACK; - dso->phdr[i].p_flags = PF_W | PF_R | (flag ? PF_X : 0); - dso->phdr[i].p_align = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); -} - -static int -execstack_make_rdwr (DSO *dso, int flag) -{ - int i, fd = -1, status; - pid_t pid; - DSO *ndso = NULL; - char *p = NULL; - char filename[strlen (dso->filename) + sizeof ".#execstack#.XXXXXX"]; - extern char *make_relative_prefix (const char *, const char *, const char *); - char *dirname; - - for (i = 0; i < dso->ehdr.e_shnum; ++i) - { - const char *name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name); - if (strcmp (name, ".gnu.prelink_undo") == 0) - break; - } - - if (i == dso->ehdr.e_shnum) - return reopen_dso (dso, NULL, NULL) ? 1 : -1; - - /* We need to unprelink the file first, so that prelink --undo - or reprelinking it doesn't destroy the PT_GNU_STACK segment - header we've created. */ - sprintf (filename, "%s.#execstack#.XXXXXX", dso->filename); - - fd = wrap_mkstemp (filename); - if (fd == -1) - { - error (0, 0, "%s: Cannot create temporary file", - dso->filename); - goto error_out; - } - - p = strdup (dso->filename); - if (p == NULL) - { - error (0, ENOMEM, "%s: Cannot create temporary file", - dso->filename); - goto error_out; - } - - if (prelink_path == NULL) - { - dirname = make_relative_prefix (program_path, BINDIR, SBINDIR); - asprintf (&prelink_path, "%s/%s", dirname, PRELINK_PROG EXEEXT); - free (dirname); - } - - pid = vfork (); - if (pid == 0) - { - close (fd); - execl (prelink_path, prelink_path, "-u", "-o", filename, - dso->filename, NULL); - _exit (-1); - } - - if (pid < 0) - { - error (0, errno, "%s: Cannot run prelink --undo", - dso->filename); - goto error_out; - } - - if (waitpid (pid, &status, 0) < 0 - || !WIFEXITED (status) - || WEXITSTATUS (status)) - { - error (0, 0, "%s: prelink --undo failed", dso->filename); - goto error_out; - } - - ndso = open_dso (filename); - if (ndso == NULL) - { - error (0, 0, "%s: Couldn't open prelink --undo output", - dso->filename); - goto error_out; - } - - for (i = 0; i < ndso->ehdr.e_shnum; ++i) - { - const char *name = strptr (ndso, ndso->ehdr.e_shstrndx, - ndso->shdr[i].sh_name); - if (strcmp (name, ".gnu.prelink_undo") == 0) - break; - } - - if (i != ndso->ehdr.e_shnum) - { - error (0, 0, "%s: prelink --undo output contains .gnu.prelink_undo section", - dso->filename); - goto error_out; - } - - if (ndso->ehdr.e_type != dso->ehdr.e_type) - { - error (0, 0, "%s: Object type changed during prelink --undo operation", - dso->filename); - } - - if (ndso->filename != ndso->soname) - free ((char *) ndso->filename); - ndso->filename = p; - p = NULL; - - wrap_unlink (filename); - fsync (fd); - close (fd); - fd = -1; - close_dso (dso); - return execstack_set (ndso, flag); - -error_out: - free (p); - if (ndso != NULL) - close_dso (ndso); - if (fd != -1) - { - wrap_unlink (filename); - fsync (fd); - close (fd); - } - close_dso (dso); - return 1; -} - -static int -execstack_set (DSO *dso, int flag) -{ - int i, null = -1, last, ret; - GElf_Addr lowoff = ~(GElf_Addr) 0, start = 0, align = 0; - GElf_Addr adjust; - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_GNU_STACK) - { - /* Found PT_GNU_STACK. Check if we need any change or not. */ - if (flag ^ ((dso->phdr[i].p_flags & PF_X) != 0)) - { - ret = execstack_make_rdwr (dso, flag); - if (ret != -1) - return ret; - dso->phdr[i].p_flags ^= PF_X; - goto out_write; - } - else - goto out_close; - } - else if (dso->phdr[i].p_type == PT_NULL) - null = i; - - if (null != -1) - { - /* Overwrite PT_NULL segment with PT_GNU_STACK. */ - ret = execstack_make_rdwr (dso, flag); - if (ret != -1) - return ret; - execstack_fill_phdr (dso, i, flag); - goto out_write; - } - - if (dso->ehdr.e_shnum == 0) - { - error (0, 0, "%s: Section header table missing", dso->filename); - goto error_out; - } - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - if (lowoff > dso->shdr[i].sh_offset) - { - if (dso->shdr[i].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)) - { - lowoff = dso->shdr[i].sh_offset; - start = dso->shdr[i].sh_addr; - } - else - { - error (0, 0, "%s: Non-alloced sections before alloced ones", - dso->filename); - goto error_out; - } - } - - if (dso->shdr[i].sh_addralign > align) - align = dso->shdr[i].sh_addralign; - } - - if (dso->ehdr.e_phoff >= lowoff) - { - error (0, 0, "%s: Program header table not before all sections", - dso->filename); - goto error_out; - } - - if (dso->ehdr.e_shoff <= lowoff) - { - error (0, 0, "%s: Section header table before first section", - dso->filename); - goto error_out; - } - - if (dso->ehdr.e_phoff + (dso->ehdr.e_phnum + 1) * dso->ehdr.e_phentsize - <= lowoff) - { - /* There is enough space for the headers even without reshuffling - anything. */ - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_PHDR) - { - if (dso->phdr[i].p_filesz - == dso->ehdr.e_phnum * dso->ehdr.e_phentsize) - dso->phdr[i].p_filesz += dso->ehdr.e_phentsize; - if (dso->phdr[i].p_memsz - == dso->ehdr.e_phnum * dso->ehdr.e_phentsize) - dso->phdr[i].p_memsz += dso->ehdr.e_phentsize; - } - i = dso->ehdr.e_phnum++; - ret = execstack_make_rdwr (dso, flag); - if (ret != -1) - return ret; - execstack_fill_phdr (dso, i, flag); - goto out_write; - } - - if (dso->ehdr.e_type != ET_DYN) - { - error (0, 0, "%s: Reshuffling of objects to make room for\n" - "program header entry only supported for shared libraries", - dso->filename); - goto error_out; - } - - adjust = dso->ehdr.e_phoff + (dso->ehdr.e_phnum + 1) * dso->ehdr.e_phentsize - - lowoff; - if (align) - adjust = (adjust + align - 1) & ~(align - 1); - - /* Need to make sure adjust doesn't cause different Phdr segments - to overlap on the same page. */ - last = -1; - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz >= start) - { - if (last != -1 - && (((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - 1) - ^ dso->phdr[i].p_vaddr) - & ~(dso->arch->max_page_size - 1)) - && !(((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - + adjust - 1) - ^ (dso->phdr[i].p_vaddr + adjust)) - & ~(dso->arch->max_page_size - 1))) - { - if (align >= dso->arch->max_page_size) - { - error (0, 0, "%s: Cannot grow reloc sections", dso->filename); - goto error_out; - } - adjust = (adjust + dso->arch->max_page_size - 1) - & ~(dso->arch->max_page_size - 1); - } - last = i; - } - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_PHDR) - { - if (dso->phdr[i].p_filesz == dso->ehdr.e_phnum * dso->ehdr.e_phentsize) - dso->phdr[i].p_filesz += dso->ehdr.e_phentsize; - if (dso->phdr[i].p_memsz == dso->ehdr.e_phnum * dso->ehdr.e_phentsize) - dso->phdr[i].p_memsz += dso->ehdr.e_phentsize; - } - - i = dso->ehdr.e_phnum++; - ret = execstack_make_rdwr (dso, flag); - if (ret != -1) - return ret; - - if (adjust_dso (dso, start, adjust)) - goto error_out; - - execstack_fill_phdr (dso, i, flag); - -out_write: - if (dynamic_info_is_set (dso, DT_CHECKSUM_BIT) - && dso_is_rdwr (dso) - && prelink_set_checksum (dso)) - goto error_out; - - dso->permissive = 1; - - return update_dso (dso, NULL); - -out_close: - close_dso (dso); - return 0; - -error_out: - close_dso (dso); - return 1; -} - -static int -execstack_query (DSO *dso) -{ - int stack = '?', i; - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_GNU_STACK) - { - stack = (dso->phdr[i].p_flags & PF_X) ? 'X' : '-'; - break; - } - printf ("%c %s\n", stack, dso->filename); - close_dso (dso); - return 0; -} - -int -main (int argc, char *argv[]) -{ - int remaining, failures = 0; - - program_path = argv[0]; - - setlocale (LC_ALL, ""); - - argp_parse (&argp, argc, argv, 0, &remaining, 0); - - elf_version (EV_CURRENT); - - if (remaining == argc) - error (EXIT_FAILURE, 0, "no files given"); - - while (remaining < argc) - { - DSO *dso = open_dso (argv[remaining++]); - int ret; - - if (dso == NULL) - { - ++failures; - continue; - } - - if (dso->ehdr.e_type != ET_DYN - && dso->ehdr.e_type != ET_EXEC) - { - ++failures; - error (0, 0, "%s is not a shared library nor executable", dso->filename); - continue; - } - - if (set) - ret = execstack_set (dso, execflag); - else - ret = execstack_query (dso); - - if (ret) - ++failures; - } - - return failures; -} - -/* FIXME: Dummy. When arch dependent files are split into adjust and prelink - parts, this can go away. */ -struct prelink_conflict * -prelink_conflict (struct prelink_info *info, GElf_Word r_sym, int reloc_type) -{ - abort (); -} - -GElf_Rela * -prelink_conflict_add_rela (struct prelink_info *info) -{ - abort (); -} - -ssize_t -send_file (int outfd, int infd, off_t *poff, size_t count) -{ - abort (); -} - -GElf_Addr mmap_reg_start; -GElf_Addr mmap_reg_end; -int exec_shield; diff --git a/trunk/src/fptr.c b/trunk/src/fptr.c deleted file mode 100644 index cfe3aed..0000000 --- a/trunk/src/fptr.c +++ /dev/null @@ -1,465 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2007 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include "fptr.h" - -struct opd_refent; - -struct opd_tabent -{ - struct opd_ent *ent; - struct opd_refent *ref; -}; - -struct opd_refent -{ - GElf_Addr val; - GElf_Addr gp; - struct opd_refent *first; - struct opd_tabent *tabent; - struct opd_refent *next, *nextref; - GElf_Word refcnt; -}; - -struct opd_fptr -{ - /* The first 2 fields have to match opd_refent. */ - GElf_Addr val; - GElf_Addr gp; - struct opd_ent *ent; -}; - -static void -opd_del (void *p) -{ - free (p); -} - -static hashval_t -opd_tabent_hash (const void *p) -{ - struct opd_tabent *e = (struct opd_tabent *)p; - - return e->ent->opd; -} - -static int -opd_tabent_eq (const void *p, const void *q) -{ - struct opd_tabent *e = (struct opd_tabent *)p; - struct opd_tabent *f = (struct opd_tabent *)q; - - return e->ent == f->ent; -} - -static hashval_t -opd_refent_hash (const void *p) -{ - struct opd_refent *e = (struct opd_refent *)p; - - return e->val ^ (e->val >> 31); -} - -static int -opd_refent_eq (const void *p, const void *q) -{ - struct opd_refent *e = (struct opd_refent *)p; - struct opd_refent *f = (struct opd_refent *)q; - - return e->val == f->val && e->gp == f->gp; -} - -static int -opd_gather_refent (void **p, void *info) -{ - struct opd_refent ***ptr = (struct opd_refent ***) info; - struct opd_refent *r = *(struct opd_refent **) p, *t; - - for (t = r; t; t = t->next) - { - *(*ptr)++ = t; - t->first = r; - } - return 1; -} - -static int -opd_refent_cmp (const void *A, const void *B) -{ - struct opd_refent *a = * (struct opd_refent **) A; - struct opd_refent *b = * (struct opd_refent **) B; - - if (a->refcnt > b->refcnt) - return -1; - if (a->refcnt < b->refcnt) - return 1; - return 0; -} - -int -opd_init (struct prelink_info *info) -{ - int i, j, nrefent = 0; - struct opd_lib *l; - struct opd_refent refent, *r, **refarr, **a; - struct opd_tabent tabent, *t; - void **tabslot; - htab_t tabent_htab = NULL, refent_htab = NULL; - - l = calloc (sizeof (struct opd_lib), 1); - if (l == NULL) - goto error_mem; - l->nrefs = (info->symtab_end - info->symtab_start) / info->symtab_entsize; - if (l->nrefs) - { - l->u.refp = calloc (l->nrefs, sizeof (struct opd_ref *)); - if (l->u.refp == NULL) - goto error_mem; - } - else - l->u.refp = NULL; - tabent_htab = htab_try_create (100, opd_tabent_hash, opd_tabent_eq, opd_del); - refent_htab = htab_try_create (100, opd_refent_hash, opd_refent_eq, opd_del); - l->htab = htab_try_create (100, opd_refent_hash, opd_refent_eq, opd_del); - if (tabent_htab == NULL || refent_htab == NULL || l->htab == NULL) - goto error_mem; - - for (i = 0; i < info->ent->ndepends; ++i) - { - struct prelink_entry *ent; - struct prelink_conflict *conflict; - struct opd_lib *ol; - size_t maxidx = 1; - - ent = info->ent->depends[i]; - ol = ent->opd; - if (info->conflicts[i + 1].hash != &info->conflicts[i + 1].first) - maxidx = 251; - for (j = 0; j < ol->nrefs; ++j) - { - GElf_Addr symoff = ol->u.refs[j].symoff; - refent.val = ol->u.refs[j].ent->val; - refent.gp = ol->u.refs[j].ent->gp; - for (conflict = info->conflicts[i + 1].hash[symoff % maxidx]; conflict; - conflict = conflict->next) - { - if (conflict->symoff == symoff - && conflict->reloc_class != RTYPE_CLASS_COPY - && conflict->reloc_class != RTYPE_CLASS_TLS) - break; - } - - if (conflict) - { - if (refent.val - != conflict->conflict.ent->base + conflict->conflictval - || refent.gp != conflict->conflict.ent->pltgot) - { - error (0, 0, "%s: OPD value changed during prelinking", - info->ent->filename); - goto error_out; - } - - refent.val = conflict->lookup.ent->base + conflict->lookupval; - refent.gp = conflict->lookup.ent->pltgot; - } - - if (ol->u.refs[j].ent->opd & OPD_ENT_PLT) - { - struct opd_ent_plt *entp - = (struct opd_ent_plt *) ol->u.refs[j].ent; - int k; - size_t idx = 0; - - for (k = 0; k < info->ent->ndepends; ++k) - if (info->ent->depends[k] == entp->lib) - break; - - assert (k < info->ent->ndepends); - - if (info->conflicts[k + 1].hash != &info->conflicts[k + 1].first) - idx = entp->symoff % 251; - for (conflict = info->conflicts[k + 1].hash[idx]; conflict; - conflict = conflict->next) - { - if (conflict->symoff == entp->symoff - && conflict->reloc_class == RTYPE_CLASS_PLT) - break; - } - - if (conflict) - { - if (ol->u.refs[j].ent->val - != conflict->conflict.ent->base + conflict->conflictval - || ol->u.refs[j].ent->gp - != conflict->conflict.ent->pltgot) - { - error (0, 0, "%s: OPD value changed during prelinking", - info->ent->filename); - goto error_out; - } - - /* FPTR originally pointed into .plt, but since they - now resolve to different values, this cannot be used. */ - if (refent.val - != conflict->lookup.ent->base + conflict->lookupval - || refent.gp != conflict->lookup.ent->pltgot) - continue; - } - else if (refent.val != ol->u.refs[j].ent->val - || refent.gp != ol->u.refs[j].ent->gp) - continue; - } - - tabslot = htab_find_slot (refent_htab, &refent, INSERT); - if (tabslot == NULL) - goto error_mem; - - if (*tabslot != NULL) - { - for (r = (struct opd_refent *) *tabslot; r; r = r->next) - if (r->tabent->ent == ol->u.refs[j].ent) - { - r->refcnt += ol->u.refs[j].refcnt; - break; - } - - if (r) - continue; - } - - r = (struct opd_refent *) calloc (sizeof (struct opd_refent), 1); - if (r == NULL) - goto error_mem; - - ++nrefent; - r->next = (struct opd_refent *) *tabslot; - *tabslot = r; - r->val = refent.val; - r->gp = refent.gp; - r->refcnt = ol->u.refs[j].refcnt; - - tabent.ent = ol->u.refs[j].ent; - - tabslot = htab_find_slot (tabent_htab, &tabent, INSERT); - if (tabslot == NULL) - goto error_mem; - - if (*tabslot != NULL) - { - t = (struct opd_tabent *) *tabslot; - t->ref->nextref = r; - r->nextref = t->ref; - } - else - { - t = (struct opd_tabent *) calloc (sizeof (struct opd_tabent), 1); - if (t == NULL) - goto error_mem; - t->ent = ol->u.refs[j].ent; - *tabslot = t; - r->nextref = r; - t->ref = r; - } - - r->tabent = t; - } - } - - refarr = alloca (nrefent * sizeof (struct opd_refent *)); - a = refarr; - htab_traverse (refent_htab, opd_gather_refent, &a); - assert (a == refarr + nrefent); - qsort (refarr, nrefent, sizeof (struct opd_refent *), opd_refent_cmp); - for (i = 0; i < nrefent; ++i) - { - struct opd_fptr *f; - - if (refarr[i]->tabent == NULL) - continue; - - f = (struct opd_fptr *) calloc (sizeof (struct opd_fptr), 1); - if (f == NULL) - goto error_mem; - - f->val = refarr[i]->val; - f->gp = refarr[i]->gp; - f->ent = refarr[i]->tabent->ent; - tabslot = htab_find_slot (l->htab, f, INSERT); - if (tabslot == NULL) - goto error_mem; - - *tabslot = f; - r = refarr[i]->tabent->ref; - do - { - if (r != refarr[i]) - r->tabent = NULL; - r = r->nextref; - } - while (r != refarr[i]->tabent->ref); - - for (r = refarr[i]->first; r; r = r->next) - r->tabent = NULL; - } - - htab_delete (tabent_htab); - htab_delete (refent_htab); - info->ent->opd = l; - return 0; - -error_mem: - error (0, ENOMEM, "%s: Could not create OPD table", - info->ent->filename); -error_out: - if (tabent_htab) - htab_delete (tabent_htab); - if (refent_htab) - htab_delete (refent_htab); - if (l && l->htab) - htab_delete (l->htab); - free (l); - return 1; -} - -int -opd_add (struct prelink_info *info, GElf_Word r_sym, int reloc_type) -{ - struct opd_fptr *f, fp; - void **tabslot; - struct opd_lib *l = info->ent->opd; - - if (l->u.refp[r_sym] != NULL) - { - ++l->u.refp[r_sym]->refcnt; - return 0; - } - - if (ELF64_ST_BIND (info->symtab [r_sym].st_info) - == STB_LOCAL) - { - fp.val = info->symtab [r_sym].st_value; - fp.gp = info->ent->pltgot; - } - else - { - fp.val = info->resolve (info, r_sym, reloc_type); - if (info->resolveent == NULL) - return 0; - fp.gp = info->resolveent->pltgot; - } - - l->u.refp[r_sym] = malloc (sizeof (struct opd_ref)); - if (l->u.refp[r_sym] == NULL) - goto error_mem; - l->u.refp[r_sym]->symoff = r_sym; - l->u.refp[r_sym]->refcnt = 1; - l->u.refp[r_sym]->ent = NULL; - - tabslot = htab_find_slot (l->htab, &fp, INSERT); - if (tabslot == NULL) - goto error_mem; - - if (*tabslot == NULL) - { - f = calloc (sizeof (struct opd_fptr), 1); - if (f == NULL) - goto error_mem; - f->val = fp.val; - f->gp = fp.gp; - *tabslot = f; - } - - l->u.refp[r_sym]->ent = *tabslot; - return 0; - -error_mem: - error (0, ENOMEM, "%s: Could not create OPD table", - info->ent->filename); - return 1; -} - -void -opd_note_plt (struct prelink_info *info, GElf_Word r_sym, int reloc_type, - GElf_Addr r_offset) -{ - struct opd_fptr *f, fp; - struct opd_lib *l = info->ent->opd; - struct opd_ent_plt *entp; - - if (ELF64_ST_BIND (info->symtab [r_sym].st_info) - == STB_LOCAL) - { - fp.val = info->symtab [r_sym].st_value; - fp.gp = info->ent->pltgot; - } - else - { - fp.val = info->resolve (info, r_sym, reloc_type); - if (info->resolveent == NULL) - return; - fp.gp = info->resolveent->pltgot; - } - - f = (struct opd_fptr *) htab_find (l->htab, &fp); - if (f == NULL || f->ent != NULL) - return; - - entp = calloc (sizeof (struct opd_ent_plt), 1); - if (entp == NULL) - return; - - entp->v.val = fp.val; - entp->v.gp = fp.gp; - entp->v.opd = (r_offset - l->plt_start) | (OPD_ENT_PLT | OPD_ENT_NEW); - entp->lib = info->ent; - entp->symoff = r_sym; - f->ent = &entp->v; -} - -GElf_Addr -opd_size (struct prelink_info *info, GElf_Word entsize) -{ - struct opd_lib *l = info->ent->opd; - int i; - GElf_Addr ret = 0; - struct opd_ent *e; - struct opd_fptr *f; - - for (i = 0; i < l->nrefs; ++i) - if ((f = (struct opd_fptr *) l->u.refp[i]->ent)->ent == NULL) - { - e = calloc (sizeof (struct opd_ent), 1); - if (e == NULL) - { - error (0, ENOMEM, "%s: Could not create OPD table", - info->ent->filename); - return -1; - } - - e->val = f->val; - e->gp = f->gp; - e->opd = ret | OPD_ENT_NEW; - ret += entsize; - } - - return ret; -} diff --git a/trunk/src/fptr.h b/trunk/src/fptr.h deleted file mode 100644 index 36ef7c6..0000000 --- a/trunk/src/fptr.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef FPTR_H -#define FPTR_H - -#include "prelink.h" -#include "hashtab.h" - -struct opd_ent -{ - GElf_Addr val; - GElf_Addr gp; - GElf_Addr opd; -#define OPD_ENT_PLT 1 -#define OPD_ENT_NEW 2 -}; - -struct opd_ent_plt -{ - struct opd_ent v; - struct prelink_entry *lib; - GElf_Word symoff; -}; - -struct opd_ref -{ - GElf_Word symoff; - GElf_Word refcnt; - struct opd_ent *ent; -}; - -struct opd_lib -{ - GElf_Addr symtab_start; - GElf_Addr opd_start; - GElf_Addr plt_start; - union - { - struct opd_ref *refs; - struct opd_ref **refp; - } u; - htab_t htab; - int nrefs; -}; - -int opd_init (struct prelink_info *info); -int opd_add (struct prelink_info *info, GElf_Word r_sym, int reloc_type); -void opd_note_plt (struct prelink_info *info, GElf_Word r_sym, int reloc_type, - GElf_Addr r_offset); -GElf_Addr opd_size (struct prelink_info *info, GElf_Word entsize); - -#endif /* FPTR_H */ diff --git a/trunk/src/gather.c b/trunk/src/gather.c deleted file mode 100644 index c61626e..0000000 --- a/trunk/src/gather.c +++ /dev/null @@ -1,1496 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <fnmatch.h> -#include <ftw.h> -#include <glob.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "prelinktab.h" -#include "reloc.h" - -#ifndef HAVE_FTW_ACTIONRETVAL -# define FTW_ACTIONRETVAL 0 -# define FTW_CONTINUE 0 -# define FTW_STOP 1 -#endif - -static int gather_lib (struct prelink_entry *ent); -static int implicit; - -static struct prelink_dir *dirs; -static struct prelink_dir *blacklist; -#ifndef HAVE_FTW_ACTIONRETVAL -static char *blacklist_dir; -static size_t blacklist_dir_len; -#endif -static struct extension -{ - const char *ext; - size_t len; - int is_glob; -} *blacklist_ext; -static int blacklist_next; - -static int -gather_deps (DSO *dso, struct prelink_entry *ent) -{ - int i, j, seen = 0; - FILE *f = NULL; - const char *argv[8]; - const char *envp[5]; - char *line = NULL, *p, *q = NULL; - const char **depends = NULL, **depends_temp; - size_t ndepends = 0, ndepends_alloced = 0; - size_t len = 0; - ssize_t n; - Elf_Scn *scn; - Elf_Data *data; - Elf32_Lib *liblist = NULL; - int nliblist = 0; - const char *dl; - const char *ent_filename; - int etype = dso->ehdr.e_type; - - if (check_dso (dso)) - { - if (! undo) - ent->type = ET_UNPRELINKABLE; - goto error_out; - } - - ent->pltgot = dso->info[DT_PLTGOT]; - ent->soname = strdup (dso->soname); - ent->flags = (dso->arch->class == ELFCLASS64 ? PCF_ELF64 : 0) - | (dso->arch->machine & PCF_MACHINE); - if (ent->soname == NULL) - { - error (0, ENOMEM, "%s: Could not record SONAME", ent->filename); - goto error_out; - } - - dl = dynamic_linker ?: dso->arch->dynamic_linker; - if (strcmp (dso->filename, dl) == 0 - || is_ldso_soname (dso->soname)) - { - if (dynamic_info_is_set (dso, DT_GNU_PRELINKED_BIT) - && dynamic_info_is_set (dso, DT_CHECKSUM_BIT)) - { - if (! undo && dso->arch->read_opd) - dso->arch->read_opd (dso, ent); - ent->done = 2; - } - close_dso (dso); - return 0; - } - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - const char *name; - if (dso->shdr[i].sh_type == SHT_GNU_LIBLIST - && (name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name)) - && ! strcmp (name, ".gnu.liblist") - && (dso->shdr[i].sh_size % sizeof (Elf32_Lib)) == 0) - { - nliblist = dso->shdr[i].sh_size / sizeof (Elf32_Lib); - liblist = (Elf32_Lib *) alloca (dso->shdr[i].sh_size); - scn = dso->scn[i]; - data = elf_getdata (scn, NULL); - if (data == NULL || elf_getdata (scn, data) - || data->d_buf == NULL || data->d_off - || data->d_size != dso->shdr[i].sh_size) - liblist = NULL; - else - memcpy (liblist, data->d_buf, dso->shdr[i].sh_size); - if (! undo) - break; - } - else if (undo - && dso->shdr[i].sh_type == SHT_PROGBITS - && (name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name)) - && ! strcmp (name, ".gnu.prelink_undo")) - ent->done = 2; - } - - if (! undo && dso->arch->read_opd) - dso->arch->read_opd (dso, ent); - close_dso (dso); - dso = NULL; - - i = 0; - argv[i++] = dl; - if (strchr (ent->filename, '/') != NULL) - ent_filename = ent->filename; - else - { - size_t flen = strlen (ent->filename); - char *tp = alloca (2 + flen + 1); - memcpy (tp, "./", 2); - memcpy (tp + 2, ent->filename, flen + 1); - ent_filename = tp; - } - - if (prelink_rtld == NULL) - { - i = 0; - argv[i++] = dl; - if (ld_library_path) - { - argv[i++] = "--library-path"; - argv[i++] = ld_library_path; - } - argv[i++] = ent_filename; - argv[i] = NULL; - envp[0] = "LD_TRACE_LOADED_OBJECTS=1"; - envp[1] = "LD_TRACE_PRELINKING=1"; - envp[2] = "LD_WARN="; - envp[3] = NULL; - f = execve_open (dl, (char * const *)argv, (char * const *)envp); - } - else - { - char *path; - i = 0; - argv[i++] = prelink_rtld; - if (ld_library_path) - { - argv[i++] = "--library-path"; - argv[i++] = ld_library_path; - } - - if(etype == ET_EXEC && ld_preload) { - argv[i++] = "--ld-preload"; - argv[i++] = ld_preload; - } - argv[i++] = "--target-paths"; - argv[i++] = ent_filename; - argv[i] = NULL; - envp[0] = "RTLD_TRACE_PRELINKING=1"; - envp[1] = "RTLD_WARN="; - path = alloca (sizeof "PATH=" + strlen (getenv ("PATH"))); - sprintf (path, "PATH=%s", getenv ("PATH")); - envp[2] = path; - - if (sysroot) - { - envp[3] = alloca (sizeof "PRELINK_SYSROOT=" + strlen (sysroot)); - sprintf ((char *) envp[3], "PRELINK_SYSROOT=%s", sysroot); - envp[4] = NULL; - } - else - envp[3] = NULL; - - f = execve_open (prelink_rtld, (char * const *)argv, (char * const *)envp); - } - - if (f == NULL) - goto error_out; - - do - { - n = getline (&line, &len, f); - if (n < 0) - break; - - if (line[n - 1] == '\n') - line[n - 1] = '\0'; - - p = strstr (line, " => "); - if (p) - { - q = strstr (p, " ("); - if (q == NULL && strcmp (p, " => not found") == 0) - { - error (0, 0, "%s: Could not find one of the dependencies: %s", - ent->filename, line); - goto error_out; - } - } - if (p == NULL || q == NULL) - { - if (strstr (line, "statically linked") != NULL) - error (0, 0, "%s: Library without dependencies", ent->filename); - else - { - p = strstr (line, "error while loading shared libraries: "); - if (p != NULL) - { - p += sizeof "error while loading shared libraries: " - 1; - q = strstr (line, "cannot open shared object file: " - "No such file or directory"); - if (q != NULL) - { - error (0, 0, - "%s: Could not find one of the dependencies: \n%s", - ent->filename, line); - goto error_out; - } - } - error (0, 0, "%s: Could not parse `%s'", ent->filename, line); - } - goto error_out; - } - - *p = '\0'; - p += sizeof " => " - 1; - *q = '\0'; - if (! strcmp (p, ent_filename)) - { - ++seen; - continue; - } - if (ndepends == ndepends_alloced) - { - ndepends_alloced += 10; - depends_temp = depends; - depends = - (const char **) realloc (depends, - ndepends_alloced * sizeof (char *)); - if (depends == NULL) - { - free(depends_temp); - error (0, ENOMEM, "%s: Could not record dependencies", - ent->filename); - goto error_out; - } - } - - depends[ndepends] = strdupa (p); - ++ndepends; - } while (!feof (f)); - - if (execve_close (f)) - { - f = NULL; - error (0, 0, "%s: Dependency tracing failed", ent->filename); - goto error_out; - } - - f = NULL; - if (seen != 1) - { - error (0, 0, "%s seen %d times in LD_TRACE_PRELINKING output, expected once", - ent->filename, seen); - goto error_out; - } - - free (line); - line = NULL; - - if (ndepends == 0) - ent->depends = NULL; - else - { - ent->depends = - (struct prelink_entry **) - malloc (ndepends * sizeof (struct prelink_entry *)); - if (ent->depends == NULL) - { - error (0, ENOMEM, "%s: Could not record dependencies", ent->filename); - goto error_out; - } - } - - ent->ndepends = ndepends; - char *cache_dyn_depends = NULL; - if (ndepends) - { - cache_dyn_depends = alloca (ndepends); - memset (cache_dyn_depends, '\0', ndepends); - } - for (i = 0; i < ndepends; ++i) - { - ent->depends[i] = prelink_find_entry (depends [i], NULL, 1); - if (ent->depends[i] == NULL) - goto error_out_free_depends; - - if (ent->depends[i]->type == ET_CACHE_DYN) - { - ent->depends[i]->type = ET_NONE; - free (ent->depends[i]->depends); - ent->depends[i]->depends = NULL; - ent->depends[i]->ndepends = 0; - cache_dyn_depends[i] = 1; - } - - if (ent->depends[i]->type != ET_NONE - && ent->depends[i]->type != ET_BAD - && ent->depends[i]->type != ET_DYN - && ent->depends[i]->type != ET_UNPRELINKABLE) - { - error (0, 0, "%s is not a shared library", depends [i]); -error_out_regather_libs: - for (i = 0; i < ndepends; ++i) - { - if (cache_dyn_depends[i] && ent->depends[i]->type == ET_NONE) - gather_lib (ent->depends[i]); - } - goto error_out_free_depends; - } - } - - free (depends); - depends = NULL; - - for (i = 0; i < ndepends; ++i) - if (ent->depends[i]->type == ET_NONE - && gather_lib (ent->depends[i])) - { - cache_dyn_depends[i] = 0; - goto error_out_regather_libs; - } - - for (i = 0; i < ndepends; ++i) - for (j = 0; j < ent->depends[i]->ndepends; ++j) - if (ent->depends[i]->depends[j] == ent) - { - error (0, 0, "%s has a dependency cycle", ent->canon_filename); - goto error_out_free_depends; - } - - for (i = 0; i < ndepends; ++i) - if (ent->depends[i]->type == ET_UNPRELINKABLE) - { - error (0, 0, "Could not prelink %s because its dependency %s could not be prelinked", - ent->filename, ent->depends[i]->filename); - ent->type = ET_UNPRELINKABLE; - goto error_out; - } - - if (! undo && (!nliblist || liblist) && nliblist == ndepends) - { - for (i = 0; i < ndepends; ++i) - if (liblist[i].l_time_stamp != ent->depends[i]->timestamp - || liblist[i].l_checksum != ent->depends[i]->checksum - || ! ent->depends[i]->done) - break; - - if (i == ndepends) - ent->done = 2; - } - - return 0; - -error_out_free_depends: - free (ent->depends); - ent->depends = NULL; - ent->ndepends = 0; -error_out: - if (f) - execve_close (f); - free (line); - free (depends); - if (dso) - close_dso (dso); - return 1; -} - -static int -gather_dso (DSO *dso, struct prelink_entry *ent) -{ - int prelinked; - - if (verbose > 5) - printf ("Checking shared library %s\n", ent->canon_filename); - - if (dso->ehdr.e_type != ET_DYN) - { - error (0, 0, "%s is not a shared library", ent->filename); - close_dso (dso); - return 1; - } - - prelinked = (dynamic_info_is_set (dso, DT_GNU_PRELINKED_BIT) - && dynamic_info_is_set (dso, DT_CHECKSUM_BIT)); - ent->timestamp = dso->info_DT_GNU_PRELINKED; - ent->checksum = dso->info_DT_CHECKSUM; - ent->base = dso->base; - ent->end = dso->end; - if (dso->arch->need_rel_to_rela != NULL && ! prelinked) - { - /* If the library has not been prelinked yet and we need - to convert REL to RELA, then make room for it. */ - struct reloc_info rinfo; - GElf_Addr adjust = 0; - int sec = dso->ehdr.e_shnum; - - if (find_reloc_sections (dso, &rinfo)) - { - close_dso (dso); - return 1; - } - - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - if (rinfo.rel_to_rela) - { - sec = rinfo.first; - adjust = (dso->shdr[rinfo.last].sh_addr - + dso->shdr[rinfo.last].sh_size - - dso->shdr[rinfo.first].sh_addr) / 2; - } - if (rinfo.rel_to_rela_plt) - { - if (rinfo.plt < sec) - sec = rinfo.plt; - adjust += dso->shdr[rinfo.plt].sh_size / 2; - } - if (adjust) - { - int align = 0, i, last; - GElf_Addr start; - - for (i = rinfo.plt ? rinfo.plt : rinfo.first; - i < dso->ehdr.e_shnum; i++) - { - if (dso->shdr[i].sh_addralign > align) - align = dso->shdr[i].sh_addralign; - } - - if (rinfo.plt) - start = dso->shdr[rinfo.plt].sh_addr - + dso->shdr[rinfo.plt].sh_size; - else - start = dso->shdr[rinfo.first].sh_addr - + dso->shdr[rinfo.first].sh_size; - - /* Need to make sure that all the remaining sections are properly - aligned. */ - if (align) - adjust = (adjust + align - 1) & ~(align - 1); - - /* Need to make sure adjust doesn't cause different Phdr segments - to overlap on the same page. */ - last = -1; - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz >= start) - { - if (last != -1 - && (((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - - 1) ^ dso->phdr[i].p_vaddr) - & ~(dso->arch->max_page_size - 1)) - && !(((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - + adjust - 1) - ^ (dso->phdr[i].p_vaddr + adjust)) - & ~(dso->arch->max_page_size - 1))) - { - if (align >= dso->arch->max_page_size) - { - error (0, 0, "%s: Cannot grow reloc sections", - ent->filename); - close_dso (dso); - return 1; - } - adjust = (adjust + dso->arch->max_page_size - 1) - & ~(dso->arch->max_page_size - 1); - } - last = i; - } - - ent->end += adjust; - } - } - - if (gather_deps (dso, ent)) - return 1; - - if (ent->done && ! prelinked && ! undo) - ent->done = 0; - ent->type = ET_DYN; - return 0; -} - -static int -gather_lib (struct prelink_entry *ent) -{ - DSO *dso; - - ent->type = ET_BAD; - dso = open_dso (ent->filename); - if (dso == NULL) - return 1; - - return gather_dso (dso, ent); -} - -static int -gather_exec (DSO *dso, const struct stat64 *st) -{ - int i, j; - Elf_Data *data; - const char *dl; - struct prelink_entry *ent; - - if (verbose > 5) - printf ("Checking executable %s\n", dso->filename); - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_INTERP) - break; - - /* If there are no PT_INTERP segments, it is statically linked. */ - if (i == dso->ehdr.e_phnum) - { -make_unprelinkable: - if (undo) - goto error_out; - - ent = prelink_find_entry (dso->filename, st, 1); - if (ent == NULL) - goto error_out; - - assert (ent->type == ET_NONE); - ent->type = ET_UNPRELINKABLE; - close_dso (dso); - return 0; - } - - j = addr_to_sec (dso, dso->phdr[i].p_vaddr); - if (j == -1 || dso->shdr[j].sh_addr != dso->phdr[i].p_vaddr - || dso->shdr[j].sh_type != SHT_PROGBITS) - { - error (0, 0, "%s: PT_INTERP segment not corresponding to .interp section", - dso->filename); - goto make_unprelinkable; - } - - data = elf_getdata (dso->scn[j], NULL); - if (data == NULL) - { - error (0, 0, "%s: Could not read .interp section", dso->filename); - goto error_out; - } - - i = strnlen (data->d_buf, data->d_size); - if (i == data->d_size) - { - error (0, 0, "%s: .interp section not zero terminated", dso->filename); - goto error_out; - } - - dl = dynamic_linker ?: dso->arch->dynamic_linker; - if (strcmp (dl, data->d_buf) != 0 - && (dynamic_linker != NULL || dso->arch->dynamic_linker_alt == NULL - || strcmp (dso->arch->dynamic_linker_alt, data->d_buf) != 0)) - { - error (0, 0, "%s: Using %s, not %s as dynamic linker", dso->filename, - (char *) data->d_buf, dl); - goto error_out; - } - - if (dso_has_bad_textrel (dso)) - { - error (0, 0, "%s has text relocations", dso->filename); - goto make_unprelinkable; - } - - ent = prelink_find_entry (dso->filename, st, 1); - if (ent == NULL) - goto error_out; - - assert (ent->type == ET_NONE); - ent->u.explicit = 1; - - if (gather_deps (dso, ent)) - return 0; - - for (i = 0; i < ent->ndepends; ++i) - ++ent->depends[i]->refs; - - ent->type = ET_EXEC; - return 0; - -error_out: - if (dso) - close_dso (dso); - return 0; -} - -static int -add_dir_to_dirlist (const char *name, dev_t dev, int flags) -{ - const char *canon_name; - struct prelink_dir *dir; - size_t len; - - canon_name = prelink_canonicalize (name, NULL); - if (canon_name == NULL) - { - if (! all && implicit) - return 0; - error (0, errno, "Could not record directory %s", name); - return 1; - } - - len = strlen (canon_name); - - for (dir = blacklist; dir; dir = dir->next) - if (((dir->flags != FTW_CHDIR && len >= dir->len) - || (dir->flags == FTW_CHDIR && len == dir->len)) - && strncmp (dir->dir, canon_name, dir->len) == 0) - { - if (dir->flags == FTW_CHDIR) - break; - if ((dir->flags & FTW_MOUNT) && dir->dev != dev) - continue; - break; - } - - if (dir != NULL) - { - free ((char *) canon_name); - return 2; - } - - dir = malloc (sizeof (struct prelink_dir) + len + 1); - if (dir == NULL) - { - error (0, ENOMEM, "Could not record directory %s", name); - free ((char *) canon_name); - return 1; - } - - dir->next = dirs; - dir->flags = flags; - dir->dev = dev; - dir->len = len; - strcpy (dir->dir, canon_name); - free ((char *) canon_name); - dirs = dir; - return 0; -} - -/* Determine if a buffer holding an ELF header and program header - table may be that of a position-independent executable. */ -static int -maybe_pie (unsigned char *e_ident, int big_endian, int sixty_four) -{ - uint16_t num_phdrs; - uint16_t phdr; - size_t p_type_offset; - size_t phnum_offset; - unsigned char *phdr_table; - unsigned char *this_phdr; - - if (sixty_four) - { - uint64_t phdr_offset; - - p_type_offset = offsetof (Elf64_Phdr, p_type); - phnum_offset = offsetof (Elf64_Ehdr, e_phnum); - if (big_endian) - phdr_offset = buf_read_ube64 (&e_ident [offsetof (Elf64_Ehdr, - e_phoff)]); - else - phdr_offset = buf_read_ule64 (&e_ident [offsetof (Elf64_Ehdr, - e_phoff)]); - phdr_table = e_ident + phdr_offset; - } - else - { - uint32_t phdr_offset; - - p_type_offset = offsetof (Elf32_Phdr, p_type); - phnum_offset = offsetof (Elf32_Ehdr, e_phnum); - if (big_endian) - phdr_offset = buf_read_ube32 (&e_ident [offsetof (Elf32_Ehdr, - e_phoff)]); - else - phdr_offset = buf_read_ule32 (&e_ident [offsetof (Elf32_Ehdr, - e_phoff)]); - phdr_table = e_ident + phdr_offset; - } - - this_phdr = phdr_table; - - if (big_endian) - num_phdrs = buf_read_ube16 (&e_ident [phnum_offset]); - else - num_phdrs = buf_read_ule16 (&e_ident [phnum_offset]); - - for (phdr = 0; phdr < num_phdrs; phdr++) - { - unsigned char *p_type_start = this_phdr + p_type_offset; - uint32_t p_type; - - if (big_endian) - p_type = buf_read_ube32 (p_type_start); - else - p_type = buf_read_ule32 (p_type_start); - - if (p_type == PT_PHDR) - return 1; - - /* Any PT_PHDR entry must come before any PT_LOAD entry. */ - if (p_type == PT_LOAD) - return 0; - - this_phdr += sixty_four ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr); - } - - return 0; -} - -static int -gather_func (const char *name, const struct stat64 *st, int type, - struct FTW *ftwp) -{ - unsigned char e_ident [sizeof (Elf64_Ehdr) + sizeof (Elf64_Phdr)]; - -#ifndef HAVE_FTW_ACTIONRETVAL - if (blacklist_dir) - { - if (strncmp (name, blacklist_dir, blacklist_dir_len) == 0) - return FTW_CONTINUE; - free (blacklist_dir); - blacklist_dir = NULL; - } -#endif - if (type == FTW_F && S_ISREG (st->st_mode) && (st->st_mode & 0111)) - { - int fd, i; - DSO *dso; - struct prelink_entry *ent; - size_t len = strlen (name); - const char *base = NULL; - - for (i = 0; i < blacklist_next; ++i) - if (blacklist_ext[i].is_glob) - { - if (base == NULL) - { - base = strrchr (name, '/'); - if (base == NULL) - base = name; - else - ++base; - } - if (fnmatch (blacklist_ext[i].ext, base, FNM_PERIOD) == 0) - return FTW_CONTINUE; - } - else if (blacklist_ext[i].len <= len - && memcmp (name + len - blacklist_ext[i].len, - blacklist_ext[i].ext, blacklist_ext[i].len) == 0) - return FTW_CONTINUE; - - ent = prelink_find_entry (name, st, 0); - if (ent != NULL && ent->type != ET_NONE) - { - if (verbose > 5) - { - if (ent->type == ET_CACHE_EXEC || ent->type == ET_CACHE_DYN) - printf ("Assuming prelinked %s\n", name); - if (ent->type == ET_UNPRELINKABLE) - printf ("Assuming non-prelinkable %s\n", name); - } - ent->u.explicit = 1; - return FTW_CONTINUE; - } - - if (st->st_size < sizeof (e_ident)) - return FTW_CONTINUE; - - fd = wrap_open (name, O_RDONLY); - if (fd == -1) - return FTW_CONTINUE; - - if (read (fd, e_ident, sizeof (e_ident)) != sizeof (e_ident)) - { -close_it: - fsync (fd); - close (fd); - return FTW_CONTINUE; - } - - /* Quickly find ET_EXEC ELF binaries and most of PIE binaries. */ - - if (memcmp (e_ident, ELFMAG, SELFMAG) != 0) - { -make_unprelinkable: - if (! undo) - { - ent = prelink_find_entry (name, st, 1); - if (ent != NULL) - { - assert (ent->type == ET_NONE); - ent->type = ET_UNPRELINKABLE; - } - } - fsync (fd); - close (fd); - return FTW_CONTINUE; - } - - switch (e_ident [EI_DATA]) - { - case ELFDATA2LSB: - if (e_ident [EI_NIDENT + 1] != 0) - goto make_unprelinkable; - if (e_ident [EI_NIDENT] != ET_EXEC) - { - if (e_ident [EI_NIDENT] != ET_DYN) - goto make_unprelinkable; - else if (e_ident [EI_CLASS] == ELFCLASS32) - { - if (maybe_pie (e_ident, 0, 0)) - { -maybe_pie: - dso = fdopen_dso (fd, name); - if (dso == NULL) - goto close_it; - if (dynamic_info_is_set (dso, DT_DEBUG)) - { - close_dso (dso); - goto make_unprelinkable; - } - close_dso (dso); - } - goto close_it; - } - else if (e_ident [EI_CLASS] == ELFCLASS64) - { - if (maybe_pie (e_ident, 0, 1)) - goto maybe_pie; - goto close_it; - } - else - goto make_unprelinkable; - } - break; - case ELFDATA2MSB: - if (e_ident [EI_NIDENT] != 0) - goto make_unprelinkable; - if (e_ident [EI_NIDENT + 1] != ET_EXEC) - { - if (e_ident [EI_NIDENT + 1] != ET_DYN) - goto make_unprelinkable; - else if (e_ident [EI_CLASS] == ELFCLASS32) - { - if (maybe_pie (e_ident, 1, 0)) - goto maybe_pie; - goto close_it; - } - else if (e_ident [EI_CLASS] == ELFCLASS64) - { - if (maybe_pie (e_ident, 1, 1)) - goto maybe_pie; - goto close_it; - } - else - goto make_unprelinkable; - } - break; - default: - goto make_unprelinkable; - } - - dso = fdopen_dso (fd, name); - if (dso == NULL) - return FTW_CONTINUE; - - gather_exec (dso, st); - } - else if (type == FTW_D) - switch (add_dir_to_dirlist (name, st->st_dev, FTW_CHDIR)) - { - case 0: return FTW_CONTINUE; - default: return FTW_STOP; - case 2: -#ifdef HAVE_FTW_ACTIONRETVAL - return FTW_SKIP_SUBTREE; -#else - { - blacklist_dir_len = strlen (name) + 1; - if (blacklist_dir_len > 1 && name[blacklist_dir_len - 2] == '/') - blacklist_dir_len--; - blacklist_dir = malloc (blacklist_dir_len + 1); - if (blacklist_dir == NULL) - { - error (0, ENOMEM, "Cannot store blacklisted dir name"); - return FTW_STOP; - } - memcpy (blacklist_dir, name, blacklist_dir_len - 1); - blacklist_dir[blacklist_dir_len - 1] = '/'; - blacklist_dir[blacklist_dir_len] = '\0'; - return FTW_CONTINUE; - } -#endif - } - - return FTW_CONTINUE; -} - -static int -gather_binlib (const char *name, const struct stat64 *st) -{ - unsigned char e_ident [EI_NIDENT + 2]; - int fd, type; - DSO *dso; - struct prelink_entry *ent; - - if (! S_ISREG (st->st_mode)) - { - error (0, 0, "%s is not a regular file", name); - return 1; - } - - ent = prelink_find_entry (name, st, 0); - if (ent != NULL && ent->type == ET_UNPRELINKABLE) - { - free (ent->depends); - ent->depends = NULL; - ent->ndepends = 0; - ent->type = ET_NONE; - } - if (ent != NULL && ent->type != ET_NONE) - { - ent->u.explicit = 1; - return 0; - } - - fd = wrap_open (name, O_RDONLY); - if (fd == -1) - { - error (0, errno, "Could not open %s", name); - return 1; - } - - if (read (fd, e_ident, sizeof (e_ident)) != sizeof (e_ident)) - { - error (0, errno, "Could not read ELF header from %s", name); - fsync (fd); - close (fd); - return 1; - } - - /* Quickly find ET_EXEC/ET_DYN ELF binaries/libraries only. */ - - if (memcmp (e_ident, ELFMAG, SELFMAG) != 0) - { - error (0, 0, "%s is not an ELF object", name); - fsync (fd); - close (fd); - return 1; - } - - switch (e_ident [EI_DATA]) - { - case ELFDATA2LSB: - if (e_ident [EI_NIDENT + 1] != 0) - goto unsupported_type; - type = e_ident [EI_NIDENT]; - break; - case ELFDATA2MSB: - if (e_ident [EI_NIDENT] != 0) - goto unsupported_type; - type = e_ident [EI_NIDENT + 1]; - break; - default: - goto unsupported_type; - } - - if (type != ET_EXEC && type != ET_DYN) - { -unsupported_type: - error (0, 0, "%s is neither ELF executable nor ELF shared library", name); - fsync (fd); - close (fd); - return 1; - } - - dso = fdopen_dso (fd, name); - if (dso == NULL) - return 0; - - if (type == ET_EXEC) - { - int i; - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_INTERP) - break; - - /* If there are no PT_INTERP segments, it is statically linked. */ - if (i == dso->ehdr.e_phnum) - { - error (0, 0, "%s is statically linked", name); - close_dso (dso); - return 1; - } - - return gather_exec (dso, st); - } - - ent = prelink_find_entry (name, st, 1); - if (ent == NULL) - { - close_dso (dso); - return 1; - } - - assert (ent->type == ET_NONE); - ent->type = ET_BAD; - ent->u.explicit = 1; - return gather_dso (dso, ent); -} - -int -gather_object (const char *name, int deref, int onefs) -{ - struct stat64 st; - - if (wrap_stat64 (name, &st) < 0) - { - if (implicit) - return 0; - error (0, errno, "Could not stat %s", name); - return 1; - } - - if (S_ISDIR (st.st_mode)) - { - int flags = 0, ret; - if (! deref) flags |= FTW_PHYS; - if (onefs) flags |= FTW_MOUNT; - - if (implicit && ! deref) - { - ret = add_dir_to_dirlist (name, st.st_dev, flags); - if (ret) - return ret == 2 ? 0 : 1; - } - if (!all && implicit && ! deref) - return 0; - ++implicit; - ret = wrap_nftw64 (name, gather_func, 20, flags | FTW_ACTIONRETVAL); - --implicit; - if (ret < 0) - error (0, errno, "Failed searching %s", name); -#ifndef HAVE_FTW_ACTIONRETVAL - free (blacklist_dir); - blacklist_dir = NULL; -#endif - return ret; - } - else - return gather_binlib (name, &st); -} - -static struct config_line -{ - struct config_line *next; - char line[1]; -} *config_lines, **config_end = &config_lines; - -int -read_config (const char *config) -{ - FILE *file = fopen (config, "r"); - char *line = NULL; - size_t len, llen; - int ret = 0; - struct config_line *c; - - if (file == NULL) - { - error (0, errno, "Can't open configuration file %s", config); - return 1; - } - - do - { - ssize_t i = getline (&line, &len, file); - char *p; - - if (i < 0) - break; - - if (line[i - 1] == '\n') - line[i - 1] = '\0'; - - p = strchr (line, '#'); - if (p != NULL) - *p = '\0'; - - p = line + strspn (line, " \t"); - if (p[0] == '-' && p[1] == 'c' && (p[2] == ' ' || p[2] == '\t')) - { - glob_t g; - p += 2 + strspn (p + 2, " \t"); - - if (!wrap_glob (p, GLOB_BRACE, NULL, &g)) - { - size_t n; - - for (n = 0; n < g.gl_pathc; ++n) - if (read_config (g.gl_pathv[n])) - { - ret = 1; - break; - } - - globfree (&g); - if (ret) - break; - } - continue; - } - - llen = strlen (p); - c = malloc (sizeof (*c) + llen); - if (c == NULL) - { - error (0, ENOMEM, "Could not cache config file"); - ret = 1; - break; - } - - c->next = NULL; - memcpy (c->line, p, llen + 1); - *config_end = c; - config_end = &c->next; - } - while (!feof (file)); - - free (line); - fclose (file); - return ret; -} - -int -gather_config (void) -{ - struct config_line *c; - int ret = 0; - - implicit = 1; - for (c = config_lines; c; c = c->next) - { - int deref = 0; - int onefs = 0; - char *p = c->line; - - while (*p == '-') - { - switch (p[1]) - { - case 'h': deref = 1; break; - case 'l': onefs = 1; break; - case 'b': p = ""; continue; - default: - error (0, 0, "Unknown directory option `%s'\n", p); - break; - } - p = p + 2 + strspn (p + 2, " \t"); - } - - if (*p == '\0') - continue; - - if (strpbrk (p, "*?[{") == NULL) - { - ret = gather_object (p, deref, onefs); - if (ret) - { - ret = 1; - break; - } - } - else - { - glob_t g; - - if (!wrap_glob (p, GLOB_BRACE, NULL, &g)) - { - size_t n; - - for (n = 0; n < g.gl_pathc; ++n) - { - ret = gather_object (g.gl_pathv[n], deref, onefs); - if (ret) - { - ret = 1; - break; - } - } - - globfree (&g); - if (ret) - break; - } - } - } - - implicit = 0; - return ret; -} - -static int -gather_check_lib (void **p, void *info) -{ - struct prelink_entry *e = * (struct prelink_entry **) p; - - if (e->type != ET_DYN) - return 1; - - if (! e->u.explicit) - { - struct prelink_dir *dir; - const char *name; - size_t len; - - name = strrchr (e->canon_filename, '/'); - if (!name) - name = e->canon_filename; - len = name - e->canon_filename; - - for (dir = blacklist; dir; dir = dir->next) - if (((dir->flags != FTW_CHDIR && len >= dir->len) - || (dir->flags == FTW_CHDIR && len == dir->len)) - && strncmp (dir->dir, e->canon_filename, dir->len) == 0) - { - if (dir->flags == FTW_CHDIR) - break; - if ((dir->flags & FTW_MOUNT) && dir->dev != e->dev) - continue; - break; - } - - if (dir != NULL) - { - error (0, 0, "%s is present in a blacklisted directory %s", - e->canon_filename, dir->dir); - e->type = ET_BAD; - return 1; - } - - for (dir = dirs; dir; dir = dir->next) - if (((dir->flags != FTW_CHDIR && len >= dir->len) - || (dir->flags == FTW_CHDIR && len == dir->len)) - && strncmp (dir->dir, e->canon_filename, dir->len) == 0) - { - if (dir->flags == FTW_CHDIR) - break; - if ((dir->flags & FTW_MOUNT) && dir->dev != e->dev) - continue; - break; - } - - if (dir == NULL) - { - error (0, 0, "%s is not present in any config file directories, nor was specified on command line", - e->canon_filename); - e->type = ET_BAD; - return 1; - } - } - - return 1; -} - -int -gather_check_libs (void) -{ - struct prelink_dir *dir; - void *f; - - htab_traverse (prelink_filename_htab, gather_check_lib, NULL); - - dir = dirs; - while (dir != NULL) - { - f = dir; - dir = dir->next; - free (f); - } - - dir = blacklist; - while (dir != NULL) - { - f = dir; - dir = dir->next; - free (f); - } - - dirs = NULL; - blacklist = NULL; - return 0; -} - -int -add_to_blacklist (const char *name, int deref, int onefs) -{ - const char *canon_name; - struct prelink_dir *path; - size_t len; - struct stat64 st; - - if (wrap_stat64 (name, &st) < 0) - { - if (implicit) - return 0; - error (0, errno, "Could not stat %s", name); - return 1; - } - - if (!S_ISDIR (st.st_mode)) - { - struct prelink_entry *ent; - - ent = prelink_find_entry (name, &st, 1); - if (ent == NULL) - return 1; - - ent->type = ET_BAD; - ent->u.explicit = 1; - return 0; - } - - canon_name = prelink_canonicalize (name, NULL); - if (canon_name == NULL) - { - if (implicit) - return 0; - error (0, errno, "Could not canonicalize %s", name); - return 1; - } - - len = strlen (canon_name); - path = malloc (sizeof (struct prelink_dir) + len + 1); - if (path == NULL) - { - error (0, ENOMEM, "Could not record path %s", name); - free ((char *) canon_name); - return 1; - } - - path->next = blacklist; - path->flags = 0; - if (! deref) path->flags |= FTW_PHYS; - if (onefs) path->flags |= FTW_MOUNT; - path->dev = 0; - path->len = len; - strcpy (path->dir, canon_name); - free ((char *) canon_name); - blacklist = path; - return 0; -} - -void -add_blacklist_ext (const char *ext) -{ - blacklist_ext = realloc (blacklist_ext, - (blacklist_next + 1) * sizeof (*blacklist_ext)); - if (blacklist_ext == NULL) - error (EXIT_FAILURE, errno, "can't create blacklist extension list"); - if (*ext == '*' && strpbrk (ext + 1, "*?[{") == NULL) - { - blacklist_ext[blacklist_next].is_glob = 0; - ext++; - } - else - blacklist_ext[blacklist_next].is_glob = 1; - blacklist_ext[blacklist_next].ext = strdup (ext); - if (blacklist_ext[blacklist_next].ext == NULL) - error (EXIT_FAILURE, errno, "can't create blacklist extension list"); - blacklist_ext[blacklist_next].len = strlen (ext); - blacklist_next++; -} - -int -blacklist_from_config (void) -{ - struct config_line *c; - int ret = 0; - - implicit = 1; - for (c = config_lines; c; c = c->next) - { - int deref = 0; - int onefs = 0; - int blacklist = 0; - char *p = c->line; - - while (*p == '-') - { - switch (p[1]) - { - case 'h': deref = 1; break; - case 'l': onefs = 1; break; - case 'b': blacklist = 1; break; - } - p = p + 2 + strspn (p + 2, " \t"); - } - - if (*p == '\0' || !blacklist) - continue; - - if (strchr (p, '/') == NULL) - { - add_blacklist_ext (p); - continue; - } - - if (strpbrk (p, "*?[{") == NULL) - { - ret = add_to_blacklist (p, deref, onefs); - if (ret) - { - ret = 1; - break; - } - } - else - { - glob_t g; - - if (!wrap_glob (p, GLOB_BRACE | GLOB_PERIOD, NULL, &g)) - { - size_t n; - - for (n = 0; n < g.gl_pathc; ++n) - { - ret = add_to_blacklist (g.gl_pathv[n], deref, onefs); - if (ret) - { - ret = 1; - break; - } - } - - globfree (&g); - if (ret) - break; - } - } - } - - implicit = 0; - return ret; -} diff --git a/trunk/src/get.c b/trunk/src/get.c deleted file mode 100644 index d10efcc..0000000 --- a/trunk/src/get.c +++ /dev/null @@ -1,760 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/wait.h> -#include "prelink.h" - -int -is_ldso_soname (const char *soname) -{ - if (! strcmp (soname, "ld-linux.so.2") - || ! strcmp (soname, "ld.so.1") - || ! strcmp (soname, "ld-linux-ia64.so.2") - || ! strcmp (soname, "ld-linux-x86-64.so.2") - || ! strcmp (soname, "ld64.so.1") - || ! strcmp (soname, "ld-linux.so.3") - || ! strcmp (soname, "ld-linux-armhf.so.3")) - return 1; - return 0; -} - -static void -conflict_hash_init (struct prelink_conflicts *conflicts) -{ - struct prelink_conflict **hash - = calloc (sizeof (struct prelink_conflict *), 251); - struct prelink_conflict *conflict, *next; - size_t idx; - - if (hash == NULL) - return; - - for (conflict = conflicts->first; conflict; conflict = next) - { - next = conflict->next; - idx = conflict->symoff % 251; - conflict->next = hash[idx]; - hash[idx] = conflict; - } - conflicts->hash = hash; -} - -static int -prelink_record_relocations (struct prelink_info *info, FILE *f, - const char *ent_filename) -{ - char buffer[8192]; - DSO *dso = info->dso; - struct prelink_entry *ent, *ent2; - struct prelink_tls *tls; - struct deps - { - struct prelink_entry *ent; - char *soname; - GElf_Addr start; - GElf_Addr l_addr; - GElf_Addr tls_modid; - GElf_Addr tls_offset; - } deps[info->ent->ndepends + 1]; - char *r; - int i, ndeps = 0, undef = 0, seen = 0, tdeps = 0; - int mask_32bit = (info->dso->ehdr.e_ident[EI_CLASS] == ELFCLASS32); - - /* Record the dependencies. */ - while ((r = fgets (buffer, 8192, f)) != NULL) - { - char *soname, *filename, *p, *q; - GElf_Addr start = 0, l_addr = 0, tls_modid = 0, tls_offset = 0; - unsigned long long l; - - if (buffer[0] != '\t' || (filename = strstr (buffer, " => ")) == NULL) - break; - soname = buffer + 1; - p = strstr (filename + sizeof (" => "), " (0x"); - if (p != NULL) - { - l = strtoull (p + sizeof (" (0x") - 1, &q, 16); - start = (GElf_Addr) l; - if (start != l || strncmp (q, ", 0x", sizeof (", 0x") - 1)) - p = NULL; - else - { - l = strtoull (q + sizeof (", 0x") - 1, &q, 16); - l_addr = (GElf_Addr) l; - if (l_addr != l || q[-1] == 'x') - p = NULL; - else if (strncmp (q, ") TLS(0x", sizeof (") TLS(0x") - 1) == 0) - { - l = strtoull (q + sizeof (") TLS(0x") - 1, &q, 16); - tls_modid = (GElf_Addr) l; - if (tls_modid != l || q[-1] == 'x' - || strncmp (q, ", 0x", sizeof (", 0x") - 1)) - p = NULL; - else - { - l = strtoull (q + sizeof (", 0x") - 1, &q, 16); - tls_offset = (GElf_Addr) l; - if (tls_offset != l || q[-1] == 'x') - p = NULL; - } - } - if (p && strcmp (q, ")\n")) - p = NULL; - } - } - if (p == NULL) - { - p = strchr (buffer, '\n'); - if (p != NULL) - *p = '\0'; - error (0, 0, "Could not parse line `%s'", buffer); - goto error_out; - } - *filename = '\0'; - filename += sizeof (" => ") - 1; - *p = '\0'; - - if (ndeps > info->ent->ndepends) - { - error (0, 0, "%s: Recorded %d dependencies, now seeing %d\n", - info->ent->filename, info->ent->ndepends, ndeps - 1); - goto error_out; - } - - tdeps = ndeps - seen + 1; - if (! seen - && (strcmp (info->ent->filename, filename) == 0 - || (info->ent->filename != ent_filename - && strcmp (ent_filename, filename) == 0) - || strcmp (info->ent->canon_filename, filename) == 0)) - { - seen = 1; - tdeps = 0; - } - else if (ent2 = info->ent->depends [tdeps - 1], - strcmp (ent2->filename, filename) != 0 - && strcmp (ent2->canon_filename, filename) != 0) - { - struct prelink_link *hardlink; - - for (hardlink = ent2->hardlink; hardlink; hardlink = hardlink->next) - if (strcmp (hardlink->canon_filename, filename) == 0) - break; - - if (hardlink == NULL) - { - struct stat64 st; - - if (wrap_stat64 (filename, &st) < 0) - { - error (0, errno, "%s: Could not stat %s", - info->ent->filename, filename); - goto error_out; - } - - if (st.st_dev != ent2->dev || st.st_ino != ent2->ino) - { - error (0, 0, "%s: %s => %s does not match recorded dependency", - info->ent->filename, soname, filename); - goto error_out; - } - } - } - - if (! tdeps) - deps[0].ent = info->ent; - else - deps[tdeps].ent = info->ent->depends[tdeps - 1]; - deps[tdeps].soname = strdup (soname); - if (deps[tdeps].soname == NULL) - { - error (0, ENOMEM, "Could not record `%s' SONAME", soname); - goto error_out; - } - deps[tdeps].start = start; - deps[tdeps].l_addr = l_addr; - deps[tdeps].tls_modid = tls_modid; - deps[tdeps].tls_offset = tls_offset; - ++ndeps; - } - - if (ndeps != info->ent->ndepends + 1) - { - error (0, 0, "%s: Recorded %d dependencies, now seeing %d\n", - info->ent->filename, info->ent->ndepends, ndeps - 1); - goto error_out; - } - - if (r == NULL && !ndeps) - { - error (0, 0, "%s: %s did not print any lookup lines", info->ent->filename, - dynamic_linker ?: dso->arch->dynamic_linker); - goto error_out; - } - - info->tls = malloc (ndeps * sizeof (struct prelink_tls)); - if (info->tls == NULL) - { - error (0, ENOMEM, "%s: Could not record dependency TLS information", - dso->filename); - goto error_out; - } - - for (i = 0; i < ndeps; i++) - { - info->tls[i].modid = deps[i].tls_modid; - info->tls[i].offset = deps[i].tls_offset; - } - - if (dso->ehdr.e_type == ET_EXEC || dso->arch->create_opd) - { - info->conflicts = (struct prelink_conflicts *) - calloc (sizeof (struct prelink_conflicts), ndeps); - if (info->conflicts == NULL) - { - error (0, ENOMEM, "%s: Can't build list of conflicts", info->ent->filename); - goto error_out; - } - for (i = 0; i < ndeps; i++) - info->conflicts[i].hash = &info->conflicts[i].first; - } - do - { - unsigned long long symstart, symoff, valstart[3], value[3]; - int reloc_class, len, type = 1, ifunc = 0; - char *symname; - - r = strchr (buffer, '\n'); - if (r) - *r = '\0'; - if (strncmp (buffer, "lookup ", sizeof ("lookup ") - 1) == 0) - { - struct prelink_symbol *s; - - if (sscanf (buffer, "lookup 0x%llx 0x%llx -> 0x%llx 0x%llx %n", - &symstart, &symoff, &valstart[0], &value[0], &len) != 4) - { - error (0, 0, "%s: Could not parse `%s'", info->ent->filename, buffer); - goto error_out; - } - - if (buffer[len] == '/') - { - ++len; - type = 0; - } - - reloc_class = strtoul (buffer + len, &symname, 16); - if (buffer + len == symname || (reloc_class == 0 && type) - || (*symname != ' ' && *symname != '\t')) - { - error (0, 0, "%s: Could not parse `%s'", info->ent->filename, buffer); - goto error_out; - } - - if (type) - reloc_class = dso->arch->reloc_class (reloc_class); - else - { - if (reloc_class & 8) - { - reloc_class = ((reloc_class & ~8) - | dso->arch->rtype_class_valid); - ifunc = 1; - } - else if ((reloc_class | RTYPE_CLASS_VALID) == RTYPE_CLASS_TLS) - reloc_class |= RTYPE_CLASS_VALID; - else - reloc_class |= dso->arch->rtype_class_valid; - } - - while (*symname == ' ' || *symname == '\t') ++symname; - - ent = NULL; - tls = NULL; - if (symstart == deps[0].start - || ((reloc_class == RTYPE_CLASS_TLS || ifunc) - && info->conflicts)) - { - for (i = 0; i < ndeps; i++) - if (deps[i].start == valstart[0]) - { - if (reloc_class == RTYPE_CLASS_TLS) - tls = info->tls + i; - else - { - ent = deps[i].ent; - /* If the library the symbol is bound to is already - prelinked, adjust the value so that it is relative - to library base. */ - if (mask_32bit) - value[0] -= (Elf32_Addr) (deps[i].start - deps[i].l_addr); - else - value[0] -= deps[i].start - deps[i].l_addr; - } - break; - } - - if (ent == NULL && tls == NULL && valstart[0]) - { - error (0, 0, "Could not find base 0x%08llx in the list of bases `%s'", - valstart[0], buffer); - goto error_out; - } - } - - if (symstart == deps[0].start && (!ifunc || info->conflicts == NULL)) - { - /* Only interested in relocations from the current object. */ - if (symoff < info->symtab_start || symoff >= info->symtab_end) - { - error (0, 0, "%s: Symbol `%s' offset 0x%08llx does not point into .dynsym section", - info->ent->filename, symname, symoff); - goto error_out; - } - - if (ent == info->ent - && reloc_class != RTYPE_CLASS_TLS) - value[0] = adjust_old_to_new (info->dso, value[0]); - - s = &info->symbols[(symoff - info->symtab_start) - / info->symtab_entsize]; - if (s->reloc_class) - { - while (s->reloc_class != reloc_class && s->next != NULL) - s = s->next; - if (s->reloc_class == reloc_class) - { - if ((reloc_class != RTYPE_CLASS_TLS && s->u.ent != ent) - || (reloc_class == RTYPE_CLASS_TLS - && s->u.tls != tls) - || s->value != value[0]) - { - error (0, 0, "%s: Symbol `%s' with the same reloc type resolves to different values each time", - info->ent->filename, symname); - goto error_out; - } - s = NULL; - } - else - { - s->next = (struct prelink_symbol *) - malloc (sizeof (struct prelink_symbol)); - if (s->next == NULL) - { - error (0, ENOMEM, "Cannot build symbol lookup map"); - goto error_out; - } - s = s->next; - } - } - if (s) - { - if (reloc_class == RTYPE_CLASS_TLS) - s->u.tls = tls; - else - s->u.ent = ent; - s->value = value[0]; - s->reloc_class = reloc_class; - s->next = NULL; - } - } - else if ((reloc_class == RTYPE_CLASS_TLS || ifunc) - && info->conflicts) - { - struct prelink_conflict *conflict; - int symowner; - size_t idx; - - for (symowner = 0; symowner < ndeps; symowner++) - if (deps[symowner].start == symstart) - break; - if (symowner == ndeps) - { - error (0, 0, "Could not find base 0x%08llx in the list of bases `%s'", - symstart, buffer); - goto error_out; - } - - idx = 0; - if (info->conflicts[symowner].hash != &info->conflicts[symowner].first) - idx = symoff % 251; - for (conflict = info->conflicts[symowner].hash[idx]; conflict; - conflict = conflict->next) - if (conflict->symoff == symoff - && conflict->reloc_class == reloc_class) - { - if ((reloc_class != RTYPE_CLASS_TLS - && (conflict->lookup.ent != ent - || conflict->conflict.ent != ent)) - || (reloc_class == RTYPE_CLASS_TLS - && (conflict->lookup.tls != tls - || conflict->conflict.tls != tls)) - || conflict->lookupval != value[0] - || conflict->conflictval != value[0]) - { - error (0, 0, "%s: Symbol `%s' with the same reloc type resolves to different values each time", - info->ent->filename, symname); - goto error_out; - } - break; - } - if (conflict == NULL) - { - conflict = malloc (sizeof (struct prelink_conflict)); - if (conflict == NULL) - { - error (0, ENOMEM, "Cannot build list of conflicts"); - goto error_out; - } - - conflict->next = info->conflicts[symowner].hash[idx]; - conflict->next2 = NULL; - info->conflicts[symowner].hash[idx] = conflict; - if (reloc_class != RTYPE_CLASS_TLS) - { - conflict->lookup.ent = ent; - conflict->conflict.ent = ent; - } - else - { - conflict->lookup.tls = tls; - conflict->conflict.tls = tls; - } - conflict->lookupval = value[0]; - conflict->conflictval = value[0]; - conflict->symoff = symoff; - conflict->reloc_class = reloc_class; - conflict->used = 0; - conflict->ifunc = ifunc; - conflict->symname = strdup(symname); - if (++info->conflicts[symowner].count == 16) - conflict_hash_init (&info->conflicts[symowner]); - } - } - } - else if (strncmp (buffer, "conflict ", sizeof ("conflict ") - 1) == 0) - { - if (sscanf (buffer, "conflict 0x%llx 0x%llx -> 0x%llx 0x%llx x 0x%llx 0x%llx %n", - &symstart, &symoff, &valstart[0], &value[0], - &valstart[1], &value[1], &len) != 6) - { - error (0, 0, "%s: Could not parse `%s'", info->ent->filename, buffer); - goto error_out; - } - - if (buffer[len] == '/') - { - ++len; - type = 0; - } - - reloc_class = strtoul (buffer + len, &symname, 16); - if (buffer + len == symname || (reloc_class == 0 && type) - || (*symname != ' ' && *symname != '\t')) - { - error (0, 0, "%s: Could not parse `%s'", info->ent->filename, buffer); - goto error_out; - } - - if (type) - reloc_class = dso->arch->reloc_class (reloc_class); - else - { - if (reloc_class & 8) - { - reloc_class = ((reloc_class & ~8) - | dso->arch->rtype_class_valid); - ifunc = 1; - } - else if ((reloc_class | RTYPE_CLASS_VALID) == RTYPE_CLASS_TLS) - reloc_class |= RTYPE_CLASS_VALID; - else - reloc_class |= dso->arch->rtype_class_valid; - } - - while (*symname == ' ' || *symname == '\t') ++symname; - - if (symstart == deps[0].start) - { - error (0, 0, "Conflict in _dl_loaded `%s'", buffer); - goto error_out; - } - - if (info->conflicts) - { - struct prelink_entry *ents[2]; - struct prelink_tls *tlss[2]; - struct prelink_conflict *conflict; - int symowner, j; - size_t idx; - - for (symowner = 1; symowner < ndeps; symowner++) - if (deps[symowner].start == symstart) - break; - if (symowner == ndeps) - { - error (0, 0, "Could not find base 0x%08llx in the list of bases `%s'", - symstart, buffer); - goto error_out; - } - - for (j = 0; j < 2; j++) - { - ents[j] = NULL; - tlss[j] = NULL; - for (i = 0; i < ndeps; i++) - if (deps[i].start == valstart[j]) - { - if (reloc_class == RTYPE_CLASS_TLS) - tlss[j] = info->tls + i; - else - { - ents[j] = deps[i].ent; - /* If the library the symbol is bound to is already - prelinked, adjust the value so that it is relative - to library base. */ - if (mask_32bit) - value[j] -= (Elf32_Addr) (deps[i].start - deps[i].l_addr); - else - value[j] -= deps[i].start - deps[i].l_addr; - } - break; - } - if (ents[j] == NULL && tlss[j] == NULL && valstart[j]) - { - error (0, 0, "Could not find base 0x%08llx in the list of bases `%s'", - valstart[j], buffer); - goto error_out; - } - } - - idx = 0; - if (info->conflicts[symowner].hash - != &info->conflicts[symowner].first) - idx = symoff % 251; - for (conflict = info->conflicts[symowner].hash[idx]; conflict; - conflict = conflict->next) - if (conflict->symoff == symoff - && conflict->reloc_class == reloc_class) - { - if ((reloc_class != RTYPE_CLASS_TLS - && (conflict->lookup.ent != ents[0] - || conflict->conflict.ent != ents[1])) - || (reloc_class == RTYPE_CLASS_TLS - && (conflict->lookup.tls != tlss[0] - || conflict->conflict.tls != tlss[1])) - || conflict->lookupval != value[0] - || conflict->conflictval != value[1]) - { - error (0, 0, "%s: Symbol `%s' with the same reloc type resolves to different values each time", - info->ent->filename, symname); - goto error_out; - } - break; - } - if (conflict == NULL) - { - conflict = malloc (sizeof (struct prelink_conflict)); - if (conflict == NULL) - { - error (0, ENOMEM, "Cannot build list of conflicts"); - goto error_out; - } - - conflict->next = info->conflicts[symowner].hash[idx]; - conflict->next2 = NULL; - info->conflicts[symowner].hash[idx] = conflict; - if (reloc_class != RTYPE_CLASS_TLS) - { - conflict->lookup.ent = ents[0]; - conflict->conflict.ent = ents[1]; - } - else - { - conflict->lookup.tls = tlss[0]; - conflict->conflict.tls = tlss[1]; - } - conflict->lookupval = value[0]; - conflict->conflictval = value[1]; - conflict->symoff = symoff; - conflict->reloc_class = reloc_class; - conflict->used = 0; - conflict->ifunc = ifunc; - conflict->symname = strdup(symname); - if (++info->conflicts[symowner].count == 16) - conflict_hash_init (&info->conflicts[symowner]); - } - } - } - else if (strncmp (buffer, "undefined symbol: ", - sizeof ("undefined symbol: ") - 1) == 0 && ! undef) - { - undef = 1; - if (verbose) - error (0, 0, "Warning: %s has undefined non-weak symbols", - info->ent->filename); - } - } while (fgets (buffer, 8192, f) != NULL); - - info->sonames = malloc (ndeps * sizeof (const char *)); - if (info->sonames == NULL) - { - error (0, ENOMEM, "%s: Could not record dependency SONAMEs", dso->filename); - goto error_out; - } - - for (i = 0; i < ndeps; i++) - info->sonames[i] = deps[i].soname; - - return 0; - -error_out: - for (i = 0; i < ndeps; i++) - free (deps[i].soname); - return 1; -} - -int -prelink_get_relocations (struct prelink_info *info) -{ - FILE *f; - DSO *dso = info->dso; - const char *argv[8]; - const char *envp[4]; - int i, ret, status; - char *p; - const char *dl = dynamic_linker ?: dso->arch->dynamic_linker; - const char *ent_filename; - int etype = info->dso->ehdr.e_type; - - if (info->ent->type == ET_DYN) - { - assert (info->ent->base == dso->base); - if (info->ent->end < dso->end) - { - error (0, 0, "%s: grew since it has been recorded", info->ent->filename); - return 0; - } - } - else - { - info->ent->base = dso->base; - info->ent->end = dso->end; - } - - if (is_ldso_soname (info->dso->soname)) - return 1; - - info->symbol_count = (info->symtab_end - info->symtab_start) - / info->symtab_entsize; - info->symbols = calloc (sizeof (struct prelink_symbol), info->symbol_count); - - if (strchr (info->ent->filename, '/') != NULL) - ent_filename = info->ent->filename; - else - { - size_t flen = strlen (info->ent->filename); - char *p = alloca (2 + flen + 1); - memcpy (p, "./", 2); - memcpy (p + 2, info->ent->filename, flen + 1); - ent_filename = p; - } - if (prelink_rtld == NULL) - { - i = 0; - argv[i++] = dl; - if (ld_library_path) - { - argv[i++] = "--library-path"; - argv[i++] = ld_library_path; - } - argv[i++] = ent_filename; - argv[i] = NULL; - envp[0] = "LD_TRACE_LOADED_OBJECTS=1"; - envp[1] = "LD_BIND_NOW=1"; - p = alloca (sizeof "LD_TRACE_PRELINKING=" + strlen (info->ent->filename)); - strcpy (stpcpy (p, "LD_TRACE_PRELINKING="), info->ent->filename); - envp[2] = p; - envp[3] = NULL; - ret = 2; - f = execve_open (dl, (char * const *)argv, (char * const *)envp); - } - else - { - i = 0; - argv[i++] = prelink_rtld; - if (ld_library_path) - { - argv[i++] = "--library-path"; - argv[i++] = ld_library_path; - } - - if(etype == ET_EXEC && ld_preload) { - argv[i++] = "--ld-preload"; - argv[i++] = ld_preload; - } - - argv[i++] = "--target-paths"; - argv[i++] = ent_filename; - argv[i] = NULL; - p = alloca (sizeof "RTLD_TRACE_PRELINKING=" + strlen (info->ent->filename)); - strcpy (stpcpy (p, "RTLD_TRACE_PRELINKING="), info->ent->filename); - envp[0] = p; - p = alloca (sizeof "PATH=" + strlen (getenv ("PATH"))); - sprintf (p, "PATH=%s", getenv ("PATH")); - envp[1] = p; - envp[2] = NULL; - if (sysroot) - { - p = alloca (sizeof "PRELINK_SYSROOT=" + strlen (sysroot)); - sprintf (p, "PRELINK_SYSROOT=%s", sysroot); - envp[2] = p; - envp[3] = NULL; - } - ret = 2; - f = execve_open (prelink_rtld, (char * const *)argv, (char * const *)envp); - } - - if (f == NULL) - { - error (0, errno, "%s: Could not trace symbol resolving", - info->ent->filename); - return 0; - } - - if (prelink_record_relocations (info, f, ent_filename)) - ret = 0; - - if ((status = execve_close (f))) - { - if (ret) - error (0, status == -1 ? errno : 0, - "%s Could not trace symbol resolving", info->ent->filename); - return 0; - } - - return ret; -} diff --git a/trunk/src/hashtab.c b/trunk/src/hashtab.c deleted file mode 100644 index fa27446..0000000 --- a/trunk/src/hashtab.c +++ /dev/null @@ -1,609 +0,0 @@ -/* An expandable hash tables datatype. - Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. - Contributed by Vladimir Makarov (vmakarov@cygnus.com). - -This file is part of the libiberty library. -Libiberty 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. - -Libiberty is distributed in the hope that 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 libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This package implements basic hash table functionality. It is possible - to search for an entry, create an entry and destroy an entry. - - Elements in the table are generic pointers. - - The size of the table is not fixed; if the occupancy of the table - grows too high the hash table will be expanded. - - The abstract data implementation is based on generalized Algorithm D - from Knuth's book "The art of computer programming". Hash table is - expanded by creation of new hash table and transferring elements from - the old table to the new table. */ - -#include <config.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include "hashtab.h" - -/* This macro defines reserved value for empty table entry. */ - -#define EMPTY_ENTRY ((void *) 0) - -/* This macro defines reserved value for table entry which contained - a deleted element. */ - -#define DELETED_ENTRY ((void *) 1) - -static unsigned long higher_prime_number (unsigned long); -static hashval_t hash_pointer (const void *); -static int eq_pointer (const void *, const void *); -static int htab_expand (htab_t); -static void **find_empty_slot_for_expand (htab_t, hashval_t); - -/* At some point, we could make these be NULL, and modify the - hash-table routines to handle NULL specially; that would avoid - function-call overhead for the common case of hashing pointers. */ -htab_hash htab_hash_pointer = hash_pointer; -htab_eq htab_eq_pointer = eq_pointer; - -/* The following function returns a nearest prime number which is - greater than N, and near a power of two. */ - -static unsigned long -higher_prime_number (n) - unsigned long n; -{ - /* These are primes that are near, but slightly smaller than, a - power of two. */ - static unsigned long primes[] = { - (unsigned long) 2, - (unsigned long) 7, - (unsigned long) 13, - (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), - }; - - unsigned long* low = &primes[0]; - unsigned long* high = &primes[sizeof(primes) / sizeof(primes[0])]; - - while (low != high) - { - unsigned long* mid = low + (high - low) / 2; - if (n > *mid) - low = mid + 1; - else - high = mid; - } - - /* If we've run out of primes, abort. */ - if (n > *low) - { - fprintf (stderr, "Cannot find prime bigger than %lu\n", n); - abort (); - } - - return *low; -} - -/* Returns a hash code for P. */ - -static hashval_t -hash_pointer (p) - const void * p; -{ - return (hashval_t) ((long)p >> 3); -} - -/* Returns non-zero if P1 and P2 are equal. */ - -static int -eq_pointer (p1, p2) - const void * p1; - const void * p2; -{ - return p1 == p2; -} - -/* This function creates table with length slightly longer than given - source length. The created hash table is initiated as empty (all the - hash table entries are EMPTY_ENTRY). The function returns the created - hash table. Memory allocation may fail; it may return NULL. */ - -htab_t -htab_try_create (size, hash_f, eq_f, del_f) - size_t size; - htab_hash hash_f; - htab_eq eq_f; - htab_del del_f; -{ - htab_t result; - - size = higher_prime_number (size); - result = (htab_t) calloc (1, sizeof (struct htab)); - if (result == NULL) - return NULL; - - result->entries = (void **) calloc (size, sizeof (void *)); - if (result->entries == NULL) - { - free (result); - return NULL; - } - - result->size = size; - result->hash_f = hash_f; - result->eq_f = eq_f; - result->del_f = del_f; - result->return_allocation_failure = 1; - return result; -} - -/* This function frees all memory allocated for given hash table. - Naturally the hash table must already exist. */ - -void -htab_delete (htab) - htab_t htab; -{ - int i; - - if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); - - free (htab->entries); - free (htab); -} - -/* This function clears all entries in the given hash table. */ - -void -htab_empty (htab) - htab_t htab; -{ - int i; - - if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); - - memset (htab->entries, 0, htab->size * sizeof (void *)); -} - -/* Similar to htab_find_slot, but without several unwanted side effects: - - Does not call htab->eq_f when it finds an existing entry. - - Does not change the count of elements/searches/collisions in the - hash table. - This function also assumes there are no deleted entries in the table. - HASH is the hash value for the element to be inserted. */ - -static void ** -find_empty_slot_for_expand (htab, hash) - htab_t htab; - hashval_t hash; -{ - size_t size = htab->size; - hashval_t hash2 = 1 + hash % (size - 2); - unsigned int index = hash % size; - - for (;;) - { - void **slot = htab->entries + index; - - if (*slot == EMPTY_ENTRY) - return slot; - else if (*slot == DELETED_ENTRY) - abort (); - - index += hash2; - if (index >= size) - index -= size; - } -} - -/* The following function changes size of memory allocated for the - entries and repeatedly inserts the table elements. The occupancy - of the table after the call will be about 50%. Naturally the hash - table must already exist. Remember also that the place of the - table entries is changed. If memory allocation failures are allowed, - this function will return zero, indicating that the table could not be - expanded. If all goes well, it will return a non-zero value. */ - -static int -htab_expand (htab) - htab_t htab; -{ - void **oentries; - void **olimit; - void **p; - - oentries = htab->entries; - olimit = oentries + htab->size; - - htab->size = higher_prime_number (htab->size * 2); - - if (htab->return_allocation_failure) - { - void **nentries = (void **) calloc (htab->size, sizeof (void **)); - if (nentries == NULL) - return 0; - htab->entries = nentries; - } - - htab->n_elements -= htab->n_deleted; - htab->n_deleted = 0; - - p = oentries; - do - { - void * x = *p; - - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) - { - void **q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x)); - - *q = x; - } - - p++; - } - while (p < olimit); - - free (oentries); - return 1; -} - -/* This function searches for a hash table entry equal to the given - element. It cannot be used to insert or delete an element. */ - -void * -htab_find_with_hash (htab, element, hash) - htab_t htab; - const void * element; - hashval_t hash; -{ - unsigned int index; - hashval_t hash2; - size_t size; - void * entry; - - htab->searches++; - size = htab->size; - index = hash % size; - - entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) - return entry; - - hash2 = 1 + hash % (size - 2); - - for (;;) - { - htab->collisions++; - index += hash2; - if (index >= size) - index -= size; - - entry = htab->entries[index]; - if (entry == EMPTY_ENTRY - || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) - return entry; - } -} - -/* Like htab_find_slot_with_hash, but compute the hash value from the - element. */ - -void * -htab_find (htab, element) - htab_t htab; - const void * element; -{ - return htab_find_with_hash (htab, element, (*htab->hash_f) (element)); -} - -/* This function searches for a hash table slot containing an entry - equal to the given element. To delete an entry, call this with - INSERT = 0, then call htab_clear_slot on the slot returned (possibly - after doing some checks). To insert an entry, call this with - INSERT = 1, then write the value you want into the returned slot. - When inserting an entry, NULL may be returned if memory allocation - fails. */ - -void ** -htab_find_slot_with_hash (htab, element, hash, insert) - htab_t htab; - const void * element; - hashval_t hash; - enum insert_option insert; -{ - void **first_deleted_slot; - unsigned int index; - hashval_t hash2; - size_t size; - - if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4 - && htab_expand (htab) == 0) - return NULL; - - size = htab->size; - hash2 = 1 + hash % (size - 2); - index = hash % size; - - htab->searches++; - first_deleted_slot = NULL; - - for (;;) - { - void * entry = htab->entries[index]; - if (entry == EMPTY_ENTRY) - { - if (insert == NO_INSERT) - return NULL; - - htab->n_elements++; - - if (first_deleted_slot) - { - *first_deleted_slot = EMPTY_ENTRY; - return first_deleted_slot; - } - - return &htab->entries[index]; - } - - if (entry == DELETED_ENTRY) - { - if (!first_deleted_slot) - first_deleted_slot = &htab->entries[index]; - } - else if ((*htab->eq_f) (entry, element)) - return &htab->entries[index]; - - htab->collisions++; - index += hash2; - if (index >= size) - index -= size; - } -} - -/* Like htab_find_slot_with_hash, but compute the hash value from the - element. */ - -void ** -htab_find_slot (htab, element, insert) - htab_t htab; - const void * element; - enum insert_option insert; -{ - return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element), - insert); -} - -/* This function deletes an element with the given value from hash - table. If there is no matching element in the hash table, this - function does nothing. */ - -void -htab_remove_elt (htab, element) - htab_t htab; - void * element; -{ - void **slot; - - slot = htab_find_slot (htab, element, NO_INSERT); - if (*slot == EMPTY_ENTRY) - return; - - if (htab->del_f) - (*htab->del_f) (*slot); - - *slot = DELETED_ENTRY; - htab->n_deleted++; -} - -/* This function clears a specified slot in a hash table. It is - useful when you've already done the lookup and don't want to do it - again. */ - -void -htab_clear_slot (htab, slot) - htab_t htab; - void **slot; -{ - if (slot < htab->entries || slot >= htab->entries + htab->size - || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY) - abort (); - - if (htab->del_f) - (*htab->del_f) (*slot); - - *slot = DELETED_ENTRY; - htab->n_deleted++; -} - -/* This function scans over the entire hash table calling - CALLBACK for each live entry. If CALLBACK returns false, - the iteration stops. INFO is passed as CALLBACK's second - argument. */ - -void -htab_traverse (htab, callback, info) - htab_t htab; - htab_trav callback; - void * info; -{ - void **slot = htab->entries; - void **limit = slot + htab->size; - - do - { - void * x = *slot; - - if (x != EMPTY_ENTRY && x != DELETED_ENTRY) - if (!(*callback) (slot, info)) - break; - } - while (++slot < limit); -} - -/* Return the current size of given hash table. */ - -size_t -htab_size (htab) - htab_t htab; -{ - return htab->size; -} - -/* Return the current number of elements in given hash table. */ - -size_t -htab_elements (htab) - htab_t htab; -{ - return htab->n_elements - htab->n_deleted; -} - -/* Return the fraction of fixed collisions during all work with given - hash table. */ - -double -htab_collisions (htab) - htab_t htab; -{ - if (htab->searches == 0) - return 0.0; - - return (double) htab->collisions / (double) htab->searches; -} - -#ifndef NDEBUG -void -htab_dump (htab, name, dumpfn) - htab_t htab; - const char *name; - htab_dumpfn dumpfn; -{ - FILE *f = fopen (name, "w"); - size_t i, j; - - if (f == NULL) - abort (); - fprintf (f, "size %zd n_elements %zd n_deleted %zd\n", - htab->size, htab->n_elements, htab->n_deleted); - for (i = 0; i < htab->size; ++i) - { - if (htab->entries [i] == EMPTY_ENTRY - || htab->entries [i] == DELETED_ENTRY) - { - for (j = i + 1; j < htab->size; ++j) - if (htab->entries [j] != htab->entries [i]) - break; - fprintf (f, "%c%zd\n", - htab->entries [i] == EMPTY_ENTRY ? 'E' : 'D', - j - i); - i = j - 1; - } - else - { - fputc ('V', f); - (*dumpfn) (f, htab->entries [i]); - } - } - fclose (f); -} - -void -htab_restore (htab, name, restorefn) - htab_t htab; - const char *name; - htab_restorefn restorefn; -{ - FILE *f = fopen (name, "r"); - size_t size, n_elements, n_deleted, i, j, k; - int c; - - if (f == NULL) - abort (); - if (fscanf (f, "size %zd n_elements %zd n_deleted %zd\n", - &size, &n_elements, &n_deleted) != 3) - abort (); - htab_empty (htab); - free (htab->entries); - htab->entries = (void **) calloc (size, sizeof (void *)); - if (htab->entries == NULL) - abort (); - htab->size = size; - htab->n_elements = n_elements; - htab->n_deleted = n_deleted; - for (i = 0; i < htab->size; ++i) - { - switch ((c = fgetc (f))) - { - case 'E': - case 'D': - if (fscanf (f, "%zd\n", &j) != 1) - abort (); - if (i + j > htab->size) - abort (); - if (c == 'D') - for (k = i; k < i + j; ++k) - htab->entries [k] = DELETED_ENTRY; - i += j - 1; - break; - case 'V': - htab->entries [i] = (*restorefn) (f); - break; - default: - abort (); - } - } - fclose (f); -} -#endif diff --git a/trunk/src/hashtab.h b/trunk/src/hashtab.h deleted file mode 100644 index 31e63e0..0000000 --- a/trunk/src/hashtab.h +++ /dev/null @@ -1,155 +0,0 @@ -/* An expandable hash tables datatype. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. - Contributed by Vladimir Makarov (vmakarov@cygnus.com). - -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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* This package implements basic hash table functionality. It is possible - to search for an entry, create an entry and destroy an entry. - - Elements in the table are generic pointers. - - The size of the table is not fixed; if the occupancy of the table - grows too high the hash table will be expanded. - - The abstract data implementation is based on generalized Algorithm D - from Knuth's book "The art of computer programming". Hash table is - expanded by creation of new hash table and transferring elements from - the old table to the new table. */ - -#ifndef __HASHTAB_H__ -#define __HASHTAB_H__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* The type for a hash code. */ -typedef unsigned int hashval_t; - -/* Callback function pointer types. */ - -/* Calculate hash of a table entry. */ -typedef hashval_t (*htab_hash) (const void *); - -/* Compare a table entry with a possible entry. The entry already in - the table always comes first, so the second element can be of a - different type (but in this case htab_find and htab_find_slot - cannot be used; instead the variants that accept a hash value - must be used). */ -typedef int (*htab_eq) (const void *, const void *); - -/* Cleanup function called whenever a live element is removed from - the hash table. */ -typedef void (*htab_del) (void *); - -/* Function called by htab_traverse for each live element. The first - arg is the slot of the element (which can be passed to htab_clear_slot - if desired), the second arg is the auxiliary pointer handed to - htab_traverse. Return 1 to continue scan, 0 to stop. */ -typedef int (*htab_trav) (void **, void *); - -/* Hash tables are of the following type. The structure - (implementation) of this type is not needed for using the hash - tables. All work with hash table should be executed only through - functions mentioned below. */ - -struct htab -{ - /* Pointer to hash function. */ - htab_hash hash_f; - - /* Pointer to comparison function. */ - htab_eq eq_f; - - /* Pointer to cleanup function. */ - htab_del del_f; - - /* Table itself. */ - void **entries; - - /* Current size (in entries) of the hash table */ - size_t size; - - /* Current number of elements including also deleted elements */ - size_t n_elements; - - /* Current number of deleted elements in the table */ - size_t n_deleted; - - /* The following member is used for debugging. Its value is number - of all calls of `htab_find_slot' for the hash table. */ - unsigned int searches; - - /* The following member is used for debugging. Its value is number - of collisions fixed for time of work with the hash table. */ - unsigned int collisions; - - /* This is non-zero if we are allowed to return NULL for function calls - that allocate memory. */ - int return_allocation_failure; -}; - -typedef struct htab *htab_t; - -/* An enum saying whether we insert into the hash table or not. */ -enum insert_option {NO_INSERT, INSERT}; - -/* The prototypes of the package functions. */ - -/* This function is like htab_create, but may return NULL if memory - allocation fails, and also signals that htab_find_slot_with_hash and - htab_find_slot are allowed to return NULL when inserting. */ -extern htab_t htab_try_create (size_t, htab_hash, htab_eq, htab_del); -extern void htab_delete (htab_t); -extern void htab_empty (htab_t); - -extern void *htab_find (htab_t, const void *); -extern void **htab_find_slot (htab_t, const void *, enum insert_option); -extern void *htab_find_with_hash (htab_t, const void *, hashval_t); -extern void **htab_find_slot_with_hash (htab_t, const void *, hashval_t, - enum insert_option); -extern void htab_clear_slot (htab_t, void **); -extern void htab_remove_elt (htab_t, void *); - -extern void htab_traverse (htab_t, htab_trav, void *); - -extern size_t htab_size (htab_t); -extern size_t htab_elements (htab_t); -extern double htab_collisions (htab_t); - -/* A hash function for pointers. */ -extern htab_hash htab_hash_pointer; - -/* An equality function for pointers. */ -extern htab_eq htab_eq_pointer; - -#ifndef NDEBUG - -#include <stdio.h> - -typedef void (*htab_dumpfn) (FILE *, const void *); -typedef void *(*htab_restorefn) (FILE *); - -extern void htab_dump (htab_t, const char *, htab_dumpfn); -extern void htab_restore (htab_t, const char *, htab_restorefn); - -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __HASHTAB_H */ diff --git a/trunk/src/layout.c b/trunk/src/layout.c deleted file mode 100644 index 859ab66..0000000 --- a/trunk/src/layout.c +++ /dev/null @@ -1,656 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2011 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <alloca.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <assert.h> -#include "prelinktab.h" -#include "layout.h" - -#ifndef NDEBUG -# define DEBUG_LAYOUT -#endif - -#ifdef DEBUG_LAYOUT -void -print_ent (struct prelink_entry *e) -{ - printf ("%s: %08x %08x/%08x\n", - e->filename, (int)e->base, (int)e->end, (int)e->layend); -} - -void -print_list (struct prelink_entry *e) -{ - for (; e; e = e->next) - print_ent (e); - printf ("\n"); -} -#endif - -static int -find_arches (void **p, void *info) -{ - struct layout_libs *l = (struct layout_libs *) info; - struct prelink_entry *e = * (struct prelink_entry **) p; - int i; - - if (e->type == ET_DYN || e->type == ET_EXEC - || e->type == ET_CACHE_DYN || e->type == ET_CACHE_EXEC) - { - for (i = 0; i < l->nbinlibs; ++i) - if ((l->binlibs[i]->flags & (PCF_ELF64 | PCF_MACHINE)) - == (e->flags & (PCF_ELF64 | PCF_MACHINE))) - return 1; - - l->binlibs[l->nbinlibs++] = e; - } - - return 1; -} - -static int -find_libs (void **p, void *info) -{ - struct layout_libs *l = (struct layout_libs *) info; - struct prelink_entry *e = * (struct prelink_entry **) p; - - if ((e->flags & (PCF_ELF64 | PCF_MACHINE)) != l->flags) - return 1; - - if (e->type == ET_DYN || e->type == ET_EXEC - || e->type == ET_CACHE_DYN || e->type == ET_CACHE_EXEC) - l->binlibs[l->nbinlibs++] = e; - if (e->type == ET_DYN || e->type == ET_CACHE_DYN) - l->libs[l->nlibs++] = e; - if (force) - e->done = 0; - if (e->type == ET_CACHE_DYN || e->type == ET_CACHE_EXEC) - e->done = 2; - if (e->base & (l->max_page_size - 1)) - { - e->done = 0; - e->end -= e->base; - e->base = 0; - } - - return 1; -} - -static int -refs_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - int i; - - /* Dynamic linkers first. */ - if (! a->ndepends && b->ndepends) - return -1; - if (a->ndepends && ! b->ndepends) - return 1; - /* Most widely used libraries first. */ - if (a->refs > b->refs) - return -1; - if (a->refs < b->refs) - return 1; - /* Largest libraries first. */ - if (a->layend - a->base > b->layend - b->base) - return -1; - if (a->layend - a->base < b->layend - b->base) - return 1; - if (a->refs) - { - i = strcmp (a->soname, b->soname); - if (i) - return i; - } - return strcmp (a->filename, b->filename); -} - -static int -refs_rnd_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - int i, refs; - - /* Dynamic linkers first. */ - if (! a->ndepends && b->ndepends) - return -1; - if (a->ndepends && ! b->ndepends) - return 1; - /* Most widely used libraries first with some randomization. */ - refs = a->refs < b->refs ? a->refs : b->refs; - if (refs < 8) - i = 1; - else if (refs < 32) - i = 2; - else if (refs < 128) - i = 4; - else - i = 8; - if (a->refs > b->refs && a->refs - b->refs >= i) - return -1; - if (a->refs < b->refs && b->refs - a->refs >= i) - return 1; - if (a->u.tmp < b->u.tmp) - return -1; - if (a->u.tmp > b->u.tmp) - return 1; - /* Largest libraries first. */ - if (a->layend - a->base > b->layend - b->base) - return -1; - if (a->layend - a->base < b->layend - b->base) - return 1; - if (a->refs && b->refs) - { - i = strcmp (a->soname, b->soname); - if (i) - return i; - } - return strcmp (a->filename, b->filename); -} - -static int -addr_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - - if (! a->done) - return b->done ? 1 : 0; - else if (! b->done) - return -1; - if (a->base < b->base) - return -1; - else if (a->base > b->base) - return 1; - if (a->layend < b->layend) - return -1; - else if (a->layend > b->layend) - return 1; - return 0; -} - -int deps_cmp (const void *A, const void *B) -{ - struct prelink_entry *a = * (struct prelink_entry **) A; - struct prelink_entry *b = * (struct prelink_entry **) B; - - if (a->base < b->base) - return -1; - if (a->base > b->base) - return 1; - return 0; -} - -int -layout_libs (void) -{ - struct layout_libs l; - int arch, *arches, narches; - struct prelink_entry **plibs, **pbinlibs; - - memset (&l, 0, sizeof (l)); - l.libs = plibs = - (struct prelink_entry **) alloca (prelink_entry_count - * sizeof (struct prelink_entry *)); - l.binlibs = pbinlibs = - (struct prelink_entry **) alloca (prelink_entry_count - * sizeof (struct prelink_entry *)); - htab_traverse (prelink_filename_htab, find_arches, &l); - narches = l.nbinlibs; - arches = (int *) alloca (narches * sizeof (int)); - for (arch = 0; arch < narches; ++arch) - arches[arch] = l.binlibs[arch]->flags & (PCF_ELF64 | PCF_MACHINE); - - for (arch = 0; arch < narches; ++arch) - { - struct PLArch *plarch; - extern struct PLArch __start_pl_arch[], __stop_pl_arch[]; - int i, j, k, m, done, class; - GElf_Addr mmap_start, mmap_base, mmap_end, mmap_fin, max_page_size; - GElf_Addr base, size; - struct prelink_entry *list, *e, *fake, **deps; - struct prelink_entry fakeent; - int fakecnt; - int (*layout_libs_pre) (struct layout_libs *l); - int (*layout_libs_post) (struct layout_libs *l); - - for (plarch = __start_pl_arch; plarch < __stop_pl_arch; plarch++) - if (plarch->class == (arches[arch] & PCF_ELF64 ? ELFCLASS64 : ELFCLASS32) - && plarch->machine == (arches[arch] & PCF_MACHINE)) - break; - - if (plarch == __stop_pl_arch) - error (EXIT_FAILURE, 0, "%d-bit ELF e_machine %04x not supported", - (arches[arch] & PCF_ELF64) ? 64 : 32, arches[arch] & PCF_MACHINE); - - list = NULL; - fake = NULL; - fakecnt = 0; - memset (&l, 0, sizeof (l)); - l.flags = arches[arch]; - l.libs = plibs; - l.binlibs = pbinlibs; - max_page_size = plarch->max_page_size; - if (layout_page_size > max_page_size) - max_page_size = layout_page_size; - l.max_page_size = max_page_size; - htab_traverse (prelink_filename_htab, find_libs, &l); - - /* Make sure there is some room between libraries. */ - for (i = 0; i < l.nlibs; ++i) - l.libs[i]->layend = (l.libs[i]->end + 8192 + max_page_size - 1) - & ~(max_page_size - 1); - - if (plarch->layout_libs_init) - { - plarch->layout_libs_init (&l); - mmap_base = l.mmap_base; - mmap_end = l.mmap_end; - } - else - { - mmap_base = plarch->mmap_base; - mmap_end = plarch->mmap_end; - } - if (mmap_reg_start != ~(GElf_Addr) 0) - mmap_base = mmap_reg_start; - if (mmap_reg_end != ~(GElf_Addr) 0) - mmap_end = mmap_reg_end; - if (mmap_base >= mmap_end) - error (EXIT_FAILURE, 0, - "--mmap-region-start cannot be bigger than --mmap-region-end"); - if ((mmap_base | mmap_end) & (max_page_size - 1)) - error (EXIT_FAILURE, 0, "--layout-page-size too large"); - class = plarch->class; - /* The code below relies on having a VA slot as big as <mmap_base,mmap_end) - above mmap_end for -R. */ - if (mmap_end + (mmap_end - mmap_base) <= mmap_end) - random_base = 0; - layout_libs_pre = plarch->layout_libs_pre; - layout_libs_post = plarch->layout_libs_post; - - deps = (struct prelink_entry **) - alloca (l.nlibs * sizeof (struct prelink_entry *)); - - /* Now see which already prelinked libraries have to be - re-prelinked to avoid overlaps. */ - for (i = 0; i < l.nbinlibs; ++i) - { - for (j = 0, k = 0; j < l.binlibs[i]->ndepends; ++j) - if (l.binlibs[i]->depends[j]->type == ET_DYN - && l.binlibs[i]->depends[j]->done) - { - assert (k < l.nlibs); - deps[k++] = l.binlibs[i]->depends[j]; - } - if (k) - { - qsort (deps, k, sizeof (struct prelink_entry *), deps_cmp); - for (j = 1; j < k; ++j) - if (deps[j]->base < deps[j - 1]->end - && (deps[j]->type == ET_DYN - || deps[j - 1]->type == ET_DYN)) - { - if (deps[j - 1]->refs < deps[j]->refs) - --j; - deps[j]->done = 0; - --k; - memmove (deps + j, deps + j + 1, (k - j) * sizeof (*deps)); - if (j > 0) - --j; - } - } - } - - /* If layout_libs_init or the for cycle above cleared - done flags for some libraries, make sure all libraries - that depend on them are re-prelinked as well. */ - for (i = 0; i < l.nlibs; ++i) - if (l.libs[i]->done) - for (j = 0; j < l.libs[i]->ndepends; ++j) - if (l.libs[i]->depends[j]->done == 0) - { - l.libs[i]->done = 0; - break; - } - - /* Put the already prelinked libs into double linked list. */ - qsort (l.libs, l.nlibs, sizeof (struct prelink_entry *), addr_cmp); - for (i = 0; i < l.nlibs; ++i) - if (! l.libs[i]->done || l.libs[i]->layend >= mmap_base) - break; - j = 0; - if (i < l.nlibs && l.libs[i]->done) - { - if (l.libs[i]->base < mmap_base) - random_base = 0; - for (j = i + 1; j < l.nlibs; ++j) - { - if (! l.libs[j]->done || l.libs[j]->base >= mmap_end) - break; - - if (l.libs[j]->base < mmap_base || l.libs[j]->layend > mmap_end) - random_base = 0; - l.libs[j]->prev = l.libs[j - 1]; - l.libs[j - 1]->next = l.libs[j]; - } - list = l.libs[i]; - list->prev = l.libs[j - 1]; - while (j < l.nlibs && l.libs[j]->done) ++j; - } - - mmap_start = mmap_base; - mmap_fin = mmap_end; - done = 1; - if (random_base & 2) - { - mmap_start = seed; - if (mmap_start < mmap_base || mmap_start >= mmap_end) - mmap_start = mmap_base; - - mmap_start = (mmap_start + max_page_size - 1) & ~(max_page_size - 1); - } - else if (random_base) - { - int fd = open ("/dev/urandom", O_RDONLY); - - mmap_start = 0; - if (fd != -1) - { - GElf_Addr x; - - if (read (fd, &x, sizeof (x)) == sizeof (x)) - { - mmap_start = x % (mmap_end - mmap_base); - mmap_start += mmap_base; - } - - fsync (fd); - close (fd); - } - - if (! mmap_start) - { - mmap_start = ((mmap_end - mmap_base) >> 16) - * (time (NULL) & 0xffff); - mmap_start += mmap_base; - } - - seed = mmap_start; - mmap_start = (mmap_start + max_page_size - 1) & ~(max_page_size - 1); - } - if (random_base) - { - srandom (mmap_start >> 12); - for (i = 0; i < l.nlibs; ++i) - l.libs[i]->u.tmp = random (); - qsort (l.libs, l.nlibs, sizeof (struct prelink_entry *), refs_rnd_cmp); - } - else - qsort (l.libs, l.nlibs, sizeof (struct prelink_entry *), refs_cmp); - - if (verbose && l.nlibs > j) - { - printf ("Laying out %d libraries in virtual address space %0*llx-%0*llx\n", - l.nlibs - j, class == ELFCLASS32 ? 8 : 16, (long long) mmap_base, - class == ELFCLASS32 ? 8 : 16, (long long) mmap_end); - if (mmap_start != mmap_base) - printf ("Random base 0x%0*llx\n", class == ELFCLASS32 ? 8 : 16, - (long long) mmap_start); - } - - if (layout_libs_pre) - { - l.list = list; - l.mmap_base = mmap_base; - l.mmap_start = mmap_start; - l.mmap_end = mmap_end; - layout_libs_pre (&l); - list = l.list; - mmap_base = l.mmap_base; - mmap_start = l.mmap_start; - mmap_fin = l.mmap_fin; - mmap_end = l.mmap_end; - fake = l.fake; - fakecnt = l.fakecnt; - } - - if (mmap_start != mmap_base && list) - { - for (e = list; e != NULL; e = e->next) - { - if (e->base >= mmap_start) - break; - if (e->layend > mmap_start) - mmap_start = (e->layend + max_page_size - 1) - & ~(max_page_size - 1); - e->base += mmap_end - mmap_base; - e->end += mmap_end - mmap_base; - e->layend += mmap_end - mmap_base; - e->done |= 0x80; - } - - if (mmap_start < mmap_end) - { - if (e && e != list) - { - memset (&fakeent, 0, sizeof (fakeent)); - fakeent.u.tmp = -1; - fakeent.base = mmap_end; - fakeent.end = mmap_end; - fakeent.layend = mmap_end; - fake = &fakeent; - fakecnt = 1; - fakeent.prev = list->prev; - fakeent.next = list; - list->prev = fake; - fakeent.prev->next = fake; - list = e; - e->prev->next = NULL; - } - } - else - { - mmap_start = mmap_base; - for (e = list; e != NULL; e = e->next) - if (e->done & 0x80) - { - e->done &= ~0x80; - e->base -= mmap_end - mmap_base; - e->end -= mmap_end - mmap_base; - e->layend -= mmap_end - mmap_base; - } - } - } - - if (mmap_start != mmap_base) - { - done |= 0x80; - mmap_fin = mmap_end + (mmap_start - mmap_base); - } - - for (i = 0; i < l.nlibs; ++i) - l.libs[i]->u.tmp = -1; - m = -1; - - for (i = 0; i < l.nlibs; ++i) - if (! l.libs[i]->done) - { - if (conserve_memory) - { - /* If conserving virtual address space, only consider libraries - which ever appear together with this one. Otherwise consider - all libraries. */ - m = i; - for (j = 0; j < l.nbinlibs; ++j) - { - for (k = 0; k < l.binlibs[j]->ndepends; ++k) - if (l.binlibs[j]->depends[k] == l.libs[i]) - { - for (k = 0; k < l.binlibs[j]->ndepends; ++k) - l.binlibs[j]->depends[k]->u.tmp = m; - break; - } - } - for (j = 0; j < fakecnt; ++j) - fake[j].u.tmp = m; - } - - size = l.libs[i]->layend - l.libs[i]->base; - base = mmap_start; - for (e = list; e; e = e->next) - if (e->u.tmp == m) - { - if (base + size <= e->base) - goto found; - - if (base < e->layend) - base = e->layend; - } - - if (base + size > mmap_fin) - goto not_found; -found: - l.libs[i]->end += base - l.libs[i]->base; - l.libs[i]->base = base; - l.libs[i]->layend = base + size; - if (base >= mmap_end) - l.libs[i]->done = done; - else - l.libs[i]->done = 1; - if (list == NULL) - { - list = l.libs[i]; - list->prev = list; - } - else - { - if (e == NULL) - e = list->prev; - else - e = e->prev; - while (e != list && e->base > base) - e = e->prev; - if (e->base > base) - { - l.libs[i]->next = list; - l.libs[i]->prev = list->prev; - list->prev = l.libs[i]; - list = l.libs[i]; - } - else - { - l.libs[i]->next = e->next; - l.libs[i]->prev = e; - if (e->next) - e->next->prev = l.libs[i]; - else - list->prev = l.libs[i]; - e->next = l.libs[i]; - } - } -#ifdef DEBUG_LAYOUT - { - struct prelink_entry *last = list; - base = 0; - for (e = list; e; last = e, e = e->next) - { - if (e->base < base) - abort (); - base = e->base; - if ((e == list && e->prev->next != NULL) - || (e != list && e->prev->next != e)) - abort (); - } - if (list->prev != last) - abort (); - } -#endif - continue; - -not_found: - error (EXIT_FAILURE, 0, "Could not find virtual address slot for %s", - l.libs[i]->filename); - } - - if (layout_libs_post) - { - l.list = list; - layout_libs_post (&l); - } - - if (done & 0x80) - for (e = list; e != NULL; e = e->next) - if (e->done & 0x80) - { - e->done &= ~0x80; - e->base -= mmap_end - mmap_base; - e->end -= mmap_end - mmap_base; - e->layend -= mmap_base - mmap_base; - } - - if (verbose) - { - if (narches == 1) - printf ("Assigned virtual address space slots for libraries:\n"); - else - printf ("Assigned virtual address space slots for %d-bit %s ELF libraries:\n", - class == ELFCLASS32 ? 32 : 64, plarch->name); - - for (i = 0; i < l.nlibs; ++i) - if (l.libs[i]->done >= 1) - printf ("%-60s %0*llx-%0*llx\n", l.libs[i]->filename, - class == ELFCLASS32 ? 8 : 16, (long long) l.libs[i]->base, - class == ELFCLASS32 ? 8 : 16, (long long) l.libs[i]->end); - } - -#ifdef DEBUG_LAYOUT - for (i = 0; i < l.nbinlibs; ++i) - { - for (j = 0; j < l.binlibs[i]->ndepends; ++j) - if ((l.binlibs[i]->depends[j]->type != ET_DYN - && l.binlibs[i]->depends[j]->type != ET_CACHE_DYN) - || l.binlibs[i]->depends[j]->done == 0) - break; - if (j < l.binlibs[i]->ndepends) - continue; - memcpy (deps, l.binlibs[i]->depends, - l.binlibs[i]->ndepends * sizeof (struct prelink_entry *)); - qsort (deps, l.binlibs[i]->ndepends, sizeof (struct prelink_entry *), - deps_cmp); - for (j = 1; j < l.binlibs[i]->ndepends; ++j) - if (deps[j]->base - < ((deps[j - 1]->end + max_page_size - 1) - & ~(max_page_size - 1)) - && (deps[j]->type == ET_DYN || deps[j - 1]->type == ET_DYN)) - abort (); - } -#endif - } - - return 0; -} diff --git a/trunk/src/layout.h b/trunk/src/layout.h deleted file mode 100644 index f481d22..0000000 --- a/trunk/src/layout.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2001, 2004, 2006 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef LAYOUT_H -#define LAYOUT_H - -struct layout_libs - { - struct prelink_entry **libs; - struct prelink_entry **binlibs; - struct prelink_entry *list; - struct prelink_entry *fake; - GElf_Addr mmap_base, mmap_start, mmap_fin, mmap_end, max_page_size; - void *arch_data; - int flags; - int nlibs; - int nbinlibs; - int fakecnt; - }; - -#endif /* LAYOUT_H */ diff --git a/trunk/src/main.c b/trunk/src/main.c deleted file mode 100644 index c879d62..0000000 --- a/trunk/src/main.c +++ /dev/null @@ -1,570 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2010, 2011 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <locale.h> -#include <error.h> -#include <argp.h> -#include <stdlib.h> -#include <unistd.h> - -#include "prelink.h" - -#define PRELINK_CONF "/etc/prelink.conf" -#define PRELINK_CACHE "/etc/prelink.cache" - -int all; -int force; -int verbose; -int print_cache; -int reloc_only; -GElf_Addr reloc_base; -int no_update; -int random_base; -int conserve_memory; -int libs_only; -int dry_run; -int dereference; -int one_file_system; -int enable_cxx_optimizations = 1; -int exec_shield; -int undo, verify; -enum verify_method_t verify_method; -int quick; -int compute_checksum; -long long seed; -GElf_Addr mmap_reg_start = ~(GElf_Addr) 0; -GElf_Addr mmap_reg_end = ~(GElf_Addr) 0; -GElf_Addr layout_page_size = 0; -const char *dynamic_linker; -const char *ld_library_path; -const char *prelink_conf = PRELINK_CONF; -const char *prelink_cache = PRELINK_CACHE; -const char *undo_output; -char *ld_preload = NULL; -int noreexecinit; -time_t initctime; - -const char *argp_program_version = PRELINK_PROG PKGVERSION " 1.0"; - -const char *argp_program_bug_address = REPORT_BUGS_TO; - -static char argp_doc[] = PRELINK_PROG " -- program to relocate and prelink ELF shared libraries and programs"; - -#define OPT_DYNAMIC_LINKER 0x80 -#define OPT_LD_LIBRARY_PATH 0x81 -#define OPT_LIBS_ONLY 0x82 -#define OPT_CXX_DISABLE 0x83 -#define OPT_MMAP_REG_START 0x84 -#define OPT_MMAP_REG_END 0x85 -#define OPT_EXEC_SHIELD 0x86 -#define OPT_NO_EXEC_SHIELD 0x87 -#define OPT_SEED 0x88 -#define OPT_MD5 0x89 -#define OPT_SHA 0x8a -#define OPT_COMPUTE_CHECKSUM 0x8b -#define OPT_LAYOUT_PAGE_SIZE 0x8c -#define OPT_SYSROOT 0x8d -#define OPT_RTLD 0x8e -#define OPT_ALLOW_TEXTREL 0x8f -#define OPT_LD_PRELOAD 0x90 - -static struct argp_option options[] = { - {"all", 'a', 0, 0, "Prelink all binaries" }, - {"black-list", 'b', "PATH", 0, "Blacklist path" }, - {"cache-file", 'C', "CACHE", 0, "Use CACHE as cache file" }, - {"config-file", 'c', "CONF", 0, "Use CONF as configuration file" }, - {"force", 'f', 0, 0, "Force prelinking" }, - {"dereference", 'h', 0, 0, "Follow symlinks when processing directory trees from command line" }, - {"one-file-system", 'l', 0, 0, "Stay in local file system when processing directories from command line" }, - {"conserve-memory", 'm', 0, 0, "Allow libraries to overlap as long as they never appear in the same program" }, - {"no-update-cache", 'N', 0, 0, "Don't update prelink cache" }, - {"dry-run", 'n', 0, 0, "Don't actually prelink anything" }, - {"undo-output", 'o', "FILE", 0, "Undo output file" }, - {"print-cache", 'p', 0, 0, "Print prelink cache" }, - {"quick", 'q', 0, 0, "Quick scan" }, - {"random", 'R', 0, 0, "Choose random base for libraries" }, - {"reloc-only", 'r', "BASE_ADDRESS", 0, "Relocate library to given address, don't prelink" }, - {"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" }, - {"undo", 'u', 0, 0, "Undo prelink" }, - {"verbose", 'v', 0, 0, "Produce verbose output" }, - {"verify", 'y', 0, 0, "Verify file consistency by undoing and redoing prelink and printing original to standard output" }, - {"md5", OPT_MD5, 0, 0, "For verify print MD5 sum of original to standard output instead of content" }, - {"sha", OPT_SHA, 0, 0, "For verify print SHA sum of original to standard output instead of content" }, - {"dynamic-linker", OPT_DYNAMIC_LINKER, "DYNAMIC_LINKER", - 0, "Special dynamic linker path" }, - {"exec-shield", OPT_EXEC_SHIELD, 0, 0, "Lay out libraries for exec-shield on IA-32" }, - {"no-exec-shield", OPT_NO_EXEC_SHIELD, 0, 0, "Don't lay out libraries for exec-shield on IA-32" }, - {"ld-library-path", OPT_LD_LIBRARY_PATH, "PATHLIST", - 0, "What LD_LIBRARY_PATH should be used" }, - {"ld-preload", OPT_LD_PRELOAD, "PATHLIST", 0, "What LD_PRELOAD should be used" }, - {"libs-only", OPT_LIBS_ONLY, 0, 0, "Prelink only libraries, no binaries" }, - {"layout-page-size", OPT_LAYOUT_PAGE_SIZE, "SIZE", 0, "Layout start of libraries at given boundary" }, - {"disable-c++-optimizations", OPT_CXX_DISABLE, 0, OPTION_HIDDEN, "" }, - {"mmap-region-start", OPT_MMAP_REG_START, "BASE_ADDRESS", OPTION_HIDDEN, "" }, - {"mmap-region-end", OPT_MMAP_REG_END, "BASE_ADDRESS", OPTION_HIDDEN, "" }, - {"seed", OPT_SEED, "SEED", OPTION_HIDDEN, "" }, - {"compute-checksum", OPT_COMPUTE_CHECKSUM, 0, OPTION_HIDDEN, "" }, - {"rtld", OPT_RTLD, "RTLD", OPTION_HIDDEN, "" }, - {"init", 'i', 0, 0, "Do not re-execute init" }, - {"allow-textrel", OPT_ALLOW_TEXTREL, 0, 0, "Allow text relocations even on architectures where they may not work" }, - { 0 } -}; - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - char *endarg; - - switch (key) - { - case 'a': - all = 1; - break; - case 'b': - if (add_to_blacklist (arg, dereference, one_file_system)) - exit (EXIT_FAILURE); - break; - case 'f': - force = 1; - break; - case 'p': - print_cache = 1; - break; - case 'q': - quick = 1; - break; - case 'v': - ++verbose; - break; - case 'R': - random_base |= 1; - break; - case OPT_SEED: - random_base |= 2; - seed = strtoull (arg, &endarg, 0); - if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "--seed option requires numberic argument"); - break; - case 'r': - reloc_only = 1; - reloc_base = strtoull (arg, &endarg, 0); - if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "-r option requires numberic argument"); - break; - case 'h': - dereference = 1; - break; - case 'l': - one_file_system = 1; - break; - case 'm': - conserve_memory = 1; - break; - case 'N': - no_update = 1; - break; - case 'n': - dry_run = 1; - break; - case 'C': - prelink_cache = arg; - break; - case 'c': - prelink_conf = arg; - break; - case 'u': - undo = 1; - break; - case 'y': - verify = 1; - break; - case 'o': - undo_output = arg; - break; - case OPT_DYNAMIC_LINKER: - dynamic_linker = arg; - break; - case OPT_LD_LIBRARY_PATH: - ld_library_path = arg; - break; - case OPT_LIBS_ONLY: - libs_only = 1; - break; - case OPT_MD5: - verify_method = VERIFY_MD5; - break; - case OPT_SHA: - verify_method = VERIFY_SHA; - break; - case OPT_CXX_DISABLE: - enable_cxx_optimizations = 0; - break; - case OPT_MMAP_REG_START: - mmap_reg_start = strtoull (arg, &endarg, 0); - if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "--mmap-region-start option requires numberic argument"); - break; - case OPT_MMAP_REG_END: - mmap_reg_end = strtoull (arg, &endarg, 0); - if (endarg != strchr (arg, '\0')) - error (EXIT_FAILURE, 0, "--mmap-region-end option requires numberic argument"); - break; - case OPT_EXEC_SHIELD: - exec_shield = 1; - break; - case OPT_NO_EXEC_SHIELD: - exec_shield = 0; - break; - case OPT_COMPUTE_CHECKSUM: - compute_checksum = 1; - break; - case OPT_LAYOUT_PAGE_SIZE: - layout_page_size = strtoull (arg, &endarg, 0); - if (endarg != strchr (arg, '\0') || (layout_page_size & (layout_page_size - 1))) - error (EXIT_FAILURE, 0, "--layout-page-size option requires numberic power-of-two argument"); - case OPT_SYSROOT: - sysroot = arg; - break; - case OPT_RTLD: - prelink_rtld = arg; - break; - case 'i': - noreexecinit=1; - break; - case OPT_ALLOW_TEXTREL: - allow_bad_textrel = 1; - break; - case OPT_LD_PRELOAD: - ld_preload = arg; - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -time_t get_ctime(const char *file) { - struct stat st; - if(stat(file,&st) == 0) - return st.st_ctime; - return 0; -} - -void checkinit() { - if(initctime != get_ctime("/sbin/init")) { - printf("Executing /sbin/init U\n"); - system("/sbin/init U"); - } -} - -static struct argp argp = { options, parse_opt, "[FILES]", argp_doc }; - -const char *prelink_rtld = NULL; - -/* Disable detection, this is not appropriate when cross prelinking. */ -#if 0 && (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) -static void -set_default_layout_page_size (void) -{ - /* From gcc.dg/20020523-1.c test in gcc 3.2 testsuite. */ - int fl1, fl2; - -#ifndef __x86_64__ - /* See if we can use cpuid. */ - __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" - "pushl %0; popfl; pushfl; popl %0; popfl" - : "=&r" (fl1), "=&r" (fl2) - : "i" (0x00200000)); - if (((fl1 ^ fl2) & 0x00200000) == 0) - return; -#define cpuid(fl1, fl2, fn) \ - __asm__ ("movl %%ebx, %1; cpuid; xchgl %%ebx, %1" \ - : "=a" (fl1), "=r" (fl2) : "0" (fn) : "ecx", "edx") -#else -#define cpuid(fl1, fl2, fn) \ - __asm__ ("cpuid" : "=a" (fl1), "=b" (fl2) : "0" (fn) : "ecx", "edx") -#endif - - /* See if CPUID gives capabilities. */ - cpuid (fl1, fl2, 0); - if (fl1 < 1 || fl2 != 0x68747541 /* Auth - AMD */) - return; - - /* CPUID 1. */ - cpuid (fl1, fl2, 1); - if (((fl1 >> 8) & 0x0f) + ((fl1 >> 20) & 0xff) == 0x15 /* Family */) - /* On AMD Bulldozer CPUs default to --layout-page-size=0x8000. */ - layout_page_size = 0x8000; -} -#else -# define set_default_layout_page_size() -#endif - -int -main (int argc, char *argv[]) -{ - int remaining, failures = 0; - - setlocale (LC_ALL, ""); - - exec_shield = 2; - - set_default_layout_page_size (); - - prelink_init_cache (); - - elf_version (EV_CURRENT); - - argp_parse (&argp, argc, argv, 0, &remaining, 0); - - if(!noreexecinit) { - initctime = get_ctime("/sbin/init"); - atexit(checkinit); - } - - if (ld_library_path == NULL) - ld_library_path = getenv ("LD_LIBRARY_PATH"); - - if (all && reloc_only) - error (EXIT_FAILURE, 0, "--all and --reloc-only options are incompatible"); - if ((undo || verify) && reloc_only) - error (EXIT_FAILURE, 0, "--undo and --reloc-only options are incompatible"); - if (verify && (undo || all)) - error (EXIT_FAILURE, 0, "--verify and either --undo or --all options are incompatible"); - if (dry_run && verify) - error (EXIT_FAILURE, 0, "--dry-run and --verify options are incompatible"); - if ((undo || verify) && quick) - error (EXIT_FAILURE, 0, "--undo and --quick options are incompatible"); - - /* Set the default for exec_shield. */ - if (exec_shield == 2) - { - if (sysroot == NULL && ! access ("/proc/sys/kernel/exec-shield", F_OK)) - exec_shield = 1; - else - exec_shield = 0; - } - -#ifdef DEFAULT_SYSROOT - if (sysroot == NULL) - { - extern char *make_relative_prefix (const char *, const char *, const char *); - sysroot = make_relative_prefix (argv[0], BINDIR, DEFAULT_SYSROOT); - } -#endif - - if (sysroot) - { - sysroot = canonicalize_file_name (sysroot); - if (sysroot == NULL) - error (EXIT_FAILURE, 0, "Could not canonicalize --root argument"); - asprintf ((char **) &prelink_conf, "%s%s", sysroot, prelink_conf); - } - if (prelink_rtld != NULL && prelink_rtld[0] == 0) - prelink_rtld = NULL; - else - if (prelink_rtld == NULL) - { - extern char *make_relative_prefix (const char *, const char *, const char *); - const char *path = make_relative_prefix (argv[0], BINDIR, BINDIR); - asprintf ((char **) &prelink_rtld, "%s/%s", path, - PRELINK_RTLD_PROG EXEEXT); - } - - if (print_cache) - { - prelink_load_cache (); - prelink_print_cache (); - return 0; - } - - if (remaining == argc && ! all) - error (EXIT_FAILURE, 0, "no files given and --all not used"); - - if (undo_output && (!undo || all)) - error (EXIT_FAILURE, 0, "-o can be only specified together with -u and without -a"); - - if (undo_output && remaining + 1 != argc) - error (EXIT_FAILURE, 0, "-o can only be used when undoing a single object"); - - if (compute_checksum) - { - while (remaining < argc) - { - DSO *dso = open_dso (argv[remaining++]); - - if (dso == NULL || reopen_dso (dso, NULL, NULL) - || prelink_set_checksum (dso)) - error (0, 0, "could not recompute checksum of %s", dso->filename); - close_dso (dso); - error (0, 0, "%08x %s\n", (unsigned int) dso->info_DT_CHECKSUM, dso->filename); - } - exit (0); - } - - if (verify) - { - if (remaining + 1 != argc) - error (EXIT_FAILURE, 0, "only one library or binary can be verified in a single command"); - return prelink_verify (argv[remaining]); - } - - if (reloc_only || (undo && ! all)) - { - while (remaining < argc) - { - DSO *dso = open_dso (argv[remaining++]); - int ret; - - if (dso == NULL) - { - ++failures; - continue; - } - - if (dso->ehdr.e_type != ET_DYN - && (reloc_only || dso->ehdr.e_type != ET_EXEC)) - { - ++failures; - error (0, 0, "%s is not a shared library", dso->filename); - continue; - } - - if (undo) - ret = prelink_undo (dso); - else - ret = relocate_dso (dso, reloc_base); - - if (ret) - { - ++failures; - close_dso (dso); - continue; - } - - if (dynamic_info_is_set (dso, DT_CHECKSUM_BIT) - && dso_is_rdwr (dso) - && prelink_set_checksum (dso)) - { - ++failures; - close_dso (dso); - continue; - } - - if (dry_run) - { - close_dso (dso); - continue; - } - - if (reloc_only) - dso->permissive = 1; - else if (undo_output) - { - const char *output, *orig_filename; - - if (!dso_is_rdwr (dso)) - { - struct stat64 st; - int err; - - if (fstat64 (dso->fd, &st) < 0) - { - error (0, errno, "Could not stat %s", dso->filename); - ++failures; - close_dso (dso); - continue; - } - err = copy_fd_to_file (dso->fd, undo_output, &st); - if (err) - { - error (0, err, "Could not undo %s to %s", dso->filename, - undo_output); - ++failures; - } - close_dso (dso); - continue; - } - - output = strdup (undo_output); - if (!output) - { - ++failures; - close_dso (dso); - continue; - } - if (dso->filename != dso->soname) - orig_filename = dso->filename; - else - orig_filename = strdup (dso->filename); - if (!orig_filename) - { - ++failures; - close_dso (dso); - continue; - } - dso->filename = output; - if (update_dso (dso, orig_filename)) - ++failures; - free ((char *) orig_filename); - continue; - } - - if (update_dso (dso, NULL)) - ++failures; - } - - return failures; - } - - if (read_config (prelink_conf)) - return EXIT_FAILURE; - - if (blacklist_from_config ()) - return EXIT_FAILURE; - - if (quick) - prelink_load_cache (); - - if (gather_config ()) - return EXIT_FAILURE; - - while (remaining < argc) - if (gather_object (argv[remaining++], dereference, one_file_system)) - return EXIT_FAILURE; - - if (gather_check_libs ()) - return EXIT_FAILURE; - - if (undo) - return undo_all (); - - if (! all && ! quick) - prelink_load_cache (); - - layout_libs (); - prelink_all (); - - if (! no_update && ! dry_run) - prelink_save_cache (all); - return 0; -} diff --git a/trunk/src/makecrc.c b/trunk/src/makecrc.c deleted file mode 100644 index db52013..0000000 --- a/trunk/src/makecrc.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Not copyrighted 1990 Mark Adler */ - -#ifndef lint -static char rcsid[] = "$Id: makecrc.c,v 0.6 1993/05/28 07:42:59 jloup Exp $"; -#endif - -#include <stdio.h> - -main() -/* - Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all - the information needed to generate CRC's on data a byte at a time for all - combinations of CRC register values and incoming bytes. The table is - written to stdout as 256 long hexadecimal values in C language format. -*/ -{ - unsigned long c; /* crc shift register */ - unsigned long e; /* polynomial exclusive-or pattern */ - int i; /* counter for all possible eight bit values */ - int k; /* byte being shifted into crc apparatus */ - - /* terms of polynomial defining this crc (except x^32): */ - static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* Make exclusive-or pattern from polynomial (0xedb88320) */ - e = 0; - for (i = 0; i < sizeof(p)/sizeof(int); i++) - e |= 1L << (31 - p[i]); - - /* Compute and print table of CRC's, five per line */ - printf(" 0x00000000"); - for (i = 1; i < 256; i++) - { - c = i; - /* The idea to initialize the register with the byte instead of - * zero was stolen from Haruhiko Okumura's ar002 - */ - for (k = 8; k; k--) - c = c & 1 ? (c >> 1) ^ e : c >> 1; - printf(i % 5 ? ", 0x%08lx" : ",\n 0x%08lx", c); - } - putchar('\n'); - return 0; -} diff --git a/trunk/src/md5.c b/trunk/src/md5.c deleted file mode 100644 index 0d2fdef..0000000 --- a/trunk/src/md5.c +++ /dev/null @@ -1,362 +0,0 @@ -/* md5.c - Functions to compute MD5 message digest of files or memory blocks - according to the definition of MD5 in RFC 1321 from April 1992. - Copyright (C) 1995, 1996, 2001, 2003 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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, 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. */ - -/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ - -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <endian.h> -#include <byteswap.h> -#include "md5.h" - -#if __BYTE_ORDER == __BIG_ENDIAN -# define SWAP(n) bswap_32 (n) -#else -# define SWAP(n) (n) -#endif - -/* This array contains the bytes used to pad the buffer to the next - 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -void -md5_init_ctx (ctx) - struct md5_ctx *ctx; -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; -} - -/* Put result from CTX in first 16 bytes following RESBUF. The result - must be in little endian byte order. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -md5_read_ctx (ctx, resbuf) - const struct md5_ctx *ctx; - void *resbuf; -{ - ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); - ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); - ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); - ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); - - return resbuf; -} - -/* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -md5_finish_ctx (ctx, resbuf) - struct md5_ctx *ctx; - void *resbuf; -{ - /* Take yet unprocessed bytes into account. */ - md5_uint32 bytes = ctx->buflen; - size_t pad; - - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; - - pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; - memcpy (&ctx->buffer[bytes], fillbuf, pad); - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); - *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | - (ctx->total[0] >> 29)); - - /* Process last bytes. */ - md5_process_block (ctx->buffer, bytes + pad + 8, ctx); - - return md5_read_ctx (ctx, resbuf); -} - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * -md5_buffer (buffer, len, resblock) - const char *buffer; - size_t len; - void *resblock; -{ - struct md5_ctx ctx; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md5_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return md5_finish_ctx (&ctx, resblock); -} - - -void -md5_process_bytes (buffer, len, ctx) - const void *buffer; - size_t len; - struct md5_ctx *ctx; -{ - /* When we already have some bits in our internal buffer concatenate - both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; - - memcpy (&ctx->buffer[left_over], buffer, add); - ctx->buflen += add; - - if (ctx->buflen > 64) - { - md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); - - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap. */ - memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], - ctx->buflen); - } - - buffer = (const char *) buffer + add; - len -= add; - } - - /* Process available complete blocks. */ - if (len >= 64) - { -#define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) - { - md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else - { - md5_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; - } - } - - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; - - memcpy (&ctx->buffer[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - md5_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - memcpy (ctx->buffer, &ctx->buffer[64], left_over); - } - ctx->buflen = left_over; - } -} - - -/* These are the four functions used in the four steps of the MD5 algorithm - and defined in the RFC 1321. The first function is a little bit optimized - (as found in Colin Plumbs public domain implementation). */ -/* #define FF(b, c, d) ((b & c) | (~b & d)) */ -#define FF(b, c, d) (d ^ (b & (c ^ d))) -#define FG(b, c, d) FF (d, b, c) -#define FH(b, c, d) (b ^ c ^ d) -#define FI(b, c, d) (c ^ (b | ~d)) - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. */ - -void -md5_process_block (buffer, len, ctx) - const void *buffer; - size_t len; - struct md5_ctx *ctx; -{ - md5_uint32 correct_words[16]; - const md5_uint32 *words = buffer; - size_t nwords = len / sizeof (md5_uint32); - const md5_uint32 *endp = words + nwords; - md5_uint32 A = ctx->A; - md5_uint32 B = ctx->B; - md5_uint32 C = ctx->C; - md5_uint32 D = ctx->D; - - /* First increment the byte count. RFC 1321 specifies the possible - length of the file up to 2^64 bits. Here we only compute the - number of bytes. Do a double word increment. */ - ctx->total[0] += len; - if (ctx->total[0] < len) - ++ctx->total[1]; - - /* Process all bytes in the buffer with 64 bytes in each round of - the loop. */ - while (words < endp) - { - md5_uint32 *cwp = correct_words; - md5_uint32 A_save = A; - md5_uint32 B_save = B; - md5_uint32 C_save = C; - md5_uint32 D_save = D; - - /* First round: using the given function, the context and a constant - the next context is computed. Because the algorithms processing - unit is a 32-bit word and it is determined to work on words in - little endian byte order we perhaps have to change the byte order - before the computation. To reduce the work for the next steps - we store the swapped words in the array CORRECT_WORDS. */ - -#define OP(a, b, c, d, s, T) \ - do \ - { \ - a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ - ++words; \ - a = rol (a, s); \ - a += b; \ - } \ - while (0) - - /* Before we start, one word to the strange constants. - They are defined in RFC 1321 as - - T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or - perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' - */ - - /* Round 1. */ - OP (A, B, C, D, 7, 0xd76aa478); - OP (D, A, B, C, 12, 0xe8c7b756); - OP (C, D, A, B, 17, 0x242070db); - OP (B, C, D, A, 22, 0xc1bdceee); - OP (A, B, C, D, 7, 0xf57c0faf); - OP (D, A, B, C, 12, 0x4787c62a); - OP (C, D, A, B, 17, 0xa8304613); - OP (B, C, D, A, 22, 0xfd469501); - OP (A, B, C, D, 7, 0x698098d8); - OP (D, A, B, C, 12, 0x8b44f7af); - OP (C, D, A, B, 17, 0xffff5bb1); - OP (B, C, D, A, 22, 0x895cd7be); - OP (A, B, C, D, 7, 0x6b901122); - OP (D, A, B, C, 12, 0xfd987193); - OP (C, D, A, B, 17, 0xa679438e); - OP (B, C, D, A, 22, 0x49b40821); - - /* For the second to fourth round we have the possibly swapped words - in CORRECT_WORDS. Redefine the macro to take an additional first - argument specifying the function to use. */ -#undef OP -#define OP(f, a, b, c, d, k, s, T) \ - do \ - { \ - a += f (b, c, d) + correct_words[k] + T; \ - a = rol (a, s); \ - a += b; \ - } \ - while (0) - - /* Round 2. */ - OP (FG, A, B, C, D, 1, 5, 0xf61e2562); - OP (FG, D, A, B, C, 6, 9, 0xc040b340); - OP (FG, C, D, A, B, 11, 14, 0x265e5a51); - OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); - OP (FG, A, B, C, D, 5, 5, 0xd62f105d); - OP (FG, D, A, B, C, 10, 9, 0x02441453); - OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); - OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); - OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); - OP (FG, D, A, B, C, 14, 9, 0xc33707d6); - OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); - OP (FG, B, C, D, A, 8, 20, 0x455a14ed); - OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); - OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); - OP (FG, C, D, A, B, 7, 14, 0x676f02d9); - OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); - - /* Round 3. */ - OP (FH, A, B, C, D, 5, 4, 0xfffa3942); - OP (FH, D, A, B, C, 8, 11, 0x8771f681); - OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); - OP (FH, B, C, D, A, 14, 23, 0xfde5380c); - OP (FH, A, B, C, D, 1, 4, 0xa4beea44); - OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); - OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); - OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); - OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); - OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); - OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); - OP (FH, B, C, D, A, 6, 23, 0x04881d05); - OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); - OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); - OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); - OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); - - /* Round 4. */ - OP (FI, A, B, C, D, 0, 6, 0xf4292244); - OP (FI, D, A, B, C, 7, 10, 0x432aff97); - OP (FI, C, D, A, B, 14, 15, 0xab9423a7); - OP (FI, B, C, D, A, 5, 21, 0xfc93a039); - OP (FI, A, B, C, D, 12, 6, 0x655b59c3); - OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); - OP (FI, C, D, A, B, 10, 15, 0xffeff47d); - OP (FI, B, C, D, A, 1, 21, 0x85845dd1); - OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); - OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); - OP (FI, C, D, A, B, 6, 15, 0xa3014314); - OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); - OP (FI, A, B, C, D, 4, 6, 0xf7537e82); - OP (FI, D, A, B, C, 11, 10, 0xbd3af235); - OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); - OP (FI, B, C, D, A, 9, 21, 0xeb86d391); - - /* Add the starting values of the context. */ - A += A_save; - B += B_save; - C += C_save; - D += D_save; - } - - /* Put checksum in context given as argument. */ - ctx->A = A; - ctx->B = B; - ctx->C = C; - ctx->D = D; -} diff --git a/trunk/src/md5.h b/trunk/src/md5.h deleted file mode 100644 index 55f6195..0000000 --- a/trunk/src/md5.h +++ /dev/null @@ -1,105 +0,0 @@ -/* md5.h - Declaration of functions and data types used for MD5 sum - computing library functions. - Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. - NOTE: The canonical source of this file is maintained with the GNU C - Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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, 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. */ - -#ifndef _MD5_H -#define _MD5_H 1 - -#include <limits.h> -#include <stdint.h> -typedef uint32_t md5_uint32; -typedef uintptr_t md5_uintptr; - -/* Structure to save state of computation between the single steps. */ -struct md5_ctx -{ - md5_uint32 A; - md5_uint32 B; - md5_uint32 C; - md5_uint32 D; - - md5_uint32 total[2]; - md5_uint32 buflen; - char buffer[128]; -}; - -/* - * The following three functions are build up the low level used in - * the function `md5_buffer'. - */ - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -extern void md5_init_ctx (struct md5_ctx *ctx); - -/* Starting with the result of former calls of this function (or the - initialization function update the context for the next LEN bytes - starting at BUFFER. - It is necessary that LEN is a multiple of 64!!! */ -extern void md5_process_block __P ((const void *buffer, size_t len, - struct md5_ctx *ctx)); - -/* Starting with the result of former calls of this function (or the - initialization function update the context for the next LEN bytes - starting at BUFFER. - It is NOT required that LEN is a multiple of 64. */ -extern void md5_process_bytes __P ((const void *buffer, size_t len, - struct md5_ctx *ctx)); - -/* Process the remaining bytes in the buffer and put result from CTX - in first 16 bytes following RESBUF. The result is always in little - endian byte order, so that a byte-wise output yields to the wanted - ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF be correctly - aligned for a 32 bits value. */ -extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); - - -/* Put result from CTX in first 16 bytes following RESBUF. The result is - always in little endian byte order, so that a byte-wise output yields - to the wanted ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf); - - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -extern void *md5_buffer (const char *buffer, size_t len, void *resblock); - -/* The following is from gnupg-1.0.2's cipher/bithelp.h. */ -/* Rotate a 32 bit integer by n bytes */ -#if defined __GNUC__ && defined __i386__ -static inline md5_uint32 -rol(md5_uint32 x, int n) -{ - __asm__("roll %%cl,%0" - :"=r" (x) - :"0" (x),"c" (n)); - return x; -} -#else -# define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) -#endif - -#endif diff --git a/trunk/src/mdebug.c b/trunk/src/mdebug.c deleted file mode 100644 index 4c22d2f..0000000 --- a/trunk/src/mdebug.c +++ /dev/null @@ -1,692 +0,0 @@ -/* Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <byteswap.h> -#include <endian.h> -#include <error.h> -#include <stddef.h> - -#include "prelink.h" - -#define F8(x) unsigned char x[1]; -#define F16(x) unsigned char x[2]; -#define F24(x) unsigned char x[3]; -#define F32(x) unsigned char x[4]; -#define F64(x) unsigned char x[8]; - -typedef struct -{ - F16(magic) - F16(vstamp) - F32(ilineMax) - F32(cbLine) - F32(cbLineOffset) - F32(idnMax) - F32(cbDnOffset) - F32(ipdMax) - F32(cbPdOffset) - F32(isymMax) - F32(cbSymOffset) - F32(ioptMax) - F32(cbOptOffset) - F32(iauxMax) - F32(cbAuxOffset) - F32(issMax) - F32(cbSsOffset) - F32(issExtMax) - F32(cbSsExtOffset) - F32(ifdMax) - F32(cbFdOffset) - F32(crfd) - F32(cbRfdOffset) - F32(iextMax) - F32(cbExtOffset) -} mdebug_hdr_32; - -typedef struct -{ - F16(magic) - F16(vstamp) - F32(ilineMax) - F32(idnMax) - F32(ipdMax) - F32(isymMax) - F32(ioptMax) - F32(iauxMax) - F32(issMax) - F32(issExtMax) - F32(ifdMax) - F32(crfd) - F32(iextMax) - F64(cbLine) - F64(cbLineOffset) - F64(cbDnOffset) - F64(cbPdOffset) - F64(cbSymOffset) - F64(cbOptOffset) - F64(cbAuxOffset) - F64(cbSsOffset) - F64(cbSsExtOffset) - F64(cbFdOffset) - F64(cbRfdOffset) - F64(cbExtOffset) -} mdebug_hdr_64; - -typedef struct -{ - F32(adr) - F32(rss) - F32(issBase) - F32(cbSs) - F32(isymBase) - F32(csym) - F32(ilineBase) - F32(cline) - F32(ioptBase) - F32(copt) - F16(ipdFirst) - F16(cpd) - F32(iauxBase) - F32(caux) - F32(rfdBase) - F32(crfd) - F8(bits1) - F24(bits2) - F32(cbLineOffset) - F32(cbLine) -} mdebug_fdr_32; - -typedef struct -{ - F64(adr) - F64(cbLineOffset) - F64(cbLine) - F64(cbSs) - F32(rss) - F32(issBase) - F32(isymBase) - F32(csym) - F32(ilineBase) - F32(cline) - F32(ioptBase) - F32(copt) - F32(ipdFirst) - F32(cpd) - F32(iauxBase) - F32(caux) - F32(rfdBase) - F32(crfd) - F8(bits1) - F24(bits2) - F32(padding) -} mdebug_fdr_64; - -typedef struct -{ - F32(iss) - F32(value) - F8(bits1) - F8(bits2) - F8(bits3) - F8(bits4) -} mdebug_sym_32; - -typedef struct -{ - F64(value) - F32(iss) - F8(bits1) - F8(bits2) - F8(bits3) - F8(bits4) -} mdebug_sym_64; - -typedef struct -{ - F8(bits1) - F8(bits2) - F16(fd) - mdebug_sym_32 asym; -} mdebug_ext_32; - -typedef struct -{ - mdebug_sym_64 asym; - F8(bits1) - F24(bits2) - F32(fd) -} mdebug_ext_64; - -typedef struct -{ - F32(adr) - F32(isym) - F32(iline) - F32(regmask) - F32(regoffset) - F32(iopt) - F32(fregmask) - F32(fregoffset) - F32(frameoffset) - F16(framereg) - F16(pcreg) - F32(lnLow) - F32(lnHigh) - F32(cbLineOffset) -} mdebug_pdr_32; - -typedef struct -{ - F64(adr) - F64(cbLineOffset) - F32(isym) - F32(iline) - F32(regmask) - F32(regoffset) - F32(iopt) - F32(fregmask) - F32(fregoffset) - F32(frameoffset) - F32(lnLow) - F32(lnHigh) - F8(gp_prologue) - F8(bits1) - F8(bits2) - F8(localoff) - F16(framereg) - F16(pcreg) -} mdebug_pdr_64; - -typedef struct -{ - F32(bits); -} mdebug_rndx; - -typedef struct -{ - F8(bits1) - F8(bits2) - F8(bits3) - F8(bits4) - mdebug_rndx rndx; - F32(offset) -} mdebug_opt; - -typedef struct -{ - F32(rfd) - F32(index) -} mdebug_dnr; - -typedef struct -{ - F32(rfd) -} mdebug_rfd; - -#define scNil 0 -#define scText 1 -#define scData 2 -#define scBss 3 -#define scRegister 4 -#define scAbs 5 -#define scUndefined 6 -#define scCdbLocal 7 -#define scBits 8 -#define scCdbSystem 9 -#define scDbx 9 -#define scRegImage 10 -#define scInfo 11 -#define scUserStruct 12 -#define scSData 13 -#define scSBss 14 -#define scRData 15 -#define scVar 16 -#define scCommon 17 -#define scSCommon 18 -#define scVarRegister 19 -#define scVariant 20 -#define scSUndefined 21 -#define scInit 22 -#define scBasedVar 23 -#define scXData 24 -#define scPData 25 -#define scFini 26 -#define scRConst 27 -#define scMax 32 - -#define stNil 0 -#define stGlobal 1 -#define stStatic 2 -#define stParam 3 -#define stLocal 4 -#define stLabel 5 -#define stProc 6 -#define stBlock 7 -#define stEnd 8 -#define stMember 9 -#define stTypedef 10 -#define stFile 11 -#define stRegReloc 12 -#define stForward 13 -#define stStaticProc 14 -#define stConstant 15 -#define stStaParam 16 -#define stStruct 26 -#define stUnion 27 -#define stEnum 28 -#define stIndirect 34 -#define stMax 64 - -struct mdebug -{ - uint32_t (*read_32) (char *); - GElf_Addr (*read_ptr) (char *); - void (*write_ptr) (char *, GElf_Addr); - void (*adjust_sym) (struct mdebug *, unsigned char *, GElf_Addr, GElf_Addr); - unsigned char *buf; - DSO *dso; -}; - -static uint32_t -read_native_32 (char *p) -{ - return *(uint32_t *)p; -} - -static uint32_t -read_swap_32 (char *p) -{ - return bswap_32 (*(uint32_t *)p); -} - -static GElf_Addr -read_native_ptr32 (char *p) -{ - return *(uint32_t *)p; -} - -static GElf_Addr -read_swap_ptr32 (char *p) -{ - return bswap_32 (*(uint32_t *)p); -} - -static void -write_native_ptr32 (char *p, GElf_Addr v) -{ - *(uint32_t *)p = v; -} - -static void -write_swap_ptr32 (char *p, GElf_Addr v) -{ - *(uint32_t *)p = bswap_32 (v); -} - -static GElf_Addr -read_native_ptr64 (char *p) -{ - return *(uint64_t *)p; -} - -static GElf_Addr -read_swap_ptr64 (char *p) -{ - return bswap_64 (*(uint64_t *)p); -} - -static void -write_native_ptr64 (char *p, GElf_Addr v) -{ - *(uint64_t *)p = v; -} - -static void -write_swap_ptr64 (char *p, GElf_Addr v) -{ - *(uint64_t *)p = bswap_64 (v); -} - -static inline int -mdebug_sym_relocate (unsigned int st, unsigned int sc) -{ - switch (sc) - { - case scData: - case scBss: - case scAbs: - case scSData: - case scSBss: - case scRData: - case scXData: - case scPData: - return 1; - case scText: - case scInit: - case scFini: - case scRConst: - if (st != stBlock && st != stEnd && st != stFile) - return 1; - default: - return 0; - } -} - -static void -adjust_mdebug_sym_le32 (struct mdebug *mdebug, mdebug_sym_32 *symptr, - GElf_Addr start, GElf_Addr adjust) -{ - unsigned int st, sc; - GElf_Addr addr; - - st = symptr->bits1[0] & 0x3f; - sc = (symptr->bits1[0] >> 6) | ((symptr->bits2[0] & 7) << 2); - if (mdebug_sym_relocate (st, sc)) - { - addr = mdebug->read_ptr (symptr->value); - if (addr >= start && (addr || sc != scAbs)) - mdebug->write_ptr (symptr->value, addr + adjust); - } -} - -static void -adjust_mdebug_sym_be32 (struct mdebug *mdebug, mdebug_sym_32 *symptr, - GElf_Addr start, GElf_Addr adjust) -{ - unsigned int st, sc; - GElf_Addr addr; - - st = symptr->bits1[0] >> 2; - sc = ((symptr->bits1[0] & 3) << 3) | (symptr->bits2[0] >> 5); - if (mdebug_sym_relocate (st, sc)) - { - addr = mdebug->read_ptr (symptr->value); - if (addr >= start && (addr || sc != scAbs)) - mdebug->write_ptr (symptr->value, addr + adjust); - } -} - -static void -adjust_mdebug_sym_le64 (struct mdebug *mdebug, mdebug_sym_64 *symptr, - GElf_Addr start, GElf_Addr adjust) -{ - unsigned int st, sc; - GElf_Addr addr; - - st = symptr->bits1[0] & 0x3f; - sc = (symptr->bits1[0] >> 6) | ((symptr->bits2[0] & 7) << 2); - if (mdebug_sym_relocate (st, sc)) - { - addr = mdebug->read_ptr (symptr->value); - if (addr >= start && (addr || sc != scAbs)) - mdebug->write_ptr (symptr->value, addr + adjust); - } -} - -static void -adjust_mdebug_sym_be64 (struct mdebug *mdebug, mdebug_sym_64 *symptr, - GElf_Addr start, GElf_Addr adjust) -{ - unsigned int st, sc; - GElf_Addr addr; - - st = symptr->bits1[0] >> 2; - sc = ((symptr->bits1[0] & 3) << 3) | (symptr->bits2[0] >> 5); - if (mdebug_sym_relocate (st, sc)) - { - addr = mdebug->read_ptr (symptr->value); - if (addr >= start && (addr || sc != scAbs)) - mdebug->write_ptr (symptr->value, addr + adjust); - } -} - -#define SIZEOf(x) \ - (dso->arch->class == ELFCLASS32 ? sizeof (x##_32) : sizeof (x##_64)) -#define SIZEOF(x) SIZEOf(x) -#define OFFSETOf(x,y) \ - (dso->arch->class == ELFCLASS32 ? offsetof (x##_32, y) : offsetof (x##_64, y)) -#define OFFSETOF(x,y) OFFSETOf(x,y) - -static int -start_mdebug (DSO *dso, int n, struct mdebug *mdebug) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - - data = elf_getdata (scn, NULL); - mdebug->buf = data->d_buf; - mdebug->dso = dso; - assert (data != NULL && data->d_buf != NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0 && data->d_size == dso->shdr[n].sh_size); - if (dso->mdebug_orig_offset == 0) - dso->mdebug_orig_offset = dso->shdr[n].sh_offset; -#if __BYTE_ORDER == __BIG_ENDIAN - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) -#elif __BYTE_ORDER == __LITTLE_ENDIAN - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) -#else -# error Not supported host endianess -#endif - { - mdebug->read_32 = read_native_32; - if (dso->arch->class == ELFCLASS32) - { - mdebug->read_ptr = read_native_ptr32; - mdebug->write_ptr = write_native_ptr32; - } - else - { - mdebug->read_ptr = read_native_ptr64; - mdebug->write_ptr = write_native_ptr64; - } - } -#if __BYTE_ORDER == __BIG_ENDIAN - else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) -#elif __BYTE_ORDER == __LITTLE_ENDIAN - else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) -#endif - { - mdebug->read_32 = read_swap_32; - if (dso->arch->class == ELFCLASS32) - { - mdebug->read_ptr = read_swap_ptr32; - mdebug->write_ptr = write_swap_ptr32; - } - else - { - mdebug->read_ptr = read_swap_ptr64; - mdebug->write_ptr = write_swap_ptr64; - } - } - else - { - error (0, 0, "%s: Wrong ELF data enconding", dso->filename); - return 1; - } - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) - { - if (dso->arch->class == ELFCLASS32) - mdebug->adjust_sym = (void *) adjust_mdebug_sym_le32; - else - mdebug->adjust_sym = (void *) adjust_mdebug_sym_le64; - } - else - { - if (dso->arch->class == ELFCLASS32) - mdebug->adjust_sym = (void *) adjust_mdebug_sym_be32; - else - mdebug->adjust_sym = (void *) adjust_mdebug_sym_be64; - } - - if (dso->shdr[n].sh_size < SIZEOF (mdebug_hdr)) - { - error (0, 0, "%s: .mdebug section too small", dso->filename); - return 1; - } - return 0; -} - -int -adjust_mdebug (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - struct mdebug mdebug; - struct { GElf_Off offset; GElf_Off size; size_t entsize; } regions [11]; - int i = 0; - unsigned char *symptr, *endptr; - - if (start_mdebug (dso, n, &mdebug)) - return 1; - -#define READ(x, y, longsize, sz) \ -do { \ - unsigned char *tmp; \ - tmp = mdebug.buf + OFFSETOF (mdebug_hdr, x); \ - regions[i].offset = mdebug.read_ptr (tmp); \ - tmp = mdebug.buf + OFFSETOF (mdebug_hdr, y); \ - if (longsize) \ - regions[i].size = mdebug.read_ptr (tmp); \ - else \ - regions[i].size = mdebug.read_32 (tmp); \ - regions[i].entsize = sz; \ - ++i; \ -} while (0) - - READ (cbLineOffset, cbLine, 1, sizeof (char)); - READ (cbDnOffset, idnMax, 0, sizeof (mdebug_dnr)); - READ (cbPdOffset, ipdMax, 0, SIZEOF (mdebug_pdr)); - READ (cbSymOffset, isymMax, 0, SIZEOF (mdebug_sym)); - READ (cbOptOffset, ioptMax, 0, sizeof (mdebug_opt)); - READ (cbAuxOffset, iauxMax, 0, 4 * sizeof (char)); - READ (cbSsOffset, issMax, 0, sizeof (char)); - READ (cbSsExtOffset, issExtMax, 0, sizeof (char)); - READ (cbFdOffset, ifdMax, 0, SIZEOF (mdebug_fdr)); - READ (cbRfdOffset, crfd, 0, sizeof (mdebug_rfd)); - READ (cbExtOffset, iextMax, 0, SIZEOF (mdebug_ext)); - -#undef READ - - for (i = 0; i < 11; ++i) - { - if (regions[i].offset) - regions[i].offset -= dso->mdebug_orig_offset; - regions[i].size *= regions[i].entsize; - if (regions[i].offset >= dso->shdr[n].sh_size - || regions[i].offset + regions[i].size > dso->shdr[n].sh_size) - { - error (0, 0, "%s: File offsets in .mdebug header point outside of .mdebug section", - dso->filename); - return 1; - } - } - - /* Adjust symbols. */ - if (regions[3].offset) - for (symptr = mdebug.buf + regions[3].offset, - endptr = symptr + regions[3].size; - symptr < endptr; - symptr += regions[3].entsize) - mdebug.adjust_sym (&mdebug, symptr, start, adjust); - - /* Adjust file descriptor's addresses. */ - if (regions[8].offset) - for (symptr = mdebug.buf + regions[8].offset, - endptr = symptr + regions[8].size; - symptr < endptr; - symptr += regions[8].entsize) - { - GElf_Addr addr; - - assert (offsetof (mdebug_fdr_32, adr) == 0); - assert (offsetof (mdebug_fdr_64, adr) == 0); - addr = mdebug.read_ptr (symptr); - if (addr >= start) - mdebug.write_ptr (symptr, addr + adjust); - } - - /* Adjust extended symbols. */ - if (regions[10].offset) - for (symptr = mdebug.buf + regions[10].offset - + OFFSETOF (mdebug_ext, asym), - endptr = symptr + regions[10].size; - symptr < endptr; - symptr += regions[10].entsize) - mdebug.adjust_sym (&mdebug, symptr, start, adjust); - - return 0; -} - -int -finalize_mdebug (DSO *dso) -{ - int i; - struct mdebug mdebug; - GElf_Addr adj; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - if ((dso->arch->machine == EM_ALPHA - && dso->shdr[i].sh_type == SHT_ALPHA_DEBUG) - || (dso->arch->machine == EM_MIPS - && dso->shdr[i].sh_type == SHT_MIPS_DEBUG)) - break; - - assert (i < dso->ehdr.e_shnum); - - /* If .mdebug's file position did not change, there is nothing to do. */ - adj = dso->shdr[i].sh_offset - dso->mdebug_orig_offset; - if (! adj) - return 0; - - if (start_mdebug (dso, i, &mdebug)) - return 1; - -#define ADJUST(x) \ -do { \ - unsigned char *tmp; \ - GElf_Addr val; \ - tmp = mdebug.buf + OFFSETOF (mdebug_hdr, x); \ - val = mdebug.read_ptr (tmp); \ - if (! val) \ - break; \ - val += adj; \ - if (val < dso->shdr[i].sh_offset \ - || val >= dso->shdr[i].sh_offset + dso->shdr[i].sh_size) \ - { \ - error (0, 0, "%s: File offsets in .mdebug header point outside of .mdebug section", \ - dso->filename); \ - return 1; \ - } \ - mdebug.write_ptr (tmp, val); \ -} while (0) - - ADJUST (cbLineOffset); - ADJUST (cbDnOffset); - ADJUST (cbPdOffset); - ADJUST (cbSymOffset); - ADJUST (cbOptOffset); - ADJUST (cbAuxOffset); - ADJUST (cbSsOffset); - ADJUST (cbSsExtOffset); - ADJUST (cbFdOffset); - ADJUST (cbRfdOffset); - ADJUST (cbExtOffset); - -#undef ADJUST - return 0; -} diff --git a/trunk/src/prelink.c b/trunk/src/prelink.c deleted file mode 100644 index 0798811..0000000 --- a/trunk/src/prelink.c +++ /dev/null @@ -1,995 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" - -static GElf_Addr -resolve_ldso (struct prelink_info *info, GElf_Word r_sym, - int reloc_type __attribute__((unused))) -{ - /* Dynamic linker does not depend on any other library, - all symbols resolve to themselves with the exception - of SHN_UNDEF symbols which resolve to 0. */ - if (info->symtab[r_sym].st_shndx == SHN_UNDEF) - { - info->resolveent = NULL; - info->resolvetls = NULL; - return 0; - } - else - { - /* As the dynamic linker is relocated first, - l_addr will be 0. */ - info->resolveent = info->ent; - info->resolvetls = NULL; - return 0 + info->symtab[r_sym].st_value; - } -} - -static GElf_Addr -resolve_dso (struct prelink_info *info, GElf_Word r_sym, - int reloc_type) -{ - struct prelink_symbol *s; - int reloc_class = info->dso->arch->reloc_class (reloc_type); - - for (s = & info->symbols[r_sym]; s; s = s->next) - if (s->reloc_class == reloc_class) - break; - - info->resolveent = NULL; - info->resolvetls = NULL; - - if (s == NULL || s->u.ent == NULL) - return 0; - - if (reloc_class == RTYPE_CLASS_TLS) - { - info->resolvetls = s->u.tls; - return s->value; - } - - info->resolveent = s->u.ent; - return s->u.ent->base + s->value; -} - -static int -prelink_rel (DSO *dso, int n, struct prelink_info *info) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rel rel; - int sec; - - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrel (dso->elf, data, ndx, &rel); - sec = addr_to_sec (dso, rel.r_offset); - if (sec == -1) - continue; - - switch (dso->arch->prelink_rel (info, &rel, addr)) - { - case 2: - gelfx_update_rel (dso->elf, data, ndx, &rel); - break; - case 0: - break; - default: - return 1; - } - } - } - return 0; -} - -static int -prelink_rela (DSO *dso, int n, struct prelink_info *info) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rela rela; - int sec; - - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrela (dso->elf, data, ndx, &rela); - sec = addr_to_sec (dso, rela.r_offset); - if (sec == -1) - continue; - - switch (dso->arch->prelink_rela (info, &rela, addr)) - { - case 2: - gelfx_update_rela (dso->elf, data, ndx, &rela); - break; - case 0: - break; - default: - return 1; - } - } - } - return 0; -} - -int -prelink_prepare (DSO *dso) -{ - struct reloc_info rinfo; - int liblist = 0, libstr = 0, newlibstr = 0, undo = 0, newundo = 0; - int i; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - const char *name - = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name); - if (! strcmp (name, ".gnu.liblist")) - liblist = i; - else if (! strcmp (name, ".gnu.libstr")) - libstr = i; - else if (! strcmp (name, ".gnu.prelink_undo")) - undo = i; - } - - if (undo == 0) - { - Elf32_Shdr *shdr32; - Elf64_Shdr *shdr64; - Elf_Data src, dst; - - dso->undo.d_size = gelf_fsize (dso->elf, ELF_T_EHDR, 1, EV_CURRENT) - + gelf_fsize (dso->elf, ELF_T_PHDR, - dso->ehdr.e_phnum, EV_CURRENT) - + gelf_fsize (dso->elf, ELF_T_SHDR, - dso->ehdr.e_shnum - 1, EV_CURRENT); - dso->undo.d_buf = malloc (dso->undo.d_size); - if (dso->undo.d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not create .gnu.prelink_undo section", - dso->filename); - return 1; - } - dso->undo.d_type = ELF_T_BYTE; - dso->undo.d_off = 0; - dso->undo.d_align = gelf_fsize (dso->elf, ELF_T_ADDR, 1, EV_CURRENT); - dso->undo.d_version = EV_CURRENT; - src = dso->undo; - src.d_type = ELF_T_EHDR; - src.d_size = gelf_fsize (dso->elf, ELF_T_EHDR, 1, EV_CURRENT); - dst = src; - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - src.d_buf = elf32_getehdr (dso->elf); - if (elf32_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - case ELFCLASS64: - src.d_buf = elf64_getehdr (dso->elf); - if (elf64_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - default: - return 1; - } - src.d_buf = dst.d_buf + src.d_size; - src.d_type = ELF_T_PHDR; - src.d_size = gelf_fsize (dso->elf, ELF_T_PHDR, dso->ehdr.e_phnum, - EV_CURRENT); - dst = src; - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - src.d_buf = elf32_getphdr (dso->elf); - if (elf32_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - case ELFCLASS64: - src.d_buf = elf64_getphdr (dso->elf); - if (elf64_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - } - src.d_buf = dst.d_buf + src.d_size; - src.d_type = ELF_T_SHDR; - src.d_size = gelf_fsize (dso->elf, ELF_T_SHDR, - dso->ehdr.e_shnum - 1, EV_CURRENT); - dst = src; - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - shdr32 = (Elf32_Shdr *) src.d_buf; - /* Note: cannot use dso->scn[i] below, since we want to save the - original section order before non-alloced sections were - sorted by sh_offset. */ - for (i = 1; i < dso->ehdr.e_shnum; ++i) - shdr32[i - 1] = *elf32_getshdr (elf_getscn (dso->elf, i)); - if (elf32_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - case ELFCLASS64: - shdr64 = (Elf64_Shdr *) src.d_buf; - /* Note: cannot use dso->scn[i] below, since we want to save the - original section order before non-alloced sections were - sorted by sh_offset. */ - for (i = 1; i < dso->ehdr.e_shnum; ++i) - shdr64[i - 1] = *elf64_getshdr (elf_getscn (dso->elf, i)); - if (elf64_xlatetof (&dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Failed to create .gnu.prelink_undo section", - dso->filename); - return 1; - } - break; - } - } - - if (dso->ehdr.e_type != ET_DYN) - return 0; - - if (find_reloc_sections (dso, &rinfo)) - return 1; - - if (is_ldso_soname (dso->soname)) - { - liblist = -1; - libstr = -1; - } - - if (liblist && libstr && undo - && ! rinfo.rel_to_rela && ! rinfo.rel_to_rela_plt) - return 0; - - if (! liblist || ! libstr || ! undo) - { - struct section_move *move; - - move = init_section_move (dso); - if (move == NULL) - return 1; - - if (! liblist) - { - liblist = move->old_to_new [dso->ehdr.e_shstrndx]; - add_section (move, liblist); - } - else - liblist = 0; - - if (! libstr) - { - add_section (move, liblist + 1); - libstr = liblist + 1; - newlibstr = 1; - } - else if (libstr != -1) - libstr = move->old_to_new[libstr]; - - if (! undo) - { - if (libstr == -1) - { - undo = move->old_to_new [dso->ehdr.e_shstrndx]; - add_section (move, undo); - } - else - { - add_section (move, libstr + 1); - undo = libstr + 1; - } - newundo = 1; - } - else - undo = move->old_to_new[undo]; - - if (reopen_dso (dso, move, NULL)) - { - free (move); - return 1; - } - - free (move); - if (liblist) - { - memset (&dso->shdr[liblist], 0, sizeof (GElf_Shdr)); - dso->shdr[liblist].sh_name = shstrtabadd (dso, ".gnu.liblist"); - if (dso->shdr[liblist].sh_name == 0) - return 1; - dso->shdr[liblist].sh_type = SHT_GNU_LIBLIST; - dso->shdr[liblist].sh_offset = dso->shdr[liblist - 1].sh_offset; - if (dso->shdr[liblist - 1].sh_type != SHT_NOBITS) - dso->shdr[liblist].sh_offset += dso->shdr[liblist - 1].sh_size; - dso->shdr[liblist].sh_link = libstr; - dso->shdr[liblist].sh_addralign = sizeof (GElf_Word); - dso->shdr[liblist].sh_entsize = sizeof (Elf32_Lib); - } - - if (newlibstr) - { - memset (&dso->shdr[libstr], 0, sizeof (GElf_Shdr)); - dso->shdr[libstr].sh_name = shstrtabadd (dso, ".gnu.libstr"); - if (dso->shdr[libstr].sh_name == 0) - return 1; - dso->shdr[libstr].sh_type = SHT_STRTAB; - dso->shdr[libstr].sh_offset = dso->shdr[libstr - 1].sh_offset; - if (dso->shdr[libstr - 1].sh_type != SHT_NOBITS) - dso->shdr[libstr].sh_offset += dso->shdr[libstr - 1].sh_size; - dso->shdr[libstr].sh_addralign = 1; - } - - if (newundo) - { - Elf_Scn *scn; - Elf_Data *data; - GElf_Addr newoffset; - - memset (&dso->shdr[undo], 0, sizeof (GElf_Shdr)); - dso->shdr[undo].sh_name = shstrtabadd (dso, ".gnu.prelink_undo"); - if (dso->shdr[undo].sh_name == 0) - return 1; - dso->shdr[undo].sh_type = SHT_PROGBITS; - dso->shdr[undo].sh_offset = dso->shdr[undo - 1].sh_offset; - if (dso->shdr[undo - 1].sh_type != SHT_NOBITS) - dso->shdr[undo].sh_offset += dso->shdr[undo - 1].sh_size; - dso->shdr[undo].sh_addralign = dso->undo.d_align; - dso->shdr[undo].sh_entsize = 1; - dso->shdr[undo].sh_size = dso->undo.d_size; - newoffset = dso->shdr[undo].sh_offset + dso->undo.d_align - 1; - newoffset &= ~(dso->shdr[undo].sh_addralign - 1); - if (adjust_dso_nonalloc (dso, undo + 1, dso->shdr[undo].sh_offset, - dso->undo.d_size + newoffset - - dso->shdr[undo].sh_offset)) - return 1; - dso->shdr[undo].sh_offset = newoffset; - scn = dso->scn[undo]; - data = elf_getdata (scn, NULL); - assert (data != NULL && elf_getdata (scn, data) == NULL); - free (data->d_buf); - *data = dso->undo; - dso->undo.d_buf = NULL; - } - } - else if (reopen_dso (dso, NULL, NULL)) - return 1; - - if (rinfo.rel_to_rela || rinfo.rel_to_rela_plt) - { - /* On REL architectures, we might need to convert some REL - relocations to RELA relocs. */ - - int safe = 1, align = 0, last; - GElf_Addr start, adjust, adjust1, adjust2; - - for (i = 1; i < (rinfo.plt ? rinfo.plt : rinfo.first); i++) - switch (dso->shdr[i].sh_type) - { - case SHT_HASH: - case SHT_GNU_HASH: - case SHT_DYNSYM: - case SHT_REL: - case SHT_RELA: - case SHT_STRTAB: - case SHT_NOTE: - case SHT_GNU_verdef: - case SHT_GNU_verneed: - case SHT_GNU_versym: - /* These sections are safe, no relocations should point - to it, therefore enlarging a section after sections - from this set only (and SHT_REL) in ET_DYN just needs - adjusting the rest of the library. */ - break; - case SHT_DYNAMIC: - case SHT_MIPS_REGINFO: - case SHT_MIPS_OPTIONS: - /* The same applies to these sections on MIPS. The convention - is to put .dynamic and .reginfo near the beginning of the - read-only segment, before the program text. No relocations - may refer to them. */ - if (dso->ehdr.e_machine == EM_MIPS) - break; - /* FALLTHROUGH */ - default: - /* The rest of sections are not safe. */ - safe = 0; - break; - } - - if (! safe) - { - error (0, 0, "%s: Cannot safely convert %s' section from REL to RELA", - dso->filename, strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[rinfo.rel_to_rela - ? rinfo.first : rinfo.plt].sh_name)); - return 1; - } - - for (i = rinfo.plt ? rinfo.plt : rinfo.first; i < dso->ehdr.e_shnum; i++) - { - if (dso->shdr[i].sh_addralign > align) - align = dso->shdr[i].sh_addralign; - } - - if (rinfo.plt) - start = dso->shdr[rinfo.plt].sh_addr + dso->shdr[rinfo.plt].sh_size; - else - start = dso->shdr[rinfo.last].sh_addr + dso->shdr[rinfo.last].sh_size; - - adjust1 = 0; - adjust2 = 0; - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - if (rinfo.rel_to_rela) - { - for (i = rinfo.first; i <= rinfo.last; ++i) - { - GElf_Addr size = dso->shdr[i].sh_size / 2 * 3; - adjust1 += size - dso->shdr[i].sh_size; - if (convert_rel_to_rela (dso, i)) - return 1; - } - } - if (rinfo.rel_to_rela_plt) - { - GElf_Addr size = dso->shdr[rinfo.plt].sh_size / 2 * 3; - adjust2 = size - dso->shdr[rinfo.plt].sh_size; - if (convert_rel_to_rela (dso, rinfo.plt)) - return 1; - } - - adjust = adjust1 + adjust2; - - /* Need to make sure that all the remaining sections are properly - aligned. */ - if (align) - adjust = (adjust + align - 1) & ~(align - 1); - - /* Need to make sure adjust doesn't cause different Phdr segments - to overlap on the same page. */ - last = -1; - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz >= start) - { - if (last != -1 - && (((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - 1) - ^ dso->phdr[i].p_vaddr) - & ~(dso->arch->max_page_size - 1)) - && !(((dso->phdr[last].p_vaddr + dso->phdr[last].p_memsz - + adjust - 1) - ^ (dso->phdr[i].p_vaddr + adjust)) - & ~(dso->arch->max_page_size - 1))) - { - if (align >= dso->arch->max_page_size) - { - error (0, 0, "%s: Cannot grow reloc sections", dso->filename); - return 1; - } - adjust = (adjust + dso->arch->max_page_size - 1) - & ~(dso->arch->max_page_size - 1); - } - last = i; - } - - /* Adjust all addresses pointing into remaining sections. */ - if (adjust_dso (dso, start - 1, adjust)) - return 1; - - if (rinfo.rel_to_rela) - { - GElf_Addr adjust3 = 0; - for (i = rinfo.first; i <= rinfo.last; ++i) - { - GElf_Addr size = dso->shdr[i].sh_size / 2 * 3; - - dso->shdr[i].sh_addr += adjust3; - dso->shdr[i].sh_offset += adjust3; - adjust3 += size - dso->shdr[i].sh_size; - dso->shdr[i].sh_size = size; - } - assert (adjust1 == adjust3); - if (rinfo.plt) - { - dso->shdr[rinfo.plt].sh_addr += adjust1; - dso->shdr[rinfo.plt].sh_offset += adjust1; - } - } - if (rinfo.rel_to_rela_plt) - dso->shdr[rinfo.plt].sh_size += adjust2; - - if (update_dynamic_rel (dso, &rinfo)) - return 1; - } - - return 0; -} - -static int -prelink_dso (struct prelink_info *info) -{ - int liblist = 0, libstr = 0, nobits_plt = 0; - int i, ndeps = info->ent->ndepends + 1; - DSO *dso = info->dso; - Elf32_Lib *list = NULL; - Elf_Scn *scn; - Elf_Data *data; - GElf_Addr oldsize, oldoffset; - size_t strsize; - - if (dso->ehdr.e_type != ET_DYN) - return 0; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - const char *name - = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name); - if (! strcmp (name, ".gnu.liblist")) - liblist = i; - else if (! strcmp (name, ".gnu.libstr")) - libstr = i; - else if (! strcmp (name, ".plt") && dso->shdr[i].sh_type == SHT_NOBITS) - nobits_plt = i; -#if 0 - else if (dso->arch->create_opd && ! strcmp (name, ".opd")) - opd = i; -#endif - } - - if (nobits_plt) - { - int j, first; - GElf_Addr adj, last_offset; - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_LOAD - && dso->phdr[i].p_vaddr <= dso->shdr[nobits_plt].sh_addr - && dso->phdr[i].p_vaddr + dso->phdr[i].p_memsz - >= dso->shdr[nobits_plt].sh_addr - + dso->shdr[nobits_plt].sh_size) - break; - - if (i == dso->ehdr.e_phnum) - { - error (0, 0, "%s: .plt section not contained within a segment", - dso->filename); - return 1; - } - - for (j = i + 1; j < dso->ehdr.e_phnum; ++j) - if (dso->phdr[j].p_type == PT_LOAD) - { - error (0, 0, "%s: library's NOBITS .plt section not in loadable last segment", - dso->filename); - return 1; - } - - for (j = nobits_plt - 1; j > 0; --j) - if (dso->shdr[j].sh_addr < dso->phdr[i].p_vaddr - || dso->shdr[j].sh_type != SHT_NOBITS) - break; - first = j + 1; - - for (j = first; j <= nobits_plt; ++j) - { - Elf_Data *data = elf_getdata (dso->scn[j], NULL); - - assert (data->d_buf == NULL); - assert (data->d_size == dso->shdr[j].sh_size); - if (data->d_size) - { - data->d_buf = calloc (data->d_size, 1); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not convert NOBITS section into PROGBITS", - dso->filename); - return 1; - } - } - data->d_type = ELF_T_BYTE; - dso->shdr[j].sh_type = SHT_PROGBITS; - dso->shdr[j].sh_offset = dso->phdr[i].p_offset + dso->shdr[j].sh_addr - - dso->phdr[i].p_vaddr; - } - - adj = dso->shdr[nobits_plt].sh_offset + dso->shdr[nobits_plt].sh_size - - dso->phdr[i].p_offset; - assert (adj <= dso->phdr[i].p_memsz); - if (adj > dso->phdr[i].p_filesz) - { - adj -= dso->phdr[i].p_filesz; - dso->phdr[i].p_filesz += adj; - if (adjust_dso_nonalloc (dso, nobits_plt + 1, - dso->shdr[first].sh_offset, adj)) - return 1; - } - - last_offset = dso->shdr[nobits_plt].sh_offset - + dso->shdr[nobits_plt].sh_size; - for (j = nobits_plt + 1; j < dso->ehdr.e_shnum; ++j) - if (!(dso->shdr[j].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR))) - break; - else - { - last_offset += dso->shdr[j].sh_addralign - 1; - last_offset &= ~(dso->shdr[j].sh_addralign - 1); - if (last_offset > dso->phdr[i].p_offset + dso->phdr[i].p_filesz) - last_offset = dso->phdr[i].p_offset + dso->phdr[i].p_filesz; - dso->shdr[j].sh_offset = last_offset; - } - } - - if (ndeps <= 1) - return 0; - - assert (liblist != 0); - assert (libstr != 0); - - list = calloc (ndeps - 1, sizeof (Elf32_Lib)); - if (list == NULL) - { - error (0, ENOMEM, "%s: Cannot build .gnu.liblist section", - dso->filename); - goto error_out; - } - - strsize = 1; - for (i = 0; i < ndeps - 1; ++i) - { - struct prelink_entry *ent = info->ent->depends[i]; - - strsize += strlen (info->sonames[i + 1]) + 1; - list[i].l_time_stamp = ent->timestamp; - list[i].l_checksum = ent->checksum; - } - - scn = dso->scn[libstr]; - data = elf_getdata (scn, NULL); - if (data == NULL) - data = elf_newdata (scn); - assert (elf_getdata (scn, data) == NULL); - - data->d_type = ELF_T_BYTE; - data->d_size = 1; - data->d_off = 0; - data->d_align = 1; - data->d_version = EV_CURRENT; - data->d_buf = realloc (data->d_buf, strsize); - if (data->d_buf == NULL) - { - error (0, ENOMEM, "%s: Could not build .gnu.libstr section", - dso->filename); - goto error_out; - } - - oldsize = dso->shdr[libstr].sh_size; - dso->shdr[libstr].sh_size = 1; - *(char *)data->d_buf = '\0'; - for (i = 0; i < ndeps - 1; ++i) - { - const char *name = info->sonames[i + 1]; - - list[i].l_name = strtabfind (dso, liblist, name); - if (list[i].l_name == 0) - { - size_t len = strlen (name) + 1; - - memcpy (data->d_buf + data->d_size, name, len); - list[i].l_name = data->d_size; - data->d_size += len; - dso->shdr[libstr].sh_size += len; - } - } - if (oldsize != dso->shdr[libstr].sh_size) - { - GElf_Addr adjust = dso->shdr[libstr].sh_size - oldsize; - - oldoffset = dso->shdr[libstr].sh_offset; - if (adjust_dso_nonalloc (dso, libstr + 1, oldoffset, adjust)) - goto error_out; - } - - scn = dso->scn[liblist]; - data = elf_getdata (scn, NULL); - if (data == NULL) - data = elf_newdata (scn); - assert (elf_getdata (scn, data) == NULL); - - data->d_type = ELF_T_WORD; - data->d_size = (ndeps - 1) * sizeof (Elf32_Lib); - data->d_off = 0; - data->d_align = sizeof (GElf_Word); - data->d_version = EV_CURRENT; - free (data->d_buf); - data->d_buf = list; - list = NULL; - - if (data->d_size != dso->shdr[liblist].sh_size) - { - GElf_Addr adjust = data->d_size - dso->shdr[liblist].sh_size; - GElf_Addr newoffset; - - oldoffset = dso->shdr[liblist].sh_offset; - newoffset = oldoffset; - if (newoffset & (data->d_align - 1)) - { - newoffset = (newoffset + data->d_align - 1) & ~(data->d_align - 1); - adjust += newoffset - dso->shdr[liblist].sh_offset; - } - if (adjust_dso_nonalloc (dso, liblist + 1, oldoffset, adjust)) - goto error_out; - dso->shdr[liblist].sh_offset = newoffset; - dso->shdr[liblist].sh_size = data->d_size; - } - - recompute_nonalloc_offsets (dso); - return 0; - -error_out: - free (list); - return 1; -} - -static int -prelink_set_timestamp (struct prelink_info *info) -{ - DSO *dso = info->dso; - - if (! verify) - info->ent->timestamp = getenv ("PRELINK_TIMESTAMP") ? - atoi (getenv ("PRELINK_TIMESTAMP")) - : (GElf_Word) time (NULL); - dso->info_DT_GNU_PRELINKED = info->ent->timestamp; - if (prelink_set_checksum (dso)) - return 1; - info->ent->checksum = dso->info_DT_CHECKSUM; - return 0; -} - -static void -free_info (struct prelink_info *info) -{ - int i; - - free (info->symtab); - free (info->dynbss); - free (info->sdynbss); - free (info->conflict_rela); - if (info->conflicts) - { - for (i = 0; i < info->ent->ndepends + 1; ++i) - { - if (info->conflicts[i].hash == &info->conflicts[i].first) - { - struct prelink_conflict *c = info->conflicts[i].first; - void *f; - - while (c != NULL) - { - f = c; - c = c->next; - free (f); - } - } - else - { - int j; - for (j = 0; j < 251; j++) - { - struct prelink_conflict *c = info->conflicts[i].hash[j]; - void *f; - - while (c != NULL) - { - f = c; - c = c->next; - free (f); - } - } - free (info->conflicts[i].hash); - } - if (info->conflicts[i].hash2 != NULL) - free (info->conflicts[i].hash2); - } - free (info->conflicts); - } - if (info->sonames) - { - for (i = 0; i < info->ent->ndepends + 1; ++i) - free ((char *) info->sonames[i]); - free (info->sonames); - } - free (info->tls); - if (info->symbols) - { - for (i = 0; i < info->symbol_count; ++i) - { - struct prelink_symbol *s = info->symbols[i].next; - void *f; - - while (s != NULL) - { - f = s; - s = s->next; - free (f); - } - } - free (info->symbols); - } -} - -int -prelink (DSO *dso, struct prelink_entry *ent) -{ - int i; - Elf_Scn *scn; - Elf_Data *data; - struct prelink_info info; - - ent->pltgot = dso->info[DT_PLTGOT]; - - if (! dso->info[DT_SYMTAB]) - return 0; - - if (! dso_is_rdwr (dso) && dso->ehdr.e_type == ET_DYN) - { - if (reopen_dso (dso, NULL, NULL)) - return 1; - } - - i = addr_to_sec (dso, dso->info[DT_SYMTAB]); - /* DT_SYMTAB should be found and should point to - start of .dynsym section. */ - if (i == -1 - || dso->info[DT_SYMTAB] != dso->shdr[i].sh_addr) - { - error (0, 0, "%s: Bad symtab", dso->filename); - return 1; - } - - memset (&info, 0, sizeof (info)); - info.ent = ent; - info.symtab_entsize = dso->shdr[i].sh_entsize; - info.symtab = calloc (dso->shdr[i].sh_size / dso->shdr[i].sh_entsize, - sizeof (GElf_Sym)); - if (info.symtab == NULL) - { - error (0, ENOMEM, "%s: Cannot convert .dynsym section", dso->filename); - return 1; - } - - scn = dso->scn[i]; - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx, loc; - - loc = data->d_off / info.symtab_entsize; - maxndx = data->d_size / info.symtab_entsize; - for (ndx = 0; ndx < maxndx; ++ndx) - gelfx_getsym (dso->elf, data, ndx, info.symtab + loc + ndx); - } - info.symtab_start = - adjust_new_to_old (dso, dso->shdr[i].sh_addr - dso->base); - info.symtab_end = info.symtab_start + dso->shdr[i].sh_size; - info.dso = dso; - switch (prelink_get_relocations (&info)) - { - case 0: - goto error_out; - case 1: - info.resolve = resolve_ldso; - break; - case 2: - info.resolve = resolve_dso; - break; - } - - if (dso->arch->arch_pre_prelink && dso->arch->arch_pre_prelink (dso)) - goto error_out; - - if (dso->ehdr.e_type == ET_EXEC) - { - if (prelink_exec (&info)) - goto error_out; - } - else if (prelink_dso (&info)) - goto error_out; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - { - if (! (dso->shdr[i].sh_flags & SHF_ALLOC)) - continue; - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".gnu.conflict")) - continue; - switch (dso->shdr[i].sh_type) - { - case SHT_REL: - if (prelink_rel (dso, i, &info)) - goto error_out; - break; - case SHT_RELA: - if (prelink_rela (dso, i, &info)) - goto error_out; - break; - } - } - - if (dso->arch->arch_prelink && dso->arch->arch_prelink (&info)) - goto error_out; - - if (dso->arch->read_opd && dso->arch->read_opd (dso, ent)) - goto error_out; - - /* Must be last. */ - if (dso->ehdr.e_type == ET_DYN - && prelink_set_timestamp (&info)) - goto error_out; - - free_info (&info); - return 0; - -error_out: - free_info (&info); - return 1; -} diff --git a/trunk/src/prelink.h b/trunk/src/prelink.h deleted file mode 100644 index 299f1fa..0000000 --- a/trunk/src/prelink.h +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2011, - 2013 Red Hat, Inc. - Copyright (C) 2008 CodeSourcery. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - Updated by Maciej W. Rozycki <macro@codesourcery.com>, 2008. - - 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, 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. */ - -#ifndef PRELINK_H -#define PRELINK_H - -#include <elf.h> -#include <libelf.h> -#include <gelfx.h> -#include <ftw.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/stat.h> -#include <utime.h> -#include <glob.h> - -#ifndef HAVE_ELF64_BYTE -typedef uint8_t Elf64_Byte; -#endif - -#ifndef DT_GNU_LIBLIST -#define DT_GNU_LIBLIST 0x6ffffef9 -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 -#define DT_GNU_CONFLICT 0x6ffffef8 -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 -#define DT_GNU_PRELINKED 0x6ffffdf5 -#define SHT_GNU_LIBLIST 0x6ffffff7 -#endif - -#if DT_GNU_LIBLIST == 0x6ffffef7 -#undef DT_GNU_LIBLIST -#undef DT_GNU_CONFLICT -#undef SHT_GNU_LIBLIST -#define DT_GNU_LIBLIST 0x6ffffef9 -#define DT_GNU_CONFLICT 0x6ffffef8 -#define SHT_GNU_LIBLIST 0x6ffffff7 -#endif - -#ifndef DT_GNU_HASH -#define DT_GNU_HASH 0x6ffffef5 -#define SHT_GNU_HASH 0x6ffffff6 -#endif - -#ifndef DT_TLSDESC_PLT -#define DT_TLSDESC_PLT 0x6ffffef6 -#endif - -#ifndef DT_MIPS_RLD_VERSION -#define DT_MIPS_RLD_VERSION 0x70000001 -#define DT_MIPS_TIME_STAMP 0x70000002 -#define DT_MIPS_ICHECKSUM 0x70000003 -#define DT_MIPS_IVERSION 0x70000004 -#define DT_MIPS_FLAGS 0x70000005 -#define DT_MIPS_BASE_ADDRESS 0x70000006 -#define DT_MIPS_CONFLICT 0x70000008 -#define DT_MIPS_LIBLIST 0x70000009 -#define DT_MIPS_LOCAL_GOTNO 0x7000000a -#define DT_MIPS_CONFLICTNO 0x7000000b -#define DT_MIPS_LIBLISTNO 0x70000010 -#define DT_MIPS_SYMTABNO 0x70000011 -#define DT_MIPS_UNREFEXTNO 0x70000012 -#define DT_MIPS_GOTSYM 0x70000013 -#define DT_MIPS_HIPAGENO 0x70000014 -#define DT_MIPS_RLD_MAP 0x70000016 -#endif - -#ifndef R_MIPS_TLS_DTPMOD32 -#define R_MIPS_TLS_DTPMOD32 38 -#define R_MIPS_TLS_DTPREL32 39 -#define R_MIPS_TLS_TPREL32 47 -#endif - -#ifndef R_MIPS_TLS_DTPMOD64 -#define R_MIPS_TLS_DTPMOD64 40 -#define R_MIPS_TLS_DTPREL64 41 -#define R_MIPS_TLS_TPREL64 48 -#endif - -#ifndef R_MIPS_GLOB_DAT -#define R_MIPS_GLOB_DAT 51 -#endif - -#ifndef R_MIPS_COPY -#define R_MIPS_COPY 126 -#define R_MIPS_JUMP_SLOT 127 -#define STO_MIPS_PLT 0x8 -#define DT_MIPS_PLTGOT 0x70000032 -#define DT_MIPS_RWPLT 0x70000034 -#endif - -#ifndef SHT_MIPS_DWARF -#define SHT_MIPS_DWARF 0x7000001e -#endif - -#ifndef RSS_UNDEF -#define RSS_UNDEF 0 -#endif - -#ifndef R_ARM_TLS_DESC -#define R_ARM_TLS_DESC 13 -#endif - -#ifndef R_ARM_TLS_DTPMOD32 -#define R_ARM_TLS_DTPMOD32 17 -#define R_ARM_TLS_DTPOFF32 18 -#define R_ARM_TLS_TPOFF32 19 -#endif - -#ifndef R_386_IRELATIVE -#define R_386_IRELATIVE 42 -#endif - -#ifndef R_X86_64_IRELATIVE -#define R_X86_64_IRELATIVE 37 -#endif - -#ifndef R_PPC_IRELATIVE -#define R_PPC_IRELATIVE 248 -#endif - -#ifndef R_PPC64_JMP_IREL -#define R_PPC64_JMP_IREL 247 -#define R_PPC64_IRELATIVE 248 -#endif - -#ifndef R_390_IRELATIVE -#define R_390_IRELATIVE 61 -#endif - -#ifndef R_ARM_IRELATIVE -#define R_ARM_IRELATIVE 160 -#endif - -struct prelink_entry; -struct prelink_info; -struct PLArch; -struct opd_lib; - -struct PLAdjust -{ - GElf_Addr start; - GElf_Addr adjust; -}; - -struct section_move -{ - int old_shnum; - int new_shnum; - int *old_to_new; - int *new_to_old; -}; - -typedef struct -{ - Elf *elf, *elfro; - GElf_Ehdr ehdr; - GElf_Phdr *phdr; - Elf_Scn **scn; - GElf_Addr base, end, align; - GElf_Addr mask; - GElf_Addr info[DT_NUM]; - GElf_Addr info_DT_GNU_PRELINKED; - GElf_Addr info_DT_CHECKSUM; - GElf_Addr info_DT_VERNEED, info_DT_VERDEF, info_DT_VERSYM; - GElf_Addr info_DT_GNU_HASH; - GElf_Addr info_DT_TLSDESC_PLT; - GElf_Addr info_DT_MIPS_LOCAL_GOTNO; - GElf_Addr info_DT_MIPS_GOTSYM; - GElf_Addr info_DT_MIPS_SYMTABNO; - GElf_Addr info_DT_MIPS_PLTGOT; -#define DT_GNU_PRELINKED_BIT 50 -#define DT_CHECKSUM_BIT 51 -#define DT_VERNEED_BIT 52 -#define DT_VERDEF_BIT 53 -#define DT_VERSYM_BIT 54 -#define DT_FILTER_BIT 55 -#define DT_AUXILIARY_BIT 56 -#define DT_LOPROC_BIT 57 -#define DT_GNU_HASH_BIT 58 -#define DT_TLSDESC_PLT_BIT 59 - uint64_t info_set_mask; - int fd, fdro; - int lastscn, dynamic; - const char *soname; - const char *filename, *temp_filename; - struct PLArch *arch; - struct PLAdjust *adjust; - /* .mdebug has absolute file offsets in it. */ - GElf_Off mdebug_orig_offset; - Elf_Data undo; - int nadjust; - int permissive; - struct section_move *move; - GElf_Shdr shdr[0]; -} DSO; - -static inline int -dynamic_info_is_set (DSO *dso, int bit) -{ - return ((dso)->info_set_mask & (1ULL << (bit))) != 0; -} - -struct layout_libs; - -struct PLArch -{ - const char *name; - int class; - int machine; - int alternate_machine[3]; - int max_reloc_size; - const char *dynamic_linker; - const char *dynamic_linker_alt; - int R_COPY; - int R_JMP_SLOT; - int R_RELATIVE; - int rtype_class_valid; - int (*arch_adjust) (DSO *dso, GElf_Addr start, GElf_Addr adjust); - int (*adjust_section) (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust); - int (*adjust_dyn) (DSO *dso, int n, GElf_Dyn *dyn, GElf_Addr start, - GElf_Addr adjust); - int (*adjust_rel) (DSO *dso, GElf_Rel *rel, GElf_Addr start, - GElf_Addr adjust); - int (*adjust_rela) (DSO *dso, GElf_Rela *rela, GElf_Addr start, - GElf_Addr adjust); - int (*prelink_rel) (struct prelink_info *info, GElf_Rel *rel, - GElf_Addr reladdr); - int (*prelink_rela) (struct prelink_info *info, GElf_Rela *rela, - GElf_Addr relaaddr); - int (*prelink_conflict_rel) (DSO *dso, struct prelink_info *info, - GElf_Rel *rel, GElf_Addr reladdr); - int (*prelink_conflict_rela) (DSO *dso, struct prelink_info *info, - GElf_Rela *rela, GElf_Addr relaaddr); - int (*arch_prelink_conflict) (DSO *dso, struct prelink_info *info); - int (*apply_conflict_rela) (struct prelink_info *info, GElf_Rela *rela, - char *buf, GElf_Addr dest_addr); - int (*apply_rel) (struct prelink_info *info, GElf_Rel *rel, char *buf); - int (*apply_rela) (struct prelink_info *info, GElf_Rela *rela, char *buf); - int (*rel_to_rela) (DSO *dso, GElf_Rel *rel, GElf_Rela *rela); - int (*rela_to_rel) (DSO *dso, GElf_Rela *rela, GElf_Rel *rel); - int (*need_rel_to_rela) (DSO *dso, int first, int last); - GElf_Addr (*create_opd) (struct prelink_info *info, int first, int last, - int plt); - int (*read_opd) (DSO *dso, struct prelink_entry *ent); - int (*free_opd) (struct prelink_entry *ent); - /* Return reloc size in bytes for given non-COPY reloc type. */ - int (*reloc_size) (int); -#define RTYPE_CLASS_VALID 8 -#define RTYPE_CLASS_PLT (8|1) -#define RTYPE_CLASS_COPY (8|2) -#define RTYPE_CLASS_TLS (8|4) - int (*reloc_class) (int); - int (*arch_pre_prelink) (DSO *dso); - int (*arch_prelink) (struct prelink_info *info); - int (*arch_undo_prelink) (DSO *dso); - int (*undo_prelink_rel) (DSO *dso, GElf_Rel *rel, GElf_Addr reladdr); - int (*undo_prelink_rela) (DSO *dso, GElf_Rela *rela, GElf_Addr relaaddr); - int (*layout_libs_init) (struct layout_libs *l); - int (*layout_libs_pre) (struct layout_libs *l); - int (*layout_libs_post) (struct layout_libs *l); - GElf_Addr mmap_base, mmap_end; - /* max_page_size is the ELF page size (ELF_MAXPAGESIZE in bfd), - page_size is PAGE_SIZE the architecture typically has, - or if there are more typical sizes, the smallest one. - It doesn't need to be the absolutely smallest supported one, - prelink only optimizes for such page_size. */ - GElf_Addr max_page_size, page_size; -} __attribute__((aligned(64))); - -DSO * open_dso (const char *name); -DSO * fdopen_dso (int fd, const char *name); -struct section_move *init_section_move (DSO *dso); -void add_section (struct section_move *move, int sec); -void remove_section (struct section_move *move, int sec); -int reopen_dso (DSO *dso, struct section_move *move, const char *); -int adjust_symbol_p (DSO *dso, GElf_Sym *sym); -int check_dso (DSO *dso); -int dso_is_rdwr (DSO *dso); -void read_dynamic (DSO *dso); -int set_dynamic (DSO *dso, GElf_Word tag, GElf_Addr value, int fatal); -int addr_to_sec (DSO *dso, GElf_Addr addr); -int adjust_dso (DSO *dso, GElf_Addr start, GElf_Addr adjust); -int adjust_nonalloc (DSO *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int first, - GElf_Addr start, GElf_Addr adjust); -int adjust_dso_nonalloc (DSO *dso, int first, GElf_Addr start, - GElf_Addr adjust); -int recompute_nonalloc_offsets (DSO *dso); -int adjust_stabs (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust); -int adjust_dwarf2 (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust); -int adjust_mdebug (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust); -int finalize_mdebug (DSO *dso); -int relocate_dso (DSO *dso, GElf_Addr base); -int copy_fd_to_file (int fdin, const char *name, struct stat64 *st); -int update_dso (DSO *dso, const char *); -int prepare_write_dso (DSO *dso); -int write_dso (DSO *dso); -int close_dso (DSO *dso); -GElf_Addr adjust_old_to_new (DSO *dso, GElf_Addr addr); -GElf_Addr adjust_new_to_old (DSO *dso, GElf_Addr addr); -int strtabfind (DSO *dso, int strndx, const char *name); -int shstrtabadd (DSO *dso, const char *name); -int dso_has_bad_textrel (DSO *dso); - -/* data.c */ - -/* Used for reading consecutive blocks of data from a DSO. */ -struct data_iterator { - /* The DSO that is being read. */ - DSO *dso; - - /* The data block that contained the last byte to be read. - NULL if no data has been read yet or if the end of the - DSO has been reached. */ - Elf_Data *data; - - /* The section that contains DATA, when DATA is nonnull. */ - int sec; - - /* The address of the next byte. */ - GElf_Addr addr; - - /* The offset of the next byte from the start of SEC, when DATA - is nonnull. */ - GElf_Addr sec_offset; -}; - -unsigned char * get_data (DSO *dso, GElf_Addr addr, int *scnp, Elf_Type *typep); -#define READWRITEPROTO(le,nn) \ -uint##nn##_t buf_read_u##le##nn (unsigned char *data); \ -uint##nn##_t read_u##le##nn (DSO *dso, GElf_Addr addr); \ -void buf_write_##le##nn (unsigned char *data, uint##nn##_t val);\ -int write_##le##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val); -#define READWRITEPROTOSIZE(nn) \ -READWRITEPROTO(le,nn) \ -READWRITEPROTO(be,nn) \ -uint##nn##_t buf_read_une##nn (DSO *dso, unsigned char *data); \ -uint##nn##_t read_une##nn (DSO *dso, GElf_Addr addr); \ -void buf_write_ne##nn (DSO *dso, unsigned char *data, \ - uint##nn##_t val); \ -void write_ne##nn (DSO *dso, GElf_Addr addr, uint##nn##_t val); -READWRITEPROTO(,8) -READWRITEPROTOSIZE(16) -READWRITEPROTOSIZE(32) -READWRITEPROTOSIZE(64) -#undef READWRITEPROTO -#undef READWRITEPROTOSIZE -const char * strptr (DSO *dso, int sec, off_t offset); -void init_data_iterator (struct data_iterator *it, DSO *dso, GElf_Addr addr); -unsigned char *get_data_from_iterator (struct data_iterator *it, - GElf_Addr size); -int get_sym_from_iterator (struct data_iterator *it, GElf_Sym *sym); - -#define PL_ARCH(F) \ -static struct PLArch plarch_##F __attribute__((section("pl_arch"),used)) - -#define addr_adjust(addr, start, adjust) \ - do { \ - if (addr >= start) \ - addr += adjust; \ - } while (0) - -struct prelink_cache_entry -{ - uint32_t filename; - uint32_t depends; - uint32_t checksum; -#define PCF_UNPRELINKABLE 0x40000 -#define PCF_PRELINKED 0x20000 -#define PCF_ELF64 0x10000 -#define PCF_MACHINE 0x0ffff - uint32_t flags; - uint32_t ctime; - uint32_t mtime; - uint64_t base; - uint64_t end; -}; - -struct prelink_cache -{ -#define PRELINK_CACHE_NAME "prelink-ELF" -#define PRELINK_CACHE_VER "0.3.2" -#define PRELINK_CACHE_MAGIC PRELINK_CACHE_NAME PRELINK_CACHE_VER - const char magic [sizeof (PRELINK_CACHE_MAGIC) - 1]; - uint32_t nlibs; - uint32_t ndeps; - uint32_t len_strings; - uint32_t unused[9]; - struct prelink_cache_entry entry[0]; - /* uint32_t depends [ndeps]; */ - /* const char strings [len_strings]; */ -}; - -struct prelink_link -{ - struct prelink_link *next; - const char *canon_filename; -}; - -struct prelink_entry -{ - const char *filename; - const char *canon_filename; - const char *soname; - struct prelink_link *hardlink; - GElf_Word timestamp; - GElf_Word checksum; - GElf_Addr base, end, layend, pltgot; - dev_t dev; - ino64_t ino; -#define ET_BAD (ET_NUM) -#define ET_CACHE_EXEC (ET_NUM + 1) -#define ET_CACHE_DYN (ET_NUM + 2) -#define ET_UNPRELINKABLE (ET_NUM + 3) - int type, done, ndepends, refs, flags; - union - { - int explicit; - int tmp; - } u; - uint32_t ctime, mtime; - struct prelink_entry **depends; - struct prelink_entry *prev, *next; - struct opd_lib *opd; -}; - -struct prelink_dir -{ - dev_t dev; - struct prelink_dir *next; - size_t len; - int flags; - char dir[0]; -}; - -struct prelink_tls -{ - GElf_Addr modid; - GElf_Addr offset; -}; - -struct prelink_symbol -{ - union - { - struct prelink_entry *ent; - struct prelink_tls *tls; - } u; - struct prelink_symbol *next; - GElf_Addr value; - int reloc_class; -}; - -struct prelink_conflict -{ - struct prelink_conflict *next; - struct prelink_conflict *next2; - /* Object which it was relocated to. */ - union - { - struct prelink_entry *ent; - struct prelink_tls *tls; - } lookup, - /* Object which the relocation was prelinked to. */ - conflict; - /* Offset from start of owner to owner's symbol. */ - GElf_Addr symoff; - /* Value it has in lookup.ent. */ - GElf_Addr lookupval; - /* Value it has in conflict.ent. */ - GElf_Addr conflictval; - int reloc_class; - unsigned char used; - unsigned char ifunc; - char * symname; -}; - -struct prelink_conflicts -{ - struct prelink_conflict *first; - struct prelink_conflict **hash; - struct prelink_conflict **hash2; - size_t count; -}; - -#define conflict_lookup_value(cfl) \ - (((cfl)->reloc_class != RTYPE_CLASS_TLS ? (cfl)->lookup.ent->base : 0) \ - + (cfl)->lookupval) - -struct prelink_info -{ - DSO *dso; - DSO **dsos; - struct prelink_entry *ent; - struct prelink_symbol *symbols; - struct prelink_conflicts *conflicts; - struct prelink_conflicts *curconflicts; - struct prelink_tls *tls, *curtls; - const char **sonames; - char *dynbss, *sdynbss; - GElf_Addr dynbss_base, sdynbss_base; - size_t dynbss_size, sdynbss_size, symtab_entsize; - int symbol_count; - GElf_Sym *symtab; - GElf_Rela *conflict_rela; - size_t conflict_rela_alloced, conflict_rela_size; - GElf_Addr symtab_start, symtab_end; - GElf_Addr (*resolve) (struct prelink_info *info, GElf_Word r_sym, - int reloc_type); - struct prelink_entry *resolveent; - struct prelink_tls *resolvetls; -}; - -int prelink_prepare (DSO *dso); -int prelink (DSO *dso, struct prelink_entry *ent); -int prelink_init_cache (void); -int prelink_load_cache (void); -int prelink_print_cache (void); -int prelink_save_cache (int do_warn); -struct prelink_entry * - prelink_find_entry (const char *filename, const struct stat64 *stp, - int insert); -struct prelink_conflict * - prelink_conflict (struct prelink_info *info, GElf_Word r_sym, - int reloc_type); -GElf_Rela *prelink_conflict_add_rela (struct prelink_info *info); -int prelink_get_relocations (struct prelink_info *info); -int prelink_build_conflicts (struct prelink_info *info); -int update_dynamic_tags (DSO *dso, GElf_Shdr *shdr, GElf_Shdr *old_shdr, - struct section_move *move); -int prelink_exec (struct prelink_info *info); -int prelink_set_checksum (DSO *dso); -int is_ldso_soname (const char *soname); - -int prelink_undo (DSO *dso); - -int prelink_verify (const char *filename); -ssize_t send_file (int outfd, int infd, off_t *poff, size_t count); - -int gather_object (const char *dir, int deref, int onefs); -int read_config (const char *config); -int gather_config (void); -int gather_check_libs (void); -int add_to_blacklist (const char *name, int deref, int onefs); -int blacklist_from_config (void); - -FILE *execve_open (const char *path, char *const argv[], char *const envp[]); -int execve_close (FILE *f); - -int remove_redundant_cxx_conflicts (struct prelink_info *info); -int get_relocated_mem (struct prelink_info *info, DSO *dso, GElf_Addr addr, - char *buf, GElf_Word size, GElf_Addr dest_addr); - -int layout_libs (void); - -void prelink_all (void); - -int undo_all (void); - -char *prelink_canonicalize (const char *name, struct stat64 *stp); - -extern const char *dynamic_linker; -extern const char *ld_library_path; -extern const char *prelink_cache; -extern const char *prelink_conf; -extern const char *undo_output; -extern int all; -extern int force; -extern int random_base; -extern int conserve_memory; -extern int verbose; -extern int dry_run; -extern int libs_only; -extern int enable_cxx_optimizations; -extern int exec_shield; -extern int undo; -extern int verify; -extern int print_cache; -enum verify_method_t { VERIFY_CONTENT, VERIFY_MD5, VERIFY_SHA }; -extern enum verify_method_t verify_method; -extern int quick; -extern long long seed; -extern GElf_Addr mmap_reg_start, mmap_reg_end, layout_page_size; -extern char *ld_preload; - -extern const char *sysroot; - -extern int allow_bad_textrel; - -int wrap_readlink (const char *path, char *buf, int len); -int wrap_lstat64 (const char *file, struct stat64 *buf); -int wrap_stat64 (const char *file, struct stat64 *buf); -int wrap_open (const char *file, int mode, ...); -int wrap_access (const char *file, int mode); -int wrap_rename (const char *old, const char *new); -int wrap_link (const char *old, const char *new); -int wrap_nftw64 (const char *dir, __nftw64_func_t func, - int descriptors, int flag); -int wrap_utime (const char *file, struct utimbuf *file_times); -int wrap_mkstemp (char *filename); -int wrap_unlink (const char *filename); -ssize_t wrap_listxattr (const char *path, char *list, size_t size); -ssize_t wrap_getxattr (const char *path, const char *name, void *value, - size_t size); -int wrap_setxattr (const char *path, const char *name, const void *value, - size_t size, int flags); -int wrap_glob (const char *pattern, int flags, - int (*errfunc) (const char *epath, int eerrno), - glob_t *pglob); - -char *sysroot_file_name (const char *name, int allow_last_link); - -extern const char *prelink_rtld; - -#endif /* PRELINK_H */ diff --git a/trunk/src/prelinktab.h b/trunk/src/prelinktab.h deleted file mode 100644 index f41c79c..0000000 --- a/trunk/src/prelinktab.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (C) 2001 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef PRELINKTAB_H -#define PRELINKTAB_H - -#include "hashtab.h" -#include "prelink.h" - -extern htab_t prelink_devino_htab, prelink_filename_htab; -extern int prelink_entry_count; - -#endif /* PRELINKTAB_H */ diff --git a/trunk/src/reloc-info.c b/trunk/src/reloc-info.c deleted file mode 100644 index 4ce333c..0000000 --- a/trunk/src/reloc-info.c +++ /dev/null @@ -1,215 +0,0 @@ -/* Copyright (C) 2008 CodeSourcery - Written by Maciej W. Rozycki <macro@codesourcery.com>, 2008. - - 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, 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 <config.h> - -#include "prelink.h" -#include "reloc-info.h" - -/* A structure to lay out generic relocation information - * in a way specific to 64-bit MIPS. */ -union mips64_r_info -{ - /* Generic r_info interpretation. */ - Elf64_Xword r_info; - - /* 64-bit MIPS r_info interpretation. */ - struct - { - /* Symbol index for the first relocation. */ - Elf64_Word r_sym; - - /* Special symbol for the second relocation. */ - Elf64_Byte r_ssym; - - /* Third relocation. */ - Elf64_Byte r_type3; - - /* Second relocation. */ - Elf64_Byte r_type2; - - /* First relocation. */ - Elf64_Byte r_type; - } - s_info; -}; - -/* Extract the symbol index from 64-bit MIPS reloc info. */ - -static GElf_Xword -mips64_r_sym (DSO *dso, GElf_Xword r_info) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne64 (dso, (unsigned char *) &mips64_r_info.r_info, r_info); - return buf_read_une32 (dso, (unsigned char *) &mips64_r_info.s_info.r_sym); -} - -/* Extract the special symbol index from 64-bit MIPS reloc info. */ - -static GElf_Xword -mips64_r_ssym (DSO *dso, GElf_Xword r_info) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne64 (dso, (unsigned char *) &mips64_r_info.r_info, r_info); - return mips64_r_info.s_info.r_ssym; -} - -/* Extract the first reloc type from 64-bit MIPS reloc info. */ - -static GElf_Xword -mips64_r_type (DSO *dso, GElf_Xword r_info) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne64 (dso, (unsigned char *) &mips64_r_info.r_info, r_info); - return mips64_r_info.s_info.r_type; -} - -/* Extract the second reloc type from 64-bit MIPS reloc info. */ - -static GElf_Xword -mips64_r_type2 (DSO *dso, GElf_Xword r_info) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne64 (dso, (unsigned char *) &mips64_r_info.r_info, r_info); - return mips64_r_info.s_info.r_type2; -} - -/* Extract the third reloc type from 64-bit MIPS reloc info. */ - -static GElf_Xword -mips64_r_type3 (DSO *dso, GElf_Xword r_info) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne64 (dso, (unsigned char *) &mips64_r_info.r_info, r_info); - return mips64_r_info.s_info.r_type3; -} - -/* Construct 64-bit MIPS reloc info from symbol indices and reloc types. */ - -static GElf_Xword -mips64_r_info_ext (DSO *dso, GElf_Word r_sym, Elf64_Byte r_ssym, - Elf64_Byte r_type, Elf64_Byte r_type2, Elf64_Byte r_type3) -{ - union mips64_r_info mips64_r_info; - - buf_write_ne32 (dso, (unsigned char *) &mips64_r_info.s_info.r_sym, r_sym); - mips64_r_info.s_info.r_ssym = r_ssym; - mips64_r_info.s_info.r_type = r_type; - mips64_r_info.s_info.r_type2 = r_type2; - mips64_r_info.s_info.r_type3 = r_type3; - return buf_read_une64 (dso, (unsigned char *) &mips64_r_info.r_info); -} - - -/* Extract the symbol index from reloc info. */ - -GElf_Xword -reloc_r_sym (DSO *dso, GElf_Xword r_info) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_sym (dso, r_info); - else - return GELF_R_SYM (r_info); -} - -/* Extract the special symbol index from reloc info. */ - -GElf_Xword -reloc_r_ssym (DSO *dso, GElf_Xword r_info) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_ssym (dso, r_info); - else - return RSS_UNDEF; -} - -/* Extract the first reloc type from reloc info. */ - -GElf_Xword -reloc_r_type (DSO *dso, GElf_Xword r_info) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_type (dso, r_info); - else - return GELF_R_TYPE (r_info); -} - -/* Extract the second reloc type from reloc info. */ - -GElf_Xword -reloc_r_type2 (DSO *dso, GElf_Xword r_info) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_type2 (dso, r_info); - else - return 0; -} - -/* Extract the third reloc type from reloc info. */ - -GElf_Xword -reloc_r_type3 (DSO *dso, GElf_Xword r_info) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_type3 (dso, r_info); - else - return 0; -} - -/* Construct reloc info from symbol index and reloc type. */ - -GElf_Xword -reloc_r_info (DSO *dso, GElf_Word r_sym, GElf_Word r_type) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - switch (r_type) - { - case R_MIPS_REL32: - case R_MIPS_GLOB_DAT: - return mips64_r_info_ext (dso, r_sym, RSS_UNDEF, - r_type, R_MIPS_64, R_MIPS_NONE); - default: - return mips64_r_info_ext (dso, r_sym, RSS_UNDEF, - r_type, R_MIPS_NONE, R_MIPS_NONE); - } - else - return GELF_R_INFO (r_sym, r_type); -} - -/* Construct reloc info from symbol index and reloc type. */ - -GElf_Xword -reloc_r_info_ext (DSO *dso, GElf_Word r_sym, Elf64_Byte r_ssym, - Elf64_Byte r_type, Elf64_Byte r_type2, Elf64_Byte r_type3) -{ - if (dso->ehdr.e_ident[EI_CLASS] == ELFCLASS64 - && dso->ehdr.e_machine == EM_MIPS) - return mips64_r_info_ext (dso, r_sym, r_ssym, r_type, r_type2, r_type3); - else - return GELF_R_INFO (r_sym, r_type); -} diff --git a/trunk/src/reloc-info.h b/trunk/src/reloc-info.h deleted file mode 100644 index a8f8b7c..0000000 --- a/trunk/src/reloc-info.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2008 CodeSourcery - Written by Maciej W. Rozycki <macro@codesourcery.com>, 2008. - - 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, 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. */ - -#ifndef RELOC_INFO_H -#define RELOC_INFO_H - -#include "prelink.h" - -/* Reloc info primitives. */ -GElf_Xword reloc_r_sym (DSO *dso, GElf_Xword r_info); -GElf_Xword reloc_r_ssym (DSO *dso, GElf_Xword r_info); -GElf_Xword reloc_r_type (DSO *dso, GElf_Xword r_info); -GElf_Xword reloc_r_type2 (DSO *dso, GElf_Xword r_info); -GElf_Xword reloc_r_type3 (DSO *dso, GElf_Xword r_info); - -GElf_Xword reloc_r_info (DSO *dso, GElf_Word r_sym, GElf_Word r_type); -GElf_Xword reloc_r_info_ext (DSO *dso, GElf_Word r_sym, Elf64_Byte r_ssym, - Elf64_Byte r_type, Elf64_Byte r_type2, - Elf64_Byte r_type3); - -#endif /* RELOC_INFO_H */ diff --git a/trunk/src/reloc.c b/trunk/src/reloc.c deleted file mode 100644 index deb0abe..0000000 --- a/trunk/src/reloc.c +++ /dev/null @@ -1,427 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2005 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" - -int -find_reloc_sections (DSO *dso, struct reloc_info *rinfo) -{ - int first, last, rela, i, pltfirst; - GElf_Addr start, end, pltstart, pltend; - - memset (rinfo, 0, sizeof (*rinfo)); - - if (dynamic_info_is_set (dso, DT_REL) - && dynamic_info_is_set (dso, DT_RELA)) - { - error (0, 0, "%s: Cannot prelink object with both DT_REL and DT_RELA tags", - dso->filename); - return 1; - } - - rela = dynamic_info_is_set (dso, DT_RELA); - - if (rela) - { - start = dso->info[DT_RELA]; - end = dso->info[DT_RELA] + dso->info[DT_RELASZ]; - } - else - { - start = dso->info[DT_REL]; - end = dso->info[DT_REL] + dso->info[DT_RELSZ]; - } - rinfo->reldyn_rela = rela; - - if (dso->info[DT_JMPREL]) - { - pltstart = dso->info[DT_JMPREL]; - pltend = dso->info[DT_JMPREL] + dso->info[DT_PLTRELSZ]; - pltfirst = first = addr_to_sec (dso, pltstart); - last = addr_to_sec (dso, pltend - 1); - if (first == -1 - || last == -1 - || first != last - || dso->shdr[first].sh_addr != pltstart - || dso->shdr[first].sh_addr + dso->shdr[first].sh_size != pltend - || (dso->info[DT_PLTREL] != DT_REL - && dso->info[DT_PLTREL] != DT_RELA) - || dso->shdr[first].sh_type - != (dso->info[DT_PLTREL] == DT_RELA ? SHT_RELA : SHT_REL) - || strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[first].sh_name), - dso->info[DT_PLTREL] == DT_RELA - ? ".rela.plt" : ".rel.plt")) - { - error (0, 0, "%s: DT_JMPREL tags don't surround .rel%s.plt section", - dso->filename, dso->info[DT_PLTREL] == DT_RELA ? "a" : ""); - return 1; - } - rinfo->plt = first; - rinfo->plt_rela = (dso->shdr[first].sh_type == SHT_RELA); - if (dso->shdr[first].sh_type == SHT_REL - && dso->arch->need_rel_to_rela != NULL - && dso->arch->need_rel_to_rela (dso, first, first)) - rinfo->rel_to_rela_plt = 1; - } - else - { - pltstart = end; - pltend = end; - pltfirst = 0; - } - - if (start == 0 && end == 0) - { - /* No non-PLT relocations. */ - return 0; - } - - if (start == end) - { - first = 0; - last = 0; - } - else - { - first = addr_to_sec (dso, start); - last = addr_to_sec (dso, end - 1); - - if (first == -1 - || last == -1 - || dso->shdr[first].sh_addr != start - || dso->shdr[last].sh_addr + dso->shdr[last].sh_size != end) - { - error (0, 0, "%s: DT_REL%s tags don't surround whole relocation sections", - dso->filename, rela ? "A" : ""); - return 1; - } - - for (i = first; i <= last; i++) - if (dso->shdr[i].sh_type != (rela ? SHT_RELA : SHT_REL)) - { - error (0, 0, "%s: DT_REL%s tags don't surround relocation sections of expected type", - dso->filename, rela ? "A" : ""); - return 1; - } - } - - if (pltstart != end && pltend != end - /* There is a gap between .rel(a).dyn and .rel(a).plt sections. - The gap may be due to a linker optimization, in which case - the sections are still adjacent, with a zero-filled gap in-between. */ - && last + 1 != pltfirst) - { - error (0, 0, "%s: DT_JMPREL tag not adjacent to DT_REL%s relocations", - dso->filename, rela ? "A" : ""); - return 1; - } - - if (pltstart == start && pltend == end) - { - /* No non-PLT relocations. */ - rinfo->overlap = 1; - return 0; - } - - if (pltstart != end && pltend == end) - { - rinfo->overlap = 1; - --last; - } - - rinfo->first = first; - rinfo->last = last; - if (! rela - && first - && dso->arch->need_rel_to_rela != NULL - && dso->arch->need_rel_to_rela (dso, first, last)) - rinfo->rel_to_rela = 1; - return 0; -} - -int -convert_rel_to_rela (DSO *dso, int i) -{ - Elf_Data d1, d2, *d; - Elf_Scn *scn; - GElf_Rel rel; - GElf_Rela rela; - int ndx, maxndx; - - scn = dso->scn[i]; - d = elf_getdata (scn, NULL); - assert (elf_getdata (scn, d) == NULL); - assert (d->d_off == 0); - assert (d->d_size == dso->shdr[i].sh_size); - d1 = *d; - d2 = *d; - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - d1.d_size = d->d_size / 2 * 3; - d1.d_buf = malloc (d1.d_size); - d1.d_type = ELF_T_RELA; - if (d1.d_buf == NULL) - { - error (0, ENOMEM, "Cannot convert REL section to RELA"); - return 1; - } - - maxndx = d->d_size / dso->shdr[i].sh_entsize; - for (ndx = 0; ndx < maxndx; ndx++) - { - if (gelfx_getrel (dso->elf, d, ndx, &rel) == 0 - || dso->arch->rel_to_rela (dso, &rel, &rela)) - { - free (d1.d_buf); - return 1; - } - /* gelf_update_rel etc. should have Elf * argument, so that - we don't have to do this crap. */ - *d = d1; - if (gelfx_update_rela (dso->elf, d, ndx, &rela) == 0) - { - *d = d2; - free (d1.d_buf); - return 1; - } - *d = d2; - } - - free (d2.d_buf); - *d = d1; - dso->shdr[i].sh_entsize - = gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - dso->shdr[i].sh_type = SHT_RELA; - return 0; -} - -int -convert_rela_to_rel (DSO *dso, int i) -{ - Elf_Data d1, d2, *d; - Elf_Scn *scn; - GElf_Rel rel; - GElf_Rela rela; - int ndx, maxndx; - - scn = dso->scn[i]; - d = elf_getdata (scn, NULL); - assert (elf_getdata (scn, d) == NULL); - assert (d->d_off == 0); - assert (d->d_size == dso->shdr[i].sh_size); - d1 = *d; - d2 = *d; - assert (sizeof (Elf32_Rel) * 3 == sizeof (Elf32_Rela) * 2); - assert (sizeof (Elf64_Rel) * 3 == sizeof (Elf64_Rela) * 2); - d1.d_size = d->d_size / 3 * 2; - d1.d_buf = malloc (d1.d_size); - d1.d_type = ELF_T_REL; - if (d1.d_buf == NULL) - { - error (0, ENOMEM, "Cannot convert RELA section to REL"); - return 1; - } - - maxndx = d->d_size / dso->shdr[i].sh_entsize; - for (ndx = 0; ndx < maxndx; ndx++) - { - if (gelfx_getrela (dso->elf, d, ndx, &rela) == 0 - || dso->arch->rela_to_rel (dso, &rela, &rel)) - { - free (d1.d_buf); - return 1; - } - /* gelf_update_rela etc. should have Elf * argument, so that - we don't have to do this crap. */ - *d = d1; - if (gelfx_update_rel (dso->elf, d, ndx, &rel) == 0) - { - *d = d2; - free (d1.d_buf); - return 1; - } - *d = d2; - } - - free (d2.d_buf); - *d = d1; - dso->shdr[i].sh_entsize - = gelf_fsize (dso->elf, ELF_T_REL, 1, EV_CURRENT); - dso->shdr[i].sh_type = SHT_REL; - return 0; -} - -int -update_dynamic_rel (DSO *dso, struct reloc_info *rinfo) -{ - GElf_Dyn *info[DT_NUM], *info_DT_RELCOUNT, *info_DT_RELACOUNT; - GElf_Dyn *dynamic = NULL; - int rel = rinfo->first, plt = rinfo->plt, overlap = rinfo->overlap; - int dynsec, count = 0, loc; - Elf_Data *data; - Elf_Scn *scn = NULL; - - memset (&info, 0, sizeof (info)); - info_DT_RELCOUNT = NULL; - info_DT_RELACOUNT = NULL; - for (dynsec = 0; dynsec < dso->ehdr.e_shnum; dynsec++) - if (dso->shdr[dynsec].sh_type == SHT_DYNAMIC) - { - scn = dso->scn[dynsec]; - dynamic = alloca (dso->shdr[dynsec].sh_size - / dso->shdr[dynsec].sh_entsize * sizeof (GElf_Dyn)); - loc = 0; - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - - maxndx = data->d_size / dso->shdr[dynsec].sh_entsize; - for (ndx = 0; ndx < maxndx; ++ndx, ++loc) - { - gelfx_getdyn (dso->elf, data, ndx, dynamic + loc); - if (dynamic[loc].d_tag == DT_NULL) - break; - else if ((GElf_Xword) dynamic[loc].d_tag < DT_NUM) - info[dynamic[loc].d_tag] = dynamic + loc; - else if (dynamic[loc].d_tag == DT_RELCOUNT) - info_DT_RELCOUNT = dynamic + loc; - else if (dynamic[loc].d_tag == DT_RELACOUNT) - info_DT_RELACOUNT = dynamic + loc; - } - if (ndx < maxndx) - break; - } - count = loc; - break; - } - - if (rel && plt && overlap) - { - if (dso->shdr[rel].sh_type != dso->shdr[plt].sh_type) - overlap = 0; - } - - if (rel || (plt && overlap)) - { - int dt_RELENT, dt_REL, dt_RELSZ; - - if (rinfo->reldyn_rela) - { - dt_RELENT = DT_RELAENT; - dt_REL = DT_RELA; - dt_RELSZ = DT_RELASZ; - } - else - { - dt_RELENT = DT_RELENT; - dt_REL = DT_REL; - dt_RELSZ = DT_RELSZ; - } - - assert (dso->info[dt_RELENT] - == gelf_fsize (dso->elf, rinfo->reldyn_rela - ? ELF_T_RELA : ELF_T_REL, 1, EV_CURRENT)); - assert (dso->info[dt_REL] != 0); - assert (dso->info[dt_RELSZ] != 0); - - info[dt_REL]->d_un.d_ptr = dso->shdr[rel ?: plt].sh_addr; - if (plt && overlap) - info[dt_RELSZ]->d_un.d_val = - dso->shdr[plt].sh_addr + dso->shdr[plt].sh_size; - else - info[dt_RELSZ]->d_un.d_val = - dso->shdr[rinfo->last].sh_addr + dso->shdr[rinfo->last].sh_size; - info[dt_RELSZ]->d_un.d_val -= info[dt_REL]->d_un.d_ptr; - - if (!rinfo->reldyn_rela && dso->shdr[rel ?: plt].sh_type == SHT_RELA) - { - info[DT_RELENT]->d_un.d_val = - gelf_fsize (dso->elf, ELF_T_RELA, 1, EV_CURRENT); - info[DT_REL]->d_tag = DT_RELA; - info[DT_RELSZ]->d_tag = DT_RELASZ; - info[DT_RELENT]->d_tag = DT_RELAENT; - if (info_DT_RELCOUNT) - info_DT_RELCOUNT->d_tag = DT_RELACOUNT; - } - else if (rinfo->reldyn_rela && dso->shdr[rel ?: plt].sh_type == SHT_REL) - { - info[DT_RELAENT]->d_un.d_val = - gelf_fsize (dso->elf, ELF_T_REL, 1, EV_CURRENT); - info[DT_RELA]->d_tag = DT_REL; - info[DT_RELASZ]->d_tag = DT_RELSZ; - info[DT_RELAENT]->d_tag = DT_RELENT; - if (info_DT_RELACOUNT) - info_DT_RELACOUNT->d_tag = DT_RELCOUNT; - } - } - - if (plt) - { - assert (dso->info[DT_JMPREL] != 0); - assert (dso->info[DT_PLTREL] == rinfo->plt_rela ? DT_RELA : DT_REL); - - info[DT_JMPREL]->d_un.d_ptr = dso->shdr[plt].sh_addr; - if (!rinfo->plt_rela && dso->shdr[plt].sh_type == SHT_RELA) - { - info[DT_PLTREL]->d_un.d_val = DT_RELA; - info[DT_PLTRELSZ]->d_un.d_val = dso->shdr[plt].sh_size; - } - else if (rinfo->plt_rela && dso->shdr[plt].sh_type == SHT_REL) - { - info[DT_PLTREL]->d_un.d_val = DT_REL; - info[DT_PLTRELSZ]->d_un.d_val = dso->shdr[plt].sh_size; - } - - if (!rel && !overlap) - { - int dt_REL = rinfo->reldyn_rela ? DT_RELA : DT_REL; - - if (info[dt_REL] && info[dt_REL]->d_un.d_ptr) - info[dt_REL]->d_un.d_ptr = info[DT_JMPREL]->d_un.d_ptr; - } - } - - loc = 0; - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - - maxndx = data->d_size / dso->shdr[dynsec].sh_entsize; - for (ndx = 0; ndx < maxndx && loc < count; ++ndx, ++loc) - if ((GElf_Xword) dynamic[loc].d_tag < DT_NUM - || dynamic[loc].d_tag == DT_RELCOUNT - || dynamic[loc].d_tag == DT_RELACOUNT) - gelfx_update_dyn (dso->elf, data, ndx, dynamic + loc); - if (ndx < maxndx) - break; - } - - read_dynamic (dso); - return 0; -} diff --git a/trunk/src/reloc.h b/trunk/src/reloc.h deleted file mode 100644 index a2ceff9..0000000 --- a/trunk/src/reloc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2001, 2002 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef RELOC_H -#define RELOC_H - -#include "prelink.h" - -struct reloc_info -{ - int first; /* First dynamic SHT_REL* section. */ - int last; /* Last dynamic SHT_REL* section not counting .rel*.plt. */ - int plt; /* .rel*.plt section. */ - int overlap; /* 1 if DT_REL{,A}SZ range includes DT_PLTRELSZ range. */ - int reldyn_rela; /* first..last sections were originally RELA. */ - int plt_rela; /* plt section was originally RELA. */ - int rel_to_rela; /* first..last sections have to be converted REL->RELA. */ - int rel_to_rela_plt; /* plt section has to be converted REL->RELA. */ - int relcount; /* DT_RELCOUNT resp. DT_RELACOUNT. */ -}; - -int find_reloc_sections (DSO *dso, struct reloc_info *rinfo); -int convert_rel_to_rela (DSO *dso, int i); -int convert_rela_to_rel (DSO *dso, int i); -int update_dynamic_rel (DSO *dso, struct reloc_info *rinfo); -int undo_sections (DSO *dso, int undo, struct section_move *move, - struct reloc_info *rinfo, GElf_Ehdr *ehdr, - GElf_Phdr *phdr, GElf_Shdr *shdr); - -#endif /* RELOC_H */ diff --git a/trunk/src/rtld/COPYING b/trunk/src/rtld/COPYING deleted file mode 100644 index d159169..0000000 --- a/trunk/src/rtld/COPYING +++ /dev/null @@ -1,339 +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 Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/trunk/src/rtld/COPYING.LIB b/trunk/src/rtld/COPYING.LIB deleted file mode 100644 index 4362b49..0000000 --- a/trunk/src/rtld/COPYING.LIB +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/trunk/src/rtld/ChangeLog b/trunk/src/rtld/ChangeLog deleted file mode 100644 index ae208d7..0000000 --- a/trunk/src/rtld/ChangeLog +++ /dev/null @@ -1,267 +0,0 @@ -2015-10-21 Mark Hatle <mark.hatle@windriver.com> - * rtld/: Resync to glibc-2.22 - * rtld/*: Update copyright dates to match glibc-2.22 - * rtld/rtld.c: Update the elf_machine_type class entries - Add support for ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA via - new extern_protected_data function. - rename reloc_typeclass to elf_machine_type_class - add machine_no_rela, machine_no_rel funcs - Update debug msg - Fix missing dso_list->map = NULL - * rtld/dl-tls.c: (rtld_determine_tlsoffsets) add NIOS2 definition - * rtld/dl-lookup.c: Add EXTERN_PROTECTED_DATA support - * rtld/dl-lookupX.h: Add EXTERN_PROTECTED_DATA support - update debug msgs - * rtld/dl-load.c: (create_map_object_from_dso_ent) Add ld.so like debug - When an executable sets a load address use it - Update the load address calculation, prevents visual overlaps - * rtld/dl-version.c: update debug msgs - * rtld/rtld.h: define _dl_debug_printf to act like ld.so debug - define RTLD_DEBUG_PID to set the debug prefix - - * glibc changes directly affecting the implementation: - - 2013-12-04 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> - Alan Modra <amodra@gmail.com> - * libc/sysdeps/powerpc/powerpc64/dl-machine.h - (elf_machine_type_class): Use SHN_UNDEF PLT handling for ELFv2 ABI. - - 2015-01-18 Chung-Lin Tang <cltang@codesourcery.com> - Sandra Loosemore <sandra@codesourcery.com> - Andrew Jenner <andrew@codesourcery.com> - Joseph Myers <joseph@codesourcery.com> - Nathan Sidwell <nathan@codesourcery.com> - * sysdeps/nios2/dl-machine.h: New file. - - 2015-03-31 H.J. Lu <hongjiu.lu@intel.com> - * elf/dl-lookup.c (do_lookup_x): When UNDEF_MAP is NULL, which - indicates it is called from do_lookup_x on relocation against - protected data, skip the data definion in the executable from - copy reloc. - (_dl_lookup_symbol_x): Pass ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA, - instead of ELF_RTYPE_CLASS_PLT, to do_lookup_x for - EXTERN_PROTECTED_DATA relocation against STT_OBJECT symbol. - * sysdeps/i386/dl-machine.h (elf_machine_type_class): Set class - to ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA for R_386_GLOB_DAT. - * sysdeps/x86_64/dl-machine.h (elf_machine_type_class): Set class - to ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA for R_X86_64_GLOB_DAT. - - 2015-07-24 Szabolcs Nagy <szabolcs.nagy@arm.com> - * sysdeps/aarch64/dl-machine.h (elf_machine_type_class): Handle - ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA. - * sysdeps/arm/dl-machine.h (elf_machine_type_class): Handle - ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA. - -2015-09-11 Vaneet Narang <v.narang@samsung.com> - * rtld/rtld.c: Add ability to specify preloaded libraries - -2015-09-09 Maninder Singh <maninder1.s@samsung.com> - Mark Hatle <mark.hatle@windriver.com> - * rtld/rtld.c: dso null pointer check fix - -2015-04-06 Mark Hatle <mark.hatle@windriver.com> - Maninder Singh <maninder1.s@samsung.com> - * rtld/dl-version.c: Add debug for mising ld-linux or libc.so - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * rtld/rtld.c: Sync aarch64 elf_machine_type_class (dl-machine.h) - (do_relocs): fix comparison pltrel_end >= rel_end - * rtld/dl-tls.c: Add basic aarch64 support - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * rtld/: Resync to glibc-2.20 - Replace referenced to GLRO_dl_debug_mask to - GLRO(dl_debug_mask) - - * rtld/rtld.h: Sync DL_DEBUG_* defines from ldsodefs.h - add DSO_FILENAME and RTLD_PROGNAME definitions - Move to __glibc_unlikely/likely instead of __builtin_expect - rename link_map and update unique_sym_table to match glibc - - * rtld/dl-hash.h: - Apply glibc changes: - 2011-12-03 Ulrich Drepper <drepper@gmail.com> - Fix more warnings - - 2011-12-04 Ulrich Drepper <drepper@gmail.com> - Fix attreibute for _dl_elf_hash - - 2011-12-04 Ulrich Drepper <drepper@gmail.com> - Small optimization of generic ELF hash function - - 2011-12-10 Ulrich Drepper <drepper@gmail.com> - Optimize generic ELF hash function a bit more - - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2013-01-02 Joseph Myers <joseph@codesourcery.com> - Update copyright notices with scripts/update-copyrights. - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - * rtld/dl-load.c: split (_dl_new_object) move to dl-object - Remove VERSYMIDX, already defined in rtld.h - - Apply glibc changes: - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2012-04-04 Siddhesh Poyarekar <siddhesh@redhat.com> - (Updated copyright date) - - 2013-01-02 Joseph Myers <joseph@codesourcery.com> - Update copyright notices with scripts/update-copyrights. - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - 2014-02-10 Ond<C5><99>ej B<C3><AD>lka <neleai@seznam.cz> - Use glibc_likely instead __builtin_expect. - - * rtld/dl-object.c: - Apply glibc changes: - 2013-11-11 Jan Kratochvil <jan.kratochvil@redhat.com> - [BZ #387] - * elf/dl-object.c (_dl_new_object): Initialize L_NAME from NEWNAME if - it is empty. - - * rtld/dl-lookup.c, rtld/dl-lookupX.h: - Apply glibc changes: - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2012-04-05 David S. Miller <davem@davemloft.net> - * elf/dl-lookup (_dl_lookup_symbol_x): If DL_DEBUG_UNUSED, ignore - undefined symbol errors. - - 2012-08-14 Roland McGrath <roland@hack.frob.com> - (Updated copyright date) - - 2013-01-02 Joseph Myers <joseph@codesourcery.com> - Update copyright notices with scripts/update-copyrights. - - 2013-05-29 Siddhesh Poyarekar <siddhesh@redhat.com> - Avoid crashing in LD_DEBUG when program name is unavailable - - 2013-11-13 Marcus Shawcroft <marcus.shawcroft@linaro.org> - Avoid passing NULL to DSO_FILENAME. - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - 2014-02-10 Ond<C5><99>ej B<C3><AD>lka <neleai@seznam.cz> - Use glibc_likely instead __builtin_expect. - - 2014-02-11 Joseph Myers <joseph@codesourcery.com> - Merge MIPS dl-lookup.c into generic file. - * elf/dl-lookup.c (ELF_MACHINE_SYM_NO_MATCH): Define if not - already defined. - (do_lookup_x): Use ELF_MACHINE_SYM_NO_MATCH. - * sysdeps/mips/dl-lookup.c: Remove. - * sysdeps/mips/dl-machine.h (ELF_MACHINE_SYM_NO_MATCH): New macro. - - 2014-02-28 Carlos O'Donell <carlos@redhat.com> - Promote do_lookup_x:check_match to a full function. - - 2014-04-02 Will Newton <will.newton@linaro.org> - elf/dl-lookup.c: Remove obsolete comment about nested function - * elf/dl-lookup.c (do_lookup_x): Remove comment - referring to nested function and move variable - declarations down to before first use. - - 2014-04-04 Will Newton <will.newton@linaro.org> - elf/dl-lookup.c: Remove unnecessary static variable - * elf/dl-lookup.c (undefined_msg): Remove variable. - (_dl_lookup_symbol_x): Replace undefined_msg with string - literal. - - 2014-04-11 Will Newton <will.newton@linaro.org> - elf/dl-lookup.c: Use __glibc_likely and __glibc_unlikely - - * rtld/dl-misc.c: - Apply glibc changes: - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2013-01-02 Joseph Myers <joseph@codesourcery.com> - Update copyright notices with scripts/update-copyrights. - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - * rtld/dl-tls.c: - Sync spacing with glibc for easier diffs (content remained the same) - - Apply glibc changes: - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - * rtld/dl-version: - Apply glibc changes: - 2012-02-09 Paul Eggert <eggert@cs.ucla.edu> - Replace FSF snail mail address with URLs. - - 2013-01-02 Joseph Myers <joseph@codesourcery.com> - Update copyright notices with scripts/update-copyrights. - - 2013-05-29 Siddhesh Poyarekar <siddhesh@redhat.com> - Avoid crashing in LD_DEBUG when program name is unavailable - - 2014-01-01 Allan McRae <allan@archlinux.org> - Update copyright notices with scripts/update-copyrights - - 2014-02-10 Ond<C5><99>ej B<C3><AD>lka <neleai@seznam.cz> - Use glibc_likely instead __builtin_expect. - -2014-12-10 Mark Hatle <mark.hatle@windriver.com> - * rtld/COPYING, rtld/COPYING.LIB, - rtld/ChangeLog, rtld/README-rtld: Add local history - information to setup for a resync to glibc-2.20 - -2012-09-12 Joseph Myers <joseph@codesourcery.com> - * rtld/dl-lookup.c: Fix variable copy reloc when host/target - byte size is different - -2012-04-10 Maxim Kuvyrkov <maxim@codesourcery.com> - * rtld/rtld.c (find_lib_by_soname): Follow ld.so's behavior of - pulling its name from PT_INTERP. - -2012-01-26 Mark Hatle <mark.hatle@windriver.com> - * elf.h, rtld/dl-lookupX.h, rtld/rtld.c: Sync to eglibc 2.15 - -2011-12-08 Mark Hatle <mark.hatle@windriver.com> - * rtld/rtld.c: Add support for $ORIGIN, $PLATFORM and $LIB. - Note: $PLATFORM = "" - -2011-12-08 Mark Hatle <mark.hatle@windriver.com> - * rtld/rtld.c: Fix an issue where missing objects would trigger - an assert in dl-version.c - * rtld/rtld.h: Add _dl_new_object prototype - -2011-09-13 Mark Hatle <mark.hatle@windriver.com> - * Fix printf problem causing prelink-rtld issues on x86 (32-bit) - and arm - -2011-08-26 Mark Hatle <mark.hatle@windriver.com> - * Add a special check for invalid GNU_HASH entries - -2011-08-26 Mark Hatle <mark.hatle@windriver.com> - * Sync to eglibc 2.13 ld.so code - * sync elf_machine_type_class macros for supports archs - -2011-08-26 Mark Hatle <mark.hatle@windriver.com> - * Sync to eglibc 2.13 ld.so code - * mips specific items from ports - -2011-08-26 Mark Hatle <mark.hatle@windriver.com> - * Rename ld-libs.c to rtld.c - * Sync to eglibc 2.13 ld.so code - -2011-08-18 Mark Hatle <mark.hatle@windriver.com> - * Move prelink-rtld specific components to rtld - diff --git a/trunk/src/rtld/Makefile.am b/trunk/src/rtld/Makefile.am deleted file mode 100644 index b02c745..0000000 --- a/trunk/src/rtld/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -PKGVERSION = "\"@PKGVERSION@\"" -REPORT_BUGS_TO = "\"@REPORT_BUGS_TO@\"" - -DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall -Wno-pointer-sign -AM_CFLAGS = -Wall -Wno-pointer-sign -AM_CPPFLAGS = -DSBINDIR='"@sbindir@"' -DBINDIR='"@bindir@"' \ - -DEXECSTACK_PROG="\"`echo execstack | sed '$(transform)'`\"" \ - -DPRELINK_PROG="\"`echo prelink | sed '$(transform)'`\"" \ - -DPRELINK_RTLD_PROG="\"`echo prelink-rtld | \ - sed '$(transform)'`\"" \ - -DEXEEXT='"$(EXEEXT)"' \ - -DPKGVERSION=$(PKGVERSION) \ - -DREPORT_BUGS_TO=$(REPORT_BUGS_TO) -INCLUDES = -I$(top_srcdir)/src @GELFINCLUDE@ - -sbin_PROGRAMS = prelink-rtld - -prelink_rtld_SOURCES = $(top_srcdir)/src/data.c $(top_srcdir)/src/dso.c \ - $(top_srcdir)/src/canonicalize.c $(top_srcdir)/src/wrap-file.c \ - $(top_srcdir)/src/reloc-info.c $(top_srcdir)/src/reloc-info.h \ - rtld.c ld-libs.h \ - dl-hash.h dl-object.c dl-load.c \ - dl-tls.c dl-version.c dl-misc.c \ - dl-lookup.c dl-lookupX.h - -prelink_rtld_LDADD = @LIBGELF@ -liberty -prelink_rtld_CFLAGS = -DDSO_READONLY -prelink_rtld_LDFLAGS = diff --git a/trunk/src/rtld/README-rtld b/trunk/src/rtld/README-rtld deleted file mode 100644 index fa737dc..0000000 --- a/trunk/src/rtld/README-rtld +++ /dev/null @@ -1,18 +0,0 @@ -The rtld emulation is based on the system libc ld.so code. - -The original version of this code was written by Daniel Jacobowitz in -2003. It needed little modification/updating until recently (2011) when -new constructs, such as STB_GNU_UNIQUE, were introduced into the dynamic -linking. - -The 2011 work was done by Mark Hatle and based on eglibc-2.13. I -attempted to document all of the code that had origins in eglibc and where -the code originated from. - -As eglibc continues to advance, similar resyncs will be needed over time. -Hopefully not such a dramatic resync will be required in the future. - -Mark Hatle <mark.hatle@windriver.com>, -August 2011 - -See the ChangeLog for additional changes. diff --git a/trunk/src/rtld/dl-hash.h b/trunk/src/rtld/dl-hash.h deleted file mode 100644 index 2b1f0b7..0000000 --- a/trunk/src/rtld/dl-hash.h +++ /dev/null @@ -1,77 +0,0 @@ -/* glibc-2.22: sysdeps/generic/dl-hash.h */ - -/* Compute hash value for given string according to ELF standard. - Copyright (C) 1995-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#ifndef _DL_HASH_H -#define _DL_HASH_H 1 - -#define _dl_elf_hash rtld_elf_hash - -/* This is the hashing function specified by the ELF ABI. In the - first five operations no overflow is possible so we optimized it a - bit. */ -static unsigned int -_dl_elf_hash (const char *name_arg) -{ - const unsigned char *name = (const unsigned char *) name_arg; - unsigned long int hash = *name; - if (hash != 0 && name[1] != '\0') - { - hash = (hash << 4) + name[1]; - if (name[2] != '\0') - { - hash = (hash << 4) + name[2]; - if (name[3] != '\0') - { - hash = (hash << 4) + name[3]; - if (name[4] != '\0') - { - hash = (hash << 4) + name[4]; - name += 5; - while (*name != '\0') - { - unsigned long int hi; - hash = (hash << 4) + *name++; - hi = hash & 0xf0000000; - - /* The algorithm specified in the ELF ABI is as - follows: - - if (hi != 0) - hash ^= hi >> 24; - - hash &= ~hi; - - But the following is equivalent and a lot - faster, especially on modern processors. */ - - hash ^= hi >> 24; - } - - /* Second part of the modified formula. This - operation can be lifted outside the loop. */ - hash &= 0x0fffffff; - } - } - } - } - return hash; -} - -#endif /* dl-hash.h */ diff --git a/trunk/src/rtld/dl-load.c b/trunk/src/rtld/dl-load.c deleted file mode 100644 index 5dc913e..0000000 --- a/trunk/src/rtld/dl-load.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Restructure code containing the original statement: - Copyright (C) 2003 MontaVista Software, Inc. - Written by Daniel Jacobowitz <drow@mvista.com>, 2003 - - Restructed and synced to latest eglibc 2.13 by - Mark Hatle <mark.hatle@windriver.com>, 2011 - - 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, 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. */ - -/* glibc-2.20: elf/dl-load.c */ - -/* Map in a shared object's segments from the file. - Copyright (C) 1995-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <error.h> -#include <errno.h> -#include <string.h> -#include "rtld.h" - -/* Add `name' to the list of names for a particular shared object. - `name' is expected to have been allocated with malloc and will - be freed if the shared object already has this name. - Returns false if the object already had this name. */ -static void -add_name_to_object (struct link_map *l, const char *name) -{ - struct libname_list *lnp, *lastp; - struct libname_list *newname; - size_t name_len; - - lastp = NULL; - for (lnp = l->l_libname; lnp != NULL; lastp = lnp, lnp = lnp->next) - if (strcmp (name, lnp->name) == 0) - return; - - name_len = strlen (name) + 1; - newname = (struct libname_list *) malloc (sizeof *newname + name_len); - if (newname == NULL) - { - /* No more memory. */ - _dl_signal_error (ENOMEM, name, NULL, ("cannot allocate name record")); - return; - } - /* The object should have a libname set from _dl_new_object. */ - assert (lastp != NULL); - - newname->name = memcpy (newname + 1, name, name_len); - newname->next = NULL; - lastp->next = newname; -} - -const char *rtld_progname; - -static Elf64_Addr load_addr = 0xdead0000; -static Elf64_Addr dynamic_addr = 0xfeed0000; - -/* mimic behavior of _dl_map_object_from_fd(...) - Note: this is not a copy of the function! */ -void -create_map_object_from_dso_ent (struct dso_list *cur_dso_ent) -{ - struct link_map *l = NULL; - DSO *dso = cur_dso_ent->dso; - - int i; - Elf_Data *data; - - - const char * realname, * name, *soname; - int l_type; - - soname = dso->soname; - realname = dso->filename; - name = dso->filename; - - l_type = (dso->ehdr.e_type == ET_EXEC ? lt_executable : lt_library); - - - /* Print debug message. */ - if ((l_type == lt_library && !is_ldso_soname(soname)) && - __glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - _dl_debug_printf("file=%s [0]; generating link map\n", soname); - - - l = _dl_new_object (realname, name, l_type); - if (l == NULL) - { - _dl_signal_error(errno, name, NULL, "cannot create shared object descriptor"); - } - - if (soname) - add_name_to_object(l, soname); - - if (name) - add_name_to_object(l, name); - - l->filename = dso->filename; - - /* Set the elfclass */ - l->elfclass = gelf_getclass (dso->elf); - - /*** Setup the l_info as if this had been loaded into memory ***/ - - /* FIXME: gelfify, endianness issues */ - /* and leaks? */ - i = addr_to_sec (dso, dso->info[DT_SYMTAB]); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[DT_SYMTAB] = data->d_buf; - } - - i = addr_to_sec (dso, dso->info[DT_STRTAB]); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[DT_STRTAB] = data->d_buf; - } - - if (dynamic_info_is_set (dso, DT_GNU_HASH_BIT)) - { - i = addr_to_sec (dso, dso->info_DT_GNU_HASH); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - -#if 0 - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) - printf("l_info DT_GNU_HASH: offset %d -- addr %p (0x%lx) - type %d\n", - (DT_ADDRTAGIDX(DT_GNU_HASH) + DT_NUM - + DT_THISPROCNUM + DT_VERSIONTAGNUM - + DT_EXTRANUM + DT_VALNUM), - data->d_buf, (unsigned long) data->d_size); -#endif - - l->l_info[DT_ADDRTAGIDX(DT_GNU_HASH) + DT_NUM - + DT_THISPROCNUM + DT_VERSIONTAGNUM - + DT_EXTRANUM + DT_VALNUM] = data->d_buf; - - /* PPC64 workaround */ - l->l_buckets_start = data->d_buf; - l->l_buckets_end = (char *)data->d_buf + data->d_size; - /* end workaround */ - } - } - - i = addr_to_sec (dso, dso->info[DT_HASH]); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[DT_HASH] = data->d_buf; - } - - if (dynamic_info_is_set (dso, DT_VERNEED_BIT)) - { - i = addr_to_sec (dso, dso->info_DT_VERNEED); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[VERSYMIDX (DT_VERNEED)] = data->d_buf; - } - } - - if (dynamic_info_is_set (dso, DT_VERDEF_BIT)) - { - i = addr_to_sec (dso, dso->info_DT_VERDEF); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[VERSYMIDX (DT_VERDEF)] = data->d_buf; - } - } - - if (dynamic_info_is_set (dso, DT_VERSYM_BIT)) - { - i = addr_to_sec (dso, dso->info_DT_VERSYM); - if (i != -1) - { - data = elf_getdata (dso->scn[i], NULL); - l->l_info[VERSYMIDX (DT_VERSYM)] = data->d_buf; - } - } - - if (dso->base) { - l->l_map_start = dso->base; - - /* We need to ensure that we don't have two DSOs loading at the same place! */ - struct dso_list * dso_list_ptr; - for (dso_list_ptr = cur_dso_ent->prev; dso_list_ptr; dso_list_ptr = dso_list_ptr->prev) - { - /* This looks for fairly obvious overlaps... */ - if ((dso_list_ptr->dso->base <= dso->base && dso->base <= dso_list_ptr->dso->end) || \ - (dso->base <= dso_list_ptr->dso->base && dso_list_ptr->dso->base <= dso->end)) - { - l->l_map_start = (Elf64_Addr)NULL; - break; - } - } - } - - if (l->l_map_start == (Elf64_Addr)NULL) - { - l->l_map_start = load_addr; - load_addr += ( ((dso->end - dso->base) + (0x1000 - 1)) & (~(0x1000-1)) ); - } - - l->sym_base = dso->info[DT_SYMTAB] - dso->base; - - if ((l_type == lt_library && !is_ldso_soname(soname)) - && (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))) { - _dl_debug_printf ("\ - dynamic: 0x%0*lx base: 0x%0*lx size: 0x%0*Zx\n", - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - (unsigned long int) dynamic_addr, - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - (unsigned long int) l->l_map_start, - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - (dso->end - dso->base)); - _dl_debug_printf ("\ - entry: 0x%0*lx phdr: 0x%0*lx phnum: %*u\n", - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - (unsigned long int) l->l_map_start + dso->ehdr.e_entry, - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - (unsigned long int) l->l_map_start + dso->ehdr.e_ehsize, - (int) sizeof (void *) * (gelf_getclass (dso->elf) == ELFCLASS64 ? 2 : 1), - dso->ehdr.e_phnum); - _dl_debug_printf ("\n"); - - /* Only used for debugging output */ - dynamic_addr += ( ((dso->end - dso->base) + (0x1000 - 1)) & (~(0x1000-1)) ); - } - - /* Set up the symbol hash table. */ - _dl_setup_hash (l); - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_TLS) - { - l->l_tls_blocksize = dso->phdr[i].p_memsz; - l->l_tls_align = dso->phdr[i].p_align; - if (l->l_tls_align == 0) - l->l_tls_firstbyte_offset = 0; - else - l->l_tls_firstbyte_offset = dso->phdr[i].p_vaddr & (l->l_tls_align - 1); - break; - } - - l->machine = dso->ehdr.e_machine; - - cur_dso_ent->map = l; -} diff --git a/trunk/src/rtld/dl-lookup.c b/trunk/src/rtld/dl-lookup.c deleted file mode 100644 index 6688966..0000000 --- a/trunk/src/rtld/dl-lookup.c +++ /dev/null @@ -1,131 +0,0 @@ -/* glibc-2.22: elf/dl-lookup.c */ - -/* Look up a symbol in the loaded objects. - Copyright (C) 1995-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -/* This file is based on the original eglibc-2.13 libc/elf/dl-lookup.c - code. - - It has been split into two pieces dl-lookup.c and dl-lookupX.c, - the purpose of the split is to enable both 32-bit and 64-bit ELF - processing in the same application. This file contains the ELF - size neutral routines. - */ - -#include <config.h> -#include <alloca.h> -#include <libintl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <dl-hash.h> - -#include <assert.h> - -#include <errno.h> - -#include <elf.h> - -#include <inttypes.h> - -#include "prelinktab.h" -#include "reloc.h" - -#include "rtld.h" - -/* Return nonzero if check_match should consider SYM to fail to match a - symbol reference for some machine-specific reason. */ -#ifndef ELF_MACHINE_SYM_NO_MATCH -/* glibc-2.20: sysdeps/mips/dl-machine.h */ -/* The semantics of zero/non-zero values of undefined symbols differs - depending on whether the non-PIC ABI is in use. Under the non-PIC - ABI, a non-zero value indicates that there is an address reference - to the symbol and thus it must always be resolved (except when - resolving a jump slot relocation) to the PLT entry whose address is - provided as the symbol's value; a zero value indicates that this - canonical-address behaviour is not required. Yet under the classic - MIPS psABI, a zero value indicates that there is an address - reference to the function and the dynamic linker must resolve the - symbol immediately upon loading. To avoid conflict, symbols for - which the dynamic linker must assume the non-PIC ABI semantics are - marked with the STO_MIPS_PLT flag. */ -#define ELF_MACHINE_SYM_NO_MATCH(sym) \ - (map->machine == EM_MIPS && \ - ((sym)->st_shndx == SHN_UNDEF && !((sym)->st_other & STO_MIPS_PLT)) \ - ) -#endif - -struct unique_sym_table * _ns_unique_sym_table = NULL; - -/* This file is from eglibc 2.13, libc/elf/dl-lookup.c - It has been split into two pieces dl-lookup.c and dl-lookupX.c, - the purpose of the split is to enable both 32-bit and 64-bit ELF - processing in the same application. This file contains the common - routines ... and is the entry to the overall set of files. - */ - -#define make_string(string, rest...) \ - ({ \ - const char *all[] = { string, ## rest }; \ - size_t len, cnt; \ - char *result, *cp; \ - \ - len = 1; \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - len += strlen (all[cnt]); \ - \ - cp = result = alloca (len); \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - cp = __stpcpy (cp, all[cnt]); \ - \ - result; \ - }) - -static uint_fast32_t -dl_new_hash (const char *s) -{ - uint_fast32_t h = 5381; - unsigned char c = *s; - for (c = *s; c != '\0'; c = *++s) - h = h * 33 + c; - return h & 0xffffffff; -} - -#undef RTLD_ELF_SIZE -#define RTLD_ELF_SIZE 32 -#include "dl-lookupX.h" - -#undef RTLD_ELF_SIZE -#define RTLD_ELF_SIZE 64 -#include "dl-lookupX.h" - -#undef RTLD_ELF_SIZE - -void -_dl_setup_hash (struct link_map *map) -{ - if (map) - { - if (map->elfclass == ELFCLASS32) - rtld_setup_hash32(map); - else if (map->elfclass == ELFCLASS64) - rtld_setup_hash64(map); - else - _dl_signal_error(EINVAL, map->l_name, NULL, "elfclass is not defined 32-bit or 64-bit!"); - } -} diff --git a/trunk/src/rtld/dl-lookupX.h b/trunk/src/rtld/dl-lookupX.h deleted file mode 100644 index dc6d4bf..0000000 --- a/trunk/src/rtld/dl-lookupX.h +++ /dev/null @@ -1,896 +0,0 @@ -/* glibc-2.22: elf/dl-lookup.c */ - -/* Look up a symbol in the loaded objects. - Copyright (C) 1995-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -/* This file is from eglibc 2.15, libc/elf/dl-lookup.c - It has been split into two pieces dl-lookup.c and dl-lookupX.c, - the purpose of the split is to enable both 32-bit and 64-bit ELF - processing in the same application. This file contains the ELF - size specific routines. It must be included from dl-lookup.c and - not used directly! - */ - -#if RTLD_ELF_SIZE == 32 - #define enter_unique_sym enter_unique_sym_val32 - #define sym_val sym_val32 - #define check_match check_match32 - #define do_lookup_unique do_lookup_unique32 - #define do_lookup_x do_lookup_x32 - #undef _dl_setup_hash - #define _dl_setup_hash rtld_setup_hash32 - #define _dl_debug_bindings rtld_debug_bindings32 - #define _dl_lookup_symbol_x rtld_lookup_symbol_x32 - #define rtld_size_t uint32_t - #define rtld_size_fmtx PRIx32 - -#elif RTLD_ELF_SIZE == 64 - #define enter_unique_sym enter_unique_sym_val64 - #define sym_val sym_val64 - #define check_match check_match64 - #define do_lookup_unique do_lookup_unique64 - #define do_lookup_x do_lookup_x64 - #undef _dl_setup_hash - #define _dl_setup_hash rtld_setup_hash64 - #define _dl_debug_bindings rtld_debug_bindings64 - #define _dl_lookup_symbol_x rtld_lookup_symbol_x64 - #define rtld_size_t uint64_t - #define rtld_size_fmtx PRIx64 - -#else - #error "You must declare RTLD_ELF_SIZE to be either 32 or 64" -#endif - -#define __ELF_NATIVE_CLASS RTLD_ELF_SIZE - -/* From eglibc 2.15 - elf/link.h */ - -/* We use this macro to refer to ELF types independent of the native wordsize. - `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'. */ -#define ELFW(type) _ElfW (ELF, __ELF_NATIVE_CLASS, type) -#define ElfW(type) _ElfW (Elf, __ELF_NATIVE_CLASS, type) -#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) -#define _ElfW_1(e,w,t) e##w##t - -struct sym_val - { - const ElfW(Sym) *s; - struct link_map *m; - }; - -/* Utility function for do_lookup_x. The caller is called with undef_name, - ref, version, flags and type_class, and those are passed as the first - five arguments. The caller then computes sym, symidx, strtab, and map - and passes them as the next four arguments. Lastly the caller passes in - versioned_sym and num_versions which are modified by check_match during - the checking process. */ -static const ElfW(Sym) * -check_match (const char *const undef_name, - const ElfW(Sym) *const ref, - const struct r_found_version *const version, - const int flags, - const int type_class, - const ElfW(Sym) *const sym, - const Elf_Symndx symidx, - const char *const strtab, - const struct link_map *const map, - const ElfW(Sym) **const versioned_sym, - int *const num_versions) -{ - unsigned int stt = ELFW(ST_TYPE) (sym->st_info); - assert (ELF_RTYPE_CLASS_PLT == 1); - if (__glibc_unlikely ((sym->st_value == 0 /* No value. */ - && stt != STT_TLS) - || ELF_MACHINE_SYM_NO_MATCH (sym) - || (type_class & (sym->st_shndx == SHN_UNDEF)))) - return NULL; - - /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC, - STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no - code/data definitions. */ -#define ALLOWED_STT \ - ((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \ - | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC)) - if (__glibc_unlikely (((1 << stt) & ALLOWED_STT) == 0)) - return NULL; - - if (sym != ref && strcmp (strtab + sym->st_name, undef_name)) - /* Not the symbol we are looking for. */ - return NULL; - - const ElfW(Half) *verstab = map->l_versyms; - if (version != NULL) - { - if (__glibc_unlikely (verstab == NULL)) - { - /* We need a versioned symbol but haven't found any. If - this is the object which is referenced in the verneed - entry it is a bug in the library since a symbol must - not simply disappear. - - It would also be a bug in the object since it means that - the list of required versions is incomplete and so the - tests in dl-version.c haven't found a problem.*/ - assert (version->filename == NULL - || ! _dl_name_match_p (version->filename, map)); - - /* Otherwise we accept the symbol. */ - } - else - { - /* We can match the version information or use the - default one if it is not hidden. */ - ElfW(Half) ndx = verstab[symidx] & 0x7fff; - if ((map->l_versions[ndx].hash != version->hash - || strcmp (map->l_versions[ndx].name, version->name)) - && (version->hidden || map->l_versions[ndx].hash - || (verstab[symidx] & 0x8000))) - /* It's not the version we want. */ - return NULL; - } - } - else - { - /* No specific version is selected. There are two ways we - can got here: - - - a binary which does not include versioning information - is loaded - - - dlsym() instead of dlvsym() is used to get a symbol which - might exist in more than one form - - If the library does not provide symbol version information - there is no problem at all: we simply use the symbol if it - is defined. - - These two lookups need to be handled differently if the - library defines versions. In the case of the old - unversioned application the oldest (default) version - should be used. In case of a dlsym() call the latest and - public interface should be returned. */ - if (verstab != NULL) - { - if ((verstab[symidx] & 0x7fff) - >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3)) - { - /* Don't accept hidden symbols. */ - if ((verstab[symidx] & 0x8000) == 0 - && (*num_versions)++ == 0) - /* No version so far. */ - *versioned_sym = sym; - - return NULL; - } - } - } - - /* There cannot be another entry for this symbol so stop here. */ - return sym; -} - -/* Utility function for do_lookup_unique. Add a symbol to TABLE. */ -static void -enter_unique_sym (struct unique_sym *table, size_t size, - unsigned int hash, const char *name, - const ElfW(Sym) *sym, const struct link_map *map) -{ - size_t idx = hash % size; - size_t hash2 = 1 + hash % (size - 2); - while (table[idx].name != NULL) - { - idx += hash2; - if (idx >= size) - idx -= size; - } - - table[idx].hashval = hash; - table[idx].name = name; - table[idx].sym = sym; - table[idx].map = map; -} - -/* Utility function for do_lookup_x. Lookup an STB_GNU_UNIQUE symbol - in the unique symbol table, creating a new entry if necessary. - Return the matching symbol in RESULT. */ -static void -do_lookup_unique (const char *undef_name, uint_fast32_t new_hash, - const struct link_map *map, struct sym_val *result, - int type_class, const ElfW(Sym) *sym, const char *strtab, - const ElfW(Sym) *ref, const struct link_map *undef_map) -{ - /* We have to determine whether we already found a symbol with this - name before. If not then we have to add it to the search table. - If we already found a definition we have to use it. */ - - struct unique_sym_table *tab - = _ns_unique_sym_table; - - __rtld_lock_lock_recursive (tab->lock); - - struct unique_sym *entries = tab->entries; - size_t size = tab->size; - if (entries != NULL) - { - size_t idx = new_hash % size; - size_t hash2 = 1 + new_hash % (size - 2); - while (1) - { - if (entries[idx].hashval == new_hash - && strcmp (entries[idx].name, undef_name) == 0) - { - if ((type_class & ELF_RTYPE_CLASS_COPY) != 0) - { - /* We possibly have to initialize the central - copy from the copy addressed through the - relocation. */ - result->s = sym; - result->m = (struct link_map *) map; - } - else - { - result->s = entries[idx].sym; - result->m = (struct link_map *) entries[idx].map; - } - __rtld_lock_unlock_recursive (tab->lock); - return; - } - - if (entries[idx].name == NULL) - break; - - idx += hash2; - if (idx >= size) - idx -= size; - } - - if (size * 3 <= tab->n_elements * 4) - { - /* Expand the table. */ -#ifdef RTLD_CHECK_FOREIGN_CALL - /* This must not happen during runtime relocations. */ - assert (!RTLD_CHECK_FOREIGN_CALL); -#endif - size_t newsize = _dl_higher_prime_number (size + 1); - struct unique_sym *newentries - = calloc (sizeof (struct unique_sym), newsize); - if (newentries == NULL) - { - nomem: - __rtld_lock_unlock_recursive (tab->lock); - _dl_fatal_printf ("out of memory\n"); - } - - for (idx = 0; idx < size; ++idx) - if (entries[idx].name != NULL) - enter_unique_sym (newentries, newsize, entries[idx].hashval, - entries[idx].name, entries[idx].sym, - entries[idx].map); - - tab->free (entries); - tab->size = newsize; - size = newsize; - entries = tab->entries = newentries; - tab->free = free; - } - } - else - { -#ifdef RTLD_CHECK_FOREIGN_CALL - /* This must not happen during runtime relocations. */ - assert (!RTLD_CHECK_FOREIGN_CALL); -#endif - -#if 1 - /* If tab->entries is NULL, but tab->size is not, it means - this is the second, conflict finding, lookup for - LD_TRACE_PRELINKING in _dl_debug_bindings. Don't - allocate anything and don't enter anything into the - hash table. */ - if (__glibc_unlikely (tab->size)) - { - assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK); - goto success; - } -#endif - -#define INITIAL_NUNIQUE_SYM_TABLE 31 - size = INITIAL_NUNIQUE_SYM_TABLE; - entries = calloc (sizeof (struct unique_sym), size); - if (entries == NULL) - goto nomem; - - tab->entries = entries; - tab->size = size; - tab->free = free; - } - - if ((type_class & ELF_RTYPE_CLASS_COPY) != 0) - enter_unique_sym (entries, size, new_hash, strtab + sym->st_name, ref, - undef_map); - else - { - enter_unique_sym (entries, size, - new_hash, strtab + sym->st_name, sym, map); - -#if 0 - if (map->l_type == lt_loaded) - /* Make sure we don't unload this object by - setting the appropriate flag. */ - ((struct link_map *) map)->l_flags_1 |= DF_1_NODELETE; -#endif - } - ++tab->n_elements; - -#if 1 - success: -#endif - - result->s = sym; - result->m = (struct link_map *) map; -} - -/* Inner part of the lookup functions. We return a value > 0 if we - found the symbol, the value 0 if nothing is found and < 0 if - something bad happened. */ -static int -do_lookup_x (const char *undef_name, uint_fast32_t new_hash, - unsigned long int *old_hash, const ElfW(Sym) *ref, - struct sym_val *result, struct r_scope_elem *scope, size_t i, - const struct r_found_version *const version, int flags, - struct link_map *skip, int type_class, struct link_map *undef_map) -{ - size_t n = scope->r_nlist; - /* Make sure we read the value before proceeding. Otherwise we - might use r_list pointing to the initial scope and r_nlist being - the value after a resize. That is the only path in dl-open.c not - protected by GSCOPE. A read barrier here might be to expensive. */ - __asm volatile ("" : "+r" (n), "+m" (scope->r_list)); - struct link_map **list = scope->r_list; - - do - { - const struct link_map *map = list[i]; - - /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */ - if (map == skip) - continue; - - /* Don't search the executable when resolving a copy reloc. */ - if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable) - continue; - - /* Print some debugging info if wanted. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS)) - _dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n", - undef_name, DSO_FILENAME (map->l_name), - 0UL); - - /* If the hash table is empty there is nothing to do here. */ - if (map->l_nbuckets == 0) - continue; - - Elf_Symndx symidx; - int num_versions = 0; - const ElfW(Sym) *versioned_sym = NULL; - - /* The tables for this map. */ - const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - - const ElfW(Sym) *sym; - const ElfW(Addr) *bitmask = map->l_gnu_bitmask; - if (__glibc_likely (bitmask != NULL)) - { - ElfW(Addr) bitmask_word - = bitmask[(new_hash / __ELF_NATIVE_CLASS) - & map->l_gnu_bitmask_idxbits]; - - unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1); - unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift) - & (__ELF_NATIVE_CLASS - 1)); - - if (__glibc_unlikely ((bitmask_word >> hashbit1) - & (bitmask_word >> hashbit2) & 1)) - { - Elf32_Word bucket = map->l_gnu_buckets[new_hash - % map->l_nbuckets]; - -/* PPC64 workaround */ - /* There is a bad hash entry and it's pointing beyond - the end of the bucket list. */ - assert ((void *)&map->l_gnu_chain_zero[bucket] < map->l_buckets_end); -/* END PPC64 workaround */ - if (bucket != 0) - { - const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket]; - - do - if (((*hasharr ^ new_hash) >> 1) == 0) - { - symidx = hasharr - map->l_gnu_chain_zero; - sym = check_match (undef_name, ref, version, flags, - type_class, &symtab[symidx], symidx, - strtab, map, &versioned_sym, - &num_versions); - if (sym != NULL) - goto found_it; - } - while ((*hasharr++ & 1u) == 0); - } - } - /* No symbol found. */ - symidx = SHN_UNDEF; - } - else - { - if (*old_hash == 0xffffffff) - *old_hash = _dl_elf_hash (undef_name); - - /* Use the old SysV-style hash table. Search the appropriate - hash bucket in this object's symbol table for a definition - for the same symbol name. */ - for (symidx = map->l_buckets[*old_hash % map->l_nbuckets]; - symidx != STN_UNDEF; - symidx = map->l_chain[symidx]) - { - sym = check_match (undef_name, ref, version, flags, - type_class, &symtab[symidx], symidx, - strtab, map, &versioned_sym, - &num_versions); - if (sym != NULL) - goto found_it; - } - } - - /* If we have seen exactly one versioned symbol while we are - looking for an unversioned symbol and the version is not the - default version we still accept this symbol since there are - no possible ambiguities. */ - sym = num_versions == 1 ? versioned_sym : NULL; - - if (sym != NULL) - { - found_it: - /* When UNDEF_MAP is NULL, which indicates we are called from - do_lookup_x on relocation against protected data, we skip - the data definion in the executable from copy reloc. */ - if (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(map->machine) - && undef_map == NULL - && map->l_type == lt_executable - && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(map->machine)) - { - const ElfW(Sym) *s; - unsigned int i; - -if (!ELF_MACHINE_NO_RELA(map->machine)) { /* #if ! ELF_MACHINE_NO_RELA */ - if (map->l_info[DT_RELA] != NULL - && map->l_info[DT_RELASZ] != NULL - && ((ElfW(Dyn) *)(map->l_info[DT_RELASZ]))->d_un.d_val != 0) - { - const ElfW(Rela) *rela - = (const ElfW(Rela) *) D_PTR (map, l_info[DT_RELA]); - unsigned int rela_count - = ((ElfW(Dyn) *)(map->l_info[DT_RELASZ]))->d_un.d_val / sizeof (*rela); - - for (i = 0; i < rela_count; i++, rela++) - if (elf_machine_type_class (ELFW(R_TYPE) (rela->r_info), map->machine) - == ELF_RTYPE_CLASS_COPY) - { - s = &symtab[ELFW(R_SYM) (rela->r_info)]; - if (!strcmp (strtab + s->st_name, undef_name)) - goto skip; - } - } -} /* #endif */ -if (!ELF_MACHINE_NO_REL(map->machine)) { /* #if ! ELF_MACHINE_NO_REL */ - if (map->l_info[DT_REL] != NULL - && map->l_info[DT_RELSZ] != NULL - && ((ElfW(Dyn) *)(map->l_info[DT_RELSZ]))->d_un.d_val != 0) - { - const ElfW(Rel) *rel - = (const ElfW(Rel) *) D_PTR (map, l_info[DT_REL]); - unsigned int rel_count - = ((ElfW(Dyn) *)(map->l_info[DT_RELSZ]))->d_un.d_val / sizeof (*rel); - - for (i = 0; i < rel_count; i++, rel++) - if (elf_machine_type_class (ELFW(R_TYPE) (rel->r_info), map->machine) - == ELF_RTYPE_CLASS_COPY) - { - s = &symtab[ELFW(R_SYM) (rel->r_info)]; - if (!strcmp (strtab + s->st_name, undef_name)) - goto skip; - } - } -} /* #endif */ - } - - switch (ELFW(ST_BIND) (sym->st_info)) - { - case STB_WEAK: - /* Weak definition. Use this value if we don't find another. */ - if (__glibc_unlikely (GLRO(dl_dynamic_weak))) - { - if (! result->s) - { - result->s = sym; - result->m = (struct link_map *) map; - } - break; - } - /* FALLTHROUGH */ - case STB_GLOBAL: - /* Global definition. Just what we need. */ - result->s = sym; - result->m = (struct link_map *) map; - return 1; - - case STB_GNU_UNIQUE:; - do_lookup_unique (undef_name, new_hash, map, result, type_class, - sym, strtab, ref, undef_map); - return 1; - - default: - /* Local symbols are ignored. */ - break; - } - } - -skip: - /* If this current map is the one mentioned in the verneed entry - and we have not found a weak entry, it is a bug. */ - if (symidx == STN_UNDEF && version != NULL && version->filename != NULL - && __glibc_unlikely (_dl_name_match_p (version->filename, map))) - return -1; - } - while (++i < n); - - /* We have not found anything until now. */ - return 0; -} - - -static void -_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, struct sym_val *value, - const struct r_found_version *version, int type_class, - int protected); - - -/* Search loaded objects' symbol tables for a definition of the symbol - UNDEF_NAME, perhaps with a requested version for the symbol. - - We must never have calls to the audit functions inside this function - or in any function which gets called. If this would happen the audit - code might create a thread which can throw off all the scope locking. */ -lookup_t -_dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int flags, struct link_map *skip_map) -{ - const uint_fast32_t new_hash = dl_new_hash (undef_name); - unsigned long int old_hash = 0xffffffff; - struct sym_val current_value = { NULL, NULL }; - struct r_scope_elem **scope = symbol_scope; - - /* No other flag than DL_LOOKUP_ADD_DEPENDENCY or DL_LOOKUP_GSCOPE_LOCK - is allowed if we look up a versioned symbol. */ - assert (version == NULL - || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_GSCOPE_LOCK)) - == 0); - - size_t i = 0; - if (__glibc_unlikely (skip_map != NULL)) - /* Search the relevant loaded objects for a definition. */ - while ((*scope)->r_list[i] != skip_map) - ++i; - - /* Search the relevant loaded objects for a definition. */ - size_t start; /* requires C99 to put it into the loop */ - for (start = i; *scope != NULL; start = 0, ++scope) - { - int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref, - ¤t_value, *scope, start, version, flags, - skip_map, type_class, undef_map); - if (res > 0) - break; - - if (__glibc_unlikely (res < 0) && skip_map == NULL) - { - /* Oh, oh. The file named in the relocation entry does not - contain the needed symbol. This code is never reached - for unversioned lookups. */ - assert (version != NULL); - const char *reference_name = undef_map ? undef_map->l_name : ""; - - /* XXX We cannot translate the message. */ - _dl_signal_cerror (0, DSO_FILENAME (reference_name), - "relocation error", - make_string ("symbol ", undef_name, ", version ", - version->name, - " not defined in file ", - version->filename, - " with link time reference", - res == -2 - ? " (no version symbols)" : "")); - *ref = NULL; - return 0; - } - } - - if (__glibc_unlikely (current_value.s == NULL)) - { - if ((*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) - && skip_map == NULL - && !(GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)) - { - /* We could find no value for a strong reference. */ - const char *reference_name = undef_map ? undef_map->l_name : ""; - const char *versionstr = version ? ", version " : ""; - const char *versionname = (version && version->name - ? version->name : ""); - - /* XXX We cannot translate the message. */ - _dl_signal_cerror (0, DSO_FILENAME (reference_name), - ("symbol lookup error"), - make_string ("undefined symbol: ", undef_name, - versionstr, versionname)); - } - *ref = NULL; - return 0; - } - - int protected = (*ref - && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED); - if (__glibc_unlikely (protected != 0)) - { - /* It is very tricky. We need to figure out what value to - return for the protected symbol. */ - if (type_class == ELF_RTYPE_CLASS_PLT) - { - if (current_value.s != NULL && current_value.m != undef_map) - { - current_value.s = *ref; - current_value.m = undef_map; - } - } - else - { - struct sym_val protected_value = { NULL, NULL }; - - for (scope = symbol_scope; *scope != NULL; i = 0, ++scope) - if (do_lookup_x (undef_name, new_hash, &old_hash, *ref, - &protected_value, *scope, i, version, flags, - skip_map, - (ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine) - && ELFW(ST_TYPE) ((*ref)->st_info) == STT_OBJECT - && type_class == ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine)) - ? ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(skip_map->machine) - : ELF_RTYPE_CLASS_PLT, NULL) != 0) - break; - - if (protected_value.s != NULL && protected_value.m != undef_map) - { - current_value.s = *ref; - current_value.m = undef_map; - } - } - } - -#if 0 - /* We have to check whether this would bind UNDEF_MAP to an object - in the global scope which was dynamically loaded. In this case - we have to prevent the latter from being unloaded unless the - UNDEF_MAP object is also unloaded. */ - if (__glibc_unlikely (current_value.m->l_type == lt_loaded) - /* Don't do this for explicit lookups as opposed to implicit - runtime lookups. */ - && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0 - /* Add UNDEF_MAP to the dependencies. */ - && add_dependency (undef_map, current_value.m, flags) < 0) - /* Something went wrong. Perhaps the object we tried to reference - was just removed. Try finding another definition. */ - return _dl_lookup_symbol_x (undef_name, undef_map, ref, - symbol_scope, - version, type_class, flags, skip_map); -#endif - - if (__glibc_unlikely (GLRO(dl_debug_mask) - & (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK))) - _dl_debug_bindings (undef_name, undef_map, ref, - ¤t_value, version, type_class, protected); - - *ref = current_value.s; - return LOOKUP_VALUE (current_value.m); -} - - -/* Cache the location of MAP's hash table. */ - -void -_dl_setup_hash (struct link_map *map) -{ - Elf_Symndx *hash; - - if (__glibc_likely (map->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM - + DT_THISPROCNUM + DT_VERSIONTAGNUM - + DT_EXTRANUM + DT_VALNUM] != NULL)) - { - Elf32_Word *hash32 - = (void *) D_PTR (map, l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM - + DT_THISPROCNUM + DT_VERSIONTAGNUM - + DT_EXTRANUM + DT_VALNUM]); - map->l_nbuckets = *hash32++; - Elf32_Word symbias = *hash32++; - Elf32_Word bitmask_nwords = *hash32++; - /* Must be a power of two. */ - assert ((bitmask_nwords & (bitmask_nwords - 1)) == 0); - map->l_gnu_bitmask_idxbits = bitmask_nwords - 1; - map->l_gnu_shift = *hash32++; - - map->l_gnu_bitmask = (ElfW(Addr) *) hash32; - hash32 += __ELF_NATIVE_CLASS / 32 * bitmask_nwords; - - map->l_gnu_buckets = hash32; - hash32 += map->l_nbuckets; - map->l_gnu_chain_zero = hash32 - symbias; - return; - } - - if (!map->l_info[DT_HASH]) - return; - hash = (void *) D_PTR (map, l_info[DT_HASH]); - - map->l_nbuckets = *hash++; - /* Skip nchain. */ - hash++; - map->l_buckets = hash; - hash += map->l_nbuckets; - map->l_chain = hash; -} - - -static void -_dl_debug_bindings (const char *undef_name, struct link_map *undef_map, - const ElfW(Sym) **ref, struct sym_val *value, - const struct r_found_version *version, int type_class, - int protected) -{ - const char *reference_name = undef_map->l_name; - - if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS) - { - _dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol `%s'", - DSO_FILENAME (reference_name), - 0UL, - DSO_FILENAME (value->m->l_name), - 0UL, - protected ? "protected" : "normal", undef_name); - if (version) - printf (" [%s]\n", version->name); - else - printf ("\n"); - } -#if 1 - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { - int conflict = 0; - struct sym_val val = { NULL, NULL }; - - /* We need to always process these or we can miss conflict symbols when - RTLD_TRACE_PRELINKING=<library> */ - if (1) - { - const uint_fast32_t new_hash = dl_new_hash (undef_name); - unsigned long int old_hash = 0xffffffff; - struct unique_sym *saved_entries - = _ns_unique_sym_table->entries; - - _ns_unique_sym_table->entries = NULL; - do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val, - undef_map->l_local_scope[0], 0, version, 0, NULL, - type_class, undef_map); - if (val.s != value->s || val.m != value->m) - conflict = 1; - else if (1 - && val.s - && __glibc_unlikely (ELFW(ST_BIND) (val.s->st_info) - == STB_GNU_UNIQUE)) - { - /* If it is STB_GNU_UNIQUE and undef_map's l_local_scope - contains any DT_SYMBOLIC libraries, unfortunately there - can be conflicts even if the above is equal. As symbol - resolution goes from the last library to the first and - if a STB_GNU_UNIQUE symbol is found in some late DT_SYMBOLIC - library, it would be the one that is looked up. */ - struct sym_val val2 = { NULL, NULL }; - size_t n; - struct r_scope_elem *scope = undef_map->l_local_scope[0]; - - for (n = 0; n < scope->r_nlist; n++) - if (scope->r_list[n] == val.m) - break; - - for (n++; n < scope->r_nlist; n++) - if (scope->r_list[n]->l_info[DT_SYMBOLIC] != NULL - && do_lookup_x (undef_name, new_hash, &old_hash, *ref, - &val2, - scope, - 0, version, 0, NULL, type_class, - undef_map) > 0) - { - conflict = 1; - val = val2; - break; - } - } - _ns_unique_sym_table->entries = saved_entries; - } - - if (value->s) - { - if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_TLS)) - type_class = 4; - else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info) - == STT_GNU_IFUNC)) - type_class |= 8; - } - - if (conflict - || GLRO(dl_trace_prelink_map) == undef_map - || GLRO(dl_trace_prelink_map) == NULL - || type_class >= 4) - { - printf ("%s 0x%0*"rtld_size_fmtx" 0x%0*"rtld_size_fmtx" -> 0x%0*"rtld_size_fmtx" 0x%0*"rtld_size_fmtx" ", - conflict ? "conflict" : "lookup", - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) undef_map->l_map_start, - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) (((char *)*ref) - ((char *)undef_map->l_info[DT_SYMTAB]) + (char *)undef_map->sym_base), - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) (value->s ? value->m->l_map_start : 0), - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) (value->s ? value->s->st_value : 0)); - - if (conflict) - printf ("x 0x%0*"rtld_size_fmtx" 0x%0*"rtld_size_fmtx" ", - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) (val.s ? val.m->l_map_start : 0), - (int) sizeof (ElfW(Addr)) * 2, - (rtld_size_t) (val.s ? val.s->st_value : 0)); - - printf ("/%x %s\n", type_class, undef_name); - } - } -#endif -} - -#undef enter_unique_sym -#undef sym_val -#undef check_match -#undef do_lookup_unique -#undef do_lookup_x -#undef _dl_setup_hash -#define _dl_setup_hash rtld_setup_hash -#undef _dl_debug_bindings -#undef _dl_lookup_symbol_x -#undef rtld_size_t -#undef rtld_size_fmtx diff --git a/trunk/src/rtld/dl-misc.c b/trunk/src/rtld/dl-misc.c deleted file mode 100644 index c70956d..0000000 --- a/trunk/src/rtld/dl-misc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* glibc 2.22, elf/dl-misc.c */ - -/* Miscellaneous support functions for dynamic linker - Copyright (C) 1997-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <error.h> -#include <errno.h> -#include <string.h> -#include "rtld.h" - -/* Test whether given NAME matches any of the names of the given object. */ -int -_dl_name_match_p (const char *name, const struct link_map *map) -{ - if (strcmp (name, map->l_name) == 0) - return 1; - - struct libname_list *runp = map->l_libname; - - while (runp != NULL) - if (strcmp (name, runp->name) == 0) - return 1; - else - runp = runp->next; - - return 0; -} - -unsigned long int -_dl_higher_prime_number (unsigned long int n) -{ - /* These are primes that are near, but slightly smaller than, a - power of two. */ - static const uint32_t primes[] = { - UINT32_C (7), - UINT32_C (13), - UINT32_C (31), - UINT32_C (61), - UINT32_C (127), - UINT32_C (251), - UINT32_C (509), - UINT32_C (1021), - UINT32_C (2039), - UINT32_C (4093), - UINT32_C (8191), - UINT32_C (16381), - UINT32_C (32749), - UINT32_C (65521), - UINT32_C (131071), - UINT32_C (262139), - UINT32_C (524287), - UINT32_C (1048573), - UINT32_C (2097143), - UINT32_C (4194301), - UINT32_C (8388593), - UINT32_C (16777213), - UINT32_C (33554393), - UINT32_C (67108859), - UINT32_C (134217689), - UINT32_C (268435399), - UINT32_C (536870909), - UINT32_C (1073741789), - UINT32_C (2147483647), - /* 4294967291L */ - UINT32_C (2147483647) + UINT32_C (2147483644) - }; - - const uint32_t *low = &primes[0]; - const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])]; - - while (low != high) - { - const uint32_t *mid = low + (high - low) / 2; - if (n > *mid) - low = mid + 1; - else - high = mid; - } - -#if 0 - /* If we've run out of primes, abort. */ - if (n > *low) - { - fprintf (stderr, "Cannot find prime bigger than %lu\n", n); - abort (); - } -#endif - - return *low; -} diff --git a/trunk/src/rtld/dl-object.c b/trunk/src/rtld/dl-object.c deleted file mode 100644 index 19f0265..0000000 --- a/trunk/src/rtld/dl-object.c +++ /dev/null @@ -1,57 +0,0 @@ -/* glibc-2.22: elf/dl-object.c */ - -/* Storage management for the chain of loaded shared objects. - Copyright (C) 1995-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <error.h> -#include <errno.h> -#include <string.h> -#include "rtld.h" - -/* Allocate a `struct link_map' for a new object being loaded, - and enter it into the _dl_loaded list. */ -struct link_map * -_dl_new_object (const char *realname, const char *libname, int type) -{ - size_t libname_len = strlen (libname) + 1; - struct link_map *new; - struct libname_list *newname; - - new = (struct link_map *) calloc (sizeof (*new) + - + sizeof (*newname) + libname_len, 1); - - if (new == NULL) - return NULL; - - new->l_libname = newname - = (struct libname_list *) ((char *) (new + 1)); - newname->name = (char *) memcpy (newname + 1, libname, libname_len); - /* newname->next = NULL; We use calloc therefore not necessary. */ - - /* When we create the executable link map, or a VDSO link map, we start - with "" for the l_name. In these cases "" points to ld.so rodata - and won't get dumped during core file generation. Therefore to assist - gdb and to create more self-contained core files we adjust l_name to - point at the newly allocated copy (which will get dumped) instead of - the ld.so rodata copy. */ - new->l_name = *realname ? realname : (char *) newname->name + libname_len - 1; - new->l_type = type; - - return new; -} diff --git a/trunk/src/rtld/dl-tls.c b/trunk/src/rtld/dl-tls.c deleted file mode 100644 index 8b972ff..0000000 --- a/trunk/src/rtld/dl-tls.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Copyright (C) 2011 Wind River Systems, Inc. - - Code reorganized from original code bearing the following copyright: - Copyright (C) 2003 MontaVista Software, Inc. - Written by Daniel Jacobowitz <drow@mvista.com>, 2003 - - Code updated by Mark Hatle <mark.hatle@windriver.com>, 2011 - to sync to eglibc 2.13 tls behavior... - - 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, 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. */ - -/* glibc 2.22: elf/dl-tls.c */ - -/* Thread-local storage handling in the ELF dynamic linker. Generic version. - Copyright (C) 2002-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <config.h> -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "rtld.h" - -/* Assign TLS offsets for every loaded library. This code is taken - almost directly from glibc! */ - -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -/* The following function needs to mimic the _dl_determine_tlsoffset in eglibc */ -void -rtld_determine_tlsoffsets (int e_machine, struct r_scope_elem *search_list) -{ - uint64_t modid = 1; - - uint64_t i; - - /* skip max_align */ - uint64_t freetop = 0; - uint64_t freebottom = 0; - - /* This comes from each architecture's ABI. If TLS_TCB_AT_TP, then - set offset to -1; if TLS_DTV_AT_TP, then set offset to - TLS_TCB_SIZE. */ - - int tls_tcb_at_tp = 0; - int tls_dtv_at_tp = 0; - uint64_t tls_tcb_size; - - switch (e_machine) - { - case EM_X86_64: - tls_tcb_at_tp = 1; - tls_tcb_size = -1; - break; - - case EM_386: - tls_tcb_at_tp = 1; - tls_tcb_size = -1; - break; - - case EM_SH: - tls_dtv_at_tp = 1; - tls_tcb_size = 8; - break; - - case EM_PPC: - tls_dtv_at_tp = 1; - tls_tcb_size = 0; - break; - - case EM_PPC64: - tls_dtv_at_tp = 1; - tls_tcb_size = 0; - break; - - case EM_ARM: - tls_dtv_at_tp = 1; - tls_tcb_size = 8; - break; - - case EM_AARCH64: - tls_dtv_at_tp = 1; - tls_tcb_size = 16; - break; - - case EM_MIPS: - tls_dtv_at_tp = 1; - tls_tcb_size = 0; - break; - - case EM_SPARC: - case EM_SPARC32PLUS: - tls_tcb_at_tp = 1; - tls_tcb_size = -1; - break; - - case EM_SPARCV9: - tls_tcb_at_tp = 1; - tls_tcb_size = -1; - break; - - case EM_ALTERA_NIOS2: - tls_dtv_at_tp = 1; - tls_tcb_size = 0; - break; - - default: - /* Hope there's no TLS! */ - for (i = 0; i < search_list->r_nlist; i++) - { - struct link_map *map = search_list->r_list[i]; - - if (map->l_tls_blocksize > 0) - _dl_signal_error(0, map->l_name, NULL, "cannot handle TLS data"); - } - - return; - } - - /* eglibc 2.20: elf/dl-tls.c: _dl_determine_tlsoffset (void) */ - /* Determining the offset of the various parts of the static TLS - block has several dependencies. In addition we have to work - around bugs in some toolchains. - - Each TLS block from the objects available at link time has a size - and an alignment requirement. The GNU ld computes the alignment - requirements for the data at the positions *in the file*, though. - I.e, it is not simply possible to allocate a block with the size - of the TLS program header entry. The data is layed out assuming - that the first byte of the TLS block fulfills - - p_vaddr mod p_align == &TLS_BLOCK mod p_align - - This means we have to add artificial padding at the beginning of - the TLS block. These bytes are never used for the TLS data in - this module but the first byte allocated must be aligned - according to mod p_align == 0 so that the first byte of the TLS - block is aligned according to p_vaddr mod p_align. This is ugly - and the linker can help by computing the offsets in the TLS block - assuming the first byte of the TLS block is aligned according to - p_align. - - The extra space which might be allocated before the first byte of - the TLS block need not go unused. The code below tries to use - that memory for the next TLS block. This can work if the total - memory requirement for the next TLS block is smaller than the - gap. */ - - /* Loop over the loaded DSOs. We use the symbol search order; this - should be the same as glibc's ordering, which traverses l_next. - It's somewhat important that we use both the same ordering to - assign module IDs and the same algorithm to assign offsets, - because the prelinker will resolve all relocations using these - offsets... and then glibc will recalculate them. Future dynamic - relocations in any loaded modules will use glibc's values. Also - if we take too much space here, glibc won't allocate enough - static TLS area to hold it. */ - -/* #if TLS_TCB_AT_TP */ if (tls_tcb_at_tp == 1) { - /* We simply start with zero. */ - uint64_t offset = 0; - - for (i = 0; i < search_list->r_nlist; i++) - { - struct link_map *map = search_list->r_list[i]; - - uint64_t firstbyte = (-map->l_tls_firstbyte_offset - & (map->l_tls_align - 1)); - uint64_t off; - - /* elf/rtld.c would have caused us to skip this block.. so emulate this */ - if (map->l_tls_blocksize == 0) - continue; - - /* allocate_tls_init would nomrally Increment the module id */ - map->l_tls_modid = modid++; - - if (freebottom - freetop >= map->l_tls_blocksize) - { - off = roundup (freetop + map->l_tls_blocksize - - firstbyte, map->l_tls_align) - + firstbyte; - if (off <= freebottom) - { - freetop = off; - - /* XXX For some architectures we perhaps should store the - negative offset. */ - map->l_tls_offset = off; - continue; - } - } - - off = roundup (offset + map->l_tls_blocksize - firstbyte, - map->l_tls_align) + firstbyte; - if (off > offset + map->l_tls_blocksize - + (freebottom - freetop)) - { - freetop = offset; - freebottom = off - map->l_tls_blocksize; - } - offset = off; - - /* XXX For some architectures we perhaps should store the - negative offset. */ - map->l_tls_offset = off; - } -/* #elif TLS_DTV_AT_TP */ } else if (tls_dtv_at_tp == 1) { - /* The TLS blocks start right after the TCB. */ - uint64_t offset = tls_tcb_size; - - for (i = 0; i < search_list->r_nlist; i++) - { - struct link_map *map = search_list->r_list[i]; - - uint64_t firstbyte = (-map->l_tls_firstbyte_offset - & (map->l_tls_align - 1)); - uint64_t off; - - /* elf/rtld.c would have caused us to skip this block.. so emulate this */ - if (map->l_tls_blocksize == 0) - continue; - - /* allocate_tls_init would nomrally Increment the module id */ - map->l_tls_modid = modid++; - - if (map->l_tls_blocksize <= freetop - freebottom) - { - off = roundup (freebottom, map->l_tls_align); - if (off - freebottom < firstbyte) - off += map->l_tls_align; - if (off + map->l_tls_blocksize - firstbyte <= freetop) - { - map->l_tls_offset = off - firstbyte; - freebottom = (off + map->l_tls_blocksize - - firstbyte); - continue; - } - } - - off = roundup (offset, map->l_tls_align); - if (off - offset < firstbyte) - off += map->l_tls_align; - - map->l_tls_offset = off - firstbyte; - if (off - firstbyte - offset > freetop - freebottom) - { - freebottom = offset; - freetop = off - firstbyte; - } - - offset = off + map->l_tls_blocksize - firstbyte; - } -/* #else */ } else { - /* Should never happen... */ - _dl_signal_error(0, NULL, NULL, "Neither TLS_TCB_AT_TP nor TLS_DTV_AT_TP is defined for this architecture"); -/* #endif */ } -} diff --git a/trunk/src/rtld/dl-version.c b/trunk/src/rtld/dl-version.c deleted file mode 100644 index 042a70f..0000000 --- a/trunk/src/rtld/dl-version.c +++ /dev/null @@ -1,369 +0,0 @@ -/* Based on code originally in eglibc 2.13, libc/elf/dl-version.c */ - -/* Handle symbol and library versioning. - Copyright (C) 1997-2015 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <assert.h> -#include <error.h> -#include <errno.h> -#include <string.h> -#include "rtld.h" - -#define make_string(string, rest...) \ - ({ \ - const char *all[] = { string, ## rest }; \ - size_t len, cnt; \ - char *result, *cp; \ - \ - len = 1; \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - len += strlen (all[cnt]); \ - \ - cp = result = alloca (len); \ - for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt) \ - cp = __stpcpy (cp, all[cnt]); \ - \ - result; \ - }) - - -static inline struct link_map * -find_needed (const char *name, struct link_map *map) -{ - struct link_map *tmap = map; - unsigned int n = 0; - - for (n = 0; n < map->l_local_scope[0]->r_nlist; n++) - { - tmap = map->l_local_scope[0]->r_list[n]; - if (_dl_name_match_p (name, tmap)) - return tmap; - } - - if (_dl_name_match_p (name, map)) - return map; - - /* Should never happen. */ - return NULL; -} - - -static int -match_symbol (const char *name, Elf64_Word hash, const char *string, - struct link_map *map, int verbose, int weak) -{ - const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - Elf64_Verdef *def; - /* Initialize to make the compiler happy. */ - const char *errstring = NULL; - int result = 0; - - /* Display information about what we are doing while debugging. */ - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_VERSIONS)) - _dl_debug_printf ("\ -checking for version `%s' in file %s [0] required by file %s [0]\n", - string, DSO_FILENAME (map->l_name), - name); - - if (__glibc_unlikely (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL)) - { - /* The file has no symbol versioning. I.e., the dependent - object was linked against another version of this file. We - only print a message if verbose output is requested. */ - if (verbose) - { - /* XXX We cannot translate the messages. */ - errstring = make_string ("\ -no version information available (required by ", name, ")"); - goto call_cerror; - } - return 0; - } - - def = (Elf64_Verdef *) ((char *) map->l_info[VERSYMIDX (DT_VERDEF)]); - while (1) - { - /* Currently the version number of the definition entry is 1. - Make sure all we see is this version. */ - if (__builtin_expect (def->vd_version, 1) != 1) - { - char buf[20]; - buf[sizeof (buf) - 1] = '\0'; - /* XXX We cannot translate the message. */ - /* _itoa (def->vd_version, - &buf[sizeof (buf) - 1], 10, 0), */ - errstring = make_string ("unsupported version ", - " of Verdef record"); - result = 1; - goto call_cerror; - } - - /* Compare the hash values. */ - if (hash == def->vd_hash) - { - Elf64_Verdaux *aux = (Elf64_Verdaux *) ((char *) def + def->vd_aux); - - /* To be safe, compare the string as well. */ - if (__builtin_expect (strcmp (string, strtab + aux->vda_name), 0) - == 0) - /* Bingo! */ - return 0; - } - - /* If no more definitions we failed to find what we want. */ - if (def->vd_next == 0) - break; - - /* Next definition. */ - def = (Elf64_Verdef *) ((char *) def + def->vd_next); - } - - /* Symbol not found. If it was a weak reference it is not fatal. */ - if (__glibc_likely (weak)) - { - if (verbose) - { - /* XXX We cannot translate the message. */ - errstring = make_string ("weak version `", string, - "' not found (required by ", name, ")"); - goto call_cerror; - } - return 0; - } - - /* XXX We cannot translate the message. */ - errstring = make_string ("version `", string, "' not found (required by ", - name, ")"); - result = 1; - call_cerror: - _dl_signal_cerror (0, DSO_FILENAME (map->l_name), - ("version lookup error"), errstring); - return result; -} - - -int -_dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) -{ - int result = 0; - const char *strtab; - /* Pointer to section with needed versions. */ - Elf64_Verneed *dyn; - /* This file may require special versions from its dependencies. */ - Elf64_Verneed *ent; - /* Pointer to dynamic section with definitions. */ - Elf64_Verdef *def; - /* We need to find out which is the highest version index used - in a dependecy. */ - unsigned int ndx_high = 0; - /* Initialize to make the compiler happy. */ - const char *errstring = NULL; - int errval = 0; - - /* If we don't have a string table, we must be ok. */ - if (map->l_info[DT_STRTAB] == NULL) - return 0; - strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); - - dyn = map->l_info[VERSYMIDX (DT_VERNEED)]; - def = map->l_info[VERSYMIDX (DT_VERDEF)]; - ent = (Elf64_Verneed *) (dyn); - - if (dyn != NULL) - { - - /* Currently the version number of the needed entry is 1. - Make sure all we see is this version. */ - if (__builtin_expect (ent->vn_version, 1) != 1) - { - char buf[20]; - buf[sizeof (buf) - 1] = '\0'; - /* XXX We cannot translate the message. */ - /* _itoa (def->vn_version, - &buf[sizeof (buf) - 1], 10, 0), */ - errstring = make_string ("unsupported version ", - " of Verneed record\n"); - call_error: - _dl_signal_error (errval, DSO_FILENAME (map->l_name), - NULL, errstring); - } - - while (1) - { - Elf64_Vernaux *aux; - struct link_map *needed = find_needed (strtab + ent->vn_file, map); - - /* If NEEDED is NULL this means a dependency was not found - and no stub entry was created. This should never happen. */ - if (needed == NULL) - { - _dl_signal_error (errval, NULL, NULL, strtab + ent->vn_file); - printf("error while loading shared libraries: %s", strtab + ent->vn_file); - exit (1); - } - assert (needed != NULL); - - /* Make sure this is no stub we created because of a missing - dependency. */ - if (__builtin_expect (! trace_mode, 1)) - { - /* NEEDED is the map for the file we need. Now look for the - dependency symbols. */ - aux = (Elf64_Vernaux *) ((char *) ent + ent->vn_aux); - while (1) - { - /* Match the symbol. */ - result |= match_symbol (DSO_FILENAME (map->l_name), - aux->vna_hash, - strtab + aux->vna_name, - needed, verbose, - aux->vna_flags & VER_FLG_WEAK); - - /* Compare the version index. */ - if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high) - ndx_high = aux->vna_other & 0x7fff; - - if (aux->vna_next == 0) - /* No more symbols. */ - break; - - /* Next symbol. */ - aux = (Elf64_Vernaux *) ((char *) aux + aux->vna_next); - } - } - - if (ent->vn_next == 0) - /* No more dependencies. */ - break; - - /* Next dependency. */ - ent = (Elf64_Verneed *) ((char *) ent + ent->vn_next); - } - } - - /* We also must store the names of the defined versions. Determine - the maximum index here as well. - - XXX We could avoid the loop by just taking the number of definitions - as an upper bound of new indeces. */ - if (def != NULL) - { - Elf64_Verdef *ent; - ent = (Elf64_Verdef *) (def); - while (1) - { - if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high) - ndx_high = ent->vd_ndx & 0x7fff; - - if (ent->vd_next == 0) - /* No more definitions. */ - break; - - ent = (Elf64_Verdef *) ((char *) ent + ent->vd_next); - } - } - - if (ndx_high > 0) - { - /* Now we are ready to build the array with the version names - which can be indexed by the version index in the VERSYM - section. */ - map->l_versions = (struct r_found_version *) - calloc (ndx_high + 1, sizeof (*map->l_versions)); - if (__glibc_unlikely (map->l_versions == NULL)) - { - errstring = ("cannot allocate version reference table"); - errval = ENOMEM; - goto call_error; - } - - /* Store the number of available symbols. */ - map->l_nversions = ndx_high + 1; - - /* Compute the pointer to the version symbols. */ - map->l_versyms = (void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); - - if (dyn != NULL) - { - Elf64_Verneed *ent; - ent = (Elf64_Verneed *) (dyn); - while (1) - { - Elf64_Vernaux *aux; - aux = (Elf64_Vernaux *) ((char *) ent + ent->vn_aux); - while (1) - { - Elf64_Half ndx = aux->vna_other & 0x7fff; - /* In trace mode, dependencies may be missing. */ - if (__glibc_likely (ndx < map->l_nversions)) - { - map->l_versions[ndx].hash = aux->vna_hash; - map->l_versions[ndx].hidden = aux->vna_other & 0x8000; - map->l_versions[ndx].name = &strtab[aux->vna_name]; - map->l_versions[ndx].filename = &strtab[ent->vn_file]; - } - - if (aux->vna_next == 0) - /* No more symbols. */ - break; - - /* Advance to next symbol. */ - aux = (Elf64_Vernaux *) ((char *) aux + aux->vna_next); - } - - if (ent->vn_next == 0) - /* No more dependencies. */ - break; - - /* Advance to next dependency. */ - ent = (Elf64_Verneed *) ((char *) ent + ent->vn_next); - } - } - - /* And insert the defined versions. */ - if (def != NULL) - { - Elf64_Verdef *ent; - ent = (Elf64_Verdef *) (def); - while (1) - { - Elf64_Verdaux *aux; - aux = (Elf64_Verdaux *) ((char *) ent + ent->vd_aux); - - if ((ent->vd_flags & VER_FLG_BASE) == 0) - { - /* The name of the base version should not be - available for matching a versioned symbol. */ - Elf64_Half ndx = ent->vd_ndx & 0x7fff; - map->l_versions[ndx].hash = ent->vd_hash; - map->l_versions[ndx].name = &strtab[aux->vda_name]; - map->l_versions[ndx].filename = NULL; - } - - if (ent->vd_next == 0) - /* No more definitions. */ - break; - - ent = (Elf64_Verdef *) ((char *) ent + ent->vd_next); - } - } - } - - return result; -} diff --git a/trunk/src/rtld/rtld.c b/trunk/src/rtld/rtld.c deleted file mode 100644 index 82ba4b2..0000000 --- a/trunk/src/rtld/rtld.c +++ /dev/null @@ -1,1425 +0,0 @@ -/* Copyright (C) 2003 MontaVista Software, Inc. - Written by Daniel Jacobowitz <drow@mvista.com>, 2003 - - Copyright (C) 2011 Wind River Systems, Inc. - Significantly updated by Mark Hatle <mark.hatle@windriver.com>, 2011 - - 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, 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 <config.h> -#include <assert.h> -#include <ctype.h> -#include <error.h> -#include <errno.h> -#include <argp.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> -#include <libgen.h> - -#include <inttypes.h> - -#include "prelinktab.h" -#include "reloc.h" -#include "reloc-info.h" - -#include "rtld.h" - -unsigned int static_binary = 0; - -unsigned int _dl_debug_mask = 0; - -/* LD_DYNAMIC_WEAK option. Default is off, changing to 1 - is equivalent to setting LD_DYNAMIC_WEAK. */ -unsigned int _dl_dynamic_weak = 0; -#define MAX_PRELOADED_LIBS 20 - -struct search_path -{ - int maxlen, count, allocated; - char **dirs; -}; - -struct search_path ld_dirs, ld_library_search_path; -int host_paths; - -char * dst_ORIGIN; -char * dst_PLATFORM = ""; /* undefined */ -char * dst_LIB = "lib"; -char * ld_preload = NULL; - - -void string_to_path (struct search_path *path, const char *string); - -const char *argp_program_version = PRELINK_RTLD_PROG PKGVERSION " 1.0"; - -const char *argp_program_bug_address = REPORT_BUGS_TO; - -static char argp_doc[] = PRELINK_RTLD_PROG " -- program to simulate the runtime linker"; - -#define OPT_SYSROOT 0x8c -#define OPT_LIBRARY_PATH 0x8e -#define OPT_TARGET_PATHS 0x8f -#define OPT_LD_PRELOAD 0x90 - -static struct argp_option options[] = { - {"library-path", OPT_LIBRARY_PATH, "LIBRARY_PATH", 0, "Set library search path to LIBRARY_PATH" }, - {"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" }, - {"target-paths", OPT_TARGET_PATHS, 0, 0, "Specified paths are based on ROOT_PATH" }, - {"ld-preload", OPT_LD_PRELOAD, "PATHLIST", 0, "List of LD_PRELOAD libraries"}, - { 0 } -}; - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - switch (key) - { - case OPT_SYSROOT: - sysroot = arg; - break; - case OPT_LIBRARY_PATH: - string_to_path(&ld_library_search_path, arg); - break; - case OPT_TARGET_PATHS: - host_paths = 0; - break; - case OPT_LD_PRELOAD: - ld_preload = arg; - break; - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -/* This function returns the same constants expected by glibc's - symbol lookup routines. This is slightly different from the - equivalent routines in prelink. It should return PLT for any - relocation where an undefined symbol in the application should - be ignored: typically, this means any jump slot or TLS relocations, - but not copy relocations. Don't return the prelinker's - RTYPE_CLASS_TLS. */ - -/* The following needs to be kept in sync with the - sysdeps/.../dl-machine.h: elf_machine_type_class macro */ - -/* From glibc-2.22: sysdeps/i386/dl-machine.h */ -# define i386_elf_machine_type_class(type) \ - ((((type) == R_386_JMP_SLOT || (type) == R_386_TLS_DTPMOD32 \ - || (type) == R_386_TLS_DTPOFF32 || (type) == R_386_TLS_TPOFF32 \ - || (type) == R_386_TLS_TPOFF || (type) == R_386_TLS_DESC) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY) \ - | (((type) == R_386_GLOB_DAT) * ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(EM_386))) - -/* From glibc-2.22: sysdeps/x86_64/dl-machine.h */ -# define x86_64_elf_machine_type_class(type) \ - ((((type) == R_X86_64_JUMP_SLOT \ - || (type) == R_X86_64_DTPMOD64 \ - || (type) == R_X86_64_DTPOFF64 \ - || (type) == R_X86_64_TPOFF64 \ - || (type) == R_X86_64_TLSDESC) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_X86_64_COPY) * ELF_RTYPE_CLASS_COPY) \ - | (((type) == R_X86_64_GLOB_DAT) * ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(EM_X86_64))) - -/* From glibc-2.22: ports/sysdeps/arm/dl-machine.h */ -# define arm_elf_machine_type_class(type) \ - ((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \ - || (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32 \ - || (type) == R_ARM_TLS_DESC) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY) \ - | (((type) == R_ARM_GLOB_DAT) * ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(EM_ARM))) - -/* From glibc-2.22: ports/sysdeps/aarch64/dl-machine.h */ -# define aarch64_elf_machine_type_class(type) \ - ((((type) == R_AARCH64_JUMP_SLOT || \ - (type) == R_AARCH64_TLS_DTPMOD || \ - (type) == R_AARCH64_TLS_DTPREL || \ - (type) == R_AARCH64_TLS_TPREL || \ - (type) == R_AARCH64_TLSDESC) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_AARCH64_COPY) * ELF_RTYPE_CLASS_COPY) \ - | (((type) == R_AARCH64_GLOB_DAT) * ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(EM_AARCH64))) - -/* From glibc-2.22: sysdeps/sh/dl-machine.h */ -# define sh_elf_machine_type_class(type) \ - ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32 \ - || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/powerpc/powerpc32/dl-machine.h */ -#define powerpc32_elf_machine_type_class(type) \ - ((((type) == R_PPC_JMP_SLOT \ - || (type) == R_PPC_REL24 \ - || ((type) >= R_PPC_DTPMOD32 /* contiguous TLS */ \ - && (type) <= R_PPC_DTPREL32) \ - || (type) == R_PPC_ADDR24) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_PPC_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/powerpc/powerpc64/dl-machine.h */ -/* we only support ELFv2 at this point */ -#define IS_PPC64_TLS_RELOC(R) \ - (((R) >= R_PPC64_TLS && (R) <= R_PPC64_DTPREL16_HIGHESTA) \ - || ((R) >= R_PPC64_TPREL16_HIGH && (R) <= R_PPC64_DTPREL16_HIGHA)) - -#define powerpc64_elf_machine_type_class(type) \ - ((((type) == R_PPC64_JMP_SLOT \ - || (type) == R_PPC64_ADDR24 \ - || IS_PPC64_TLS_RELOC (type)) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/mips/dl-machine.h */ -#define ELF_MACHINE_JMP_SLOT R_MIPS_JUMP_SLOT -#define mips_elf_machine_type_class(type) \ - ((((type) == ELF_MACHINE_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/sparc/sparc32/dl-machine.h */ -#define sparc_elf_machine_type_class(type) \ - ((((type) == R_SPARC_JMP_SLOT \ - || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/sparc/sparc64/dl-machine.h */ -# define sparc64_elf_machine_type_class(type) \ - ((((type) == R_SPARC_JMP_SLOT \ - || ((type) >= R_SPARC_TLS_GD_HI22 && (type) <= R_SPARC_TLS_TPOFF64)) \ - * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_SPARC_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* From glibc-2.22: sysdeps/nios2/dl-machine.h */ -# define nios2_elf_machine_type_class(type) \ - ((((type) == R_NIOS2_JUMP_SLOT \ - || (type) == R_NIOS2_TLS_DTPMOD \ - || (type) == R_NIOS2_TLS_DTPREL \ - || (type) == R_NIOS2_TLS_TPREL) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_NIOS2_COPY) * ELF_RTYPE_CLASS_COPY) \ - | (((type) == R_NIOS2_GLOB_DAT) * ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(EM_ALTERA_NIOS2))) - -int -elf_machine_type_class (int type, int machine) -{ - switch (machine) - { - case EM_386: - return i386_elf_machine_type_class(type); - case EM_X86_64: - return x86_64_elf_machine_type_class(type); - case EM_ARM: - return arm_elf_machine_type_class(type); - case EM_AARCH64: - return aarch64_elf_machine_type_class(type); - case EM_SH: - return sh_elf_machine_type_class(type); - case EM_PPC: - return powerpc32_elf_machine_type_class(type); - case EM_PPC64: - return powerpc64_elf_machine_type_class(type); - case EM_MIPS: - return mips_elf_machine_type_class(type); - case EM_SPARC: - case EM_SPARC32PLUS: - return sparc_elf_machine_type_class(type); - case EM_SPARCV9: - return sparc64_elf_machine_type_class(type); - case EM_ALTERA_NIOS2: - return nios2_elf_machine_type_class(type); - - default: - printf ("Unknown architecture!\n"); - exit (1); - return 0; - } -} - -int -extern_protected_data(int machine) -{ - switch (machine) - { - case EM_386: - case EM_X86_64: - case EM_ARM: - case EM_AARCH64: - case EM_ALTERA_NIOS2: - return 4; - default: - return 0; - } -} - -int -machine_no_rela (int machine) -{ - switch (machine) - { - case EM_386: - case EM_X86_64: - case EM_ARM: - case EM_AARCH64: - case EM_SH: - case EM_PPC: - case EM_PPC64: - case EM_MIPS: - case EM_SPARC: - case EM_SPARC32PLUS: - case EM_SPARCV9: - case EM_ALTERA_NIOS2: - return 0; - default: - return 1; - } -} - -int -machine_no_rel (int machine) -{ - switch (machine) - { - case EM_386: - case EM_MIPS: - case EM_ARM: - return 0; - default: - return 1; - } -} - -int -is_ldso_soname (const char *soname) -{ - if ( ! strcmp (soname, "ld-linux.so.2") - || ! strcmp (soname, "ld-linux.so.3") - || ! strcmp (soname, "ld.so.1") - || ! strcmp (soname, "ld-linux-ia64.so.2") - || ! strcmp (soname, "ld-linux-x86-64.so.2") - || ! strcmp (soname, "ld64.so.2") - || ! strcmp (soname, "ld-linux-armhf.so.3") - || ! strcmp (soname, "ld-linux-aarch64.so.1") - || ! strcmp (soname, "ld-linux-aarch64_be.so.1") - || ! strcmp (soname, "ld-linux-nios2.so.1") - ) - return 1; - return 0; -} - -static int dso_open_error = 0; - -static void -free_needed (struct needed_list *p) -{ - struct needed_list *old_p = p; - while (old_p) - { - old_p = p->next; - free (p); - p = old_p; - } -} - -static struct dso_list * -in_dso_list (struct dso_list *dso_list, const char *soname, const char *filename) -{ - while (dso_list != NULL) - { - if (dso_list->dso != NULL) - { - if (strcmp (dso_list->dso->soname, soname) == 0) - return dso_list; - } - - if (strcmp (dso_list->name, soname) == 0) - return dso_list; - - if (filename && dso_list->canon_filename - && strcmp (dso_list->canon_filename, filename) == 0) - return dso_list; - - dso_list = dso_list->next; - } - return NULL; -} - -static int -in_needed_list (struct needed_list *needed_list, const char *soname) -{ - while (needed_list != NULL) - { - if (needed_list->ent->dso != NULL - && strcmp (needed_list->ent->dso->soname, soname) == 0) - return 1; - needed_list = needed_list->next; - } - return 0; -} - - -/****/ - -void -add_dir (struct search_path *path, const char *dir, int dirlen) -{ - if (path->allocated == 0) - { - path->allocated = 5; - path->dirs = malloc (sizeof (char *) * 5); - } - else if (path->count == path->allocated) - { - path->allocated *= 2; - path->dirs = realloc (path->dirs, sizeof (char *) * path->allocated); - } - path->dirs[path->count] = malloc (dirlen + 1); - memcpy (path->dirs[path->count], dir, dirlen); - path->dirs[path->count++][dirlen] = 0; - - if (path->maxlen < dirlen) - path->maxlen = dirlen; -} - -void -free_path (struct search_path *path) -{ - if (path->allocated) - { - int i; - for (i = 0; i < path->count; i++) - free (path->dirs[i]); - free (path->dirs); - } -} - -void -load_ld_so_conf (int use_64bit, int use_mipsn32) -{ - int fd; - FILE *conf; - char buf[1024]; - - memset (&ld_dirs, 0, sizeof (ld_dirs)); - - /* Only use the correct machine, to prevent mismatches if we - have both /lib/ld.so and /lib64/ld.so on x86-64. */ - if (use_64bit) - { - dst_LIB = "lib64"; - add_dir (&ld_dirs, "/lib64/tls", strlen ("/lib64/tls")); - add_dir (&ld_dirs, "/lib64", strlen ("/lib64")); - add_dir (&ld_dirs, "/usr/lib64/tls", strlen ("/usr/lib64/tls")); - add_dir (&ld_dirs, "/usr/lib64", strlen ("/usr/lib64")); - } - else if (use_mipsn32) - { - dst_LIB = "lib32"; - add_dir (&ld_dirs, "/lib32/tls", strlen ("/lib32/tls")); - add_dir (&ld_dirs, "/lib32", strlen ("/lib32")); - add_dir (&ld_dirs, "/usr/lib32/tls", strlen ("/usr/lib32/tls")); - add_dir (&ld_dirs, "/usr/lib32", strlen ("/usr/lib32")); - } - else - { - dst_LIB = "lib"; - add_dir (&ld_dirs, "/lib/tls", strlen ("/lib/tls")); - add_dir (&ld_dirs, "/lib", strlen ("/lib")); - add_dir (&ld_dirs, "/usr/lib/tls", strlen ("/usr/lib/tls")); - add_dir (&ld_dirs, "/usr/lib", strlen ("/usr/lib")); - } - - fd = wrap_open ("/etc/ld.so.conf", O_RDONLY); - if (fd == -1) - return; - conf = fdopen (fd, "r"); - while (fgets (buf, 1024, conf) != NULL) - { - int len; - char *p; - - p = strchr (buf, '#'); - if (p) - *p = 0; - len = strlen (buf); - while (len > 0 && isspace (buf[len - 1])) - buf[--len] = 0; - - if (len > 0) - add_dir (&ld_dirs, buf, len); - } - fclose (conf); -} - -void -string_to_path (struct search_path *path, const char *string) -{ - const char *start, *end, *end_tmp; - - start = string; - while (1) { - end = start; - while (*end && *end != ':' && *end != ';') - end ++; - - /* Eliminate any trailing '/' characters, but be sure to leave a - leading slash if someeone wants / in their RPATH. */ - end_tmp = end; - while (end_tmp > start + 1 && end_tmp[-1] == '/') - end_tmp --; - - add_dir (path, start, end_tmp - start); - - if (*end == 0) - break; - - /* Skip the separator. */ - start = end + 1; - } -} - -char * -find_lib_in_path (struct search_path *path, const char *soname, - int elfclass, int machine) -{ - char *ret = NULL; - int i; - int alt_machine; - - switch (machine) - { - case EM_SPARC: - alt_machine = EM_SPARC32PLUS; - break; - case EM_SPARC32PLUS: - alt_machine = EM_SPARC; - break; - default: - alt_machine = machine; - break; - } - - for (i = 0; i < path->count; i++) - { - char * fixup_path, * path_string; - - path_string = fixup_path = strdup(path->dirs[i]); - - while ((path_string = strchr (path_string, '$'))) - { - char * replace = NULL; - size_t len = 0; - - if (strncmp("$ORIGIN", path_string, 7) == 0) { - replace = dst_ORIGIN; - len = 7; - } else if (strncmp("${ORIGIN}", path_string, 9) == 0) { - replace = dst_ORIGIN; - len = 9; - } else if (strncmp("$PLATFORM", path_string, 9) == 0) { - replace = dst_PLATFORM; - len = 9; - } else if (strncmp("${PLATFORM}", path_string, 11) == 0) { - replace = dst_PLATFORM; - len = 11; - } else if (strncmp("$LIB", path_string, 4) == 0) { - replace = dst_LIB; - len = 4; - } else if (strncmp("${LIB}", path_string, 6) == 0) { - replace = dst_LIB; - len = 6; - } else { - /* Not a defined item, so we skip to the next character */ - path_string += 1; - } - - if (replace) { - size_t new_path_len = strlen(fixup_path) - len + strlen(replace) + 1; - char * new_path = malloc(new_path_len); - - /* Calculate the new path_string position based on the old position */ - size_t new_path_pos = (path_string - fixup_path) + strlen(replace); - - snprintf(new_path, new_path_len, "%.*s%s%s", (int)(path_string-fixup_path), - fixup_path, replace, path_string + len); - - free(fixup_path); - - fixup_path = new_path; - path_string = fixup_path + new_path_pos; - } - } - - ret = malloc (strlen (soname) + 2 + strlen(fixup_path)); - sprintf (ret, "%s/%s", fixup_path, soname); - - if (wrap_access (ret, F_OK) == 0) - { - DSO *dso = open_dso (ret); - int dso_class, dso_machine; - - if (dso == NULL) - continue; - - dso_class = gelf_getclass (dso->elf); - dso_machine = (dso_class == ELFCLASS32) ? - elf32_getehdr (dso->elf)->e_machine : - elf64_getehdr (dso->elf)->e_machine; - - /* Skip 32-bit libraries when looking for 64-bit. Also - skip libraries for alternative machines. */ - if (gelf_getclass (dso->elf) != elfclass - || (dso_machine != machine && dso_machine != alt_machine)) - { - close_dso (dso); - continue; - } - - close_dso (dso); - return ret; - } - } - - free (ret); - return NULL; -} - -char * -find_lib_by_soname (const char *soname, struct dso_list *loader, - int elfclass, int machine) -{ - char *ret; - - if (strchr (soname, '/')) - return strdup (soname); - - if (is_ldso_soname (soname)) - /* For dynamic linker, pull the path out of PT_INTERP header. - When loading an executable the dynamic linker creates an entry for - itself under the name stored in PT_INTERP, and the name that we - record in .gnu.liblist should match that exactly. */ - { - struct dso_list *loader_p = loader; - - while (loader_p) - { - if (loader_p->dso->ehdr.e_type == ET_EXEC) - { - int i; - - for (i = 0; i < loader_p->dso->ehdr.e_phnum; ++i) - if (loader_p->dso->phdr[i].p_type == PT_INTERP) - { - const char *interp; - interp = get_data (loader_p->dso, - loader_p->dso->phdr[i].p_vaddr, - NULL, NULL); - return strdup (interp); - } - } - loader_p = loader_p->loader; - } - } - - if (loader->dso->info[DT_RUNPATH] == 0) - { - /* Search DT_RPATH all the way up. */ - struct dso_list *loader_p = loader; - while (loader_p) - { - if (loader_p->dso->info[DT_RPATH]) - { - struct search_path r_path; - const char *rpath = get_data (loader_p->dso, - loader_p->dso->info[DT_STRTAB] - + loader_p->dso->info[DT_RPATH], - NULL, NULL); - memset (&r_path, 0, sizeof (r_path)); - string_to_path (&r_path, rpath); - ret = find_lib_in_path (&r_path, soname, elfclass, machine); - free_path (&r_path); - if (ret) - return ret; - } - loader_p = loader_p->loader; - } - } - - ret = find_lib_in_path (&ld_library_search_path, soname, elfclass, machine); - if (ret) - return ret; - - if (loader->dso->info[DT_RUNPATH]) - { - struct search_path r_path; - const char *rpath = get_data (loader->dso, - loader->dso->info[DT_STRTAB] - + loader->dso->info[DT_RUNPATH], - NULL, NULL); - memset (&r_path, 0, sizeof (r_path)); - string_to_path (&r_path, rpath); - ret = find_lib_in_path (&r_path, soname, elfclass, machine); - free_path (&r_path); - if (ret) - return ret; - } - - ret = find_lib_in_path (&ld_dirs, soname, elfclass, machine); - if (ret) - return ret; - - return NULL; -} - -static struct dso_list * -load_dsos (DSO *dso, int host_paths) -{ - struct dso_list *dso_list, *dso_list_tail, *cur_dso_ent, *new_dso_ent; - struct stat64 st; - int total_preload = 0; - char * libname[MAX_PRELOADED_LIBS] = {NULL}; - - /* Assume it's static unless we find DT_NEEDED entries */ - static_binary = 1; - - dso_list = malloc (sizeof (struct dso_list)); - dso_list->dso = dso; - dso_list->map = NULL; - dso_list->next = NULL; - dso_list->prev = NULL; - dso_list->needed = NULL; - dso_list->name = dso->filename; - dso_list->loader = NULL; - - if (host_paths) - dso_list->canon_filename = canonicalize_file_name (dso->filename); - else - dso_list->canon_filename = prelink_canonicalize (dso->filename, &st); - - if (dso_list->canon_filename == NULL) - dso_list->canon_filename = strdup (dso->filename); - - cur_dso_ent = dso_list_tail = dso_list; - - if(dso->ehdr.e_type == ET_EXEC && ld_preload) { - char *next_lib = ld_preload; - libname[total_preload] = ld_preload; - total_preload++; - next_lib=strchr(ld_preload,':'); - while(next_lib!=NULL){ - *next_lib = '\0'; - next_lib++; - libname[total_preload] = next_lib; - total_preload++; - next_lib=strchr(next_lib,':'); - } - } - else { - total_preload = 0; - } - while (cur_dso_ent != NULL) - { - DSO *cur_dso, *new_dso; - Elf_Scn *scn; - Elf_Data *data; - GElf_Dyn dyn; - - cur_dso = cur_dso_ent->dso; - if (cur_dso == NULL) - { - cur_dso_ent = cur_dso_ent->next; - continue; - } - - scn = cur_dso->scn[cur_dso->dynamic]; - data = NULL; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - maxndx = data->d_size / cur_dso->shdr[cur_dso->dynamic].sh_entsize; - for (ndx = 0; ndx < maxndx + total_preload; ++ndx) - { - - if(ndx - total_preload >= 0) { - gelfx_getdyn (cur_dso->elf, data, ndx - total_preload, &dyn); - } - else { - dyn.d_tag = DT_NEEDED; - } - - if (dyn.d_tag == DT_NULL) - break; - if (dyn.d_tag == DT_NEEDED) - { - /* Not static... */ - static_binary = 0; - - char *new_name=NULL, *new_canon_name=NULL; - const char * soname = NULL; - if(ndx - total_preload >= 0) { - soname = get_data (cur_dso, - cur_dso->info[DT_STRTAB] - + dyn.d_un.d_val, - NULL, NULL); - } - else { - soname = libname[ndx]; - } - - new_dso_ent = in_dso_list (dso_list, soname, NULL); - if (new_dso_ent == NULL) - { - if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)) - _dl_debug_printf ("file=%s [0]; needed by %s [0]\n", - soname, cur_dso->filename); - - int machine; - int class = gelf_getclass (dso->elf); - machine = (class == ELFCLASS32) ? - elf32_getehdr (dso->elf)->e_machine : - elf64_getehdr (dso->elf)->e_machine; - new_name = find_lib_by_soname (soname, cur_dso_ent, - class, machine); - if (new_name == 0 || wrap_access (new_name, R_OK) < 0) - { - dso_open_error ++; - - new_dso_ent = malloc (sizeof (struct dso_list)); - dso_list_tail->next = new_dso_ent; - dso_list_tail->next->prev = dso_list_tail; - dso_list_tail = dso_list_tail->next; - dso_list_tail->next = NULL; - dso_list_tail->dso = NULL; - dso_list_tail->map = NULL; - dso_list_tail->needed = NULL; - dso_list_tail->name = soname; - dso_list_tail->loader = NULL; - dso_list_tail->canon_filename = strdup(soname); - dso_list_tail->err_no = errno; - - continue; - } - - /* See if the filename we found has already been - opened (possibly under a different SONAME via - some symlink). */ - new_canon_name = prelink_canonicalize (new_name, NULL); - if (new_canon_name == NULL) - new_canon_name = strdup (new_name); - new_dso_ent = in_dso_list (dso_list, soname, new_canon_name); - } - else if (new_dso_ent->dso == NULL) - continue; - - if (new_dso_ent == NULL) - { - new_dso = open_dso (new_name); - free (new_name); - new_dso_ent = malloc (sizeof (struct dso_list)); - dso_list_tail->next = new_dso_ent; - dso_list_tail->next->prev = dso_list_tail; - dso_list_tail = dso_list_tail->next; - dso_list_tail->next = NULL; - dso_list_tail->dso = new_dso; - dso_list_tail->map = NULL; - dso_list_tail->needed = NULL; - dso_list_tail->loader = cur_dso_ent; - dso_list_tail->canon_filename = new_canon_name; - dso_list_tail->err_no = 0; - - if (is_ldso_soname (new_dso->soname)) - dso_list_tail->name = new_dso->filename; - else if (strcmp (new_dso->soname, new_dso->filename) == 0) - /* new_dso->soname might be a full path if the library - had no SONAME. Use the original SONAME instead. */ - dso_list_tail->name = soname; - else - /* Use the new SONAME if possible, in case some library - links to this one using an incorrect SONAME. */ - dso_list_tail->name = new_dso->soname; - } - - if (!cur_dso_ent->needed) - { - cur_dso_ent->needed = malloc (sizeof (struct needed_list)); - cur_dso_ent->needed_tail = cur_dso_ent->needed; - cur_dso_ent->needed_tail->ent = new_dso_ent; - cur_dso_ent->needed_tail->next = NULL; - } - else if (!in_needed_list (cur_dso_ent->needed, soname)) - { - cur_dso_ent->needed_tail->next = malloc (sizeof (struct needed_list)); - cur_dso_ent->needed_tail = cur_dso_ent->needed_tail->next; - cur_dso_ent->needed_tail->ent = new_dso_ent; - cur_dso_ent->needed_tail->next = NULL; - } - - continue; - } - if (dyn.d_tag == DT_FILTER || dyn.d_tag == DT_AUXILIARY) - { - // big fat warning; - } - } - } - cur_dso_ent = cur_dso_ent->next; - } - return dso_list; -} - -struct -{ - void *symptr; - int rtypeclass; -} cache; - -void -do_reloc (DSO *dso, struct link_map *map, struct r_scope_elem *scope[], - GElf_Word sym, GElf_Word type) -{ - struct r_found_version *ver; - int rtypeclass; - void *symptr; - const char *name; - Elf64_Word st_name; - - if (map->l_versyms) - { - int vernum = map->l_versyms[sym] & 0x7fff; - ver = &map->l_versions[vernum]; - - /* Memory was allocated for the hash table, but it's empty! */ - if (ver && (ver->name == NULL || ver->hash == 0)) - ver = NULL; - } - else - ver = NULL; - - rtypeclass = elf_machine_type_class (type, dso->ehdr.e_machine); - - if (gelf_getclass (dso->elf) == ELFCLASS32) - { - Elf32_Sym *sym32 = &((Elf32_Sym *)map->l_info[DT_SYMTAB])[sym]; - - if (ELF32_ST_BIND (sym32->st_info) == STB_LOCAL) - return; - symptr = sym32; - st_name = sym32->st_name; - } - else - { - Elf64_Sym *sym64 = &((Elf64_Sym *)map->l_info[DT_SYMTAB])[sym]; - - if (ELF64_ST_BIND (sym64->st_info) == STB_LOCAL) - return; - symptr = sym64; - st_name = sym64->st_name; - } - - if (cache.symptr == symptr && cache.rtypeclass == rtypeclass) - return; - cache.symptr = symptr; - cache.rtypeclass = rtypeclass; - - name = ((const char *)map->l_info[DT_STRTAB]) + st_name; - - if (gelf_getclass (dso->elf) == ELFCLASS32) - { - const Elf32_Sym *sym32 = symptr; - rtld_lookup_symbol_x32 (name, map, &sym32, scope, ver, rtypeclass, - 0, NULL); - symptr = (void *) sym32; - } - else - { - const Elf64_Sym *sym64 = symptr; - rtld_lookup_symbol_x64 (name, map, &sym64, scope, ver, rtypeclass, - 0, NULL); - symptr = (void *) sym64; - } -} - -void -do_rel_section (DSO *dso, struct link_map *map, - struct r_scope_elem *scope[], - int tag, int section) -{ - Elf_Data *data; - int ndx, maxndx, sym, type; - - data = elf_getdata (dso->scn[section], NULL); - maxndx = data->d_size / dso->shdr[section].sh_entsize; - for (ndx = 0; ndx < maxndx; ndx++) - { - if (tag == DT_REL) - { - GElf_Rel rel; - gelfx_getrel (dso->elf, data, ndx, &rel); - sym = reloc_r_sym (dso, rel.r_info); - type = reloc_r_type (dso, rel.r_info); - } - else - { - GElf_Rela rela; - gelfx_getrela (dso->elf, data, ndx, &rela); - sym = reloc_r_sym (dso, rela.r_info); - type = reloc_r_type (dso, rela.r_info); - } - if (sym != 0) - do_reloc (dso, map, scope, sym, type); - } -} - -void -do_relocs (DSO *dso, struct link_map *map, struct r_scope_elem *scope[], int tag) -{ - GElf_Addr rel_start, rel_end; - GElf_Addr pltrel_start, pltrel_end; - int first, last; - - /* Load the DT_REL or DT_RELA section. */ - if (dso->info[tag] != 0) - { - rel_start = dso->info[tag]; - rel_end = rel_start + dso->info[tag == DT_REL ? DT_RELSZ : DT_RELASZ]; - first = addr_to_sec (dso, rel_start); - last = addr_to_sec (dso, rel_end - 1); - while (first <= last) - do_rel_section (dso, map, scope, tag, first++); - - /* If the DT_JMPREL relocs are of the same type and not included, - load them too. Assume they overlap completely or not at all, - and are in at most a single section. They also need to be adjacent. */ - if (dso->info[DT_PLTREL] == tag) - { - pltrel_start = dso->info[DT_JMPREL]; - pltrel_end = pltrel_start + dso->info[DT_PLTRELSZ]; - if (pltrel_start < rel_start || pltrel_end >= rel_end) - do_rel_section (dso, map, scope, tag, addr_to_sec (dso, pltrel_start)); - } - } - else if (dso->info[DT_PLTREL] == tag) - do_rel_section (dso, map, scope, tag, addr_to_sec (dso, dso->info[DT_JMPREL])); -} - -/* MIPS GOTs are not handled by normal relocations. Instead, entry X - in the global GOT is associated with symbol DT_MIPS_GOTSYM + X. - For the purposes of symbol lookup and conflict resolution, we need - to act as though entry X had a dynamic relocation against symbol - DT_MIPS_GOTSYM + X. */ - -void -do_mips_global_got_relocs (DSO *dso, struct link_map *map, - struct r_scope_elem *scope[]) -{ - GElf_Word i; - - for (i = dso->info_DT_MIPS_GOTSYM; i < dso->info_DT_MIPS_SYMTABNO; i++) - do_reloc (dso, map, scope, i, R_MIPS_REL32); -} - -void -handle_relocs_in_entry (struct dso_list *entry, struct dso_list *dso_list) -{ - do_relocs (entry->dso, entry->map, dso_list->map->l_local_scope, DT_REL); - do_relocs (entry->dso, entry->map, dso_list->map->l_local_scope, DT_RELA); - if (entry->dso->ehdr.e_machine == EM_MIPS) - do_mips_global_got_relocs (entry->dso, entry->map, - dso_list->map->l_local_scope); -} - -void -handle_relocs (DSO *dso, struct dso_list *dso_list) -{ - struct dso_list *ldso, *tail; - - /* do them all last to first. - skip the dynamic linker; then do it last - in glibc this is conditional on the opencount; but every binary - should be linked to libc and thereby have an opencount for ld.so... - besides, that's the only way it would get on our dso list. */ - - tail = dso_list; - while (tail->next) - tail = tail->next; - - ldso = NULL; - while (tail) - { - if (is_ldso_soname (tail->dso->soname)) - ldso = tail; - else - handle_relocs_in_entry (tail, dso_list); - tail = tail->prev; - } - - if (ldso) - handle_relocs_in_entry (ldso, dso_list); -} - -void -add_to_scope (struct r_scope_elem *scope[], struct dso_list *ent) -{ - struct needed_list *n; - int i; - - for (i = 0; i < scope[0]->r_nlist; i++) - if (scope[0]->r_list[i] == ent->map) - return; - - scope[0]->r_list[scope[0]->r_nlist++] = ent->map; - n = ent->needed; - while (n) - { - add_to_scope (scope, n->ent); - n = n->next; - } -} - -void -build_local_scope (struct dso_list *ent, int max) -{ - ent->map->l_local_scope[0] = malloc (sizeof (struct r_scope_elem)); - ent->map->l_local_scope[0]->r_list = malloc (sizeof (struct link_map *) * max); - ent->map->l_local_scope[0]->r_nlist = 0; - add_to_scope (ent->map->l_local_scope, ent); -} - -static struct argp argp = { options, parse_opt, "[FILES]", argp_doc }; - -struct link_map *requested_map = NULL; - -static void process_one_dso (DSO *dso, int host_paths); - -int -main(int argc, char **argv) -{ - int remaining; - int multiple = 0; - host_paths = 1; - - char * debug = NULL; - - sysroot = getenv ("PRELINK_SYSROOT"); -#ifdef DEFAULT_SYSROOT - if (sysroot == NULL) - { - extern char *make_relative_prefix (const char *, const char *, const char *); - sysroot = make_relative_prefix (argv[0], BINDIR, DEFAULT_SYSROOT); - } -#endif - - elf_version (EV_CURRENT); - - argp_parse (&argp, argc, argv, 0, &remaining, 0); - - if (sysroot) - sysroot = canonicalize_file_name (sysroot); - - if (remaining == argc) - error (1, 0, "missing file arguments\nTry `%s: --help' for more information.", argv[0]); - - if ((argc-remaining) >= 2) - multiple = 1; - - /* More simplistic then glibc, one option only... */ - debug = getenv ("RTLD_DEBUG"); - if (debug && (!strcmp(debug, "files") || !strcmp(debug, "all"))) - _dl_debug_mask |= DL_DEBUG_FILES; - - if (debug && (!strcmp(debug, "symbols") || !strcmp(debug, "all"))) - _dl_debug_mask |= DL_DEBUG_SYMBOLS; - - if (debug && (!strcmp(debug, "versions") || !strcmp(debug, "all"))) - _dl_debug_mask |= DL_DEBUG_VERSIONS; - - if (debug && (!strcmp(debug, "bindings") || !strcmp(debug, "all"))) - _dl_debug_mask |= DL_DEBUG_BINDINGS; - - while (remaining < argc) - { - DSO *dso = NULL; - int i, fd; - - struct stat64 st; - - if (host_paths) - fd = open (argv[remaining], O_RDONLY); - else - fd = wrap_open (argv[remaining], O_RDONLY); - - if (fd >= 0 && fstat64(fd, &st) == 0) - if (!S_ISREG(st.st_mode)) - { - error (0, 0, "%s: %s", - argv[remaining], - "not regular file"); - goto exit; - } - - if (fd >= 0) { - dso = fdopen_dso (fd, argv[remaining]); - dst_ORIGIN = dirname(strdup(dso->filename)); - } - - if (dso == NULL) - { - error (0, 0, "%s: %s", - argv[remaining], - strerror(errno)); - goto exit; - } - - load_ld_so_conf (gelf_getclass (dso->elf) == ELFCLASS64, - ( dso->ehdr.e_machine == EM_MIPS) && ( dso->ehdr.e_flags & EF_MIPS_ABI2 ) ); - - if (multiple) - printf ("%s:\n", argv[remaining]); - - for (i = 0; i < dso->ehdr.e_phnum; ++i) - if (dso->phdr[i].p_type == PT_INTERP) - break; - - /* If there are no PT_INTERP segments, it is statically linked. */ - if (dso->ehdr.e_type == ET_EXEC && i == dso->ehdr.e_phnum) - printf ("\tnot a dynamic executable\n"); - else - { - int j; - Elf_Data *data; - j = addr_to_sec (dso, dso->phdr[i].p_vaddr); - if (j != -1) - { - data = elf_getdata (dso->scn[j], NULL); - if (data != NULL) - { - i = strnlen (data->d_buf, data->d_size); - if (i == data->d_size) - { - rtld_signal_error (0, dso->filename, NULL, ".interp section not zero terminated", 0); - } - else - { - rtld_progname = strdup (data->d_buf); - } - } - } - process_one_dso (dso, host_paths); - } - -exit: - remaining++; - } - - return 0; -} - -/* If you run ldd /lib/ld.so you get: - \tstatically linked - - The prelink-rtld does not do this, and returns blank... - */ -static void -process_one_dso (DSO *dso, int host_paths) -{ - struct dso_list *dso_list, *cur_dso_ent, *old_dso_ent; - const char *req; - int i; - int ld_warn = 1; - - if ((req = getenv ("RTLD_TRACE_PRELINKING")) != NULL) - _dl_debug_mask |= DL_DEBUG_PRELINK; - - /* Close enough. Really it's if LD_WARN is "" and RTLD_TRACE_PRELINKING. */ - if (getenv ("RTLD_WARN") == NULL) - ld_warn = 0; - - /* Initialize unique symtable list */ - _ns_unique_sym_table = calloc(sizeof (struct unique_sym_table), 1); - - dso_list = load_dsos (dso, host_paths); - - cur_dso_ent = dso_list; - i = 0; - while (cur_dso_ent) - { - if (cur_dso_ent->dso) - { - create_map_object_from_dso_ent (cur_dso_ent); - if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) && strcmp (req, cur_dso_ent->dso->filename) == 0) - requested_map = cur_dso_ent->map; - } - else - { - /* This is a dummy entry, we couldn't find the object */ - cur_dso_ent->map = _dl_new_object(cur_dso_ent->name, cur_dso_ent->canon_filename, lt_library); - } - i++; - cur_dso_ent = cur_dso_ent->next; - } - dso_list->map->l_local_scope[0] = malloc (sizeof (struct r_scope_elem)); - dso_list->map->l_local_scope[0]->r_list = malloc (sizeof (struct link_map *) * i); - dso_list->map->l_local_scope[0]->r_nlist = i; - cur_dso_ent = dso_list; - i = 0; - while (cur_dso_ent) - { - if (cur_dso_ent->map) - { - dso_list->map->l_local_scope[0]->r_list[i] = cur_dso_ent->map; - if (cur_dso_ent != dso_list) - build_local_scope (cur_dso_ent, dso_list->map->l_local_scope[0]->r_nlist); - - i++; - } - cur_dso_ent = cur_dso_ent->next; - } - - cur_dso_ent = dso_list; - - for (i = 0; i < cur_dso_ent->map->l_local_scope[0]->r_nlist; ++i) - if (cur_dso_ent->map->l_local_scope[0]->r_list[i]->l_versions == NULL) - _dl_check_map_versions (cur_dso_ent->map->l_local_scope[0]->r_list[i], 0, 0); - - rtld_determine_tlsoffsets (dso->ehdr.e_machine, dso_list->map->l_local_scope[0]); - - cur_dso_ent = dso_list; - - /* In ldd mode, do not show the application. Note that we do show it - in list-loaded-objects RTLD_TRACE_PRELINK mode. */ - if (!(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) && cur_dso_ent) - { - /* Based on the presence of DT_NEEDED, see load_dsos */ - if (static_binary) - { - printf ("\tstatically linked\n"); - } - cur_dso_ent = cur_dso_ent->next; - } - while (cur_dso_ent) - { - char *filename; - - if (host_paths && sysroot && cur_dso_ent->dso) - { - const char *rooted_filename; - - if (cur_dso_ent->dso->filename[0] == '/') - rooted_filename = cur_dso_ent->dso->filename; - else - rooted_filename = cur_dso_ent->canon_filename; - - filename = malloc (strlen (rooted_filename) + strlen (sysroot) + 1); - strcpy (filename, sysroot); - strcat (filename, rooted_filename); - } - else if (cur_dso_ent->dso) - filename = strdup (cur_dso_ent->dso->filename); - else - filename = NULL; - - int size_pointer = 16; - if (cur_dso_ent && cur_dso_ent->dso && gelf_getclass (cur_dso_ent->dso->elf) == ELFCLASS32) - size_pointer = 8; - - /* The difference between the two numbers must be dso->base, - and the first number must be unique. */ - if (dso_open_error && ld_warn && (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)) - { - if (cur_dso_ent->dso == NULL) - rtld_signal_error(cur_dso_ent->err_no, cur_dso_ent->name, NULL, "cannot open shared object file", 0); - } - else if (cur_dso_ent->dso == NULL) - printf ("\t%s => not found\n", cur_dso_ent->name); - else if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { - struct link_map * l = cur_dso_ent->map; - if (size_pointer == 16) - printf ("\t%s => %s (0x%016"PRIx64", 0x%016"PRIx64")", - cur_dso_ent->name ? cur_dso_ent->name - : rtld_progname ?: "<main program>", - filename ? filename - : rtld_progname ?: "<main program>", - (uint64_t) l->l_map_start, - (uint64_t) (l->l_map_start == cur_dso_ent->dso->base ? 0 : l->l_map_start)); - else - printf ("\t%s => %s (0x%08"PRIx32", 0x%08"PRIx32")", - cur_dso_ent->name ? cur_dso_ent->name - : rtld_progname ?: "<main program>", - filename ? filename - : rtld_progname ?: "<main program>", - (uint32_t) l->l_map_start, - (uint32_t) (l->l_map_start == cur_dso_ent->dso->base ? 0 : l->l_map_start)); - - if (l->l_tls_modid) - if (size_pointer == 16) - printf (" TLS(0x%"PRIx64", 0x%016"PRIx64")\n", - (uint64_t) l->l_tls_modid, - (uint64_t) l->l_tls_offset); - else - printf (" TLS(0x%"PRIx32", 0x%08"PRIx32")\n", - (uint32_t) l->l_tls_modid, - (uint32_t) l->l_tls_offset); - else - printf ("\n"); - } - else - { - struct link_map * l = cur_dso_ent->map; - if (!(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) && strcmp (cur_dso_ent->name, filename) == 0) - if (size_pointer == 16) - printf ("\t%s (0x%016"PRIx64")\n", cur_dso_ent->name, - (uint64_t) l->l_map_start); - else - printf ("\t%s (0x%08"PRIx32")\n", cur_dso_ent->name, - (uint32_t) l->l_map_start); - else - if (size_pointer == 16) - printf ("\t%s => %s (0x%016"PRIx64")\n", cur_dso_ent->name, - filename, - (uint64_t) l->l_map_start); - else - printf ("\t%s => %s (0x%08"PRIx32")\n", cur_dso_ent->name, - filename, - (uint32_t) l->l_map_start); - } - - if (filename) - free (filename); - - cur_dso_ent = cur_dso_ent->next; - } - - if (dso_open_error) - exit (127); - - if (!ld_warn && (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)) - handle_relocs (dso_list->dso, dso_list); - - cur_dso_ent = dso_list; - while (cur_dso_ent) - { - if (cur_dso_ent->dso) - close_dso (cur_dso_ent->dso); - old_dso_ent = cur_dso_ent; - cur_dso_ent = cur_dso_ent->next; - if (old_dso_ent->needed) - free_needed (old_dso_ent->needed); - free (old_dso_ent); - } -} diff --git a/trunk/src/rtld/rtld.h b/trunk/src/rtld/rtld.h deleted file mode 100644 index c7b5d91..0000000 --- a/trunk/src/rtld/rtld.h +++ /dev/null @@ -1,338 +0,0 @@ -#ifndef _LD_LIBS_H -#define _LD_LIBS_H - -#include "prelinktab.h" - -#include <elf.h> - -#if !defined (__linux__) -#define DT_VERSIONTAGNUM 16 -#endif - -#define link_map ldlibs_link_map - -struct needed_list -{ - struct dso_list *ent; - struct needed_list *next; -}; - -struct dso_list -{ - DSO *dso; - struct link_map *map; - struct dso_list *next, *prev; - struct needed_list *needed, *needed_tail; - const char *name; - struct dso_list *loader; - const char *canon_filename; - int err_no; -}; - -/* A data structure for a simple single linked list of strings. */ -struct libname_list - { - const char *name; /* Name requested (before search). */ - struct libname_list *next; /* Link to next name for this object. */ - }; - -struct link_map; - -struct r_scope_elem -{ - struct link_map **r_list; - unsigned int r_nlist; -}; - -struct r_found_version - { - const char *name; - Elf64_Word hash; - - int hidden; - const char *filename; - }; - -struct unique_sym_table - { - struct unique_sym - { - uint32_t hashval; - const char *name; - const void *sym; - const struct link_map *map; - } *entries; - size_t size; - size_t n_elements; - void (*free) (void *); - }; - -extern struct unique_sym_table * _ns_unique_sym_table; - -/* The size of entries in .hash. Only Alpha and 64-bit S/390 use 64-bit - entries; those are not currently supported. */ -typedef uint32_t Elf_Symndx; - -/* Mimic libc/include/link.h struct link_map */ - -struct link_map - { - int elfclass; - - const char *l_name; - - struct libname_list *l_libname; - -#undef DT_THISPROCNUM -#define DT_THISPROCNUM 0 - - void *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM - + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM]; - - /* Array with vesion names. */ - struct r_found_version *l_versions; - unsigned int l_nversions; - - /* Symbol hash table. */ - Elf_Symndx l_nbuckets; - /* Begin PPC64 workaround */ - void *l_buckets_start; - void *l_buckets_end; - /* end workaround */ - Elf32_Word l_gnu_bitmask_idxbits; - Elf32_Word l_gnu_shift; - void *l_gnu_bitmask; - union - { - const Elf32_Word *l_gnu_buckets; - const Elf_Symndx *l_chain; - }; - union - { - const Elf32_Word *l_gnu_chain_zero; - const Elf_Symndx *l_buckets; - }; - - enum /* Where this object came from. */ - { - lt_executable, /* The main executable program. */ - lt_library, /* Library needed by main executable. */ - lt_loaded /* Extra run-time loaded shared object. */ - } l_type:2; - - /* Pointer to the version information if available. */ - Elf64_Versym *l_versyms; - - /* Start and finish of memory map for this object. l_map_start - need not be the same as l_addr. */ - Elf64_Addr l_map_start; - - /* A similar array, this time only with the local scope. This is - used occasionally. */ - struct r_scope_elem *l_local_scope[2]; - - /* Thread-local storage related info. */ - - /* Size of the TLS block. */ - uint64_t l_tls_blocksize; - /* Alignment requirement of the TLS block. */ - uint64_t l_tls_align; - /* Offset of first byte module alignment. */ - uint64_t l_tls_firstbyte_offset; - - /* For objects present at startup time: offset in the static TLS block. */ - uint64_t l_tls_offset; - /* Index of the module in the dtv array. */ - uint64_t l_tls_modid; - - Elf64_Addr sym_base; - const char *filename; - - Elf64_Half machine; - }; - -#define ELF_RTYPE_CLASS_COPY 2 -#define ELF_RTYPE_CLASS_PLT 1 - -int elf_machine_type_class(int type, int machine); - -int extern_protected_data(int machine); -#define ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA(machine) extern_protected_data(machine) - -int machine_no_rela(int machine); -#define ELF_MACHINE_NO_RELA(machine) machine_no_rela(machine) - -int machine_no_rel(int machine); -#define ELF_MACHINE_NO_REL(machine) machine_no_rel(machine) - -#define GL(x) _##x -#define GLRO(x) _##x -#define INTUSE(x) x - -#define D_PTR(MAP,MEM) MAP->MEM -#define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) - -extern unsigned int _dl_debug_mask; -extern unsigned int _dl_dynamic_weak; - -extern const char *rtld_progname; - -/* This is an optional value before the ':' when debuging is enabled. */ -/* Typically glibc sets this to a number of spaces and the pid of the process*/ -#ifndef RTLD_DEBUG_PID -# define RTLD_DEBUG_PID " " -#endif -#define _dl_debug_printf(...) printf( RTLD_DEBUG_PID ":\t" __VA_ARGS__) - -#define __rtld_lock_lock_recursive(NAME) -#define __rtld_lock_unlock_recursive(NAME) - -/* glibc-2.20: sysdeps/generic/ldsodefs.h */ -/* The filename itself, or the main program name, if available. */ -#define DSO_FILENAME(name) ((name)[0] ? (name) \ - : (rtld_progname ?: "<main program>")) - -#define RTLD_PROGNAME (rtld_progname ?: "<program name unknown>") - -/* glibc-2.20: sysdeps/generic/ldsodefs.h */ -#define DL_DEBUG_LIBS (1 << 0) -#define DL_DEBUG_IMPCALLS (1 << 1) -#define DL_DEBUG_BINDINGS (1 << 2) -#define DL_DEBUG_SYMBOLS (1 << 3) -#define DL_DEBUG_VERSIONS (1 << 4) -#define DL_DEBUG_RELOC (1 << 5) -#define DL_DEBUG_FILES (1 << 6) -#define DL_DEBUG_STATISTICS (1 << 7) -#define DL_DEBUG_UNUSED (1 << 8) -#define DL_DEBUG_SCOPES (1 << 9) -/* These two are used only internally. */ -#define DL_DEBUG_HELP (1 << 10) -#define DL_DEBUG_PRELINK (1 << 11) - -#define _dl_trace_prelink_map requested_map - -extern struct link_map *requested_map; - -#ifndef __glibc_unlikely -#define __glibc_unlikely(a) (a) -#endif - -#ifndef __glibc_likely -#define __glibc_likely(a) (a) -#endif - -/* dl-load.c */ - -#define _dl_new_object rtld_new_object - -struct link_map * _dl_new_object (const char *realname, const char *libname, int type); - -/* dl-lookup.c */ - -#define lookup_t struct link_map * -#define LOOKUP_VALUE(map) map - -/* Search loaded objects' symbol tables for a definition of the symbol - referred to by UNDEF. *SYM is the symbol table entry containing the - reference; it is replaced with the defining symbol, and the base load - address of the defining object is returned. SYMBOL_SCOPE is a - null-terminated list of object scopes to search; each object's - l_searchlist (i.e. the segment of the dependency tree starting at that - object) is searched in turn. REFERENCE_NAME should name the object - containing the reference; it is used in error messages. - TYPE_CLASS describes the type of symbol we are looking for. */ -enum - { - /* If necessary add dependency between user and provider object. */ - DL_LOOKUP_ADD_DEPENDENCY = 1, - /* Return most recent version instead of default version for - unversioned lookup. */ - DL_LOOKUP_RETURN_NEWEST = 2, - /* Set if dl_lookup* called with GSCOPE lock held. */ - DL_LOOKUP_GSCOPE_LOCK = 4, - }; - -#define _dl_setup_hash rtld_setup_hash -void _dl_setup_hash (struct link_map *map); - -#define _dl_lookup_symbol_x32 rtld_lookup_symbol_x32 -#define _dl_lookup_symbol_x64 rtld_lookup_symbol_x64 - -/* Lookup versioned symbol. */ -inline lookup_t _dl_lookup_symbol_x (const char *undef, - struct link_map *undef_map, - const Elf64_Sym **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int flags, - struct link_map *skip_map); - -/* Lookup versioned symbol. */ -lookup_t _dl_lookup_symbol_x32 (const char *undef, - struct link_map *undef_map, - const Elf32_Sym **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int flags, - struct link_map *skip_map); - -/* Lookup versioned symbol. */ -lookup_t _dl_lookup_symbol_x64 (const char *undef, - struct link_map *undef_map, - const Elf64_Sym **sym, - struct r_scope_elem *symbol_scope[], - const struct r_found_version *version, - int type_class, int flags, - struct link_map *skip_map); - -/* dl-version.c */ - -#define _dl_check_map_versions rtld_check_map_versions -int _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode); - -#define _dl_name_match_p rtld_name_match_p -int _dl_name_match_p (const char *name, const struct link_map *map); - -/* Error handling */ - -#include <error.h> -#include <errno.h> - -/* Mimic the behavior and output of _dl_signal_error */ -#define rtld_signal_error(errcode, objname, occation, errstring, status) \ - error(status, errcode, "%s: %s%s%s", \ - occation ?: "error while loading shared libraries", \ - objname ?: "", (objname && *(char *)objname) ? ": " : "", \ - errstring ?: "DYNAMIC LINKER BUG!!!") - -#define _dl_signal_error(errcode, objname, occation, errstring) rtld_signal_error(errcode, objname, occation, errstring, 1) -#define _dl_signal_cerror(errcode, objname, occation, errstring) rtld_signal_error(errcode, objname, occation, errstring, 0) -#define _dl_fatal_printf(errstring) rtld_signal_error(EINVAL, NULL, NULL, errstring, 1) - -/* dl-load.c */ - -extern void create_map_object_from_dso_ent (struct dso_list *); - -/* dl-tls.c */ - -void rtld_determine_tlsoffsets (int e_machine, struct r_scope_elem *search_list); - -#define _dl_determine_tlsoffsets rtld_determine_tlsoffsets - -/* dl-misc.c */ - -#define _dl_name_match_p rtld_name_match_p -#define _dl_higher_prime_number rtld_higher_prime_number - -extern int _dl_name_match_p (const char *name, const struct link_map *map); -extern unsigned long int _dl_higher_prime_number (unsigned long int n); - - -#if defined(__MINGW32__) -# define HOST_LONG_LONG_FORMAT "I64" -#else -# define HOST_LONG_LONG_FORMAT "ll" -#endif - -#endif - diff --git a/trunk/src/sha.c b/trunk/src/sha.c deleted file mode 100644 index cfbc956..0000000 --- a/trunk/src/sha.c +++ /dev/null @@ -1,331 +0,0 @@ -/* sha.c - Functions to compute the SHA1 hash (message-digest) of files - or blocks of memory. Complies to the NIST specification FIPS-180-1. - - Copyright (C) 2000, 2001, 2003 Scott G. Miller - - Credits: - Robert Klep <robert@ilse.nl> -- Expansion function fix - NOTE: The canonical source of this file is maintained in GNU coreutils. -*/ - -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <byteswap.h> -#include "md5.h" -#include "sha.h" - -/* - Not-swap is a macro that does an endian swap on architectures that are - big-endian, as SHA needs some data in a little-endian format -*/ - -#if __BYTE_ORDER == __BIG_ENDIAN -# define SWAP(n) bswap_32 (n) -# define NOTSWAP(n) (n) -#else -# define SWAP(n) (n) -# define NOTSWAP(n) bswap_32 (n) -#endif - -/* This array contains the bytes used to pad the buffer to the next - 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - - -/* - Takes a pointer to a 160 bit block of data (five 32 bit ints) and - intializes it to the start constants of the SHA1 algorithm. This - must be called before using hash in the call to sha_hash -*/ -void -sha_init_ctx (struct sha_ctx *ctx) -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - ctx->E = 0xc3d2e1f0; - - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; -} - -/* Put result from CTX in first 20 bytes following RESBUF. The result - must be in little endian byte order. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -sha_read_ctx (const struct sha_ctx *ctx, void *resbuf) -{ - ((md5_uint32 *) resbuf)[0] = NOTSWAP (ctx->A); - ((md5_uint32 *) resbuf)[1] = NOTSWAP (ctx->B); - ((md5_uint32 *) resbuf)[2] = NOTSWAP (ctx->C); - ((md5_uint32 *) resbuf)[3] = NOTSWAP (ctx->D); - ((md5_uint32 *) resbuf)[4] = NOTSWAP (ctx->E); - - return resbuf; -} - -/* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * -sha_finish_ctx (struct sha_ctx *ctx, void *resbuf) -{ - /* Take yet unprocessed bytes into account. */ - md5_uint32 bytes = ctx->buflen; - size_t pad; - - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; - - pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; - memcpy (&ctx->buffer[bytes], fillbuf, pad); - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = NOTSWAP (ctx->total[0] << 3); - *(md5_uint32 *) &ctx->buffer[bytes + pad] = NOTSWAP ((ctx->total[1] << 3) | - (ctx->total[0] >> 29)); - - /* Process last bytes. */ - sha_process_block (ctx->buffer, bytes + pad + 8, ctx); - - return sha_read_ctx (ctx, resbuf); -} - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * -sha_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha_ctx ctx; - - /* Initialize the computation context. */ - sha_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - sha_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return sha_finish_ctx (&ctx, resblock); -} - -void -sha_process_bytes (const void *buffer, size_t len, struct sha_ctx *ctx) -{ - /* When we already have some bits in our internal buffer concatenate - both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; - - memcpy (&ctx->buffer[left_over], buffer, add); - ctx->buflen += add; - - if (ctx->buflen > 64) - { - sha_process_block (ctx->buffer, ctx->buflen & ~63, ctx); - - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap. */ - memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], - ctx->buflen); - } - - buffer = (const char *) buffer + add; - len -= add; - } - - /* Process available complete blocks. */ - if (len >= 64) - { -#define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) - if (UNALIGNED_P (buffer)) - while (len > 64) - { - sha_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else - { - sha_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; - } - } - - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; - - memcpy (&ctx->buffer[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - sha_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - memcpy (ctx->buffer, &ctx->buffer[64], left_over); - } - ctx->buflen = left_over; - } -} - -/* --- Code below is the primary difference between md5.c and sha.c --- */ - -/* SHA1 round constants */ -#define K1 0x5a827999L -#define K2 0x6ed9eba1L -#define K3 0x8f1bbcdcL -#define K4 0xca62c1d6L - -/* Round functions. Note that F2 is the same as F4. */ -#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) -#define F2(B,C,D) (B ^ C ^ D) -#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) -#define F4(B,C,D) (B ^ C ^ D) - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. - Most of this code comes from GnuPG's cipher/sha1.c. */ - -void -sha_process_block (const void *buffer, size_t len, struct sha_ctx *ctx) -{ - const md5_uint32 *words = buffer; - size_t nwords = len / sizeof (md5_uint32); - const md5_uint32 *endp = words + nwords; - md5_uint32 x[16]; - md5_uint32 a = ctx->A; - md5_uint32 b = ctx->B; - md5_uint32 c = ctx->C; - md5_uint32 d = ctx->D; - md5_uint32 e = ctx->E; - - /* First increment the byte count. RFC 1321 specifies the possible - length of the file up to 2^64 bits. Here we only compute the - number of bytes. Do a double word increment. */ - ctx->total[0] += len; - if (ctx->total[0] < len) - ++ctx->total[1]; - -#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ - ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ - , (x[I&0x0f] = rol(tm, 1)) ) - -#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ - + F( B, C, D ) \ - + K \ - + M; \ - B = rol( B, 30 ); \ - } while(0) - - while (words < endp) - { - md5_uint32 tm; - int t; - /* FIXME: see sha1.c for a better implementation. */ - for (t = 0; t < 16; t++) - { - x[t] = NOTSWAP (*words); - words++; - } - - R( a, b, c, d, e, F1, K1, x[ 0] ); - R( e, a, b, c, d, F1, K1, x[ 1] ); - R( d, e, a, b, c, F1, K1, x[ 2] ); - R( c, d, e, a, b, F1, K1, x[ 3] ); - R( b, c, d, e, a, F1, K1, x[ 4] ); - R( a, b, c, d, e, F1, K1, x[ 5] ); - R( e, a, b, c, d, F1, K1, x[ 6] ); - R( d, e, a, b, c, F1, K1, x[ 7] ); - R( c, d, e, a, b, F1, K1, x[ 8] ); - R( b, c, d, e, a, F1, K1, x[ 9] ); - R( a, b, c, d, e, F1, K1, x[10] ); - R( e, a, b, c, d, F1, K1, x[11] ); - R( d, e, a, b, c, F1, K1, x[12] ); - R( c, d, e, a, b, F1, K1, x[13] ); - R( b, c, d, e, a, F1, K1, x[14] ); - R( a, b, c, d, e, F1, K1, x[15] ); - R( e, a, b, c, d, F1, K1, M(16) ); - R( d, e, a, b, c, F1, K1, M(17) ); - R( c, d, e, a, b, F1, K1, M(18) ); - R( b, c, d, e, a, F1, K1, M(19) ); - R( a, b, c, d, e, F2, K2, M(20) ); - R( e, a, b, c, d, F2, K2, M(21) ); - R( d, e, a, b, c, F2, K2, M(22) ); - R( c, d, e, a, b, F2, K2, M(23) ); - R( b, c, d, e, a, F2, K2, M(24) ); - R( a, b, c, d, e, F2, K2, M(25) ); - R( e, a, b, c, d, F2, K2, M(26) ); - R( d, e, a, b, c, F2, K2, M(27) ); - R( c, d, e, a, b, F2, K2, M(28) ); - R( b, c, d, e, a, F2, K2, M(29) ); - R( a, b, c, d, e, F2, K2, M(30) ); - R( e, a, b, c, d, F2, K2, M(31) ); - R( d, e, a, b, c, F2, K2, M(32) ); - R( c, d, e, a, b, F2, K2, M(33) ); - R( b, c, d, e, a, F2, K2, M(34) ); - R( a, b, c, d, e, F2, K2, M(35) ); - R( e, a, b, c, d, F2, K2, M(36) ); - R( d, e, a, b, c, F2, K2, M(37) ); - R( c, d, e, a, b, F2, K2, M(38) ); - R( b, c, d, e, a, F2, K2, M(39) ); - R( a, b, c, d, e, F3, K3, M(40) ); - R( e, a, b, c, d, F3, K3, M(41) ); - R( d, e, a, b, c, F3, K3, M(42) ); - R( c, d, e, a, b, F3, K3, M(43) ); - R( b, c, d, e, a, F3, K3, M(44) ); - R( a, b, c, d, e, F3, K3, M(45) ); - R( e, a, b, c, d, F3, K3, M(46) ); - R( d, e, a, b, c, F3, K3, M(47) ); - R( c, d, e, a, b, F3, K3, M(48) ); - R( b, c, d, e, a, F3, K3, M(49) ); - R( a, b, c, d, e, F3, K3, M(50) ); - R( e, a, b, c, d, F3, K3, M(51) ); - R( d, e, a, b, c, F3, K3, M(52) ); - R( c, d, e, a, b, F3, K3, M(53) ); - R( b, c, d, e, a, F3, K3, M(54) ); - R( a, b, c, d, e, F3, K3, M(55) ); - R( e, a, b, c, d, F3, K3, M(56) ); - R( d, e, a, b, c, F3, K3, M(57) ); - R( c, d, e, a, b, F3, K3, M(58) ); - R( b, c, d, e, a, F3, K3, M(59) ); - R( a, b, c, d, e, F4, K4, M(60) ); - R( e, a, b, c, d, F4, K4, M(61) ); - R( d, e, a, b, c, F4, K4, M(62) ); - R( c, d, e, a, b, F4, K4, M(63) ); - R( b, c, d, e, a, F4, K4, M(64) ); - R( a, b, c, d, e, F4, K4, M(65) ); - R( e, a, b, c, d, F4, K4, M(66) ); - R( d, e, a, b, c, F4, K4, M(67) ); - R( c, d, e, a, b, F4, K4, M(68) ); - R( b, c, d, e, a, F4, K4, M(69) ); - R( a, b, c, d, e, F4, K4, M(70) ); - R( e, a, b, c, d, F4, K4, M(71) ); - R( d, e, a, b, c, F4, K4, M(72) ); - R( c, d, e, a, b, F4, K4, M(73) ); - R( b, c, d, e, a, F4, K4, M(74) ); - R( a, b, c, d, e, F4, K4, M(75) ); - R( e, a, b, c, d, F4, K4, M(76) ); - R( d, e, a, b, c, F4, K4, M(77) ); - R( c, d, e, a, b, F4, K4, M(78) ); - R( b, c, d, e, a, F4, K4, M(79) ); - - a = ctx->A += a; - b = ctx->B += b; - c = ctx->C += c; - d = ctx->D += d; - e = ctx->E += e; - } -} diff --git a/trunk/src/sha.h b/trunk/src/sha.h deleted file mode 100644 index 13583e3..0000000 --- a/trunk/src/sha.h +++ /dev/null @@ -1,69 +0,0 @@ -/* sha.h - Declaration of functions and datatypes for SHA1 sum computing - library functions. - - Copyright (C) 1999, Scott G. Miller -*/ - -#ifndef _SHA_H -# define _SHA_H 1 - -# include "md5.h" - -/* Structure to save state of computation between the single steps. */ -struct sha_ctx -{ - md5_uint32 A; - md5_uint32 B; - md5_uint32 C; - md5_uint32 D; - md5_uint32 E; - - md5_uint32 total[2]; - md5_uint32 buflen; - char buffer[128]; -}; - - -/* Starting with the result of former calls of this function (or the - initialization function update the context for the next LEN bytes - starting at BUFFER. - It is necessary that LEN is a multiple of 64!!! */ -extern void sha_process_block (const void *buffer, size_t len, - struct sha_ctx *ctx); - -/* Starting with the result of former calls of this function (or the - initialization function update the context for the next LEN bytes - starting at BUFFER. - It is NOT required that LEN is a multiple of 64. */ -extern void sha_process_bytes (const void *buffer, size_t len, - struct sha_ctx *ctx); - -/* Initialize structure containing state of computation. */ -extern void sha_init_ctx (struct sha_ctx *ctx); - -/* Process the remaining bytes in the buffer and put result from CTX - in first 16 bytes following RESBUF. The result is always in little - endian byte order, so that a byte-wise output yields to the wanted - ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -extern void *sha_finish_ctx (struct sha_ctx *ctx, void *resbuf); - - -/* Put result from CTX in first 16 bytes following RESBUF. The result is - always in little endian byte order, so that a byte-wise output yields - to the wanted ASCII representation of the message digest. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -extern void *sha_read_ctx (const struct sha_ctx *ctx, void *resbuf); - - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -extern void *sha_buffer (const char *buffer, size_t len, void *resblock); - -#endif diff --git a/trunk/src/space.c b/trunk/src/space.c deleted file mode 100644 index 4bd4760..0000000 --- a/trunk/src/space.c +++ /dev/null @@ -1,767 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" -#include "space.h" - -#define DEBUG_SECTIONS - -#ifdef DEBUG_SECTIONS -void -print_sections (DSO *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr) -{ - int elf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64; - int i, j, shf, flag; - char buf[32], *q; - const char *p; - static struct { int sh_type; const char *type_name; } types[] = - { - { SHT_NULL, "NULL" }, - { SHT_PROGBITS, "PROGBITS" }, - { SHT_SYMTAB, "SYMTAB" }, - { SHT_STRTAB, "STRTAB" }, - { SHT_RELA, "RELA" }, - { SHT_HASH, "HASH" }, - { SHT_DYNAMIC, "DYNAMIC" }, - { SHT_NOTE, "NOTE" }, - { SHT_NOBITS, "NOBITS" }, - { SHT_REL, "REL" }, - { SHT_SHLIB, "SHLIB" }, - { SHT_DYNSYM, "DYNSYM" }, - { SHT_INIT_ARRAY, "INIT_ARRAY" }, - { SHT_FINI_ARRAY, "FINI_ARRAY" }, - { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" }, - { SHT_GROUP, "GROUP" }, - { SHT_SYMTAB_SHNDX, "SYMTAB SECTION INDICIES" }, - { SHT_GNU_verdef, "VERDEF" }, - { SHT_GNU_verneed, "VERNEED" }, - { SHT_GNU_versym, "VERSYM" }, - { SHT_GNU_LIBLIST, "LIBLIST" }, - { SHT_GNU_HASH, "GNU_HASH" }, - { 0, NULL } - }; - - if (elf64) - printf (" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"); - else - printf (" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"); - for (i = 0; i < ehdr->e_shnum; ++i) - { - p = NULL; - for (j = 0; types[j].type_name; ++j) - if (types[j].sh_type == shdr[i].sh_type) - { - p = types[j].type_name; - break; - } - - if (p == NULL) - { - if (shdr[i].sh_type >= SHT_LOPROC && shdr[i].sh_type <= SHT_HIPROC) - sprintf (buf, "LOPROC+%x", shdr[i].sh_type - SHT_LOPROC); - else if (shdr[i].sh_type >= SHT_LOOS && shdr[i].sh_type <= SHT_HIOS) - sprintf (buf, "LOOS+%x", shdr[i].sh_type - SHT_LOOS); - else if (shdr[i].sh_type >= SHT_LOUSER && shdr[i].sh_type <= SHT_HIUSER) - sprintf (buf, "LOUSER+%x", shdr[i].sh_type - SHT_LOUSER); - else - sprintf (buf, "Unknown: %x", shdr[i].sh_type); - p = buf; - } - - printf (" [%2d] %-17.17s %-15.15s ", i, - strptr (dso, ehdr->e_shstrndx, shdr[i].sh_name), p); - - q = buf; - shf = shdr[i].sh_flags; - while (shf) - { - flag = shf & -shf; - shf &= ~flag; - switch (flag) - { - case SHF_WRITE: *q++ = 'W'; break; - case SHF_ALLOC: *q++ = 'A'; break; - case SHF_EXECINSTR: *q++ = 'X'; break; - case SHF_MERGE: *q++ = 'M'; break; - case SHF_STRINGS: *q++ = 'S'; break; - case SHF_INFO_LINK: *q++ = 'I'; break; - case SHF_LINK_ORDER: *q++ = 'L'; break; - case SHF_OS_NONCONFORMING: *q++ = 'O'; break; - case SHF_TLS: *q++ = 'T'; break; - default: - if (flag & SHF_MASKOS) - *q++ = 'o', shf &= ~SHF_MASKOS; - else if (flag & SHF_MASKPROC) - *q++ = 'p', shf &= ~SHF_MASKPROC; - else - *q++ = 'x'; - break; - } - } - *q = '\0'; - if (elf64) - printf (" %16.16llx %6.6llx %6.6llx %2.2lx %3s %2ld %3lx %2ld\n", - (long long) shdr[i].sh_addr, (long long) shdr[i].sh_offset, - (long long) shdr[i].sh_size, (long) shdr[i].sh_entsize, - buf, (long) shdr[i].sh_link, (long) shdr[i].sh_info, - (long) shdr[i].sh_addralign); - else - printf (" %8.8lx %6.6lx %6.6lx %2.2lx %3s %2ld %3lx %2ld\n", - (long) shdr[i].sh_addr, (long) shdr[i].sh_offset, - (long) shdr[i].sh_size, (long) shdr[i].sh_entsize, - buf, (long) shdr[i].sh_link, (long) shdr[i].sh_info, - (long) shdr[i].sh_addralign); - } -} -#endif - -void -insert_readonly_section (GElf_Ehdr *ehdr, GElf_Shdr *shdr, int n, - struct readonly_adjust *adjust) -{ - int i; - - memmove (&shdr[n + 1], &shdr[n], - (ehdr->e_shnum - n) * sizeof (GElf_Shdr)); - ++ehdr->e_shnum; - for (i = 0; i < adjust->newcount; ++i) - if (adjust->new[i] >= n) - ++adjust->new[i]; -} - -int -remove_readonly_section (GElf_Ehdr *ehdr, GElf_Shdr *shdr, int n, - struct readonly_adjust *adjust) -{ - int i, ret = -1; - - memmove (&shdr[n], &shdr[n + 1], - (ehdr->e_shnum - n) * sizeof (GElf_Shdr)); - --ehdr->e_shnum; - for (i = 0; i < adjust->newcount; ++i) - if (adjust->new[i] > n) - --adjust->new[i]; - else if (adjust->new[i] == n) - { - adjust->new[i] = -1; - ret = i; - } - - return ret; -} - -static inline int -readonly_is_movable (DSO *dso, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int k) -{ - if (! (shdr[k].sh_flags & (SHF_ALLOC | SHF_WRITE))) - return 0; - - switch (shdr[k].sh_type) - { - case SHT_HASH: - case SHT_GNU_HASH: - case SHT_DYNSYM: - case SHT_REL: - case SHT_RELA: - case SHT_STRTAB: - case SHT_NOTE: - case SHT_GNU_verdef: - case SHT_GNU_verneed: - case SHT_GNU_versym: - case SHT_GNU_LIBLIST: - return 1; - default: - if (strcmp (strptr (dso, ehdr->e_shstrndx, - shdr[k].sh_name), ".interp") == 0) - return 1; - return 0; - } -} - -int -find_readonly_space (DSO *dso, GElf_Shdr *add, GElf_Ehdr *ehdr, - GElf_Phdr *phdr, GElf_Shdr *shdr, - struct readonly_adjust *adjust) -{ - int i, j; - GElf_Addr addr; - GElf_Off p_filesz; - - if (add->sh_addr) - { - /* Prefer the current address if possible. */ - for (i = 0; i < ehdr->e_phnum; ++i) - if (phdr[i].p_type == PT_LOAD - && (phdr[i].p_flags & (PF_R | PF_W)) == PF_R - && phdr[i].p_vaddr <= add->sh_addr - && phdr[i].p_vaddr + phdr[i].p_filesz - >= add->sh_addr + add->sh_size) - break; - - if (i < ehdr->e_phnum) - for (j = 1; j < ehdr->e_shnum; ++j) - if ((shdr[j].sh_flags & SHF_ALLOC) - && shdr[j].sh_addr >= add->sh_addr) - { - if (shdr[j].sh_addr >= add->sh_addr + add->sh_size - && shdr[j - 1].sh_addr + shdr[j - 1].sh_size <= add->sh_addr) - { - insert_readonly_section (ehdr, shdr, j, adjust); - shdr[j] = *add; - shdr[j].sh_offset = (shdr[j].sh_addr - phdr[i].p_vaddr) - + phdr[i].p_offset; - return j; - } - break; - } - } - - for (i = 0; i < ehdr->e_phnum; ++i) - if (phdr[i].p_type == PT_LOAD - && (phdr[i].p_flags & (PF_R | PF_W)) == PF_R) - { - GElf_Addr start = phdr[i].p_vaddr; - int after = -1, min; - - if (phdr[i].p_offset < ehdr->e_phoff) - { - for (j = 0; j < ehdr->e_phnum; j++) - if (phdr[j].p_type == PT_PHDR - && phdr[j].p_offset == ehdr->e_phoff - && phdr[j].p_filesz >= ehdr->e_phnum * ehdr->e_phentsize) - break; - start += ehdr->e_phoff; - if (j < ehdr->e_phnum) - start += phdr[j].p_filesz; - else - start += ehdr->e_phnum * ehdr->e_phentsize; - start -= phdr[i].p_offset; - } - start = (start + add->sh_addralign - 1) & ~(add->sh_addralign - 1); - for (j = 1; j < ehdr->e_shnum; ++j) - if ((shdr[j].sh_flags & SHF_ALLOC) - && shdr[j].sh_addr >= phdr[i].p_vaddr - && shdr[j].sh_addr + shdr[j].sh_size - <= phdr[i].p_vaddr + phdr[i].p_filesz) - { - if (after == -1) - after = j - 1; - if (start + add->sh_size > shdr[j].sh_addr) - { - start = shdr[j].sh_addr + shdr[j].sh_size; - start = (start + add->sh_addralign - 1) - & ~(add->sh_addralign - 1); - after = j; - } - } - - min = -1; - for (j = i + 1; j < ehdr->e_phnum; ++j) - if (phdr[j].p_offset >= phdr[i].p_offset + phdr[i].p_filesz - && (min == -1 || phdr[min].p_offset > phdr[j].p_offset)) - min = j; - - if (after != -1 - && (start + add->sh_size <= phdr[i].p_vaddr + phdr[i].p_filesz - || (phdr[i].p_filesz == phdr[i].p_memsz - && (min == -1 - || start + add->sh_size - phdr[i].p_vaddr - <= phdr[min].p_offset)))) - { - insert_readonly_section (ehdr, shdr, after + 1, adjust); - shdr[after + 1] = *add; - shdr[after + 1].sh_addr = start; - shdr[after + 1].sh_offset = (start - phdr[i].p_vaddr) - + phdr[i].p_offset; - if (start + add->sh_size > phdr[i].p_vaddr + phdr[i].p_filesz) - { - adjust_nonalloc (dso, ehdr, shdr, 0, 0, - start + add->sh_size - phdr[i].p_vaddr - - phdr[i].p_filesz); - phdr[i].p_filesz = start + add->sh_size - phdr[i].p_vaddr; - phdr[i].p_memsz = phdr[i].p_filesz; - } - return after + 1; - } - } - - /* If SHT_NOBITS sections are small, just extend the last PT_LOAD - segment. Small enough here means that the whole .bss fits into - the same CPU page as the alloced part of it. */ - for (i = -1, j = 0; j < ehdr->e_phnum; ++j) - if (phdr[j].p_type == PT_LOAD) - i = j; - p_filesz = phdr[i].p_filesz; - - /* If we'll be converting NOBITS .plt to PROGBITS, account for that in the - calculation. */ - for (j = 1; j < ehdr->e_shnum; ++j) - { - if (shdr[j].sh_type == SHT_NOBITS - && shdr[j].sh_addr >= phdr[i].p_vaddr - && shdr[j].sh_addr + shdr[j].sh_size - <= phdr[i].p_vaddr + phdr[i].p_memsz - && !strcmp (strptr (dso, ehdr->e_shstrndx, shdr[j].sh_name), ".plt")) - { - if (shdr[j].sh_addr + shdr[j].sh_size - phdr[i].p_vaddr > p_filesz) - p_filesz = shdr[j].sh_addr + shdr[j].sh_size - phdr[i].p_vaddr; - break; - } - } - - if (phdr[i].p_filesz - && p_filesz <= phdr[i].p_memsz - && !(((phdr[i].p_vaddr + phdr[i].p_memsz - 1) - ^ (phdr[i].p_vaddr + p_filesz - 1)) & ~(dso->arch->page_size - 1))) - { - for (j = 1; j < ehdr->e_shnum; ++j) - { - if (!(shdr[j].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_ALLOC))) - break; - if (shdr[j].sh_type == SHT_NOBITS - && (shdr[j].sh_flags & SHF_TLS) == 0 - && shdr[j].sh_addr >= phdr[i].p_vaddr) - shdr[j].sh_type = SHT_PROGBITS; - } - - insert_readonly_section (ehdr, shdr, j, adjust); - shdr[j] = *add; - shdr[j].sh_addr = (shdr[j - 1].sh_addr + shdr[j - 1].sh_size - + add->sh_addralign - 1) & ~(add->sh_addralign - 1); - shdr[j].sh_offset = (shdr[j].sh_addr - phdr[i].p_vaddr) - + phdr[i].p_offset; - phdr[i].p_filesz = shdr[j].sh_addr + add->sh_size - phdr[i].p_vaddr; - phdr[i].p_memsz = phdr[i].p_filesz; - adjust_nonalloc (dso, ehdr, shdr, 0, 0, phdr[i].p_offset - + phdr[i].p_filesz - shdr[j + 1].sh_offset); - return j; - } - - /* See if we can decrease binary's base VMA and thus gain space. - This trick is mainly useful for IA-32. */ - for (i = 0; i < ehdr->e_phnum; ++i) - if (phdr[i].p_type == PT_LOAD) - break; - - addr = (add->sh_size + add->sh_addralign - 1 + phdr[i].p_align - 1) - & ~(phdr[i].p_align - 1); - if (phdr[i].p_align <= dso->arch->page_size - && phdr[i].p_flags == (PF_R | PF_X) - && phdr[i].p_filesz == phdr[i].p_memsz - && phdr[i].p_vaddr - addr - && ! (((phdr[i].p_vaddr - addr) ^ phdr[i].p_vaddr) - & ~(phdr[i].p_align * 256 - 1))) - { - int moveend; - if (! adjust->basemove_end) - { - for (moveend = 1; moveend < ehdr->e_shnum; ++moveend) - if (strcmp (strptr (dso, ehdr->e_shstrndx, - shdr[moveend].sh_name), ".interp") - && shdr[moveend].sh_type != SHT_NOTE) - break; - if (moveend < ehdr->e_shnum && moveend > 1) - { - adjust->basemove_end = shdr[moveend].sh_addr; - adjust->moveend = moveend; - } - } - else - moveend = adjust->moveend; - if (moveend < ehdr->e_shnum && moveend > 1 - && (shdr[moveend].sh_flags & (SHF_ALLOC | SHF_WRITE))) - { - int k = moveend; - GElf_Addr adj = addr; - - if (add->sh_addr && ! adjust->move2 - && phdr[i].p_vaddr <= add->sh_addr - && phdr[i].p_vaddr + phdr[i].p_filesz > add->sh_addr) - { - for (k = moveend; k < ehdr->e_shnum; ++k) - { - if (! (shdr[k].sh_flags & (SHF_ALLOC | SHF_WRITE))) - { - k = ehdr->e_shnum; - break; - } - - if (shdr[k].sh_addr > add->sh_addr) - { - /* Don't allow inserting in between reloc sections - if they are adjacent. Similarly for adjacent - note sections. */ - int sh_type1 = (shdr[k - 1].sh_type == SHT_RELA) - ? SHT_REL : shdr[k - 1].sh_type; - int sh_type2 = (shdr[k].sh_type == SHT_RELA) - ? SHT_REL : shdr[k].sh_type; - - if (sh_type1 != sh_type2) - break; - - if (sh_type1 != SHT_REL && sh_type1 != SHT_NOTE) - break; - if ((shdr[k - 1].sh_addr - + ((shdr[k - 1].sh_size + 3) & -4)) - != shdr[k].sh_addr) - break; - } - - if (! readonly_is_movable (dso, ehdr, shdr, k)) - { - k = ehdr->e_shnum; - break; - } - } - - if (k < ehdr->e_shnum) - { - GElf_Addr a; - - a = shdr[k].sh_addr; - a -= shdr[k - 1].sh_addr + shdr[k - 1].sh_size; - assert (add->sh_addralign <= phdr[i].p_align); - assert (add->sh_size > a); - a = (add->sh_size - a + phdr[i].p_align - 1) - & ~(phdr[i].p_align - 1); - if (a < adj) - { - adjust->move2 = 1; - adj = a; - } - else - k = moveend; - } - else - k = moveend; - } - - for (j = 1; j < k; ++j) - shdr[j].sh_addr -= adj; - phdr[i].p_vaddr -= adj; - phdr[i].p_paddr -= adj; - phdr[i].p_filesz += adj; - phdr[i].p_memsz += adj; - for (j = 0; j < ehdr->e_phnum; ++j) - { - if (j == i) - continue; - /* Leave STACK segment alone, it has p_vaddr == p_paddr == 0 - and p_offset == p_filesz == p_memsz == 0. */ - if (phdr[j].p_type == PT_GNU_STACK) - continue; - if (phdr[j].p_vaddr - < adjust->basemove_end - adjust->basemove_adjust) - { - phdr[j].p_vaddr -= adj; - phdr[j].p_paddr -= adj; - } - else - phdr[j].p_offset += adj; - } - adjust->basemove_adjust += adj; - insert_readonly_section (ehdr, shdr, k, adjust); - shdr[k] = *add; - if (k == moveend) - { - addr = shdr[k - 1].sh_addr + shdr[k - 1].sh_size; - addr = (addr + add->sh_addralign - 1) & ~(add->sh_addralign - 1); - } - else - { - addr = (shdr[k + 1].sh_addr - add->sh_size) - & ~(add->sh_addralign - 1); - } - - shdr[k].sh_addr = addr; - shdr[k].sh_offset = (addr - phdr[i].p_vaddr) + phdr[i].p_offset; - adjust_nonalloc (dso, ehdr, shdr, 0, 0, adj); - return k; - } - } - - /* We have to create new PT_LOAD if at all possible. */ - for (j = 0; j < ehdr->e_phnum; ++j) - if (phdr[j].p_type == PT_NULL) - break; - - if (j < ehdr->e_phnum) - { - memmove (phdr, &phdr[j + 1], - (ehdr->e_phnum - j - 1) * sizeof (GElf_Phdr)); - ehdr->e_phnum--; - } - else - { - addr = ehdr->e_phoff + (ehdr->e_phnum + 1) * ehdr->e_phentsize; - for (j = 1; j < ehdr->e_shnum; ++j) - { - if (addr > shdr[j].sh_offset) - { - GElf_Addr start, addstart, endaddr, *old_addr; - GElf_Addr minsize = ~(GElf_Addr) 0; - int movesec = -1, last, k, e; - - if (ehdr->e_phoff < phdr[i].p_offset - || ehdr->e_phoff + (ehdr->e_phnum + 1) * ehdr->e_phentsize - > phdr[i].p_offset + phdr[i].p_filesz - || ! readonly_is_movable (dso, ehdr, shdr, j) - || shdr[j].sh_addr >= phdr[i].p_vaddr + phdr[i].p_filesz) - { - error (0, 0, "%s: No space in ELF segment table to add new ELF segment", - dso->filename); - return 0; - } - - start = phdr[i].p_vaddr - phdr[i].p_offset + ehdr->e_phoff - + (ehdr->e_phnum + 1) * ehdr->e_phentsize; - for (last = 1; last < ehdr->e_shnum; ++last) - if (! readonly_is_movable (dso, ehdr, shdr, last) - || shdr[last].sh_addr >= phdr[i].p_vaddr + phdr[i].p_filesz) - break; - for (j = 1; j < last; ++j) - { - addstart = (start + add->sh_addralign - 1) - & ~(add->sh_addralign - 1); - start = (start + shdr[j].sh_addralign - 1) - & ~(shdr[j].sh_addralign - 1); - endaddr = -1; - if (j + 1 < ehdr->e_shnum) - endaddr = shdr[j + 1].sh_addr; - if (phdr[i].p_vaddr + phdr[i].p_filesz < endaddr) - endaddr = phdr[i].p_vaddr + phdr[i].p_filesz; - - switch (shdr[j].sh_type) - { - case SHT_HASH: - case SHT_GNU_HASH: - case SHT_DYNSYM: - case SHT_STRTAB: - case SHT_GNU_verdef: - case SHT_GNU_verneed: - case SHT_GNU_versym: - case SHT_GNU_LIBLIST: - if (endaddr >= start - && endaddr - start < minsize) - { - minsize = endaddr - start; - movesec = j; - } - if (endaddr > addstart - && endaddr - addstart > add->sh_size - && endaddr - addstart - add->sh_size - < minsize) - { - minsize = endaddr - addstart - add->sh_size; - movesec = j; - } - break; - case SHT_REL: - case SHT_RELA: - case SHT_NOTE: - /* Don't allow inserting in between reloc sections - if they are adjacent. Similarly for adjacent - note sections. */ - if (j + 1 < ehdr->e_shnum) - { - if (shdr[j].sh_type == SHT_NOTE) - { - if (shdr[j + 1].sh_type != SHT_NOTE) - break; - } - else if (shdr[j + 1].sh_type != SHT_REL - && shdr[j + 1].sh_type != SHT_RELA) - { - break; - } - - if ((shdr[j].sh_addr - + ((shdr[j].sh_size + 3) & -4)) - != shdr[j + 1].sh_addr) - break; - - start += shdr[j].sh_size; - continue; - } - break; - } - - if (start + shdr[j].sh_size <= endaddr) - { - movesec = j + 1; - break; - } - start += shdr[j].sh_size; - } - - if (movesec == -1) - { - error (0, 0, "%s: No space in ELF segment table to add new ELF segment", - dso->filename); - return 0; - } - - start = phdr[i].p_vaddr - phdr[i].p_offset + ehdr->e_phoff - + (ehdr->e_phnum + 1) * ehdr->e_phentsize; - old_addr = (GElf_Addr *) alloca (movesec * sizeof (GElf_Addr)); - for (k = 1; k < movesec; ++k) - { - start = (start + shdr[k].sh_addralign - 1) - & ~(shdr[k].sh_addralign - 1); - old_addr[k] = shdr[k].sh_addr; - shdr[k].sh_addr = start; - shdr[k].sh_offset = start + phdr[i].p_offset - - phdr[i].p_vaddr; - start += shdr[k].sh_size; - } - - for (e = 0; e < ehdr->e_phnum; ++e) - if (phdr[e].p_type != PT_LOAD - && phdr[e].p_type != PT_GNU_STACK) - for (k = 1; k < movesec; ++k) - if (old_addr[k] == phdr[e].p_vaddr) - { - if (phdr[e].p_filesz != shdr[k].sh_size - || phdr[e].p_memsz != shdr[k].sh_size) - { - int k1 = -1; - if (phdr[e].p_type == PT_NOTE - && shdr[k].sh_type == SHT_NOTE - && phdr[e].p_filesz == phdr[e].p_memsz) - { - k1 = k; - while (k1 < movesec) - { - if (shdr[k1].sh_type != SHT_NOTE - || shdr[k1].sh_addr - old_addr[k1] - != shdr[k].sh_addr - old_addr[k] - || old_addr[k1] + shdr[k1].sh_size - > phdr[e].p_vaddr + phdr[e].p_filesz) - { - k1 = -1; - break; - } - if (old_addr[k1] + shdr[k1].sh_size - == phdr[e].p_vaddr + phdr[e].p_filesz) - break; - ++k1; - } - if (k1 == movesec) - k1 = -1; - } - if (k1 == -1) - { - error (0, 0, "%s: Non-PT_LOAD segment spanning more than one section", - dso->filename); - return 0; - } - } - phdr[e].p_vaddr += shdr[k].sh_addr - old_addr[k]; - phdr[e].p_paddr += shdr[k].sh_addr - old_addr[k]; - phdr[e].p_offset += shdr[k].sh_addr - old_addr[k]; - break; - } - - if (j < last) - /* Now continue as if there was place for a new PT_LOAD - in ElfW(Phdr) table initially. */ - break; - else - { - GElf_Shdr moveshdr; - int newidx, ret, movedidx, oldidx; - - moveshdr = shdr[movesec]; - newidx = remove_readonly_section (ehdr, shdr, movesec, adjust); - oldidx = adjust->move->new_to_old[movesec]; - remove_section (adjust->move, movesec); - ret = find_readonly_space (dso, add, ehdr, phdr, shdr, adjust); - if (ret == 0) - return 0; - movedidx = find_readonly_space (dso, &moveshdr, ehdr, phdr, - shdr, adjust); - if (movedidx == 0) - return 0; - if (newidx != -1) - adjust->new[newidx] = movedidx; - add_section (adjust->move, movedidx); - if (oldidx != -1) - { - adjust->move->old_to_new[oldidx] = movedidx; - adjust->move->new_to_old[movedidx] = oldidx; - } - if (movedidx <= ret) - ++ret; - return ret; - } - } - } - } - - for (i = 0, j = 0; i < ehdr->e_phnum; ++i) - if (phdr[i].p_type == PT_LOAD) - j = i; - else if (phdr[i].p_type == PT_PHDR) - { - if (phdr[i].p_filesz == ehdr->e_phnum * ehdr->e_phentsize) - phdr[i].p_filesz += ehdr->e_phentsize; - if (phdr[i].p_memsz == ehdr->e_phnum * ehdr->e_phentsize) - phdr[i].p_memsz += ehdr->e_phentsize; - } - - memmove (&phdr[j + 2], &phdr[j + 1], - (ehdr->e_phnum - j - 1) * sizeof (GElf_Phdr)); - ++ehdr->e_phnum; - phdr[++j].p_type = PT_LOAD; - phdr[j].p_offset = phdr[j - 1].p_offset + phdr[j - 1].p_filesz; - phdr[j].p_offset = (phdr[j].p_offset + add->sh_addralign - 1) - & ~(add->sh_addralign - 1); - phdr[j].p_align = phdr[j - 1].p_align; - phdr[j].p_vaddr = phdr[j - 1].p_vaddr + phdr[j - 1].p_memsz; - phdr[j].p_vaddr += (phdr[j].p_align - 1); - phdr[j].p_vaddr &= ~(phdr[j].p_align - 1); - phdr[j].p_vaddr += (phdr[j].p_offset & (phdr[j].p_align - 1)); - phdr[j].p_paddr = phdr[j].p_vaddr; - /* Although the content of the segment is read-only, unless it ends on - a page boundary, we must make it writeable. This is because the rest of - the last page in the segment will be used as sbrk area which is assumed - to be writeable. */ - phdr[j].p_flags = (PF_R | PF_W); - phdr[j].p_filesz = add->sh_size; - phdr[j].p_memsz = add->sh_size; - for (i = 1; i < ehdr->e_shnum; ++i) - if (! (shdr[i].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR))) - break; - assert (i < ehdr->e_shnum); - insert_readonly_section (ehdr, shdr, i, adjust); - shdr[i] = *add; - shdr[i].sh_addr = phdr[j].p_vaddr; - shdr[i].sh_offset = phdr[j].p_offset; - adjust_nonalloc (dso, ehdr, shdr, 0, 0, - phdr[j].p_offset + phdr[j].p_filesz - phdr[j - 1].p_offset - - phdr[j - 1].p_filesz); - return i; -} diff --git a/trunk/src/space.h b/trunk/src/space.h deleted file mode 100644 index 5c9f725..0000000 --- a/trunk/src/space.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2001, 2004 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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. */ - -#ifndef SPACE_H -#define SPACE_H - -struct readonly_adjust -{ - off_t basemove_adjust; - GElf_Addr basemove_end; - int moveend; - int move2; - int newcount, *new; - struct section_move *move; -}; - -void insert_readonly_section (GElf_Ehdr *ehdr, GElf_Shdr *shdr, int n, - struct readonly_adjust *adjust); -int remove_readonly_section (GElf_Ehdr *ehdr, GElf_Shdr *shdr, int n, - struct readonly_adjust *adjust); -int find_readonly_space (DSO *dso, GElf_Shdr *add, GElf_Ehdr *ehdr, - GElf_Phdr *phdr, GElf_Shdr *shdr, - struct readonly_adjust *adjust); - -#endif /* SPACE_H */ diff --git a/trunk/src/stabs.c b/trunk/src/stabs.c deleted file mode 100644 index c0a5a6a..0000000 --- a/trunk/src/stabs.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (C) 2001, 2005, 2006 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <byteswap.h> -#include <endian.h> -#include <error.h> - -#include "prelink.h" - -#define N_ZERO 0x00 -#define N_GSYM 0x20 -#define N_FNAME 0x22 -#define N_FUN 0x24 -#define N_STSYM 0x26 -#define N_LCSYM 0x28 -#define N_MAIN 0x2a -#define N_BNSYM 0x2e -#define N_PC 0x30 -#define N_NSYMS 0x32 -#define N_NOMAP 0x34 -#define N_OBJ 0x38 -#define N_OPT 0x3c -#define N_RSYM 0x40 -#define N_M2C 0x42 -#define N_SLINE 0x44 -#define N_DSLINE 0x46 -#define N_BSLINE 0x48 -#define N_BROWS 0x48 -#define N_DEFD 0x4a -#define N_ENSYM 0x4e -#define N_EHDECL 0x50 -#define N_MOD2 0x50 -#define N_CATCH 0x54 -#define N_SSYM 0x60 -#define N_SO 0x64 -#define N_LSYM 0x80 -#define N_BINCL 0x82 -#define N_SOL 0x84 -#define N_PSYM 0xa0 -#define N_EINCL 0xa2 -#define N_ENTRY 0xa4 -#define N_LBRAC 0xc0 -#define N_EXCL 0xc2 -#define N_SCOPE 0xc4 -#define N_RBRAC 0xe0 -#define N_BCOMM 0xe2 -#define N_ECOMM 0xe4 -#define N_ECOML 0xe8 -#define N_LENG 0xfe - -static uint32_t -read_native (char *p) -{ - return *(uint32_t *)p; -} - -static uint32_t -read_swap (char *p) -{ - return bswap_32 (*(uint32_t *)p); -} - -static void -write_native (char *p, uint32_t v) -{ - *(uint32_t *)p = v; -} - -static void -write_swap (char *p, uint32_t v) -{ - *(uint32_t *)p = bswap_32 (v); -} - -int -adjust_stabs (DSO *dso, int n, GElf_Addr start, GElf_Addr adjust) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - off_t off; - uint32_t (*read_32) (char *p); - void (*write_32) (char *p, uint32_t v); - uint32_t value; - int sec, type; - - assert (dso->shdr[n].sh_entsize == 12); - data = elf_getdata (scn, NULL); - assert (data != NULL && data->d_buf != NULL); - assert (elf_getdata (scn, data) == NULL); - assert (data->d_off == 0 && data->d_size == dso->shdr[n].sh_size); -#if __BYTE_ORDER == __BIG_ENDIAN - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) -#elif __BYTE_ORDER == __LITTLE_ENDIAN - if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) -#else -# error Not supported host endianess -#endif - { - read_32 = read_native; - write_32 = write_native; - } -#if __BYTE_ORDER == __BIG_ENDIAN - else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB) -#elif __BYTE_ORDER == __LITTLE_ENDIAN - else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) -#endif - { - read_32 = read_swap; - write_32 = write_swap; - } - else - { - error (0, 0, "%s: Wrong ELF data enconding", dso->filename); - return 1; - } - - for (off = 0; off < data->d_size; off += 12) - { - switch ((type = *(uint8_t *)(data->d_buf + off + 4))) - { - case N_FUN: - /* If string is "", N_FUN is function length, otherwise - it is function start address. */ - if (read_32 (data->d_buf + off) == 0) - break; - /* FALLTHROUGH */ - case N_STSYM: - case N_LCSYM: - case N_CATCH: - case N_SO: - case N_SOL: - case N_BNSYM: - case N_ENSYM: - value = read_32 (data->d_buf + off + 8); - sec = addr_to_sec (dso, value); - if (sec != -1) - { - addr_adjust (value, start, adjust); - write_32 (data->d_buf + off + 8, value); - } - break; - /* These should be always 0. */ - case N_GSYM: - case N_BINCL: - case N_EINCL: - case N_EXCL: - case N_BCOMM: - case N_ECOMM: - /* These contain other values. */ - case N_ZERO: - case N_NSYMS: - case N_NOMAP: - case N_RSYM: - case N_LSYM: - case N_PSYM: - case N_OPT: - /* These are relative. */ - case N_LBRAC: - case N_RBRAC: - case N_SLINE: - case N_BSLINE: - case N_DSLINE: - break; - default: - error (0, 0, "%s: Unknown stabs code 0x%02x\n", dso->filename, type); - return 1; - } - } - - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - return 0; -} diff --git a/trunk/src/undo.c b/trunk/src/undo.c deleted file mode 100644 index 8a55bf2..0000000 --- a/trunk/src/undo.c +++ /dev/null @@ -1,713 +0,0 @@ -/* Copyright (C) 2001, 2002, 2003, 2005, 2010 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2001. - - 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, 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 <config.h> -#include <assert.h> -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include "prelink.h" -#include "reloc.h" - -static int -undo_prelink_rel (DSO *dso, int n) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rel rel; - int sec; - - if (dso->arch->undo_prelink_rel == NULL) - return 0; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrel (dso->elf, data, ndx, &rel); - sec = addr_to_sec (dso, rel.r_offset); - if (sec == -1) - continue; - - switch (dso->arch->undo_prelink_rel (dso, &rel, addr)) - { - case 2: - gelfx_update_rel (dso->elf, data, ndx, &rel); - break; - case 0: - break; - default: - return 1; - } - } - } - return 0; -} - -static int -undo_prelink_rela (DSO *dso, int n) -{ - Elf_Data *data = NULL; - Elf_Scn *scn = dso->scn[n]; - GElf_Rela rela; - int sec; - - if (dso->arch->undo_prelink_rela == NULL) - return 0; - while ((data = elf_getdata (scn, data)) != NULL) - { - int ndx, maxndx; - GElf_Addr addr = dso->shdr[n].sh_addr + data->d_off; - - maxndx = data->d_size / dso->shdr[n].sh_entsize; - for (ndx = 0; ndx < maxndx; - ++ndx, addr += dso->shdr[n].sh_entsize) - { - gelfx_getrela (dso->elf, data, ndx, &rela); - sec = addr_to_sec (dso, rela.r_offset); - if (sec == -1) - continue; - - switch (dso->arch->undo_prelink_rela (dso, &rela, addr)) - { - case 2: - gelfx_update_rela (dso->elf, data, ndx, &rela); - break; - case 0: - break; - default: - return 1; - } - } - } - return 0; -} - -static int -remove_dynamic_prelink_tags (DSO *dso) -{ - Elf_Data *data; - Elf_Scn *scn; - GElf_Dyn dyn; - int ndx; - - assert (dso->shdr[dso->dynamic].sh_type == SHT_DYNAMIC); - scn = dso->scn[dso->dynamic]; - data = elf_getdata (scn, NULL); - assert (elf_getdata (scn, data) == NULL); - ndx = data->d_size / dso->shdr[dso->dynamic].sh_entsize; - while (--ndx >= 0) - { - gelfx_getdyn (dso->elf, data, ndx, &dyn); - switch (dyn.d_tag) - { - case DT_NULL: - continue; - case DT_CHECKSUM: - case DT_GNU_PRELINKED: - case DT_GNU_LIBLIST: - case DT_GNU_LIBLISTSZ: - case DT_GNU_CONFLICT: - case DT_GNU_CONFLICTSZ: - dyn.d_tag = DT_NULL; - dyn.d_un.d_val = 0; - gelfx_update_dyn (dso->elf, data, ndx, &dyn); - elf_flagscn (scn, ELF_C_SET, ELF_F_DIRTY); - break; - default: - ndx = 0; - break; - } - } - return 0; -} - -int -undo_sections (DSO *dso, int undo, struct section_move *move, - struct reloc_info *rinfo, GElf_Ehdr *ehdr, - GElf_Phdr *phdr, GElf_Shdr *shdr) -{ - Elf_Data src, dst, *d; - Elf_Scn *scn; - int i, j; - - scn = dso->scn[undo]; - d = elf_getdata (scn, NULL); - assert (d != NULL && elf_getdata (scn, d) == NULL); - - src = *d; - src.d_type = ELF_T_EHDR; - src.d_align = dso->shdr[undo].sh_addralign; - src.d_size = gelf_fsize (dso->elf, ELF_T_EHDR, 1, EV_CURRENT); - dst = src; - if (src.d_size > d->d_size) - { - error (0, 0, "%s: .gnu.prelink_undo section too small", - dso->filename); - return 1; - } - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - dst.d_buf = alloca (dst.d_size); - break; - case ELFCLASS64: - dst.d_buf = ehdr; - break; - default: - return 1; - } - if (gelf_xlatetom (dso->elf, &dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Could not read .gnu.prelink_undo section", - dso->filename); - return 1; - } - if (gelf_getclass (dso->elf) == ELFCLASS32) - { - Elf32_Ehdr *ehdr32 = (Elf32_Ehdr *) dst.d_buf; - - memcpy (ehdr->e_ident, ehdr32->e_ident, sizeof (ehdr->e_ident)); -#define COPY(name) ehdr->name = ehdr32->name - COPY (e_type); - COPY (e_machine); - COPY (e_version); - COPY (e_entry); - COPY (e_phoff); - COPY (e_shoff); - COPY (e_flags); - COPY (e_ehsize); - COPY (e_phentsize); - COPY (e_phnum); - COPY (e_shentsize); - COPY (e_shnum); - COPY (e_shstrndx); -#undef COPY - } - - if (memcmp (ehdr->e_ident, dso->ehdr.e_ident, sizeof (ehdr->e_ident)) - || ehdr->e_type != dso->ehdr.e_type - || ehdr->e_machine != dso->ehdr.e_machine - || ehdr->e_version != dso->ehdr.e_version - || ehdr->e_flags != dso->ehdr.e_flags - || ehdr->e_ehsize != dso->ehdr.e_ehsize - || ehdr->e_phentsize != dso->ehdr.e_phentsize - || ehdr->e_shentsize != dso->ehdr.e_shentsize) - { - error (0, 0, "%s: ELF headers changed since prelinking", - dso->filename); - return 1; - } - - if (ehdr->e_phnum > dso->ehdr.e_phnum) - { - error (0, 0, "%s: Number of program headers is less than before prelinking", - dso->filename); - return 1; - } - - if (d->d_size != (src.d_size - + gelf_fsize (dso->elf, ELF_T_PHDR, ehdr->e_phnum, - EV_CURRENT) - + gelf_fsize (dso->elf, ELF_T_SHDR, ehdr->e_shnum - 1, - EV_CURRENT))) - { - error (0, 0, "%s: Incorrect size of .gnu.prelink_undo section", - dso->filename); - return 1; - } - - src.d_type = ELF_T_PHDR; - src.d_buf += src.d_size; - src.d_size = gelf_fsize (dso->elf, ELF_T_PHDR, ehdr->e_phnum, EV_CURRENT); - dst = src; - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - dst.d_buf = alloca (dst.d_size); - break; - case ELFCLASS64: - dst.d_buf = phdr; - break; - } - if (gelf_xlatetom (dso->elf, &dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Could not read .gnu.prelink_undo section", - dso->filename); - return 1; - } - - if (gelf_getclass (dso->elf) == ELFCLASS32) - { - Elf32_Phdr *phdr32 = (Elf32_Phdr *) dst.d_buf; - - for (i = 0; i < ehdr->e_phnum; ++i) - { -#define COPY(name) phdr[i].name = phdr32[i].name - COPY(p_type); - COPY(p_flags); - COPY(p_offset); - COPY(p_vaddr); - COPY(p_paddr); - COPY(p_filesz); - COPY(p_memsz); - COPY(p_align); -#undef COPY - } - } - - memset (shdr, 0, sizeof (GElf_Shdr)); - src.d_type = ELF_T_SHDR; - src.d_buf += src.d_size; - src.d_size = gelf_fsize (dso->elf, ELF_T_SHDR, ehdr->e_shnum - 1, EV_CURRENT); - dst = src; - switch (gelf_getclass (dso->elf)) - { - case ELFCLASS32: - dst.d_buf = alloca (dst.d_size); - break; - case ELFCLASS64: - dst.d_buf = shdr + 1; - break; - default: - return 1; - } - if (gelf_xlatetom (dso->elf, &dst, &src, dso->ehdr.e_ident[EI_DATA]) == NULL) - { - error (0, 0, "%s: Could not read .gnu.prelink_undo section", - dso->filename); - return 1; - } - - if (gelf_getclass (dso->elf) == ELFCLASS32) - { - Elf32_Shdr *shdr32 = (Elf32_Shdr *) dst.d_buf; - - for (i = 1; i < ehdr->e_shnum; ++i) - { -#define COPY(name) shdr[i].name = shdr32[i - 1].name - COPY (sh_name); - COPY (sh_type); - COPY (sh_flags); - COPY (sh_addr); - COPY (sh_offset); - COPY (sh_size); - COPY (sh_link); - COPY (sh_info); - COPY (sh_addralign); - COPY (sh_entsize); -#undef COPY - } - } - - move->new_shnum = ehdr->e_shnum; - for (i = 1; i < move->old_shnum; ++i) - move->old_to_new[i] = -1; - for (i = 1; i < move->new_shnum; ++i) - move->new_to_old[i] = -1; - - for (i = 1; i < move->old_shnum; ++i) - { - for (j = 1; j < move->new_shnum; ++j) - if (dso->shdr[i].sh_name == shdr[j].sh_name - && dso->shdr[i].sh_type == shdr[j].sh_type - && dso->shdr[i].sh_flags == shdr[j].sh_flags - && dso->shdr[i].sh_addralign == shdr[j].sh_addralign - && dso->shdr[i].sh_entsize == shdr[j].sh_entsize - && dso->shdr[i].sh_size == shdr[j].sh_size - && move->new_to_old[j] == -1) - break; - - if (j == move->new_shnum) - continue; - - move->old_to_new[i] = j; - move->new_to_old[j] = i; - } - - for (i = 1; i < move->old_shnum; ++i) - if (move->old_to_new[i] == -1) - { - const char *name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name); - - if (! strcmp (name, ".gnu.prelink_undo") - || ! strcmp (name, ".gnu.conflict") - || ! strcmp (name, ".gnu.liblist") - || ! strcmp (name, ".gnu.libstr") - || ((! strcmp (name, ".dynbss") || ! strcmp (name, ".sdynbss")) - && dso->ehdr.e_type == ET_EXEC)) - continue; - - if ((! strcmp (name, ".dynstr") && dso->ehdr.e_type == ET_EXEC) - || i == dso->ehdr.e_shstrndx) - { - for (j = 1; j < move->new_shnum; ++j) - if (dso->shdr[i].sh_name == shdr[j].sh_name - && dso->shdr[i].sh_type == shdr[j].sh_type - && dso->shdr[i].sh_flags == shdr[j].sh_flags - && dso->shdr[i].sh_addralign == shdr[j].sh_addralign - && dso->shdr[i].sh_entsize == shdr[j].sh_entsize - && dso->shdr[i].sh_size > shdr[j].sh_size - && move->new_to_old[j] == -1) - break; - - if (j < move->new_shnum) - { - move->old_to_new[i] = j; - move->new_to_old[j] = i; - continue; - } - } - - if (((i >= rinfo->first && i <= rinfo->last) || i == rinfo->plt) - && dso->shdr[i].sh_type == SHT_RELA) - { - for (j = 1; j < move->new_shnum; ++j) - if (dso->shdr[i].sh_name == shdr[j].sh_name - && shdr[j].sh_type == SHT_REL - && dso->shdr[i].sh_flags == shdr[j].sh_flags - && dso->shdr[i].sh_addralign == shdr[j].sh_addralign - && 2 * dso->shdr[i].sh_entsize == 3 * shdr[j].sh_entsize - && 2 * dso->shdr[i].sh_size == 3 * shdr[j].sh_size - && move->new_to_old[j] == -1) - break; - - if (j < move->new_shnum) - { - move->old_to_new[i] = j; - move->new_to_old[j] = i; - continue; - } - } - - if (! strcmp (name, ".bss") - || ! strcmp (name, ".sbss") - || ((! strcmp (name, ".plt") || ! strcmp (name, ".iplt")) - && dso->shdr[i].sh_type == SHT_PROGBITS)) - { - int is_plt = ! strcmp (name, ".plt"); - - for (j = 1; j < move->new_shnum; ++j) - if (dso->shdr[i].sh_name == shdr[j].sh_name - && dso->shdr[i].sh_flags == shdr[j].sh_flags - && dso->shdr[i].sh_addralign == shdr[j].sh_addralign - && (is_plt || dso->shdr[i].sh_entsize == shdr[j].sh_entsize) - && move->new_to_old[j] == -1) - { - if (is_plt) - { - if (dso->shdr[i].sh_size != shdr[j].sh_size) - continue; - if (shdr[j].sh_type == SHT_NOBITS - && dso->shdr[i].sh_entsize == shdr[j].sh_entsize) - break; - /* On Alpha prelink fixes bogus sh_entsize of .plt - sections. */ - if (shdr[j].sh_type == SHT_PROGBITS) - break; - } - else - { - const char *pname; - - if (dso->shdr[i].sh_type != shdr[j].sh_type - && (dso->shdr[i].sh_type != SHT_PROGBITS - || shdr[j].sh_type != SHT_NOBITS)) - continue; - - if (dso->shdr[i].sh_size == shdr[j].sh_size) - break; - - pname = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i - 1].sh_name); - if (strcmp (pname, ".dynbss") - && strcmp (pname, ".sdynbss")) - continue; - - if (dso->shdr[i].sh_size + dso->shdr[i - 1].sh_size - == shdr[j].sh_size) - break; - } - } - - if (j < move->new_shnum) - { - move->old_to_new[i] = j; - move->new_to_old[j] = i; - continue; - } - } - - error (0, 0, "%s: Section %s created after prelinking", - dso->filename, name); - return 1; - } - - for (i = 1; i < move->new_shnum; ++i) - if (move->new_to_old[i] == -1) - { - const char *name = strptr (dso, dso->ehdr.e_shstrndx, shdr[i].sh_name); - - error (0, 0, "%s: Section %s removed after prelinking", dso->filename, - name); - return 1; - } - - return 0; -} - -int -prelink_undo (DSO *dso) -{ - GElf_Ehdr ehdr; - GElf_Shdr shdr[dso->ehdr.e_shnum + 20], old_shdr[dso->ehdr.e_shnum]; - GElf_Phdr phdr[dso->ehdr.e_phnum]; - Elf_Scn *scn; - Elf_Data *d; - int undo, i; - struct section_move *move; - struct reloc_info rinfo; - - for (undo = 1; undo < dso->ehdr.e_shnum; ++undo) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[undo].sh_name), - ".gnu.prelink_undo")) - break; - - if (undo == dso->ehdr.e_shnum) - { - if (undo_output) - return 0; - error (0, 0, "%s does not have .gnu.prelink_undo section", dso->filename); - return 1; - } - - memcpy (old_shdr, dso->shdr, sizeof (GElf_Shdr) * dso->ehdr.e_shnum); - move = init_section_move (dso); - if (move == NULL) - return 1; - - if (find_reloc_sections (dso, &rinfo)) - goto error_out; - - if (undo_sections (dso, undo, move, &rinfo, &ehdr, phdr, shdr)) - goto error_out; - - if (reopen_dso (dso, move, (undo_output && strcmp (undo_output, "-") == 0) - ? "/tmp/undo" : undo_output)) - goto error_out; - - if (find_reloc_sections (dso, &rinfo)) - goto error_out; - - for (i = 1; i < dso->ehdr.e_shnum; i++) - { - if (! (dso->shdr[i].sh_flags & SHF_ALLOC)) - continue; - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name), - ".gnu.conflict")) - continue; - switch (dso->shdr[i].sh_type) - { - case SHT_REL: - if (undo_prelink_rel (dso, i)) - goto error_out; - break; - case SHT_RELA: - if (undo_prelink_rela (dso, i)) - goto error_out; - break; - } - } - - if (dso->arch->arch_undo_prelink && dso->arch->arch_undo_prelink (dso)) - goto error_out; - - if (dso->ehdr.e_type == ET_DYN) - { - GElf_Addr adjust = 0, diff; - - for (i = dso->ehdr.e_shnum - 1; i > 0; --i) - if (shdr[i].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)) - { - adjust = shdr[i].sh_addr - dso->shdr[i].sh_addr; - break; - } - while (i > 0) - { - int nsec = 1, j; - /* Change here PROGBITS .plt into NOBITS if needed. */ - - /* Convert RELA to REL if needed. */ - if (dso->shdr[i].sh_type == SHT_RELA && shdr[i].sh_type == SHT_REL) - { - assert (dso->arch->rela_to_rel != NULL); - if (i == rinfo.plt) - { - if (convert_rela_to_rel (dso, i)) - goto error_out; - dso->shdr[i].sh_size = shdr[i].sh_size; - } - else if (i == rinfo.last) - { - GElf_Addr start = dso->shdr[rinfo.first].sh_addr; - - for (j = rinfo.first; j <= rinfo.last; ++j) - { - if (convert_rela_to_rel (dso, j)) - goto error_out; - dso->shdr[j].sh_addr = start; - dso->shdr[j].sh_size = shdr[j].sh_size; - start += dso->shdr[j].sh_size; - } - nsec = rinfo.last - rinfo.first + 1; - i = rinfo.first; - } - else - { - error (0, 0, "%s: Cannot convert RELA to REL", dso->filename); - goto error_out; - } - } - diff = shdr[i].sh_addr - dso->shdr[i].sh_addr; - if (diff != adjust) - { - assert (diff >= adjust); - if (adjust_dso (dso, dso->shdr[i + nsec].sh_addr, adjust - diff)) - goto error_out; - adjust = diff; - } - --i; - } - if (adjust && adjust_dso (dso, 0, adjust)) - goto error_out; - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (shdr[i].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)) - assert (shdr[i].sh_addr == dso->shdr[i].sh_addr); - } - else - { - /* Executable. */ - for (i = 1; i < dso->ehdr.e_shnum; ++i) - { - const char *name = strptr (dso, dso->ehdr.e_shstrndx, - dso->shdr[i].sh_name); - - if (dso->shdr[i].sh_type == SHT_PROGBITS - && shdr[i].sh_type == SHT_NOBITS) - { - assert (strcmp (name, ".bss") == 0 - || strcmp (name, ".sbss") == 0 - || strcmp (name, ".plt") == 0 - || strcmp (name, ".iplt") == 0); - scn = dso->scn[i]; - d = elf_getdata (scn, NULL); - assert (d != NULL && elf_getdata (scn, d) == NULL); - assert (d->d_size == 0 || d->d_buf != NULL); - assert (d->d_size == dso->shdr[i].sh_size); - free (d->d_buf); - d->d_buf = NULL; - dso->shdr[i].sh_type = SHT_NOBITS; - } - else if (dso->shdr[i].sh_type == SHT_RELA - && shdr[i].sh_type == SHT_REL) - { - if (convert_rela_to_rel (dso, i)) - goto error_out; - dso->shdr[i].sh_size = shdr[i].sh_size; - } - else - assert (dso->shdr[i].sh_type == shdr[i].sh_type); - if (dso->shdr[i].sh_size != shdr[i].sh_size) - { - /* This is handled in code below for both ET_DYN and ET_EXEC. */ - if (i == dso->ehdr.e_shstrndx) - continue; - assert (shdr[i].sh_type == SHT_NOBITS - || shdr[i].sh_size < dso->shdr[i].sh_size); - assert (strcmp (name, ".dynstr") == 0 - || strcmp (name, ".bss") == 0 - || strcmp (name, ".sbss") == 0); - scn = dso->scn[i]; - d = elf_getdata (scn, NULL); - assert (d != NULL && elf_getdata (scn, d) == NULL); - d->d_size = shdr[i].sh_size; - } - } - - if (update_dynamic_tags (dso, shdr, old_shdr, move)) - goto error_out; - - for (i = 1; i < dso->ehdr.e_shnum; ++i) - if (shdr[i].sh_flags & (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR)) - dso->shdr[i].sh_addr = shdr[i].sh_addr; - } - - /* Clear .dynamic entries added by prelink, update others. */ - if (remove_dynamic_prelink_tags (dso) - || update_dynamic_rel (dso, &rinfo)) - goto error_out; - - /* Shrink .shstrtab. */ - i = dso->ehdr.e_shstrndx; - if (shdr[i].sh_size < dso->shdr[i].sh_size) - { - scn = dso->scn[i]; - d = elf_getdata (scn, NULL); - assert (d != NULL && elf_getdata (scn, d) == NULL); - assert (d->d_size == dso->shdr[i].sh_size); - d->d_size = shdr[i].sh_size; - } - - /* Now restore the rest. */ - for (i = 1; i < dso->ehdr.e_shnum; ++i) - dso->shdr[i] = shdr[i]; - if (dso->ehdr.e_phnum != ehdr.e_phnum) - { - assert (ehdr.e_phnum < dso->ehdr.e_phnum); - if (gelf_newphdr (dso->elf, ehdr.e_phnum) == 0) - { - error (0, 0, "Could not create new ELF headers"); - goto error_out; - } - } - for (i = 0; i < ehdr.e_phnum; ++i) - dso->phdr[i] = phdr[i]; - dso->permissive = 1; - assert (dso->ehdr.e_entry == ehdr.e_entry); - assert (dso->ehdr.e_shnum == ehdr.e_shnum); - assert (dso->ehdr.e_shstrndx == ehdr.e_shstrndx); - dso->ehdr.e_phoff = ehdr.e_phoff; - dso->ehdr.e_shoff = ehdr.e_shoff; - dso->ehdr.e_phnum = ehdr.e_phnum; - free (move); - return 0; - -error_out: - free (move); - return 1; -} diff --git a/trunk/src/undoall.c b/trunk/src/undoall.c deleted file mode 100644 index 99d2397..0000000 --- a/trunk/src/undoall.c +++ /dev/null @@ -1,175 +0,0 @@ -/* Copyright (C) 2002, 2005 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2002. - - 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, 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 <config.h> -#include <alloca.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <string.h> -#include <sys/stat.h> -#include <time.h> -#include <unistd.h> -#include "prelinktab.h" - -static int -undo_one (void **p, void *info) -{ - struct prelink_entry *ent = * (struct prelink_entry **) p; - DSO *dso; - struct stat64 st; - struct prelink_link *hardlink; - char *move = NULL, *move_temp; - size_t movelen = 0; - - if (ent->done != 2) - return 1; - - if (ent->type != ET_DYN - && (ent->type != ET_EXEC || libs_only)) - return 1; - - dso = open_dso (ent->canon_filename); - if (dso == NULL) - goto error_out; - - if (fstat64 (dso->fd, &st) < 0) - { - error (0, errno, "%s changed during prelinking", ent->filename); - goto error_out; - } - - if (st.st_dev != ent->dev || st.st_ino != ent->ino) - { - error (0, 0, "%s changed during prelinking", ent->filename); - goto error_out; - } - - if (verbose) - { - if (dry_run) - printf ("Would undo %s\n", ent->canon_filename); - else - printf ("Undoing %s\n", ent->canon_filename); - } - - if (prelink_undo (dso)) - goto error_out; - - if (dry_run) - close_dso (dso); - else - { - if (update_dso (dso, NULL)) - { - dso = NULL; - goto error_out; - } - } - - dso = NULL; - - /* Redo hardlinks. */ - for (hardlink = ent->hardlink; hardlink; hardlink = hardlink->next) - { - size_t len; - - if (wrap_lstat64 (hardlink->canon_filename, &st) < 0) - { - error (0, 0, "Could not stat %s (former hardlink to %s)", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (st.st_dev != ent->dev || st.st_ino != ent->ino) - { - error (0, 0, "%s is no longer hardlink to %s", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (verbose) - { - if (dry_run) - printf ("Would link %s to %s\n", hardlink->canon_filename, - ent->canon_filename); - else - printf ("Linking %s to %s\n", hardlink->canon_filename, - ent->canon_filename); - } - - len = strlen (hardlink->canon_filename); - if (len + sizeof (".#prelink#") > movelen) - { - movelen = len + sizeof (".#prelink#"); - move_temp = move; - move = realloc (move, movelen); - if (move == NULL) - { - free(move_temp); - error (0, ENOMEM, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - movelen = 0; - continue; - } - } - - memcpy (mempcpy (move, hardlink->canon_filename, len), ".#prelink#", - sizeof (".#prelink#")); - if (wrap_rename (hardlink->canon_filename, move) < 0) - { - error (0, errno, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - continue; - } - - if (wrap_link (ent->canon_filename, hardlink->canon_filename) < 0) - { - error (0, errno, "Could not hardlink %s to %s", - hardlink->canon_filename, ent->canon_filename); - - if (wrap_rename (move, hardlink->canon_filename) < 0) - { - error (0, errno, "Could not rename %s back to %s", - move, hardlink->canon_filename); - } - continue; - } - - if (wrap_unlink (move) < 0) - { - error (0, errno, "Could not unlink %s", move); - continue; - } - } - free (move); - return 1; - -error_out: - if (dso) - close_dso (dso); - (*(int *)info)++; - return 1; -} - -int -undo_all (void) -{ - int failures = 0; - htab_traverse (prelink_filename_htab, undo_one, &failures); - return failures != 0; -} diff --git a/trunk/src/verify.c b/trunk/src/verify.c deleted file mode 100644 index d9f4d7d..0000000 --- a/trunk/src/verify.c +++ /dev/null @@ -1,458 +0,0 @@ -/* Copyright (C) 2002, 2003, 2006, 2007, 2010 Red Hat, Inc. - Written by Jakub Jelinek <jakub@redhat.com>, 2002. - - 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, 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 <config.h> -#include <assert.h> -#include <endian.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <sys/mman.h> -#include "prelink.h" -#include "md5.h" -#include "sha.h" - -ssize_t -send_file (int outfd, int infd, off_t *poff, size_t count) -{ - char buf[65536], *b, *p, *q; - size_t todo = count, len; - ssize_t n; - - b = mmap (NULL, count, PROT_READ, MAP_PRIVATE, infd, *poff); - if (b != MAP_FAILED) - { - p = b; - q = p + count; - while (p != q) - { - n = TEMP_FAILURE_RETRY (write (outfd, p, q - p)); - if (n <= 0) - { - munmap (b, count); - return -1; - } - p += n; - } - munmap (b, count); - return count; - } - - if (lseek (infd, *poff, SEEK_SET) != *poff) - return -1; - while (todo > 0) - { - len = todo > sizeof (buf) ? sizeof (buf) : todo; - p = buf; - q = buf + len; - while (p != q) - { - n = TEMP_FAILURE_RETRY (read (infd, p, q - p)); - if (n <= 0) - return -1; - p += n; - } - p = buf; - while (p != q) - { - n = TEMP_FAILURE_RETRY (write (outfd, p, q - p)); - if (n <= 0) - return -1; - p += n; - } - todo -= len; - } - return count; -} - -static int -checksum_file (int fd, size_t count, - void (*sum) (const void *, size_t, void *), void *arg) -{ - char buf[65536+64], *b, *p, *q; - size_t todo = count, len; - ssize_t n; - - b = mmap (NULL, count, PROT_READ, MAP_PRIVATE, fd, 0); - if (b != MAP_FAILED) - { - sum (b, count, arg); - munmap (b, count); - return 0; - } - - b = (char *) (((uintptr_t) buf + 63) & ~(uintptr_t) 63); - while (todo > 0) - { - len = todo > 65536 ? 65536 : todo; - p = b; - q = b + len; - while (p != q) - { - n = TEMP_FAILURE_RETRY (read (fd, p, q - p)); - if (n < 0) - return 1; - p += n; - } - sum (b, len, arg); - todo -= len; - } - return 0; -} - -static int -handle_verify (int fd, const char *filename) -{ - off_t off; - size_t cnt; - struct stat64 st; - - if (fstat64 (fd, &st) < 0) - { - error (0, errno, "%s: couldn't fstat temporary file", filename); - return 1; - } - - if (verify_method == VERIFY_CONTENT) - { - off = 0; - if (send_file (1, fd, &off, st.st_size) != st.st_size) - { - error (0, errno, "Couldn't write file to standard output"); - return 1; - } - } - else if (verify_method == VERIFY_MD5) - { - struct md5_ctx ctx; - unsigned char bin_buffer[16]; - - md5_init_ctx (&ctx); - if (checksum_file (fd, st.st_size, - (void (*) (const void *, size_t, void *)) - md5_process_bytes, &ctx)) - { - error (0, errno, "%s: Couldn't read temporary file", filename); - return 1; - } - - md5_finish_ctx (&ctx, bin_buffer); - for (cnt = 0; cnt < 16; ++cnt) - printf ("%02x", bin_buffer[cnt]); - printf (" %s\n", filename); - } - else if (verify_method == VERIFY_SHA) - { - struct sha_ctx ctx; - unsigned char bin_buffer[20]; - - sha_init_ctx (&ctx); - if (checksum_file (fd, st.st_size, - (void (*) (const void *, size_t, void *)) - sha_process_bytes, &ctx)) - { - error (0, errno, "%s: Couldn't read temporary file", filename); - return 1; - } - - sha_finish_ctx (&ctx, bin_buffer); - for (cnt = 0; cnt < 20; ++cnt) - printf ("%02x", bin_buffer[cnt]); - printf (" %s\n", filename); - } - return 0; -} - -int -prelink_verify (const char *filename) -{ - DSO *dso = NULL, *dso2 = NULL; - int fd = -1, fdorig = -1, fdundone = -1, undo, ret; - struct stat64 st, st2; - struct prelink_entry *ent; - GElf_Addr base; - char buffer[32768], buffer2[32768]; - size_t count; - char *p, *q; - - if (wrap_stat64 (filename, &st) < 0) - error (EXIT_FAILURE, errno, "Couldn't stat %s", filename); - - dso = open_dso (filename); - if (dso == NULL) - goto not_prelinked; - - if (dso->ehdr.e_type != ET_DYN && dso->ehdr.e_type != ET_EXEC) - { - error (0, 0, "%s is not an ELF shared library nor binary", filename); - goto not_prelinked; - } - - for (undo = 1; undo < dso->ehdr.e_shnum; ++undo) - if (! strcmp (strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[undo].sh_name), - ".gnu.prelink_undo")) - break; - - if (undo == dso->ehdr.e_shnum) - goto not_prelinked; - - if (fstat64 (dso->fd, &st2) < 0) - { - error (0, errno, "Couldn't fstat %s", filename); - goto failure; - } - - if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino - || st.st_size != st2.st_size) - { - error (0, 0, "%s: changed during --verify", filename); - goto failure; - } - - if (read_config (prelink_conf)) - goto failure; - - if (gather_config ()) - goto failure; - - if (gather_object (filename, 0, 0)) - goto failure; - - ent = prelink_find_entry (filename, &st, 0); - if (ent == NULL) - { - error (0, 0, "%s disappeared while running --verify", filename); - goto failure; - } - - if (ent->done != 2) - { - error (0, 0, "%s: at least one of file's dependencies has changed since prelinking", - filename); - goto failure; - } - - base = dso->base; - ent->base = base; - - ret = prelink_undo (dso); - if (ret) - goto failure; - - switch (write_dso (dso)) - { - case 2: - error (0, 0, "Could not write temporary for %s: %s", filename, - elf_errmsg (-1)); - goto failure; - case 1: - goto failure; - case 0: - break; - } - - fd = wrap_open (dso->temp_filename, O_RDONLY); - if (fd < 0) - { - error (0, errno, "Could not verify %s", filename); - goto failure; - } - - fdorig = dup (dso->fdro); - if (fdorig < 0) - { - error (0, errno, "Could not verify %s", filename); - goto failure; - } - - ent->filename = dso->temp_filename; - dso->temp_filename = NULL; - close_dso (dso); - dso = NULL; - - fchmod (fd, 0700); - - dso2 = fdopen_dso (fd, filename); - if (dso2 == NULL) - goto failure_unlink; - fd = -1; - - if (prelink_prepare (dso2)) - goto failure_unlink; - - if (ent->type == ET_DYN && relocate_dso (dso2, base)) - goto failure_unlink; - - if (prelink (dso2, ent)) - goto failure_unlink; - - wrap_unlink (ent->filename); - - if (write_dso (dso2)) - goto failure; - - fd = dup (dso2->fd); - if (fd < 0) - { - error (0, errno, "Could not verify %s", filename); - goto failure; - } - - fdundone = dup (dso2->fdro); - if (fdundone < 0) - { - error (0, errno, "Could not verify %s", filename); - goto failure; - } - - close_dso (dso2); - dso2 = NULL; - - if (fstat64 (fdorig, &st2) < 0) - { - error (0, errno, "Couldn't fstat %s", filename); - goto failure; - } - - if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino - || st.st_size != st2.st_size) - { - error (0, 0, "%s: changed during --verify", filename); - goto failure; - } - - if (fstat64 (fd, &st2) < 0) - { - error (0, errno, "Couldn't fstat temporary file"); - goto failure; - } - - if (st.st_size != st2.st_size) - { - error (0, 0, "%s: prelinked file size differs", filename); - goto failure; - } - - q = MAP_FAILED; - p = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fdorig, 0); - if (p != MAP_FAILED) - { - q = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (q == MAP_FAILED) - { - munmap (p, st.st_size); - p = MAP_FAILED; - } - } - if (p != MAP_FAILED) - { - int ret = memcmp (p, q, st.st_size); - - munmap (p, st.st_size); - munmap (q, st.st_size); - if (ret != 0) - { - error (0, 0, "%s: prelinked file was modified", filename); - goto failure; - } - } - else - { - if (lseek (fdorig, 0, SEEK_SET) != 0 - || lseek (fd, 0, SEEK_SET) != 0) - { - error (0, errno, "%s: couldn't seek to start of files", filename); - goto failure; - } - - count = st.st_size; - while (count > 0) - { - size_t len = sizeof (buffer); - - if (len > count) - len = count; - if (read (fdorig, buffer, len) != len) - { - error (0, errno, "%s: couldn't read file", filename); - goto failure; - } - if (read (fd, buffer2, len) != len) - { - error (0, errno, "%s: couldn't read temporary file", filename); - goto failure; - } - if (memcmp (buffer, buffer2, len) != 0) - { - error (0, 0, "%s: prelinked file was modified", filename); - goto failure; - } - count -= len; - } - } - - if (handle_verify (fdundone, filename)) - goto failure; - - fsync (fd); - fsync (fdorig); - fsync (fdundone); - close (fd); - close (fdorig); - close (fdundone); - return 0; - -failure_unlink: - unlink (ent->filename); -failure: - if (fd != -1) - { - fsync (fd); - close (fd); - } - if (fdorig != -1) - { - fsync (fdorig); - close (fdorig); - } - if (fdundone != -1) - { - fsync (fdundone); - close (fdundone); - } - if (dso) - close_dso (dso); - if (dso2) - close_dso (dso2); - return EXIT_FAILURE; - -not_prelinked: - if (dso) - close_dso (dso); - fd = wrap_open (filename, O_RDONLY); - if (fd < 0) - error (EXIT_FAILURE, errno, "Couldn't open %s", filename); - if (handle_verify (fd, filename)) - return EXIT_FAILURE; - fsync (fd); - close (fd); - return 0; -} diff --git a/trunk/src/wrap-file.c b/trunk/src/wrap-file.c deleted file mode 100644 index f2cf305..0000000 --- a/trunk/src/wrap-file.c +++ /dev/null @@ -1,399 +0,0 @@ -/* Copyright (C) 2003 MontaVista Software, Inc. - Written by Daniel Jacobowitz <drow@mvista.com>, 2003. - - 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, 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 <config.h> -#include <assert.h> -#include <errno.h> -#include <error.h> -#include <fcntl.h> -#include <ftw.h> -#include <glob.h> -#include <stdarg.h> -#include <stddef.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/xattr.h> -#include <time.h> -#include <unistd.h> -#include <utime.h> -#include "prelink.h" - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -#ifndef MAXSYMLINKS -#define MAXSYMLINKS 20 -#endif - -extern char *canon_filename (const char *name, int nested, struct stat64 *stp, - const char *chroot, int allow_last_link, - int allow_missing); - -const char *sysroot; - -char * -sysroot_file_name (const char *name, int allow_last_link) -{ - struct stat64 st; - char *ret; - - if (sysroot == NULL) - return (char *) name; - - ret = canon_filename (name, 0, &st, sysroot, allow_last_link, 1); - - if (ret == NULL) - /* That will have set errno. */ - return NULL; - - return ret; -} - -char * -unsysroot_file_name (const char *name) -{ - if (sysroot) - { - int sysroot_len = strlen (sysroot); - if (strncmp (name, sysroot, sysroot_len) == 0) - { - if (name[sysroot_len] == '/') - return strdup (name + sysroot_len); - else if (name[sysroot_len] == 0) - return strdup ("/"); - } - } - return (char *)name; -} - -static int -wrap_stat_body (const char *file, struct stat64 *buf, int lstat) -{ - char* file_copy; - char *tmpname; - int ret; - int len; - - tmpname = sysroot_file_name (file, lstat); - - if (tmpname == NULL) - return -1; - - file_copy = strdup (tmpname); - - if (tmpname != file) - free (tmpname); - - if (file_copy == NULL) - return -1; - - len = strlen (file_copy); - if (len && (file_copy[len - 1] == '/' || file_copy[len - 1] == '\\')) - file_copy[len - 1] = '\0'; - - ret = lstat ? lstat64 (file_copy, buf) : stat64 (file_copy, buf); - - free (file_copy); - - return ret; -} - -int -wrap_lstat64 (const char *file, struct stat64 *buf) -{ - return wrap_stat_body (file, buf, 1); -} - -int -wrap_stat64 (const char *file, struct stat64 *buf) -{ - return wrap_stat_body (file, buf, 0); -} - -int -wrap_rename (const char *old, const char *new) -{ - char *tmpold = sysroot_file_name (old, 1); - char *tmpnew; - int ret; - - if (tmpold == NULL) - return -1; - - tmpnew = sysroot_file_name (new, 1); - if (tmpnew == NULL) - return -1; - - ret = rename (tmpold, tmpnew); - - if (tmpold != old) - free (tmpold); - if (tmpnew != new) - free (tmpnew); - return ret; -} - -int -wrap_open (const char *name, int mode, ...) -{ - char *tmpname = sysroot_file_name (name, 0); - int ret; - - if (tmpname == NULL) - return -1; - - if (mode & O_CREAT) - { - va_list va; - int flags; - va_start (va, mode); - flags = va_arg (va, int); - va_end (va); - ret = open (tmpname, mode, flags); - } - else - ret = open (tmpname, mode); - - if (tmpname != name) - free (tmpname); - return ret; -} - -int -wrap_access (const char *name, int mode) -{ - char *tmpname = sysroot_file_name (name, 0); - int ret; - - if (tmpname == NULL) - return -1; - - ret = access (tmpname, mode); - - if (tmpname != name) - free (tmpname); - return ret; -} - -int -wrap_link (const char *old, const char *new) -{ - char *tmpold = sysroot_file_name (old, 1); - char *tmpnew; - int ret; - - if (tmpold == NULL) - return -1; - - tmpnew = sysroot_file_name (new, 1); - if (tmpnew == NULL) - return -1; - - ret = link (tmpold, tmpnew); - - if (tmpold != old) - free (tmpold); - if (tmpnew != new) - free (tmpnew); - return ret; -} - -/* Note that this isn't recursive safe, since nftw64 doesn't - pass an opaque object around to use. But that fits our needs - for now. */ - -static __nftw64_func_t nftw64_cur_func; - -static int -wrap_nftw64_func (const char *filename, const struct stat64 *status, - int flag, struct FTW *info) -{ - char *tmpname = unsysroot_file_name (filename); - int ret = nftw64_cur_func (tmpname, status, flag, info); - - if (tmpname != filename) - free (tmpname); - return ret; -} - -int -wrap_nftw64 (const char *dir, __nftw64_func_t func, - int descriptors, int flag) -{ - char *tmpdir = sysroot_file_name (dir, 1); - int ret; - - if (tmpdir == NULL) - return -1; - - nftw64_cur_func = func; - ret = nftw64 (tmpdir, wrap_nftw64_func, descriptors, flag); - - if (tmpdir != dir) - free (tmpdir); - return ret; -} - -int -wrap_utime (const char *file, struct utimbuf *file_times) -{ - char *tmpname = sysroot_file_name (file, 0); - int ret; - - if (tmpname == NULL) - return -1; - - ret = utime (tmpname, file_times); - - if (tmpname != file) - free (tmpname); - return ret; -} - -int -wrap_mkstemp (char *filename) -{ - char *tmpname = sysroot_file_name (filename, 1); - int ret; - - if (tmpname == NULL) - return -1; - - ret = mkstemp (tmpname); - - if (tmpname != filename) - { - strcpy (filename, tmpname + strlen (sysroot)); - free (tmpname); - } - return ret; -} - -int -wrap_unlink (const char *filename) -{ - char *tmpname = sysroot_file_name (filename, 1); - int ret; - - if (tmpname == NULL) - return -1; - - ret = unlink (tmpname); - - if (tmpname != filename) - free (tmpname); - return ret; -} - -int -wrap_readlink (const char *path, char *buf, int len) -{ - char *tmpname = sysroot_file_name (path, 1); - int ret; - - if (tmpname == NULL) - return -1; - - ret = readlink (tmpname, buf, len); - - if (tmpname != path) - free (tmpname); - return ret; -} - -int -wrap_setxattr (const char *path, const char *name, const void *value, - size_t size, int flags) -{ - char *tmpname = sysroot_file_name (path, 0); - int ret; - - if (tmpname == NULL) - return -1; - - ret = setxattr (tmpname, name, value, size, flags); - - if (tmpname != path) - free (tmpname); - return ret; -} - -ssize_t -wrap_getxattr (const char *path, const char *name, void *value, - size_t size) -{ - char *tmpname = sysroot_file_name (path, 0); - ssize_t ret; - - if (tmpname == NULL) - return -1; - - ret = getxattr (tmpname, name, value, size); - - if (tmpname != path) - free (tmpname); - return ret; -} - -ssize_t -wrap_listxattr (const char *path, char *list, size_t size) -{ - char *tmpname = sysroot_file_name (path, 0); - ssize_t ret; - - if (tmpname == NULL) - return -1; - - ret = listxattr (tmpname, list, size); - - if (tmpname != path) - free (tmpname); - return ret; -} - -int -wrap_glob (const char *pattern, int flags, - int (*errfunc) (const char *epath, int eerrno), - glob_t *pglob) -{ - char *tmp; - int ret; - - if (!sysroot) - return glob (pattern, flags, errfunc, pglob); - - asprintf (&tmp, "%s%s", sysroot, pattern); - - ret = glob(tmp, flags, errfunc, pglob); - if (!ret) - { - size_t n; - - for (n = 0; n < pglob->gl_pathc; ++n) - { - char *usname = unsysroot_file_name(pglob->gl_pathv[n]); - if (usname != pglob->gl_pathv[n]) - free(pglob->gl_pathv[n]); - pglob->gl_pathv[n] = usname; - } - } - - free(tmp); - return ret; -} diff --git a/trunk/testsuite/Makefile.am b/trunk/testsuite/Makefile.am deleted file mode 100644 index 65d035d..0000000 --- a/trunk/testsuite/Makefile.am +++ /dev/null @@ -1,57 +0,0 @@ -## Process this file with automake to create Makefile.in - -AUTOMAKE_OPTIONS = 1.4 gnu - -DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -Wall -AM_CFLAGS = -Wall - -TESTS = movelibs.sh \ - reloc1.sh reloc2.sh reloc3.sh reloc4.sh reloc5.sh reloc6.sh \ - reloc7.sh reloc8.sh reloc9.sh reloc10.sh reloc11.sh \ - shuffle1.sh shuffle2.sh shuffle3.sh shuffle4.sh shuffle5.sh \ - shuffle6.sh shuffle7.sh shuffle8.sh shuffle9.sh undo1.sh \ - layout1.sh layout2.sh unprel1.sh \ - tls1.sh tls2.sh tls3.sh tls4.sh tls5.sh tls6.sh tls7.sh \ - cxx1.sh cxx2.sh cxx3.sh quick1.sh quick2.sh quick3.sh \ - cycle1.sh cycle2.sh \ - deps1.sh deps2.sh \ - ifunc1.sh ifunc2.sh ifunc3.sh \ - undosyslibs.sh preload1.sh -TESTS_ENVIRONMENT = \ - PRELINK="../src/prelink -c ./prelink.conf -C ./prelink.cache --ld-library-path=. --dynamic-linker=`echo ./ld*.so.*[0-9]` --rtld=../src/rtld/prelink-rtld" \ - CC="$(CC) $(LINKOPTS)" CCLINK="$(CC) -Wl,--dynamic-linker=`echo ./ld*.so.*[0-9]`" \ - CXX="$(CXX) $(LINKOPTS)" CXXLINK="$(CXX) -Wl,--dynamic-linker=`echo ./ld*.so.*[0-9]`" - -extra_DIST = $(TESTS) functions.sh - -CLEANFILES = *.so *.so.* *.nop syslib.list syslnk.list prelink.cache prelink.conf \ - $(TESTS:%.sh=%) $(TESTS:%.sh=%.log) $(TESTS:%.sh=%.lds) \ - *.orig *.new core* *.\#prelink\#* tlstest *.first *.second - -clean-am: clean-dirs - -clean-dirs: - rm -rf *.tree - -.NOTPARALLEL: - -check-cycle: - @optlist=.; \ - if [ "`uname -m | sed s/i.86/i.86/`" = i.86 ]; then \ - optlist="--no-exec-shield --exec-shield"; \ - fi; \ - for opts2 in $$optlist; do \ - for opts in -v -vm -vR -vmR; do \ - PRELINK_OPTS="$$opts"; \ - [ $$opts2 != . ] && PRELINK_OPTS="$$opts $$opts2"; \ - echo "Checking with $$PRELINK_OPTS"; \ - PRELINK_OPTS="$$PRELINK_OPTS" $(MAKE) $(AM_MAKEFLAGS) check || exit; \ - $(MAKE) $(AM_MAKEFLAGS) clean || exit; \ - done; \ - done; \ - echo "Checking with -Wl,-z,nocombreloc"; \ - LINKOPTS=-Wl,-z,nocombreloc $(MAKE) $(AM_MAKEFLAGS) check || exit; \ - $(MAKE) $(AM_MAKEFLAGS) clean || exit - -check-harder: - @CHECK_ME_HARDER=1 $(MAKE) $(AM_MAKEFLAGS) check || exit diff --git a/trunk/testsuite/cxx1.C b/trunk/testsuite/cxx1.C deleted file mode 100644 index 9c11a6d..0000000 --- a/trunk/testsuite/cxx1.C +++ /dev/null @@ -1,26 +0,0 @@ -#include "cxx1.h" -extern "C" void abort (void); - -void -check (A *x, B *y) -{ - C d; - if (x->b () != 21) - abort (); - if (y->B::a () != 22) - abort (); - if (d.a () != 23) - abort (); - if (d.C::b () != 24) - abort (); -} - -int -main () -{ - A x; - if (x.a () != 20) - abort (); - do_check (check, &x); - return 0; -} diff --git a/trunk/testsuite/cxx1.h b/trunk/testsuite/cxx1.h deleted file mode 100644 index d6efe9b..0000000 --- a/trunk/testsuite/cxx1.h +++ /dev/null @@ -1,19 +0,0 @@ -struct A - { - virtual int a (); - virtual int b (); - int c; - }; -struct B - { - virtual int a (); - int b; - }; -struct C - { - virtual int a (); - virtual int b (); - int c; - }; - -void do_check (void (*check) (A *x, B *y), A *x); diff --git a/trunk/testsuite/cxx1.sh b/trunk/testsuite/cxx1.sh deleted file mode 100755 index b208746..0000000 --- a/trunk/testsuite/cxx1.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f cxx1 cxx1lib*.so cxx1.log -rm -f prelink.cache -$RUN_HOST $CXX -shared -O2 -fpic -o cxx1lib1.so $srcdir/cxx1lib1.C -$RUN_HOST $CXX -shared -O2 -fpic -o cxx1lib2.so $srcdir/cxx1lib2.C cxx1lib1.so -BINS="cxx1" -LIBS="cxx1lib1.so cxx1lib2.so" -$RUN_HOST $CXXLINK -o cxx1 $srcdir/cxx1.C -Wl,--rpath-link,. cxx1lib2.so cxx1lib1.so -savelibs -echo $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx1 > cxx1.log -$RUN_HOST $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx1 >> cxx1.log 2>&1 || exit 1 -grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx1.log | grep -q -v 'C++ conflict' && exit 2 -case "`$RUN uname -m`" in - arm*) ;; # EABI says that vtables/typeinfo aren't vague linkage if there is a key method - *) [ $( grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx1.log | grep 'Removing C++ conflict' | wc -l ) -ge 5 ] || exit 3;; -esac -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./cxx1 || exit 4 -fi -$RUN_HOST $READELF -a ./cxx1 >> cxx1.log 2>&1 || exit 5 -# So that it is not prelinked again -chmod -x ./cxx1 -comparelibs >> cxx1.log 2>&1 || exit 6 diff --git a/trunk/testsuite/cxx1lib1.C b/trunk/testsuite/cxx1lib1.C deleted file mode 100644 index 1eb192a..0000000 --- a/trunk/testsuite/cxx1lib1.C +++ /dev/null @@ -1,34 +0,0 @@ -#include "cxx1.h" - -int A::a () -{ - return 10; -} - -int A::b () -{ - return 11; -} - -int B::a () -{ - return 12; -} - -int C::a () -{ - return 13; -} - -int C::b () -{ - return 14; -} - -void -do_check (void (*check) (A *x, B *y), A *x) -{ - B y; - - check (x, &y); -} diff --git a/trunk/testsuite/cxx1lib2.C b/trunk/testsuite/cxx1lib2.C deleted file mode 100644 index 77055da..0000000 --- a/trunk/testsuite/cxx1lib2.C +++ /dev/null @@ -1,28 +0,0 @@ -#include "cxx1.h" - -int A::a () -{ - return 20; -} - -int A::b () -{ - return 21; -} - -int B::a () -{ - return 22; -} - -int C::a () -{ - return 23; -} - -int C::b () -{ - return 24; -} - -C c; diff --git a/trunk/testsuite/cxx2.C b/trunk/testsuite/cxx2.C deleted file mode 100644 index 8b6e0bf..0000000 --- a/trunk/testsuite/cxx2.C +++ /dev/null @@ -1,51 +0,0 @@ -#include "cxx1.h" -extern "C" void abort (void); - -int A::a () -{ - return 30; -} - -int A::b () -{ - return 31; -} - -int B::a () -{ - return 32; -} - -int C::a () -{ - return 33; -} - -int C::b () -{ - return 34; -} - -void -check (A *x, B *y) -{ - C d; - if (x->b () != 31) - abort (); - if (y->B::a () != 32) - abort (); - if (d.a () != 33) - abort (); - if (d.C::b () != 34) - abort (); -} - -int -main () -{ - A x; - if (x.a () != 30) - abort (); - do_check (check, &x); - return 0; -} diff --git a/trunk/testsuite/cxx2.sh b/trunk/testsuite/cxx2.sh deleted file mode 100755 index 651e595..0000000 --- a/trunk/testsuite/cxx2.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f cxx2 cxx2lib*.so cxx2.log -rm -f prelink.cache -$RUN_HOST $CXX -shared -O2 -fpic -o cxx2lib1.so $srcdir/cxx1lib1.C -$RUN_HOST $CXX -shared -O2 -fpic -o cxx2lib2.so $srcdir/cxx1lib2.C cxx2lib1.so -BINS="cxx2" -LIBS="cxx2lib1.so cxx2lib2.so" -$RUN_HOST $CXXLINK -o cxx2 $srcdir/cxx2.C -Wl,--rpath-link,. cxx2lib2.so cxx2lib1.so -savelibs -echo $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx2 > cxx2.log -$RUN_HOST $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx2 >> cxx2.log 2>&1 || exit 1 -grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx2.log | grep -q -v 'C++ conflict' && exit 2 -case "`$RUN uname -m`" in - arm*) ;; # EABI says that vtables/typeinfo aren't vague linkage if there is a key method - *) [ $( grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx2.log | grep 'Removing C++ conflict' | wc -l ) -ge 9 ] || exit 3;; -esac -$RUN LD_LIBRARY_PATH=. ./cxx2 || exit 4 -$RUN_HOST $READELF -a ./cxx2 >> cxx2.log 2>&1 || exit 5 -# So that it is not prelinked again -chmod -x ./cxx2 -comparelibs >> cxx2.log 2>&1 || exit 6 diff --git a/trunk/testsuite/cxx3.C b/trunk/testsuite/cxx3.C deleted file mode 100644 index 0a4ad7b..0000000 --- a/trunk/testsuite/cxx3.C +++ /dev/null @@ -1,26 +0,0 @@ -#include "cxx3.h" -extern "C" void abort (void); - -void -check (A *x, B *y) -{ - C d; - if (x->b () != 2) - abort (); - if (y->B::a () != 3) - abort (); - if (d.a () != 4) - abort (); - if (d.C::b () != 5) - abort (); -} - -int -main () -{ - A x; - if (x.a () != 1) - abort (); - do_check (check, &x); - return 0; -} diff --git a/trunk/testsuite/cxx3.h b/trunk/testsuite/cxx3.h deleted file mode 100644 index ad2de7e..0000000 --- a/trunk/testsuite/cxx3.h +++ /dev/null @@ -1,22 +0,0 @@ -struct A - { - virtual int a () { return 1; } - virtual int b () { return 2; } - virtual ~A () {} - int c; - }; -struct B - { - virtual int a () { return 3; } - virtual ~B () {} - int b; - }; -struct C - { - virtual int a () { return 4; } - virtual int b () { return 5; } - virtual ~C () {} - int c; - }; - -void do_check (void (*check) (A *x, B *y), A *x); diff --git a/trunk/testsuite/cxx3.sh b/trunk/testsuite/cxx3.sh deleted file mode 100755 index 0908978..0000000 --- a/trunk/testsuite/cxx3.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f cxx3 cxx3lib*.so cxx3.log -rm -f prelink.cache -$RUN_HOST $CXX -shared -O2 -fpic -o cxx3lib1.so $srcdir/cxx3lib1.C -$RUN_HOST $CXX -shared -O2 -fpic -o cxx3lib2.so $srcdir/cxx3lib2.C cxx3lib1.so -BINS="cxx3" -LIBS="cxx3lib1.so cxx3lib2.so" -$RUN_HOST $CXXLINK -o cxx3 $srcdir/cxx3.C -Wl,--rpath-link,. cxx3lib2.so cxx3lib1.so -savelibs -echo $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx3 > cxx3.log -$RUN_HOST $PRELINK -vvvv ${PRELINK_OPTS--vm} ./cxx3 >> cxx3.log 2>&1 || exit 1 -grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx3.log | grep -q -v 'C++ conflict' && exit 2 -[ $( grep ^`echo $PRELINK | sed 's/ .*$/: /'` cxx3.log | grep 'Removing C++ conflict' | wc -l ) -ge 29 ] || exit 3 -$RUN LD_LIBRARY_PATH=. ./cxx3 || exit 4 -$RUN_HOST $READELF -a ./cxx3 >> cxx3.log 2>&1 || exit 5 -# So that it is not prelinked again -chmod -x ./cxx3 -comparelibs >> cxx3.log 2>&1 || exit 6 diff --git a/trunk/testsuite/cxx3lib1.C b/trunk/testsuite/cxx3lib1.C deleted file mode 100644 index f870bf0..0000000 --- a/trunk/testsuite/cxx3lib1.C +++ /dev/null @@ -1,13 +0,0 @@ -#include "cxx3.h" - -A a1; -B b1; -C c1; - -void -do_check (void (*check) (A *x, B *y), A *x) -{ - B y; - - check (x, &y); -} diff --git a/trunk/testsuite/cxx3lib2.C b/trunk/testsuite/cxx3lib2.C deleted file mode 100644 index 75f2b12..0000000 --- a/trunk/testsuite/cxx3lib2.C +++ /dev/null @@ -1,5 +0,0 @@ -#include "cxx3.h" - -A a2; -B b2; -C c; diff --git a/trunk/testsuite/cycle1.sh b/trunk/testsuite/cycle1.sh deleted file mode 100755 index f8c32b6..0000000 --- a/trunk/testsuite/cycle1.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f cycle1 cycle1lib*.so cycle1.log -rm -f prelink.cache -# Test whether prelink doesn't segfault or loop endlessly on -# bogus library dependency chains -echo 'int foo;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle1lib1.so -xc - -echo 'int bar;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle1lib2.so -xc - -xnone cycle1lib1.so -echo 'int foo;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle1lib1.so -xc - -xnone cycle1lib2.so -BINS="cycle1" -LIBS="cycle1lib1.so cycle1lib2.so" -echo 'int main (void) { return 0; } ' \ - | $RUN_HOST $CCLINK -o cycle1 -xc - -xnone -Wl,--rpath-link,. cycle1lib2.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./cycle1 > cycle1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./cycle1 >> cycle1.log 2>&1 || exit 1 -grep -v 'has a dependency cycle' cycle1.log \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 2 -grep -q "^`echo $PRELINK | sed 's/ .*$/: .*has a dependency cycle/'`" \ - cycle1.log || exit 3 -if [ "x$CROSS" = "x" ] ; then - $RUN LD_LIBRARY_PATH=. ./cycle1 || exit 4 -fi -# So that it is not prelinked again -chmod -x ./cycle1 diff --git a/trunk/testsuite/cycle2.sh b/trunk/testsuite/cycle2.sh deleted file mode 100755 index 9616464..0000000 --- a/trunk/testsuite/cycle2.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f cycle2 cycle2lib*.so cycle2.log -rm -f prelink.cache -# Test whether prelink doesn't segfault or loop endlessly on -# bogus library dependency chains -echo 'int i1;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib1.so -xc - -echo 'int i2;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib2.so -xc - -xnone cycle2lib1.so -echo 'int i3;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib3.so -xc - -xnone cycle2lib2.so -echo 'int i4;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib4.so -xc - -xnone cycle2lib3.so -echo 'int i5;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib5.so -xc - -xnone cycle2lib4.so -echo 'int i1;' | $RUN_HOST $CC -shared -O2 -fpic -o cycle2lib1.so -xc - -xnone cycle2lib5.so -BINS="cycle2" -LIBS="cycle2lib1.so cycle2lib2.so cycle2lib3.so cycle2lib4.so cycle2lib5.so" -echo 'int main (void) { return 0; } ' \ - | $RUN_HOST $CCLINK -o cycle2 -xc - -xnone -Wl,--rpath-link,. cycle2lib5.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./cycle2 > cycle2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./cycle2 >> cycle2.log 2>&1 || exit 1 -grep -v 'has a dependency cycle' cycle2.log \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 2 -grep -q "^`echo $PRELINK | sed 's/ .*$/: .*has a dependency cycle/'`" \ - cycle2.log || exit 3 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./cycle2 || exit 4 -fi -# So that it is not prelinked again -chmod -x ./cycle2 diff --git a/trunk/testsuite/deps1.c b/trunk/testsuite/deps1.c deleted file mode 100644 index 331546c..0000000 --- a/trunk/testsuite/deps1.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -static struct A local = { 77, &local, &bar + 4 }; - -int main() -{ - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 1 || f2 () != 2) - abort (); - local.c -= 4; - if (local.a != 77 || local.b != &local || local.c != &bar) - abort (); - if (f8 () != 17) - abort (); - exit (0); -} diff --git a/trunk/testsuite/deps1.h b/trunk/testsuite/deps1.h deleted file mode 100644 index d5868f7..0000000 --- a/trunk/testsuite/deps1.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "reloc1.h" - -extern int f8 (void); -extern int f9 (void); diff --git a/trunk/testsuite/deps1.sh b/trunk/testsuite/deps1.sh deleted file mode 100755 index a5bdcac..0000000 --- a/trunk/testsuite/deps1.sh +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), deps1.tree/etc/\1,g' \ - -e 's,path=\.,path=deps1.tree/lib:deps1.tree/usr/lib:deps1.tree/opt/lib,' \ - -e 's,linker=\./,linker=deps1.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=deps1.tree/lib/,'` -rm -rf deps1.tree -rm -f deps1.log -mkdir -p deps1.tree/{lib,etc,usr/lib,opt/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o deps1.tree/usr/lib/lib1.so $srcdir/deps1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o deps1.tree/opt/lib/lib1.so $srcdir/deps1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o deps1.tree/usr/lib/lib2.so $srcdir/deps1lib2.c \ - -L deps1.tree/opt/lib -Wl,-rpath,deps1.tree/opt/lib -l1 -echo '' | $RUN_HOST $CC -shared -O2 -fpic -o deps1.tree/usr/lib/lib3.so -xc - -xnone \ - -L deps1.tree/usr/lib -L deps1.tree/opt/lib -Wl,-rpath,deps1.tree/usr/lib \ - -l1 -l2 -for lib in `cat syslib.list`; do - cp -p $lib.orig deps1.tree/lib/$lib - cp -p $lib.orig deps1.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib deps1.tree/lib -done -$RUN_HOST $CCLINK -o deps1.tree/usr/bin/bin1 $srcdir/deps1.c \ - -Wl,-rpath,deps1.tree/usr/lib -L deps1.tree/usr/lib -l3 -lc -l1 -l2 -cat > deps1.tree/etc/prelink.conf <<EOF -deps1.tree/usr/bin -deps1.tree/lib -deps1.tree/usr/lib -deps1.tree/opt/lib -EOF -LIBS="deps1.tree/usr/lib/lib1.so deps1.tree/usr/lib/lib2.so" -LIBS="$LIBS deps1.tree/usr/lib/lib3.so deps1.tree/opt/lib/lib1.so" -LIBS="$LIBS `sed 's|^|deps1.tree/lib/|' syslib.list`" -BINS="deps1.tree/usr/bin/bin1" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -echo $PRELINK ${PRELINK_OPTS--v} -avvvvv > deps1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--v} -avvvvv > deps1.tree/etc/log1 2>&1 || exit 1 -cat deps1.tree/etc/log1 >> deps1.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=deps1.tree/lib deps1.tree/usr/bin/bin1 || exit 2 -fi -$RUN_HOST $READELF -d deps1.tree/{usr,opt}/lib/lib1.so 2>&1 | grep CHECKSUM >> deps1.log || exit 3 -$RUN_HOST $READELF -A deps1.tree/usr/lib/lib1.so >> deps1.log 2>&1 || exit 4 -$RUN_HOST $READELF -A deps1.tree/opt/lib/lib1.so >> deps1.log 2>&1 || exit 5 -$RUN_HOST $READELF -A deps1.tree/usr/lib/lib2.so >> deps1.log 2>&1 || exit 6 -$RUN_HOST $READELF -A deps1.tree/usr/lib/lib3.so >> deps1.log 2>&1 || exit 7 -$RUN_HOST $READELF -A deps1.tree/usr/bin/bin1 >> deps1.log 2>&1 || exit 8 -LIBS="deps1.tree/usr/lib/lib1.so deps1.tree/usr/lib/lib2.so" -LIBS="$LIBS deps1.tree/opt/lib/lib1.so" -$RUN_HOST $READELF -S deps1.tree/usr/lib/lib3.so | grep -q .gnu.prelink_undo \ - && LIBS="$LIBS deps1.tree/usr/lib/lib3.so" -$RUN_HOST $READELF -S deps1.tree/usr/bin/bin1 | grep -q .gnu.prelink_undo \ - || BINS= -comparelibs >> deps1.log 2>&1 || exit 8 -exit 0 diff --git a/trunk/testsuite/deps1lib1.c b/trunk/testsuite/deps1lib1.c deleted file mode 100644 index d4ab28b..0000000 --- a/trunk/testsuite/deps1lib1.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "deps1.h" - -int bar = 26; -int baz = 28; - -struct A foo = { 1, &foo, &bar }; - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return f1 () + 1; -} - -int f9 (void) -{ - return 18; -} diff --git a/trunk/testsuite/deps1lib2.c b/trunk/testsuite/deps1lib2.c deleted file mode 100644 index f73b456..0000000 --- a/trunk/testsuite/deps1lib2.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "reloc1.h" - -int f1 (void) -{ - return 11; -} - -int f8 (void) -{ - return f9 () - 1; -} diff --git a/trunk/testsuite/deps2.sh b/trunk/testsuite/deps2.sh deleted file mode 100755 index cdd6f59..0000000 --- a/trunk/testsuite/deps2.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), deps2.tree/etc/\1,g' \ - -e 's,path=\.,path=deps2.tree/lib:deps2.tree/usr/lib:deps2.tree/opt/lib,' \ - -e 's,linker=\./,linker=deps2.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=deps2.tree/lib/,'` -rm -rf deps2.tree -rm -f deps2.log -mkdir -p deps2.tree/{lib,etc,usr/lib,opt/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o deps2.tree/usr/lib/lib1.so $srcdir/deps1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o deps2.tree/opt/lib/lib1.so $srcdir/deps2lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o deps2.tree/usr/lib/lib2.so $srcdir/deps1lib2.c \ - -L deps2.tree/opt/lib -Wl,-rpath,deps2.tree/opt/lib -l1 -echo '' | $RUN_HOST $CC -shared -O2 -fpic -o deps2.tree/usr/lib/lib3.so -xc - -xnone \ - -L deps2.tree/usr/lib -L deps2.tree/opt/lib -Wl,-rpath,deps2.tree/usr/lib \ - -l1 -l2 -for lib in `cat syslib.list`; do - cp -p $lib.orig deps2.tree/lib/$lib - cp -p $lib.orig deps2.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib deps2.tree/lib -done -$RUN_HOST $CCLINK -o deps2.tree/usr/bin/bin1 $srcdir/deps1.c \ - -Wl,-rpath,deps2.tree/usr/lib -L deps2.tree/usr/lib -l3 -lc -l1 -l2 -cat > deps2.tree/etc/prelink.conf <<EOF -deps2.tree/usr/bin -deps2.tree/lib -deps2.tree/usr/lib -deps2.tree/opt/lib -EOF -LIBS="deps2.tree/usr/lib/lib1.so deps2.tree/usr/lib/lib2.so" -LIBS="$LIBS deps2.tree/usr/lib/lib3.so deps2.tree/opt/lib/lib1.so" -LIBS="$LIBS `sed 's|^|deps2.tree/lib/|' syslib.list`" -BINS="deps2.tree/usr/bin/bin1" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -echo $PRELINK ${PRELINK_OPTS--v} -avvvvv > deps2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--v} -avvvvv > deps2.tree/etc/log1 2>&1 || exit 1 -cat deps2.tree/etc/log1 >> deps2.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=deps2.tree/lib deps2.tree/usr/bin/bin1 || exit 2 -fi -$RUN_HOST $READELF -d deps2.tree/{usr,opt}/lib/lib1.so 2>&1 | grep CHECKSUM >> deps2.log || exit 3 -$RUN_HOST $READELF -A deps2.tree/usr/lib/lib1.so >> deps2.log 2>&1 || exit 4 -$RUN_HOST $READELF -A deps2.tree/opt/lib/lib1.so >> deps2.log 2>&1 || exit 5 -$RUN_HOST $READELF -A deps2.tree/usr/lib/lib2.so >> deps2.log 2>&1 || exit 6 -$RUN_HOST $READELF -A deps2.tree/usr/lib/lib3.so >> deps2.log 2>&1 || exit 7 -$RUN_HOST $READELF -A deps2.tree/usr/bin/bin1 >> deps2.log 2>&1 || exit 8 -LIBS="deps2.tree/usr/lib/lib1.so deps2.tree/usr/lib/lib2.so" -LIBS="$LIBS deps2.tree/opt/lib/lib1.so" -BINS= -comparelibs >> deps2.log 2>&1 || exit 9 -exit 0 diff --git a/trunk/testsuite/deps2lib1.c b/trunk/testsuite/deps2lib1.c deleted file mode 100644 index 9d4b2de..0000000 --- a/trunk/testsuite/deps2lib1.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "deps1.h" - -int bar = 26; -int baz = 28; - -struct A foo = { 1, &foo, &bar }; - -int f0 (void) -{ - return f1 () + f2 () + f9 () + bar + baz; -} - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return f1 () + 1; -} - -int f9 (void) -{ - return 18; -} diff --git a/trunk/testsuite/functions.sh b/trunk/testsuite/functions.sh deleted file mode 100755 index 07a3827..0000000 --- a/trunk/testsuite/functions.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -CC="${CC:-gcc} ${LINKOPTS}" -CCLINK=${CCLINK:-${CC} -Wl,--dynamic-linker=`echo ./ld*.so.*[0-9]`} -CXX="${CXX:-g++} ${LINKOPTS}" -CXXLINK=${CXXLINK:-${CXX} -Wl,--dynamic-linker=`echo ./ld*.so.*[0-9]`} -PRELINK=${PRELINK:-../src/prelink -c ./prelink.conf -C ./prelink.cache --ld-library-path=. --dynamic-linker=`echo ./ld*.so.*[0-9]` --rtld=../src/rtld/prelink-rtld} -LDD=${LDD:-../src/rtld/prelink-rtld} -STRIP=${STRIP:-strip} -HOST_CC=${HOST_CC:-$CC} -READELF=${READELF:-readelf} -RUN=${RUN:-env} -RUN_HOST=${RUN_HOST:-env} -srcdir=${srcdir:-`dirname $0`} -savelibs() { - for i in $LIBS $BINS; do cp -p $i $i.orig; done -} -comparelibs() { - for i in $LIBS $BINS; do - cp -p $i $i.new - echo $PRELINK -u $i.new - $RUN_HOST $PRELINK -u $i.new || exit - cmp -s $i.orig $i.new || exit - rm -f $i.new - echo $PRELINK -y $i \> $i.new - $RUN_HOST $PRELINK -y $i > $i.new || exit - cmp -s $i.orig $i.new || exit - rm -f $i.new - done -} diff --git a/trunk/testsuite/ifunc.h b/trunk/testsuite/ifunc.h deleted file mode 100644 index 8507f19..0000000 --- a/trunk/testsuite/ifunc.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef PICKNO -# define PICKNO 1 -#endif -#if PICKNO == 2 -# define PICK(fn1, fn2) #fn2 -#else -# define PICK(fn1, fn2) #fn1 -#endif -#ifdef __x86_64__ -# define IFUNC_ASM(fn) "\tleaq " fn "(%rip), %rax\n\tretq\n" -#elif defined __i386__ -# ifdef __PIC__ -# define IFUNC_ASM(fn) "\tcall 1f\n1:\tpopl %ecx\n" \ - "\taddl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ecx\n" \ - "\tleal " fn "@GOTOFF(%ecx), %eax\n\tret\n" -# else -# define IFUNC_ASM(fn) "\tmovl $" fn ", %eax\n\tret\n" -# endif -#elif defined __powerpc__ -# define IFUNC_ASM(fn) "\tmflr 12\n\tbcl 20,31,1f\n" \ - "\t1:mflr 3\n\tmtlr 12\n\taddis 3,3, " fn \ - "-1b@ha\n\taddi 3,3," fn "-1b@l\n\tblr\n" -# if defined __powerpc64__ -# define IFUNC_DECL(name, hidden, fn1, fn2) \ -asm (".text\n" \ - "\t.globl " #name "\n" \ - "\t" hidden " " #name "\n" \ - "\t.type " #name ", @gnu_indirect_function\n" \ - "\t.section .opd,\"aw\"\n" \ - "\t.align 3\n" \ - #name ":\n" \ - "\t.quad .L." #name ",.TOC.@tocbase,0\n" \ - "\t.previous\n" \ - ".L." #name ":\n" \ - IFUNC_ASM (PICK (fn1, fn2)) \ - "\t.size " #name ", .-.L" #name "\n") -# endif -#elif defined __s390x__ -# define IFUNC_ASM(fn) "\tlarl %r2," fn "\n" \ - "\tbr %r14\n" -#elif defined __s390__ -# define IFUNC_ASM(fn) "\t" \ - "\tst %r12,48(%r15)\n" \ - "\tbasr %r5,0\n" \ - "1:\tl %r12,3f-1b(%r5)\n" \ - "\tl %r1,2f-1b(%r5)\n" \ - "\tla %r12,0(%r12,%r5)\n" \ - "\tla %r2,0(%r1,%r12)\n" \ - "\tl %r12,48(%r15)\n" \ - "\tbr %r14\n" \ - "\t.align 4\n" \ - "2:\t.long " fn "@GOTOFF\n" \ - "3:\t.long _GLOBAL_OFFSET_TABLE_-1b\n" -elif defined __arm__ -# ifdef __thumb__ -# define PIPE_OFFSET "4" -# else -# define PIPE_OFFSET "8" -# endif -# define IFUNC_ASM(fn) \ - "\tldr r0, .L" fn "\n" \ - "1:\tadd r0, pc, r0\n" \ - "\tmov pc, lr\n" \ - ".L" fn ": .long " fn " - 1b - " PIPE_OFFSET "\n" -# define IFUNC_DECL(name, hidden, fn1, fn2) \ -asm (".text\n" \ - "\t.globl " #name "\n" \ - "\t" hidden " " #name "\n" \ - "\t.type " #name ", %gnu_indirect_function\n" \ - #name ":\n" \ - IFUNC_ASM (PICK (fn1, fn2)) \ - "\t.size " #name ", .-" #name "\n") -#else -# error Architecture not supported -#endif -#ifndef IFUNC_DECL -#define IFUNC_DECL(name, hidden, fn1, fn2) \ -asm (".text\n" \ - "\t.globl " #name "\n" \ - "\t" hidden " " #name "\n" \ - "\t.type " #name ", @gnu_indirect_function\n" \ - #name ":\n" \ - IFUNC_ASM (PICK (fn1, fn2)) \ - "\t.size " #name ", .-" #name "\n") -#endif -#define IFUNC(name, hidden, fn1, fn2) \ -extern __typeof (fn1) fn1 __attribute__((used)); \ -extern __typeof (fn2) fn2 __attribute__((used)); \ -extern __typeof (fn1) name; \ -IFUNC_DECL (name, hidden, fn1, fn2) -#define IFUNC_LOCAL(name, fn1, fn2) IFUNC(name, ".hidden", fn1, fn2) -#define IFUNC_GLOBAL(name, fn1, fn2) IFUNC(name, ".globl", fn1, fn2) diff --git a/trunk/testsuite/ifunc1.c b/trunk/testsuite/ifunc1.c deleted file mode 100644 index f5500df..0000000 --- a/trunk/testsuite/ifunc1.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "ifunc.h" - -static int bint11 (void) { return 1; } -static int bint12 (void) { return 2; } - -IFUNC_LOCAL (bint1, bint11, bint12); - -static int lib2t21 (void) { return 1; } -static int lib2t22 (void) { return 2; } - -IFUNC_GLOBAL (lib2t2, lib2t21, lib2t22); - -extern int lib1t2 (void); -extern int lib1test (void); -extern int lib2test (void); - -extern void abort (void); - -int -main (void) -{ - lib1test (); - lib2test (); - if (bint1 () != PICKNO) - abort (); - if (lib1t2 () != PICKNO) - abort (); - return 0; -} diff --git a/trunk/testsuite/ifunc1.sh b/trunk/testsuite/ifunc1.sh deleted file mode 100755 index 39a008a..0000000 --- a/trunk/testsuite/ifunc1.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -$RUN_HOST $CCLINK -o ifunctest $srcdir/ifunctest.c -Wl,--rpath-link,. > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./ifunctest || { rm -f ifunctest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f ifunctest ifunc1 ifunc1lib*.so ifunc1.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o ifunc1lib1.so $srcdir/ifunc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o ifunc1lib2.so $srcdir/ifunc1lib2.c ifunc1lib1.so -BINS="ifunc1" -LIBS="ifunc1lib1.so ifunc1lib2.so" -$RUN_HOST $CCLINK -o ifunc1 $srcdir/ifunc1.c -Wl,--rpath-link,. ifunc1lib2.so -lc ifunc1lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./ifunc1 >> ifunc1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./ifunc1 >> ifunc1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` ifunc1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./ifunc1 || exit 3 -fi -$RUN_HOST $READELF -a ./ifunc1 >> ifunc1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./ifunc1 -comparelibs >> ifunc1.log 2>&1 || exit 5 diff --git a/trunk/testsuite/ifunc1lib1.c b/trunk/testsuite/ifunc1lib1.c deleted file mode 100644 index 27a3f03..0000000 --- a/trunk/testsuite/ifunc1lib1.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "ifunc.h" - -static int lib1t11 (void) { return 11; } -static int lib1t12 (void) { return 12; } - -IFUNC_LOCAL (lib1t1, lib1t11, lib1t12); - -static int lib1t21 (void) { return 1; } -static int lib1t22 (void) { return 2; } - -IFUNC_GLOBAL (lib1t2, lib1t21, lib1t22); - -static int lib1t31 (void) { return 3; } -static int lib1t32 (void) { return 4; } - -IFUNC_GLOBAL (lib1t3, lib1t31, lib1t32); - -extern void abort (void); - -int (*lib1p1) (void) = lib1t1; - -int -lib1test (void) -{ - if (lib1t1 () != PICKNO + 10) - abort (); - if (lib1t3 () != PICKNO) - abort (); - if (lib1p1 () != PICKNO + 10) - abort (); - return 0; -} diff --git a/trunk/testsuite/ifunc1lib2.c b/trunk/testsuite/ifunc1lib2.c deleted file mode 100644 index ca12e3d..0000000 --- a/trunk/testsuite/ifunc1lib2.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "ifunc.h" - -static int lib2t11 (void) { return 1; } -static int lib2t12 (void) { return 2; } - -IFUNC_LOCAL (lib2t1, lib2t11, lib2t12); - -static int lib2t21 (void) { return 3; } -static int lib2t22 (void) { return 4; } - -IFUNC_GLOBAL (lib2t2, lib2t21, lib2t22); - -static int lib2t31 (void) { return 1; } -static int lib2t32 (void) { return 2; } - -IFUNC_GLOBAL (lib2t3, lib2t31, lib2t32); - -static int lib1t31 (void) { return 1; } -static int lib1t32 (void) { return 2; } - -IFUNC_GLOBAL (lib1t3, lib1t31, lib1t32); - -int (*lib2p1) (void) = lib2t2; - -extern void abort (void); - -int -lib2test (void) -{ - if (lib2t1 () != PICKNO) - abort (); - if (lib2t2 () != PICKNO) - abort (); - if (lib2t3 () != PICKNO) - abort (); - if (lib2p1 () != PICKNO) - abort (); - return 0; -} diff --git a/trunk/testsuite/ifunc2.sh b/trunk/testsuite/ifunc2.sh deleted file mode 100755 index 16f427c..0000000 --- a/trunk/testsuite/ifunc2.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -$RUN_HOST $CCLINK -o ifunctest $srcdir/ifunctest.c -Wl,--rpath-link,. > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./ifunctest || { rm -f ifunctest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f ifunctest ifunc2 ifunc2lib*.so ifunc2.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o ifunc2lib1.so $srcdir/ifunc1lib1.c -DPICKNO=2 -$RUN_HOST $CC -shared -O2 -fpic -o ifunc2lib2.so $srcdir/ifunc1lib2.c ifunc2lib1.so -DPICKNO=2 -BINS="ifunc2" -LIBS="ifunc2lib1.so ifunc2lib2.so" -$RUN_HOST $CCLINK -o ifunc2 $srcdir/ifunc1.c -Wl,--rpath-link,. ifunc2lib2.so -lc ifunc2lib1.so -DPICKNO=2 -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./ifunc2 >> ifunc2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./ifunc2 >> ifunc2.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` ifunc2.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./ifunc2 || exit 3 -fi -$RUN_HOST $READELF -a ./ifunc2 >> ifunc2.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./ifunc2 -comparelibs >> ifunc2.log 2>&1 || exit 5 diff --git a/trunk/testsuite/ifunc3.c b/trunk/testsuite/ifunc3.c deleted file mode 100644 index 1f243d8..0000000 --- a/trunk/testsuite/ifunc3.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "ifunc.h" - -static int bint11 (void) { return 1; } -static int bint12 (void) { return 2; } - -IFUNC_LOCAL (bint1, bint11, bint12); - -static int lib2t21 (void) { return 1; } -static int lib2t22 (void) { return 2; } - -IFUNC_GLOBAL (lib2t2, lib2t21, lib2t22); - -extern int lib1t2 (void); -extern int lib1test (void); -extern int lib2test (void); -extern int (*lib1p1) (void); - -extern void abort (void); - -int -main (void) -{ - lib1test (); - lib2test (); - if (bint1 () != PICKNO) - abort (); - if (lib1t2 () != PICKNO) - abort (); - if (lib1p1 () != PICKNO + 10) - abort (); - return 0; -} diff --git a/trunk/testsuite/ifunc3.sh b/trunk/testsuite/ifunc3.sh deleted file mode 100755 index 2f8c0aa..0000000 --- a/trunk/testsuite/ifunc3.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -$RUN_HOST $CCLINK -o ifunctest $srcdir/ifunctest.c -Wl,--rpath-link,. > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./ifunctest || { rm -f ifunctest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f ifunctest ifunc3 ifunc3lib*.so ifunc3.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o ifunc3lib1.so $srcdir/ifunc3lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o ifunc3lib2.so $srcdir/ifunc1lib2.c ifunc3lib1.so -BINS="ifunc3" -LIBS="ifunc3lib1.so ifunc3lib2.so" -$RUN_HOST $CCLINK -o ifunc3 $srcdir/ifunc3.c -Wl,--rpath-link,. ifunc3lib2.so -lc ifunc3lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./ifunc3 >> ifunc3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./ifunc3 >> ifunc3.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` ifunc3.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./ifunc3 || exit 3 -fi -$RUN_HOST $READELF -a ./ifunc3 >> ifunc3.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./ifunc3 -comparelibs >> ifunc3.log 2>&1 || exit 5 diff --git a/trunk/testsuite/ifunc3lib1.c b/trunk/testsuite/ifunc3lib1.c deleted file mode 100644 index 133b389..0000000 --- a/trunk/testsuite/ifunc3lib1.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "ifunc.h" - -static int lib1t11 (void) { return 11; } -static int lib1t12 (void) { return 12; } - -IFUNC_LOCAL (lib1t1, lib1t11, lib1t12); - -static int lib1t21 (void) { return 1; } -static int lib1t22 (void) { return 2; } - -IFUNC_GLOBAL (lib1t2, lib1t21, lib1t22); - -static int lib1t31 (void) { return 3; } -static int lib1t32 (void) { return 4; } - -IFUNC_GLOBAL (lib1t3, lib1t31, lib1t32); - -char lib1b1[4]; -char *lib1b2 = &lib1b1[2]; - -extern void abort (void); - -int (*lib1p1) (void) = lib1t1; - -int -lib1test (void) -{ - if (lib1t1 () != PICKNO + 10) - abort (); - if (lib1t3 () != PICKNO) - abort (); - if (lib1p1 () != PICKNO + 10) - abort (); - if (lib1b2 != lib1b1 + 2) - abort (); - return 0; -} diff --git a/trunk/testsuite/ifunctest.c b/trunk/testsuite/ifunctest.c deleted file mode 100644 index 9ce7b1a..0000000 --- a/trunk/testsuite/ifunctest.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "ifunc.h" - -static int foo1 (void) { return 1; } -static int foo2 (void) { return 2; } - -IFUNC_LOCAL (foo, foo1, foo2); - -extern void abort (void); - -int -main (void) -{ - if (foo () != PICKNO) - abort (); - return 0; -} diff --git a/trunk/testsuite/layout.C b/trunk/testsuite/layout.C deleted file mode 100644 index 5047a34..0000000 --- a/trunk/testsuite/layout.C +++ /dev/null @@ -1,3 +0,0 @@ -int main() -{ -} diff --git a/trunk/testsuite/layout1.sh b/trunk/testsuite/layout1.sh deleted file mode 100755 index 0af196e..0000000 --- a/trunk/testsuite/layout1.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f prelink.cache -rm -f layout1 layoutlib*.so layout1.log -i=10 -BINS="layout1" -LIBS= -while [ $i -lt 74 ]; do - $RUN_HOST $CXX -shared -fpic -o layout1lib$i.so $srcdir/layoutlib.C - LIBS="$LIBS layout1lib$i.so" - i=`expr $i + 1` -done -$RUN_HOST $CXXLINK -o layout1 $srcdir/layout.C layout1lib*.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vR} ./layout1 > layout1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vR} ./layout1 >> layout1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` layout1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./layout1 || exit 3 -fi -$RUN_HOST $READELF -a ./layout1 >> layout1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./layout1 -comparelibs >> layout1.log 2>&1 || exit 5 diff --git a/trunk/testsuite/layout2.sh b/trunk/testsuite/layout2.sh deleted file mode 100755 index 03f8b28..0000000 --- a/trunk/testsuite/layout2.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f layout2 layout2lib*.so layout2.log -i=1 -BINS="layout2" -LIBS= -while [ $i -lt 6 ]; do - $RUN_HOST $CXX -shared -fpic -o layout2lib$i.so $srcdir/layoutlib.C - LIBS="$LIBS layout2lib$i.so" - i=`expr $i + 1` -done -$RUN_HOST $CXXLINK -o layout2 $srcdir/layout.C layout2lib*.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vR} ./layout2 > layout2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vR} ./layout2 >> layout2.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` layout2.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./layout2 || exit 3 -fi -$RUN_HOST $READELF -a ./layout2 >> layout2.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./layout2 -comparelibs >> layout2.log 2>&1 || exit 5 diff --git a/trunk/testsuite/layoutlib.C b/trunk/testsuite/layoutlib.C deleted file mode 100644 index 8162515..0000000 --- a/trunk/testsuite/layoutlib.C +++ /dev/null @@ -1,10 +0,0 @@ -struct A - { - virtual int a(); - int b; - }; - -int A::a() -{ - return 10; -} diff --git a/trunk/testsuite/movelibs.sh b/trunk/testsuite/movelibs.sh deleted file mode 100755 index c640f45..0000000 --- a/trunk/testsuite/movelibs.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# This script copies needed C and C++ libraries into the test directory -echo 'int main() { }' > movelibs.C -$RUN_HOST $CXX -o movelibs movelibs.C -> syslib.list -> syslnk.list -for i in `$RUN_HOST RTLD_TRACE_PRELINKING=1 RTLD_WARN= $LDD ./movelibs \ - | awk '$1 !~ /^\.\/movelibs/ { print $3 } '`; do - k=`basename $i` - if [ -L $i ]; then - j=`ls -l $i | sed 's/^.* -> //'` - if echo $j | grep / >/dev/null 2>&1; then - cp -p $i . - echo $k >> syslib.list - else - cp -dp $i . - cp -p `dirname $i`/$j . - echo $j >> syslib.list - echo $k >> syslnk.list - fi - else - cp -p $i . - echo $k >> syslib.list - fi -done -rm -f movelibs.C movelibs -pwd > prelink.conf -for i in `cat syslib.list`; do - if $RUN_HOST $READELF -WS $i 2>/dev/null | grep -q .gnu.prelink_undo; then - $RUN_HOST $PRELINK -u $i > /dev/null 2>&1 || exit 1 - fi - cp -p $i $i.orig -done -exit 77 diff --git a/trunk/testsuite/preload1.c b/trunk/testsuite/preload1.c deleted file mode 100644 index d6ee489..0000000 --- a/trunk/testsuite/preload1.c +++ /dev/null @@ -1,12 +0,0 @@ -#include <stdlib.h> -#include "preload1.h" - -int main() -{ - int rc = foo(2, 2); - - if (rc != 0) - abort (); - - exit (rc); -} diff --git a/trunk/testsuite/preload1.h b/trunk/testsuite/preload1.h deleted file mode 100644 index 139bee0..0000000 --- a/trunk/testsuite/preload1.h +++ /dev/null @@ -1,2 +0,0 @@ -int foo(int x, int y); - diff --git a/trunk/testsuite/preload1.sh b/trunk/testsuite/preload1.sh deleted file mode 100755 index a44ea5c..0000000 --- a/trunk/testsuite/preload1.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -check_one() { - cnt=0 - log=$1 - echo -n . >> preload1.log - text="$2" - shift 2 - while [ $# -gt 0 ]; do - grep -q "^$text .*$1" $log || exit 40 - cnt=$((++cnt)) - shift - done - [ `grep "^$text " $log | wc -l` = $cnt ] || exit 41 -} -check_log() { - log=$1 - echo -n "Checking $1 " >> preload1.log - check_one $log 'Checking executable' $CHECKE - check_one $log 'Checking shared library' $CHECKL - check_one $log 'Assuming prelinked' $ASSUME - check_one $log 'Prelinking' $PREL - echo >> preload1.log -} - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), preload1.tree/etc/\1,g' \ - -e 's,path=\.,path=preload1.tree/lib:preload1.tree/usr/lib,' \ - -e 's,linker=\./,linker=preload1.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=preload1.tree/lib/,'` -rm -rf preload1.tree -rm -f preload1.log -mkdir -p preload1.tree/{lib,etc,usr/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o preload1.tree/usr/lib/lib1.so $srcdir/preload1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o preload1.tree/usr/lib/lib2.so $srcdir/preload1lib2.c -for lib in `cat syslib.list`; do - cp -p $lib.orig preload1.tree/lib/$lib - cp -p $lib.orig preload1.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib preload1.tree/lib -done -$RUN_HOST $CCLINK -o preload1.tree/usr/bin/bin1 $srcdir/preload1.c \ - -Wl,--rpath-link,preload1.tree/usr/lib -L preload1.tree/usr/lib -lc -l1 -cat > preload1.tree/etc/prelink.conf <<EOF -preload1.tree/usr/bin -preload1.tree/lib -preload1.tree/usr/lib -EOF -LIBS="preload1.tree/usr/lib/lib1.so preload1.tree/usr/lib/lib2.so" -LIBS="$LIBS `sed 's|^|preload1.tree/lib/|' syslib.list`" -BINS="preload1.tree/usr/bin/bin1" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -# Make sure prelinked binaries and libraries will have different ctimes -# than mtimes -sleep 3s -echo $PRELINK ${PRELINK_OPTS--vm} -avvvvv > preload1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -avvvvv > preload1.tree/etc/log1 2>&1 || exit 1 -cat preload1.tree/etc/log1 >> preload1.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> preload1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > preload1.tree/etc/log2 2>&1 || exit 2 -cat preload1.tree/etc/log2 >> preload1.log -if [ "x$CROSS" = "x" ]; then - # We -expect- a failure here! - $RUN LD_LIBRARY_PATH=preload1.tree/lib:preload1.tree/usr/lib preload1.tree/usr/bin/bin1 && exit 3 -fi -for f in $LIBS $BINS ; do - cp $f $f.orig -done -echo $PRELINK ${PRELINK_OPTS--vm} --ld-preload=preload1.tree/usr/lib/lib2.so -avvvvv >> preload1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} --ld-preload=preload1.tree/usr/lib/lib2.so -avvvvv > preload1.tree/etc/log4 2>&1 || exit 4 -cat preload1.tree/etc/log4 >> preload1.log -# System libs and lib1.so MIGHT change, but lib2.so and bin1 must change -for i in preload1.tree/usr/lib/lib2.so preload1.tree/usr/bin/bin1; do - cmp -s $i.orig $i && exit 5 -done -if [ "x$CROSS" = "x" ]; then - # Should run, but fail (no preload) - $RUN LD_LIBRARY_PATH=preload1.tree/lib:preload1.tree/usr/lib preload1.tree/usr/bin/bin1 && exit 6 - # Should run, and exit successfully - $RUN LD_PRELOAD=preload1.tree/usr/lib/lib2.so LD_LIBRARY_PATH=preload1.tree/lib:preload1.tree/usr/lib preload1.tree/usr/bin/bin1 || exit 7 -fi -chmod 755 $BINS -exit 0 diff --git a/trunk/testsuite/preload1lib1.c b/trunk/testsuite/preload1lib1.c deleted file mode 100644 index 0c1fa43..0000000 --- a/trunk/testsuite/preload1lib1.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "preload1.h" - -int foo(int x, int y) { - return x * y; -} diff --git a/trunk/testsuite/preload1lib2.c b/trunk/testsuite/preload1lib2.c deleted file mode 100644 index 7ab50aa..0000000 --- a/trunk/testsuite/preload1lib2.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "preload1.h" - -int foo(int x, int y) { - return 0; -} diff --git a/trunk/testsuite/quick1.c b/trunk/testsuite/quick1.c deleted file mode 100644 index dc98441..0000000 --- a/trunk/testsuite/quick1.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -static struct A local = { 77, &local, &bar + 4 }; -extern int baz; -static char *bazp0 = (char *) &baz; -static char *bazp1 = ((char *) &baz) + 1; - -int main() -{ - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - local.c -= 4; - if (local.a != 77 || local.b != &local || local.c != &bar) - abort (); - if (bazp1 - bazp0 != 1) - abort (); - exit (0); -} diff --git a/trunk/testsuite/quick1.sh b/trunk/testsuite/quick1.sh deleted file mode 100755 index 228ba4c..0000000 --- a/trunk/testsuite/quick1.sh +++ /dev/null @@ -1,212 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -check_one() { - cnt=0 - log=$1 - echo -n . >> quick1.log - text="$2" - shift 2 - while [ $# -gt 0 ]; do - grep -q "^$text .*$1" $log || exit 40 - cnt=$((++cnt)) - shift - done - [ `grep "^$text " $log | wc -l` = $cnt ] || exit 41 -} -check_log() { - log=$1 - echo -n "Checking $1 " >> quick1.log - check_one $log 'Checking executable' $CHECKE - check_one $log 'Checking shared library' $CHECKL - check_one $log 'Assuming prelinked' $ASSUME - check_one $log 'Prelinking' $PREL - echo >> quick1.log -} - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), quick1.tree/etc/\1,g' \ - -e 's,path=\.,path=quick1.tree/lib:quick1.tree/usr/lib,' \ - -e 's,linker=\./,linker=quick1.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=quick1.tree/lib/,'` -rm -rf quick1.tree -rm -f quick1.log -mkdir -p quick1.tree/{lib,etc,usr/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib2.so $srcdir/reloc1lib2.c \ - -L quick1.tree/usr/lib -l1 -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib3.so $srcdir/quick1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib2.later.so \ - $srcdir/quick1lib2.c -L quick1.tree/usr/lib -l1 -l3 -echo 'int foo;' | $RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib4.so -xc - -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib5.so $srcdir/quick1lib3.c \ - -L quick1.tree/usr/lib -Wl,--rpath-link,quick1.tree/usr/lib -l2 -$RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib6.so $srcdir/quick1lib4.c \ - -L quick1.tree/usr/lib -Wl,--rpath-link,quick1.tree/usr/lib -l5 -echo 'int baz;' | $RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib7.so -xc - \ - -L quick1.tree/usr/lib -Wl,--rpath-link,quick1.tree/usr/lib -l6 -echo 'int baz;' | $RUN_HOST $CC -shared -O2 -fpic -o quick1.tree/usr/lib/lib7.later.so \ - -xc - -L quick1.tree/usr/lib -Wl,--rpath-link,quick1.tree/usr/lib -l2 -for lib in `cat syslib.list`; do - cp -p $lib.orig quick1.tree/lib/$lib - cp -p $lib.orig quick1.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib quick1.tree/lib -done -$RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin1 $srcdir/reloc1.c \ - -Wl,--rpath-link,quick1.tree/usr/lib -L quick1.tree/usr/lib -l2 -lc -l1 -echo 'int main () { extern int foo; return foo; }' \ - | $RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin2 -xc - -xnone \ - -L quick1.tree/usr/lib -l4 -$RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin3 $srcdir/reloc1.c \ - -Wl,--rpath-link,quick1.tree/usr/lib -L quick1.tree/usr/lib -l7 -lc -l2 -l1 -$RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin4 $srcdir/quick1.c \ - -Wl,--rpath-link,quick1.tree/usr/lib -L quick1.tree/usr/lib -l2 -lc -l1 -$RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin5 $srcdir/quick1.c \ - -Wl,--rpath-link,quick1.tree/usr/lib -L quick1.tree/usr/lib -l7 -lc -l2 -l1 -echo 'int main () { return 0; }' \ - | $RUN_HOST $CCLINK -o quick1.tree/usr/bin/bin6 -xc - -xnone \ - -Wl,--rpath-link,quick1.tree/usr/lib -L quick1.tree/usr/lib -l6 -cat > quick1.tree/etc/prelink.conf <<EOF -quick1.tree/usr/bin -quick1.tree/lib -quick1.tree/usr/lib -EOF -LIBS="quick1.tree/usr/lib/lib1.so quick1.tree/usr/lib/lib2.so" -LIBS="$LIBS quick1.tree/usr/lib/lib3.so quick1.tree/usr/lib/lib4.so" -LIBS="$LIBS quick1.tree/usr/lib/lib5.so quick1.tree/usr/lib/lib6.so" -LIBS="$LIBS quick1.tree/usr/lib/lib7.so" -LIBS="$LIBS `sed 's|^|quick1.tree/lib/|' syslib.list`" -BINS="quick1.tree/usr/bin/bin1 quick1.tree/usr/bin/bin2" -BINS="$BINS quick1.tree/usr/bin/bin3 quick1.tree/usr/bin/bin4" -BINS="$BINS quick1.tree/usr/bin/bin5 quick1.tree/usr/bin/bin6" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -# Make sure prelinked binaries and libraries will have different ctimes -# than mtimes -sleep 3s -# lib2.later.so needs different timestamps than lib2.so for the tests below -touch quick1.tree/usr/lib/lib2.later.so -cp -p quick1.tree/usr/lib/lib2.later.so{,.orig} -# lib7.later.so needs different timestamps than lib7.so for the tests below -touch quick1.tree/usr/lib/lib7.later.so -cp -p quick1.tree/usr/lib/lib7.later.so{,.orig} -echo $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick1.tree/etc/log1 2>&1 || exit 1 -cat quick1.tree/etc/log1 >> quick1.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick1.tree/etc/log2 2>&1 || exit 2 -cat quick1.tree/etc/log2 >> quick1.log -stat quick1.tree/usr/lib/lib2.so >> quick1.log -echo chmod 644 quick1.tree/usr/lib/lib2.so >> quick1.log -chmod 644 quick1.tree/usr/lib/lib2.so -sleep 3s -echo chmod 755 quick1.tree/usr/lib/lib2.so >> quick1.log -chmod 755 quick1.tree/usr/lib/lib2.so -stat quick1.tree/usr/lib/lib2.so >> quick1.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick1.tree/etc/log3 2>&1 || exit 3 -cat quick1.tree/etc/log3 >> quick1.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick1.tree/etc/log4 2>&1 || exit 4 -cat quick1.tree/etc/log4 >> quick1.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin1 || exit 5 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin2 || exit 6 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin3 || exit 7 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin4 || exit 8 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin5 || exit 9 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin6 || exit 10 -fi -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin1 >> quick1.log 2>&1 || exit 11 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin3 >> quick1.log 2>&1 || exit 12 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin4 >> quick1.log 2>&1 || exit 13 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin5 >> quick1.log 2>&1 || exit 14 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin6 >> quick1.log 2>&1 || exit 15 -BINS="quick1.tree/usr/bin/bin1 quick1.tree/usr/bin/bin3" -BINS="$BINS quick1.tree/usr/bin/bin4 quick1.tree/usr/bin/bin5" -BINS="$BINS quick1.tree/usr/bin/bin6" -LIBS="quick1.tree/usr/lib/lib2.so quick1.tree/usr/lib/lib7.so" -comparelibs >> quick1.log 2>&1 || exit 16 -for l in 2 7; do - mv -f quick1.tree/usr/lib/lib$l.so{,.old} - mv -f quick1.tree/usr/lib/lib$l.so{,.old}.orig - cp -p quick1.tree/usr/lib/lib$l{.later,}.so - cp -p quick1.tree/usr/lib/lib$l{.later,}.so.orig -done -for b in 1 3 4 5 6; do - cp -p quick1.tree/usr/bin/bin$b{,.old} - chmod 644 quick1.tree/usr/bin/bin$b.old -done -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick1.tree/etc/log5 2>&1 || exit 17 -cat quick1.tree/etc/log5 >> quick1.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin1 || exit 18 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin2 || exit 19 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin3 || exit 20 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin4 || exit 21 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin5 || exit 22 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick1.tree/lib:quick1.tree/usr/lib quick1.tree/usr/bin/bin6 || exit 23 -fi -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin1 >> quick1.log 2>&1 || exit 24 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin3 >> quick1.log 2>&1 || exit 25 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin4 >> quick1.log 2>&1 || exit 26 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin5 >> quick1.log 2>&1 || exit 27 -$RUN_HOST $READELF -a quick1.tree/usr/bin/bin6 >> quick1.log 2>&1 || exit 28 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` quick1.log && exit 29 -L=quick1.tree/usr/lib/lib -L1=${L}1.so; L2=${L}2.so; L3=${L}3.so; L4=${L}4.so -L5=${L}5.so; L6=${L}6.so; L7=${L}7.so -B=quick1.tree/usr/bin/bin -B1=${B}1; B2=${B}2; B3=${B}3; B4=${B}4; B5=${B}5; B6=${B}6 -SL=`grep -f syslib.list quick1.tree/etc/log1 \ - | sed -n '/^Prelinking/s|^.*\(quick1.tree/lib/\)|\1|p'` -CHECKE="$B1 $B2 $B3 $B4 $B5 $B6"; CHECKL="$SL $L1 $L2 $L4 $L5 $L6 $L7" PREL="$CHECKE $CHECKL"; ASSUME="" -check_log quick1.tree/etc/log1 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $B2 $B3 $B4 $B5 $B6 $SL $L1 $L2 $L4 $L5 $L6 $L7" -check_log quick1.tree/etc/log2 -CHECKE="$B1 $B3 $B4 $B5 $B6"; CHECKL="$SL $L1 $L2 $L5 $L6 $L7"; PREL=""; ASSUME="$B2 $L4" -check_log quick1.tree/etc/log3 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $B2 $B3 $B4 $B5 $B6 $SL $L1 $L2 $L4 $L5 $L6 $L7" -check_log quick1.tree/etc/log4 -CHECKE="$B1 $B3 $B4 $B5 $B6"; CHECKL="$SL $L1 $L2 $L3 $L5 $L7 $L7"; PREL="$B1 $B3 $B4 $B5 $B6 $L2 $L3 $L5 $L6 $L7"; ASSUME="$B2 $L4" -check_log quick1.tree/etc/log5 -BINS="$B1 $B2 $B3 $B4 $B5 $B6" -LIBS="$SL $L1 $L2 $L3 $L4 $L5 $L6 $L7 $L2.old" -comparelibs >> quick1.log 2>&1 || exit 30 -for i in $BINS $SL $L1 $L2 $L3 $L4 $L5 $L6 $L7; do - cp -p $i $i.prelinked -done -for i in $BINS; do - chmod 644 $i.prelinked -done -echo $PRELINK -uavvvvvv >> quick1.log -$RUN_HOST $PRELINK -uavvvvvv >> quick1.log 2>&1 || exit 31 -for i in $BINS $SL $L1 $L2 $L3 $L4 $L5 $L6 $L7; do - cmp -s $i.orig $i || exit 32 - mv -f $i.prelinked $i -done -chmod 755 $BINS -exit 0 diff --git a/trunk/testsuite/quick1lib1.c b/trunk/testsuite/quick1lib1.c deleted file mode 100644 index 41767ce..0000000 --- a/trunk/testsuite/quick1lib1.c +++ /dev/null @@ -1,9 +0,0 @@ -int q1 (void) -{ - return q2 () + 1; -} - -int q2 (void) -{ - return 77; -} diff --git a/trunk/testsuite/quick1lib2.c b/trunk/testsuite/quick1lib2.c deleted file mode 100644 index b545086..0000000 --- a/trunk/testsuite/quick1lib2.c +++ /dev/null @@ -1,11 +0,0 @@ -extern int q1 (void); - -int f1 (void) -{ - return q1 () + 1; -} - -int q2 (void) -{ - return 9; -} diff --git a/trunk/testsuite/quick1lib3.c b/trunk/testsuite/quick1lib3.c deleted file mode 100644 index 06760a3..0000000 --- a/trunk/testsuite/quick1lib3.c +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef D1 -#define D1(n) int qvar##n; int *qpvar##n = &qvar##n; -#endif -#define D2(n) D1(n##0) D1(n##1) D1(n##2) D1(n##3) D1(n##4) -#define D3(n) D2(n##0) D2(n##1) D2(n##2) D2(n##3) D2(n##4) -#define D4(n) D3(n##0) D3(n##1) D3(n##2) D3(n##3) D3(n##4) -D4(0) D4(1) diff --git a/trunk/testsuite/quick1lib4.c b/trunk/testsuite/quick1lib4.c deleted file mode 100644 index 53e23d7..0000000 --- a/trunk/testsuite/quick1lib4.c +++ /dev/null @@ -1,2 +0,0 @@ -#define D1(n) int qvar##n; -#include "quick1lib3.c" diff --git a/trunk/testsuite/quick2.sh b/trunk/testsuite/quick2.sh deleted file mode 100755 index 8ffaf76..0000000 --- a/trunk/testsuite/quick2.sh +++ /dev/null @@ -1,282 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -check_one() { - cnt=0 - log=$1 - echo -n . >> quick2.log - text="$2" - shift 2 - while [ $# -gt 0 ]; do - grep -q "^$text .*$1" $log || exit 40 - cnt=$((++cnt)) - shift - done - [ `grep "^$text " $log | wc -l` = $cnt ] || exit 41 -} -check_log() { - log=$1 - echo -n "Checking $1 " >> quick2.log - check_one $log 'Checking executable' $CHECKE - check_one $log 'Checking shared library' $CHECKL - check_one $log 'Assuming prelinked' $ASSUME - check_one $log 'Prelinking' $PREL - check_one $log 'Assuming non-prelinkable' $UNPREL - echo >> quick2.log -} - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), quick2.tree/etc/\1,g' \ - -e 's,path=\.,path=quick2.tree/lib:quick2.tree/usr/lib,' \ - -e 's,linker=\./,linker=quick2.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=quick2.tree/lib/,'` -rm -rf quick2.tree -rm -f quick2.log -mkdir -p quick2.tree/{lib,etc,usr/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib2.so $srcdir/reloc1lib2.c \ - -L quick2.tree/usr/lib -l1 -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib3.so $srcdir/quick1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib2.later.so \ - $srcdir/quick1lib2.c -L quick2.tree/usr/lib -l1 -l3 -echo 'int foo;' | $RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib4.so -xc - -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib5.so $srcdir/quick1lib3.c \ - -L quick2.tree/usr/lib -Wl,--rpath-link,quick2.tree/usr/lib -l2 -$RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib6.so $srcdir/quick1lib4.c \ - -L quick2.tree/usr/lib -Wl,--rpath-link,quick2.tree/usr/lib -l5 -echo 'int baz;' | $RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib7.so -xc - \ - -L quick2.tree/usr/lib -Wl,--rpath-link,quick2.tree/usr/lib -l6 \ - -Wl,--spare-dynamic-tags=0 -echo 'int baz;' | $RUN_HOST $CC -shared -O2 -fpic -o quick2.tree/usr/lib/lib7.later.so \ - -xc - -L quick2.tree/usr/lib -Wl,--rpath-link,quick2.tree/usr/lib -l2 -for lib in `cat syslib.list`; do - cp -p $lib.orig quick2.tree/lib/$lib - cp -p $lib.orig quick2.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib quick2.tree/lib -done -$RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin1 $srcdir/reloc1.c \ - -Wl,--rpath-link,quick2.tree/usr/lib -L quick2.tree/usr/lib -l2 -lc -l1 -echo 'int main () { extern int foo; return foo; }' \ - | $RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin2 -xc - -xnone \ - -L quick2.tree/usr/lib -l4 -$RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin3 $srcdir/reloc1.c \ - -Wl,--rpath-link,quick2.tree/usr/lib -L quick2.tree/usr/lib -l7 -lc -l2 -l1 -$RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin4 $srcdir/quick1.c \ - -Wl,--rpath-link,quick2.tree/usr/lib -L quick2.tree/usr/lib -l2 -lc -l1 -$RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin5 $srcdir/quick1.c \ - -Wl,--rpath-link,quick2.tree/usr/lib -L quick2.tree/usr/lib -l7 -lc -l2 -l1 -echo 'int main () { return 0; }' \ - | $RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin6 -xc - -xnone \ - -Wl,--rpath-link,quick2.tree/usr/lib -L quick2.tree/usr/lib -l6 -echo 'int main () { return 0; }' \ - | $RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin7 -static -xc - -xnone -cat > quick2.tree/usr/bin/bin8 <<EOF -#!/bin/sh -echo This is a sample shell script -echo used to test whether even shell scripts -echo and other executable non-ELF files -echo are cached as non-prelinkable -echo in /etc/prelink.cache and thus do not -echo need to be reread every time prelink -aq -echo is run. -exit 0 -EOF -chmod 755 quick2.tree/usr/bin/bin8 -cat > quick2.tree/usr/bin/bin9.sh <<EOF -#!/bin/sh -echo This is another sample shell script, -echo this time with a .sh extension. -echo This does not need to be even cached -echo as non-prelinkable, provided -b *.sh -echo is present in prelink.conf. -exit 0 -EOF -chmod 755 quick2.tree/usr/bin/bin9.sh -cat > quick2.tree/usr/bin/bin10.py <<EOF -#! /usr/bin/env python -print "This is a sample python script." -print "This does not need to be even cached" -print "as non-prelinkable, provided -b *.py" -print "is present in prelink.conf." -EOF -chmod 755 quick2.tree/usr/bin/bin10.py -cat > quick2.tree/usr/bin/bin11.script <<EOF -#!/bin/sh -echo This is another sample shell script, -echo this time matching b*11*r[hijk]*t shell pattern. -echo This does not need to be even cached -echo as non-prelinkable, provided -b b*11*r[hijk]*t -echo is present in prelink.conf. -exit 0 -EOF -chmod 755 quick2.tree/usr/bin/bin11.script -echo 'int main () { return 0; }' \ - | $RUN_HOST $CCLINK -o quick2.tree/usr/bin/bin12 -pie -fPIE -xc - -xnone -cat > quick2.tree/etc/prelink.conf <<EOF --b *.sh --c quick2.tree/etc/prelink.conf.d/*.conf -EOF -mkdir quick2.tree/etc/prelink.conf.d -echo '-b *.py' > quick2.tree/etc/prelink.conf.d/py.conf -echo '-b b*11*r[hijk]*t' > quick2.tree/etc/prelink.conf.d/script.conf -cat > quick2.tree/etc/prelink.conf.d/rest.conf <<EOF -quick2.tree/usr/bin -quick2.tree/lib -quick2.tree/usr/lib -EOF -LIBS="quick2.tree/usr/lib/lib1.so quick2.tree/usr/lib/lib2.so" -LIBS="$LIBS quick2.tree/usr/lib/lib3.so quick2.tree/usr/lib/lib4.so" -LIBS="$LIBS quick2.tree/usr/lib/lib5.so quick2.tree/usr/lib/lib6.so" -LIBS="$LIBS quick2.tree/usr/lib/lib7.so" -LIBS="$LIBS `sed 's|^|quick2.tree/lib/|' syslib.list`" -BINS="quick2.tree/usr/bin/bin1 quick2.tree/usr/bin/bin2" -BINS="$BINS quick2.tree/usr/bin/bin3 quick2.tree/usr/bin/bin4" -BINS="$BINS quick2.tree/usr/bin/bin5 quick2.tree/usr/bin/bin6" -BINS="$BINS quick2.tree/usr/bin/bin7 quick2.tree/usr/bin/bin8" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -# Make sure prelinked binaries and libraries will have different ctimes -# than mtimes -sleep 3s -# lib2.later.so needs different timestamps than lib2.so for the tests below -touch quick2.tree/usr/lib/lib2.later.so -cp -p quick2.tree/usr/lib/lib2.later.so{,.orig} -# lib7.later.so needs different timestamps than lib7.so for the tests below -touch quick2.tree/usr/lib/lib7.later.so -cp -p quick2.tree/usr/lib/lib7.later.so{,.orig} -echo $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick2.tree/etc/log1 2>&1 || exit 1 -cat quick2.tree/etc/log1 >> quick2.log -grep -q 'lib7.so: Not enough room to add .dynamic entry' \ - quick2.tree/etc/log1 || exit 60 -grep -q 'Could not prelink .*bin3 because its dependency .*lib7.so could not be prelinked' \ - quick2.tree/etc/log1 || exit 61 -grep -q 'Could not prelink .*bin5 because its dependency .*lib7.so could not be prelinked' \ - quick2.tree/etc/log1 || exit 62 -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick2.tree/etc/log2 2>&1 || exit 2 -cat quick2.tree/etc/log2 >> quick2.log -stat quick2.tree/usr/lib/lib2.so >> quick2.log -echo chmod 644 quick2.tree/usr/lib/lib2.so >> quick2.log -chmod 644 quick2.tree/usr/lib/lib2.so -sleep 3s -echo chmod 755 quick2.tree/usr/lib/lib2.so >> quick2.log -chmod 755 quick2.tree/usr/lib/lib2.so -stat quick2.tree/usr/lib/lib2.so >> quick2.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick2.tree/etc/log3 2>&1 || exit 3 -cat quick2.tree/etc/log3 >> quick2.log -grep -q 'lib7.so: Not enough room to add .dynamic entry' \ - quick2.tree/etc/log3 || exit 63 -grep -q 'Could not prelink .*bin3 because its dependency .*lib7.so could not be prelinked' \ - quick2.tree/etc/log3 || exit 64 -grep -q 'Could not prelink .*bin5 because its dependency .*lib7.so could not be prelinked' \ - quick2.tree/etc/log3 || exit 65 -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick2.tree/etc/log4 2>&1 || exit 4 -cat quick2.tree/etc/log4 >> quick2.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin1 || exit 5 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin2 || exit 6 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin3 || exit 7 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin4 || exit 8 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin5 || exit 9 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin6 || exit 10 -fi -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin1 >> quick2.log 2>&1 || exit 11 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin3 >> quick2.log 2>&1 || exit 12 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin4 >> quick2.log 2>&1 || exit 13 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin5 >> quick2.log 2>&1 || exit 14 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin6 >> quick2.log 2>&1 || exit 15 -BINS="quick2.tree/usr/bin/bin1 quick2.tree/usr/bin/bin4" -BINS="$BINS quick2.tree/usr/bin/bin6" -LIBS="quick2.tree/usr/lib/lib2.so" -comparelibs >> quick2.log 2>&1 || exit 16 -for l in 2 7; do - mv -f quick2.tree/usr/lib/lib$l.so{,.old} - mv -f quick2.tree/usr/lib/lib$l.so{,.old}.orig - cp -p quick2.tree/usr/lib/lib$l{.later,}.so - cp -p quick2.tree/usr/lib/lib$l{.later,}.so.orig -done -for b in 1 3 4 5 6; do - cp -p quick2.tree/usr/bin/bin$b{,.old} - chmod 644 quick2.tree/usr/bin/bin$b.old -done -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick2.tree/etc/log5 2>&1 || exit 17 -cat quick2.tree/etc/log5 >> quick2.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin1 || exit 18 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin2 || exit 19 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin3 || exit 20 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin4 || exit 21 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin5 || exit 22 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick2.tree/lib:quick2.tree/usr/lib quick2.tree/usr/bin/bin6 || exit 23 -fi -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin1 >> quick2.log 2>&1 || exit 24 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin3 >> quick2.log 2>&1 || exit 25 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin4 >> quick2.log 2>&1 || exit 26 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin5 >> quick2.log 2>&1 || exit 27 -$RUN_HOST $READELF -a quick2.tree/usr/bin/bin6 >> quick2.log 2>&1 || exit 28 -# In both etc/log1 and etc/log3 there should be one -# "Not enough room" and two "Could not prelink" warnings. -[ $(grep ^`echo $PRELINK | sed 's/ .*$/: /'` quick2.log | wc -l) -eq 6 ] || exit 29 -L=quick2.tree/usr/lib/lib -L1=${L}1.so; L2=${L}2.so; L3=${L}3.so; L4=${L}4.so -L5=${L}5.so; L6=${L}6.so; L7=${L}7.so -B=quick2.tree/usr/bin/bin -B1=${B}1; B2=${B}2; B3=${B}3; B4=${B}4; B5=${B}5 -B6=${B}6; B7=${B}7; B8=${B}8; B12=${B}12 -SL=`grep -f syslib.list quick2.tree/etc/log1 \ - | sed -n '/^Prelinking/s|^.*\(quick2.tree/lib/\)|\1|p'` -CHECK_E="$B1 $B2 $B4 $B6"; CHECKE="$CHECK_E $B3 $B5 $B7" -CHECKL="$SL $L1 $L2 $L4 $L5 $L6 $L7"; PREL="$CHECK_E $CHECKL"; ASSUME=""; UNPREL="" -check_log quick2.tree/etc/log1 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $B2 $B4 $B6 $SL $L1 $L2 $L4 $L5 $L6" -UNPREL="$B3 $B5 $B7 $B8 $B12 $L7" -check_log quick2.tree/etc/log2 -CHECKE="$B1 $B3 $B4 $B5 $B6"; CHECKL="$SL $L1 $L2 $L5 $L6 $L7"; PREL="$L7"; ASSUME="$B2 $L4"; UNPREL="$B7 $B8 $B12" -check_log quick2.tree/etc/log3 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $B2 $B4 $B6 $SL $L1 $L2 $L4 $L5 $L6"; UNPREL="$B3 $B5 $B7 $B8 $B12 $L7" -check_log quick2.tree/etc/log4 -CHECKE="$B1 $B3 $B4 $B5 $B6"; CHECKL="$SL $L1 $L2 $L3 $L5 $L7 $L7"; PREL="$B1 $B3 $B4 $B5 $B6 $L2 $L3 $L5 $L6 $L7"; ASSUME="$B2 $L4"; UNPREL="$B7 $B8 $B12" -check_log quick2.tree/etc/log5 -BINS="$B1 $B2 $B3 $B4 $B5 $B6" -LIBS="$SL $L1 $L2 $L3 $L4 $L5 $L6 $L7 $L2.old" -comparelibs >> quick2.log 2>&1 || exit 30 -for i in $BINS $SL $L1 $L2 $L3 $L4 $L5 $L6 $L7; do - cp -p $i $i.prelinked -done -for i in $BINS; do - chmod 644 $i.prelinked -done -echo $PRELINK -uavvvvvv >> quick2.log -$RUN_HOST $PRELINK -uavvvvvv >> quick2.log 2>&1 || exit 31 -for i in $BINS $SL $L1 $L2 $L3 $L4 $L5 $L6 $L7; do - cmp -s $i.orig $i || exit 32 - mv -f $i.prelinked $i -done -chmod 755 $BINS -exit 0 diff --git a/trunk/testsuite/quick3.sh b/trunk/testsuite/quick3.sh deleted file mode 100755 index d302748..0000000 --- a/trunk/testsuite/quick3.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -check_one() { - cnt=0 - log=$1 - echo -n . >> quick3.log - text="$2" - shift 2 - while [ $# -gt 0 ]; do - grep -q "^$text .*$1" $log || exit 40 - cnt=$((++cnt)) - shift - done - [ `grep "^$text " $log | wc -l` = $cnt ] || exit 41 -} -check_log() { - log=$1 - echo -n "Checking $1 " >> quick3.log - check_one $log 'Checking executable' $CHECKE - check_one $log 'Checking shared library' $CHECKL - check_one $log 'Assuming prelinked' $ASSUME - check_one $log 'Prelinking' $PREL - echo >> quick3.log -} - -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), quick3.tree/etc/\1,g' \ - -e 's,path=\.,path=quick3.tree/lib:quick3.tree/usr/lib,' \ - -e 's,linker=\./,linker=quick3.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=quick3.tree/lib/,'` -rm -rf quick3.tree -rm -f quick3.log -mkdir -p quick3.tree/{lib,etc,usr/lib,usr/bin} -$RUN_HOST $CC -shared -O2 -fpic -o quick3.tree/usr/lib/lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o quick3.tree/usr/lib/lib2.so $srcdir/reloc1lib2.c \ - -L quick3.tree/usr/lib -l1 -Wl,-soname,lib2.so -for lib in `cat syslib.list`; do - cp -p $lib.orig quick3.tree/lib/$lib - cp -p $lib.orig quick3.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib quick3.tree/lib -done -$RUN_HOST $CCLINK -o quick3.tree/usr/bin/bin1 $srcdir/reloc1.c \ - -Wl,--rpath-link,quick3.tree/usr/lib -L quick3.tree/usr/lib -l2 -lc -l1 -cat > quick3.tree/etc/prelink.conf <<EOF -quick3.tree/usr/bin -quick3.tree/lib -quick3.tree/usr/lib -EOF -LIBS="quick3.tree/usr/lib/lib1.so quick3.tree/usr/lib/lib2.so" -LIBS="$LIBS `sed 's|^|quick3.tree/lib/|' syslib.list`" -BINS="quick3.tree/usr/bin/bin1" -savelibs -chmod 644 `ls $BINS | sed 's|$|.orig|'` -# Make sure prelinked binaries and libraries will have different ctimes -# than mtimes -sleep 3s -echo $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -avvvvv > quick3.tree/etc/log1 2>&1 || exit 1 -cat quick3.tree/etc/log1 >> quick3.log -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick3.tree/etc/log2 2>&1 || exit 2 -cat quick3.tree/etc/log2 >> quick3.log -$RUN_HOST $CC -shared -O2 -fpic -o quick3.tree/usr/lib/lib2.so.0 $srcdir/reloc1lib2.c \ - -L quick3.tree/usr/lib -l1 -Wl,-soname,lib2.so -rm -f quick3.tree/usr/lib/lib2.so{,.orig} -cp -p quick3.tree/usr/lib/lib2.so.0{,.orig} -ln -sf lib2.so.0 quick3.tree/usr/lib/lib2.so -sleep 3s -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick3.tree/etc/log3 2>&1 || exit 3 -cat quick3.tree/etc/log3 >> quick3.log -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=quick3.tree/lib:quick3.tree/usr/lib quick3.tree/usr/bin/bin1 || exit 4 -fi -LIBS="quick3.tree/usr/lib/lib1.so quick3.tree/usr/lib/lib2.so.0" -echo $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv >> quick3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} -aqvvvvv > quick3.tree/etc/log4 2>&1 || exit 5 -cat quick3.tree/etc/log4 >> quick3.log -comparelibs >> quick3.log 2>&1 || exit 6 -[ -L quick3.tree/usr/lib/lib2.so ] || exit 7 -L=quick3.tree/usr/lib/lib -L1=${L}1.so; L2=${L}2.so; L3=${L}2.so.0 -B1=quick3.tree/usr/bin/bin1 -SL=`grep -f syslib.list quick3.tree/etc/log1 \ - | sed -n '/^Prelinking/s|^.*\(quick3.tree/lib/\)|\1|p'` -CHECKE="$B1"; CHECKL="$SL $L1 $L2" PREL="$CHECKE $CHECKL"; ASSUME="" -check_log quick3.tree/etc/log1 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $L1 $L2 $SL" -check_log quick3.tree/etc/log2 -CHECKE="$B1"; CHECKL="$SL $L1 $L3"; PREL="$B1 $L3"; ASSUME="" -check_log quick3.tree/etc/log3 -CHECKE=""; CHECKL=""; PREL=""; ASSUME="$B1 $L1 $L3 $SL" -check_log quick3.tree/etc/log4 -for i in $B1 $SL $L1 $L3; do - cp -p $i $i.prelinked -done -for i in $B1; do - chmod 644 $i.prelinked -done -echo $PRELINK -uavvvvvv >> quick3.log -$RUN_HOST $PRELINK -uavvvvvv >> quick3.log 2>&1 || exit 31 -for i in $B1 $SL $L1 $L3; do - cmp -s $i.orig $i || exit 32 - mv -f $i.prelinked $i -done -chmod 755 $BINS -exit 0 diff --git a/trunk/testsuite/reloc1.c b/trunk/testsuite/reloc1.c deleted file mode 100644 index e679bed..0000000 --- a/trunk/testsuite/reloc1.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -static struct A local = { 77, &local, &bar + 4 }; - -int main() -{ - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - local.c -= 4; - if (local.a != 77 || local.b != &local || local.c != &bar) - abort (); - exit (0); -} diff --git a/trunk/testsuite/reloc1.h b/trunk/testsuite/reloc1.h deleted file mode 100644 index 093dd3a..0000000 --- a/trunk/testsuite/reloc1.h +++ /dev/null @@ -1,12 +0,0 @@ -struct A - { - char a; - struct A *b; - int *c; - }; - -extern struct A foo; -extern int bar; -extern int f1 (void); -extern int f2 (void); -extern struct A *f3 (void); diff --git a/trunk/testsuite/reloc1.sh b/trunk/testsuite/reloc1.sh deleted file mode 100755 index 06c6aba..0000000 --- a/trunk/testsuite/reloc1.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc1 reloc1lib*.so reloc1.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o reloc1lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o reloc1lib2.so $srcdir/reloc1lib2.c reloc1lib1.so -BINS="reloc1" -LIBS="reloc1lib1.so reloc1lib2.so" -$RUN_HOST $CCLINK -o reloc1 $srcdir/reloc1.c -Wl,--rpath-link,. reloc1lib2.so -lc reloc1lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc1 > reloc1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc1 >> reloc1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc1 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc1 >> reloc1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc1 -comparelibs >> reloc1.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc10.c b/trunk/testsuite/reloc10.c deleted file mode 100644 index 5720d33..0000000 --- a/trunk/testsuite/reloc10.c +++ /dev/null @@ -1,19 +0,0 @@ -#include <stdlib.h> - -extern int bar, baz, *barp, *bazp, dummy; -extern int f1 (void), f2 (void), f3 (void), f4 (void); -/* Try to use COPY reloc for bar and get away without COPY - reloc for baz. Similarly for barp and bazp. */ -int *bazp2 = &baz; -int **bazp3 = &bazp; - -int main (void) -{ - if (f1 () != 11 || f2 () != 12 || bar != 36 || *bazp2 != 38) - abort (); - if (f3 () != 14 || f4 () != 16 || *barp != 36 || **bazp3 != 38) - abort (); - if (dummy != 24) - abort (); - exit (0); -} diff --git a/trunk/testsuite/reloc10.sh b/trunk/testsuite/reloc10.sh deleted file mode 100755 index 55181cc..0000000 --- a/trunk/testsuite/reloc10.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc10 reloc10lib*.so reloc10.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o reloc10lib1.so $srcdir/reloc10lib1.c -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc10lib2.so $srcdir/reloc10lib2.c reloc10lib1.so -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc10lib3.so $srcdir/reloc10lib3.c reloc10lib1.so -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc10lib4.so $srcdir/reloc10lib4.c reloc10lib1.so -$RUN_HOST $CC -shared -O2 -fpic -o reloc10lib5.so $srcdir/reloc10lib5.c -Wl,--rpath-link,. \ - reloc10lib2.so reloc10lib3.so reloc10lib4.so -BINS="reloc10" -LIBS="reloc10lib1.so reloc10lib2.so reloc10lib3.so reloc10lib4.so reloc10lib5.so" -$RUN_HOST $CCLINK -o reloc10 $srcdir/reloc10.c -Wl,--rpath-link,. reloc10lib5.so -lc reloc10lib{2,3,4}.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc10 > reloc10.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc10 >> reloc10.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc10.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc10 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc10 >> reloc10.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc10 -comparelibs >> reloc10.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc10lib1.c b/trunk/testsuite/reloc10lib1.c deleted file mode 100644 index 2ee06d2..0000000 --- a/trunk/testsuite/reloc10lib1.c +++ /dev/null @@ -1,12 +0,0 @@ -int bar = 26; -int baz = 28; - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return 2; -} diff --git a/trunk/testsuite/reloc10lib2.c b/trunk/testsuite/reloc10lib2.c deleted file mode 100644 index fc327fc..0000000 --- a/trunk/testsuite/reloc10lib2.c +++ /dev/null @@ -1,11 +0,0 @@ -extern int bar, baz, f1 (void), f2 (void); - -int f3 (void) -{ - return f1 () + 3; -} - -int f4 (void) -{ - return f2 () + 4; -} diff --git a/trunk/testsuite/reloc10lib3.c b/trunk/testsuite/reloc10lib3.c deleted file mode 100644 index 2ec80ab..0000000 --- a/trunk/testsuite/reloc10lib3.c +++ /dev/null @@ -1,3 +0,0 @@ -extern int bar, baz, f1 (void), f2 (void); - -int *barp = &bar, *bazp = &baz; diff --git a/trunk/testsuite/reloc10lib4.c b/trunk/testsuite/reloc10lib4.c deleted file mode 100644 index 4376249..0000000 --- a/trunk/testsuite/reloc10lib4.c +++ /dev/null @@ -1 +0,0 @@ -int dummy = 24; diff --git a/trunk/testsuite/reloc10lib5.c b/trunk/testsuite/reloc10lib5.c deleted file mode 100644 index 19fd925..0000000 --- a/trunk/testsuite/reloc10lib5.c +++ /dev/null @@ -1,12 +0,0 @@ -int bar = 36; -int baz = 38; - -int f1 (void) -{ - return 11; -} - -int f2 (void) -{ - return 12; -} diff --git a/trunk/testsuite/reloc11.c b/trunk/testsuite/reloc11.c deleted file mode 100644 index 923aff4..0000000 --- a/trunk/testsuite/reloc11.c +++ /dev/null @@ -1,16 +0,0 @@ -#include <stdlib.h> - -extern int dummy; -extern int var, var2, varp1 (), var2m1 (), bar (); -int *pvar = &var, *pvar2 = &var2; - -int main (void) -{ - if (dummy != 24) - abort (); - if (*pvar != 32 || *pvar2 != 16) - abort (); - if (varp1 () != 33 || var2m1 () != 6 || bar () != 40) - abort (); - exit (0); -} diff --git a/trunk/testsuite/reloc11.sh b/trunk/testsuite/reloc11.sh deleted file mode 100755 index 706fdb4..0000000 --- a/trunk/testsuite/reloc11.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc11 reloc11lib*.so reloc11.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc11lib1.so $srcdir/reloc10lib4.c -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc11lib2.so $srcdir/reloc11lib2.c -$RUN_HOST $CC -shared -O2 -nostdlib -fpic -o reloc11lib3.so $srcdir/reloc11lib3.c reloc11lib2.so -BINS="reloc11" -LIBS="reloc11lib1.so reloc11lib2.so reloc11lib3.so" -$RUN_HOST $CCLINK -o reloc11 $srcdir/reloc11.c -Wl,--rpath-link,. reloc11lib1.so reloc11lib3.so -lc reloc11lib2.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc11 > reloc11.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc11 >> reloc11.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc11.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc11 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc11 >> reloc11.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc11 -comparelibs >> reloc11.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc11lib2.c b/trunk/testsuite/reloc11lib2.c deleted file mode 100644 index 6a2191c..0000000 --- a/trunk/testsuite/reloc11lib2.c +++ /dev/null @@ -1,16 +0,0 @@ -int var = 24, var2 = 16; - -int varp1 (void) -{ - return var + 1; -} - -int var2m1 (void) -{ - return var2 - 1; -} - -int bar (void) -{ - return varp1 () + var2m1 () + 1; -} diff --git a/trunk/testsuite/reloc11lib3.c b/trunk/testsuite/reloc11lib3.c deleted file mode 100644 index 0cea7f3..0000000 --- a/trunk/testsuite/reloc11lib3.c +++ /dev/null @@ -1,7 +0,0 @@ -int var = 32; -extern int var2; - -int var2m1 (void) -{ - return var2 - 10; -} diff --git a/trunk/testsuite/reloc1lib1.c b/trunk/testsuite/reloc1lib1.c deleted file mode 100644 index 8aa0628..0000000 --- a/trunk/testsuite/reloc1lib1.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "reloc1.h" - -int bar = 26; -int baz = 28; - -struct A foo = { 1, &foo, &bar }; - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return f1 () + 1; -} diff --git a/trunk/testsuite/reloc1lib2.c b/trunk/testsuite/reloc1lib2.c deleted file mode 100644 index a338c1d..0000000 --- a/trunk/testsuite/reloc1lib2.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "reloc1.h" - -int f1 (void) -{ - return 11; -} diff --git a/trunk/testsuite/reloc2.c b/trunk/testsuite/reloc2.c deleted file mode 100644 index 6c7fed5..0000000 --- a/trunk/testsuite/reloc2.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <stdlib.h> - -extern int f2 (int add); -extern void * f3 (void); - -int main() -{ - if (f2 (1) != 27 || f2 (0) != 1) - abort (); - if (f3 () != (void *) f3) - abort (); - exit (0); -} diff --git a/trunk/testsuite/reloc2.sh b/trunk/testsuite/reloc2.sh deleted file mode 100755 index b21d535..0000000 --- a/trunk/testsuite/reloc2.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -SHFLAGS= -case "`$RUN uname -m`" in - ia64|ppc*|x86_64|mips*|arm*) SHFLAGS=-fpic;; # Does not support non-pic shared libs - s390*) if file reloc1lib1.so | grep -q 64-bit; then SHFLAGS=-fpic; fi;; -esac -# Disable this test under SELinux if textrel -if test -z "$SHFLAGS" -a -x /usr/sbin/getenforce; then - case "`/usr/sbin/getenforce 2>/dev/null`" in - Permissive|Disabled) ;; - *) exit 77 ;; - esac -fi -rm -f reloc2 reloc2lib*.so reloc2.log -$RUN_HOST $CC -shared $SHFLAGS -O2 -o reloc2lib1.so $srcdir/reloc2lib1.c -$RUN_HOST $CC -shared $SHFLAGS -O2 -o reloc2lib2.so $srcdir/reloc2lib2.c \ - reloc2lib1.so 2>/dev/null -BINS="reloc2" -LIBS="reloc2lib1.so reloc2lib2.so" -$RUN_HOST $CCLINK -o reloc2 $srcdir/reloc2.c -Wl,--rpath-link,. reloc2lib2.so -$RUN_HOST $STRIP -R .comment $BINS $LIBS -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc2 > reloc2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc2 >> reloc2.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc2.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc2 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc2 >> reloc2.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc2 -comparelibs >> reloc2.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc2lib1.c b/trunk/testsuite/reloc2lib1.c deleted file mode 100644 index 3551704..0000000 --- a/trunk/testsuite/reloc2lib1.c +++ /dev/null @@ -1,4 +0,0 @@ -int f1 (int dummy) -{ - return 1; -} diff --git a/trunk/testsuite/reloc2lib2.c b/trunk/testsuite/reloc2lib2.c deleted file mode 100644 index 094daad..0000000 --- a/trunk/testsuite/reloc2lib2.c +++ /dev/null @@ -1,15 +0,0 @@ -extern int f1 (int dummy); - -int f2 (int add) -{ - if (add) - return f1 (0) + 26; - return f1 (0); -} - -/* Make sure conflict in f3 is not against read-only segment. */ -asm (".section trampoline, \"awx\"; .previous"); -void * __attribute__((section ("trampoline"))) f3 (void) -{ - return (void *) f3; -} diff --git a/trunk/testsuite/reloc3.c b/trunk/testsuite/reloc3.c deleted file mode 100644 index 2f455d7..0000000 --- a/trunk/testsuite/reloc3.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> -#include <stdio.h> - -int i; -int j __attribute__((aligned (32))); -int k[2048]; -int l = 26; - -void f5 (FILE *f) -{ - fprintf (stdout, "OK"); -} - -int main() -{ - struct A *x; - foo.c -= 2; - if (foo.a != 1 || foo.b != &foo || foo.c[0] != 28 || foo.c[1] != 29 - || foo.c[2] != 30) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - x = f3 (); - if (x->a != 2 || x->b != x || x->c != foo.c + 1) - abort (); - f5 (stdout); - exit (0); -} diff --git a/trunk/testsuite/reloc3.sh b/trunk/testsuite/reloc3.sh deleted file mode 100755 index 96c2c05..0000000 --- a/trunk/testsuite/reloc3.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc3 reloc3lib*.so reloc3.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o reloc3lib1.so $srcdir/reloc3lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o reloc3lib2.so $srcdir/reloc1lib2.c reloc3lib1.so -BINS="reloc3" -LIBS="reloc3lib1.so reloc3lib2.so" -$RUN_HOST $CCLINK -o reloc3 $srcdir/reloc3.c -Wl,--rpath-link,. reloc3lib2.so -lc reloc3lib1.so -$RUN_HOST $STRIP -g $BINS $LIBS -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc3 > reloc3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc3 >> reloc3.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc3.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc3 >> reloc3.log || exit 3 -fi -$RUN_HOST $READELF -a ./reloc3 >> reloc3.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc3 -comparelibs >> reloc3.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc3lib1.c b/trunk/testsuite/reloc3lib1.c deleted file mode 100644 index fd649c6..0000000 --- a/trunk/testsuite/reloc3lib1.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "reloc1.h" - -int baz[3] = { 28, 29, 30 }; - -struct A foo = { 1, &foo, &baz[2] }; -static struct A xfoo = { 2, &xfoo, &baz[1] }; - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return f1 () + 1; -} - -struct A *f3 (void) -{ - return &xfoo; -} diff --git a/trunk/testsuite/reloc4.c b/trunk/testsuite/reloc4.c deleted file mode 100644 index cb3b17a..0000000 --- a/trunk/testsuite/reloc4.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <stdio.h> - -int main (void) -{ - int i; - - printf ("#include <stdlib.h>\nextern int"); - for (i = 0; i < 255; ++i) - printf (" bar%02x (int),", i); - printf (" barff (int);\nint main (void)\n{\n int x = 0;\n"); - for (i = 0; i < 256; ++i) - printf (" x = bar%02x (x);\n", i); - printf (" if (x != 0x7fff8000) abort ();\n exit (0);\n}\n"); -} diff --git a/trunk/testsuite/reloc4.sh b/trunk/testsuite/reloc4.sh deleted file mode 100755 index 0201205..0000000 --- a/trunk/testsuite/reloc4.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# This test takes a lot of time, so skip it normally -[ -z "$CHECK_ME_HARDER" ] && exit 77 -rm -f reloc4 reloc4lib*.so reloc4.log -rm -f prelink.cache -$HOST_CC -O2 -o reloc4lib1.tmp $srcdir/reloc4lib1.c -$HOST_CC -O2 -o reloc4lib2.tmp $srcdir/reloc4lib2.c -$HOST_CC -O2 -o reloc4lib3.tmp $srcdir/reloc4lib3.c -$HOST_CC -O2 -o reloc4.tmp $srcdir/reloc4.c -./reloc4lib1.tmp > reloc4lib1.tmp.c -./reloc4lib2.tmp > reloc4lib2.tmp.c -./reloc4lib3.tmp > reloc4lib3.tmp.c -./reloc4.tmp > reloc4.tmp.c -case "`$RUN uname -m`" in - mips*) extra=-mxgot ;; - *) extra= ;; -esac -$RUN_HOST $CC -shared -fpic $extra -o reloc4lib1.so reloc4lib1.tmp.c -$RUN_HOST $CC -shared -fpic $extra -o reloc4lib2.so reloc4lib2.tmp.c reloc4lib1.so -$RUN_HOST $CC -shared -fpic $extra -o reloc4lib3.so reloc4lib3.tmp.c reloc4lib2.so -BINS="reloc4" -LIBS="reloc4lib1.so reloc4lib2.so reloc4lib3.so" -$RUN_HOST $CCLINK $extra -o reloc4 reloc4.tmp.c -Wl,--rpath-link,. reloc4lib3.so -lc reloc4lib2.so -savelibs -rm -f reloc4*.tmp reloc4*.tmp.c -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc4 > reloc4.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc4 >> reloc4.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc4.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc4 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc4 >> reloc4.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc4 -comparelibs >> reloc4.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc4lib1.c b/trunk/testsuite/reloc4lib1.c deleted file mode 100644 index f1297d8..0000000 --- a/trunk/testsuite/reloc4lib1.c +++ /dev/null @@ -1,9 +0,0 @@ -#include <stdio.h> - -int main (void) -{ - int i; - - for (i = 0; i < 65536; ++i) - printf ("int foo%04x (void) { return %d; }\n", i, (i & 31) == 0 ? 0 : i); -} diff --git a/trunk/testsuite/reloc4lib2.c b/trunk/testsuite/reloc4lib2.c deleted file mode 100644 index 07aa721..0000000 --- a/trunk/testsuite/reloc4lib2.c +++ /dev/null @@ -1,17 +0,0 @@ -#include <stdio.h> - -int main (void) -{ - int i, j; - - for (i = 0; i < 256; ++i) - { - printf ("extern int "); - for (j = 0; j < 255; ++j) - printf ("foo%02x%02x (void), ", i, j); - printf ("foo%02xff (void);\nint bar%02x (int x) { return x", i, i); - for (j = 0; j < 256; ++j) - printf (" + foo%02x%02x ()", i, j); - printf ("; }\n"); - } -} diff --git a/trunk/testsuite/reloc4lib3.c b/trunk/testsuite/reloc4lib3.c deleted file mode 100644 index 1f30817..0000000 --- a/trunk/testsuite/reloc4lib3.c +++ /dev/null @@ -1,9 +0,0 @@ -#include <stdio.h> - -int main (void) -{ - int i; - - for (i = 0; i < 65536; i += 32) - printf ("int foo%04x (void) { return %d; }\n", i, i); -} diff --git a/trunk/testsuite/reloc5.c b/trunk/testsuite/reloc5.c deleted file mode 100644 index 123ad5d..0000000 --- a/trunk/testsuite/reloc5.c +++ /dev/null @@ -1,21 +0,0 @@ -#include <stdio.h> - -int main (void) -{ - int i; - - printf ("#include <stdlib.h>\nextern char testzero[16384];\nextern int"); - for (i = 0; i < 255; ++i) - printf (" bar%02x (int),", i); - printf (" barff (int);\nint main (void)\n{\n int x = 0;\n"); - for (i = 0; i < 256; ++i) - printf (" x = bar%02x (x);\n", i); - printf (" if (x != 0x7fff8000) abort ();\n"); - printf (" for (x = 0; x < 16384; ++x)\n"); - printf (" if (testzero[x]) abort ();\n"); - printf (" exit (0);\n}\n\n"); - printf ("asm (\".section nonalloced,\\\"aw\\\",%%nobits\\n\\t\"\n"); - printf (" \".globl testzero\\n\\t\"\n"); - printf (" \"testzero: .skip 16384\\n\\t\"\n"); - printf (" \".previous\");\n"); -} diff --git a/trunk/testsuite/reloc5.sh b/trunk/testsuite/reloc5.sh deleted file mode 100755 index 0fbf2a8..0000000 --- a/trunk/testsuite/reloc5.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# This test takes a lot of time, so skip it normally -[ -z "$CHECK_ME_HARDER" ] && exit 77 -rm -f reloc5 reloc5.log -rm -f prelink.cache -$HOST_CC -O2 -o reloc5.tmp $srcdir/reloc5.c -./reloc5.tmp > reloc5.tmp.c -BINS="reloc5" -$RUN_HOST $CCLINK -o reloc5 reloc5.tmp.c -Wl,--rpath-link,. reloc4lib3.so -lc reloc4lib2.so -savelibs -rm -f reloc5*.tmp reloc5*.tmp.c -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc5 > reloc5.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc5 >> reloc5.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc5.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc5 || exit 3 -fi -$RUN_HOST $READELF -a ./reloc5 >> reloc5.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc5 -comparelibs >> reloc5.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc6.sh b/trunk/testsuite/reloc6.sh deleted file mode 100755 index a660233..0000000 --- a/trunk/testsuite/reloc6.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc6 reloc6lib*.so reloc6.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o reloc6lib1.so $srcdir/reloc3lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o reloc6lib2.so $srcdir/reloc1lib2.c reloc6lib1.so -$RUN_HOST $CCLINK -o reloc6 $srcdir/reloc3.c -Wl,--rpath-link,. reloc6lib2.so -lc reloc6lib1.so -$RUN_HOST $CCLINK -o reloc6.nop $srcdir/reloc3.c -Wl,--rpath-link,. reloc6lib2.so -lc reloc6lib1.so -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc6 > reloc6.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc6 >> reloc6.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc6.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc6 >> reloc6.log || exit 3 -fi -$RUN_HOST $READELF -a ./reloc6 >> reloc6.log 2>&1 || exit 4 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc6.nop >> reloc6.log || exit 5 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. LD_BIND_NOW=1 ./reloc6.nop >> reloc6.log || exit 6 -fi -mv -f reloc6lib2.so reloc6lib2.so.p -$RUN_HOST $CC -shared -O2 -fpic -o reloc6lib2.so $srcdir/reloc1lib2.c reloc6lib1.so -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc6 >> reloc6.log || exit 7 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc6.nop >> reloc6.log || exit 8 -fi -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. LD_BIND_NOW=1 ./reloc6.nop >> reloc6.log || exit 9 -fi -mv -f reloc6lib2.so reloc6lib2.so.nop -mv -f reloc6lib2.so.p reloc6lib2.so -# So that it is not prelinked again -chmod -x ./reloc6 ./reloc6.nop diff --git a/trunk/testsuite/reloc7.c b/trunk/testsuite/reloc7.c deleted file mode 100644 index c1f6dc8..0000000 --- a/trunk/testsuite/reloc7.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> -#include <stdio.h> - -int i; -int j __attribute__((aligned (32))); -int k[2048]; -int l = 26; -int m[3] = { 28, 29, 30 }; -extern int baz[3]; - -struct A n __attribute__((section("nsec"))) = { 1, &n, &m[2] }; -static struct A o __attribute__((section("osec"))) = { 2, &o, &baz[1] }; - -void f5 (FILE *f) -{ - fprintf (stdout, "OK"); -} - -int main() -{ - struct A *x; - foo.c -= 2; - if (foo.a != 1 || foo.b != &foo || foo.c[0] != 28 || foo.c[1] != 29 - || foo.c[2] != 30) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - x = f3 (); - if (x->a != 2 || x->b != x || x->c != foo.c + 1) - abort (); - if (n.a != 1 || n.b != &n || n.c != m + 2) - abort (); - if (o.a != 2 || o.b != &o || o.c != baz + 1) - abort (); - f5 (stdout); - exit (0); -} diff --git a/trunk/testsuite/reloc7.sh b/trunk/testsuite/reloc7.sh deleted file mode 100755 index a3dcaf6..0000000 --- a/trunk/testsuite/reloc7.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f reloc7 reloc7lib*.so reloc7.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc7lib1.so $srcdir/reloc3lib1.c -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc7lib2.so $srcdir/reloc1lib2.c reloc7lib1.so -BINS="reloc7" -LIBS="reloc7lib1.so reloc7lib2.so" -$RUN_HOST $CCLINK -o reloc7 -Wl,-z,nocombreloc $srcdir/reloc7.c -Wl,--rpath-link,. reloc7lib2.so -lc reloc7lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc7 > reloc7.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc7 >> reloc7.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc7.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc7 >> reloc7.log || exit 3 -fi -$RUN_HOST $READELF -a ./reloc7 >> reloc7.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc7 -comparelibs >> reloc7.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc8.sh b/trunk/testsuite/reloc8.sh deleted file mode 100755 index 46382af..0000000 --- a/trunk/testsuite/reloc8.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Disable this test under SELinux -if [ "x$CROSS" = "x" ]; then - if test -x /usr/sbin/getenforce; then - case "`/usr/sbin/getenforce 2>/dev/null`" in - Permissive|Disabled) ;; - *) exit 77 ;; - esac - fi -fi -rm -f reloc8 reloc8lib*.so reloc8.log -rm -f prelink.cache -NOCOPYRELOC=-Wl,-z,nocopyreloc -case "`$RUN uname -m`" in - x86_64|s390*|sparc*) if file reloc1lib1.so | grep -q 64-bit; then NOCOPYRELOC=; fi;; -esac -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc8lib1.so $srcdir/reloc3lib1.c -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc8lib2.so $srcdir/reloc1lib2.c reloc8lib1.so -BINS="reloc8" -LIBS="reloc8lib1.so reloc8lib2.so" -$RUN_HOST $CCLINK -o reloc8 $NOCOPYRELOC $srcdir/reloc7.c -Wl,--rpath-link,. reloc8lib2.so -lc reloc8lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc8 > reloc8.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc8 >> reloc8.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc8.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc8 >> reloc8.log || exit 3 -fi -$RUN_HOST $READELF -a ./reloc8 >> reloc8.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc8 -comparelibs >> reloc8.log 2>&1 || exit 5 diff --git a/trunk/testsuite/reloc9.sh b/trunk/testsuite/reloc9.sh deleted file mode 100755 index 4350c30..0000000 --- a/trunk/testsuite/reloc9.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Disable this test under SELinux -if [ "x$CROSS" = "x" ]; then - if test -x /usr/sbin/getenforce; then - case "`/usr/sbin/getenforce 2>/dev/null`" in - Permissive|Disabled) ;; - *) exit 77 ;; - esac - fi -fi -rm -f reloc9 reloc9lib*.so reloc9.log -rm -f prelink.cache -NOCOPYRELOC=-Wl,-z,nocopyreloc -case "`$RUN uname -m`" in - x86_64|s390*|sparc*) if file reloc1lib1.so | grep -q 64-bit; then NOCOPYRELOC=; fi;; -esac -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc9lib1.so $srcdir/reloc3lib1.c -$RUN_HOST $CC -shared -O2 -Wl,-z,nocombreloc -fpic -o reloc9lib2.so $srcdir/reloc1lib2.c reloc9lib1.so -BINS="reloc9" -LIBS="reloc9lib1.so reloc9lib2.so" -$RUN_HOST $CCLINK -o reloc9 -Wl,-z,nocombreloc $NOCOPYRELOC $srcdir/reloc7.c -Wl,--rpath-link,. reloc9lib2.so -lc reloc9lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./reloc9 > reloc9.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./reloc9 >> reloc9.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` reloc9.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./reloc9 >> reloc9.log || exit 3 -fi -$RUN_HOST $READELF -a ./reloc9 >> reloc9.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./reloc9 -comparelibs >> reloc9.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle1.sh b/trunk/testsuite/shuffle1.sh deleted file mode 100755 index d3d3e18..0000000 --- a/trunk/testsuite/shuffle1.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f shuffle1 shuffle1lib*.so shuffle1.log shuffle1.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle1lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle1lib2.so $srcdir/reloc1lib2.c shuffle1lib1.so -BINS="shuffle1" -LIBS="shuffle1lib1.so shuffle1lib2.so" -$RUN_HOST $CCLINK -o shuffle1 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle1lib2.so -lc shuffle1lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e 's/0x08048000/0x08000000/;s/SIZEOF_HEADERS.*$/& . += 56;/' > shuffle1.lds -$RUN_HOST $CCLINK -o shuffle1 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle1lib2.so -lc shuffle1lib1.so \ - -Wl,-T,shuffle1.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle1 > shuffle1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle1 >> shuffle1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle1 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle1 >> shuffle1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle1 -comparelibs >> shuffle1.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle2.c b/trunk/testsuite/shuffle2.c deleted file mode 100644 index 8c06942..0000000 --- a/trunk/testsuite/shuffle2.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -extern char testzero[16384]; - -int main() -{ - int i; - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - for (i = 0; i < 16384; ++i) - if (testzero[i]) - abort (); - exit (0); -} - -asm (".section nonalloced,\"aw\",%nobits\n\t" - ".globl testzero\n\t" - "testzero: .skip 16384\n\t" - ".previous"); diff --git a/trunk/testsuite/shuffle2.sh b/trunk/testsuite/shuffle2.sh deleted file mode 100755 index 0ce3758..0000000 --- a/trunk/testsuite/shuffle2.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Kernels before 2.4.10 are known not to work -if [ "x$CROSS" = "x" ]; then - case "`$RUN uname -r`" in - [01].*|2.[0-3].*|2.4.[0-9]|2.4.[0-9][^0-9]*) exit 77;; - esac -fi -rm -f shuffle2 shuffle2lib*.so shuffle2.log shuffle2.lds -$RUN_HOST $CC -shared -O2 -fpic -o shuffle2lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle2lib2.so $srcdir/reloc1lib2.c shuffle2lib1.so -BINS="shuffle2" -LIBS="shuffle2lib1.so shuffle2lib2.so" -$RUN_HOST $CCLINK -o shuffle2 $srcdir/shuffle2.c -Wl,--rpath-link,. shuffle2lib2.so -lc shuffle2lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e 's/0x08048000/0x08000000/;s/SIZEOF_HEADERS.*$/& . += 56;/' > shuffle2.lds -$RUN_HOST $CCLINK -o shuffle2 $srcdir/shuffle2.c -Wl,--rpath-link,. shuffle2lib2.so -lc shuffle2lib1.so \ - -Wl,-T,shuffle2.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle2 > shuffle2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle2 >> shuffle2.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle2.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle2 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle2 >> shuffle2.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle2 -comparelibs >> shuffle2.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle3.sh b/trunk/testsuite/shuffle3.sh deleted file mode 100755 index 985de3a..0000000 --- a/trunk/testsuite/shuffle3.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Kernels before 2.4.10 are known not to work -if [ "x$CROSS" = "x" ]; then - case "`$RUN uname -r`" in - [01].*|2.[0-3].*|2.4.[0-9]|2.4.[0-9][^0-9]*) exit 77;; - esac -fi -rm -f shuffle3 shuffle3lib*.so shuffle3.log shuffle3.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle3lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle3lib2.so $srcdir/reloc1lib2.c shuffle3lib1.so -BINS="shuffle3" -LIBS="shuffle3lib1.so shuffle3lib2.so" -$RUN_HOST $CCLINK -o shuffle3 $srcdir/shuffle2.c -Wl,--rpath-link,. shuffle3lib2.so -lc shuffle3lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e 's/0x08048000/0x08000000/' > shuffle3.lds -$RUN_HOST $CCLINK -o shuffle3 $srcdir/shuffle2.c -Wl,--rpath-link,. shuffle3lib2.so -lc shuffle3lib1.so \ - -Wl,-T,shuffle3.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle3 > shuffle3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle3 >> shuffle3.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle3.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle3 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle3 >> shuffle3.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle3 -comparelibs >> shuffle3.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle4.sh b/trunk/testsuite/shuffle4.sh deleted file mode 100755 index b9375ee..0000000 --- a/trunk/testsuite/shuffle4.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Kernels before 2.4.10 are known not to work -if [ "x$CROSS" = "x" ]; then - case "`$RUN uname -r`" in - [01].*|2.[0-3].*|2.4.[0-9]|2.4.[0-9][^0-9]*) exit 77;; - esac -fi -rm -f shuffle4 shuffle4.log -BINS="shuffle4" -$RUN_HOST $CCLINK -o shuffle4 $srcdir/shuffle2.c -Wl,--rpath-link,. shuffle3lib2.so -lc shuffle3lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle4 > shuffle4.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle4 >> shuffle4.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle4.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle4 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle4 >> shuffle4.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle4 -comparelibs >> shuffle4.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle5.sh b/trunk/testsuite/shuffle5.sh deleted file mode 100755 index 0c71a19..0000000 --- a/trunk/testsuite/shuffle5.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f shuffle5 shuffle5lib*.so shuffle5.log shuffle5.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle5lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle5lib2.so $srcdir/reloc1lib2.c shuffle5lib1.so -BINS="shuffle5" -LIBS="shuffle5lib1.so shuffle5lib2.so" -$RUN_HOST $CCLINK -o shuffle5 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle5lib2.so -lc shuffle5lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e 's/0x08048000/0x08000000/;s/SIZEOF_HEADERS.*$/& . += 180;/' > shuffle5.lds -$RUN_HOST $CCLINK -o shuffle5 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle5lib2.so -lc shuffle5lib1.so \ - -Wl,-T,shuffle5.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle5 > shuffle5.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle5 >> shuffle5.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle5.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle5 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle5 >> shuffle5.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle5 -comparelibs >> shuffle5.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle6.sh b/trunk/testsuite/shuffle6.sh deleted file mode 100755 index 4ce00ee..0000000 --- a/trunk/testsuite/shuffle6.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f shuffle6 shuffle6lib*.so shuffle6.log shuffle6.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle6lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle6lib2.so $srcdir/reloc1lib2.c shuffle6lib1.so -BINS="shuffle6" -LIBS="shuffle6lib1.so shuffle6lib2.so" -$RUN_HOST $CCLINK -o shuffle6 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle6lib2.so -lc shuffle6lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e 's/0x08048000/0x08000000/;s/SIZEOF_HEADERS.*$/& . += 56;/' > shuffle6.lds -$RUN_HOST $CCLINK -o shuffle6 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle6lib2.so -lc shuffle6lib1.so \ - -Wl,-T,shuffle6.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 > shuffle6.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle6.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle6 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle6 >> shuffle6.log 2>&1 || exit 4 -comparelibs >> shuffle6.log 2>&1 || exit 5 -for l in shuffle6lib{1,2}.so{,.orig}; do mv -f $l $l.first; done -cp -p shuffle6 shuffle6.first -$RUN_HOST $CC -shared -O2 -fpic -o shuffle6lib1.so $srcdir/shuffle6lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle6lib2.so $srcdir/shuffle6lib2.c shuffle6lib1.so -for l in shuffle6lib{1,2}.so; do cp -p $l $l.orig; done -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle6 >> shuffle6.log 2>&1 || exit 6 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle6.log && exit 7 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle6 || exit 8 -fi -$RUN_HOST $READELF -a ./shuffle6 >> shuffle6.log 2>&1 || exit 9 -# So that it is not prelinked again -chmod -x ./shuffle6 -comparelibs >> shuffle6.log 2>&1 || exit 10 diff --git a/trunk/testsuite/shuffle6lib1.c b/trunk/testsuite/shuffle6lib1.c deleted file mode 100644 index 8053293..0000000 --- a/trunk/testsuite/shuffle6lib1.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "reloc1.h" - -int bar = 26; -int baz = 28; -#define M(i) int b##i, *pb##i = &b##i; -M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9) -M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19) -#undef M - -struct A foo = { 1, &foo, &bar }; - -int f1 (void) -{ - return 1; -} - -int f2 (void) -{ - return f1 () + 1; -} diff --git a/trunk/testsuite/shuffle6lib2.c b/trunk/testsuite/shuffle6lib2.c deleted file mode 100644 index ed18f6b..0000000 --- a/trunk/testsuite/shuffle6lib2.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -#define M(i) int b##i; extern *pb##i; -M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9) -M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19) -#undef M - -int f1 (void) -{ -#define M(i) if (pb##i != &b##i) abort (); -M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9) -M(10) M(11) M(12) M(13) M(14) M(15) M(16) M(17) M(18) M(19) -#undef M - return 11; -} diff --git a/trunk/testsuite/shuffle7.sh b/trunk/testsuite/shuffle7.sh deleted file mode 100755 index e94002d..0000000 --- a/trunk/testsuite/shuffle7.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f shuffle7 shuffle7lib*.so shuffle7.log shuffle7.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle7lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle7lib2.so $srcdir/reloc1lib2.c shuffle7lib1.so -BINS="shuffle7" -LIBS="shuffle7lib1.so shuffle7lib2.so" -$RUN_HOST $CCLINK -o shuffle7 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle7lib2.so -lc shuffle7lib1.so \ - -Wl,--verbose 2>&1 | sed -e '/^=========/,/^=========/!d;/^=========/d' \ - -e '/\.hash/a\ - . = . + 0x300;' > shuffle7.lds -$RUN_HOST $CCLINK -o shuffle7 $srcdir/reloc1.c -Wl,--rpath-link,. shuffle7lib2.so -lc shuffle7lib1.so \ - -Wl,-T,shuffle7.lds -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 > shuffle7.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle7 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle7 >> shuffle7.log 2>&1 || exit 4 -comparelibs >> shuffle7.log 2>&1 || exit 5 -for l in shuffle7lib{1,2}.so{,.orig}; do mv -f $l $l.first; done -cp -p shuffle7 shuffle7.first -$RUN_HOST $CC -shared -O2 -fpic -o shuffle7lib1.so $srcdir/shuffle6lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle7lib2.so $srcdir/shuffle6lib2.c shuffle7lib1.so -for l in shuffle7lib{1,2}.so; do cp -p $l $l.orig; done -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 6 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 7 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle7 || exit 8 -fi -$RUN_HOST $READELF -a ./shuffle7 >> shuffle7.log 2>&1 || exit 9 -comparelibs >> shuffle7.log 2>&1 || exit 10 -for l in shuffle7lib{1,2}.so{,.orig}; do mv -f $l $l.second; done -cp -p shuffle7 shuffle7.second -for l in shuffle7lib{1,2}.so{,.orig}; do cp -p $l.first $l; done -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle7 >> shuffle7.log 2>&1 || exit 11 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle7.log && exit 12 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle7 || exit 13 -fi -$RUN_HOST $READELF -a ./shuffle7 >> shuffle7.log 2>&1 || exit 14 -comparelibs >> shuffle7.log 2>&1 || exit 15 -cmp -s shuffle7{,.first} || exit 16 -# So that it is not prelinked again -chmod -x ./shuffle7 diff --git a/trunk/testsuite/shuffle8.c b/trunk/testsuite/shuffle8.c deleted file mode 100644 index 4e80184..0000000 --- a/trunk/testsuite/shuffle8.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -static struct A local = { 77, &local, &bar + 4 }; -int vbss[16384] __attribute__((aligned (4096))); -int vdata __attribute__((aligned (4096))) = 5; - -asm (".text; .balign 4096; vtext:; .previous"); - -int main() -{ - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - local.c -= 4; - if (local.a != 77 || local.b != &local || local.c != &bar) - abort (); - exit (vbss[31] + vdata - 5); -} diff --git a/trunk/testsuite/shuffle8.sh b/trunk/testsuite/shuffle8.sh deleted file mode 100755 index da2e499..0000000 --- a/trunk/testsuite/shuffle8.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f shuffle8 shuffle8lib*.so shuffle8.log shuffle8.lds -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o shuffle8lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o shuffle8lib2.so $srcdir/reloc1lib2.c shuffle8lib1.so -BINS="shuffle8" -LIBS="shuffle8lib1.so shuffle8lib2.so" -$RUN_HOST $CCLINK -o shuffle8 $srcdir/shuffle8.c -Wl,--rpath-link,. shuffle8lib2.so -lc shuffle8lib1.so -$RUN_HOST $STRIP -R .comment shuffle8 -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle8 > shuffle8.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle8 >> shuffle8.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle8.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./shuffle8 || exit 3 -fi -$RUN_HOST $READELF -a ./shuffle8 >> shuffle8.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle8 -comparelibs >> shuffle8.log 2>&1 || exit 5 diff --git a/trunk/testsuite/shuffle9.c b/trunk/testsuite/shuffle9.c deleted file mode 100644 index 201eabc..0000000 --- a/trunk/testsuite/shuffle9.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "reloc1.h" -#include <stdlib.h> - -extern char testzero[16384]; - -int main() -{ - int i; - if (foo.a != 1 || foo.b != &foo || foo.c != &bar || bar != 26) - abort (); - if (f1 () != 11 || f2 () != 12) - abort (); - for (i = 0; i < 16384; ++i) - if (testzero[i]) - abort (); - exit (0); -} - -asm (".section nonalloced,\"aw\",%nobits\n\t" - ".globl testzero\n\t" - "testzero: .skip 16384\n\t" - ".previous\n"); - -asm (".section \".note.PRELINK.1\", \"a\"\n\t" - ".balign 4\n\t" - ".long 1f - 0f\n\t" - ".long 3f - 2f\n\t" - ".long 1\n" - "0:\t.asciz \"PRELINK\"\n" - "1:\t.balign 4\n" - "2:\t.long 12\n\t" - ".long 17\n" - "3:\t.balign 4\n\t" - ".previous\n"); - -asm (".section \".note.PRELINK.2\", \"a\"\n\t" - ".balign 4\n\t" - ".long 1f - 0f\n\t" - ".long 3f - 2f\n\t" - ".long 2\n" - "0:\t.asciz \"PRELINK\"\n" - "1:\t.balign 4\n" - "2:\t.long 12\n\t" - ".long 17\n" - "3:\t.balign 4\n\t" - ".previous\n"); - -asm (".section \".note.PRELINK.3\", \"a\"\n\t" - ".balign 4\n\t" - ".long 1f - 0f\n\t" - ".long 3f - 2f\n\t" - ".long 3\n" - "0:\t.asciz \"PRELINK\"\n" - "1:\t.balign 4\n" - "2:\t.long 12\n\t" - ".long 17\n" - "3:\t.balign 4\n\t" - ".previous\n"); diff --git a/trunk/testsuite/shuffle9.sh b/trunk/testsuite/shuffle9.sh deleted file mode 100755 index 6b54646..0000000 --- a/trunk/testsuite/shuffle9.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# Kernels before 2.4.10 are known not to work -case "`$RUN uname -r`" in - [01].*|2.[0-3].*|2.4.[0-9]|2.4.[0-9][^0-9]*) exit 77;; -esac -rm -f shuffle9 shuffle9.log -BINS="shuffle9" -$RUN_HOST $CCLINK -o shuffle9 $srcdir/shuffle9.c -Wl,--rpath-link,. shuffle3lib2.so -lc shuffle3lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./shuffle9 > shuffle9.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./shuffle9 >> shuffle9.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` shuffle9.log && exit 2 -$RUN LD_LIBRARY_PATH=. ./shuffle9 || exit 3 -$RUN_HOST $READELF -a ./shuffle9 >> shuffle9.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./shuffle9 -comparelibs >> shuffle9.log 2>&1 || exit 5 diff --git a/trunk/testsuite/tls1.c b/trunk/testsuite/tls1.c deleted file mode 100644 index 08bd26f..0000000 --- a/trunk/testsuite/tls1.c +++ /dev/null @@ -1,36 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy = 12; -__thread struct A local = { 1, 2, 3 }; - -#define CHECK(N, S) \ - p = f##N##a (); \ - if (p->a != S || p->b != S + 1 || p->c != S + 2) \ - abort () - -int main() -{ - struct A *p; - if (local.a != 1 || local.b != 2 || local.c != 3) - abort (); - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a3.a != 10 || a3.b != 11 || a3.c != 12) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - check1 (); - check2 (); - if (f1a () != &a1 || f2a () != &a2 || f3a () != &a3 || f4a () != &a4) - abort (); - CHECK (5, 16); - CHECK (6, 19); - if (f7a () != &a2 || f8a () != &a4) - abort (); - CHECK (9, 28); - CHECK (10, 31); - exit (0); -} diff --git a/trunk/testsuite/tls1.h b/trunk/testsuite/tls1.h deleted file mode 100644 index d627340..0000000 --- a/trunk/testsuite/tls1.h +++ /dev/null @@ -1,30 +0,0 @@ -struct A - { - char a; - int b; - long long c; - }; - -extern __thread struct A a1, a2, a3, a4; -extern struct A *f1a (void); -extern struct A *f2a (void); -extern struct A *f3a (void); -extern struct A *f4a (void); -extern struct A *f5a (void); -extern struct A *f6a (void); -extern struct A *f7a (void); -extern struct A *f8a (void); -extern struct A *f9a (void); -extern struct A *f10a (void); -extern int f1b (void); -extern int f2b (void); -extern int f3b (void); -extern int f4b (void); -extern int f5b (void); -extern int f6b (void); -extern int f7b (void); -extern int f8b (void); -extern int f9b (void); -extern int f10b (void); -extern void check1 (void); -extern void check2 (void); diff --git a/trunk/testsuite/tls1.sh b/trunk/testsuite/tls1.sh deleted file mode 100755 index 664a2f5..0000000 --- a/trunk/testsuite/tls1.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls1 tls1lib*.so tls1.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o tls1lib1.so $srcdir/tls1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o tls1lib2.so $srcdir/tls1lib2.c tls1lib1.so -BINS="tls1" -LIBS="tls1lib1.so tls1lib2.so" -$RUN_HOST $CCLINK -o tls1 $srcdir/tls1.c -Wl,--rpath-link,. tls1lib2.so -lc tls1lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls1 > tls1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls1 >> tls1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls1 || exit 3 -fi -$RUN_HOST $READELF -a ./tls1 >> tls1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./tls1 -comparelibs >> tls1.log 2>&1 || exit 5 diff --git a/trunk/testsuite/tls1lib1.c b/trunk/testsuite/tls1lib1.c deleted file mode 100644 index eb0734b..0000000 --- a/trunk/testsuite/tls1lib1.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy = 12; -__thread struct A a1 = { 4, 5, 6 }; -__thread struct A a2 = { 7, 8, 9 }; -__thread struct A a3 __attribute__((tls_model("initial-exec"))) - = { 10, 11, 12 }; -__thread struct A a4 __attribute__((tls_model("initial-exec"))) - = { 13, 14, 15 }; -static __thread struct A local1 = { 16, 17, 18 }; -static __thread struct A local2 __attribute__((tls_model("initial-exec"))) - = { 19, 20, 21 }; - -void check1 (void) -{ - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a3.a != 10 || a3.b != 11 || a3.c != 12) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 16 || local1.b != 17 || local1.c != 18) - abort (); - if (local2.a != 19 || local2.b != 20 || local2.c != 21) - abort (); -} - -struct A *f1a (void) -{ - return &a1; -} - -struct A *f2a (void) -{ - return &a2; -} - -struct A *f3a (void) -{ - return &a3; -} - -struct A *f4a (void) -{ - return &a4; -} - -struct A *f5a (void) -{ - return &local1; -} - -struct A *f6a (void) -{ - return &local2; -} - -int f1b (void) -{ - return a1.a; -} - -int f2b (void) -{ - return a2.b; -} - -int f3b (void) -{ - return a3.c; -} - -int f4b (void) -{ - return a4.a; -} - -int f5b (void) -{ - return local1.b; -} - -int f6b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls1lib2.c b/trunk/testsuite/tls1lib2.c deleted file mode 100644 index eee03a9..0000000 --- a/trunk/testsuite/tls1lib2.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread long long dummy = 12; -__thread struct A a2 = { 22, 23, 24 }; -__thread struct A a4 __attribute__((tls_model("initial-exec"))) - = { 25, 26, 27 }; -static __thread struct A local1 = { 28, 29, 30 }; -static __thread struct A local2 __attribute__((tls_model("initial-exec"))) - = { 31, 32, 33 }; - -void check2 (void) -{ - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 28 || local1.b != 29 || local1.c != 30) - abort (); - if (local2.a != 31 || local2.b != 32 || local2.c != 33) - abort (); -} - -struct A *f7a (void) -{ - return &a2; -} - -struct A *f8a (void) -{ - return &a4; -} - -struct A *f9a (void) -{ - return &local1; -} - -struct A *f10a (void) -{ - return &local2; -} - -int f7b (void) -{ - return a2.b; -} - -int f8b (void) -{ - return a4.a; -} - -int f9b (void) -{ - return local1.b; -} - -int f10b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls2.c b/trunk/testsuite/tls2.c deleted file mode 100644 index 1246165..0000000 --- a/trunk/testsuite/tls2.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -#define CHECK(N, S) \ - p = f##N##a (); \ - if (p->a != S || p->b != S + 1 || p->c != S + 2) \ - abort () - -int main() -{ - struct A *p; - check1 (); - check2 (); - CHECK (1, 4); - CHECK (2, 22); - CHECK (3, 10); - CHECK (4, 25); - CHECK (5, 16); - CHECK (6, 19); - CHECK (7, 22); - CHECK (8, 25); - CHECK (9, 28); - CHECK (10, 31); - exit (0); -} diff --git a/trunk/testsuite/tls2.sh b/trunk/testsuite/tls2.sh deleted file mode 100755 index 8c21625..0000000 --- a/trunk/testsuite/tls2.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls2 tls2lib*.so tls2.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o tls2lib1.so $srcdir/tls2lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o tls2lib2.so $srcdir/tls1lib2.c tls2lib1.so -BINS="tls2" -LIBS="tls2lib1.so tls2lib2.so" -$RUN_HOST $CCLINK -o tls2 $srcdir/tls2.c -Wl,--rpath-link,. tls2lib2.so -lc tls2lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls2 > tls2.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls2 >> tls2.log 2>&1 || exit 1 -grep -v 'has undefined non-weak symbols' tls2.log \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls2 || exit 3 -fi -$RUN_HOST $READELF -a ./tls2 >> tls2.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./tls2 -comparelibs >> tls2.log 2>&1 || exit 5 diff --git a/trunk/testsuite/tls2lib1.c b/trunk/testsuite/tls2lib1.c deleted file mode 100644 index 24b7555..0000000 --- a/trunk/testsuite/tls2lib1.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy = 12; -__thread struct A a1 = { 4, 5, 6 }; -__thread struct A a3 __attribute__((tls_model("initial-exec"))) - = { 10, 11, 12 }; -extern __thread struct A a4 __attribute__((tls_model("initial-exec"))); -static __thread struct A local1 = { 16, 17, 18 }; -static __thread struct A local2 __attribute__((tls_model("initial-exec"))) - = { 19, 20, 21 }; - -void check1 (void) -{ - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a3.a != 10 || a3.b != 11 || a3.c != 12) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 16 || local1.b != 17 || local1.c != 18) - abort (); - if (local2.a != 19 || local2.b != 20 || local2.c != 21) - abort (); -} - -struct A *f1a (void) -{ - return &a1; -} - -struct A *f2a (void) -{ - return &a2; -} - -struct A *f3a (void) -{ - return &a3; -} - -struct A *f4a (void) -{ - return &a4; -} - -struct A *f5a (void) -{ - return &local1; -} - -struct A *f6a (void) -{ - return &local2; -} - -int f1b (void) -{ - return a1.a; -} - -int f2b (void) -{ - return a2.b; -} - -int f3b (void) -{ - return a3.c; -} - -int f4b (void) -{ - return a4.a; -} - -int f5b (void) -{ - return local1.b; -} - -int f6b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls3.sh b/trunk/testsuite/tls3.sh deleted file mode 100755 index eb6e626..0000000 --- a/trunk/testsuite/tls3.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -SHFLAGS= -case "`$RUN uname -m`" in - ia64|ppc*|x86_64|alpha*|s390*|mips*|arm*) SHFLAGS=-fpic;; # Does not support non-pic shared libs -esac -# Disable this test under SELinux if textrel -if test -z "$SHFLAGS" -a -x /usr/sbin/getenforce; then - case "`/usr/sbin/getenforce 2>/dev/null`" in - Permissive|Disabled) ;; - *) exit 77 ;; - esac -fi -rm -f tls3 tls3lib*.so tls3.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o tls3lib1.so $srcdir/tls1lib1.c -$RUN_HOST $CC -shared -O2 $SHFLAGS -o tls3lib2.so $srcdir/tls3lib2.c \ - tls3lib1.so 2>/dev/null -BINS="tls3" -LIBS="tls3lib1.so tls3lib2.so" -$RUN_HOST $CCLINK -o tls3 $srcdir/tls1.c -Wl,--rpath-link,. tls3lib2.so -lc tls3lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls3 > tls3.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls3 >> tls3.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls3.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls3 || exit 3 -fi -$RUN_HOST $READELF -a ./tls3 >> tls3.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./tls3 -comparelibs >> tls3.log 2>&1 || exit 5 diff --git a/trunk/testsuite/tls3lib2.c b/trunk/testsuite/tls3lib2.c deleted file mode 100644 index ba485d3..0000000 --- a/trunk/testsuite/tls3lib2.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -asm (".section trampoline, \"awx\"; .previous"); - -#if !defined __sparc__ || defined __pic__ || defined __PIC__ -#define ieattr __attribute__((tls_model("initial-exec"))) -#else -#define ieattr -#endif - -static __thread long long dummy = 12; -__thread struct A a2 = { 22, 23, 24 }; -__thread struct A a4 ieattr = { 25, 26, 27 }; -static __thread struct A local1 = { 28, 29, 30 }; -static __thread struct A local2 ieattr = { 31, 32, 33 }; - -void __attribute__((section ("trampoline"))) check2 (void) -{ - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 28 || local1.b != 29 || local1.c != 30) - abort (); - if (local2.a != 31 || local2.b != 32 || local2.c != 33) - abort (); -} - -struct A * __attribute__((section ("trampoline"))) f7a (void) -{ - return &a2; -} - -struct A * __attribute__((section ("trampoline"))) f8a (void) -{ - return &a4; -} - -struct A * __attribute__((section ("trampoline"))) f9a (void) -{ - return &local1; -} - -struct A * __attribute__((section ("trampoline"))) f10a (void) -{ - return &local2; -} - -int __attribute__((section ("trampoline"))) f7b (void) -{ - return a2.b; -} - -int __attribute__((section ("trampoline"))) f8b (void) -{ - return a4.a; -} - -int __attribute__((section ("trampoline"))) f9b (void) -{ - return local1.b; -} - -int __attribute__((section ("trampoline"))) f10b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls4.c b/trunk/testsuite/tls4.c deleted file mode 100644 index 0882f07..0000000 --- a/trunk/testsuite/tls4.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -#define CHECK(N, S) \ - p = &a##N; \ - if (p->a != S || p->b != S + 1 || p->c != S + 2) \ - abort () - -int main() -{ - struct A *p; - check1 (); - CHECK (1, 4); - CHECK (2, 7); - exit (0); -} diff --git a/trunk/testsuite/tls4.sh b/trunk/testsuite/tls4.sh deleted file mode 100755 index 889f0cc..0000000 --- a/trunk/testsuite/tls4.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls4 tls4lib*.so tls4.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o tls4lib1.so $srcdir/tls4lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o tls4lib2.so $srcdir/tls4lib2.c \ - tls4lib1.so 2>/dev/null -BINS="tls4" -LIBS="tls4lib1.so tls4lib2.so" -$RUN_HOST $CCLINK -o tls4 $srcdir/tls4.c -Wl,--rpath-link,. tls4lib2.so -lc tls4lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls4 > tls4.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls4 >> tls4.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls4.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls4 || exit 3 -fi -$RUN_HOST $READELF -a ./tls4 >> tls4.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./tls4 -comparelibs >> tls4.log 2>&1 || exit 5 diff --git a/trunk/testsuite/tls4lib1.c b/trunk/testsuite/tls4lib1.c deleted file mode 100644 index a03af0b..0000000 --- a/trunk/testsuite/tls4lib1.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -__thread struct A a1 = { 4, 5, 6 }; -__thread struct A a2 = { 7, 8, 9 }; diff --git a/trunk/testsuite/tls4lib2.c b/trunk/testsuite/tls4lib2.c deleted file mode 100644 index 309504b..0000000 --- a/trunk/testsuite/tls4lib2.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -extern __thread struct A a2 __attribute__((tls_model("initial-exec"))); - -void check1 (void) -{ - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 7 || a2.b != 8 || a2.c != 9) - abort (); -} diff --git a/trunk/testsuite/tls5.sh b/trunk/testsuite/tls5.sh deleted file mode 100755 index 8c1fac4..0000000 --- a/trunk/testsuite/tls5.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls5 tls5lib*.so tls5.log -rm -f prelink.cache -echo 'int tls5;' | $RUN_HOST $CC -shared -O2 -fpic -xc - -o tls5lib3.so -$RUN_HOST $CC -shared -O2 -fpic -o tls5lib1.so $srcdir/tls5lib1.c tls5lib3.so -$RUN_HOST $CC -shared -O2 -fpic -o tls5lib2.so $srcdir/tls1lib2.c \ - -Wl,--rpath-link,. tls5lib1.so -BINS="tls5" -LIBS="tls5lib1.so tls5lib2.so tls5lib3.so" -$RUN_HOST $CCLINK -o tls5 $srcdir/tls1.c -Wl,--rpath-link,. tls5lib2.so -lc tls5lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls5 > tls5.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls5 >> tls5.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls5.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls5 || exit 3 -fi -$RUN_HOST $PRELINK -u tls5lib3.so || exit 4 -echo $PRELINK ${PRELINK_OPTS--vm} ./tls5 >> tls5.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls5 >> tls5.log 2>&1 || exit 5 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls5.log && exit 6 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls5 || exit 7 -fi -$RUN_HOST $READELF -a ./tls5 >> tls5.log 2>&1 || exit 8 -# So that it is not prelinked again -chmod -x ./tls5 -comparelibs >> tls5.log 2>&1 || exit 9 diff --git a/trunk/testsuite/tls5lib1.c b/trunk/testsuite/tls5lib1.c deleted file mode 100644 index 9677848..0000000 --- a/trunk/testsuite/tls5lib1.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy = 12; -__thread struct A a1 = { 4, 5, 6 }; -__thread struct A a2 = { 7, 8, 9 }; -__thread struct A a3 __attribute__((tls_model("initial-exec"))) - = { 10, 11, 12 }; -__thread struct A a4 __attribute__((tls_model("initial-exec"))) - = { 13, 14, 15 }; -static __thread struct A local1 = { 16, 17, 18 }; -static __thread struct A local2 __attribute__((tls_model("initial-exec"))) - = { 19, 20, 21 }; -struct Z { char a; struct Z *b; int *c; }; -int y[2]; -struct Z z[2] = { { 1, &z[1], &y[0] }, { 2, &z[0], &y[1] } }; - -void check1 (void) -{ - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a3.a != 10 || a3.b != 11 || a3.c != 12) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 16 || local1.b != 17 || local1.c != 18) - abort (); - if (local2.a != 19 || local2.b != 20 || local2.c != 21) - abort (); - if (z[0].a != 1 || z[0].b != &z[1] || z[0].c != &y[0]) - abort (); - if (z[1].a != 2 || z[1].b != &z[0] || z[1].c != &y[1]) - abort (); -} - -struct A *f1a (void) -{ - return &a1; -} - -struct A *f2a (void) -{ - return &a2; -} - -struct A *f3a (void) -{ - return &a3; -} - -struct A *f4a (void) -{ - return &a4; -} - -struct A *f5a (void) -{ - return &local1; -} - -struct A *f6a (void) -{ - return &local2; -} - -int f1b (void) -{ - return a1.a; -} - -int f2b (void) -{ - return a2.b; -} - -int f3b (void) -{ - return a3.c; -} - -int f4b (void) -{ - return a4.a; -} - -int f5b (void) -{ - return local1.b; -} - -int f6b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls6.sh b/trunk/testsuite/tls6.sh deleted file mode 100755 index 54d4666..0000000 --- a/trunk/testsuite/tls6.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls6 tls6lib*.so tls6.log -rm -f prelink.cache -echo 'int tls6;' | $RUN_HOST $CC -shared -O2 -fpic -xc - -o tls6lib3.so -$RUN_HOST $CC -shared -O2 -fpic -o tls6lib1.so $srcdir/tls6lib1.c tls6lib3.so -$RUN_HOST $CC -shared -O2 -fpic -o tls6lib2.so $srcdir/tls1lib2.c \ - -Wl,--rpath-link,. tls6lib1.so -BINS="tls6" -LIBS="tls6lib1.so tls6lib2.so tls6lib3.so" -$RUN_HOST $CCLINK -o tls6 $srcdir/tls2.c -Wl,--rpath-link,. tls6lib2.so -lc tls6lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls6 > tls6.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls6 >> tls6.log 2>&1 || exit 1 -grep -v 'has undefined non-weak symbols' tls6.log \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls6 || exit 3 -fi -$RUN_HOST $PRELINK -u tls6lib3.so || exit 4 -echo $PRELINK ${PRELINK_OPTS--vm} ./tls6 >> tls6.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls6 >> tls6.log 2>&1 || exit 5 -grep -v 'has undefined non-weak symbols' tls6.log \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 6 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls6 || exit 7 -fi -$RUN_HOST $READELF -a ./tls6 >> tls6.log 2>&1 || exit 8 -# So that it is not prelinked again -chmod -x ./tls6 -comparelibs >> tls6.log 2>&1 || exit 9 diff --git a/trunk/testsuite/tls6lib1.c b/trunk/testsuite/tls6lib1.c deleted file mode 100644 index 5310c06..0000000 --- a/trunk/testsuite/tls6lib1.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy = 12; -__thread struct A a1 = { 4, 5, 6 }; -__thread struct A a3 __attribute__((tls_model("initial-exec"))) - = { 10, 11, 12 }; -extern __thread struct A a4 __attribute__((tls_model("initial-exec"))); -static __thread struct A local1 = { 16, 17, 18 }; -static __thread struct A local2 __attribute__((tls_model("initial-exec"))) - = { 19, 20, 21 }; -struct Z { char a; struct Z *b; int *c; }; -int y[2]; -struct Z z[2] = { { 1, &z[1], &y[0] }, { 2, &z[0], &y[1] } }; - -void check1 (void) -{ - if (a1.a != 4 || a1.b != 5 || a1.c != 6) - abort (); - if (a2.a != 22 || a2.b != 23 || a2.c != 24) - abort (); - if (a3.a != 10 || a3.b != 11 || a3.c != 12) - abort (); - if (a4.a != 25 || a4.b != 26 || a4.c != 27) - abort (); - if (local1.a != 16 || local1.b != 17 || local1.c != 18) - abort (); - if (local2.a != 19 || local2.b != 20 || local2.c != 21) - abort (); - if (z[0].a != 1 || z[0].b != &z[1] || z[0].c != &y[0]) - abort (); - if (z[1].a != 2 || z[1].b != &z[0] || z[1].c != &y[1]) - abort (); -} - -struct A *f1a (void) -{ - return &a1; -} - -struct A *f2a (void) -{ - return &a2; -} - -struct A *f3a (void) -{ - return &a3; -} - -struct A *f4a (void) -{ - return &a4; -} - -struct A *f5a (void) -{ - return &local1; -} - -struct A *f6a (void) -{ - return &local2; -} - -int f1b (void) -{ - return a1.a; -} - -int f2b (void) -{ - return a2.b; -} - -int f3b (void) -{ - return a3.c; -} - -int f4b (void) -{ - return a4.a; -} - -int f5b (void) -{ - return local1.b; -} - -int f6b (void) -{ - return local2.c; -} diff --git a/trunk/testsuite/tls7.c b/trunk/testsuite/tls7.c deleted file mode 100644 index 4a3db24..0000000 --- a/trunk/testsuite/tls7.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "tls1.h" -#include <stdlib.h> - -static __thread int dummy; -__thread struct A local; - -int main() -{ - exit (dummy + local.a + local.b + local.c); -} diff --git a/trunk/testsuite/tls7.sh b/trunk/testsuite/tls7.sh deleted file mode 100755 index f7e35ff..0000000 --- a/trunk/testsuite/tls7.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -# First check if __thread is supported by ld.so/gcc/ld/as: -rm -f tlstest -echo '__thread int a; int main (void) { return a; }' \ - | $RUN_HOST $CCLINK -xc - -o tlstest > /dev/null 2>&1 || exit 77 -if [ "x$CROSS" = "x" ]; then - ( $RUN LD_LIBRARY_PATH=. ./tlstest || { rm -f tlstest; exit 77; } ) 2>/dev/null || exit 77 -fi -rm -f tls7 tls7.log -rm -f prelink.cache -BINS="tls7" -LIBS="" -$RUN_HOST $CCLINK -o tls7 $srcdir/tls7.c -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./tls7 > tls7.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./tls7 >> tls7.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` tls7.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./tls7 || exit 3 -fi -$RUN_HOST $READELF -a ./tls7 >> tls7.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./tls7 -comparelibs >> tls7.log 2>&1 || exit 5 diff --git a/trunk/testsuite/undo1.sh b/trunk/testsuite/undo1.sh deleted file mode 100755 index c349798..0000000 --- a/trunk/testsuite/undo1.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -rm -f undo1 undo1lib*.so undo1.log -rm -f prelink.cache -$RUN_HOST $CC -shared -O2 -fpic -o undo1lib1.so $srcdir/reloc1lib1.c -$RUN_HOST $CC -shared -O2 -fpic -o undo1lib2.so $srcdir/reloc1lib2.c undo1lib1.so -BINS="undo1" -LIBS="undo1lib1.so undo1lib2.so" -$RUN_HOST $CCLINK -o undo1 $srcdir/reloc1.c -Wl,--rpath-link,. undo1lib2.so -lc undo1lib1.so -savelibs -echo $PRELINK ${PRELINK_OPTS--vm} ./undo1 > undo1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} ./undo1 >> undo1.log 2>&1 || exit 1 -grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` undo1.log && exit 2 -if [ "x$CROSS" = "x" ]; then - $RUN LD_LIBRARY_PATH=. ./undo1 || exit 3 -fi -$RUN_HOST $READELF -a ./undo1 >> undo1.log 2>&1 || exit 4 -# So that it is not prelinked again -chmod -x ./undo1 -echo $PRELINK -uo undo1.undo undo1 >> undo1.log -$RUN_HOST $PRELINK -uo undo1.undo undo1 >> undo1.log 2>&1 || exit 5 -cmp -s undo1.undo undo1.orig >> undo1.log 2>&1 || exit 6 -rm -f undo1.undo -comparelibs >> undo1.log 2>&1 || exit 7 diff --git a/trunk/testsuite/undosyslibs.sh b/trunk/testsuite/undosyslibs.sh deleted file mode 100755 index 1ce136d..0000000 --- a/trunk/testsuite/undosyslibs.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -LIBS=`cat syslib.list` -comparelibs >> undosyslibs.log 2>&1 || exit 1 diff --git a/trunk/testsuite/unprel1.c b/trunk/testsuite/unprel1.c deleted file mode 100644 index 0c8e9f9..0000000 --- a/trunk/testsuite/unprel1.c +++ /dev/null @@ -1,7 +0,0 @@ -extern int bar (); - -int -main () -{ - return bar () - 42; -} diff --git a/trunk/testsuite/unprel1.sh b/trunk/testsuite/unprel1.sh deleted file mode 100755 index 481db12..0000000 --- a/trunk/testsuite/unprel1.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -. `dirname $0`/functions.sh -PRELINK=`echo $PRELINK \ - | sed -e 's, \./\(prelink\.\(cache\|conf\)\), unprel1.tree/etc/\1,g' \ - -e 's,path=\.,path=unprel1.tree/opt:unprel1.tree/lib,' \ - -e 's,linker=\./,linker=unprel1.tree/lib/,'` -CCLINK=`echo $CCLINK \ - | sed -e 's,linker=\./,linker=unprel1.tree/lib/,'` -rm -rf unprel1.tree -rm -f unprel1.log -mkdir -p unprel1.tree/{lib,etc,opt,bin} -$RUN_HOST $CC -shared -O2 -fpic -o unprel1.tree/lib/lib1.so $srcdir/unprel1lib1.c -cp -a unprel1.tree/{lib,opt}/lib1.so -$RUN_HOST $CC -shared -O2 -fpic -o unprel1.tree/lib/lib2.so $srcdir/unprel1lib2.c \ - -L unprel1.tree/lib -l1 -$RUN_HOST $CCLINK -o unprel1.tree/bin/bin1 $srcdir/unprel1.c \ - -Wl,-rpath,unprel1.tree/lib -L unprel1.tree/lib -l2 -cat > unprel1.tree/etc/prelink.conf <<EOF -unprel1.tree/bin -unprel1.tree/lib -EOF -for lib in `cat syslib.list`; do - cp -p $lib.orig unprel1.tree/lib/$lib - cp -p $lib.orig unprel1.tree/lib/$lib.orig -done -for lib in `cat syslnk.list`; do - cp -dp $lib unprel1.tree/lib -done -LIBS="unprel1.tree/lib/lib1.so unprel1.tree/lib/lib2.so" -LIBS="$LIBS unprel1.tree/opt/lib1.so" -BINS="unprel1.tree/bin/bin1" -savelibs -chmod -x unprel1.tree/bin/bin1.orig -echo $PRELINK ${PRELINK_OPTS--vm} unprel1.tree/{bin,lib} > unprel1.log -$RUN_HOST $PRELINK ${PRELINK_OPTS--vm} unprel1.tree/{bin,lib} >> unprel1.log 2>&1 || exit 1 -grep -v 'opt/lib1.so is not present in any config file directories' unprel1.log \ - | grep -v 'lib/lib2.so because its dependency unprel1.tree/opt/lib1.so could not be prelinked' \ - | grep -v 'bin/bin1 because its dependency unprel1.tree/lib/lib2.so could not be prelinked' \ - | grep -q ^`echo $PRELINK | sed 's/ .*$/: /'` && exit 2 -grep -q 'opt/lib1.so is not present in any config file directories' \ - unprel1.log || exit 3 -grep -q 'lib/lib2.so because its dependency unprel1.tree/opt/lib1.so could not be prelinked' \ - unprel1.log || exit 4 -grep -q 'bin/bin1 because its dependency unprel1.tree/lib/lib2.so could not be prelinked' \ - unprel1.log || exit 5 -unprel1.tree/bin/bin1 || exit 6 -# So that it is not prelinked again -chmod -x unprel1.tree/bin/bin1 -LIBS=unprel1.tree/lib/lib1.so -BINS= -comparelibs >> unprel1.log 2>&1 || exit 7 -for i in unprel1.tree/lib/lib2.so unprel1.tree/opt/lib1.so unprel1.tree/bin/bin1; do - cmp -s $i $i.orig || exit 8 -done -exit 0 diff --git a/trunk/testsuite/unprel1lib1.c b/trunk/testsuite/unprel1lib1.c deleted file mode 100644 index 8f85da3..0000000 --- a/trunk/testsuite/unprel1lib1.c +++ /dev/null @@ -1,5 +0,0 @@ -int -baz () -{ - return 42; -} diff --git a/trunk/testsuite/unprel1lib2.c b/trunk/testsuite/unprel1lib2.c deleted file mode 100644 index 4783123..0000000 --- a/trunk/testsuite/unprel1lib2.c +++ /dev/null @@ -1,7 +0,0 @@ -extern int baz (); - -int -bar () -{ - return baz (); -} |