diff options
author | gj <gj@FreeBSD.org> | 1997-01-15 22:28:25 +0000 |
---|---|---|
committer | gj <gj@FreeBSD.org> | 1997-01-15 22:28:25 +0000 |
commit | 5a3eeda46b960f4ac9faa83cb378cd2f9a7de905 (patch) | |
tree | 6c9afc87fe5cc9ceb4985f3cd56b1c002f4a138f | |
parent | d79ac17aa7f51d5b45f8296878d075f24f26acea (diff) | |
download | FreeBSD-src-5a3eeda46b960f4ac9faa83cb378cd2f9a7de905.zip FreeBSD-src-5a3eeda46b960f4ac9faa83cb378cd2f9a7de905.tar.gz |
changes required in the bfd directory for making gdb
using the sources in /usr/src/contrib/gdb.
This is based on /usr/ports/devel/gdb.
2.2 candidate ?
50 files changed, 705 insertions, 43235 deletions
diff --git a/gnu/usr.bin/gdb/bfd/COPYING b/gnu/usr.bin/gdb/bfd/COPYING deleted file mode 100644 index a43ea21..0000000 --- a/gnu/usr.bin/gdb/bfd/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, 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 - - Appendix: 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., 675 Mass Ave, Cambridge, MA 02139, 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/gnu/usr.bin/gdb/bfd/Makefile b/gnu/usr.bin/gdb/bfd/Makefile index 24322af..e474809 100644 --- a/gnu/usr.bin/gdb/bfd/Makefile +++ b/gnu/usr.bin/gdb/bfd/Makefile @@ -1,21 +1,26 @@ LIB = bfd -SRCS = libbfd.c opncls.c bfd.c archive.c targets.c cache.c \ +GDBDIR= ${.CURDIR}/../../../../contrib/gdb +.PATH: ${GDBDIR}/bfd + +SRCS = libbfd.c opncls.c bfd.c archive.c targets.c cache.c \ archures.c coff-i386.c aout32.c \ srec.c \ ecoff.c ecofflink.c \ coffgen.c format.c \ - section.c core.c syms.c stab-syms.c reloc.c init.c ctor.c \ + section.c syms.c stab-syms.c reloc.c init.c \ trad-core.c \ i386aout.c \ - freebsd386.c \ + i386freebsd.c i386bsd.c \ cpu-i386.c \ - elf.c elf32.c elf32-i386.c \ - hash.c linker.c + elf.c \ + hash.c linker.c corefile.c binary.c \ + tekhex.c ihex.c -CFLAGS+= -I$(.CURDIR)/. -I$(.CURDIR)/../gdb/. -CFLAGS+= -DDEFAULT_VECTOR=freebsd386_vec -DSELECT_VECS='&freebsd386_vec' \ - -DSELECT_ARCHITECTURES='bfd_i386_arch' -DTRAD_CORE +CFLAGS+= -I${.CURDIR}/. -I${.CURDIR}/../gdb/. +CFLAGS+= -DDEFAULT_VECTOR=i386freebsd_vec \ + -DSELECT_VECS='&i386freebsd_vec,&i386bsd_vec' \ + -DSELECT_ARCHITECTURES='&bfd_i386_arch' -DTRAD_CORE NOPROFILE=no NOPIC=no diff --git a/gnu/usr.bin/gdb/bfd/README.FreeBSD b/gnu/usr.bin/gdb/bfd/README.FreeBSD deleted file mode 100644 index 033fa00..0000000 --- a/gnu/usr.bin/gdb/bfd/README.FreeBSD +++ /dev/null @@ -1,4 +0,0 @@ -This is a greatly pared down libbfd directory. Only what's required to build -gdb-4.13 on FreeBSD 2.0 was kept. - -gj@freebsd.org diff --git a/gnu/usr.bin/gdb/bfd/VERSION b/gnu/usr.bin/gdb/bfd/VERSION deleted file mode 100644 index ae7202b..0000000 --- a/gnu/usr.bin/gdb/bfd/VERSION +++ /dev/null @@ -1 +0,0 @@ -cygnus-2.3 diff --git a/gnu/usr.bin/gdb/bfd/aout-target.h b/gnu/usr.bin/gdb/bfd/aout-target.h deleted file mode 100644 index 7e4a846..0000000 --- a/gnu/usr.bin/gdb/bfd/aout-target.h +++ /dev/null @@ -1,555 +0,0 @@ -/* Define a target vector and some small routines for a variant of a.out. - Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" -/*#include "libaout.h"*/ - -extern CONST struct reloc_howto_struct * NAME(aout,reloc_type_lookup) (); - -/* Set parameters about this a.out file that are machine-dependent. - This routine is called from some_aout_object_p just before it returns. */ -#ifndef MY_callback -static const bfd_target * -MY(callback) (abfd) - bfd *abfd; -{ - struct internal_exec *execp = exec_hdr (abfd); - unsigned int arch_align_power; - unsigned long arch_align; - - /* Calculate the file positions of the parts of a newly read aout header */ - obj_textsec (abfd)->_raw_size = N_TXTSIZE(*execp); - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR(*execp); - obj_datasec (abfd)->vma = N_DATADDR(*execp); - obj_bsssec (abfd)->vma = N_BSSADDR(*execp); - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF (*execp); - obj_datasec (abfd)->filepos = N_DATOFF (*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); - - /* The file offsets of the string table and symbol table. */ - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - obj_str_filepos (abfd) = N_STROFF (*execp); - - /* Determine the architecture and machine type of the object file. */ -#ifdef SET_ARCH_MACH - SET_ARCH_MACH(abfd, *execp); -#else - bfd_default_set_arch_mach(abfd, DEFAULT_ARCH, 0); -#endif - - /* Now that we know the architecture, set the alignments of the - sections. This is normally done by NAME(aout,new_section_hook), - but when the initial sections were created the architecture had - not yet been set. However, for backward compatibility, we don't - set the alignment power any higher than as required by the size - of the section. */ - arch_align_power = bfd_get_arch_info (abfd)->section_align_power; - arch_align = 1 << arch_align_power; - if ((BFD_ALIGN (obj_textsec (abfd)->_raw_size, arch_align) - == obj_textsec (abfd)->_raw_size) - && (BFD_ALIGN (obj_datasec (abfd)->_raw_size, arch_align) - == obj_datasec (abfd)->_raw_size) - && (BFD_ALIGN (obj_bsssec (abfd)->_raw_size, arch_align) - == obj_bsssec (abfd)->_raw_size)) - { - obj_textsec (abfd)->alignment_power = arch_align_power; - obj_datasec (abfd)->alignment_power = arch_align_power; - obj_bsssec (abfd)->alignment_power = arch_align_power; - } - - /* Don't set sizes now -- can't be sure until we know arch & mach. - Sizes get set in set_sizes callback, later. */ -#if 0 - adata(abfd).page_size = PAGE_SIZE; -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = PAGE_SIZE; -#endif - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; -#endif - - return abfd->xvec; -} -#endif - -#ifndef MY_object_p -/* Finish up the reading of an a.out file header */ - -static const bfd_target * -MY(object_p) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; /* Raw exec header from file */ - struct internal_exec exec; /* Cleaned-up exec header */ - const bfd_target *target; - - if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) - != EXEC_BYTES_SIZE) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - -#ifdef SWAP_MAGIC - exec.a_info = SWAP_MAGIC (exec_bytes.e_info); -#else - exec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info); -#endif /* SWAP_MAGIC */ - - if (N_BADMAG (exec)) return 0; -#ifdef MACHTYPE_OK - if (!(MACHTYPE_OK (N_MACHTYPE (exec)))) return 0; -#endif - - NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec); - -#ifdef SWAP_MAGIC - /* swap_exec_header_in read in a_info with the wrong byte order */ - exec.a_info = SWAP_MAGIC (exec_bytes.e_info); -#endif /* SWAP_MAGIC */ - - target = NAME(aout,some_aout_object_p) (abfd, &exec, MY(callback)); - -#ifdef ENTRY_CAN_BE_ZERO - /* The NEWSOS3 entry-point is/was 0, which (amongst other lossage) - * means that it isn't obvious if EXEC_P should be set. - * All of the following must be true for an executable: - * There must be no relocations, the bfd can be neither an - * archive nor an archive element, and the file must be executable. */ - - if (exec.a_trsize + exec.a_drsize == 0 - && bfd_get_format(abfd) == bfd_object && abfd->my_archive == NULL) - { - struct stat buf; -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif - if (stat(abfd->filename, &buf) == 0 && (buf.st_mode & S_IXUSR)) - abfd->flags |= EXEC_P; - } -#endif /* ENTRY_CAN_BE_ZERO */ - - return target; -} -#define MY_object_p MY(object_p) -#endif - - -#ifndef MY_mkobject -static boolean -MY(mkobject) (abfd) - bfd *abfd; -{ - if (NAME(aout,mkobject)(abfd) == false) - return false; -#if 0 /* Sizes get set in set_sizes callback, later, after we know - the architecture and machine. */ - adata(abfd).page_size = PAGE_SIZE; -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = PAGE_SIZE; -#endif - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; -#endif - return true; -} -#define MY_mkobject MY(mkobject) -#endif - -#ifndef MY_bfd_copy_private_section_data - -/* Copy private section data. This actually does nothing with the - sections. It copies the subformat field. We copy it here, because - we need to know whether this is a QMAGIC file before we set the - section contents, and copy_private_bfd_data is not called until - after the section contents have been set. */ - -/*ARGSUSED*/ -static boolean -MY_bfd_copy_private_section_data (ibfd, isec, obfd, osec) - bfd *ibfd; - asection *isec; - bfd *obfd; - asection *osec; -{ - obj_aout_subformat (obfd) = obj_aout_subformat (ibfd); - return true; -} - -#endif - -/* Write an object file. - Section contents have already been written. We write the - file header, symbols, and relocation. */ - -#ifndef MY_write_object_contents -static boolean -MY(write_object_contents) (abfd) - bfd *abfd; -{ - struct external_exec exec_bytes; - struct internal_exec *execp = exec_hdr (abfd); - -#if CHOOSE_RELOC_SIZE - CHOOSE_RELOC_SIZE(abfd); -#else - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; -#endif - - WRITE_HEADERS(abfd, execp); - - return true; -} -#define MY_write_object_contents MY(write_object_contents) -#endif - -#ifndef MY_set_sizes -static boolean -MY(set_sizes) (abfd) - bfd *abfd; -{ - adata(abfd).page_size = PAGE_SIZE; - -#ifdef SEGMENT_SIZE - adata(abfd).segment_size = SEGMENT_SIZE; -#else - adata(abfd).segment_size = PAGE_SIZE; -#endif - -#ifdef ZMAGIC_DISK_BLOCK_SIZE - adata(abfd).zmagic_disk_block_size = ZMAGIC_DISK_BLOCK_SIZE; -#else - adata(abfd).zmagic_disk_block_size = PAGE_SIZE; -#endif - - adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; - return true; -} -#define MY_set_sizes MY(set_sizes) -#endif - -#ifndef MY_exec_hdr_flags -#define MY_exec_hdr_flags 0 -#endif - -#ifndef MY_backend_data - -#ifndef MY_text_includes_header -#define MY_text_includes_header 0 -#endif -#ifndef MY_add_dynamic_symbols -#define MY_add_dynamic_symbols 0 -#endif -#ifndef MY_add_one_symbol -#define MY_add_one_symbol 0 -#endif -#ifndef MY_link_dynamic_object -#define MY_link_dynamic_object 0 -#endif -#ifndef MY_write_dynamic_symbol -#define MY_write_dynamic_symbol 0 -#endif -#ifndef MY_check_dynamic_reloc -#define MY_check_dynamic_reloc 0 -#endif -#ifndef MY_finish_dynamic_link -#define MY_finish_dynamic_link 0 -#endif - -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - MY_text_includes_header, - MY_exec_hdr_flags, - 0, /* text vma? */ - MY_set_sizes, - 0, /* exec header is counted */ - MY_add_dynamic_symbols, - MY_add_one_symbol, - MY_link_dynamic_object, - MY_write_dynamic_symbol, - MY_check_dynamic_reloc, - MY_finish_dynamic_link -}; -#define MY_backend_data &MY(backend_data) -#endif - -#ifndef MY_final_link_callback - -/* Callback for the final_link routine to set the section offsets. */ - -static void MY_final_link_callback - PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); - -static void -MY_final_link_callback (abfd, ptreloff, pdreloff, psymoff) - bfd *abfd; - file_ptr *ptreloff; - file_ptr *pdreloff; - file_ptr *psymoff; -{ - struct internal_exec *execp = exec_hdr (abfd); - - *ptreloff = N_TRELOFF (*execp); - *pdreloff = N_DRELOFF (*execp); - *psymoff = N_SYMOFF (*execp); -} - -#endif - -#ifndef MY_bfd_final_link - -/* Final link routine. We need to use a call back to get the correct - offsets in the output file. */ - -static boolean -MY_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - return NAME(aout,final_link) (abfd, info, MY_final_link_callback); -} - -#endif - -/* We assume BFD generic archive files. */ -#ifndef MY_openr_next_archived_file -#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file -#endif -#ifndef MY_generic_stat_arch_elt -#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt -#endif -#ifndef MY_slurp_armap -#define MY_slurp_armap bfd_slurp_bsd_armap -#endif -#ifndef MY_slurp_extended_name_table -#define MY_slurp_extended_name_table _bfd_slurp_extended_name_table -#endif -#ifndef MY_write_armap -#define MY_write_armap bsd_write_armap -#endif -#ifndef MY_truncate_arname -#define MY_truncate_arname bfd_bsd_truncate_arname -#endif - -/* No core file defined here -- configure in trad-core.c separately. */ -#ifndef MY_core_file_failing_command -#define MY_core_file_failing_command _bfd_nocore_core_file_failing_command -#endif -#ifndef MY_core_file_failing_signal -#define MY_core_file_failing_signal _bfd_nocore_core_file_failing_signal -#endif -#ifndef MY_core_file_matches_executable_p -#define MY_core_file_matches_executable_p \ - _bfd_nocore_core_file_matches_executable_p -#endif -#ifndef MY_core_file_p -#define MY_core_file_p _bfd_dummy_target -#endif - -#ifndef MY_bfd_debug_info_start -#define MY_bfd_debug_info_start bfd_void -#endif -#ifndef MY_bfd_debug_info_end -#define MY_bfd_debug_info_end bfd_void -#endif -#ifndef MY_bfd_debug_info_accumulate -#define MY_bfd_debug_info_accumulate \ - (void (*) PARAMS ((bfd*, struct sec *))) bfd_void -#endif - -#ifndef MY_core_file_failing_command -#define MY_core_file_failing_command NAME(aout,core_file_failing_command) -#endif -#ifndef MY_core_file_failing_signal -#define MY_core_file_failing_signal NAME(aout,core_file_failing_signal) -#endif -#ifndef MY_core_file_matches_executable_p -#define MY_core_file_matches_executable_p NAME(aout,core_file_matches_executable_p) -#endif -#ifndef MY_set_section_contents -#define MY_set_section_contents NAME(aout,set_section_contents) -#endif -#ifndef MY_get_section_contents -#define MY_get_section_contents NAME(aout,get_section_contents) -#endif -#ifndef MY_new_section_hook -#define MY_new_section_hook NAME(aout,new_section_hook) -#endif -#ifndef MY_get_symtab_upper_bound -#define MY_get_symtab_upper_bound NAME(aout,get_symtab_upper_bound) -#endif -#ifndef MY_get_symtab -#define MY_get_symtab NAME(aout,get_symtab) -#endif -#ifndef MY_get_reloc_upper_bound -#define MY_get_reloc_upper_bound NAME(aout,get_reloc_upper_bound) -#endif -#ifndef MY_canonicalize_reloc -#define MY_canonicalize_reloc NAME(aout,canonicalize_reloc) -#endif -#ifndef MY_make_empty_symbol -#define MY_make_empty_symbol NAME(aout,make_empty_symbol) -#endif -#ifndef MY_print_symbol -#define MY_print_symbol NAME(aout,print_symbol) -#endif -#ifndef MY_get_symbol_info -#define MY_get_symbol_info NAME(aout,get_symbol_info) -#endif -#ifndef MY_get_lineno -#define MY_get_lineno NAME(aout,get_lineno) -#endif -#ifndef MY_set_arch_mach -#define MY_set_arch_mach NAME(aout,set_arch_mach) -#endif -#ifndef MY_find_nearest_line -#define MY_find_nearest_line NAME(aout,find_nearest_line) -#endif -#ifndef MY_sizeof_headers -#define MY_sizeof_headers NAME(aout,sizeof_headers) -#endif -#ifndef MY_bfd_get_relocated_section_contents -#define MY_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#endif -#ifndef MY_bfd_relax_section -#define MY_bfd_relax_section bfd_generic_relax_section -#endif -#ifndef MY_bfd_reloc_type_lookup -#define MY_bfd_reloc_type_lookup NAME(aout,reloc_type_lookup) -#endif -#ifndef MY_bfd_make_debug_symbol -#define MY_bfd_make_debug_symbol 0 -#endif -#ifndef MY_bfd_link_hash_table_create -#define MY_bfd_link_hash_table_create NAME(aout,link_hash_table_create) -#endif -#ifndef MY_bfd_link_add_symbols -#define MY_bfd_link_add_symbols NAME(aout,link_add_symbols) -#endif - -#ifndef MY_bfd_copy_private_bfd_data -#define MY_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data -#endif - -#ifndef MY_bfd_is_local_label -#define MY_bfd_is_local_label bfd_generic_is_local_label -#endif - -#ifndef MY_bfd_free_cached_info -#define MY_bfd_free_cached_info NAME(aout,bfd_free_cached_info) -#endif - -#ifndef MY_close_and_cleanup -#define MY_close_and_cleanup MY_bfd_free_cached_info -#endif - -#ifndef MY_get_dynamic_symtab_upper_bound -#define MY_get_dynamic_symtab_upper_bound \ - _bfd_nodynamic_get_dynamic_symtab_upper_bound -#endif -#ifndef MY_canonicalize_dynamic_symtab -#define MY_canonicalize_dynamic_symtab \ - _bfd_nodynamic_canonicalize_dynamic_symtab -#endif -#ifndef MY_get_dynamic_reloc_upper_bound -#define MY_get_dynamic_reloc_upper_bound \ - _bfd_nodynamic_get_dynamic_reloc_upper_bound -#endif -#ifndef MY_canonicalize_dynamic_reloc -#define MY_canonicalize_dynamic_reloc \ - _bfd_nodynamic_canonicalize_dynamic_reloc -#endif - -/* Aout symbols normally have leading underscores */ -#ifndef MY_symbol_leading_char -#define MY_symbol_leading_char '_' -#endif - -/* Aout archives normally use spaces for padding */ -#ifndef AR_PAD_CHAR -#define AR_PAD_CHAR ' ' -#endif - -#ifndef MY_BFD_TARGET -const bfd_target MY(vec) = -{ - TARGETNAME, /* name */ - bfd_target_aout_flavour, -#ifdef TARGET_IS_BIG_ENDIAN_P - true, /* target byte order (big) */ - true, /* target headers byte order (big) */ -#else - false, /* target byte order (little) */ - false, /* target headers byte order (little) */ -#endif - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - MY_symbol_leading_char, - AR_PAD_CHAR, /* ar_pad_char */ - 15, /* ar_max_namelen */ - 3, /* minimum alignment */ -#ifdef TARGET_IS_BIG_ENDIAN_P - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ -#else - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ -#endif - {_bfd_dummy_target, MY_object_p, /* bfd_check_format */ - bfd_generic_archive_p, MY_core_file_p}, - {bfd_false, MY_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, MY_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (MY), - BFD_JUMP_TABLE_COPY (MY), - BFD_JUMP_TABLE_CORE (MY), - BFD_JUMP_TABLE_ARCHIVE (MY), - BFD_JUMP_TABLE_SYMBOLS (MY), - BFD_JUMP_TABLE_RELOCS (MY), - BFD_JUMP_TABLE_WRITE (MY), - BFD_JUMP_TABLE_LINK (MY), - BFD_JUMP_TABLE_DYNAMIC (MY), - - (PTR) MY_backend_data, -}; -#endif /* MY_BFD_TARGET */ diff --git a/gnu/usr.bin/gdb/bfd/aout32.c b/gnu/usr.bin/gdb/bfd/aout32.c deleted file mode 100644 index 294dc1d..0000000 --- a/gnu/usr.bin/gdb/bfd/aout32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* BFD back-end for 32-bit a.out files. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#define ARCH_SIZE 32 - -#include "aoutx.h" diff --git a/gnu/usr.bin/gdb/bfd/aoutx.h b/gnu/usr.bin/gdb/bfd/aoutx.h deleted file mode 100644 index 5afed7a..0000000 --- a/gnu/usr.bin/gdb/bfd/aoutx.h +++ /dev/null @@ -1,4994 +0,0 @@ -/* BFD semi-generic back-end for a.out binaries. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - a.out backends - - -DESCRIPTION - - BFD supports a number of different flavours of a.out format, - though the major differences are only the sizes of the - structures on disk, and the shape of the relocation - information. - - The support is split into a basic support file @file{aoutx.h} - and other files which derive functions from the base. One - derivation file is @file{aoutf1.h} (for a.out flavour 1), and - adds to the basic a.out functions support for sun3, sun4, 386 - and 29k a.out files, to create a target jump vector for a - specific target. - - This information is further split out into more specific files - for each machine, including @file{sunos.c} for sun3 and sun4, - @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a - demonstration of a 64 bit a.out format. - - The base file @file{aoutx.h} defines general mechanisms for - reading and writing records to and from disk and various - other methods which BFD requires. It is included by - @file{aout32.c} and @file{aout64.c} to form the names - <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc. - - As an example, this is what goes on to make the back end for a - sun4, from @file{aout32.c}: - -| #define ARCH_SIZE 32 -| #include "aoutx.h" - - Which exports names: - -| ... -| aout_32_canonicalize_reloc -| aout_32_find_nearest_line -| aout_32_get_lineno -| aout_32_get_reloc_upper_bound -| ... - - from @file{sunos.c}: - -| #define TARGET_NAME "a.out-sunos-big" -| #define VECNAME sunos_big_vec -| #include "aoutf1.h" - - requires all the names from @file{aout32.c}, and produces the jump vector - -| sunos_big_vec - - The file @file{host-aout.c} is a special case. It is for a large set - of hosts that use ``more or less standard'' a.out files, and - for which cross-debugging is not interesting. It uses the - standard 32-bit a.out support routines, but determines the - file offsets and addresses of the text, data, and BSS - sections, the machine architecture and machine type, and the - entry point address, in a host-dependent manner. Once these - values have been determined, generic code is used to handle - the object file. - - When porting it to run on a new system, you must supply: - -| HOST_PAGE_SIZE -| HOST_SEGMENT_SIZE -| HOST_MACHINE_ARCH (optional) -| HOST_MACHINE_MACHINE (optional) -| HOST_TEXT_START_ADDR -| HOST_STACK_END_ADDR - - in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These - values, plus the structures and macros defined in @file{a.out.h} on - your host system, will produce a BFD target that will access - ordinary a.out files on your host. To configure a new machine - to use @file{host-aout.c}, specify: - -| TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec -| TDEPFILES= host-aout.o trad-core.o - - in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in} - to use the - @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your - configuration is selected. - -*/ - -/* Some assumptions: - * Any BFD with D_PAGED set is ZMAGIC, and vice versa. - Doesn't matter what the setting of WP_TEXT is on output, but it'll - get set on input. - * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC. - * Any BFD with both flags clear is OMAGIC. - (Just want to make these explicit, so the conditions tested in this - file make sense if you're more familiar with a.out than with BFD.) */ - -#define KEEPIT flags -#define KEEPITTYPE int - -#include <string.h> /* For strchr and friends */ -#include "bfd.h" -#include <sysdep.h> -#include "bfdlink.h" - -#include "libaout.h" -#include "libbfd.h" -#include "aout/aout64.h" -#include "aout/stab_gnu.h" -#include "aout/ar.h" - -static boolean aout_get_external_symbols PARAMS ((bfd *)); -static boolean translate_from_native_sym_flags - PARAMS ((bfd *, aout_symbol_type *)); -static boolean translate_to_native_sym_flags - PARAMS ((bfd *, asymbol *, struct external_nlist *)); - -/* -SUBSECTION - Relocations - -DESCRIPTION - The file @file{aoutx.h} provides for both the @emph{standard} - and @emph{extended} forms of a.out relocation records. - - The standard records contain only an - address, a symbol index, and a type field. The extended records - (used on 29ks and sparcs) also have a full integer for an - addend. - -*/ -#ifndef CTOR_TABLE_RELOC_HOWTO -#define CTOR_TABLE_RELOC_IDX 2 -#define CTOR_TABLE_RELOC_HOWTO(BFD) ((obj_reloc_entry_size(BFD) == RELOC_EXT_SIZE \ - ? howto_table_ext : howto_table_std) \ - + CTOR_TABLE_RELOC_IDX) -#endif - -#ifndef MY_swap_std_reloc_in -#define MY_swap_std_reloc_in NAME(aout,swap_std_reloc_in) -#endif - -#ifndef MY_swap_std_reloc_out -#define MY_swap_std_reloc_out NAME(aout,swap_std_reloc_out) -#endif - -#define howto_table_ext NAME(aout,ext_howto_table) -#define howto_table_std NAME(aout,std_howto_table) - -reloc_howto_type howto_table_ext[] = -{ - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ - HOWTO(RELOC_8, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", false, 0,0x000000ff, false), - HOWTO(RELOC_16, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", false, 0,0x0000ffff, false), - HOWTO(RELOC_32, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", false, 0,0xffffffff, false), - HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, complain_overflow_signed,0,"DISP8", false, 0,0x000000ff, false), - HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, complain_overflow_signed,0,"DISP16", false, 0,0x0000ffff, false), - HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, complain_overflow_signed,0,"DISP32", false, 0,0xffffffff, false), - HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, complain_overflow_signed,0,"WDISP30", false, 0,0x3fffffff, false), - HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, complain_overflow_signed,0,"WDISP22", false, 0,0x003fffff, false), - HOWTO(RELOC_HI22, 10, 2, 22, false, 0, complain_overflow_bitfield,0,"HI22", false, 0,0x003fffff, false), - HOWTO(RELOC_22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"22", false, 0,0x003fffff, false), - HOWTO(RELOC_13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"13", false, 0,0x00001fff, false), - HOWTO(RELOC_LO10, 0, 2, 10, false, 0, complain_overflow_dont,0,"LO10", false, 0,0x000003ff, false), - HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false), - HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false), - HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, complain_overflow_bitfield,0,"BASE10", false, 0,0x0000ffff, false), - HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, complain_overflow_bitfield,0,"BASE13", false, 0,0x00001fff, false), - HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASE22", false, 0,0x00000000, false), - HOWTO(RELOC_PC10, 0, 2, 10, false, 0, complain_overflow_bitfield,0,"PC10", false, 0,0x000003ff, false), - HOWTO(RELOC_PC22, 0, 2, 22, false, 0, complain_overflow_bitfield,0,"PC22", false, 0,0x003fffff, false), - HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, complain_overflow_bitfield,0,"JMP_TBL", false, 0,0xffffffff, false), - HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, complain_overflow_bitfield,0,"SEGOFF16", false, 0,0x00000000, false), - HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"GLOB_DAT", false, 0,0x00000000, false), - HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_SLOT", false, 0,0x00000000, false), - HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false), -}; - -/* Convert standard reloc records to "arelent" format (incl byte swap). */ - -reloc_howto_type howto_table_std[] = { - /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */ -HOWTO( 0, 0, 0, 8, false, 0, complain_overflow_bitfield,0,"8", true, 0x000000ff,0x000000ff, false), -HOWTO( 1, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"16", true, 0x0000ffff,0x0000ffff, false), -HOWTO( 2, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"32", true, 0xffffffff,0xffffffff, false), -HOWTO( 3, 0, 4, 64, false, 0, complain_overflow_bitfield,0,"64", true, 0xdeaddead,0xdeaddead, false), -HOWTO( 4, 0, 0, 8, true, 0, complain_overflow_signed, 0,"DISP8", true, 0x000000ff,0x000000ff, false), -HOWTO( 5, 0, 1, 16, true, 0, complain_overflow_signed, 0,"DISP16", true, 0x0000ffff,0x0000ffff, false), -HOWTO( 6, 0, 2, 32, true, 0, complain_overflow_signed, 0,"DISP32", true, 0xffffffff,0xffffffff, false), -HOWTO( 7, 0, 4, 64, true, 0, complain_overflow_signed, 0,"DISP64", true, 0xfeedface,0xfeedface, false), -HOWTO( 8, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"GOT_REL", false, 0,0x00000000, false), -HOWTO( 9, 0, 1, 16, false, 0, complain_overflow_bitfield,0,"BASE16", false,0xffffffff,0xffffffff, false), -HOWTO(10, 0, 2, 32, false, 0, complain_overflow_bitfield,0,"BASE32", false,0xffffffff,0xffffffff, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, - HOWTO(16, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false, 0,0x00000000, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, - HOWTO(32, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"RELATIVE", false, 0,0x00000000, false), -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, -{ -1 }, - HOWTO(40, 0, 2, 0, false, 0, complain_overflow_bitfield,0,"BASEREL", false, 0,0x00000000, false), -}; - -#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0])) - -CONST struct reloc_howto_struct * -NAME(aout,reloc_type_lookup) (abfd,code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ -#define EXT(i,j) case i: return &howto_table_ext[j] -#define STD(i,j) case i: return &howto_table_std[j] - int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE; - if (code == BFD_RELOC_CTOR) - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 32: - code = BFD_RELOC_32; - break; - case 64: - code = BFD_RELOC_64; - break; - } - if (ext) - switch (code) - { - EXT (BFD_RELOC_32, 2); - EXT (BFD_RELOC_HI22, 8); - EXT (BFD_RELOC_LO10, 11); - EXT (BFD_RELOC_32_PCREL_S2, 6); - EXT (BFD_RELOC_SPARC_WDISP22, 7); - EXT (BFD_RELOC_SPARC13, 10); - EXT (BFD_RELOC_SPARC_BASE13, 15); - default: return (CONST struct reloc_howto_struct *) 0; - } - else - /* std relocs */ - switch (code) - { - STD (BFD_RELOC_16, 1); - STD (BFD_RELOC_32, 2); - STD (BFD_RELOC_8_PCREL, 4); - STD (BFD_RELOC_16_PCREL, 5); - STD (BFD_RELOC_32_PCREL, 6); - STD (BFD_RELOC_16_BASEREL, 9); - STD (BFD_RELOC_32_BASEREL, 10); - default: return (CONST struct reloc_howto_struct *) 0; - } -} - -/* -SUBSECTION - Internal entry points - -DESCRIPTION - @file{aoutx.h} exports several routines for accessing the - contents of an a.out file, which are gathered and exported in - turn by various format specific files (eg sunos.c). - -*/ - -/* -FUNCTION - aout_@var{size}_swap_exec_header_in - -SYNOPSIS - void aout_@var{size}_swap_exec_header_in, - (bfd *abfd, - struct external_exec *raw_bytes, - struct internal_exec *execp); - -DESCRIPTION - Swap the information in an executable header @var{raw_bytes} taken - from a raw byte stream memory image into the internal exec header - structure @var{execp}. -*/ - -#ifndef NAME_swap_exec_header_in -void -NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp) - bfd *abfd; - struct external_exec *raw_bytes; - struct internal_exec *execp; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* The internal_exec structure has some fields that are unused in this - configuration (IE for i960), so ensure that all such uninitialized - fields are zero'd out. There are places where two of these structs - are memcmp'd, and thus the contents do matter. */ - memset ((PTR) execp, 0, sizeof (struct internal_exec)); - /* Now fill in fields in the execp, from the bytes in the raw data. */ - execp->a_info = bfd_h_get_32 (abfd, bytes->e_info); - execp->a_text = GET_WORD (abfd, bytes->e_text); - execp->a_data = GET_WORD (abfd, bytes->e_data); - execp->a_bss = GET_WORD (abfd, bytes->e_bss); - execp->a_syms = GET_WORD (abfd, bytes->e_syms); - execp->a_entry = GET_WORD (abfd, bytes->e_entry); - execp->a_trsize = GET_WORD (abfd, bytes->e_trsize); - execp->a_drsize = GET_WORD (abfd, bytes->e_drsize); -} -#define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in) -#endif - -/* -FUNCTION - aout_@var{size}_swap_exec_header_out - -SYNOPSIS - void aout_@var{size}_swap_exec_header_out - (bfd *abfd, - struct internal_exec *execp, - struct external_exec *raw_bytes); - -DESCRIPTION - Swap the information in an internal exec header structure - @var{execp} into the buffer @var{raw_bytes} ready for writing to disk. -*/ -void -NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes) - bfd *abfd; - struct internal_exec *execp; - struct external_exec *raw_bytes; -{ - struct external_exec *bytes = (struct external_exec *)raw_bytes; - - /* Now fill in fields in the raw data, from the fields in the exec struct. */ - bfd_h_put_32 (abfd, execp->a_info , bytes->e_info); - PUT_WORD (abfd, execp->a_text , bytes->e_text); - PUT_WORD (abfd, execp->a_data , bytes->e_data); - PUT_WORD (abfd, execp->a_bss , bytes->e_bss); - PUT_WORD (abfd, execp->a_syms , bytes->e_syms); - PUT_WORD (abfd, execp->a_entry , bytes->e_entry); - PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize); - PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize); -} - -/* Make all the section for an a.out file. */ - -boolean -NAME(aout,make_sections) (abfd) - bfd *abfd; -{ - if (obj_textsec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".text") == (asection *) NULL) - return false; - if (obj_datasec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".data") == (asection *) NULL) - return false; - if (obj_bsssec (abfd) == (asection *) NULL - && bfd_make_section (abfd, ".bss") == (asection *) NULL) - return false; - return true; -} - -/* -FUNCTION - aout_@var{size}_some_aout_object_p - -SYNOPSIS - const bfd_target *aout_@var{size}_some_aout_object_p - (bfd *abfd, - const bfd_target *(*callback_to_real_object_p)()); - -DESCRIPTION - Some a.out variant thinks that the file open in @var{abfd} - checking is an a.out file. Do some more checking, and set up - for access if it really is. Call back to the calling - environment's "finish up" function just before returning, to - handle any last-minute setup. -*/ - -const bfd_target * -NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p) - bfd *abfd; - struct internal_exec *execp; - const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)); -{ - struct aout_data_struct *rawptr, *oldrawptr; - const bfd_target *result; - - rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct )); - if (rawptr == NULL) { - bfd_set_error (bfd_error_no_memory); - return 0; - } - - oldrawptr = abfd->tdata.aout_data; - abfd->tdata.aout_data = rawptr; - - /* Copy the contents of the old tdata struct. - In particular, we want the subformat, since for hpux it was set in - hp300hpux.c:swap_exec_header_in and will be used in - hp300hpux.c:callback. */ - if (oldrawptr != NULL) - *abfd->tdata.aout_data = *oldrawptr; - - abfd->tdata.aout_data->a.hdr = &rawptr->e; - *(abfd->tdata.aout_data->a.hdr) = *execp; /* Copy in the internal_exec struct */ - execp = abfd->tdata.aout_data->a.hdr; - - /* Set the file flags */ - abfd->flags = NO_FLAGS; - if (execp->a_drsize || execp->a_trsize) - abfd->flags |= HAS_RELOC; - /* Setting of EXEC_P has been deferred to the bottom of this function */ - if (execp->a_syms) - abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS; - if (N_DYNAMIC(*execp)) - abfd->flags |= DYNAMIC; - - if (N_MAGIC (*execp) == ZMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - } - else if (N_MAGIC (*execp) == QMAGIC) - { - abfd->flags |= D_PAGED | WP_TEXT; - adata (abfd).magic = z_magic; - adata (abfd).subformat = q_magic_format; - } - else if (N_MAGIC (*execp) == NMAGIC) - { - abfd->flags |= WP_TEXT; - adata (abfd).magic = n_magic; - } - else if (N_MAGIC (*execp) == OMAGIC - || N_MAGIC (*execp) == BMAGIC) - adata (abfd).magic = o_magic; - else - { - /* Should have been checked with N_BADMAG before this routine - was called. */ - abort (); - } - - bfd_get_start_address (abfd) = execp->a_entry; - - obj_aout_symbols (abfd) = (aout_symbol_type *)NULL; - bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist); - - /* The default relocation entry size is that of traditional V7 Unix. */ - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - - /* The default symbol entry size is that of traditional Unix. */ - obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE; - - obj_aout_external_syms (abfd) = NULL; - obj_aout_external_strings (abfd) = NULL; - obj_aout_sym_hashes (abfd) = NULL; - - if (! NAME(aout,make_sections) (abfd)) - return NULL; - - obj_datasec (abfd)->_raw_size = execp->a_data; - obj_bsssec (abfd)->_raw_size = execp->a_bss; - - obj_textsec (abfd)->flags = - (execp->a_trsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS)); - obj_datasec (abfd)->flags = - (execp->a_drsize != 0 - ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) - : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS)); - obj_bsssec (abfd)->flags = SEC_ALLOC; - -#ifdef THIS_IS_ONLY_DOCUMENTATION - /* The common code can't fill in these things because they depend - on either the start address of the text segment, the rounding - up of virtual addresses between segments, or the starting file - position of the text segment -- all of which varies among different - versions of a.out. */ - - /* Call back to the format-dependent code to fill in the rest of the - fields and do any further cleanup. Things that should be filled - in by the callback: */ - - struct exec *execp = exec_hdr (abfd); - - obj_textsec (abfd)->size = N_TXTSIZE(*execp); - obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp); - /* data and bss are already filled in since they're so standard */ - - /* The virtual memory addresses of the sections */ - obj_textsec (abfd)->vma = N_TXTADDR(*execp); - obj_datasec (abfd)->vma = N_DATADDR(*execp); - obj_bsssec (abfd)->vma = N_BSSADDR(*execp); - - /* The file offsets of the sections */ - obj_textsec (abfd)->filepos = N_TXTOFF(*execp); - obj_datasec (abfd)->filepos = N_DATOFF(*execp); - - /* The file offsets of the relocation info */ - obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); - obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); - - /* The file offsets of the string table and symbol table. */ - obj_str_filepos (abfd) = N_STROFF (*execp); - obj_sym_filepos (abfd) = N_SYMOFF (*execp); - - /* Determine the architecture and machine type of the object file. */ - switch (N_MACHTYPE (*exec_hdr (abfd))) { - default: - abfd->obj_arch = bfd_arch_obscure; - break; - } - - adata(abfd)->page_size = PAGE_SIZE; - adata(abfd)->segment_size = SEGMENT_SIZE; - adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE; - - return abfd->xvec; - - /* The architecture is encoded in various ways in various a.out variants, - or is not encoded at all in some of them. The relocation size depends - on the architecture and the a.out variant. Finally, the return value - is the bfd_target vector in use. If an error occurs, return zero and - set bfd_error to the appropriate error code. - - Formats such as b.out, which have additional fields in the a.out - header, should cope with them in this callback as well. */ -#endif /* DOCUMENTATION */ - - result = (*callback_to_real_object_p)(abfd); - -#if defined(MACH) || defined(STAT_FOR_EXEC) - /* The original heuristic doesn't work in some important cases. The - * a.out file has no information about the text start address. For - * files (like kernels) linked to non-standard addresses (ld -Ttext - * nnn) the entry point may not be between the default text start - * (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size - * This is not just a mach issue. Many kernels are loaded at non - * standard addresses. - */ - { - struct stat stat_buf; - if (abfd->iostream - && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0) - && ((stat_buf.st_mode & 0111) != 0)) - abfd->flags |= EXEC_P; - } -#else /* ! MACH */ - /* Now that the segment addresses have been worked out, take a better - guess at whether the file is executable. If the entry point - is within the text segment, assume it is. (This makes files - executable even if their entry point address is 0, as long as - their text starts at zero.) - - At some point we should probably break down and stat the file and - declare it executable if (one of) its 'x' bits are on... */ - if ((execp->a_entry >= obj_textsec(abfd)->vma) && - (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size)) - abfd->flags |= EXEC_P; -#endif /* MACH */ - if (result) - { -#if 0 /* These should be set correctly anyways. */ - abfd->sections = obj_textsec (abfd); - obj_textsec (abfd)->next = obj_datasec (abfd); - obj_datasec (abfd)->next = obj_bsssec (abfd); -#endif - } - else - { - free (rawptr); - abfd->tdata.aout_data = oldrawptr; - } - return result; -} - -/* -FUNCTION - aout_@var{size}_mkobject - -SYNOPSIS - boolean aout_@var{size}_mkobject, (bfd *abfd); - -DESCRIPTION - Initialize BFD @var{abfd} for use with a.out files. -*/ - -boolean -NAME(aout,mkobject) (abfd) - bfd *abfd; -{ - struct aout_data_struct *rawptr; - - bfd_set_error (bfd_error_system_call); - - /* Use an intermediate variable for clarity */ - rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct )); - - if (rawptr == NULL) { - bfd_set_error (bfd_error_no_memory); - return false; - } - - abfd->tdata.aout_data = rawptr; - exec_hdr (abfd) = &(rawptr->e); - - obj_textsec (abfd) = (asection *)NULL; - obj_datasec (abfd) = (asection *)NULL; - obj_bsssec (abfd) = (asection *)NULL; - - return true; -} - - -/* -FUNCTION - aout_@var{size}_machine_type - -SYNOPSIS - enum machine_type aout_@var{size}_machine_type - (enum bfd_architecture arch, - unsigned long machine)); - -DESCRIPTION - Keep track of machine architecture and machine type for - a.out's. Return the <<machine_type>> for a particular - architecture and machine, or <<M_UNKNOWN>> if that exact architecture - and machine can't be represented in a.out format. - - If the architecture is understood, machine type 0 (default) - is always understood. -*/ - -enum machine_type -NAME(aout,machine_type) (arch, machine, unknown) - enum bfd_architecture arch; - unsigned long machine; - boolean *unknown; -{ - enum machine_type arch_flags; - - arch_flags = M_UNKNOWN; - *unknown = true; - - switch (arch) { - case bfd_arch_sparc: - if (machine == 0) arch_flags = M_SPARC; - break; - - case bfd_arch_m68k: - switch (machine) { - case 0: arch_flags = M_68010; break; - case 68000: arch_flags = M_UNKNOWN; *unknown = false; break; - case 68010: arch_flags = M_68010; break; - case 68020: arch_flags = M_68020; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_i386: - if (machine == 0) arch_flags = M_386; - break; - - case bfd_arch_a29k: - if (machine == 0) arch_flags = M_29K; - break; - - case bfd_arch_mips: - switch (machine) { - case 0: - case 2000: - case 3000: arch_flags = M_MIPS1; break; - case 4000: - case 4400: - case 6000: arch_flags = M_MIPS2; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - case bfd_arch_ns32k: - switch (machine) { - case 0: arch_flags = M_NS32532; break; - case 32032: arch_flags = M_NS32032; break; - case 32532: arch_flags = M_NS32532; break; - default: arch_flags = M_UNKNOWN; break; - } - break; - - default: - arch_flags = M_UNKNOWN; - } - - if (arch_flags != M_UNKNOWN) - *unknown = false; - - return arch_flags; -} - - -/* -FUNCTION - aout_@var{size}_set_arch_mach - -SYNOPSIS - boolean aout_@var{size}_set_arch_mach, - (bfd *, - enum bfd_architecture arch, - unsigned long machine)); - -DESCRIPTION - Set the architecture and the machine of the BFD @var{abfd} to the - values @var{arch} and @var{machine}. Verify that @var{abfd}'s format - can support the architecture required. -*/ - -boolean -NAME(aout,set_arch_mach) (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch != bfd_arch_unknown) - { - boolean unknown; - - NAME(aout,machine_type) (arch, machine, &unknown); - if (unknown) - return false; - } - - /* Determine the size of a relocation entry */ - switch (arch) { - case bfd_arch_sparc: - case bfd_arch_a29k: - case bfd_arch_mips: - obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE; - break; - default: - obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; - break; - } - - return (*aout_backend_info(abfd)->set_sizes) (abfd); -} - -static void -adjust_o_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - file_ptr pos = adata (abfd).exec_bytes_size; - bfd_vma vma = 0; - int pad = 0; - - /* Text. */ - obj_textsec(abfd)->filepos = pos; - pos += obj_textsec(abfd)->_raw_size; - vma += obj_textsec(abfd)->_raw_size; - - /* Data. */ - if (!obj_datasec(abfd)->user_set_vma) - { -#if 0 /* ?? Does alignment in the file image really matter? */ - pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma; -#endif - obj_textsec(abfd)->_raw_size += pad; - pos += pad; - vma += pad; - obj_datasec(abfd)->vma = vma; - } - obj_datasec(abfd)->filepos = pos; - pos += obj_datasec(abfd)->_raw_size; - vma += obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - { -#if 0 - pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma; -#endif - obj_datasec(abfd)->_raw_size += pad; - pos += pad; - vma += pad; - obj_bsssec(abfd)->vma = vma; - } - obj_bsssec(abfd)->filepos = pos; - - /* Fix up the exec header. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - execp->a_data = obj_datasec(abfd)->_raw_size; - execp->a_bss = obj_bsssec(abfd)->_raw_size; - N_SET_MAGIC (*execp, OMAGIC); -} - -static void -adjust_z_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - bfd_size_type data_pad, text_pad; - file_ptr text_end; - CONST struct aout_backend_data *abdp; - int ztih; /* Nonzero if text includes exec header. */ - - abdp = aout_backend_info (abfd); - - /* Text. */ - ztih = (abdp != NULL - && (abdp->text_includes_header - || obj_aout_subformat (abfd) == q_magic_format)); - obj_textsec(abfd)->filepos = (ztih - ? adata(abfd).exec_bytes_size - : adata(abfd).zmagic_disk_block_size); - if (! obj_textsec(abfd)->user_set_vma) - /* ?? Do we really need to check for relocs here? */ - obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC) - ? 0 - : (ztih - ? (abdp->default_text_vma - + adata(abfd).exec_bytes_size) - : abdp->default_text_vma)); - /* Could take strange alignment of text section into account here? */ - - /* Find start of data. */ - if (ztih) - { - text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->_raw_size; - text_pad = BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; - } - else - { - /* Note that if page_size == zmagic_disk_block_size, then - filepos == page_size, and this case is the same as the ztih - case. */ - text_end = obj_textsec (abfd)->_raw_size; - text_pad = BFD_ALIGN (text_end, adata (abfd).page_size) - text_end; - text_end += obj_textsec (abfd)->filepos; - } - obj_textsec(abfd)->_raw_size += text_pad; - text_end += text_pad; - - /* Data. */ - if (!obj_datasec(abfd)->user_set_vma) - { - bfd_vma vma; - vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size; - obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size); - } - if (abdp && abdp->zmagic_mapped_contiguous) - { - text_pad = (obj_datasec(abfd)->vma - - obj_textsec(abfd)->vma - - obj_textsec(abfd)->_raw_size); - obj_textsec(abfd)->_raw_size += text_pad; - } - obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos - + obj_textsec(abfd)->_raw_size); - - /* Fix up exec header while we're at it. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted))) - execp->a_text += adata(abfd).exec_bytes_size; - if (obj_aout_subformat (abfd) == q_magic_format) - N_SET_MAGIC (*execp, QMAGIC); - else - N_SET_MAGIC (*execp, ZMAGIC); - - /* Spec says data section should be rounded up to page boundary. */ - obj_datasec(abfd)->_raw_size - = align_power (obj_datasec(abfd)->_raw_size, - obj_bsssec(abfd)->alignment_power); - execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size, - adata(abfd).page_size); - data_pad = execp->a_data - obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma - + obj_datasec(abfd)->_raw_size); - /* If the BSS immediately follows the data section and extra space - in the page is left after the data section, fudge data - in the header so that the bss section looks smaller by that - amount. We'll start the bss section there, and lie to the OS. - (Note that a linker script, as well as the above assignment, - could have explicitly set the BSS vma to immediately follow - the data section.) */ - if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power) - == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size) - execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 : - obj_bsssec(abfd)->_raw_size - data_pad; - else - execp->a_bss = obj_bsssec(abfd)->_raw_size; -} - -static void -adjust_n_magic (abfd, execp) - bfd *abfd; - struct internal_exec *execp; -{ - file_ptr pos = adata(abfd).exec_bytes_size; - bfd_vma vma = 0; - int pad; - - /* Text. */ - obj_textsec(abfd)->filepos = pos; - if (!obj_textsec(abfd)->user_set_vma) - obj_textsec(abfd)->vma = vma; - else - vma = obj_textsec(abfd)->vma; - pos += obj_textsec(abfd)->_raw_size; - vma += obj_textsec(abfd)->_raw_size; - - /* Data. */ - obj_datasec(abfd)->filepos = pos; - if (!obj_datasec(abfd)->user_set_vma) - obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size); - vma = obj_datasec(abfd)->vma; - - /* Since BSS follows data immediately, see if it needs alignment. */ - vma += obj_datasec(abfd)->_raw_size; - pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma; - obj_datasec(abfd)->_raw_size += pad; - pos += obj_datasec(abfd)->_raw_size; - - /* BSS. */ - if (!obj_bsssec(abfd)->user_set_vma) - obj_bsssec(abfd)->vma = vma; - else - vma = obj_bsssec(abfd)->vma; - - /* Fix up exec header. */ - execp->a_text = obj_textsec(abfd)->_raw_size; - execp->a_data = obj_datasec(abfd)->_raw_size; - execp->a_bss = obj_bsssec(abfd)->_raw_size; - N_SET_MAGIC (*execp, NMAGIC); -} - -boolean -NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end) - bfd *abfd; - bfd_size_type *text_size; - file_ptr *text_end; -{ - struct internal_exec *execp = exec_hdr (abfd); - - if (! NAME(aout,make_sections) (abfd)) - return false; - - if (adata(abfd).magic != undecided_magic) - return true; - - obj_textsec(abfd)->_raw_size = - align_power(obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->alignment_power); - - *text_size = obj_textsec (abfd)->_raw_size; - /* Rule (heuristic) for when to pad to a new page. Note that there - are (at least) two ways demand-paged (ZMAGIC) files have been - handled. Most Berkeley-based systems start the text segment at - (PAGE_SIZE). However, newer versions of SUNOS start the text - segment right after the exec header; the latter is counted in the - text segment size, and is paged in by the kernel with the rest of - the text. */ - - /* This perhaps isn't the right way to do this, but made it simpler for me - to understand enough to implement it. Better would probably be to go - right from BFD flags to alignment/positioning characteristics. But the - old code was sloppy enough about handling the flags, and had enough - other magic, that it was a little hard for me to understand. I think - I understand it better now, but I haven't time to do the cleanup this - minute. */ - - if (abfd->flags & D_PAGED) - /* Whether or not WP_TEXT is set -- let D_PAGED override. */ - adata(abfd).magic = z_magic; - else if (abfd->flags & WP_TEXT) - adata(abfd).magic = n_magic; - else - adata(abfd).magic = o_magic; - -#ifdef BFD_AOUT_DEBUG /* requires gcc2 */ -#if __GNUC__ >= 2 - fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n", - ({ char *str; - switch (adata(abfd).magic) { - case n_magic: str = "NMAGIC"; break; - case o_magic: str = "OMAGIC"; break; - case z_magic: str = "ZMAGIC"; break; - default: abort (); - } - str; - }), - obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->alignment_power, - obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, - obj_datasec(abfd)->alignment_power, - obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, - obj_bsssec(abfd)->alignment_power); -#endif -#endif - - switch (adata(abfd).magic) - { - case o_magic: - adjust_o_magic (abfd, execp); - break; - case z_magic: - adjust_z_magic (abfd, execp); - break; - case n_magic: - adjust_n_magic (abfd, execp); - break; - default: - abort (); - } - -#ifdef BFD_AOUT_DEBUG - fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n", - obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, - obj_textsec(abfd)->filepos, - obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, - obj_datasec(abfd)->filepos, - obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size); -#endif - - return true; -} - -/* -FUNCTION - aout_@var{size}_new_section_hook - -SYNOPSIS - boolean aout_@var{size}_new_section_hook, - (bfd *abfd, - asection *newsect)); - -DESCRIPTION - Called by the BFD in response to a @code{bfd_make_section} - request. -*/ -boolean -NAME(aout,new_section_hook) (abfd, newsect) - bfd *abfd; - asection *newsect; -{ - /* align to double at least */ - newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power; - - - if (bfd_get_format (abfd) == bfd_object) - { - if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) { - obj_textsec(abfd)= newsect; - newsect->target_index = N_TEXT; - return true; - } - - if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) { - obj_datasec(abfd) = newsect; - newsect->target_index = N_DATA; - return true; - } - - if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) { - obj_bsssec(abfd) = newsect; - newsect->target_index = N_BSS; - return true; - } - - } - - /* We allow more than three sections internally */ - return true; -} - -boolean -NAME(aout,set_section_contents) (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - file_ptr text_end; - bfd_size_type text_size; - - if (abfd->output_has_begun == false) - { - if (NAME(aout,adjust_sizes_and_vmas) (abfd, - &text_size, - &text_end) == false) - return false; - } - - /* regardless, once we know what we're doing, we might as well get going */ - if (section != obj_bsssec(abfd)) - { - if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0) - return false; - - if (count) { - return (bfd_write ((PTR)location, 1, count, abfd) == count) ? - true : false; - } - return true; - } - return true; -} - -/* Read the external symbols from an a.out file. */ - -static boolean -aout_get_external_symbols (abfd) - bfd *abfd; -{ - if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL) - { - bfd_size_type count; - struct external_nlist *syms; - - count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE; - - /* We allocate using malloc to make the values easy to free - later on. If we put them on the obstack it might not be - possible to free them. */ - syms = ((struct external_nlist *) - malloc ((size_t) count * EXTERNAL_NLIST_SIZE)); - if (syms == (struct external_nlist *) NULL && count != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0 - || (bfd_read (syms, 1, exec_hdr (abfd)->a_syms, abfd) - != exec_hdr (abfd)->a_syms)) - { - free (syms); - return false; - } - - obj_aout_external_syms (abfd) = syms; - obj_aout_external_sym_count (abfd) = count; - } - - if (obj_aout_external_strings (abfd) == NULL - && exec_hdr (abfd)->a_syms != 0) - { - unsigned char string_chars[BYTES_IN_WORD]; - bfd_size_type stringsize; - char *strings; - - /* Get the size of the strings. */ - if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0 - || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd) - != BYTES_IN_WORD)) - return false; - stringsize = GET_WORD (abfd, string_chars); - - strings = (char *) malloc ((size_t) stringsize + 1); - if (strings == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* Skip space for the string count in the buffer for convenience - when using indexes. */ - if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, - abfd) - != stringsize - BYTES_IN_WORD) - { - free (strings); - return false; - } - - /* Sanity preservation. */ - strings[stringsize] = '\0'; - - obj_aout_external_strings (abfd) = strings; - obj_aout_external_string_size (abfd) = stringsize; - } - - return true; -} - -/* Translate an a.out symbol into a BFD symbol. The desc, other, type - and symbol->value fields of CACHE_PTR will be set from the a.out - nlist structure. This function is responsible for setting - symbol->flags and symbol->section, and adjusting symbol->value. */ - -static boolean -translate_from_native_sym_flags (abfd, cache_ptr) - bfd *abfd; - aout_symbol_type *cache_ptr; -{ - flagword visible; - - if ((cache_ptr->type & N_STAB) != 0 - || cache_ptr->type == N_FN) - { - asection *sec; - - /* This is a debugging symbol. */ - - cache_ptr->symbol.flags = BSF_DEBUGGING; - - /* Work out the symbol section. */ - switch (cache_ptr->type & N_TYPE) - { - case N_TEXT: - case N_FN: - sec = obj_textsec (abfd); - break; - case N_DATA: - sec = obj_datasec (abfd); - break; - case N_BSS: - sec = obj_bsssec (abfd); - break; - default: - case N_ABS: - sec = bfd_abs_section_ptr; - break; - } - - cache_ptr->symbol.section = sec; - cache_ptr->symbol.value -= sec->vma; - - return true; - } - - /* Get the default visibility. This does not apply to all types, so - we just hold it in a local variable to use if wanted. */ - if ((cache_ptr->type & N_EXT) == 0) - visible = BSF_LOCAL; - else - visible = BSF_GLOBAL; - - switch (cache_ptr->type) - { - default: - case N_ABS: case N_ABS | N_EXT: - cache_ptr->symbol.section = bfd_abs_section_ptr; - cache_ptr->symbol.flags = visible; - break; - - case N_UNDF | N_EXT: - if (cache_ptr->symbol.value != 0) - { - /* This is a common symbol. */ - cache_ptr->symbol.flags = BSF_GLOBAL; - cache_ptr->symbol.section = bfd_com_section_ptr; - } - else - { - cache_ptr->symbol.flags = 0; - cache_ptr->symbol.section = bfd_und_section_ptr; - } - break; - - case N_TEXT: case N_TEXT | N_EXT: - cache_ptr->symbol.section = obj_textsec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - /* N_SETV symbols used to represent set vectors placed in the - data section. They are no longer generated. Theoretically, - it was possible to extract the entries and combine them with - new ones, although I don't know if that was ever actually - done. Unless that feature is restored, treat them as data - symbols. */ - case N_SETV: case N_SETV | N_EXT: - case N_DATA: case N_DATA | N_EXT: - cache_ptr->symbol.section = obj_datasec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - case N_BSS: case N_BSS | N_EXT: - cache_ptr->symbol.section = obj_bsssec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = visible; - break; - - case N_SETA: case N_SETA | N_EXT: - case N_SETT: case N_SETT | N_EXT: - case N_SETD: case N_SETD | N_EXT: - case N_SETB: case N_SETB | N_EXT: - { - asection *section; - arelent_chain *reloc; - asection *into_section; - - /* This is a set symbol. The name of the symbol is the name - of the set (e.g., __CTOR_LIST__). The value of the symbol - is the value to add to the set. We create a section with - the same name as the symbol, and add a reloc to insert the - appropriate value into the section. - - This action is actually obsolete; it used to make the - linker do the right thing, but the linker no longer uses - this function. */ - - section = bfd_get_section_by_name (abfd, cache_ptr->symbol.name); - if (section == NULL) - { - char *copy; - - copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1); - if (copy == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - strcpy (copy, cache_ptr->symbol.name); - section = bfd_make_section (abfd, copy); - if (section == NULL) - return false; - } - - reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain)); - if (reloc == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* Build a relocation entry for the constructor. */ - switch (cache_ptr->type & N_TYPE) - { - case N_SETA: - into_section = bfd_abs_section_ptr; - cache_ptr->type = N_ABS; - break; - case N_SETT: - into_section = obj_textsec (abfd); - cache_ptr->type = N_TEXT; - break; - case N_SETD: - into_section = obj_datasec (abfd); - cache_ptr->type = N_DATA; - break; - case N_SETB: - into_section = obj_bsssec (abfd); - cache_ptr->type = N_BSS; - break; - } - - /* Build a relocation pointing into the constructor section - pointing at the symbol in the set vector specified. */ - reloc->relent.addend = cache_ptr->symbol.value; - cache_ptr->symbol.section = into_section; - reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr; - - /* We modify the symbol to belong to a section depending upon - the name of the symbol, and add to the size of the section - to contain a pointer to the symbol. Build a reloc entry to - relocate to this symbol attached to this section. */ - section->flags = SEC_CONSTRUCTOR | SEC_RELOC; - - section->reloc_count++; - section->alignment_power = 2; - - reloc->next = section->constructor_chain; - section->constructor_chain = reloc; - reloc->relent.address = section->_raw_size; - section->_raw_size += BYTES_IN_WORD; - - reloc->relent.howto = CTOR_TABLE_RELOC_HOWTO(abfd); - - cache_ptr->symbol.flags |= BSF_CONSTRUCTOR; - } - break; - - case N_WARNING: - /* This symbol is the text of a warning message. The next - symbol is the symbol to associate the warning with. If a - reference is made to that symbol, a warning is issued. */ - cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING; - - /* @@ Stuffing pointers into integers is a no-no. We can - usually get away with it if the integer is large enough - though. */ - if (sizeof (cache_ptr + 1) > sizeof (bfd_vma)) - abort (); - cache_ptr->symbol.value = (bfd_vma) (cache_ptr + 1); - - cache_ptr->symbol.section = bfd_abs_section_ptr; - - break; - - case N_INDR: case N_INDR | N_EXT: - /* An indirect symbol. This consists of two symbols in a row. - The first symbol is the name of the indirection. The second - symbol is the name of the target. A reference to the first - symbol becomes a reference to the second. */ - cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible; - - /* @@ Stuffing pointers into integers is a no-no. We can - usually get away with it if the integer is large enough - though. */ - if (sizeof (cache_ptr + 1) > sizeof (bfd_vma)) - abort (); - cache_ptr->symbol.value = (bfd_vma) (cache_ptr + 1); - - cache_ptr->symbol.section = bfd_ind_section_ptr; - - break; - - case N_WEAKU: - cache_ptr->symbol.section = bfd_und_section_ptr; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKA: - cache_ptr->symbol.section = bfd_abs_section_ptr; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKT: - cache_ptr->symbol.section = obj_textsec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKD: - cache_ptr->symbol.section = obj_datasec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - - case N_WEAKB: - cache_ptr->symbol.section = obj_bsssec (abfd); - cache_ptr->symbol.value -= cache_ptr->symbol.section->vma; - cache_ptr->symbol.flags = BSF_WEAK; - break; - } - - return true; -} - -/* Set the fields of SYM_POINTER according to CACHE_PTR. */ - -static boolean -translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer) - bfd *abfd; - asymbol *cache_ptr; - struct external_nlist *sym_pointer; -{ - bfd_vma value = cache_ptr->value; - - /* Mask out any existing type bits in case copying from one section - to another. */ - sym_pointer->e_type[0] &= ~N_TYPE; - - if (bfd_is_abs_section (bfd_get_section (cache_ptr))) - sym_pointer->e_type[0] |= N_ABS; - else if (bfd_get_section (cache_ptr) == obj_textsec (abfd) - || (bfd_get_section (cache_ptr)->output_section - == obj_textsec (abfd))) - sym_pointer->e_type[0] |= N_TEXT; - else if (bfd_get_section (cache_ptr) == obj_datasec (abfd) - || (bfd_get_section (cache_ptr)->output_section - == obj_datasec (abfd))) - sym_pointer->e_type[0] |= N_DATA; - else if (bfd_get_section (cache_ptr) == obj_bsssec (abfd) - || (bfd_get_section (cache_ptr)->output_section - == obj_bsssec (abfd))) - sym_pointer->e_type[0] |= N_BSS; - else if (bfd_get_section (cache_ptr) == NULL) - { - /* Protect the bfd_is_com_section call. This case occurs, e.g., - for the *DEBUG* section of a COFF file. */ - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - else if (bfd_is_und_section (bfd_get_section (cache_ptr))) - sym_pointer->e_type[0] = N_UNDF | N_EXT; - else if (bfd_is_ind_section (bfd_get_section (cache_ptr))) - sym_pointer->e_type[0] = N_INDR; - else if (bfd_is_com_section (bfd_get_section (cache_ptr))) - sym_pointer->e_type[0] = N_UNDF | N_EXT; - else - { - bfd_set_error (bfd_error_nonrepresentable_section); - return false; - } - - /* Turn the symbol from section relative to absolute again */ - value += cache_ptr->section->vma; - - if ((cache_ptr->flags & BSF_WARNING) != 0) - sym_pointer->e_type[0] = N_WARNING; - - if ((cache_ptr->flags & BSF_DEBUGGING) != 0) - sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type; - else if ((cache_ptr->flags & BSF_GLOBAL) != 0) - sym_pointer->e_type[0] |= N_EXT; - - if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0) - { - int type = ((aout_symbol_type *) cache_ptr)->type; - switch (type) - { - case N_ABS: type = N_SETA; break; - case N_TEXT: type = N_SETT; break; - case N_DATA: type = N_SETD; break; - case N_BSS: type = N_SETB; break; - } - sym_pointer->e_type[0] = type; - } - - if ((cache_ptr->flags & BSF_WEAK) != 0) - { - int type; - - switch (sym_pointer->e_type[0] & N_TYPE) - { - default: - case N_ABS: type = N_WEAKA; break; - case N_TEXT: type = N_WEAKT; break; - case N_DATA: type = N_WEAKD; break; - case N_BSS: type = N_WEAKB; break; - case N_UNDF: type = N_WEAKU; break; - } - sym_pointer->e_type[0] = type; - } - - PUT_WORD(abfd, value, sym_pointer->e_value); - - return true; -} - -/* Native-level interface to symbols. */ - -asymbol * -NAME(aout,make_empty_symbol) (abfd) - bfd *abfd; -{ - aout_symbol_type *new = - (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type)); - if (!new) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - new->symbol.the_bfd = abfd; - - return &new->symbol; -} - -/* Translate a set of internal symbols into external symbols. */ - -boolean -NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic) - bfd *abfd; - aout_symbol_type *in; - struct external_nlist *ext; - bfd_size_type count; - char *str; - bfd_size_type strsize; - boolean dynamic; -{ - struct external_nlist *ext_end; - - ext_end = ext + count; - for (; ext < ext_end; ext++, in++) - { - bfd_vma x; - - x = GET_WORD (abfd, ext->e_strx); - in->symbol.the_bfd = abfd; - - /* For the normal symbols, the zero index points at the number - of bytes in the string table but is to be interpreted as the - null string. For the dynamic symbols, the number of bytes in - the string table is stored in the __DYNAMIC structure and the - zero index points at an actual string. */ - if (x == 0 && ! dynamic) - in->symbol.name = ""; - else if (x < strsize) - in->symbol.name = str + x; - else - return false; - - in->symbol.value = GET_SWORD (abfd, ext->e_value); - in->desc = bfd_h_get_16 (abfd, ext->e_desc); - in->other = bfd_h_get_8 (abfd, ext->e_other); - in->type = bfd_h_get_8 (abfd, ext->e_type); - in->symbol.udata = 0; - - if (! translate_from_native_sym_flags (abfd, in)) - return false; - - if (dynamic) - in->symbol.flags |= BSF_DYNAMIC; - } - - return true; -} - -/* We read the symbols into a buffer, which is discarded when this - function exits. We read the strings into a buffer large enough to - hold them all plus all the cached symbol entries. */ - -boolean -NAME(aout,slurp_symbol_table) (abfd) - bfd *abfd; -{ - struct external_nlist *old_external_syms; - aout_symbol_type *cached; - size_t cached_size; - - /* If there's no work to be done, don't do any */ - if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL) - return true; - - old_external_syms = obj_aout_external_syms (abfd); - - if (! aout_get_external_symbols (abfd)) - return false; - - if (obj_aout_external_sym_count (abfd) == 0) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - cached_size = (obj_aout_external_sym_count (abfd) - * sizeof (aout_symbol_type)); - cached = (aout_symbol_type *) malloc (cached_size); - if (cached == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (cached, 0, cached_size); - - /* Convert from external symbol information to internal. */ - if (! (NAME(aout,translate_symbol_table) - (abfd, cached, - obj_aout_external_syms (abfd), - obj_aout_external_sym_count (abfd), - obj_aout_external_strings (abfd), - obj_aout_external_string_size (abfd), - false))) - { - free (cached); - return false; - } - - bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd); - - obj_aout_symbols (abfd) = cached; - - /* It is very likely that anybody who calls this function will not - want the external symbol information, so if it was allocated - because of our call to aout_get_external_symbols, we free it up - right away to save space. */ - if (old_external_syms == (struct external_nlist *) NULL - && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) - { - free (obj_aout_external_syms (abfd)); - obj_aout_external_syms (abfd) = NULL; - } - - return true; -} - -/* We use a hash table when writing out symbols so that we only write - out a particular string once. This helps particularly when the - linker writes out stabs debugging entries, because each different - contributing object file tends to have many duplicate stabs - strings. - - Possible improvements: - + look for strings matching trailing substrings of other strings - + better data structures? balanced trees? - + look at reducing memory use elsewhere -- maybe if we didn't have - to construct the entire symbol table at once, we could get by - with smaller amounts of VM? (What effect does that have on the - string table reductions?) - - This hash table code breaks dbx on SunOS 4.1.3, so we don't do it - if BFD_TRADITIONAL_FORMAT is set. */ - -/* An entry in the strtab hash table. */ - -struct strtab_hash_entry -{ - struct bfd_hash_entry root; - /* Index in string table. */ - bfd_size_type index; - /* Next string in strtab. */ - struct strtab_hash_entry *next; -}; - -/* The strtab hash table. */ - -struct strtab_hash -{ - struct bfd_hash_table table; - /* Size of strtab--also next available index. */ - bfd_size_type size; - /* First string in strtab. */ - struct strtab_hash_entry *first; - /* Last string in strtab. */ - struct strtab_hash_entry *last; -}; - -static struct bfd_hash_entry *strtab_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean stringtab_init PARAMS ((struct strtab_hash *)); -static bfd_size_type add_to_stringtab - PARAMS ((bfd *, struct strtab_hash *, const char *, boolean)); -static boolean emit_stringtab PARAMS ((bfd *, struct strtab_hash *)); - -/* Routine to create an entry in a strtab. */ - -static struct bfd_hash_entry * -strtab_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct strtab_hash_entry *) NULL) - ret = ((struct strtab_hash_entry *) - bfd_hash_allocate (table, sizeof (struct strtab_hash_entry))); - if (ret == (struct strtab_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct strtab_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->index = (bfd_size_type) -1; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in an strtab. */ - -#define strtab_hash_lookup(t, string, create, copy) \ - ((struct strtab_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Create a new strtab. */ - -static boolean -stringtab_init (table) - struct strtab_hash *table; -{ - if (! bfd_hash_table_init (&table->table, strtab_hash_newfunc)) - return false; - - /* Leave space for the size of the string table. */ - table->size = BYTES_IN_WORD; - - table->first = NULL; - table->last = NULL; - - return true; -} - -/* Free a strtab. */ - -#define stringtab_free(tab) bfd_hash_table_free (&(tab)->table) - -/* Get the index of a string in a strtab, adding it if it is not - already present. If HASH is false, we don't really use the hash - table, and we don't eliminate duplicate strings. */ - -static INLINE bfd_size_type -add_to_stringtab (abfd, tab, str, copy) - bfd *abfd; - struct strtab_hash *tab; - const char *str; - boolean copy; -{ - register struct strtab_hash_entry *entry; - - /* An index of 0 always means the empty string. */ - if (*str == '\0') - return 0; - - if ((abfd->flags & BFD_TRADITIONAL_FORMAT) == 0) - { - entry = strtab_hash_lookup (tab, str, true, copy); - if (entry == NULL) - return (bfd_size_type) -1; - } - else - { - entry = ((struct strtab_hash_entry *) - bfd_hash_allocate (&tab->table, - sizeof (struct strtab_hash_entry))); - if (entry == NULL) - return (bfd_size_type) -1; - if (! copy) - entry->root.string = str; - else - { - char *n; - - n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1); - if (n == NULL) - return (bfd_size_type) -1; - entry->root.string = n; - } - entry->index = (bfd_size_type) -1; - entry->next = NULL; - } - - if (entry->index == (bfd_size_type) -1) - { - entry->index = tab->size; - tab->size += strlen (str) + 1; - if (tab->first == NULL) - tab->first = entry; - else - tab->last->next = entry; - tab->last = entry; - } - - return entry->index; -} - -/* Write out a strtab. ABFD is already at the right location in the - file. */ - -static boolean -emit_stringtab (abfd, tab) - register bfd *abfd; - struct strtab_hash *tab; -{ - bfd_byte buffer[BYTES_IN_WORD]; - register struct strtab_hash_entry *entry; - - PUT_WORD (abfd, tab->size, buffer); - if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD) - return false; - - for (entry = tab->first; entry != NULL; entry = entry->next) - { - register const char *str; - register size_t len; - - str = entry->root.string; - len = strlen (str) + 1; - if (bfd_write ((PTR) str, 1, len, abfd) != len) - return false; - } - - return true; -} - -boolean -NAME(aout,write_syms) (abfd) - bfd *abfd; -{ - unsigned int count ; - asymbol **generic = bfd_get_outsymbols (abfd); - struct strtab_hash strtab; - - if (! stringtab_init (&strtab)) - return false; - - for (count = 0; count < bfd_get_symcount (abfd); count++) - { - asymbol *g = generic[count]; - bfd_size_type indx; - struct external_nlist nsp; - - indx = add_to_stringtab (abfd, &strtab, g->name, false); - if (indx == (bfd_size_type) -1) - goto error_return; - PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx); - - if (bfd_asymbol_flavour(g) == abfd->xvec->flavour) - { - bfd_h_put_16(abfd, aout_symbol(g)->desc, nsp.e_desc); - bfd_h_put_8(abfd, aout_symbol(g)->other, nsp.e_other); - bfd_h_put_8(abfd, aout_symbol(g)->type, nsp.e_type); - } - else - { - bfd_h_put_16(abfd,0, nsp.e_desc); - bfd_h_put_8(abfd, 0, nsp.e_other); - bfd_h_put_8(abfd, 0, nsp.e_type); - } - - if (! translate_to_native_sym_flags (abfd, g, &nsp)) - goto error_return; - - if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd) - != EXTERNAL_NLIST_SIZE) - goto error_return; - - /* NB: `KEEPIT' currently overlays `flags', so set this only - here, at the end. */ - g->KEEPIT = count; - } - - if (! emit_stringtab (abfd, &strtab)) - goto error_return; - - stringtab_free (&strtab); - - return true; - -error_return: - stringtab_free (&strtab); - return false; -} - - -long -NAME(aout,get_symtab) (abfd, location) - bfd *abfd; - asymbol **location; -{ - unsigned int counter = 0; - aout_symbol_type *symbase; - - if (!NAME(aout,slurp_symbol_table)(abfd)) - return -1; - - for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);) - *(location++) = (asymbol *)( symbase++); - *location++ =0; - return bfd_get_symcount (abfd); -} - - -/* Standard reloc stuff */ -/* Output standard relocation information to a file in target byte order. */ - -void -NAME(aout,swap_std_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - struct reloc_std_external *natptr; -{ - int r_index; - asymbol *sym = *(g->sym_ptr_ptr); - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - asection *output_section = sym->section->output_section; - - PUT_WORD(abfd, g->address, natptr->r_address); - - r_length = g->howto->size ; /* Size as a power of two */ - r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */ - /* XXX This relies on relocs coming from a.out files. */ - r_baserel = (g->howto->type & 8) != 0; - r_jmptable = (g->howto->type & 16) != 0; - r_relative = (g->howto->type & 32) != 0; - -#if 0 - /* For a standard reloc, the addend is in the object file. */ - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; -#endif - - /* name was clobbered by aout_write_syms to be symbol index */ - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here - */ - - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - /* Fill in symbol */ - r_extern = 1; - r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT); - - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (abfd->xvec->header_byteorder_big_p != false) { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0) - | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0) - | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0) - | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG); - } else { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0) - | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0) - | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0) - | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0) - | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE); - } -} - - -/* Extended stuff */ -/* Output extended relocation information to a file in target byte order. */ - -void -NAME(aout,swap_ext_reloc_out) (abfd, g, natptr) - bfd *abfd; - arelent *g; - register struct reloc_ext_external *natptr; -{ - int r_index; - int r_extern; - unsigned int r_type; - unsigned int r_addend; - asymbol *sym = *(g->sym_ptr_ptr); - asection *output_section = sym->section->output_section; - - PUT_WORD (abfd, g->address, natptr->r_address); - - r_type = (unsigned int) g->howto->type; - - r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma; - - /* If this relocation is relative to a symbol then set the - r_index to the symbols index, and the r_extern bit. - - Absolute symbols can come in in two ways, either as an offset - from the abs section, or as a symbol which has an abs value. - check for that here. */ - - if (bfd_is_com_section (output_section) - || bfd_is_abs_section (output_section) - || bfd_is_und_section (output_section)) - { - if (bfd_abs_section_ptr->symbol == sym) - { - /* Whoops, looked like an abs symbol, but is really an offset - from the abs section */ - r_index = 0; - r_extern = 0; - } - else - { - r_extern = 1; - r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT); - } - } - else - { - /* Just an ordinary section */ - r_extern = 0; - r_index = output_section->target_index; - } - - /* now the fun stuff */ - if (abfd->xvec->header_byteorder_big_p != false) { - natptr->r_index[0] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[2] = r_index; - natptr->r_type[0] = - ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG)); - } else { - natptr->r_index[2] = r_index >> 16; - natptr->r_index[1] = r_index >> 8; - natptr->r_index[0] = r_index; - natptr->r_type[0] = - (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0) - | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (abfd, r_addend, natptr->r_addend); -} - -/* BFD deals internally with all things based from the section they're - in. so, something in 10 bytes into a text section with a base of - 50 would have a symbol (.text+10) and know .text vma was 50. - - Aout keeps all it's symbols based from zero, so the symbol would - contain 60. This macro subs the base of each section from the value - to give the true offset from the section */ - - -#define MOVE_ADDRESS(ad) \ - if (r_extern) { \ - /* undefined symbol */ \ - cache_ptr->sym_ptr_ptr = symbols + r_index; \ - cache_ptr->addend = ad; \ - } else { \ - /* defined, section relative. replace symbol with pointer to \ - symbol which points to section */ \ - switch (r_index) { \ - case N_TEXT: \ - case N_TEXT | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->textsec->vma; \ - break; \ - case N_DATA: \ - case N_DATA | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->datasec->vma; \ - break; \ - case N_BSS: \ - case N_BSS | N_EXT: \ - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; \ - cache_ptr->addend = ad - su->bsssec->vma; \ - break; \ - default: \ - case N_ABS: \ - case N_ABS | N_EXT: \ - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \ - cache_ptr->addend = ad; \ - break; \ - } \ - } \ - -void -NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols) - bfd *abfd; - struct reloc_ext_external *bytes; - arelent *cache_ptr; - asymbol **symbols; -{ - int r_index; - int r_extern; - unsigned int r_type; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - - cache_ptr->address = (GET_SWORD (abfd, bytes->r_address)); - - /* now the fun stuff */ - if (abfd->xvec->header_byteorder_big_p != false) { - r_index = (bytes->r_index[0] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[2]; - r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG; - } else { - r_index = (bytes->r_index[2] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[0]; - r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE; - } - - cache_ptr->howto = howto_table_ext + r_type; - MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend)); -} - -void -NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols) - bfd *abfd; - struct reloc_std_external *bytes; - arelent *cache_ptr; - asymbol **symbols; -{ - int r_index; - int r_extern; - unsigned int r_length; - int r_pcrel; - int r_baserel, r_jmptable, r_relative; - struct aoutdata *su = &(abfd->tdata.aout_data->a); - int howto_idx; - - cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address); - - /* now the fun stuff */ - if (abfd->xvec->header_byteorder_big_p != false) { - r_index = (bytes->r_index[0] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[2]; - r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG; - } else { - r_index = (bytes->r_index[2] << 16) - | (bytes->r_index[1] << 8) - | bytes->r_index[0]; - r_extern = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); - r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); - r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE)); - r_length = (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE; - } - - howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel - + 16 * r_jmptable + 32 * r_relative; - BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std)); - cache_ptr->howto = howto_table_std + howto_idx; - BFD_ASSERT (cache_ptr->howto->type != -1); - - MOVE_ADDRESS(0); -} - -/* Read and swap the relocs for a section. */ - -boolean -NAME(aout,slurp_reloc_table) (abfd, asect, symbols) - bfd *abfd; - sec_ptr asect; - asymbol **symbols; -{ - unsigned int count; - bfd_size_type reloc_size; - PTR relocs; - arelent *reloc_cache; - size_t each_size; - unsigned int counter = 0; - arelent *cache_ptr; - - if (asect->relocation) - return true; - - if (asect->flags & SEC_CONSTRUCTOR) - return true; - - if (asect == obj_datasec (abfd)) - reloc_size = exec_hdr(abfd)->a_drsize; - else if (asect == obj_textsec (abfd)) - reloc_size = exec_hdr(abfd)->a_trsize; - else if (asect == obj_bsssec (abfd)) - reloc_size = 0; - else - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0) - return false; - - each_size = obj_reloc_entry_size (abfd); - - count = reloc_size / each_size; - - reloc_cache = (arelent *) malloc ((size_t) (count * sizeof (arelent))); - if (reloc_cache == NULL && count != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (reloc_cache, 0, count * sizeof (arelent)); - - relocs = malloc (reloc_size); - if (relocs == NULL && reloc_size != 0) - { - free (reloc_cache); - bfd_set_error (bfd_error_no_memory); - return false; - } - - if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) - { - free (relocs); - free (reloc_cache); - return false; - } - - cache_ptr = reloc_cache; - if (each_size == RELOC_EXT_SIZE) - { - register struct reloc_ext_external *rptr = - (struct reloc_ext_external *) relocs; - - for (; counter < count; counter++, rptr++, cache_ptr++) - NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols); - } - else - { - register struct reloc_std_external *rptr = - (struct reloc_std_external *) relocs; - - for (; counter < count; counter++, rptr++, cache_ptr++) - MY_swap_std_reloc_in(abfd, rptr, cache_ptr, symbols); - } - - free (relocs); - - asect->relocation = reloc_cache; - asect->reloc_count = cache_ptr - reloc_cache; - - return true; -} - -/* Write out a relocation section into an object file. */ - -boolean -NAME(aout,squirt_out_relocs) (abfd, section) - bfd *abfd; - asection *section; -{ - arelent **generic; - unsigned char *native, *natptr; - size_t each_size; - - unsigned int count = section->reloc_count; - size_t natsize; - - if (count == 0) return true; - - each_size = obj_reloc_entry_size (abfd); - natsize = each_size * count; - native = (unsigned char *) bfd_zalloc (abfd, natsize); - if (!native) { - bfd_set_error (bfd_error_no_memory); - return false; - } - - generic = section->orelocation; - - if (each_size == RELOC_EXT_SIZE) - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr); - } - else - { - for (natptr = native; - count != 0; - --count, natptr += each_size, ++generic) - MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr); - } - - if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { - bfd_release(abfd, native); - return false; - } - bfd_release (abfd, native); - - return true; -} - -/* This is stupid. This function should be a boolean predicate */ -long -NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count; - - if (section == obj_bsssec (abfd)) - { - *relptr = NULL; - return 0; - } - - if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols))) - return -1; - - if (section->flags & SEC_CONSTRUCTOR) { - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count ++) { - *relptr ++ = &chain->relent; - chain = chain->next; - } - } - else { - tblptr = section->relocation; - - for (count = 0; count++ < section->reloc_count;) - { - *relptr++ = tblptr++; - } - } - *relptr = 0; - - return section->reloc_count; -} - -long -NAME(aout,get_reloc_upper_bound) (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format (abfd) != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - if (asect->flags & SEC_CONSTRUCTOR) { - return (sizeof (arelent *) * (asect->reloc_count+1)); - } - - if (asect == obj_datasec (abfd)) - return (sizeof (arelent *) - * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd)) - + 1)); - - if (asect == obj_textsec (abfd)) - return (sizeof (arelent *) - * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd)) - + 1)); - - if (asect == obj_bsssec (abfd)) - return sizeof (arelent *); - - if (asect == obj_bsssec (abfd)) - return 0; - - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - - -long -NAME(aout,get_symtab_upper_bound) (abfd) - bfd *abfd; -{ - if (!NAME(aout,slurp_symbol_table)(abfd)) - return -1; - - return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *)); -} - -/*ARGSUSED*/ - alent * -NAME(aout,get_lineno) (ignore_abfd, ignore_symbol) - bfd *ignore_abfd; - asymbol *ignore_symbol; -{ -return (alent *)NULL; -} - -/*ARGSUSED*/ -void -NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); - - if (ret->type == '?') - { - int type_code = aout_symbol(symbol)->type & 0xff; - CONST char *stab_name = aout_stab_name(type_code); - static char buf[10]; - - if (stab_name == NULL) - { - sprintf(buf, "(%d)", type_code); - stab_name = buf; - } - ret->type = '-'; - ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff); - ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff); - ret->stab_name = stab_name; - } -} - -/*ARGSUSED*/ -void -NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *)afile; - - switch (how) { - case bfd_print_symbol_name: - if (symbol->name) - fprintf(file,"%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff), - (unsigned)(aout_symbol(symbol)->other & 0xff), - (unsigned)(aout_symbol(symbol)->type)); - break; - case bfd_print_symbol_all: - { - CONST char *section_name = symbol->section->name; - - - bfd_print_symbol_vandf((PTR)file,symbol); - - fprintf(file," %-5s %04x %02x %02x", - section_name, - (unsigned)(aout_symbol(symbol)->desc & 0xffff), - (unsigned)(aout_symbol(symbol)->other & 0xff), - (unsigned)(aout_symbol(symbol)->type & 0xff)); - if (symbol->name) - fprintf(file," %s", symbol->name); - } - break; - } -} - -/* - provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. -*/ - -boolean -NAME(aout,find_nearest_line) - (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - /* Run down the file looking for the filename, function and linenumber */ - asymbol **p; - static char buffer[100]; - static char filename_buffer[200]; - CONST char *directory_name = NULL; - CONST char *main_file_name = NULL; - CONST char *current_file_name = NULL; - CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */ - bfd_vma high_line_vma = ~0; - bfd_vma low_func_vma = 0; - asymbol *func = 0; - *filename_ptr = abfd->filename; - *functionname_ptr = 0; - *line_ptr = 0; - if (symbols != (asymbol **)NULL) { - for (p = symbols; *p; p++) { - aout_symbol_type *q = (aout_symbol_type *)(*p); - next: - switch (q->type){ - case N_SO: - main_file_name = current_file_name = q->symbol.name; - /* Look ahead to next symbol to check if that too is an N_SO. */ - p++; - if (*p == NULL) - break; - q = (aout_symbol_type *)(*p); - if (q->type != (int)N_SO) - goto next; - - /* Found a second N_SO First is directory; second is filename. */ - directory_name = current_file_name; - main_file_name = current_file_name = q->symbol.name; - if (obj_textsec(abfd) != section) - goto done; - break; - case N_SOL: - current_file_name = q->symbol.name; - break; - - case N_SLINE: - - case N_DSLINE: - case N_BSLINE: - /* We'll keep this if it resolves nearer than the one we have already */ - if (q->symbol.value >= offset && - q->symbol.value < high_line_vma) { - *line_ptr = q->desc; - high_line_vma = q->symbol.value; - line_file_name = current_file_name; - } - break; - case N_FUN: - { - /* We'll keep this if it is nearer than the one we have already */ - if (q->symbol.value >= low_func_vma && - q->symbol.value <= offset) { - low_func_vma = q->symbol.value; - func = (asymbol *)q; - } - if (*line_ptr && func) { - CONST char *function = func->name; - char *p; - - /* The caller expects a symbol name. We actually have a - function name, without the leading underscore. Put the - underscore back in, so that the caller gets a symbol - name. */ - if (bfd_get_symbol_leading_char (abfd) == '\0') - strncpy (buffer, function, sizeof (buffer) - 1); - else - { - buffer[0] = bfd_get_symbol_leading_char (abfd); - strncpy (buffer + 1, function, sizeof (buffer) - 2); - } - buffer[sizeof(buffer)-1] = 0; - /* Have to remove : stuff */ - p = strchr(buffer,':'); - if (p != NULL) { *p = '\0'; } - *functionname_ptr = buffer; - goto done; - - } - } - break; - } - } - } - - done: - if (*line_ptr) - main_file_name = line_file_name; - if (main_file_name) { - if (main_file_name[0] == '/' || directory_name == NULL) - *filename_ptr = main_file_name; - else { - sprintf(filename_buffer, "%.140s%.50s", - directory_name, main_file_name); - *filename_ptr = filename_buffer; - } - } - return true; - -} - -/*ARGSUSED*/ -int -NAME(aout,sizeof_headers) (abfd, execable) - bfd *abfd; - boolean execable; -{ - return adata(abfd).exec_bytes_size; -} - -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ - -boolean -NAME(aout,bfd_free_cached_info) (abfd) - bfd *abfd; -{ - asection *o; - - if (bfd_get_format (abfd) != bfd_object) - return true; - -#define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; } - BFCI_FREE (obj_aout_symbols (abfd)); - BFCI_FREE (obj_aout_external_syms (abfd)); - BFCI_FREE (obj_aout_external_strings (abfd)); - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - BFCI_FREE (o->relocation); -#undef BFCI_FREE - - return true; -} - -/* a.out link code. */ - -static boolean aout_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean aout_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *)); -static boolean aout_link_free_symbols PARAMS ((bfd *)); -static boolean aout_link_check_ar_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean aout_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Routine to create an entry in an a.out link hash table. */ - -struct bfd_hash_entry * -NAME(aout,link_hash_newfunc) (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct aout_link_hash_entry *) NULL) - ret = ((struct aout_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry))); - if (ret == (struct aout_link_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_hash_entry *) ret; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct aout_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret) - { - /* Set local fields. */ - ret->written = false; - ret->indx = -1; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize an a.out link hash table. */ - -boolean -NAME(aout,link_hash_table_init) (table, abfd, newfunc) - struct aout_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create an a.out link hash table. */ - -struct bfd_link_hash_table * -NAME(aout,link_hash_table_create) (abfd) - bfd *abfd; -{ - struct aout_link_hash_table *ret; - - ret = ((struct aout_link_hash_table *) - malloc (sizeof (struct aout_link_hash_table))); - if (ret == (struct aout_link_hash_table *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_link_hash_table *) NULL; - } - if (! NAME(aout,link_hash_table_init) (ret, abfd, - NAME(aout,link_hash_newfunc))) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Given an a.out BFD, add symbols to the global hash table as - appropriate. */ - -boolean -NAME(aout,link_add_symbols) (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return aout_link_add_object_symbols (abfd, info); - case bfd_archive: - return _bfd_generic_link_add_archive_symbols - (abfd, info, aout_link_check_archive_element); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from an a.out object file. */ - -static boolean -aout_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - if (! aout_get_external_symbols (abfd)) - return false; - if (! aout_link_add_symbols (abfd, info)) - return false; - if (! info->keep_memory) - { - if (! aout_link_free_symbols (abfd)) - return false; - } - return true; -} - -/* Check a single archive element to see if we need to include it in - the link. *PNEEDED is set according to whether this element is - needed in the link or not. This is called from - _bfd_generic_link_add_archive_symbols. */ - -static boolean -aout_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - if (! aout_get_external_symbols (abfd)) - return false; - - if (! aout_link_check_ar_symbols (abfd, info, pneeded)) - return false; - - if (*pneeded) - { - if (! aout_link_add_symbols (abfd, info)) - return false; - } - - /* We keep around the symbols even if we aren't going to use this - object file, because we may want to reread it. This doesn't - waste too much memory, because it isn't all that common to read - an archive element but not need it. */ - if (! info->keep_memory) - { - if (! aout_link_free_symbols (abfd)) - return false; - } - - return true; -} - -/* Free up the internal symbols read from an a.out file. */ - -static boolean -aout_link_free_symbols (abfd) - bfd *abfd; -{ - if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL) - { - free ((PTR) obj_aout_external_syms (abfd)); - obj_aout_external_syms (abfd) = (struct external_nlist *) NULL; - } - if (obj_aout_external_strings (abfd) != (char *) NULL) - { - free ((PTR) obj_aout_external_strings (abfd)); - obj_aout_external_strings (abfd) = (char *) NULL; - } - return true; -} - -/* Look through the internal symbols to see if this object file should - be included in the link. We should include this object file if it - defines any symbols which are currently undefined. If this object - file defines a common symbol, then we may adjust the size of the - known symbol but we do not include the object file in the link - (unless there is some other reason to include it). */ - -static boolean -aout_link_check_ar_symbols (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - register struct external_nlist *p; - struct external_nlist *pend; - char *strings; - - *pneeded = false; - - /* Look through all the symbols. */ - p = obj_aout_external_syms (abfd); - pend = p + obj_aout_external_sym_count (abfd); - strings = obj_aout_external_strings (abfd); - for (; p < pend; p++) - { - int type = bfd_h_get_8 (abfd, p->e_type); - const char *name; - struct bfd_link_hash_entry *h; - - /* Ignore symbols that are not externally visible. This is an - optimization only, as we check the type more thoroughly - below. */ - if (((type & N_EXT) == 0 - || (type & N_STAB) != 0 - || type == N_FN) - && type != N_WEAKA - && type != N_WEAKT - && type != N_WEAKD - && type != N_WEAKB) - { - if (type == N_WARNING - || type == N_INDR) - ++p; - continue; - } - - name = strings + GET_WORD (abfd, p->e_strx); - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* We are only interested in symbols that are currently - undefined or common. */ - if (h == (struct bfd_link_hash_entry *) NULL - || (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common)) - { - if (type == (N_INDR | N_EXT)) - ++p; - continue; - } - - if (type == (N_TEXT | N_EXT) - || type == (N_DATA | N_EXT) - || type == (N_BSS | N_EXT) - || type == (N_ABS | N_EXT) - || type == (N_INDR | N_EXT)) - { - /* This object file defines this symbol. We must link it - in. This is true regardless of whether the current - definition of the symbol is undefined or common. If the - current definition is common, we have a case in which we - have already seen an object file including - int a; - and this object file from the archive includes - int a = 5; - In such a case we must include this object file. - - FIXME: The SunOS 4.1.3 linker will pull in the archive - element if the symbol is defined in the .data section, - but not if it is defined in the .text section. That - seems a bit crazy to me, and I haven't implemented it. - However, it might be correct. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - - if (type == (N_UNDF | N_EXT)) - { - bfd_vma value; - - value = GET_WORD (abfd, p->e_value); - if (value != 0) - { - /* This symbol is common in the object from the archive - file. */ - if (h->type == bfd_link_hash_undefined) - { - bfd *symbfd; - - symbfd = h->u.undef.abfd; - if (symbfd == (bfd *) NULL) - { - /* This symbol was created as undefined from - outside BFD. We assume that we should link - in the object file. This is done for the -u - option in the linker. */ - if (! (*info->callbacks->add_archive_element) (info, - abfd, - name)) - return false; - *pneeded = true; - return true; - } - /* Turn the current link symbol into a common - symbol. It is already on the undefs list. */ - h->type = bfd_link_hash_common; - h->u.c.size = value; - h->u.c.section = bfd_make_section_old_way (symbfd, - "COMMON"); - } - else - { - /* Adjust the size of the common symbol if - necessary. */ - if (value > h->u.c.size) - h->u.c.size = value; - } - } - } - - if (type == N_WEAKA - || type == N_WEAKT - || type == N_WEAKD - || type == N_WEAKB) - { - /* This symbol is weak but defined. We must pull it in if - the current link symbol is undefined, but we don't want - it if the current link symbol is common. */ - if (h->type == bfd_link_hash_undefined) - { - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - return false; - *pneeded = true; - return true; - } - } - } - - /* We do not need this object file. */ - return true; -} - -/* Add all symbols from an object file to the hash table. */ - -static boolean -aout_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *, - const char *, flagword, asection *, - bfd_vma, const char *, boolean, - boolean, - struct bfd_link_hash_entry **)); - bfd_size_type sym_count; - char *strings; - boolean copy; - struct aout_link_hash_entry **sym_hash; - register struct external_nlist *p; - struct external_nlist *pend; - - sym_count = obj_aout_external_sym_count (abfd); - strings = obj_aout_external_strings (abfd); - if (info->keep_memory) - copy = false; - else - copy = true; - - /* We keep a list of the linker hash table entries that correspond - to particular symbols. We could just look them up in the hash - table, but keeping the list is more efficient. Perhaps this - should be conditional on info->keep_memory. */ - sym_hash = ((struct aout_link_hash_entry **) - bfd_alloc (abfd, - ((size_t) sym_count - * sizeof (struct aout_link_hash_entry *)))); - if (sym_hash == NULL && sym_count != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - obj_aout_sym_hashes (abfd) = sym_hash; - - if ((abfd->flags & DYNAMIC) != 0 - && aout_backend_info (abfd)->add_dynamic_symbols != NULL) - { - if (! (*aout_backend_info (abfd)->add_dynamic_symbols) (abfd, info)) - return false; - } - - add_one_symbol = aout_backend_info (abfd)->add_one_symbol; - if (add_one_symbol == NULL) - add_one_symbol = _bfd_generic_link_add_one_symbol; - - p = obj_aout_external_syms (abfd); - pend = p + sym_count; - for (; p < pend; p++, sym_hash++) - { - int type; - const char *name; - bfd_vma value; - asection *section; - flagword flags; - const char *string; - - *sym_hash = NULL; - - type = bfd_h_get_8 (abfd, p->e_type); - - /* Ignore debugging symbols. */ - if ((type & N_STAB) != 0) - continue; - - name = strings + GET_WORD (abfd, p->e_strx); - value = GET_WORD (abfd, p->e_value); - flags = BSF_GLOBAL; - string = NULL; - switch (type) - { - default: - abort (); - - case N_UNDF: - case N_ABS: - case N_TEXT: - case N_DATA: - case N_BSS: - case N_FN_SEQ: - case N_COMM: - case N_SETV: - case N_FN: - /* Ignore symbols that are not externally visible. */ - continue; - case N_INDR: - /* Ignore local indirect symbol. */ - ++p; - ++sym_hash; - continue; - - case N_UNDF | N_EXT: - if (value == 0) - { - section = bfd_und_section_ptr; - flags = 0; - } - else - section = bfd_com_section_ptr; - break; - case N_ABS | N_EXT: - section = bfd_abs_section_ptr; - break; - case N_TEXT | N_EXT: - section = obj_textsec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_DATA | N_EXT: - case N_SETV | N_EXT: - /* Treat N_SETV symbols as N_DATA symbol; see comment in - translate_from_native_sym_flags. */ - section = obj_datasec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_BSS | N_EXT: - section = obj_bsssec (abfd); - value -= bfd_get_section_vma (abfd, section); - break; - case N_INDR | N_EXT: - /* An indirect symbol. The next symbol is the symbol - which this one really is. */ - BFD_ASSERT (p + 1 < pend); - ++p; - string = strings + GET_WORD (abfd, p->e_strx); - section = bfd_ind_section_ptr; - flags |= BSF_INDIRECT; - break; - case N_COMM | N_EXT: - section = bfd_com_section_ptr; - break; - case N_SETA: case N_SETA | N_EXT: - section = bfd_abs_section_ptr; - flags |= BSF_CONSTRUCTOR; - break; - case N_SETT: case N_SETT | N_EXT: - section = obj_textsec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_SETD: case N_SETD | N_EXT: - section = obj_datasec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_SETB: case N_SETB | N_EXT: - section = obj_bsssec (abfd); - flags |= BSF_CONSTRUCTOR; - value -= bfd_get_section_vma (abfd, section); - break; - case N_WARNING: - /* A warning symbol. The next symbol is the one to warn - about. */ - BFD_ASSERT (p + 1 < pend); - ++p; - string = name; - name = strings + GET_WORD (abfd, p->e_strx); - section = bfd_und_section_ptr; - flags |= BSF_WARNING; - break; - case N_WEAKU: - section = bfd_und_section_ptr; - flags = BSF_WEAK; - break; - case N_WEAKA: - section = bfd_abs_section_ptr; - flags = BSF_WEAK; - break; - case N_WEAKT: - section = obj_textsec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - case N_WEAKD: - section = obj_datasec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - case N_WEAKB: - section = obj_bsssec (abfd); - value -= bfd_get_section_vma (abfd, section); - flags = BSF_WEAK; - break; - } - - if (! ((*add_one_symbol) - (info, abfd, name, flags, section, value, string, copy, false, - (struct bfd_link_hash_entry **) sym_hash))) - return false; - - if (type == (N_INDR | N_EXT) || type == N_WARNING) - ++sym_hash; - } - - return true; -} - -/* During the final link step we need to pass around a bunch of - information, so we do it in an instance of this structure. */ - -struct aout_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output bfd. */ - bfd *output_bfd; - /* Reloc file positions. */ - file_ptr treloff, dreloff; - /* File position of symbols. */ - file_ptr symoff; - /* String table. */ - struct strtab_hash strtab; -}; - -static boolean aout_link_input_bfd - PARAMS ((struct aout_final_link_info *, bfd *input_bfd)); -static boolean aout_link_write_symbols - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map)); -static boolean aout_link_write_other_symbol - PARAMS ((struct aout_link_hash_entry *, PTR)); -static boolean aout_link_input_section - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, file_ptr *reloff_ptr, - bfd_size_type rel_size, int *symbol_map)); -static boolean aout_link_input_section_std - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, struct reloc_std_external *, - bfd_size_type rel_size, bfd_byte *contents, int *symbol_map)); -static boolean aout_link_input_section_ext - PARAMS ((struct aout_final_link_info *, bfd *input_bfd, - asection *input_section, struct reloc_ext_external *, - bfd_size_type rel_size, bfd_byte *contents, int *symbol_map)); -static INLINE asection *aout_reloc_index_to_section - PARAMS ((bfd *, int)); -static boolean aout_link_reloc_link_order - PARAMS ((struct aout_final_link_info *, asection *, - struct bfd_link_order *)); - -/* Do the final link step. This is called on the output BFD. The - INFO structure should point to a list of BFDs linked through the - link_next field which can be used to find each BFD which takes part - in the output. Also, each section in ABFD should point to a list - of bfd_link_order structures which list all the input sections for - the output section. */ - -boolean -NAME(aout,final_link) (abfd, info, callback) - bfd *abfd; - struct bfd_link_info *info; - void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *)); -{ - struct aout_final_link_info aout_info; - register bfd *sub; - bfd_size_type text_size; - file_ptr text_end; - register struct bfd_link_order *p; - asection *o; - boolean have_link_order_relocs; - - aout_info.info = info; - aout_info.output_bfd = abfd; - - if (! info->relocateable) - { - exec_hdr (abfd)->a_trsize = 0; - exec_hdr (abfd)->a_drsize = 0; - } - else - { - bfd_size_type trsize, drsize; - - /* Count up the relocation sizes. */ - trsize = 0; - drsize = 0; - for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) - { - if (bfd_get_flavour (sub) == bfd_target_aout_flavour) - { - trsize += exec_hdr (sub)->a_trsize; - drsize += exec_hdr (sub)->a_drsize; - } - else - { - /* FIXME: We need to identify the .text and .data sections - and call get_reloc_upper_bound and canonicalize_reloc to - work out the number of relocs needed, and then multiply - by the reloc size. */ - abort (); - } - } - if (obj_textsec (abfd) != (asection *) NULL) - trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd) - ->link_order_head) - * obj_reloc_entry_size (abfd)); - exec_hdr (abfd)->a_trsize = trsize; - if (obj_datasec (abfd) != (asection *) NULL) - drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd) - ->link_order_head) - * obj_reloc_entry_size (abfd)); - exec_hdr (abfd)->a_drsize = drsize; - } - - exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd); - - /* Adjust the section sizes and vmas according to the magic number. - This sets a_text, a_data and a_bss in the exec_hdr and sets the - filepos for each section. */ - if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end)) - return false; - - /* The relocation and symbol file positions differ among a.out - targets. We are passed a callback routine from the backend - specific code to handle this. - FIXME: At this point we do not know how much space the symbol - table will require. This will not work for any (nonstandard) - a.out target that needs to know the symbol table size before it - can compute the relocation file positions. This may or may not - be the case for the hp300hpux target, for example. */ - (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff, - &aout_info.symoff); - obj_textsec (abfd)->rel_filepos = aout_info.treloff; - obj_datasec (abfd)->rel_filepos = aout_info.dreloff; - obj_sym_filepos (abfd) = aout_info.symoff; - - /* We keep a count of the symbols as we output them. */ - obj_aout_external_sym_count (abfd) = 0; - - /* We accumulate the string table as we write out the symbols. */ - if (! stringtab_init (&aout_info.strtab)) - return false; - - /* The most time efficient way to do the link would be to read all - the input object files into memory and then sort out the - information into the output file. Unfortunately, that will - probably use too much memory. Another method would be to step - through everything that composes the text section and write it - out, and then everything that composes the data section and write - it out, and then write out the relocs, and then write out the - symbols. Unfortunately, that requires reading stuff from each - input file several times, and we will not be able to keep all the - input files open simultaneously, and reopening them will be slow. - - What we do is basically process one input file at a time. We do - everything we need to do with an input file once--copy over the - section contents, handle the relocation information, and write - out the symbols--and then we throw away the information we read - from it. This approach requires a lot of lseeks of the output - file, which is unfortunate but still faster than reopening a lot - of files. - - We use the output_has_begun field of the input BFDs to see - whether we have already handled it. */ - for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) - sub->output_has_begun = false; - - have_link_order_relocs = false; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_aout_flavour)) - { - bfd *input_bfd; - - input_bfd = p->u.indirect.section->owner; - if (! input_bfd->output_has_begun) - { - if (! aout_link_input_bfd (&aout_info, input_bfd)) - return false; - input_bfd->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - /* These are handled below. */ - have_link_order_relocs = true; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; - } - } - } - - /* Write out any symbols that we have not already written out. */ - aout_link_hash_traverse (aout_hash_table (info), - aout_link_write_other_symbol, - (PTR) &aout_info); - - /* Now handle any relocs we were asked to create by the linker. - These did not come from any input file. We must do these after - we have written out all the symbols, so that we know the symbol - indices to use. */ - if (have_link_order_relocs) - { - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! aout_link_reloc_link_order (&aout_info, o, p)) - return false; - } - } - } - } - - /* Finish up any dynamic linking we may be doing. */ - if (aout_backend_info (abfd)->finish_dynamic_link != NULL) - { - if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info)) - return false; - } - - /* Update the header information. */ - abfd->symcount = obj_aout_external_sym_count (abfd); - exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE; - obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms; - obj_textsec (abfd)->reloc_count = - exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd); - obj_datasec (abfd)->reloc_count = - exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd); - - /* Write out the string table. */ - if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0) - return false; - return emit_stringtab (abfd, &aout_info.strtab); -} - -/* Link an a.out input BFD into the output file. */ - -static boolean -aout_link_input_bfd (finfo, input_bfd) - struct aout_final_link_info *finfo; - bfd *input_bfd; -{ - bfd_size_type sym_count; - int *symbol_map = NULL; - - BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object); - - /* If this is a dynamic object, it may need special handling. */ - if ((input_bfd->flags & DYNAMIC) != 0 - && aout_backend_info (input_bfd)->link_dynamic_object != NULL) - { - return ((*aout_backend_info (input_bfd)->link_dynamic_object) - (finfo->info, input_bfd)); - } - - /* Get the symbols. We probably have them already, unless - finfo->info->keep_memory is false. */ - if (! aout_get_external_symbols (input_bfd)) - return false; - - sym_count = obj_aout_external_sym_count (input_bfd); - symbol_map = (int *) malloc ((size_t) sym_count * sizeof (int)); - if (symbol_map == NULL && sym_count != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* Write out the symbols and get a map of the new indices. */ - if (! aout_link_write_symbols (finfo, input_bfd, symbol_map)) - goto error_return; - - /* Relocate and write out the sections. */ - if (! aout_link_input_section (finfo, input_bfd, - obj_textsec (input_bfd), - &finfo->treloff, - exec_hdr (input_bfd)->a_trsize, - symbol_map) - || ! aout_link_input_section (finfo, input_bfd, - obj_datasec (input_bfd), - &finfo->dreloff, - exec_hdr (input_bfd)->a_drsize, - symbol_map)) - goto error_return; - - /* If we are not keeping memory, we don't need the symbols any - longer. We still need them if we are keeping memory, because the - strings in the hash table point into them. */ - if (! finfo->info->keep_memory) - { - if (! aout_link_free_symbols (input_bfd)) - goto error_return; - } - - if (symbol_map != NULL) - free (symbol_map); - return true; - error_return: - if (symbol_map != NULL) - free (symbol_map); - return false; -} - -/* Adjust and write out the symbols for an a.out file. Set the new - symbol indices into a symbol_map. */ - -static boolean -aout_link_write_symbols (finfo, input_bfd, symbol_map) - struct aout_final_link_info *finfo; - bfd *input_bfd; - int *symbol_map; -{ - bfd *output_bfd; - bfd_size_type sym_count; - char *strings; - enum bfd_link_strip strip; - enum bfd_link_discard discard; - struct external_nlist *output_syms = NULL; - struct external_nlist *outsym; - bfd_size_type strtab_index; - register struct external_nlist *sym; - struct external_nlist *sym_end; - struct aout_link_hash_entry **sym_hash; - boolean pass; - boolean skip_indirect; - - output_bfd = finfo->output_bfd; - sym_count = obj_aout_external_sym_count (input_bfd); - strings = obj_aout_external_strings (input_bfd); - strip = finfo->info->strip; - discard = finfo->info->discard; - output_syms = ((struct external_nlist *) - malloc ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE)); - if (output_syms == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - outsym = output_syms; - - /* First write out a symbol for this object file, unless we are - discarding such symbols. */ - if (strip != strip_all - && (strip != strip_some - || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename, - false, false) != NULL) - && discard != discard_all) - { - bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type); - bfd_h_put_8 (output_bfd, 0, outsym->e_other); - bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc); - strtab_index = add_to_stringtab (output_bfd, &finfo->strtab, - input_bfd->filename, false); - if (strtab_index == (bfd_size_type) -1) - goto error_return; - PUT_WORD (output_bfd, strtab_index, outsym->e_strx); - PUT_WORD (output_bfd, - (bfd_get_section_vma (output_bfd, - obj_textsec (input_bfd)->output_section) - + obj_textsec (input_bfd)->output_offset), - outsym->e_value); - ++obj_aout_external_sym_count (output_bfd); - ++outsym; - } - - pass = false; - skip_indirect = false; - sym = obj_aout_external_syms (input_bfd); - sym_end = sym + sym_count; - sym_hash = obj_aout_sym_hashes (input_bfd); - for (; sym < sym_end; sym++, sym_hash++, symbol_map++) - { - const char *name; - int type; - struct aout_link_hash_entry *h; - boolean skip; - asection *symsec; - bfd_vma val = 0; - boolean copy; - - *symbol_map = -1; - - type = bfd_h_get_8 (input_bfd, sym->e_type); - name = strings + GET_WORD (input_bfd, sym->e_strx); - - h = NULL; - - if (pass) - { - /* Pass this symbol through. It is the target of an - indirect or warning symbol. */ - val = GET_WORD (input_bfd, sym->e_value); - pass = false; - } - else if (skip_indirect) - { - /* Skip this symbol, which is the target of an indirect - symbol that we have changed to no longer be an indirect - symbol. */ - skip_indirect = false; - continue; - } - else - { - struct aout_link_hash_entry *hresolve; - - /* We have saved the hash table entry for this symbol, if - there is one. Note that we could just look it up again - in the hash table, provided we first check that it is an - external symbol. */ - h = *sym_hash; - - /* If this is an indirect or warning symbol, then change - hresolve to the base symbol. We also change *sym_hash so - that the relocation routines relocate against the real - symbol. */ - hresolve = h; - if (h != (struct aout_link_hash_entry *) NULL - && (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning)) - { - hresolve = (struct aout_link_hash_entry *) h->root.u.i.link; - while (hresolve->root.type == bfd_link_hash_indirect - || hresolve->root.type == bfd_link_hash_warning) - hresolve = ((struct aout_link_hash_entry *) - hresolve->root.u.i.link); - *sym_hash = hresolve; - } - - /* If the symbol has already been written out, skip it. */ - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type != bfd_link_hash_warning - && h->written) - { - if ((type & N_TYPE) == N_INDR) - skip_indirect = true; - *symbol_map = h->indx; - continue; - } - - /* See if we are stripping this symbol. */ - skip = false; - switch (strip) - { - case strip_none: - break; - case strip_debugger: - if ((type & N_STAB) != 0) - skip = true; - break; - case strip_some: - if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) - == NULL) - skip = true; - break; - case strip_all: - skip = true; - break; - } - if (skip) - { - if (h != (struct aout_link_hash_entry *) NULL) - h->written = true; - continue; - } - - /* Get the value of the symbol. */ - if ((type & N_TYPE) == N_TEXT - || type == N_WEAKT) - symsec = obj_textsec (input_bfd); - else if ((type & N_TYPE) == N_DATA - || type == N_WEAKD) - symsec = obj_datasec (input_bfd); - else if ((type & N_TYPE) == N_BSS - || type == N_WEAKB) - symsec = obj_bsssec (input_bfd); - else if ((type & N_TYPE) == N_ABS - || type == N_WEAKA) - symsec = bfd_abs_section_ptr; - else if (((type & N_TYPE) == N_INDR - && (hresolve == (struct aout_link_hash_entry *) NULL - || (hresolve->root.type != bfd_link_hash_defined - && hresolve->root.type != bfd_link_hash_common))) - || type == N_WARNING) - { - /* Pass the next symbol through unchanged. The - condition above for indirect symbols is so that if - the indirect symbol was defined, we output it with - the correct definition so the debugger will - understand it. */ - pass = true; - val = GET_WORD (input_bfd, sym->e_value); - symsec = NULL; - } - else if ((type & N_STAB) != 0) - { - val = GET_WORD (input_bfd, sym->e_value); - symsec = NULL; - } - else - { - /* If we get here with an indirect symbol, it means that - we are outputting it with a real definition. In such - a case we do not want to output the next symbol, - which is the target of the indirection. */ - if ((type & N_TYPE) == N_INDR) - skip_indirect = true; - - /* We need to get the value from the hash table. We use - hresolve so that if we have defined an indirect - symbol we output the final definition. */ - if (h == (struct aout_link_hash_entry *) NULL) - val = 0; - else if (hresolve->root.type == bfd_link_hash_defined) - { - asection *input_section; - asection *output_section; - - /* This case means a common symbol which was turned - into a defined symbol. */ - input_section = hresolve->root.u.def.section; - output_section = input_section->output_section; - BFD_ASSERT (bfd_is_abs_section (output_section) - || output_section->owner == output_bfd); - val = (hresolve->root.u.def.value - + bfd_get_section_vma (output_bfd, output_section) - + input_section->output_offset); - - /* Get the correct type based on the section. If - this is a constructed set, force it to be - globally visible. */ - if (type == N_SETT - || type == N_SETD - || type == N_SETB - || type == N_SETA) - type |= N_EXT; - - type &=~ N_TYPE; - - if (output_section == obj_textsec (output_bfd)) - type |= N_TEXT; - else if (output_section == obj_datasec (output_bfd)) - type |= N_DATA; - else if (output_section == obj_bsssec (output_bfd)) - type |= N_BSS; - else - type |= N_ABS; - } - else if (hresolve->root.type == bfd_link_hash_common) - val = hresolve->root.u.c.size; - else if (hresolve->root.type == bfd_link_hash_weak) - { - val = 0; - type = N_WEAKU; - } - else - val = 0; - - symsec = NULL; - } - if (symsec != (asection *) NULL) - val = (symsec->output_section->vma - + symsec->output_offset - + (GET_WORD (input_bfd, sym->e_value) - - symsec->vma)); - - /* If this is a global symbol set the written flag, and if - it is a local symbol see if we should discard it. */ - if (h != (struct aout_link_hash_entry *) NULL) - { - h->written = true; - h->indx = obj_aout_external_sym_count (output_bfd); - } - else - { - switch (discard) - { - case discard_none: - break; - case discard_l: - if (*name == *finfo->info->lprefix - && (finfo->info->lprefix_len == 1 - || strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - skip = true; - break; - case discard_all: - skip = true; - break; - } - if (skip) - { - pass = false; - continue; - } - } - } - - /* Copy this symbol into the list of symbols we are going to - write out. */ - bfd_h_put_8 (output_bfd, type, outsym->e_type); - bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other), - outsym->e_other); - bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc), - outsym->e_desc); - copy = false; - if (! finfo->info->keep_memory) - { - /* name points into a string table which we are going to - free. If there is a hash table entry, use that string. - Otherwise, copy name into memory. */ - if (h != (struct aout_link_hash_entry *) NULL) - name = (*sym_hash)->root.root.string; - else - copy = true; - } - strtab_index = add_to_stringtab (output_bfd, &finfo->strtab, - name, copy); - if (strtab_index == (bfd_size_type) -1) - goto error_return; - PUT_WORD (output_bfd, strtab_index, outsym->e_strx); - PUT_WORD (output_bfd, val, outsym->e_value); - *symbol_map = obj_aout_external_sym_count (output_bfd); - ++obj_aout_external_sym_count (output_bfd); - ++outsym; - } - - /* Write out the output symbols we have just constructed. */ - if (outsym > output_syms) - { - bfd_size_type outsym_count; - - if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0) - goto error_return; - outsym_count = outsym - output_syms; - if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE, - (bfd_size_type) outsym_count, output_bfd) - != outsym_count * EXTERNAL_NLIST_SIZE) - goto error_return; - finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE; - } - - if (output_syms != NULL) - free (output_syms); - return true; - error_return: - if (output_syms != NULL) - free (output_syms); - return false; -} - -/* Write out a symbol that was not associated with an a.out input - object. */ - -static boolean -aout_link_write_other_symbol (h, data) - struct aout_link_hash_entry *h; - PTR data; -{ - struct aout_final_link_info *finfo = (struct aout_final_link_info *) data; - bfd *output_bfd; - int type; - bfd_vma val; - struct external_nlist outsym; - bfd_size_type indx; - - output_bfd = finfo->output_bfd; - - if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL) - { - if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol) - (output_bfd, finfo->info, h))) - { - /* FIXME: No way to handle errors. */ - abort (); - } - } - - if (h->written) - return true; - - h->written = true; - - if (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string, - false, false) == NULL)) - return true; - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - /* Avoid variable not initialized warnings. */ - return true; - case bfd_link_hash_undefined: - type = N_UNDF | N_EXT; - val = 0; - break; - case bfd_link_hash_defined: - { - asection *sec; - - sec = h->root.u.def.section->output_section; - BFD_ASSERT (bfd_is_abs_section (sec) - || sec->owner == output_bfd); - if (sec == obj_textsec (output_bfd)) - type = N_TEXT | N_EXT; - else if (sec == obj_datasec (output_bfd)) - type = N_DATA | N_EXT; - else if (sec == obj_bsssec (output_bfd)) - type = N_BSS | N_EXT; - else - type = N_ABS | N_EXT; - val = (h->root.u.def.value - + sec->vma - + h->root.u.def.section->output_offset); - } - break; - case bfd_link_hash_common: - type = N_UNDF | N_EXT; - val = h->root.u.c.size; - break; - case bfd_link_hash_weak: - type = N_WEAKU; - val = 0; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - bfd_h_put_8 (output_bfd, type, outsym.e_type); - bfd_h_put_8 (output_bfd, 0, outsym.e_other); - bfd_h_put_16 (output_bfd, 0, outsym.e_desc); - indx = add_to_stringtab (output_bfd, &finfo->strtab, h->root.root.string, - false); - if (indx == (bfd_size_type) -1) - { - /* FIXME: No way to handle errors. */ - abort (); - } - PUT_WORD (output_bfd, indx, outsym.e_strx); - PUT_WORD (output_bfd, val, outsym.e_value); - - if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0 - || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE, - (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE) - { - /* FIXME: No way to handle errors. */ - abort (); - } - - finfo->symoff += EXTERNAL_NLIST_SIZE; - h->indx = obj_aout_external_sym_count (output_bfd); - ++obj_aout_external_sym_count (output_bfd); - - return true; -} - -/* Link an a.out section into the output file. */ - -static boolean -aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr, - rel_size, symbol_map) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - file_ptr *reloff_ptr; - bfd_size_type rel_size; - int *symbol_map; -{ - bfd_size_type input_size; - bfd_byte *contents = NULL; - PTR relocs; - PTR free_relocs = NULL; - - /* Get the section contents. */ - input_size = bfd_section_size (input_bfd, input_section); - contents = (bfd_byte *) malloc (input_size); - if (contents == NULL && input_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents, - (file_ptr) 0, input_size)) - goto error_return; - - /* Read in the relocs if we haven't already done it. */ - if (aout_section_data (input_section) != NULL - && aout_section_data (input_section)->relocs != NULL) - relocs = aout_section_data (input_section)->relocs; - else - { - relocs = free_relocs = (PTR) malloc (rel_size); - if (relocs == NULL && rel_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 - || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size) - goto error_return; - } - - /* Relocate the section contents. */ - if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE) - { - if (! aout_link_input_section_std (finfo, input_bfd, input_section, - (struct reloc_std_external *) relocs, - rel_size, contents, symbol_map)) - goto error_return; - } - else - { - if (! aout_link_input_section_ext (finfo, input_bfd, input_section, - (struct reloc_ext_external *) relocs, - rel_size, contents, symbol_map)) - goto error_return; - } - - /* Write out the section contents. */ - if (! bfd_set_section_contents (finfo->output_bfd, - input_section->output_section, - (PTR) contents, - input_section->output_offset, - input_size)) - goto error_return; - - /* If we are producing relocateable output, the relocs were - modified, and we now write them out. */ - if (finfo->info->relocateable) - { - if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0) - goto error_return; - if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd) - != rel_size) - goto error_return; - *reloff_ptr += rel_size; - - /* Assert that the relocs have not run into the symbols, and - that if these are the text relocs they have not run into the - data relocs. */ - BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd) - && (reloff_ptr != &finfo->treloff - || (*reloff_ptr - <= obj_datasec (finfo->output_bfd)->rel_filepos))); - } - - if (free_relocs != NULL) - free (free_relocs); - if (contents != NULL) - free (contents); - return true; - error_return: - if (free_relocs != NULL) - free (free_relocs); - if (contents != NULL) - free (contents); - return false; -} - -/* Get the section corresponding to a reloc index. */ - -static INLINE asection * -aout_reloc_index_to_section (abfd, indx) - bfd *abfd; - int indx; -{ - switch (indx & N_TYPE) - { - case N_TEXT: - return obj_textsec (abfd); - case N_DATA: - return obj_datasec (abfd); - case N_BSS: - return obj_bsssec (abfd); - case N_ABS: - case N_UNDF: - return bfd_abs_section_ptr; - default: - abort (); - } -} - -/* Relocate an a.out section using standard a.out relocs. */ - -static boolean -aout_link_input_section_std (finfo, input_bfd, input_section, relocs, - rel_size, contents, symbol_map) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - struct reloc_std_external *relocs; - bfd_size_type rel_size; - bfd_byte *contents; - int *symbol_map; -{ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *, - bfd *, asection *, - struct aout_link_hash_entry *, - PTR, boolean *)); - bfd *output_bfd; - boolean relocateable; - struct external_nlist *syms; - char *strings; - struct aout_link_hash_entry **sym_hashes; - bfd_size_type reloc_count; - register struct reloc_std_external *rel; - struct reloc_std_external *rel_end; - - output_bfd = finfo->output_bfd; - check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; - - BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE); - BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p - == output_bfd->xvec->header_byteorder_big_p); - - relocateable = finfo->info->relocateable; - syms = obj_aout_external_syms (input_bfd); - strings = obj_aout_external_strings (input_bfd); - sym_hashes = obj_aout_sym_hashes (input_bfd); - - reloc_count = rel_size / RELOC_STD_SIZE; - rel = relocs; - rel_end = rel + reloc_count; - for (; rel < rel_end; rel++) - { - bfd_vma r_addr; - int r_index; - int r_extern; - int r_pcrel; - int r_baserel; - int r_jmptable; - int r_relative; - int r_length; - int howto_idx; - reloc_howto_type *howto; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_addr = GET_SWORD (input_bfd, rel->r_address); - -#ifdef MY_reloc_howto - howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel); -#else - if (input_bfd->xvec->header_byteorder_big_p) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG)); - r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG)); - r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); - r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG)); - r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) - >> RELOC_STD_BITS_LENGTH_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE)); - r_pcrel = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE)); - r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); - r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE)); - r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE)); - r_length = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) - >> RELOC_STD_BITS_LENGTH_SH_LITTLE); - } - - howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel - + 16 * r_jmptable + 32 * r_relative; - BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std)); - howto = howto_table_std + howto_idx; -#endif - - if (relocateable) - { - /* We are generating a relocateable output file, and must - modify the reloc accordingly. */ - if (r_extern) - { - struct aout_link_hash_entry *h; - - /* If we know the symbol this relocation is against, - convert it into a relocation against a section. This - is what the native linker does. */ - h = sym_hashes[r_index]; - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_defined) - { - asection *output_section; - - /* Change the r_extern value. */ - if (output_bfd->xvec->header_byteorder_big_p) - rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG; - else - rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE; - - /* Compute a new r_index. */ - output_section = h->root.u.def.section->output_section; - if (output_section == obj_textsec (output_bfd)) - r_index = N_TEXT; - else if (output_section == obj_datasec (output_bfd)) - r_index = N_DATA; - else if (output_section == obj_bsssec (output_bfd)) - r_index = N_BSS; - else - r_index = N_ABS; - - /* Add the symbol value and the section VMA to the - addend stored in the contents. */ - relocation = (h->root.u.def.value - + output_section->vma - + h->root.u.def.section->output_offset); - } - else - { - /* We must change r_index according to the symbol - map. */ - r_index = symbol_map[r_index]; - - if (r_index == -1) - { - const char *name; - - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - r_index = 0; - } - - relocation = 0; - } - - /* Write out the new r_index value. */ - if (output_bfd->xvec->header_byteorder_big_p) - { - rel->r_index[0] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[2] = r_index; - } - else - { - rel->r_index[2] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[0] = r_index; - } - } - else - { - asection *section; - - /* This is a relocation against a section. We must - adjust by the amount that the section moved. */ - section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - } - - /* Change the address of the relocation. */ - PUT_WORD (output_bfd, - r_addr + input_section->output_offset, - rel->r_address); - - /* Adjust a PC relative relocation by removing the reference - to the original address in the section and including the - reference to the new address. */ - if (r_pcrel) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - if (relocation == 0) - r = bfd_reloc_ok; - else - r = _bfd_relocate_contents (howto, - input_bfd, relocation, - contents + r_addr); - } - else - { - /* We are generating an executable, and must do a full - relocation. */ - if (r_extern) - { - struct aout_link_hash_entry *h; - - h = sym_hashes[r_index]; - - if (check_dynamic_reloc != NULL) - { - boolean skip; - - if (! ((*check_dynamic_reloc) - (finfo->info, input_bfd, input_section, h, - (PTR) rel, &skip))) - return false; - if (skip) - continue; - } - - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_defined) - { - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_weak) - relocation = 0; - else - { - const char *name; - - name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - relocation = 0; - } - } - else - { - asection *section; - - section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - if (r_pcrel) - relocation += input_section->vma; - } - - r = _bfd_final_link_relocate (howto, - input_bfd, input_section, - contents, r_addr, relocation, - (bfd_vma) 0); - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern) - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - else - { - asection *s; - - s = aout_reloc_index_to_section (input_bfd, r_index); - name = bfd_section_name (input_bfd, s); - } - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, name, howto->name, - (bfd_vma) 0, input_bfd, input_section, r_addr))) - return false; - } - break; - } - } - } - - return true; -} - -/* Relocate an a.out section using extended a.out relocs. */ - -static boolean -aout_link_input_section_ext (finfo, input_bfd, input_section, relocs, - rel_size, contents, symbol_map) - struct aout_final_link_info *finfo; - bfd *input_bfd; - asection *input_section; - struct reloc_ext_external *relocs; - bfd_size_type rel_size; - bfd_byte *contents; - int *symbol_map; -{ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *, - bfd *, asection *, - struct aout_link_hash_entry *, - PTR, boolean *)); - bfd *output_bfd; - boolean relocateable; - struct external_nlist *syms; - char *strings; - struct aout_link_hash_entry **sym_hashes; - bfd_size_type reloc_count; - register struct reloc_ext_external *rel; - struct reloc_ext_external *rel_end; - - output_bfd = finfo->output_bfd; - check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc; - - BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE); - BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p - == output_bfd->xvec->header_byteorder_big_p); - - relocateable = finfo->info->relocateable; - syms = obj_aout_external_syms (input_bfd); - strings = obj_aout_external_strings (input_bfd); - sym_hashes = obj_aout_sym_hashes (input_bfd); - - reloc_count = rel_size / RELOC_EXT_SIZE; - rel = relocs; - rel_end = rel + reloc_count; - for (; rel < rel_end; rel++) - { - bfd_vma r_addr; - int r_index; - int r_extern; - int r_type; - bfd_vma r_addend; - bfd_vma relocation; - - r_addr = GET_SWORD (input_bfd, rel->r_address); - - if (input_bfd->xvec->header_byteorder_big_p) - { - r_index = ((rel->r_index[0] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[2]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG) - >> RELOC_EXT_BITS_TYPE_SH_BIG); - } - else - { - r_index = ((rel->r_index[2] << 16) - | (rel->r_index[1] << 8) - | rel->r_index[0]); - r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE)); - r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE) - >> RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - r_addend = GET_SWORD (input_bfd, rel->r_addend); - - BFD_ASSERT (r_type >= 0 - && r_type < TABLE_SIZE (howto_table_ext)); - - if (relocateable) - { - /* We are generating a relocateable output file, and must - modify the reloc accordingly. */ - if (r_extern) - { - struct aout_link_hash_entry *h; - - /* If we know the symbol this relocation is against, - convert it into a relocation against a section. This - is what the native linker does. */ - h = sym_hashes[r_index]; - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_defined) - { - asection *output_section; - - /* Change the r_extern value. */ - if (output_bfd->xvec->header_byteorder_big_p) - rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG; - else - rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE; - - /* Compute a new r_index. */ - output_section = h->root.u.def.section->output_section; - if (output_section == obj_textsec (output_bfd)) - r_index = N_TEXT; - else if (output_section == obj_datasec (output_bfd)) - r_index = N_DATA; - else if (output_section == obj_bsssec (output_bfd)) - r_index = N_BSS; - else - r_index = N_ABS; - - /* Add the symbol value and the section VMA to the - addend. */ - relocation = (h->root.u.def.value - + output_section->vma - + h->root.u.def.section->output_offset); - - /* Now RELOCATION is the VMA of the final - destination. If this is a PC relative reloc, - then ADDEND is the negative of the source VMA. - We want to set ADDEND to the difference between - the destination VMA and the source VMA, which - means we must adjust RELOCATION by the change in - the source VMA. This is done below. */ - } - else - { - /* We must change r_index according to the symbol - map. */ - r_index = symbol_map[r_index]; - - if (r_index == -1) - { - const char *name; - - name = (strings - + GET_WORD (input_bfd, syms[r_index].e_strx)); - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - r_index = 0; - } - - relocation = 0; - - /* If this is a PC relative reloc, then the addend - is the negative of the source VMA. We must - adjust it by the change in the source VMA. This - is done below. */ - } - - /* Write out the new r_index value. */ - if (output_bfd->xvec->header_byteorder_big_p) - { - rel->r_index[0] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[2] = r_index; - } - else - { - rel->r_index[2] = r_index >> 16; - rel->r_index[1] = r_index >> 8; - rel->r_index[0] = r_index; - } - } - else - { - asection *section; - - /* This is a relocation against a section. We must - adjust by the amount that the section moved. */ - section = aout_reloc_index_to_section (input_bfd, r_index); - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - - /* If this is a PC relative reloc, then the addend is - the difference in VMA between the destination and the - source. We have just adjusted for the change in VMA - of the destination, so we must also adjust by the - change in VMA of the source. This is done below. */ - } - - /* As described above, we must always adjust a PC relative - reloc by the change in VMA of the source. */ - if (howto_table_ext[r_type].pc_relative) - relocation -= (input_section->output_section->vma - + input_section->output_offset - - input_section->vma); - - /* Change the addend if necessary. */ - if (relocation != 0) - PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend); - - /* Change the address of the relocation. */ - PUT_WORD (output_bfd, - r_addr + input_section->output_offset, - rel->r_address); - } - else - { - bfd_reloc_status_type r; - - /* We are generating an executable, and must do a full - relocation. */ - if (r_extern) - { - struct aout_link_hash_entry *h; - - h = sym_hashes[r_index]; - - if (check_dynamic_reloc != NULL) - { - boolean skip; - - if (! ((*check_dynamic_reloc) - (finfo->info, input_bfd, input_section, h, - (PTR) rel, &skip))) - return false; - if (skip) - continue; - } - - if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_defined) - { - relocation = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - } - else if (h != (struct aout_link_hash_entry *) NULL - && h->root.type == bfd_link_hash_weak) - relocation = 0; - else - { - const char *name; - - name = strings + GET_WORD (input_bfd, syms[r_index].e_strx); - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, name, input_bfd, input_section, - r_addr))) - return false; - relocation = 0; - } - } - else - { - asection *section; - - section = aout_reloc_index_to_section (input_bfd, r_index); - - /* If this is a PC relative reloc, then R_ADDEND is the - difference between the two vmas, or - old_dest_sec + old_dest_off - (old_src_sec + old_src_off) - where - old_dest_sec == section->vma - and - old_src_sec == input_section->vma - and - old_src_off == r_addr - - _bfd_final_link_relocate expects RELOCATION + - R_ADDEND to be the VMA of the destination minus - r_addr (the minus r_addr is because this relocation - is not pcrel_offset, which is a bit confusing and - should, perhaps, be changed), or - new_dest_sec - where - new_dest_sec == output_section->vma + output_offset - We arrange for this to happen by setting RELOCATION to - new_dest_sec + old_src_sec - old_dest_sec - - If this is not a PC relative reloc, then R_ADDEND is - simply the VMA of the destination, so we set - RELOCATION to the change in the destination VMA, or - new_dest_sec - old_dest_sec - */ - relocation = (section->output_section->vma - + section->output_offset - - section->vma); - if (howto_table_ext[r_type].pc_relative) - relocation += input_section->vma; - } - - r = _bfd_final_link_relocate (howto_table_ext + r_type, - input_bfd, input_section, - contents, r_addr, relocation, - r_addend); - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (r_extern) - name = strings + GET_WORD (input_bfd, - syms[r_index].e_strx); - else - { - asection *s; - - s = aout_reloc_index_to_section (input_bfd, r_index); - name = bfd_section_name (input_bfd, s); - } - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, name, howto_table_ext[r_type].name, - r_addend, input_bfd, input_section, r_addr))) - return false; - } - break; - } - } - } - } - - return true; -} - -/* Handle a link order which is supposed to generate a reloc. */ - -static boolean -aout_link_reloc_link_order (finfo, o, p) - struct aout_final_link_info *finfo; - asection *o; - struct bfd_link_order *p; -{ - struct bfd_link_order_reloc *pr; - int r_index; - int r_extern; - const reloc_howto_type *howto; - file_ptr *reloff_ptr; - struct reloc_std_external srel; - struct reloc_ext_external erel; - PTR rel_ptr; - - pr = p->u.reloc.p; - - if (p->type == bfd_section_reloc_link_order) - { - r_extern = 0; - if (bfd_is_abs_section (pr->u.section)) - r_index = N_ABS | N_EXT; - else - { - BFD_ASSERT (pr->u.section->owner == finfo->output_bfd); - r_index = pr->u.section->target_index; - } - } - else - { - struct aout_link_hash_entry *h; - - BFD_ASSERT (p->type == bfd_symbol_reloc_link_order); - r_extern = 1; - h = aout_link_hash_lookup (aout_hash_table (finfo->info), - pr->u.name, false, false, true); - if (h != (struct aout_link_hash_entry *) NULL - && h->indx == -1) - r_index = h->indx; - else - { - if (! ((*finfo->info->callbacks->unattached_reloc) - (finfo->info, pr->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - r_index = 0; - } - } - - howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc); - if (howto == (const reloc_howto_type *) NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (o == obj_textsec (finfo->output_bfd)) - reloff_ptr = &finfo->treloff; - else if (o == obj_datasec (finfo->output_bfd)) - reloff_ptr = &finfo->dreloff; - else - abort (); - - if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE) - { - int r_pcrel; - int r_baserel; - int r_jmptable; - int r_relative; - int r_length; - -#ifdef MY_put_reloc - MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto, &srel); -#else - r_pcrel = howto->pc_relative; - r_baserel = (howto->type & 8) != 0; - r_jmptable = (howto->type & 16) != 0; - r_relative = (howto->type & 32) != 0; - r_length = howto->size; - - PUT_WORD (finfo->output_bfd, p->offset, srel.r_address); - if (finfo->output_bfd->xvec->header_byteorder_big_p) - { - srel.r_index[0] = r_index >> 16; - srel.r_index[1] = r_index >> 8; - srel.r_index[2] = r_index; - srel.r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG)); - } - else - { - srel.r_index[2] = r_index >> 16; - srel.r_index[1] = r_index >> 8; - srel.r_index[0] = r_index; - srel.r_type[0] = - ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0) - | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0) - | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0) - | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0) - | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0) - | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE)); - } -#endif - rel_ptr = (PTR) &srel; - - /* We have to write the addend into the object file, since - standard a.out relocs are in place. It would be more - reliable if we had the current contents of the file here, - rather than assuming zeroes, but we can't read the file since - it was opened using bfd_openw. */ - if (pr->addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type r; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - r = _bfd_relocate_contents (howto, finfo->output_bfd, - pr->addend, buf); - switch (r) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*finfo->info->callbacks->reloc_overflow) - (finfo->info, - (p->type == bfd_section_reloc_link_order - ? bfd_section_name (finfo->output_bfd, - pr->u.section) - : pr->u.name), - howto->name, pr->addend, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (finfo->output_bfd, o, - (PTR) buf, - (file_ptr) p->offset, - size); - free (buf); - if (! ok) - return false; - } - } - else - { - PUT_WORD (finfo->output_bfd, p->offset, erel.r_address); - - if (finfo->output_bfd->xvec->header_byteorder_big_p) - { - erel.r_index[0] = r_index >> 16; - erel.r_index[1] = r_index >> 8; - erel.r_index[2] = r_index; - erel.r_type[0] = - ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0) - | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG)); - } - else - { - erel.r_index[2] = r_index >> 16; - erel.r_index[1] = r_index >> 8; - erel.r_index[0] = r_index; - erel.r_type[0] = - (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0) - | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE); - } - - PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend); - - rel_ptr = (PTR) &erel; - } - - if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0 - || (bfd_write (rel_ptr, (bfd_size_type) 1, - obj_reloc_entry_size (finfo->output_bfd), - finfo->output_bfd) - != obj_reloc_entry_size (finfo->output_bfd))) - return false; - - *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd); - - /* Assert that the relocs have not run into the symbols, and that n - the text relocs have not run into the data relocs. */ - BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd) - && (reloff_ptr != &finfo->treloff - || (*reloff_ptr - <= obj_datasec (finfo->output_bfd)->rel_filepos))); - - return true; -} diff --git a/gnu/usr.bin/gdb/bfd/archive.c b/gnu/usr.bin/gdb/bfd/archive.c deleted file mode 100644 index a91b496..0000000 --- a/gnu/usr.bin/gdb/bfd/archive.c +++ /dev/null @@ -1,2016 +0,0 @@ -/* BFD back-end for archive files (libraries). - Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -@setfilename archive-info -SECTION - Archives - -DESCRIPTION - An archive (or library) is just another BFD. It has a symbol - table, although there's not much a user program will do with it. - - The big difference between an archive BFD and an ordinary BFD - is that the archive doesn't have sections. Instead it has a - chain of BFDs that are considered its contents. These BFDs can - be manipulated like any other. The BFDs contained in an - archive opened for reading will all be opened for reading. You - may put either input or output BFDs into an archive opened for - output; they will be handled correctly when the archive is closed. - - Use <<bfd_openr_next_archived_file>> to step through - the contents of an archive opened for input. You don't - have to read the entire archive if you don't want - to! Read it until you find what you want. - - Archive contents of output BFDs are chained through the - <<next>> pointer in a BFD. The first one is findable through - the <<archive_head>> slot of the archive. Set it with - <<bfd_set_archive_head>> (q.v.). A given BFD may be in only one - open output archive at a time. - - As expected, the BFD archive code is more general than the - archive code of any given environment. BFD archives may - contain files of different formats (e.g., a.out and coff) and - even different architectures. You may even place archives - recursively into archives! - - This can cause unexpected confusion, since some archive - formats are more expressive than others. For instance, Intel - COFF archives can preserve long filenames; SunOS a.out archives - cannot. If you move a file from the first to the second - format and back again, the filename may be truncated. - Likewise, different a.out environments have different - conventions as to how they truncate filenames, whether they - preserve directory names in filenames, etc. When - interoperating with native tools, be sure your files are - homogeneous. - - Beware: most of these formats do not react well to the - presence of spaces in filenames. We do the best we can, but - can't always handle this case due to restrictions in the format of - archives. Many Unix utilities are braindead in regards to - spaces and such in filenames anyway, so this shouldn't be much - of a restriction. - - Archives are supported in BFD in <<archive.c>>. - -*/ - -/* Assumes: - o - all archive elements start on an even boundary, newline padded; - o - all arch headers are char *; - o - all arch headers are the same size (across architectures). -*/ - -/* Some formats provide a way to cram a long filename into the short - (16 chars) space provided by a BSD archive. The trick is: make a - special "file" in the front of the archive, sort of like the SYMDEF - entry. If the filename is too long to fit, put it in the extended - name table, and use its index as the filename. To prevent - confusion prepend the index with a space. This means you can't - have filenames that start with a space, but then again, many Unix - utilities can't handle that anyway. - - This scheme unfortunately requires that you stand on your head in - order to write an archive since you need to put a magic file at the - front, and need to touch every entry to do so. C'est la vie. - - We support two variants of this idea: - The SVR4 format (extended name table is named "//"), - and an extended pseudo-BSD variant (extended name table is named - "ARFILENAMES/"). The origin of the latter format is uncertain. - - BSD 4.4 uses a third scheme: It writes a long filename - directly after the header. This allows 'ar q' to work. - We currently can read BSD 4.4 archives, but not write them. -*/ - -/* Summary of archive member names: - - Symbol table (must be first): - "__.SYMDEF " - Symbol table, Berkeley style, produced by ranlib. - "/ " - Symbol table, system 5 style. - - Long name table (must be before regular file members): - "// " - Long name table, System 5 R4 style. - "ARFILENAMES/ " - Long name table, non-standard extended BSD (not BSD 4.4). - - Regular file members with short names: - "filename.o/ " - Regular file, System 5 style (embedded spaces ok). - "filename.o " - Regular file, Berkeley style (no embedded spaces). - - Regular files with long names (or embedded spaces, for BSD variants): - "/18 " - SVR4 style, name at offset 18 in name table. - "#1/23 " - Long name (or embedded paces) 23 characters long, - BSD 4.4 style, full name follows header. - Implemented for reading, not writing. - " 18 " - Long name 18 characters long, extended pseudo-BSD. - */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "aout/ar.h" -#include "aout/ranlib.h" -#include <errno.h> -#include <string.h> /* For memchr, strrchr and friends */ -#include <ctype.h> - -#ifndef errno -extern int errno; -#endif - -#ifdef GNU960 -#define BFD_GNU960_ARMAG(abfd) (BFD_COFF_FILE_P((abfd)) ? ARMAG : ARMAGB) -#endif - -/* Can't define this in hosts/foo.h, because (e.g. in gprof) the hosts file - is included, then obstack.h, which thinks if offsetof is defined, it - doesn't need to include stddef.h. */ -/* Define offsetof for those systems which lack it */ - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* We keep a cache of archive filepointers to archive elements to - speed up searching the archive by filepos. We only add an entry to - the cache when we actually read one. We also don't sort the cache; - it's generally short enough to search linearly. - Note that the pointers here point to the front of the ar_hdr, not - to the front of the contents! -*/ -struct ar_cache -{ - file_ptr ptr; - bfd *arelt; - struct ar_cache *next; -}; - -#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char) -#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen) - -#define arch_eltdata(bfd) ((struct areltdata *)((bfd)->arelt_data)) -#define arch_hdr(bfd) ((struct ar_hdr *)arch_eltdata(bfd)->arch_header) - -static char *get_extended_arelt_filename PARAMS ((bfd *arch, - const char *name)); -static boolean do_slurp_bsd_armap PARAMS ((bfd *abfd)); -static boolean do_slurp_coff_armap PARAMS ((bfd *abfd)); -static const char *normalize PARAMS ((const char *file)); -static boolean bfd_construct_extended_name_table PARAMS ((bfd *abfd, - char **tabloc, - unsigned int *)); -static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd, - const char *)); -static boolean compute_and_write_armap PARAMS ((bfd *arch, - unsigned int elength)); -static boolean bsd_update_armap_timestamp PARAMS ((bfd *arch)); - -boolean -_bfd_generic_mkarchive (abfd) - bfd *abfd; -{ - abfd->tdata.aout_ar_data = ((struct artdata *) - bfd_zalloc (abfd, sizeof (struct artdata))); - - if (bfd_ardata (abfd) == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - return true; -} - -/* -FUNCTION - bfd_get_next_mapent - -SYNOPSIS - symindex bfd_get_next_mapent(bfd *abfd, symindex previous, carsym **sym); - -DESCRIPTION - Step through archive @var{abfd}'s symbol table (if it - has one). Successively update @var{sym} with the next symbol's - information, returning that symbol's (internal) index into the - symbol table. - - Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get - the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already - got the last one. - - A <<carsym>> is a canonical archive symbol. The only - user-visible element is its name, a null-terminated string. -*/ - -symindex -bfd_get_next_mapent (abfd, prev, entry) - bfd *abfd; - symindex prev; - carsym **entry; -{ - if (!bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_invalid_operation); - return BFD_NO_MORE_SYMBOLS; - } - - if (prev == BFD_NO_MORE_SYMBOLS) - prev = 0; - else if (++prev >= bfd_ardata (abfd)->symdef_count) - return BFD_NO_MORE_SYMBOLS; - - *entry = (bfd_ardata (abfd)->symdefs + prev); - return prev; -} - -/* To be called by backends only */ - -bfd * -_bfd_create_empty_archive_element_shell (obfd) - bfd *obfd; -{ - bfd *nbfd; - - nbfd = _bfd_new_bfd_contained_in (obfd); - if (nbfd == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - return nbfd; -} - -/* -FUNCTION - bfd_set_archive_head - -SYNOPSIS - boolean bfd_set_archive_head(bfd *output, bfd *new_head); - -DESCRIPTION - Set the head of the chain of - BFDs contained in the archive @var{output} to @var{new_head}. -*/ - -boolean -bfd_set_archive_head (output_archive, new_head) - bfd *output_archive; - bfd *new_head; -{ - - output_archive->archive_head = new_head; - return true; -} - -bfd * -_bfd_look_for_bfd_in_cache (arch_bfd, filepos) - bfd *arch_bfd; - file_ptr filepos; -{ - struct ar_cache *current; - - for (current = bfd_ardata (arch_bfd)->cache; current != NULL; - current = current->next) - if (current->ptr == filepos) - return current->arelt; - - return NULL; -} - -/* Kind of stupid to call cons for each one, but we don't do too many */ -boolean -_bfd_add_bfd_to_archive_cache (arch_bfd, filepos, new_elt) - bfd *arch_bfd, *new_elt; - file_ptr filepos; -{ - struct ar_cache *new_cache = ((struct ar_cache *) - bfd_zalloc (arch_bfd, - sizeof (struct ar_cache))); - - if (new_cache == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - new_cache->ptr = filepos; - new_cache->arelt = new_elt; - new_cache->next = (struct ar_cache *) NULL; - if (bfd_ardata (arch_bfd)->cache == NULL) - bfd_ardata (arch_bfd)->cache = new_cache; - else - { - struct ar_cache *current = bfd_ardata (arch_bfd)->cache; - - while (current->next != NULL) - current = current->next; - current->next = new_cache; - } - - return true; -} - -/* The name begins with space. Hence the rest of the name is an index into - the string table. */ - -static char * -get_extended_arelt_filename (arch, name) - bfd *arch; - const char *name; -{ - unsigned long index = 0; - - /* Should extract string so that I can guarantee not to overflow into - the next region, but I'm too lazy. */ - errno = 0; - /* Skip first char, which is '/' in SVR4 or ' ' in some other variants. */ - index = strtol (name + 1, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - return bfd_ardata (arch)->extended_names + index; -} - -/* This functions reads an arch header and returns an areltdata pointer, or - NULL on error. - - Presumes the file pointer is already in the right place (ie pointing - to the ar_hdr in the file). Moves the file pointer; on success it - should be pointing to the front of the file contents; on failure it - could have been moved arbitrarily. -*/ - -struct areltdata * -_bfd_snarf_ar_hdr (abfd) - bfd *abfd; -{ -#ifndef errno - extern int errno; -#endif - - struct ar_hdr hdr; - char *hdrp = (char *) &hdr; - unsigned int parsed_size; - struct areltdata *ared; - char *filename = NULL; - unsigned int namelen = 0; - unsigned int allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr); - char *allocptr = 0; - - if (bfd_read ((PTR) hdrp, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - if (strncmp (hdr.ar_fmag, ARFMAG, 2)) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - errno = 0; - parsed_size = strtol (hdr.ar_size, NULL, 10); - if (errno != 0) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - - /* Extract the filename from the archive - there are two ways to - specify an extendend name table, either the first char of the - name is a space, or it's a slash. */ - if ((hdr.ar_name[0] == '/' - || (hdr.ar_name[0] == ' ' - && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL)) - && bfd_ardata (abfd)->extended_names != NULL) - { - filename = get_extended_arelt_filename (abfd, hdr.ar_name); - if (filename == NULL) - { - bfd_set_error (bfd_error_malformed_archive); - return NULL; - } - } - /* BSD4.4-style long filename. - Only implemented for reading, so far! */ - else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1' - && hdr.ar_name[2] == '/' && isdigit (hdr.ar_name[3])) - { - /* BSD-4.4 extended name */ - namelen = atoi (&hdr.ar_name[3]); - allocsize += namelen + 1; - parsed_size -= namelen; - - allocptr = bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - filename = (allocptr - + sizeof (struct areltdata) - + sizeof (struct ar_hdr)); - if (bfd_read (filename, 1, namelen, abfd) != namelen) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_no_more_archived_files); - return NULL; - } - filename[namelen] = '\0'; - } - else - { - /* We judge the end of the name by looking for '/' or ' '. - Note: The SYSV format (terminated by '/') allows embedded - spaces, so only look for ' ' if we don't find '/'. */ - - namelen = 0; - while (hdr.ar_name[namelen] != '\0' && - hdr.ar_name[namelen] != '/') - { - namelen++; - if (namelen == (unsigned) ar_maxnamelen (abfd)) - { - namelen = 0; - while (hdr.ar_name[namelen] != ' ' - && namelen < (unsigned) ar_maxnamelen (abfd)) - namelen++; - break; - } - } - - allocsize += namelen + 1; - } - - if (!allocptr) - { - allocptr = bfd_zalloc (abfd, allocsize); - if (allocptr == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - } - - ared = (struct areltdata *) allocptr; - - ared->arch_header = allocptr + sizeof (struct areltdata); - memcpy ((char *) ared->arch_header, (char *) &hdr, sizeof (struct ar_hdr)); - ared->parsed_size = parsed_size; - - if (filename != NULL) - ared->filename = filename; - else - { - ared->filename = allocptr + (sizeof (struct areltdata) + - sizeof (struct ar_hdr)); - if (namelen) - memcpy (ared->filename, hdr.ar_name, namelen); - ared->filename[namelen] = '\0'; - } - - return ared; -} - -/* This is an internal function; it's mainly used when indexing - through the archive symbol table, but also used to get the next - element, since it handles the bookkeeping so nicely for us. */ - -bfd * -_bfd_get_elt_at_filepos (archive, filepos) - bfd *archive; - file_ptr filepos; -{ - struct areltdata *new_areldata; - bfd *n_nfd; - - n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); - if (n_nfd) - return n_nfd; - - if (0 > bfd_seek (archive, filepos, SEEK_SET)) - return NULL; - - if ((new_areldata = _bfd_snarf_ar_hdr (archive)) == NULL) - return NULL; - - n_nfd = _bfd_create_empty_archive_element_shell (archive); - if (n_nfd == NULL) - { - bfd_release (archive, (PTR) new_areldata); - return NULL; - } - - n_nfd->origin = bfd_tell (archive); - n_nfd->arelt_data = (PTR) new_areldata; - n_nfd->filename = new_areldata->filename; - - if (_bfd_add_bfd_to_archive_cache (archive, filepos, n_nfd)) - return n_nfd; - - /* huh? */ - bfd_release (archive, (PTR) n_nfd); - bfd_release (archive, (PTR) new_areldata); - return NULL; -} - -/* -FUNCTION - bfd_get_elt_at_index - -SYNOPSIS - bfd *bfd_get_elt_at_index(bfd *archive, int index); - -DESCRIPTION - Return the BFD which is referenced by the symbol in @var{archive} - indexed by @var{index}. @var{index} should have been returned by - <<bfd_get_next_mapent>> (q.v.). - -*/ -bfd * -bfd_get_elt_at_index (abfd, index) - bfd *abfd; - int index; -{ - carsym *entry; - - entry = bfd_ardata (abfd)->symdefs + index; - return _bfd_get_elt_at_filepos (abfd, entry->file_offset); -} - -/* -FUNCTION - bfd_openr_next_archived_file - -SYNOPSIS - bfd *bfd_openr_next_archived_file(bfd *archive, bfd *previous); - -DESCRIPTION - Provided a BFD, @var{archive}, containing an archive and NULL, open - an input BFD on the first contained element and returns that. - Subsequent calls should pass - the archive and the previous return value to return a created - BFD to the next contained element. NULL is returned when there - are no more. - -*/ - -bfd * -bfd_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - if ((bfd_get_format (archive) != bfd_archive) || - (archive->direction == write_direction)) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - return BFD_SEND (archive, - openr_next_archived_file, - (archive, - last_file)); -} - -bfd * -bfd_generic_openr_next_archived_file (archive, last_file) - bfd *archive; - bfd *last_file; -{ - file_ptr filestart; - - if (!last_file) - filestart = bfd_ardata (archive)->first_file_filepos; - else - { - unsigned int size = arelt_size (last_file); - /* Pad to an even boundary... - Note that last_file->origin can be odd in the case of - BSD-4.4-style element with a long odd size. */ - filestart = last_file->origin + size; - filestart += filestart % 2; - } - - return _bfd_get_elt_at_filepos (archive, filestart); -} - - -const bfd_target * -bfd_generic_archive_p (abfd) - bfd *abfd; -{ - char armag[SARMAG + 1]; - - if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - -#ifdef GNU960 - if (strncmp (armag, BFD_GNU960_ARMAG (abfd), SARMAG) != 0) - return 0; -#else - if (strncmp (armag, ARMAG, SARMAG) != 0 && - strncmp (armag, ARMAGB, SARMAG) != 0) - return 0; -#endif - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of assignment. */ - abfd->tdata.aout_ar_data = ((struct artdata *) - bfd_zalloc (abfd, sizeof (struct artdata))); - - if (bfd_ardata (abfd) == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = NULL; - return NULL; - } - - if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd))) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = NULL; - return NULL; - } - - return abfd->xvec; -} - -/* Some constants for a 32 bit BSD archive structure. We do not - support 64 bit archives presently; so far as I know, none actually - exist. Supporting them would require changing these constants, and - changing some bfd_h_get_32 to bfd_h_get_64. */ - -/* The size of an external symdef structure. */ -#define BSD_SYMDEF_SIZE 8 - -/* The offset from the start of a symdef structure to the file offset. */ -#define BSD_SYMDEF_OFFSET_SIZE 4 - -/* The size of the symdef count. */ -#define BSD_SYMDEF_COUNT_SIZE 4 - -/* The size of the string count. */ -#define BSD_STRING_COUNT_SIZE 4 - -/* Returns false on error, true otherwise */ - -static boolean -do_slurp_bsd_armap (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int parsed_size; - carsym *set; - - mapdata = _bfd_snarf_ar_hdr (abfd); - if (mapdata == NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */ - - raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); - if (raw_armap == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - byebye: - bfd_release (abfd, (PTR) raw_armap); - return false; - } - - ardata->symdef_count = bfd_h_get_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; - - if (ardata->symdef_count * BSD_SYMDEF_SIZE > - parsed_size - BSD_SYMDEF_COUNT_SIZE) - { - /* Probably we're using the wrong byte ordering. */ - bfd_set_error (bfd_error_wrong_format); - goto byebye; - } - - ardata->cache = 0; - rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE; - stringbase = ((char *) rbase - + ardata->symdef_count * BSD_SYMDEF_SIZE - + BSD_STRING_COUNT_SIZE); - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * sizeof (carsym))); - if (!ardata->symdefs) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = bfd_h_get_32 (abfd, rbase) + stringbase; - set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an obstack anyway... */ - bfd_has_map (abfd) = true; - return true; -} - -/* Returns false on error, true otherwise */ -static boolean -do_slurp_coff_armap (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - int *raw_armap, *rawptr; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int stringsize; - unsigned int parsed_size; - carsym *carsyms; - unsigned int nsymz; /* Number of symbols in armap. */ - bfd_vma (*swap) PARAMS ((const bfd_byte *)); - char int_buf[sizeof (long)]; - unsigned int carsym_size, ptrsize, i; - - mapdata = _bfd_snarf_ar_hdr (abfd); - if (mapdata == NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); /* Don't need it any more. */ - - if (bfd_read ((PTR) int_buf, 1, 4, abfd) != 4) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return false; - } - /* It seems that all numeric information in a coff archive is always - in big endian format, nomatter the host or target. */ - swap = bfd_getb32; - nsymz = bfd_getb32 ((PTR) int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - -#if 1 - /* ... except that some archive formats are broken, and it may be our - fault - the i960 little endian coff sometimes has big and sometimes - little, because our tools changed. Here's a horrible hack to clean - up the crap. */ - - if (stringsize > 0xfffff) - { - /* This looks dangerous, let's do it the other way around */ - nsymz = bfd_getl32 ((PTR) int_buf); - stringsize = parsed_size - (4 * nsymz) - 4; - swap = bfd_getl32; - } -#endif - - /* The coff armap must be read sequentially. So we construct a - bsd-style one in core all at once, for simplicity. */ - - carsym_size = (nsymz * sizeof (carsym)); - ptrsize = (4 * nsymz); - - ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1); - if (ardata->symdefs == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - carsyms = ardata->symdefs; - stringbase = ((char *) ardata->symdefs) + carsym_size; - - /* Allocate and read in the raw offsets. */ - raw_armap = (int *) bfd_alloc (abfd, ptrsize); - if (raw_armap == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto release_symdefs; - } - if (bfd_read ((PTR) raw_armap, 1, ptrsize, abfd) != ptrsize - || bfd_read ((PTR) stringbase, 1, stringsize, abfd) != stringsize) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - goto release_raw_armap; - } - - /* OK, build the carsyms */ - for (i = 0; i < nsymz; i++) - { - rawptr = raw_armap + i; - carsyms->file_offset = swap ((PTR) rawptr); - carsyms->name = stringbase; - stringbase += strlen (stringbase) + 1; - carsyms++; - } - *stringbase = 0; - - ardata->symdef_count = nsymz; - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - - bfd_has_map (abfd) = true; - bfd_release (abfd, (PTR) raw_armap); - return true; - -release_raw_armap: - bfd_release (abfd, (PTR) raw_armap); -release_symdefs: - bfd_release (abfd, (PTR) (ardata)->symdefs); - return false; -} - -/* This routine can handle either coff-style or bsd-style armaps. - Returns false on error, true otherwise */ - -boolean -bfd_slurp_armap (abfd) - bfd *abfd; -{ - char nextname[17]; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) - return false; - - if (!strncmp (nextname, "__.SYMDEF ", 16) - || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ - return do_slurp_bsd_armap (abfd); - else if (!strncmp (nextname, "/ ", 16)) - return do_slurp_coff_armap (abfd); - - bfd_has_map (abfd) = false; - return true; -} - -/* Returns false on error, true otherwise */ -/* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the - header is in a slightly different order and the map name is '/'. - This flavour is used by hp300hpux. */ - -#define HPUX_SYMDEF_COUNT_SIZE 2 - -boolean -bfd_slurp_bsd_armap_f2 (abfd) - bfd *abfd; -{ - struct areltdata *mapdata; - char nextname[17]; - unsigned int counter; - bfd_byte *raw_armap, *rbase; - struct artdata *ardata = bfd_ardata (abfd); - char *stringbase; - unsigned int stringsize; - carsym *set; - int i = bfd_read ((PTR) nextname, 1, 16, abfd); - - if (i == 0) - return true; - if (i != 16) - return false; - - /* The archive has at least 16 bytes in it */ - if (bfd_seek (abfd, -16L, SEEK_CUR) != 0) - return false; - - if (!strncmp (nextname, "__.SYMDEF ", 16) - || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ - return do_slurp_bsd_armap (abfd); - - if (strncmp (nextname, "/ ", 16)) - { - bfd_has_map (abfd) = false; - return true; - } - - mapdata = _bfd_snarf_ar_hdr (abfd); - if (mapdata == NULL) - return false; - - raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size); - if (raw_armap == NULL) - { - bfd_set_error (bfd_error_no_memory); - byebye: - bfd_release (abfd, (PTR) mapdata); - return false; - } - - if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) != - mapdata->parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - byebyebye: - bfd_release (abfd, (PTR) raw_armap); - goto byebye; - } - - ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap); - - if (ardata->symdef_count * BSD_SYMDEF_SIZE - > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE) - { - /* Probably we're using the wrong byte ordering. */ - bfd_set_error (bfd_error_wrong_format); - goto byebyebye; - } - - ardata->cache = 0; - - stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE); - /* skip sym count and string sz */ - stringbase = ((char *) raw_armap - + HPUX_SYMDEF_COUNT_SIZE - + BSD_STRING_COUNT_SIZE); - rbase = (bfd_byte *) stringbase + stringsize; - ardata->symdefs = (carsym *) bfd_alloc (abfd, - (ardata->symdef_count - * BSD_SYMDEF_SIZE)); - if (!ardata->symdefs) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - for (counter = 0, set = ardata->symdefs; - counter < ardata->symdef_count; - counter++, set++, rbase += BSD_SYMDEF_SIZE) - { - set->name = bfd_h_get_32 (abfd, rbase) + stringbase; - set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary if you have to */ - ardata->first_file_filepos += (ardata->first_file_filepos) % 2; - /* FIXME, we should provide some way to free raw_ardata when - we are done using the strings from it. For now, it seems - to be allocated on an obstack anyway... */ - bfd_has_map (abfd) = true; - return true; -} - -/** Extended name table. - - Normally archives support only 14-character filenames. - - Intel has extended the format: longer names are stored in a special - element (the first in the archive, or second if there is an armap); - the name in the ar_hdr is replaced by <space><index into filename - element>. Index is the P.R. of an int (decimal). Data General have - extended the format by using the prefix // for the special element */ - -/* Returns false on error, true otherwise */ -boolean -_bfd_slurp_extended_name_table (abfd) - bfd *abfd; -{ - char nextname[17]; - struct areltdata *namedata; - - /* FIXME: Formatting sucks here, and in case of failure of BFD_READ, - we probably don't want to return true. */ - if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16) - { - - if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) - return false; - - if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 && - strncmp (nextname, "// ", 16) != 0) - { - bfd_ardata (abfd)->extended_names = NULL; - return true; - } - - namedata = _bfd_snarf_ar_hdr (abfd); - if (namedata == NULL) - return false; - - bfd_ardata (abfd)->extended_names = - bfd_zalloc (abfd, namedata->parsed_size); - if (bfd_ardata (abfd)->extended_names == NULL) - { - bfd_set_error (bfd_error_no_memory); - byebye: - bfd_release (abfd, (PTR) namedata); - return false; - } - - if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1, - namedata->parsed_size, abfd) != namedata->parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names)); - bfd_ardata (abfd)->extended_names = NULL; - goto byebye; - } - - /* Since the archive is supposed to be printable if it contains - text, the entries in the list are newline-padded, not null - padded. In SVR4-style archives, the names also have a - trailing '/'. We'll fix both problems here.. */ - { - char *temp = bfd_ardata (abfd)->extended_names; - char *limit = temp + namedata->parsed_size; - for (; temp < limit; ++temp) - if (*temp == '\012') - temp[temp[-1] == '/' ? -1 : 0] = '\0'; - } - - /* Pad to an even boundary if you have to */ - bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd); - bfd_ardata (abfd)->first_file_filepos += - (bfd_ardata (abfd)->first_file_filepos) % 2; - - /* FIXME, we can't release namedata here because it was allocated - below extended_names on the obstack... */ - /* bfd_release (abfd, namedata); */ - } - return true; -} - -#ifdef VMS - -/* Return a copy of the stuff in the filename between any :]> and a - semicolon */ -static const char * -normalize (file) - const char *file; -{ - CONST char *first; - CONST char *last; - char *copy; - - first = file + strlen (file) - 1; - last = first + 1; - - while (first != file) - { - if (*first == ';') - last = first; - if (*first == ':' || *first == ']' || *first == '>') - { - first++; - break; - } - first--; - } - - - copy = malloc (last - first + 1); - if (!copy) - return copy; - - memcpy (copy, first, last - first); - copy[last - first] = 0; - - return copy; -} - -#else -static const char * -normalize (file) - const char *file; -{ - CONST char *filename = strrchr (file, '/'); - - if (filename != (char *) NULL) - filename++; - else - filename = file; - return filename; -} -#endif - -/* Follows archive_head and produces an extended name table if - necessary. Returns (in tabloc) a pointer to an extended name - table, and in tablen the length of the table. If it makes an entry - it clobbers the filename so that the element may be written without - further massage. Returns true if it ran successfully, false if - something went wrong. A successful return may still involve a - zero-length tablen! */ - -static boolean -bfd_construct_extended_name_table (abfd, tabloc, tablen) - bfd *abfd; - char **tabloc; - unsigned int *tablen; -{ - unsigned int maxname = abfd->xvec->ar_max_namelen; - unsigned int total_namelen = 0; - bfd *current; - char *strptr; - - *tablen = 0; - - /* Figure out how long the table should be */ - for (current = abfd->archive_head; current != NULL; current = current->next) - { - CONST char *normal = normalize (current->filename); - unsigned int thislen; - - if (!normal) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - thislen = strlen (normal); - if (thislen > maxname) - total_namelen += thislen + 1; /* leave room for \n */ - } - - if (total_namelen == 0) - return true; - - *tabloc = bfd_zalloc (abfd, total_namelen); - if (*tabloc == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - *tablen = total_namelen; - strptr = *tabloc; - - for (current = abfd->archive_head; current != NULL; current = - current->next) - { - CONST char *normal = normalize (current->filename); - unsigned int thislen; - - if (!normal) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - thislen = strlen (normal); - if (thislen > maxname) - { - /* Works for now; may need to be re-engineered if we - encounter an oddball archive format and want to - generalise this hack. */ - struct ar_hdr *hdr = arch_hdr (current); - strcpy (strptr, normal); - strptr[thislen] = '\012'; - hdr->ar_name[0] = ar_padchar (current); - /* We know there will always be enough room (one of the few - cases where you may safely use sprintf). */ - sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc)); - /* Kinda Kludgy. We should just use the returned value of - sprintf but not all implementations get this right */ - { - char *temp = hdr->ar_name + 2; - for (; temp < hdr->ar_name + maxname; temp++) - if (*temp == '\0') - *temp = ' '; - } - strptr += thislen + 1; - } - } - - return true; -} - -/** A couple of functions for creating ar_hdrs */ - -/* Takes a filename, returns an arelt_data for it, or NULL if it can't - make one. The filename must refer to a filename in the filesystem. - The filename field of the ar_hdr will NOT be initialized */ - -static struct areltdata * -bfd_ar_hdr_from_filesystem (abfd, filename) - bfd *abfd; - const char *filename; -{ - struct stat status; - struct areltdata *ared; - struct ar_hdr *hdr; - char *temp, *temp1; - - if (stat (filename, &status) != 0) - { - bfd_set_error (bfd_error_system_call); - return NULL; - } - - ared = (struct areltdata *) bfd_zalloc (abfd, sizeof (struct ar_hdr) + - sizeof (struct areltdata)); - if (ared == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata)); - - /* ar headers are space padded, not null padded! */ - memset ((PTR) hdr, ' ', sizeof (struct ar_hdr)); - - strncpy (hdr->ar_fmag, ARFMAG, 2); - - /* Goddamned sprintf doesn't permit MAXIMUM field lengths */ - sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime); - sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid); - sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid); - sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode); - sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size); - /* Correct for a lossage in sprintf whereby it null-terminates. I cannot - understand how these C losers could design such a ramshackle bunch of - IO operations */ - temp = (char *) hdr; - temp1 = temp + sizeof (struct ar_hdr) - 2; - for (; temp < temp1; temp++) - { - if (*temp == '\0') - *temp = ' '; - } - strncpy (hdr->ar_fmag, ARFMAG, 2); - ared->parsed_size = status.st_size; - ared->arch_header = (char *) hdr; - - return ared; -} - -/* This is magic required by the "ar" program. Since it's - undocumented, it's undocumented. You may think that it would take - a strong stomach to write this, and it does, but it takes even a - stronger stomach to try to code around such a thing! */ - -struct ar_hdr * -bfd_special_undocumented_glue (abfd, filename) - bfd *abfd; - char *filename; -{ - struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename); - if (ar_elt == NULL) - return NULL; - return (struct ar_hdr *) ar_elt->arch_header; -} - - -/* Analogous to stat call */ -int -bfd_generic_stat_arch_elt (abfd, buf) - bfd *abfd; - struct stat *buf; -{ - struct ar_hdr *hdr; - char *aloser; - - if (abfd->arelt_data == NULL) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - hdr = arch_hdr (abfd); - -#define foo(arelt, stelt, size) \ - buf->stelt = strtol (hdr->arelt, &aloser, size); \ - if (aloser == hdr->arelt) return -1; - - foo (ar_date, st_mtime, 10); - foo (ar_uid, st_uid, 10); - foo (ar_gid, st_gid, 10); - foo (ar_mode, st_mode, 8); - - buf->st_size = arch_eltdata (abfd)->parsed_size; - - return 0; -} - -void -bfd_dont_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - /* FIXME: This interacts unpleasantly with ar's quick-append option. - Fortunately ic960 users will never use that option. Fixing this - is very hard; fortunately I know how to do it and will do so once - intel's release is out the door. */ - - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - int length; - CONST char *filename = normalize (pathname); - int maxlen = ar_maxnamelen (abfd); - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - - if (length < maxlen) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -void -bfd_bsd_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - int length; - CONST char *filename = strrchr (pathname, '/'); - int maxlen = ar_maxnamelen (abfd); - - if (filename == NULL) - filename = pathname; - else - ++filename; - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { - /* pathname: meet procrustes */ - memcpy (hdr->ar_name, filename, maxlen); - length = maxlen; - } - - if (length < maxlen) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* Store name into ar header. Truncates the name to fit. - 1> strip pathname to be just the basename. - 2> if it's short enuf to fit, stuff it in. - 3> If it doesn't end with .o, truncate it to fit - 4> truncate it before the .o, append .o, stuff THAT in. */ - -/* This is what gnu ar does. It's better but incompatible with the - bsd ar. */ - -void -bfd_gnu_truncate_arname (abfd, pathname, arhdr) - bfd *abfd; - CONST char *pathname; - char *arhdr; -{ - struct ar_hdr *hdr = (struct ar_hdr *) arhdr; - int length; - CONST char *filename = strrchr (pathname, '/'); - int maxlen = ar_maxnamelen (abfd); - - if (filename == NULL) - filename = pathname; - else - ++filename; - - length = strlen (filename); - - if (length <= maxlen) - memcpy (hdr->ar_name, filename, length); - else - { /* pathname: meet procrustes */ - memcpy (hdr->ar_name, filename, maxlen); - if ((filename[length - 2] == '.') && (filename[length - 1] == 'o')) - { - hdr->ar_name[maxlen - 2] = '.'; - hdr->ar_name[maxlen - 1] = 'o'; - } - length = maxlen; - } - - if (length < 16) - (hdr->ar_name)[length] = ar_padchar (abfd); -} - -/* The BFD is open for write and has its format set to bfd_archive */ - -boolean -_bfd_write_archive_contents (arch) - bfd *arch; -{ - bfd *current; - char *etable = NULL; - unsigned int elength = 0; - boolean makemap = bfd_has_map (arch); - boolean hasobjects = false; /* if no .o's, don't bother to make a map */ - bfd_size_type wrote; - unsigned int i; - int tries; - - /* Verify the viability of all entries; if any of them live in the - filesystem (as opposed to living in an archive open for input) - then construct a fresh ar_hdr for them. */ - for (current = arch->archive_head; current; current = current->next) - { - if (bfd_write_p (current)) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - if (!current->arelt_data) - { - current->arelt_data = - (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename); - if (!current->arelt_data) - return false; - - /* Put in the file name */ - BFD_SEND (arch, _bfd_truncate_arname, (arch, - current->filename, - (char *) arch_hdr (current))); - } - - if (makemap && ! hasobjects) - { /* don't bother if we won't make a map! */ - if ((bfd_check_format (current, bfd_object)) -#if 0 /* FIXME -- these are not set correctly */ - && ((bfd_get_file_flags (current) & HAS_SYMS)) -#endif - ) - hasobjects = true; - } - } - - if (!bfd_construct_extended_name_table (arch, &etable, &elength)) - return false; - - if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0) - return false; -#ifdef GNU960 - wrote = bfd_write (BFD_GNU960_ARMAG (arch), 1, SARMAG, arch); -#else - wrote = bfd_write (ARMAG, 1, SARMAG, arch); -#endif - if (wrote != SARMAG) - return false; - - if (makemap && hasobjects) - { - if (compute_and_write_armap (arch, elength) != true) - return false; - } - - if (elength != 0) - { - struct ar_hdr hdr; - - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - if (ar_padchar (arch) == '/') - sprintf (&(hdr.ar_name[0]), "//"); - else - sprintf (&(hdr.ar_name[0]), "ARFILENAMES/"); - sprintf (&(hdr.ar_size[0]), "%-10d", (int) elength); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - if ((bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - || bfd_write (etable, 1, elength, arch) != elength) - return false; - if ((elength % 2) == 1) - { - if (bfd_write ("\012", 1, 1, arch) != 1) - return false; - } - } - - for (current = arch->archive_head; current; current = current->next) - { - char buffer[DEFAULT_BUFFERSIZE]; - unsigned int remaining = arelt_size (current); - struct ar_hdr *hdr = arch_hdr (current); - - /* write ar header */ - if (bfd_write ((char *) hdr, 1, sizeof (*hdr), arch) != sizeof (*hdr)) - return false; - if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0) - return false; - while (remaining) - { - unsigned int amt = DEFAULT_BUFFERSIZE; - if (amt > remaining) - amt = remaining; - errno = 0; - if (bfd_read (buffer, amt, 1, current) != amt) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - return false; - } - if (bfd_write (buffer, amt, 1, arch) != amt) - return false; - remaining -= amt; - } - if ((arelt_size (current) % 2) == 1) - { - if (bfd_write ("\012", 1, 1, arch) != 1) - return false; - } - } - - /* Verify the timestamp in the archive file. If it would not be - accepted by the linker, rewrite it until it would be. If - anything odd happens, break out and just return. (The Berkeley - linker checks the timestamp and refuses to read the - table-of-contents if it is >60 seconds less than the file's - modified-time. That painful hack requires this painful hack. */ - - tries = 1; - do - { - /* FIXME! This kludge is to avoid adding a member to the xvec, - while generating a small patch for Adobe. FIXME! The - update_armap_timestamp function call should be in the xvec, - thus: - - if (bfd_update_armap_timestamp (arch) == true) break; - ^ - - Instead, we check whether in a BSD archive, and call - directly. */ - - if (arch->xvec->write_armap != bsd_write_armap) - break; - if (bsd_update_armap_timestamp (arch) == true) /* FIXME!!! Vector it */ - break; - if (tries > 0) - fprintf (stderr, - "Warning: writing archive was slow: rewriting timestamp\n"); - } - while (++tries < 6); - - return true; -} - -/* Note that the namidx for the first symbol is 0 */ - -static boolean -compute_and_write_armap (arch, elength) - bfd *arch; - unsigned int elength; -{ - char *first_name = NULL; - bfd *current; - file_ptr elt_no = 0; - struct orl *map = NULL; - int orl_max = 1024; /* fine initial default */ - int orl_count = 0; - int stridx = 0; /* string index */ - asymbol **syms = NULL; - long syms_max = 0; - boolean ret; - - /* Dunno if this is the best place for this info... */ - if (elength != 0) - elength += sizeof (struct ar_hdr); - elength += elength % 2; - - map = (struct orl *) malloc (orl_max * sizeof (struct orl)); - if (map == NULL) - goto no_memory_return; - - /* We put the symbol names on the arch obstack, and then discard - them when done. */ - first_name = bfd_alloc (arch, 1); - if (first_name == NULL) - goto no_memory_return; - - /* Drop all the files called __.SYMDEF, we're going to make our - own */ - while (arch->archive_head && - strcmp (arch->archive_head->filename, "__.SYMDEF") == 0) - arch->archive_head = arch->archive_head->next; - - /* Map over each element */ - for (current = arch->archive_head; - current != (bfd *) NULL; - current = current->next, elt_no++) - { - if ((bfd_check_format (current, bfd_object) == true) - && ((bfd_get_file_flags (current) & HAS_SYMS))) - { - long storage; - long symcount; - long src_count; - - storage = bfd_get_symtab_upper_bound (current); - if (storage < 0) - goto error_return; - - if (storage != 0) - { - if (storage > syms_max) - { - if (syms_max > 0) - free (syms); - syms_max = storage; - syms = (asymbol **) malloc ((size_t) syms_max); - if (syms == NULL) - goto no_memory_return; - } - symcount = bfd_canonicalize_symtab (current, syms); - if (symcount < 0) - goto error_return; - - /* Now map over all the symbols, picking out the ones we want */ - for (src_count = 0; src_count < symcount; src_count++) - { - flagword flags = (syms[src_count])->flags; - asection *sec = syms[src_count]->section; - - if ((flags & BSF_GLOBAL || - flags & BSF_WEAK || - flags & BSF_INDIRECT || - bfd_is_com_section (sec)) - && ! bfd_is_und_section (sec)) - { - size_t namelen; - struct orl *new_map; - - /* This symbol will go into the archive header */ - if (orl_count == orl_max) - { - orl_max *= 2; - new_map = ((struct orl *) - realloc ((PTR) map, - orl_max * sizeof (struct orl))); - if (new_map == (struct orl *) NULL) - goto no_memory_return; - - map = new_map; - } - - namelen = strlen (syms[src_count]->name); - map[orl_count].name = ((char **) - bfd_alloc (arch, - sizeof (char *))); - if (map[orl_count].name == NULL) - goto no_memory_return; - *(map[orl_count].name) = bfd_alloc (arch, namelen + 1); - if (*(map[orl_count].name) == NULL) - goto no_memory_return; - strcpy (*(map[orl_count].name), syms[src_count]->name); - (map[orl_count]).pos = (file_ptr) current; - (map[orl_count]).namidx = stridx; - - stridx += namelen + 1; - ++orl_count; - } - } - } - - /* Now ask the BFD to free up any cached information, so we - don't fill all of memory with symbol tables. */ - if (! bfd_free_cached_info (current)) - goto error_return; - } - } - - /* OK, now we have collected all the data, let's write them out */ - ret = BFD_SEND (arch, write_armap, - (arch, elength, map, orl_count, stridx)); - - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return ret; - - no_memory_return: - bfd_set_error (bfd_error_no_memory); - - error_return: - if (syms_max > 0) - free (syms); - if (map != NULL) - free (map); - if (first_name != NULL) - bfd_release (arch, first_name); - - return false; -} - -boolean -bsd_write_armap (arch, elength, map, orl_count, stridx) - bfd *arch; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - int padit = stridx & 1; - unsigned int ranlibsize = orl_count * sizeof (struct ranlib); - unsigned int stringsize = stridx + padit; - /* Include 8 bytes to store ranlibsize and stringsize in output. */ - unsigned int mapsize = ranlibsize + stringsize + 8; - file_ptr firstreal; - bfd *current = arch->archive_head; - bfd *last_elt = current; /* last element arch seen */ - int temp; - int count; - struct ar_hdr hdr; - struct stat statbuf; - unsigned int i; - - firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG; - - stat (arch->filename, &statbuf); - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - sprintf (hdr.ar_name, RANLIBMAG); - /* Remember the timestamp, to keep it holy. But fudge it a little. */ - bfd_ardata (arch)->armap_timestamp = statbuf.st_mtime + ARMAP_TIME_OFFSET; - bfd_ardata (arch)->armap_datepos = (SARMAG - + offsetof (struct ar_hdr, ar_date[0])); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - sprintf (hdr.ar_uid, "%d", getuid ()); - sprintf (hdr.ar_gid, "%d", getgid ()); - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - strncpy (hdr.ar_fmag, ARFMAG, 2); - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - if (bfd_write ((char *) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return false; - bfd_h_put_32 (arch, (bfd_vma) ranlibsize, (PTR) &temp); - if (bfd_write (&temp, 1, sizeof (temp), arch) != sizeof (temp)) - return false; - - for (count = 0; count < orl_count; count++) - { - struct symdef outs; - struct symdef *outp = &outs; - - if (((bfd *) (map[count]).pos) != last_elt) - { - do - { - firstreal += arelt_size (current) + sizeof (struct ar_hdr); - firstreal += firstreal % 2; - current = current->next; - } - while (current != (bfd *) (map[count]).pos); - } /* if new archive element */ - - last_elt = current; - bfd_h_put_32 (arch, ((map[count]).namidx), (PTR) &outs.s.string_offset); - bfd_h_put_32 (arch, firstreal, (PTR) &outs.file_offset); - if (bfd_write ((char *) outp, 1, sizeof (outs), arch) != sizeof (outs)) - return false; - } - - /* now write the strings themselves */ - bfd_h_put_32 (arch, stringsize, (PTR) &temp); - if (bfd_write ((PTR) &temp, 1, sizeof (temp), arch) != sizeof (temp)) - return false; - for (count = 0; count < orl_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_write (*map[count].name, 1, len, arch) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for sun's ar we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, arch) != 1) - return false; - } - - return true; -} - -/* At the end of archive file handling, update the timestamp in the - file, so the linker will accept it. - - Return true if the timestamp was OK, or an unusual problem happened. - Return false if we updated the timestamp. */ - -static boolean -bsd_update_armap_timestamp (arch) - bfd *arch; -{ - struct stat archstat; - struct ar_hdr hdr; - int i; - - /* Flush writes, get last-write timestamp from file, and compare it - to the timestamp IN the file. */ - bfd_flush (arch); - if (bfd_stat (arch, &archstat) == -1) - { - perror ("Reading archive file mod timestamp"); - return true; /* Can't read mod time for some reason */ - } - if (archstat.st_mtime <= bfd_ardata (arch)->armap_timestamp) - return true; /* OK by the linker's rules */ - - /* Update the timestamp. */ - bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET; - - /* Prepare an ASCII version suitable for writing. */ - memset (hdr.ar_date, 0, sizeof (hdr.ar_date)); - sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp); - for (i = 0; i < sizeof (hdr.ar_date); i++) - if (hdr.ar_date[i] == '\0') - (hdr.ar_date)[i] = ' '; - - /* Write it into the file. */ - if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0 - || (bfd_write (hdr.ar_date, sizeof (hdr.ar_date), 1, arch) - != sizeof (hdr.ar_date))) - { - /* FIXME: bfd can't call perror. */ - perror ("Writing updated armap timestamp"); - return true; /* Some error while writing */ - } - - return false; /* We updated the timestamp successfully. */ -} - -/* A coff armap looks like : - lARMAG - struct ar_hdr with name = '/' - number of symbols - offset of file for symbol 0 - offset of file for symbol 1 - - offset of file for symbol n-1 - symbol name 0 - symbol name 1 - - symbol name n-1 -*/ - -boolean -coff_write_armap (arch, elength, map, symbol_count, stridx) - bfd *arch; - unsigned int elength; - struct orl *map; - unsigned int symbol_count; - int stridx; -{ - /* The size of the ranlib is the number of exported symbols in the - archive * the number of bytes in a int, + an int for the count */ - unsigned int ranlibsize = (symbol_count * 4) + 4; - unsigned int stringsize = stridx; - unsigned int mapsize = stringsize + ranlibsize; - file_ptr archive_member_file_ptr; - bfd *current = arch->archive_head; - int count; - struct ar_hdr hdr; - unsigned int i; - int padit = mapsize & 1; - - if (padit) - mapsize++; - - /* work out where the first object file will go in the archive */ - archive_member_file_ptr = (mapsize - + elength - + sizeof (struct ar_hdr) - + SARMAG); - - memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); - hdr.ar_name[0] = '/'; - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - sprintf (hdr.ar_date, "%ld", (long) time (NULL)); - /* This, at least, is what Intel coff sets the values to.: */ - sprintf ((hdr.ar_uid), "%d", 0); - sprintf ((hdr.ar_gid), "%d", 0); - sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); - strncpy (hdr.ar_fmag, ARFMAG, 2); - - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *) (&hdr))[i] == '\0') - (((char *) (&hdr))[i]) = ' '; - - /* Write the ar header for this item and the number of symbols */ - - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch) - != sizeof (struct ar_hdr)) - return false; - - bfd_write_bigendian_4byte_int (arch, symbol_count); - - /* Two passes, first write the file offsets for each symbol - - remembering that each offset is on a two byte boundary. */ - - /* Write out the file offset for the file associated with each - symbol, and remember to keep the offsets padded out. */ - - current = arch->archive_head; - count = 0; - while (current != (bfd *) NULL && count < symbol_count) - { - /* For each symbol which is used defined in this object, write out - the object file's address in the archive */ - - while (((bfd *) (map[count]).pos) == current) - { - bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr); - count++; - } - /* Add size of this archive entry */ - archive_member_file_ptr += (arelt_size (current) - + sizeof (struct ar_hdr)); - /* remember aboout the even alignment */ - archive_member_file_ptr += archive_member_file_ptr % 2; - current = current->next; - } - - /* now write the strings themselves */ - for (count = 0; count < symbol_count; count++) - { - size_t len = strlen (*map[count].name) + 1; - - if (bfd_write (*map[count].name, 1, len, arch) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for arc960 we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, arch) != 1) - return false; - } - - return true; -} diff --git a/gnu/usr.bin/gdb/bfd/archures.c b/gnu/usr.bin/gdb/bfd/archures.c deleted file mode 100644 index 1bff43a..0000000 --- a/gnu/usr.bin/gdb/bfd/archures.c +++ /dev/null @@ -1,745 +0,0 @@ -/* BFD library support routines for architectures. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Hacked by John Gilmore and Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* - -SECTION - Architectures - - BFD keeps one atom in a BFD describing the - architecture of the data attached to the BFD: a pointer to a - <<bfd_arch_info_type>>. - - Pointers to structures can be requested independently of a BFD - so that an architecture's information can be interrogated - without access to an open BFD. - - The architecture information is provided by each architecture package. - The set of default architectures is selected by the macro - <<SELECT_ARCHITECTURES>>. This is normally set up in the - @file{config/@var{target}.mt} file of your choice. If the name is not - defined, then all the architectures supported are included. - - When BFD starts up, all the architectures are called with an - initialize method. It is up to the architecture back end to - insert as many items into the list of architectures as it wants to; - generally this would be one for each machine and one for the - default case (an item with a machine field of 0). - - BFD's idea of an architecture is implemented in @file{archures.c}. -*/ - -/* - -SUBSECTION - bfd_architecture - -DESCRIPTION - This enum gives the object file's CPU architecture, in a - global sense---i.e., what processor family does it belong to? - Another field indicates which processor within - the family is in use. The machine gives a number which - distinguishes different versions of the architecture, - containing, for example, 2 and 3 for Intel i960 KA and i960 KB, - and 68020 and 68030 for Motorola 68020 and 68030. - -.enum bfd_architecture -.{ -. bfd_arch_unknown, {* File arch not known *} -. bfd_arch_obscure, {* Arch known, not one of these *} -. bfd_arch_m68k, {* Motorola 68xxx *} -. bfd_arch_vax, {* DEC Vax *} -. bfd_arch_i960, {* Intel 960 *} -. {* The order of the following is important. -. lower number indicates a machine type that -. only accepts a subset of the instructions -. available to machines with higher numbers. -. The exception is the "ca", which is -. incompatible with all other machines except -. "core". *} -. -.#define bfd_mach_i960_core 1 -.#define bfd_mach_i960_ka_sa 2 -.#define bfd_mach_i960_kb_sb 3 -.#define bfd_mach_i960_mc 4 -.#define bfd_mach_i960_xa 5 -.#define bfd_mach_i960_ca 6 -. -. bfd_arch_a29k, {* AMD 29000 *} -. bfd_arch_sparc, {* SPARC *} -. bfd_arch_mips, {* MIPS Rxxxx *} -. bfd_arch_i386, {* Intel 386 *} -. bfd_arch_we32k, {* AT&T WE32xxx *} -. bfd_arch_tahoe, {* CCI/Harris Tahoe *} -. bfd_arch_i860, {* Intel 860 *} -. bfd_arch_romp, {* IBM ROMP PC/RT *} -. bfd_arch_alliant, {* Alliant *} -. bfd_arch_convex, {* Convex *} -. bfd_arch_m88k, {* Motorola 88xxx *} -. bfd_arch_pyramid, {* Pyramid Technology *} -. bfd_arch_h8300, {* Hitachi H8/300 *} -.#define bfd_mach_h8300 1 -.#define bfd_mach_h8300h 2 -. bfd_arch_powerpc, {* PowerPC *} -. bfd_arch_rs6000, {* IBM RS/6000 *} -. bfd_arch_hppa, {* HP PA RISC *} -. bfd_arch_z8k, {* Zilog Z8000 *} -.#define bfd_mach_z8001 1 -.#define bfd_mach_z8002 2 -. bfd_arch_h8500, {* Hitachi H8/500 *} -. bfd_arch_sh, {* Hitachi SH *} -. bfd_arch_alpha, {* Dec Alpha *} -. bfd_arch_ns32k, {* National Semiconductors ns32000 *} -. bfd_arch_last -. }; - - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* - -SUBSECTION - bfd_arch_info - -DESCRIPTION - This structure contains information on architectures for use - within BFD. - -. -.typedef struct bfd_arch_info -.{ -. int bits_per_word; -. int bits_per_address; -. int bits_per_byte; -. enum bfd_architecture arch; -. long mach; -. char *arch_name; -. CONST char *printable_name; -. unsigned int section_align_power; -. {* true if this is the default machine for the architecture *} -. boolean the_default; -. CONST struct bfd_arch_info * (*compatible) -. PARAMS ((CONST struct bfd_arch_info *a, -. CONST struct bfd_arch_info *b)); -. -. boolean (*scan) PARAMS ((CONST struct bfd_arch_info *, CONST char *)); -. {* How to disassemble an instruction, producing a printable -. representation on a specified stdio stream. This isn't -. defined for most processors at present, because of the size -. of the additional tables it would drag in, and because gdb -. wants to use a different interface. *} -. unsigned int (*disassemble) PARAMS ((bfd_vma addr, CONST char *data, -. PTR stream)); -. -. struct bfd_arch_info *next; -.} bfd_arch_info_type; -*/ - -bfd_arch_info_type *bfd_arch_info_list; - - -/* -FUNCTION - bfd_printable_name - -SYNOPSIS - CONST char *bfd_printable_name(bfd *abfd); - -DESCRIPTION - Return a printable string representing the architecture and machine - from the pointer to the architecture info structure. - -*/ - -CONST char * -bfd_printable_name (abfd) - bfd *abfd; -{ - return abfd->arch_info->printable_name; -} - - - -/* -FUNCTION - bfd_scan_arch - -SYNOPSIS - bfd_arch_info_type *bfd_scan_arch(CONST char *string); - -DESCRIPTION - Figure out if BFD supports any cpu which could be described with - the name @var{string}. Return a pointer to an <<arch_info>> - structure if a machine is found, otherwise NULL. - -*/ - -bfd_arch_info_type * -bfd_scan_arch (string) - CONST char *string; -{ - struct bfd_arch_info *ap; - - /* Look through all the installed architectures */ - for (ap = bfd_arch_info_list; - ap != (bfd_arch_info_type *)NULL; - ap = ap->next) { - - if (ap->scan(ap, string)) - return ap; - } - return (bfd_arch_info_type *)NULL; -} - - - -/* -FUNCTION - bfd_arch_get_compatible - -SYNOPSIS - CONST bfd_arch_info_type *bfd_arch_get_compatible( - CONST bfd *abfd, - CONST bfd *bbfd); - -DESCRIPTION - Determine whether two BFDs' - architectures and machine types are compatible. Calculates - the lowest common denominator between the two architectures - and machine types implied by the BFDs and returns a pointer to - an <<arch_info>> structure describing the compatible machine. -*/ - -CONST bfd_arch_info_type * -bfd_arch_get_compatible (abfd, bbfd) - CONST bfd *abfd; - CONST bfd *bbfd; -{ - return abfd->arch_info->compatible(abfd->arch_info,bbfd->arch_info); -} - - -/* -INTERNAL_DEFINITION - bfd_default_arch_struct - -DESCRIPTION - The <<bfd_default_arch_struct>> is an item of - <<bfd_arch_info_type>> which has been initialized to a fairly - generic state. A BFD starts life by pointing to this - structure, until the correct back end has determined the real - architecture of the file. - -.extern bfd_arch_info_type bfd_default_arch_struct; - -*/ - -bfd_arch_info_type bfd_default_arch_struct = -{ - 32,32,8,bfd_arch_unknown,0,"unknown","unknown",2,true, - bfd_default_compatible, - bfd_default_scan, - 0, -}; - -/* -FUNCTION - bfd_set_arch_info - -SYNOPSIS - void bfd_set_arch_info(bfd *abfd, bfd_arch_info_type *arg); - -DESCRIPTION - Set the architecture info of @var{abfd} to @var{arg}. -*/ - -void -bfd_set_arch_info (abfd, arg) - bfd *abfd; - bfd_arch_info_type *arg; -{ - abfd->arch_info = arg; -} - -/* -INTERNAL_FUNCTION - bfd_default_set_arch_mach - -SYNOPSIS - boolean bfd_default_set_arch_mach(bfd *abfd, - enum bfd_architecture arch, - unsigned long mach); - -DESCRIPTION - Set the architecture and machine type in BFD @var{abfd} - to @var{arch} and @var{mach}. Find the correct - pointer to a structure and insert it into the <<arch_info>> - pointer. -*/ - -boolean -bfd_default_set_arch_mach (abfd, arch, mach) - bfd *abfd; - enum bfd_architecture arch; - unsigned long mach; -{ - static struct bfd_arch_info *old_ptr = &bfd_default_arch_struct; - boolean found = false; - /* run through the table to find the one we want, we keep a little - cache to speed things up */ - if (old_ptr == 0 || arch != old_ptr->arch || mach != old_ptr->mach) { - bfd_arch_info_type *ptr; - old_ptr = (bfd_arch_info_type *)NULL; - for (ptr = bfd_arch_info_list; - ptr != (bfd_arch_info_type *)NULL; - ptr= ptr->next) { - if (ptr->arch == arch && - ((ptr->mach == mach) || (ptr->the_default && mach == 0))) { - old_ptr = ptr; - found = true; - break; - } - } - if (found==false) { - /*looked for it and it wasn't there, so put in the default */ - old_ptr = &bfd_default_arch_struct; - bfd_set_error (bfd_error_bad_value); - } - } - else { - /* it was in the cache */ - found = true; - } - - abfd->arch_info = old_ptr; - - return found; -} - - -/* -FUNCTION - bfd_get_arch - -SYNOPSIS - enum bfd_architecture bfd_get_arch(bfd *abfd); - -DESCRIPTION - Return the enumerated type which describes the BFD @var{abfd}'s - architecture. - -*/ - -enum bfd_architecture -bfd_get_arch (abfd) - bfd *abfd; -{ - return abfd->arch_info->arch; -} - -/* -FUNCTION - bfd_get_mach - -SYNOPSIS - unsigned long bfd_get_mach(bfd *abfd); - -DESCRIPTION - Return the long type which describes the BFD @var{abfd}'s - machine. -*/ - -unsigned long -bfd_get_mach (abfd) - bfd *abfd; -{ - return abfd->arch_info->mach; -} - -/* -FUNCTION - bfd_arch_bits_per_byte - -SYNOPSIS - unsigned int bfd_arch_bits_per_byte(bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's bytes. - -*/ - -unsigned int -bfd_arch_bits_per_byte (abfd) - bfd *abfd; -{ - return abfd->arch_info->bits_per_byte; -} - -/* -FUNCTION - bfd_arch_bits_per_address - -SYNOPSIS - unsigned int bfd_arch_bits_per_address(bfd *abfd); - -DESCRIPTION - Return the number of bits in one of the BFD @var{abfd}'s - architecture's addresses. -*/ - -unsigned int -bfd_arch_bits_per_address (abfd) - bfd *abfd; -{ - return abfd->arch_info->bits_per_address; -} - - -extern void bfd_a29k_arch PARAMS ((void)); -extern void bfd_alpha_arch PARAMS ((void)); -extern void bfd_h8300_arch PARAMS ((void)); -extern void bfd_h8500_arch PARAMS ((void)); -extern void bfd_hppa_arch PARAMS ((void)); -extern void bfd_i386_arch PARAMS ((void)); -extern void bfd_i960_arch PARAMS ((void)); -extern void bfd_m68k_arch PARAMS ((void)); -extern void bfd_m88k_arch PARAMS ((void)); -extern void bfd_mips_arch PARAMS ((void)); -extern void bfd_powerpc_arch PARAMS ((void)); -extern void bfd_rs6000_arch PARAMS ((void)); -extern void bfd_sh_arch PARAMS ((void)); -extern void bfd_sparc_arch PARAMS ((void)); -extern void bfd_vax_arch PARAMS ((void)); -extern void bfd_we32k_arch PARAMS ((void)); -extern void bfd_z8k_arch PARAMS ((void)); -extern void bfd_ns32k_arch PARAMS ((void)); - -static void (*archures_init_table[]) PARAMS ((void)) = -{ -#ifdef SELECT_ARCHITECTURES - SELECT_ARCHITECTURES, -#else - bfd_a29k_arch, - bfd_alpha_arch, - bfd_h8300_arch, - bfd_h8500_arch, - bfd_hppa_arch, - bfd_i386_arch, - bfd_i960_arch, - bfd_m68k_arch, - bfd_m88k_arch, - bfd_mips_arch, - bfd_powerpc_arch, - bfd_rs6000_arch, - bfd_sh_arch, - bfd_sparc_arch, - bfd_vax_arch, - bfd_we32k_arch, - bfd_z8k_arch, - bfd_ns32k_arch, -#endif - 0 - }; - - - -/* -INTERNAL_FUNCTION - bfd_arch_init - -SYNOPSIS - void bfd_arch_init(void); - -DESCRIPTION - Initialize the architecture dispatch table by - calling all installed architecture packages and getting them - to poke around. -*/ - -void -bfd_arch_init () -{ - void (**ptable) PARAMS ((void)); - for (ptable = archures_init_table; - *ptable ; - ptable++) - { - (*ptable)(); - } -} - - -/* -INTERNAL_FUNCTION - bfd_arch_linkin - -SYNOPSIS - void bfd_arch_linkin(bfd_arch_info_type *ptr); - -DESCRIPTION - Link the architecture info structure @var{ptr} into the list. -*/ - -void -bfd_arch_linkin (ptr) - bfd_arch_info_type *ptr; -{ - ptr->next = bfd_arch_info_list; - bfd_arch_info_list = ptr; -} - - -/* -INTERNAL_FUNCTION - bfd_default_compatible - -SYNOPSIS - CONST bfd_arch_info_type *bfd_default_compatible - (CONST bfd_arch_info_type *a, - CONST bfd_arch_info_type *b); - -DESCRIPTION - The default function for testing for compatibility. -*/ - -CONST bfd_arch_info_type * -bfd_default_compatible (a,b) - CONST bfd_arch_info_type *a; - CONST bfd_arch_info_type *b; -{ - if(a->arch != b->arch) return NULL; - - if (a->mach > b->mach) { - return a; - } - if (b->mach > a->mach) { - return b; - } - return a; -} - - -/* -INTERNAL_FUNCTION - bfd_default_scan - -SYNOPSIS - boolean bfd_default_scan(CONST struct bfd_arch_info *info, CONST char *string); - -DESCRIPTION - The default function for working out whether this is an - architecture hit and a machine hit. -*/ - -boolean -bfd_default_scan (info, string) - CONST struct bfd_arch_info *info; - CONST char *string; -{ - CONST char *ptr_src; - CONST char *ptr_tst; - unsigned long number; - enum bfd_architecture arch; - /* First test for an exact match */ - if (strcmp(string, info->printable_name) == 0) return true; - - /* See how much of the supplied string matches with the - architecture, eg the string m68k:68020 would match the 68k entry - up to the :, then we get left with the machine number */ - - for (ptr_src = string, - ptr_tst = info->arch_name; - *ptr_src && *ptr_tst; - ptr_src++, - ptr_tst++) - { - if (*ptr_src != *ptr_tst) break; - } - - /* Chewed up as much of the architecture as will match, skip any - colons */ - if (*ptr_src == ':') ptr_src++; - - if (*ptr_src == 0) { - /* nothing more, then only keep this one if it is the default - machine for this architecture */ - return info->the_default; - } - number = 0; - while (isdigit(*ptr_src)) { - number = number * 10 + *ptr_src - '0'; - ptr_src++; - } - - switch (number) - { - case 300: - arch = bfd_arch_h8300; - break; - - case 500: - arch = bfd_arch_h8500; - break; - - case 68010: - case 68020: - case 68030: - case 68040: - case 68332: - case 68050: - case 68000: - arch = bfd_arch_m68k; - break; - case 386: - case 80386: - case 486: - case 80486: - arch = bfd_arch_i386; - break; - case 29000: - arch = bfd_arch_a29k; - break; - - case 8000: - arch = bfd_arch_z8k; - break; - - case 32000: - arch = bfd_arch_we32k; - break; - - case 860: - case 80860: - arch = bfd_arch_i860; - break; - case 960: - case 80960: - arch = bfd_arch_i960; - break; - - case 2000: - case 3000: - case 4000: - case 4400: - arch = bfd_arch_mips; - break; - - case 6000: - arch = bfd_arch_rs6000; - break; - - default: - return false; - } - if (arch != info->arch) - return false; - - if (number != info->mach) - return false; - - return true; -} - - -/* -FUNCTION - bfd_get_arch_info - -SYNOPSIS - bfd_arch_info_type * bfd_get_arch_info(bfd *abfd); - -DESCRIPTION - Return the architecture info struct in @var{abfd}. -*/ - -bfd_arch_info_type * -bfd_get_arch_info (abfd) - bfd *abfd; -{ - return abfd->arch_info; -} - - -/* -FUNCTION - bfd_lookup_arch - -SYNOPSIS - bfd_arch_info_type *bfd_lookup_arch - (enum bfd_architecture - arch, - long machine); - -DESCRIPTION - Look for the architecure info structure which matches the - arguments @var{arch} and @var{machine}. A machine of 0 matches the - machine/architecture structure which marks itself as the - default. -*/ - -bfd_arch_info_type * -bfd_lookup_arch (arch, machine) - enum bfd_architecture arch; - long machine; -{ - bfd_arch_info_type *ap; - bfd_check_init(); - for (ap = bfd_arch_info_list; - ap != (bfd_arch_info_type *)NULL; - ap = ap->next) { - if (ap->arch == arch && - ((ap->mach == machine) - || (ap->the_default && machine == 0))) { - return ap; - } - } - return (bfd_arch_info_type *)NULL; -} - - -/* -FUNCTION - bfd_printable_arch_mach - -SYNOPSIS - CONST char *bfd_printable_arch_mach - (enum bfd_architecture arch, unsigned long machine); - -DESCRIPTION - Return a printable string representing the architecture and - machine type. - - This routine is depreciated. -*/ - -CONST char * -bfd_printable_arch_mach (arch, machine) - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_arch_info_type *ap = bfd_lookup_arch(arch, machine); - if(ap) return ap->printable_name; - return "UNKNOWN!"; -} diff --git a/gnu/usr.bin/gdb/bfd/bfd.c b/gnu/usr.bin/gdb/bfd/bfd.c deleted file mode 100644 index d6372ac..0000000 --- a/gnu/usr.bin/gdb/bfd/bfd.c +++ /dev/null @@ -1,825 +0,0 @@ -/* Generic BFD library interface and support routines. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - <<typedef bfd>> - - A BFD has type <<bfd>>; objects of this type are the - cornerstone of any application using BFD. Using BFD - consists of making references though the BFD and to data in the BFD. - - Here is the structure that defines the type <<bfd>>. It - contains the major data about the file and pointers - to the rest of the data. - -CODE_FRAGMENT -. -.struct _bfd -.{ -. {* The filename the application opened the BFD with. *} -. CONST char *filename; -. -. {* A pointer to the target jump table. *} -. const struct bfd_target *xvec; -. -. {* To avoid dragging too many header files into every file that -. includes `<<bfd.h>>', IOSTREAM has been declared as a "char -. *", and MTIME as a "long". Their correct types, to which they -. are cast when used, are "FILE *" and "time_t". The iostream -. is the result of an fopen on the filename. *} -. char *iostream; -. -. {* Is the file descriptor being cached? That is, can it be closed as -. needed, and re-opened when accessed later? *} -. -. boolean cacheable; -. -. {* Marks whether there was a default target specified when the -. BFD was opened. This is used to select which matching algorithm -. to use to choose the back end. *} -. -. boolean target_defaulted; -. -. {* The caching routines use these to maintain a -. least-recently-used list of BFDs *} -. -. struct _bfd *lru_prev, *lru_next; -. -. {* When a file is closed by the caching routines, BFD retains -. state information on the file here: *} -. -. file_ptr where; -. -. {* and here: (``once'' means at least once) *} -. -. boolean opened_once; -. -. {* Set if we have a locally maintained mtime value, rather than -. getting it from the file each time: *} -. -. boolean mtime_set; -. -. {* File modified time, if mtime_set is true: *} -. -. long mtime; -. -. {* Reserved for an unimplemented file locking extension.*} -. -. int ifd; -. -. {* The format which belongs to the BFD. (object, core, etc.) *} -. -. bfd_format format; -. -. {* The direction the BFD was opened with*} -. -. enum bfd_direction {no_direction = 0, -. read_direction = 1, -. write_direction = 2, -. both_direction = 3} direction; -. -. {* Format_specific flags*} -. -. flagword flags; -. -. {* Currently my_archive is tested before adding origin to -. anything. I believe that this can become always an add of -. origin, with origin set to 0 for non archive files. *} -. -. file_ptr origin; -. -. {* Remember when output has begun, to stop strange things -. from happening. *} -. boolean output_has_begun; -. -. {* Pointer to linked list of sections*} -. struct sec *sections; -. -. {* The number of sections *} -. unsigned int section_count; -. -. {* Stuff only useful for object files: -. The start address. *} -. bfd_vma start_address; -. -. {* Used for input and output*} -. unsigned int symcount; -. -. {* Symbol table for output BFD (with symcount entries) *} -. struct symbol_cache_entry **outsymbols; -. -. {* Pointer to structure which contains architecture information*} -. struct bfd_arch_info *arch_info; -. -. {* Stuff only useful for archives:*} -. PTR arelt_data; -. struct _bfd *my_archive; {* The containing archive BFD. *} -. struct _bfd *next; {* The next BFD in the archive. *} -. struct _bfd *archive_head; {* The first BFD in the archive. *} -. boolean has_armap; -. -. {* A chain of BFD structures involved in a link. *} -. struct _bfd *link_next; -. -. {* A field used by _bfd_generic_link_add_archive_symbols. This will -. be used only for archive elements. *} -. int archive_pass; -. -. {* Used by the back end to hold private data. *} -. -. union -. { -. struct aout_data_struct *aout_data; -. struct artdata *aout_ar_data; -. struct _oasys_data *oasys_obj_data; -. struct _oasys_ar_data *oasys_ar_data; -. struct coff_tdata *coff_obj_data; -. struct ecoff_tdata *ecoff_obj_data; -. struct ieee_data_struct *ieee_data; -. struct ieee_ar_data_struct *ieee_ar_data; -. struct srec_data_struct *srec_data; -. struct tekhex_data_struct *tekhex_data; -. struct elf_obj_tdata *elf_obj_data; -. struct nlm_obj_tdata *nlm_obj_data; -. struct bout_data_struct *bout_data; -. struct sun_core_struct *sun_core_data; -. struct trad_core_struct *trad_core_data; -. struct som_data_struct *som_data; -. struct hpux_core_struct *hpux_core_data; -. struct hppabsd_core_struct *hppabsd_core_data; -. struct sgi_core_struct *sgi_core_data; -. struct lynx_core_struct *lynx_core_data; -. struct osf_core_struct *osf_core_data; -. struct cisco_core_struct *cisco_core_data; -. PTR any; -. } tdata; -. -. {* Used by the application to hold private data*} -. PTR usrdata; -. -. {* Where all the allocated stuff under this BFD goes *} -. struct obstack memory; -.}; -. -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "libcoff.h" -#include "libecoff.h" -#undef obj_symbols -#include "libelf.h" - - -/* -SECTION - Error reporting - - Most BFD functions return nonzero on success (check their - individual documentation for precise semantics). On an error, - they call <<bfd_set_error>> to set an error condition that callers - can check by calling <<bfd_get_error>>. - If that returns <<bfd_error_system_call>>, then check - <<errno>>. - - The easiest way to report a BFD error to the user is to - use <<bfd_perror>>. - -SUBSECTION - Type <<bfd_error_type>> - - The values returned by <<bfd_get_error>> are defined by the - enumerated type <<bfd_error_type>>. - -CODE_FRAGMENT -. -.typedef enum bfd_error -.{ -. bfd_error_no_error = 0, -. bfd_error_system_call, -. bfd_error_invalid_target, -. bfd_error_wrong_format, -. bfd_error_invalid_operation, -. bfd_error_no_memory, -. bfd_error_no_symbols, -. bfd_error_no_more_archived_files, -. bfd_error_malformed_archive, -. bfd_error_file_not_recognized, -. bfd_error_file_ambiguously_recognized, -. bfd_error_no_contents, -. bfd_error_nonrepresentable_section, -. bfd_error_no_debug_section, -. bfd_error_bad_value, -. bfd_error_file_truncated, -. bfd_error_invalid_error_code -.} bfd_error_type; -. -*/ - -#undef strerror -extern char *strerror(); - -static bfd_error_type bfd_error = bfd_error_no_error; - -CONST char *CONST bfd_errmsgs[] = { - "No error", - "System call error", - "Invalid bfd target", - "File in wrong format", - "Invalid operation", - "Memory exhausted", - "No symbols", - "No more archived files", - "Malformed archive", - "File format not recognized", - "File format is ambiguous", - "Section has no contents", - "Nonrepresentable section on output", - "Symbol needs debug section which does not exist", - "Bad value", - "File truncated", - "#<Invalid error code>" - }; - -/* -FUNCTION - bfd_get_error - -SYNOPSIS - bfd_error_type bfd_get_error (void); - -DESCRIPTION - Return the current BFD error condition. -*/ - -bfd_error_type -bfd_get_error () -{ - return bfd_error; -} - -/* -FUNCTION - bfd_set_error - -SYNOPSIS - void bfd_set_error (bfd_error_type error_tag); - -DESCRIPTION - Set the BFD error condition to be @var{error_tag}. -*/ - -void -bfd_set_error (error_tag) - bfd_error_type error_tag; -{ - bfd_error = error_tag; -} - -/* -FUNCTION - bfd_errmsg - -SYNOPSIS - CONST char *bfd_errmsg (bfd_error_type error_tag); - -DESCRIPTION - Return a string describing the error @var{error_tag}, or - the system error if @var{error_tag} is <<bfd_error_system_call>>. -*/ - -CONST char * -bfd_errmsg (error_tag) - bfd_error_type error_tag; -{ -#ifndef errno - extern int errno; -#endif - if (error_tag == bfd_error_system_call) - return strerror (errno); - - if ((((int)error_tag <(int) bfd_error_no_error) || - ((int)error_tag > (int)bfd_error_invalid_error_code))) - error_tag = bfd_error_invalid_error_code;/* sanity check */ - - return bfd_errmsgs [(int)error_tag]; -} - -/* -FUNCTION - bfd_perror - -SYNOPSIS - void bfd_perror (CONST char *message); - -DESCRIPTION - Print to the standard error stream a string describing the - last BFD error that occurred, or the last system error if - the last BFD error was a system call failure. If @var{message} - is non-NULL and non-empty, the error string printed is preceded - by @var{message}, a colon, and a space. It is followed by a newline. -*/ - -void -bfd_perror (message) - CONST char *message; -{ - if (bfd_get_error () == bfd_error_system_call) - perror((char *)message); /* must be system error then... */ - else { - if (message == NULL || *message == '\0') - fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ())); - else - fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ())); - } -} - - -/* -SECTION - Symbols -*/ - -/* -FUNCTION - bfd_get_reloc_upper_bound - -SYNOPSIS - long bfd_get_reloc_upper_bound(bfd *abfd, asection *sect); - -DESCRIPTION - Return the number of bytes required to store the - relocation information associated with section @var{sect} - attached to bfd @var{abfd}. If an error occurs, return -1. - -*/ - - -long -bfd_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (abfd->format != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect)); -} - -/* -FUNCTION - bfd_canonicalize_reloc - -SYNOPSIS - long bfd_canonicalize_reloc - (bfd *abfd, - asection *sec, - arelent **loc, - asymbol **syms); - -DESCRIPTION - Call the back end associated with the open BFD - @var{abfd} and translate the external form of the relocation - information attached to @var{sec} into the internal canonical - form. Place the table into memory at @var{loc}, which has - been preallocated, usually by a call to - <<bfd_get_reloc_upper_bound>>. Returns the number of relocs, or - -1 on error. - - The @var{syms} table is also needed for horrible internal magic - reasons. - - -*/ -long -bfd_canonicalize_reloc (abfd, asect, location, symbols) - bfd *abfd; - sec_ptr asect; - arelent **location; - asymbol **symbols; -{ - if (abfd->format != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - return BFD_SEND (abfd, _bfd_canonicalize_reloc, - (abfd, asect, location, symbols)); -} - -/* -FUNCTION - bfd_set_reloc - -SYNOPSIS - void bfd_set_reloc - (bfd *abfd, asection *sec, arelent **rel, unsigned int count) - -DESCRIPTION - Set the relocation pointer and count within - section @var{sec} to the values @var{rel} and @var{count}. - The argument @var{abfd} is ignored. - -*/ -/*ARGSUSED*/ -void -bfd_set_reloc (ignore_abfd, asect, location, count) - bfd *ignore_abfd; - sec_ptr asect; - arelent **location; - unsigned int count; -{ - asect->orelocation = location; - asect->reloc_count = count; -} - -/* -FUNCTION - bfd_set_file_flags - -SYNOPSIS - boolean bfd_set_file_flags(bfd *abfd, flagword flags); - -DESCRIPTION - Set the flag word in the BFD @var{abfd} to the value @var{flags}. - - Possible errors are: - o <<bfd_error_wrong_format>> - The target bfd was not of object format. - o <<bfd_error_invalid_operation>> - The target bfd was open for reading. - o <<bfd_error_invalid_operation>> - - The flag word contained a bit which was not applicable to the - type of file. E.g., an attempt was made to set the <<D_PAGED>> bit - on a BFD format which does not support demand paging. - -*/ - -boolean -bfd_set_file_flags (abfd, flags) - bfd *abfd; - flagword flags; -{ - if (abfd->format != bfd_object) { - bfd_set_error (bfd_error_wrong_format); - return false; - } - - if (bfd_read_p (abfd)) { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - bfd_get_file_flags (abfd) = flags; - if ((flags & bfd_applicable_file_flags (abfd)) != flags) { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - -return true; -} - -void -bfd_assert(file, line) -char *file; -int line; -{ - fprintf(stderr, "bfd assertion fail %s:%d\n",file,line); -} - - -/* -FUNCTION - bfd_set_start_address - -SYNOPSIS - boolean bfd_set_start_address(bfd *abfd, bfd_vma vma); - -DESCRIPTION - Make @var{vma} the entry point of output BFD @var{abfd}. - -RETURNS - Returns <<true>> on success, <<false>> otherwise. -*/ - -boolean -bfd_set_start_address(abfd, vma) -bfd *abfd; -bfd_vma vma; -{ - abfd->start_address = vma; - return true; -} - - -/* -FUNCTION - bfd_get_mtime - -SYNOPSIS - long bfd_get_mtime(bfd *abfd); - -DESCRIPTION - Return the file modification time (as read from the file system, or - from the archive header for archive members). - -*/ - -long -bfd_get_mtime (abfd) - bfd *abfd; -{ - FILE *fp; - struct stat buf; - - if (abfd->mtime_set) - return abfd->mtime; - - fp = bfd_cache_lookup (abfd); - if (0 != fstat (fileno (fp), &buf)) - return 0; - - abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */ - return buf.st_mtime; -} - -/* -FUNCTION - bfd_get_size - -SYNOPSIS - long bfd_get_size(bfd *abfd); - -DESCRIPTION - Return the file size (as read from file system) for the file - associated with BFD @var{abfd}. - - The initial motivation for, and use of, this routine is not - so we can get the exact size of the object the BFD applies to, since - that might not be generally possible (archive members for example). - It would be ideal if someone could eventually modify - it so that such results were guaranteed. - - Instead, we want to ask questions like "is this NNN byte sized - object I'm about to try read from file offset YYY reasonable?" - As as example of where we might do this, some object formats - use string tables for which the first <<sizeof(long)>> bytes of the - table contain the size of the table itself, including the size bytes. - If an application tries to read what it thinks is one of these - string tables, without some way to validate the size, and for - some reason the size is wrong (byte swapping error, wrong location - for the string table, etc.), the only clue is likely to be a read - error when it tries to read the table, or a "virtual memory - exhausted" error when it tries to allocate 15 bazillon bytes - of space for the 15 bazillon byte table it is about to read. - This function at least allows us to answer the quesion, "is the - size reasonable?". -*/ - -long -bfd_get_size (abfd) - bfd *abfd; -{ - FILE *fp; - struct stat buf; - - fp = bfd_cache_lookup (abfd); - if (0 != fstat (fileno (fp), &buf)) - return 0; - - return buf.st_size; -} - -/* -FUNCTION - bfd_get_gp_size - -SYNOPSIS - int bfd_get_gp_size(bfd *abfd); - -DESCRIPTION - Return the maximum size of objects to be optimized using the GP - register under MIPS ECOFF. This is typically set by the <<-G>> - argument to the compiler, assembler or linker. -*/ - -int -bfd_get_gp_size (abfd) - bfd *abfd; -{ - if (abfd->format == bfd_object) - { - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - return ecoff_data (abfd)->gp_size; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - return elf_gp_size (abfd); - } - return 0; -} - -/* -FUNCTION - bfd_set_gp_size - -SYNOPSIS - void bfd_set_gp_size(bfd *abfd, int i); - -DESCRIPTION - Set the maximum size of objects to be optimized using the GP - register under ECOFF or MIPS ELF. This is typically set by - the <<-G>> argument to the compiler, assembler or linker. -*/ - -void -bfd_set_gp_size (abfd, i) - bfd *abfd; - int i; -{ - /* Don't try to set GP size on an archive or core file! */ - if (abfd->format != bfd_object) - return; - if (abfd->xvec->flavour == bfd_target_ecoff_flavour) - ecoff_data (abfd)->gp_size = i; - else if (abfd->xvec->flavour == bfd_target_elf_flavour) - elf_gp_size (abfd) = i; -} - -/* -FUNCTION - bfd_scan_vma - -SYNOPSIS - bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base); - -DESCRIPTION - Convert, like <<strtoul>>, a numerical expression - @var{string} into a <<bfd_vma>> integer, and return that integer. - (Though without as many bells and whistles as <<strtoul>>.) - The expression is assumed to be unsigned (i.e., positive). - If given a @var{base}, it is used as the base for conversion. - A base of 0 causes the function to interpret the string - in hex if a leading "0x" or "0X" is found, otherwise - in octal if a leading zero is found, otherwise in decimal. - - Overflow is not detected. -*/ - -bfd_vma -bfd_scan_vma (string, end, base) - CONST char *string; - CONST char **end; - int base; -{ - bfd_vma value; - int digit; - - /* Let the host do it if possible. */ - if (sizeof(bfd_vma) <= sizeof(unsigned long)) - return (bfd_vma) strtoul (string, 0, base); - - /* A negative base makes no sense, and we only need to go as high as hex. */ - if ((base < 0) || (base > 16)) - return (bfd_vma) 0; - - if (base == 0) - { - if (string[0] == '0') - { - if ((string[1] == 'x') || (string[1] == 'X')) - base = 16; - /* XXX should we also allow "0b" or "0B" to set base to 2? */ - else - base = 8; - } - else - base = 10; - } - if ((base == 16) && - (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) - string += 2; - /* XXX should we also skip over "0b" or "0B" if base is 2? */ - -/* Speed could be improved with a table like hex_value[] in gas. */ -#define HEX_VALUE(c) \ - (isxdigit(c) ? \ - (isdigit(c) ? \ - (c - '0') : \ - (10 + c - (islower(c) ? 'a' : 'A'))) : \ - 42) - - for (value = 0; (digit = HEX_VALUE(*string)) < base; string++) - { - value = value * base + digit; - } - - if (end) - *end = string; - - return value; -} - -/* -FUNCTION - bfd_copy_private_bfd_data - -SYNOPSIS - boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd); - -DESCRIPTION - Copy private BFD information from the BFD @var{ibfd} to the - the BFD @var{obfd}. Return <<true>> on success, <<false>> on error. - Possible error returns are: - - o <<bfd_error_no_memory>> - - Not enough memory exists to create private data for @var{obfd}. - -.#define bfd_copy_private_bfd_data(ibfd, obfd) \ -. BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \ -. (ibfd, obfd)) - -*/ - -/* -FUNCTION - stuff - -DESCRIPTION - Stuff which should be documented: - -.#define bfd_sizeof_headers(abfd, reloc) \ -. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) -. -.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ -. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)) -. -. {* Do these three do anything useful at all, for any back end? *} -.#define bfd_debug_info_start(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) -. -.#define bfd_debug_info_end(abfd) \ -. BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) -. -.#define bfd_debug_info_accumulate(abfd, section) \ -. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) -. -. -.#define bfd_stat_arch_elt(abfd, stat) \ -. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) -. -.#define bfd_set_arch_mach(abfd, arch, mach)\ -. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) -. -.#define bfd_get_relocated_section_contents(abfd, link_info, link_order, data, relocateable, symbols) \ -. BFD_SEND (abfd, _bfd_get_relocated_section_contents, \ -. (abfd, link_info, link_order, data, relocateable, symbols)) -. -.#define bfd_relax_section(abfd, section, link_info, again) \ -. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) -. -.#define bfd_link_hash_table_create(abfd) \ -. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) -. -.#define bfd_link_add_symbols(abfd, info) \ -. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) -. -.#define bfd_final_link(abfd, info) \ -. BFD_SEND (abfd, _bfd_final_link, (abfd, info)) -. -.#define bfd_free_cached_info(abfd) \ -. BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) -. -.#define bfd_get_dynamic_symtab_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) -. -.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) -. -.#define bfd_get_dynamic_reloc_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) -. -.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ -. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) -. - -*/ diff --git a/gnu/usr.bin/gdb/bfd/bfd.h b/gnu/usr.bin/gdb/bfd/bfd.h index 78b0e9f..c9b55d4 100644 --- a/gnu/usr.bin/gdb/bfd/bfd.h +++ b/gnu/usr.bin/gdb/bfd/bfd.h @@ -1,5 +1,5 @@ /* Main header file for the bfd library -- portable access to object files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. Contributed by Cygnus Support. ** NOTE: bfd.h and bfd-in2.h are GENERATED files. Don't change them; @@ -20,9 +20,9 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* bfd.h -- The only header file required by users of the bfd library +/* bfd.h -- The only header file required by users of the bfd library The bfd.h file is generated from bfd-in.h and various .c files; if you change it, your changes will probably be lost. @@ -44,12 +44,17 @@ here. */ #ifndef __BFD_H_SEEN__ #define __BFD_H_SEEN__ +#ifdef __cplusplus +extern "C" { +#endif + #include "ansidecl.h" #include "obstack.h" /* These two lines get substitutions done by commands in Makefile.in. */ -#define BFD_VERSION "cygnus-2.3" +#define BFD_VERSION "cygnus-2.6" #define BFD_ARCH_SIZE 32 +#define BFD_HOST_64BIT_LONG 0 #if BFD_ARCH_SIZE >= 64 #define BFD64 @@ -63,9 +68,6 @@ here. */ #endif #endif -/* 64-bit type definition (if any) from bfd's sysdep.h goes here */ - - /* forward declaration */ typedef struct _bfd bfd; @@ -82,60 +84,70 @@ typedef struct _bfd bfd; /* typedef enum boolean {false, true} boolean; */ /* Yup, SVR4 has a "typedef enum boolean" in <sys/types.h> -fnf */ /* It gets worse if the host also defines a true/false enum... -sts */ +/* And even worse if your compiler has built-in boolean types... -law */ +#if defined (__GNUG__) && (__GNUC_MINOR__ > 5) +#define TRUE_FALSE_ALREADY_DEFINED +#endif +#ifdef MPW +/* Pre-emptive strike - get the file with the enum. */ +#include <Types.h> +#define TRUE_FALSE_ALREADY_DEFINED +#endif /* MPW */ #ifndef TRUE_FALSE_ALREADY_DEFINED typedef enum bfd_boolean {false, true} boolean; #define BFD_TRUE_FALSE #else -typedef enum bfd_boolean {bfd_false, bfd_true} boolean; +/* Use enum names that will appear nowhere else. */ +typedef enum bfd_boolean {bfd_fffalse, bfd_tttrue} boolean; #endif /* A pointer to a position in a file. */ /* FIXME: This should be using off_t from <sys/types.h>. For now, try to avoid breaking stuff by not including <sys/types.h> here. This will break on systems with 64-bit file offsets (e.g. 4.4BSD). - Probably the best long-term answer is to avoid using file_ptr AND off_t + Probably the best long-term answer is to avoid using file_ptr AND off_t in this header file, and to handle this in the BFD implementation rather than in its interface. */ /* typedef off_t file_ptr; */ typedef long int file_ptr; -/* Support for different sizes of target format ints and addresses. If the - host implements 64-bit values, it defines BFD_HOST_64_BIT to be the appropriate - type. Otherwise, this code will fall back on gcc's "long long" type if gcc - is being used. BFD_HOST_64_BIT must be defined in such a way as to be a valid - type name by itself or with "unsigned" prefixed. It should be a signed - type by itself. - - If neither is the case, then compilation will fail if 64-bit targets are - requested. If you don't request any 64-bit targets, you should be safe. */ +/* Support for different sizes of target format ints and addresses. + If the type `long' is at least 64 bits, BFD_HOST_64BIT_LONG will be + set to 1 above. Otherwise, if gcc is being used, this code will + use gcc's "long long" type. Otherwise, the compilation will fail + if 64-bit targets are requested. */ -#ifdef BFD64 +#ifdef BFD64 -#if defined (__GNUC__) && !defined (BFD_HOST_64_BIT) +#ifndef BFD_HOST_64_BIT +#if BFD_HOST_64BIT_LONG +#define BFD_HOST_64_BIT long +#else +#ifdef __GNUC__ #define BFD_HOST_64_BIT long long -typedef BFD_HOST_64_BIT int64_type; -typedef unsigned BFD_HOST_64_BIT uint64_type; -#endif - -#if !defined (uint64_type) && defined (__GNUC__) -#define uint64_type unsigned long long -#define int64_type long long -#endif -#ifndef uint64_typeLOW -#define uint64_typeLOW(x) ((unsigned long)(((x) & 0xffffffff))) -#define uint64_typeHIGH(x) ((unsigned long)(((x) >> 32) & 0xffffffff)) -#endif +#endif /* defined (__GNUC__) */ +#endif /* ! BFD_HOST_64BIT_LONG */ +#endif /* ! defined (BFD_HOST_64_BIT) */ typedef unsigned BFD_HOST_64_BIT bfd_vma; typedef BFD_HOST_64_BIT bfd_signed_vma; typedef unsigned BFD_HOST_64_BIT bfd_size_type; typedef unsigned BFD_HOST_64_BIT symvalue; + #ifndef fprintf_vma +#if BFD_HOST_64BIT_LONG +#define sprintf_vma(s,x) sprintf (s, "%016lx", x) +#define fprintf_vma(f,x) fprintf (f, "%016lx", x) +#else +#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff))) +#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) #define fprintf_vma(s,x) \ - fprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x)) + fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) #define sprintf_vma(s,x) \ - sprintf(s,"%08lx%08lx", uint64_typeHIGH(x), uint64_typeLOW(x)) + sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x)) +#endif #endif + #else /* not BFD64 */ /* Represent a target address. Also used as a generic unsigned type @@ -159,6 +171,7 @@ typedef unsigned long bfd_size_type; #define printf_vma(x) fprintf_vma(stdout,x) typedef unsigned int flagword; /* 32 bits of flags */ +typedef unsigned char bfd_byte; /** File formats */ @@ -213,7 +226,8 @@ typedef enum bfd_format { #define D_PAGED 0x100 /* BFD is relaxable (this means that bfd_relax_section may be able to - do something). */ + do something) (sometimes bfd_relax_section can do something even if + this is not set). */ #define BFD_IS_RELAXABLE 0x200 /* This may be set before writing out a BFD to request using a @@ -221,12 +235,19 @@ typedef enum bfd_format { writing out an a.out object the symbols not be hashed to eliminate duplicates. */ #define BFD_TRADITIONAL_FORMAT 0x400 + +/* This flag indicates that the BFD contents are actually cached in + memory. If this is set, iostream points to a bfd_in_memory struct. */ +#define BFD_IN_MEMORY 0x800 /* symbols and relocation */ /* A count of carsyms (canonical archive symbols). */ typedef unsigned long symindex; +/* How to perform a relocation. */ +typedef const struct reloc_howto_struct reloc_howto_type; + #define BFD_NO_MORE_SYMBOLS ((symindex) ~0) /* General purpose part of a symbol X; @@ -249,20 +270,19 @@ typedef struct carsym { file_ptr file_offset; /* look here to find the file */ } carsym; /* to make these you call a carsymogen */ - + /* Used in generating armaps (archive tables of contents). Perhaps just a forward definition would do? */ struct orl { /* output ranlib */ - char **name; /* symbol name */ + char **name; /* symbol name */ file_ptr pos; /* bfd* or file position */ int namidx; /* index into string table */ }; - /* Linenumber stuff */ typedef struct lineno_cache_entry { - unsigned int line_number; /* Linenumber from start of function*/ + unsigned int line_number; /* Linenumber from start of function*/ union { struct symbol_cache_entry *sym; /* Function name */ unsigned long offset; /* Offset into section */ @@ -271,7 +291,6 @@ typedef struct lineno_cache_entry { /* object and core file sections */ - #define align_power(addr, align) \ ( ((addr) + ((1<<(align))-1)) & (-1 << (align))) @@ -289,19 +308,19 @@ typedef struct sec *sec_ptr; #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) -#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = true), true) +#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma= (val)), ((ptr)->user_set_vma = (boolean)true), true) #define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),true) #define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),true) -typedef struct stat stat_type; +typedef struct stat stat_type; typedef enum bfd_print_symbol -{ +{ bfd_print_symbol_name, bfd_print_symbol_more, bfd_print_symbol_all } bfd_print_symbol_type; - + /* Information about a symbol that nm needs. */ typedef struct _symbol_info @@ -309,10 +328,15 @@ typedef struct _symbol_info symvalue value; char type; CONST char *name; /* Symbol name. */ - char stab_other; /* Unused. */ - short stab_desc; /* Info for N_TYPE. */ - CONST char *stab_name; + unsigned char stab_type; /* Stab type. */ + char stab_other; /* Stab other. */ + short stab_desc; /* Stab desc. */ + CONST char *stab_name; /* String for stab type. */ } symbol_info; + +/* Get the name of a stabs type code. */ + +extern const char *bfd_get_stab_name PARAMS ((int)); /* Hash table routines. There is no way to free up a hash table. */ @@ -378,6 +402,11 @@ extern struct bfd_hash_entry *bfd_hash_lookup PARAMS ((struct bfd_hash_table *, const char *, boolean create, boolean copy)); +/* Replace an entry in a hash table. */ +extern void bfd_hash_replace + PARAMS ((struct bfd_hash_table *, struct bfd_hash_entry *old, + struct bfd_hash_entry *nw)); + /* Base method for creating a hash table entry. */ extern struct bfd_hash_entry *bfd_hash_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, @@ -424,6 +453,19 @@ extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, /* User program access to BFD facilities */ +/* Direct I/O routines, for programs which know more about the object + file than BFD does. Use higher level routines if possible. */ + +extern bfd_size_type bfd_read + PARAMS ((PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); +extern bfd_size_type bfd_write + PARAMS ((const PTR, bfd_size_type size, bfd_size_type nitems, bfd *abfd)); +extern int bfd_seek PARAMS ((bfd *abfd, file_ptr fp, int direction)); +extern long bfd_tell PARAMS ((bfd *abfd)); +extern int bfd_flush PARAMS ((bfd *abfd)); +extern int bfd_stat PARAMS ((bfd *abfd, struct stat *)); + + /* Cast from const char * to char * so that caller can assign to a char * without a warning. */ #define bfd_get_filename(abfd) ((char *) (abfd)->filename) @@ -431,6 +473,12 @@ extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, #define bfd_get_format(abfd) ((abfd)->format) #define bfd_get_target(abfd) ((abfd)->xvec->name) #define bfd_get_flavour(abfd) ((abfd)->xvec->flavour) +#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG) +#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE) +#define bfd_header_big_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG) +#define bfd_header_little_endian(abfd) \ + ((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE) #define bfd_get_file_flags(abfd) ((abfd)->flags) #define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags) #define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags) @@ -447,7 +495,11 @@ extern void bfd_hash_traverse PARAMS ((struct bfd_hash_table *, #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) -#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (bool)), true) +#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = (boolean)(bool)), true) + +extern boolean bfd_record_phdr + PARAMS ((bfd *, unsigned long, boolean, flagword, boolean, bfd_vma, + boolean, boolean, unsigned int, struct sec **)); /* Byte swapping routines. */ @@ -478,6 +530,7 @@ struct ecoff_debug_swap; struct ecoff_extr; struct symbol_cache_entry; struct bfd_link_info; +struct bfd_link_hash_entry; #endif extern bfd_vma bfd_ecoff_get_gp_value PARAMS ((bfd * abfd)); extern boolean bfd_ecoff_set_gp_value PARAMS ((bfd *abfd, bfd_vma gp_value)); @@ -524,21 +577,38 @@ extern boolean bfd_ecoff_write_accumulated_debug PARAMS ((PTR handle, bfd *abfd, struct ecoff_debug_info *debug, const struct ecoff_debug_swap *swap, struct bfd_link_info *info, file_ptr where)); +extern boolean bfd_mips_ecoff_create_embedded_relocs + PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *, + char **)); /* Externally visible ELF routines. */ +struct bfd_link_needed_list +{ + struct bfd_link_needed_list *next; + bfd *by; + const char *name; +}; + extern boolean bfd_elf32_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); + PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); extern boolean bfd_elf64_record_link_assignment - PARAMS ((bfd *, struct bfd_link_info *, const char *)); + PARAMS ((bfd *, struct bfd_link_info *, const char *, boolean)); +extern struct bfd_link_needed_list *bfd_elf_get_needed_list + PARAMS ((bfd *, struct bfd_link_info *)); extern boolean bfd_elf32_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, struct sec **)); + PARAMS ((bfd *, const char *, const char *, boolean, + struct bfd_link_info *, struct sec **)); extern boolean bfd_elf64_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *, struct sec **)); + PARAMS ((bfd *, const char *, const char *, boolean, + struct bfd_link_info *, struct sec **)); extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *)); +extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *)); /* SunOS shared library support routines for the linker. */ +extern struct bfd_link_needed_list *bfd_sunos_get_needed_list + PARAMS ((bfd *, struct bfd_link_info *)); extern boolean bfd_sunos_record_link_assignment PARAMS ((bfd *, struct bfd_link_info *, const char *)); extern boolean bfd_sunos_size_dynamic_sections @@ -547,11 +617,56 @@ extern boolean bfd_sunos_size_dynamic_sections /* Linux shared library support routines for the linker. */ -extern boolean bfd_linux_size_dynamic_sections +extern boolean bfd_i386linux_size_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +extern boolean bfd_m68klinux_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); +/* mmap hacks */ + +struct _bfd_window_internal; +typedef struct _bfd_window_internal bfd_window_internal; + +typedef struct _bfd_window { + /* What the user asked for. */ + PTR data; + bfd_size_type size; + /* The actual window used by BFD. Small user-requested read-only + regions sharing a page may share a single window into the object + file. Read-write versions shouldn't until I've fixed things to + keep track of which portions have been claimed by the + application; don't want to give the same region back when the + application wants two writable copies! */ + struct _bfd_window_internal *i; +} bfd_window; + +extern void bfd_init_window PARAMS ((bfd_window *)); +extern void bfd_free_window PARAMS ((bfd_window *)); +extern boolean bfd_get_file_window + PARAMS ((bfd *, file_ptr, bfd_size_type, bfd_window *, boolean)); + +/* XCOFF support routines for the linker. */ + +extern boolean bfd_xcoff_link_record_set + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, + bfd_size_type)); +extern boolean bfd_xcoff_import_symbol + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, + bfd_vma, const char *, const char *, const char *)); +extern boolean bfd_xcoff_export_symbol + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, + boolean)); +extern boolean bfd_xcoff_link_count_reloc + PARAMS ((bfd *, struct bfd_link_info *, const char *)); +extern boolean bfd_xcoff_record_link_assignment + PARAMS ((bfd *, struct bfd_link_info *, const char *)); +extern boolean bfd_xcoff_size_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, + unsigned long, unsigned long, unsigned long, boolean, + int, boolean, boolean, struct sec **)); + /* And more from the source. */ -void +void bfd_init PARAMS ((void)); bfd * @@ -561,15 +676,18 @@ bfd * bfd_fdopenr PARAMS ((CONST char *filename, CONST char *target, int fd)); bfd * +bfd_openstreamr PARAMS (()); + +bfd * bfd_openw PARAMS ((CONST char *filename, CONST char *target)); -boolean +boolean bfd_close PARAMS ((bfd *abfd)); -boolean +boolean bfd_close_all_done PARAMS ((bfd *)); -bfd_size_type +bfd_size_type bfd_alloc_size PARAMS ((bfd *abfd)); bfd * @@ -763,6 +881,16 @@ typedef struct sec memory if appropriate. */ #define SEC_IN_MEMORY 0x20000 + /* The contents of this section are to be excluded by the + linker for executable and shared objects unless those + objects are to be further relocated. */ +#define SEC_EXCLUDE 0x40000 + + /* The contents of this section are to be sorted by the + based on the address specified in the associated symbol + table. */ +#define SEC_SORT_ENTRIES 0x80000 + /* End of section flags. */ /* The virtual memory address of the section - where it will be @@ -929,20 +1057,20 @@ bfd_make_section_anyway PARAMS ((bfd *abfd, CONST char *name)); asection * bfd_make_section PARAMS ((bfd *, CONST char *name)); -boolean +boolean bfd_set_section_flags PARAMS ((bfd *abfd, asection *sec, flagword flags)); -void +void bfd_map_over_sections PARAMS ((bfd *abfd, void (*func)(bfd *abfd, asection *sect, PTR obj), PTR obj)); -boolean +boolean bfd_set_section_size PARAMS ((bfd *abfd, asection *sec, bfd_size_type val)); -boolean +boolean bfd_set_section_contents PARAMS ((bfd *abfd, asection *section, @@ -950,30 +1078,30 @@ bfd_set_section_contents file_ptr offset, bfd_size_type count)); -boolean +boolean bfd_get_section_contents PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset, bfd_size_type count)); -boolean +boolean bfd_copy_private_section_data PARAMS ((bfd *ibfd, asection *isec, bfd *obfd, asection *osec)); #define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ BFD_SEND (ibfd, _bfd_copy_private_section_data, \ (ibfd, isection, obfd, osection)) -enum bfd_architecture +enum bfd_architecture { bfd_arch_unknown, /* File arch not known */ bfd_arch_obscure, /* Arch known, not one of these */ bfd_arch_m68k, /* Motorola 68xxx */ - bfd_arch_vax, /* DEC Vax */ + bfd_arch_vax, /* DEC Vax */ bfd_arch_i960, /* Intel 960 */ /* The order of the following is important. - lower number indicates a machine type that + lower number indicates a machine type that only accepts a subset of the instructions available to machines with higher numbers. The exception is the "ca", which is - incompatible with all other machines except + incompatible with all other machines except "core". */ #define bfd_mach_i960_core 1 @@ -982,9 +1110,19 @@ enum bfd_architecture #define bfd_mach_i960_mc 4 #define bfd_mach_i960_xa 5 #define bfd_mach_i960_ca 6 +#define bfd_mach_i960_jx 7 +#define bfd_mach_i960_hx 8 bfd_arch_a29k, /* AMD 29000 */ bfd_arch_sparc, /* SPARC */ +#define bfd_mach_sparc 1 + /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +#define bfd_mach_sparc_v8plus 2 +#define bfd_mach_sparc_v8plusa 3 /* with ultrasparc add'ns */ +#define bfd_mach_sparc_v9 4 +#define bfd_mach_sparc_v9a 5 /* with ultrasparc add'ns */ + /* Nonzero if MACH has the v9 instruction set. */ +#define bfd_mach_sparc_v9_p(mach) ((mach) != bfd_mach_sparc) bfd_arch_mips, /* MIPS Rxxxx */ bfd_arch_i386, /* Intel 386 */ bfd_arch_we32k, /* AT&T WE32xxx */ @@ -1007,73 +1145,68 @@ enum bfd_architecture bfd_arch_h8500, /* Hitachi H8/500 */ bfd_arch_sh, /* Hitachi SH */ bfd_arch_alpha, /* Dec Alpha */ + bfd_arch_arm, /* Advanced Risc Machines ARM */ bfd_arch_ns32k, /* National Semiconductors ns32000 */ + bfd_arch_w65, /* WDC 65816 */ bfd_arch_last }; -typedef struct bfd_arch_info +typedef struct bfd_arch_info { int bits_per_word; int bits_per_address; int bits_per_byte; enum bfd_architecture arch; - long mach; - char *arch_name; - CONST char *printable_name; + unsigned long mach; + const char *arch_name; + const char *printable_name; unsigned int section_align_power; /* true if this is the default machine for the architecture */ - boolean the_default; - CONST struct bfd_arch_info * (*compatible) - PARAMS ((CONST struct bfd_arch_info *a, - CONST struct bfd_arch_info *b)); - - boolean (*scan) PARAMS ((CONST struct bfd_arch_info *, CONST char *)); - /* How to disassemble an instruction, producing a printable - representation on a specified stdio stream. This isn't - defined for most processors at present, because of the size - of the additional tables it would drag in, and because gdb - wants to use a different interface. */ - unsigned int (*disassemble) PARAMS ((bfd_vma addr, CONST char *data, - PTR stream)); - - struct bfd_arch_info *next; + boolean the_default; + const struct bfd_arch_info * (*compatible) + PARAMS ((const struct bfd_arch_info *a, + const struct bfd_arch_info *b)); + + boolean (*scan) PARAMS ((const struct bfd_arch_info *, const char *)); + + const struct bfd_arch_info *next; } bfd_arch_info_type; -CONST char * +const char * bfd_printable_name PARAMS ((bfd *abfd)); -bfd_arch_info_type * -bfd_scan_arch PARAMS ((CONST char *string)); +const bfd_arch_info_type * +bfd_scan_arch PARAMS ((const char *string)); -CONST bfd_arch_info_type * +const bfd_arch_info_type * bfd_arch_get_compatible PARAMS (( - CONST bfd *abfd, - CONST bfd *bbfd)); + const bfd *abfd, + const bfd *bbfd)); -void -bfd_set_arch_info PARAMS ((bfd *abfd, bfd_arch_info_type *arg)); +void +bfd_set_arch_info PARAMS ((bfd *abfd, const bfd_arch_info_type *arg)); -enum bfd_architecture +enum bfd_architecture bfd_get_arch PARAMS ((bfd *abfd)); -unsigned long +unsigned long bfd_get_mach PARAMS ((bfd *abfd)); -unsigned int +unsigned int bfd_arch_bits_per_byte PARAMS ((bfd *abfd)); -unsigned int +unsigned int bfd_arch_bits_per_address PARAMS ((bfd *abfd)); -bfd_arch_info_type * +const bfd_arch_info_type * bfd_get_arch_info PARAMS ((bfd *abfd)); -bfd_arch_info_type * +const bfd_arch_info_type * bfd_lookup_arch PARAMS ((enum bfd_architecture arch, - long machine)); + unsigned long machine)); -CONST char * +const char * bfd_printable_arch_mach PARAMS ((enum bfd_architecture arch, unsigned long machine)); @@ -1121,7 +1254,7 @@ typedef struct reloc_cache_entry bfd_vma addend; /* Pointer to how to perform the required relocation */ - const struct reloc_howto_struct *howto; + reloc_howto_type *howto; } arelent; enum complain_overflow @@ -1142,9 +1275,6 @@ enum complain_overflow complain_overflow_unsigned }; -typedef unsigned char bfd_byte; -typedef struct reloc_howto_struct reloc_howto_type; - struct reloc_howto_struct { /* The type field has mainly a documetary use - the back end can @@ -1241,8 +1371,8 @@ struct reloc_howto_struct } \ } \ } -int -bfd_get_reloc_size PARAMS ((const reloc_howto_type *)); +int +bfd_get_reloc_size PARAMS ((reloc_howto_type *)); typedef struct relent_chain { arelent relent; @@ -1258,9 +1388,20 @@ bfd_perform_relocation bfd *output_bfd, char **error_message)); -typedef enum bfd_reloc_code_real -{ - /* Basic absolute relocations */ +bfd_reloc_status_type + +bfd_install_relocation + PARAMS ((bfd *abfd, + arelent *reloc_entry, + PTR data, bfd_vma data_start, + asection *input_section, + char **error_message)); + +enum bfd_reloc_code_real { + _dummy_first_bfd_reloc_code_real, + + +/* Basic absolute relocations of N bits. */ BFD_RELOC_64, BFD_RELOC_32, BFD_RELOC_26, @@ -1268,51 +1409,84 @@ typedef enum bfd_reloc_code_real BFD_RELOC_14, BFD_RELOC_8, - /* PC-relative relocations */ +/* PC-relative relocations. Sometimes these are relative to the address +of the relocation itself; sometimes they are relative to the start of +the section containing the relocation. It depends on the specific target. + +The 24-bit relocation is used in some Intel 960 configurations. */ BFD_RELOC_64_PCREL, BFD_RELOC_32_PCREL, - BFD_RELOC_24_PCREL, /* used by i960 */ + BFD_RELOC_24_PCREL, BFD_RELOC_16_PCREL, + BFD_RELOC_12_PCREL, BFD_RELOC_8_PCREL, - /* Linkage-table relative */ +/* For ELF. */ + BFD_RELOC_32_GOT_PCREL, + BFD_RELOC_16_GOT_PCREL, + BFD_RELOC_8_GOT_PCREL, + BFD_RELOC_32_GOTOFF, + BFD_RELOC_16_GOTOFF, + BFD_RELOC_LO16_GOTOFF, + BFD_RELOC_HI16_GOTOFF, + BFD_RELOC_HI16_S_GOTOFF, + BFD_RELOC_8_GOTOFF, + BFD_RELOC_32_PLT_PCREL, + BFD_RELOC_24_PLT_PCREL, + BFD_RELOC_16_PLT_PCREL, + BFD_RELOC_8_PLT_PCREL, + BFD_RELOC_32_PLTOFF, + BFD_RELOC_16_PLTOFF, + BFD_RELOC_LO16_PLTOFF, + BFD_RELOC_HI16_PLTOFF, + BFD_RELOC_HI16_S_PLTOFF, + BFD_RELOC_8_PLTOFF, + +/* Relocations used by 68K ELF. */ + BFD_RELOC_68K_GLOB_DAT, + BFD_RELOC_68K_JMP_SLOT, + BFD_RELOC_68K_RELATIVE, + +/* Linkage-table relative. */ BFD_RELOC_32_BASEREL, BFD_RELOC_16_BASEREL, + BFD_RELOC_LO16_BASEREL, + BFD_RELOC_HI16_BASEREL, + BFD_RELOC_HI16_S_BASEREL, BFD_RELOC_8_BASEREL, + BFD_RELOC_RVA, - /* The type of reloc used to build a contructor table - at the moment - probably a 32 bit wide abs address, but the cpu can choose. */ - BFD_RELOC_CTOR, - - /* 8 bits wide, but used to form an address like 0xffnn */ +/* Absolute 8-bit relocation, but used to form an address like 0xFFnn. */ BFD_RELOC_8_FFnn, - /* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit - word displacement, e.g. for SPARC) */ +/* These PC-relative relocations are stored as word displacements -- +i.e., byte displacements shifted right two bits. The 30-bit word +displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the +SPARC. (SPARC tools generally refer to this as <<WDISP30>>.) The +signed 16-bit displacement is used on the MIPS, and the 23-bit +displacement is used on the Alpha. */ BFD_RELOC_32_PCREL_S2, - /* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) */ BFD_RELOC_16_PCREL_S2, - /* this is used on the Alpha */ BFD_RELOC_23_PCREL_S2, - /* High 22 bits of 32-bit value, placed into lower 22 bits of - target word; simple reloc. */ +/* High 22 bits and low 10 bits of 32-bit value, placed into lower bits of +the target word. These are used on the SPARC. */ BFD_RELOC_HI22, - /* Low 10 bits. */ BFD_RELOC_LO10, - /* For systems that allocate a Global Pointer register, these are - displacements off that register. These relocation types are - handled specially, because the value the register will have is - decided relatively late. */ +/* For systems that allocate a Global Pointer register, these are +displacements off that register. These relocation types are +handled specially, because the value the register will have is +decided relatively late. */ BFD_RELOC_GPREL16, BFD_RELOC_GPREL32, - /* Reloc types used for i960/b.out. */ +/* Reloc types used for i960/b.out. */ BFD_RELOC_I960_CALLJ, - /* now for the sparc/elf codes */ - BFD_RELOC_NONE, /* actually used */ +/* SPARC ELF relocations. There is probably some overlap with other +relocation types already defined. */ + BFD_RELOC_NONE, BFD_RELOC_SPARC_WDISP22, BFD_RELOC_SPARC22, BFD_RELOC_SPARC13, @@ -1328,15 +1502,14 @@ typedef enum bfd_reloc_code_real BFD_RELOC_SPARC_RELATIVE, BFD_RELOC_SPARC_UA32, - /* these are a.out specific? */ +/* I think these are specific to SPARC a.out (e.g., Sun 4). */ BFD_RELOC_SPARC_BASE13, BFD_RELOC_SPARC_BASE22, - /* some relocations we're using for sparc v9 - -- subject to change */ +/* Some relocations we're using for SPARC V9 -- subject to change. */ +#define BFD_RELOC_SPARC_64 BFD_RELOC_64 BFD_RELOC_SPARC_10, BFD_RELOC_SPARC_11, -#define BFD_RELOC_SPARC_64 BFD_RELOC_64 BFD_RELOC_SPARC_OLO10, BFD_RELOC_SPARC_HH22, BFD_RELOC_SPARC_HM10, @@ -1347,78 +1520,89 @@ typedef enum bfd_reloc_code_real BFD_RELOC_SPARC_WDISP16, BFD_RELOC_SPARC_WDISP19, BFD_RELOC_SPARC_GLOB_JMP, - BFD_RELOC_SPARC_LO7, - - /* Alpha ECOFF relocations. Some of these treat the symbol or "addend" - in some special way. */ - /* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when - writing; when reading, it will be the absolute section symbol. The - addend is the displacement in bytes of the "lda" instruction from - the "ldah" instruction (which is at the address of this reloc). */ + BFD_RELOC_SPARC_7, + BFD_RELOC_SPARC_6, + BFD_RELOC_SPARC_5, + +/* Alpha ECOFF relocations. Some of these treat the symbol or "addend" +in some special way. +For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when +writing; when reading, it will be the absolute section symbol. The +addend is the displacement in bytes of the "lda" instruction from +the "ldah" instruction (which is at the address of this reloc). */ BFD_RELOC_ALPHA_GPDISP_HI16, - /* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as - with GPDISP_HI16 relocs. The addend is ignored when writing the - relocations out, and is filled in with the file's GP value on - reading, for convenience. */ + +/* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +with GPDISP_HI16 relocs. The addend is ignored when writing the +relocations out, and is filled in with the file's GP value on +reading, for convenience. */ BFD_RELOC_ALPHA_GPDISP_LO16, - /* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; - the assembler turns it into a LDQ instruction to load the address of - the symbol, and then fills in a register in the real instruction. - - The LITERAL reloc, at the LDQ instruction, refers to the .lita - section symbol. The addend is ignored when writing, but is filled - in with the file's GP value on reading, for convenience, as with the - GPDISP_LO16 reloc. - - The LITUSE reloc, on the instruction using the loaded address, gives - information to the linker that it might be able to use to optimize - away some literal section references. The symbol is ignored (read - as the absolute section symbol), and the "addend" indicates the type - of instruction using the register: - 1 - "memory" fmt insn - 2 - byte-manipulation (byte offset reg) - 3 - jsr (target of branch) - - The GNU linker currently doesn't do any of this optimizing. */ +/* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +the assembler turns it into a LDQ instruction to load the address of +the symbol, and then fills in a register in the real instruction. + +The LITERAL reloc, at the LDQ instruction, refers to the .lita +section symbol. The addend is ignored when writing, but is filled +in with the file's GP value on reading, for convenience, as with the +GPDISP_LO16 reloc. + +The LITUSE reloc, on the instruction using the loaded address, gives +information to the linker that it might be able to use to optimize +away some literal section references. The symbol is ignored (read +as the absolute section symbol), and the "addend" indicates the type +of instruction using the register: +1 - "memory" fmt insn +2 - byte-manipulation (byte offset reg) +3 - jsr (target of branch) + +The GNU linker currently doesn't do any of this optimizing. */ BFD_RELOC_ALPHA_LITERAL, BFD_RELOC_ALPHA_LITUSE, - /* The HINT relocation indicates a value that should be filled into the - "hint" field of a jmp/jsr/ret instruction, for possible branch- - prediction logic which may be provided on some processors. */ +/* The HINT relocation indicates a value that should be filled into the +"hint" field of a jmp/jsr/ret instruction, for possible branch- +prediction logic which may be provided on some processors. */ BFD_RELOC_ALPHA_HINT, - /* Bits 27..2 of the relocation address shifted right 2 bits; - simple reloc otherwise. */ +/* Bits 27..2 of the relocation address shifted right 2 bits; +simple reloc otherwise. */ BFD_RELOC_MIPS_JMP, - /* High 16 bits of 32-bit value; simple reloc. */ +/* High 16 bits of 32-bit value; simple reloc. */ BFD_RELOC_HI16, - /* High 16 bits of 32-bit value but the low 16 bits will be sign - extended and added to form the final result. If the low 16 - bits form a negative number, we need to add one to the high value - to compensate for the borrow when the low bits are added. */ + +/* High 16 bits of 32-bit value but the low 16 bits will be sign +extended and added to form the final result. If the low 16 +bits form a negative number, we need to add one to the high value +to compensate for the borrow when the low bits are added. */ BFD_RELOC_HI16_S, - /* Low 16 bits. */ + +/* Low 16 bits. */ BFD_RELOC_LO16, - /* Like BFD_RELOC_HI16_S, but PC relative. */ + +/* Like BFD_RELOC_HI16_S, but PC relative. */ BFD_RELOC_PCREL_HI16_S, - /* Like BFD_RELOC_LO16, but PC relative. */ + +/* Like BFD_RELOC_LO16, but PC relative. */ BFD_RELOC_PCREL_LO16, - /* relocation relative to the global pointer. */ +/* Relocation relative to the global pointer. */ #define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16 - /* Relocation against a MIPS literal section. */ +/* Relocation against a MIPS literal section. */ BFD_RELOC_MIPS_LITERAL, - /* MIPS ELF relocations. */ +/* MIPS ELF relocations. */ BFD_RELOC_MIPS_GOT16, BFD_RELOC_MIPS_CALL16, #define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32 + BFD_RELOC_MIPS_GOT_HI16, + BFD_RELOC_MIPS_GOT_LO16, + BFD_RELOC_MIPS_CALL_HI16, + BFD_RELOC_MIPS_CALL_LO16, - /* i386/elf relocations */ +/* i386/elf relocations */ BFD_RELOC_386_GOT32, BFD_RELOC_386_PLT32, BFD_RELOC_386_COPY, @@ -1428,7 +1612,7 @@ typedef enum bfd_reloc_code_real BFD_RELOC_386_GOTOFF, BFD_RELOC_386_GOTPC, - /* ns32k relocations */ +/* ns32k relocations */ BFD_RELOC_NS32K_IMM_8, BFD_RELOC_NS32K_IMM_16, BFD_RELOC_NS32K_IMM_32, @@ -1442,22 +1626,68 @@ typedef enum bfd_reloc_code_real BFD_RELOC_NS32K_DISP_16_PCREL, BFD_RELOC_NS32K_DISP_32_PCREL, - /* PowerPC/POWER (RS/6000) relocs. */ - /* 26 bit relative branch. Low two bits must be zero. High 24 - bits installed in bits 6 through 29 of instruction. */ +/* Power(rs6000) and PowerPC relocations. */ BFD_RELOC_PPC_B26, - /* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute. */ BFD_RELOC_PPC_BA26, - /* 16 bit TOC relative reference. */ BFD_RELOC_PPC_TOC16, + BFD_RELOC_PPC_B16, + BFD_RELOC_PPC_B16_BRTAKEN, + BFD_RELOC_PPC_B16_BRNTAKEN, + BFD_RELOC_PPC_BA16, + BFD_RELOC_PPC_BA16_BRTAKEN, + BFD_RELOC_PPC_BA16_BRNTAKEN, + BFD_RELOC_PPC_COPY, + BFD_RELOC_PPC_GLOB_DAT, + BFD_RELOC_PPC_JMP_SLOT, + BFD_RELOC_PPC_RELATIVE, + BFD_RELOC_PPC_LOCAL24PC, + BFD_RELOC_PPC_EMB_NADDR32, + BFD_RELOC_PPC_EMB_NADDR16, + BFD_RELOC_PPC_EMB_NADDR16_LO, + BFD_RELOC_PPC_EMB_NADDR16_HI, + BFD_RELOC_PPC_EMB_NADDR16_HA, + BFD_RELOC_PPC_EMB_SDAI16, + BFD_RELOC_PPC_EMB_SDA2I16, + BFD_RELOC_PPC_EMB_SDA2REL, + BFD_RELOC_PPC_EMB_SDA21, + BFD_RELOC_PPC_EMB_MRKREF, + BFD_RELOC_PPC_EMB_RELSEC16, + BFD_RELOC_PPC_EMB_RELST_LO, + BFD_RELOC_PPC_EMB_RELST_HI, + BFD_RELOC_PPC_EMB_RELST_HA, + BFD_RELOC_PPC_EMB_BIT_FLD, + BFD_RELOC_PPC_EMB_RELSDA, + +/* The type of reloc used to build a contructor table - at the moment +probably a 32 bit wide absolute relocation, but the target can choose. +It generally does map to one of the other relocation types. */ + BFD_RELOC_CTOR, - /* this must be the highest numeric value */ - BFD_RELOC_UNUSED - } bfd_reloc_code_real_type; -const struct reloc_howto_struct * +/* ARM 26 bit pc-relative branch. The lowest two bits must be zero and are +not stored in the instruction. */ + BFD_RELOC_ARM_PCREL_BRANCH, + +/* These relocs are only used within the ARM assembler. They are not +(at present) written to any object files. */ + BFD_RELOC_ARM_IMMEDIATE, + BFD_RELOC_ARM_OFFSET_IMM, + BFD_RELOC_ARM_SHIFT_IMM, + BFD_RELOC_ARM_SWI, + BFD_RELOC_ARM_MULTI, + BFD_RELOC_ARM_CP_OFF_IMM, + BFD_RELOC_ARM_ADR_IMM, + BFD_RELOC_ARM_LDR_IMM, + BFD_RELOC_ARM_LITERAL, + BFD_RELOC_ARM_IN_POOL, + BFD_RELOC_UNUSED }; +typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; +reloc_howto_type * bfd_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); +const char * +bfd_get_reloc_code_name PARAMS ((bfd_reloc_code_real_type code)); + typedef struct symbol_cache_entry { @@ -1540,15 +1770,14 @@ typedef struct symbol_cache_entry /* Signal that the symbol is the label of constructor section. */ #define BSF_CONSTRUCTOR 0x800 - /* Signal that the symbol is a warning symbol. If the symbol - is a warning symbol, then the value field (I know this is - tacky) will point to the asymbol which when referenced will - cause the warning. */ + /* Signal that the symbol is a warning symbol. The name is a + warning. The name of the next symbol is the one to warn about; + if a reference is made to a symbol with the same name as the next + symbol, a warning is issued by the linker. */ #define BSF_WARNING 0x1000 - /* Signal that the symbol is indirect. The value of the symbol - is a pointer to an undefined asymbol which contains the - name to use instead. */ + /* Signal that the symbol is indirect. This symbol is an indirect + pointer to the symbol with the same name as the next symbol. */ #define BSF_INDIRECT 0x2000 /* BSF_FILE marks symbols that contain a file name. This is used @@ -1558,21 +1787,28 @@ typedef struct symbol_cache_entry /* Symbol is from dynamic linking information. */ #define BSF_DYNAMIC 0x8000 + /* The symbol denotes a data object. Used in ELF, and perhaps + others someday. */ +#define BSF_OBJECT 0x10000 + flagword flags; /* A pointer to the section to which this symbol is relative. This will always be non NULL, there are special - sections for undefined and absolute symbols */ + sections for undefined and absolute symbols. */ struct sec *section; - /* Back end special data. This is being phased out in favour - of making this a union. */ - PTR udata; + /* Back end special data. */ + union + { + PTR p; + bfd_vma i; + } udata; } asymbol; #define bfd_get_symtab_upper_bound(abfd) \ BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) -boolean +boolean bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym)); #define bfd_is_local_label(abfd, sym) \ @@ -1580,26 +1816,32 @@ bfd_is_local_label PARAMS ((bfd *abfd, asymbol *sym)); #define bfd_canonicalize_symtab(abfd, location) \ BFD_SEND (abfd, _bfd_canonicalize_symtab,\ (abfd, location)) -boolean +boolean bfd_set_symtab PARAMS ((bfd *abfd, asymbol **location, unsigned int count)); -void +void bfd_print_symbol_vandf PARAMS ((PTR file, asymbol *symbol)); #define bfd_make_empty_symbol(abfd) \ BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) #define bfd_make_debug_symbol(abfd,ptr,size) \ BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -int +int bfd_decode_symclass PARAMS ((asymbol *symbol)); -void +void bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret)); -struct _bfd +boolean +bfd_copy_private_symbol_data PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym)); + +#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ + BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \ + (ibfd, isymbol, obfd, osymbol)) +struct _bfd { /* The filename the application opened the BFD with. */ - CONST char *filename; + CONST char *filename; /* A pointer to the target jump table. */ const struct bfd_target *xvec; @@ -1608,8 +1850,10 @@ struct _bfd includes `<<bfd.h>>', IOSTREAM has been declared as a "char *", and MTIME as a "long". Their correct types, to which they are cast when used, are "FILE *" and "time_t". The iostream - is the result of an fopen on the filename. */ - char *iostream; + is the result of an fopen on the filename. However, if the + BFD_IN_MEMORY flag is set, then iostream is actually a pointer + to a bfd_in_memory struct. */ + PTR iostream; /* Is the file descriptor being cached? That is, can it be closed as needed, and re-opened when accessed later? */ @@ -1630,7 +1874,7 @@ struct _bfd /* When a file is closed by the caching routines, BFD retains state information on the file here: */ - file_ptr where; + file_ptr where; /* and here: (``once'' means at least once) */ @@ -1643,7 +1887,7 @@ struct _bfd /* File modified time, if mtime_set is true: */ - long mtime; + long mtime; /* Reserved for an unimplemented file locking extension.*/ @@ -1662,13 +1906,13 @@ struct _bfd /* Format_specific flags*/ - flagword flags; + flagword flags; /* Currently my_archive is tested before adding origin to anything. I believe that this can become always an add of origin, with origin set to 0 for non archive files. */ - file_ptr origin; + file_ptr origin; /* Remember when output has begun, to stop strange things from happening. */ @@ -1680,7 +1924,7 @@ struct _bfd /* The number of sections */ unsigned int section_count; - /* Stuff only useful for object files: + /* Stuff only useful for object files: The start address. */ bfd_vma start_address; @@ -1688,17 +1932,17 @@ struct _bfd unsigned int symcount; /* Symbol table for output BFD (with symcount entries) */ - struct symbol_cache_entry **outsymbols; + struct symbol_cache_entry **outsymbols; /* Pointer to structure which contains architecture information*/ - struct bfd_arch_info *arch_info; + const struct bfd_arch_info *arch_info; /* Stuff only useful for archives:*/ - PTR arelt_data; + PTR arelt_data; struct _bfd *my_archive; /* The containing archive BFD. */ struct _bfd *next; /* The next BFD in the archive. */ struct _bfd *archive_head; /* The first BFD in the archive. */ - boolean has_armap; + boolean has_armap; /* A chain of BFD structures involved in a link. */ struct _bfd *link_next; @@ -1709,17 +1953,20 @@ struct _bfd /* Used by the back end to hold private data. */ - union + union { struct aout_data_struct *aout_data; struct artdata *aout_ar_data; struct _oasys_data *oasys_obj_data; struct _oasys_ar_data *oasys_ar_data; struct coff_tdata *coff_obj_data; + struct pe_tdata *pe_obj_data; + struct xcoff_tdata *xcoff_obj_data; struct ecoff_tdata *ecoff_obj_data; struct ieee_data_struct *ieee_data; struct ieee_ar_data_struct *ieee_ar_data; struct srec_data_struct *srec_data; + struct ihex_data_struct *ihex_data; struct tekhex_data_struct *tekhex_data; struct elf_obj_tdata *elf_obj_data; struct nlm_obj_tdata *nlm_obj_data; @@ -1733,9 +1980,11 @@ struct _bfd struct lynx_core_struct *lynx_core_data; struct osf_core_struct *osf_core_data; struct cisco_core_struct *cisco_core_data; + struct versados_data_struct *versados_data; + struct netbsd_core_struct *netbsd_core_data; PTR any; } tdata; - + /* Used by the application to hold private data*/ PTR usrdata; @@ -1752,6 +2001,7 @@ typedef enum bfd_error bfd_error_invalid_operation, bfd_error_no_memory, bfd_error_no_symbols, + bfd_error_no_armap, bfd_error_no_more_archived_files, bfd_error_malformed_archive, bfd_error_file_not_recognized, @@ -1761,64 +2011,85 @@ typedef enum bfd_error bfd_error_no_debug_section, bfd_error_bad_value, bfd_error_file_truncated, + bfd_error_file_too_big, bfd_error_invalid_error_code } bfd_error_type; -bfd_error_type +bfd_error_type bfd_get_error PARAMS ((void)); -void +void bfd_set_error PARAMS ((bfd_error_type error_tag)); CONST char * bfd_errmsg PARAMS ((bfd_error_type error_tag)); -void +void bfd_perror PARAMS ((CONST char *message)); -long +typedef void (*bfd_error_handler_type) PARAMS ((const char *, ...)); + +bfd_error_handler_type +bfd_set_error_handler PARAMS ((bfd_error_handler_type)); + +void +bfd_set_error_program_name PARAMS ((const char *)); + +long bfd_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect)); -long +long bfd_canonicalize_reloc PARAMS ((bfd *abfd, asection *sec, arelent **loc, asymbol **syms)); -void +void bfd_set_reloc PARAMS ((bfd *abfd, asection *sec, arelent **rel, unsigned int count) - + ); -boolean +boolean bfd_set_file_flags PARAMS ((bfd *abfd, flagword flags)); -boolean +boolean bfd_set_start_address PARAMS ((bfd *abfd, bfd_vma vma)); -long +long bfd_get_mtime PARAMS ((bfd *abfd)); -long +long bfd_get_size PARAMS ((bfd *abfd)); -int +int bfd_get_gp_size PARAMS ((bfd *abfd)); -void +void bfd_set_gp_size PARAMS ((bfd *abfd, int i)); -bfd_vma +bfd_vma bfd_scan_vma PARAMS ((CONST char *string, CONST char **end, int base)); -boolean +boolean bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); #define bfd_copy_private_bfd_data(ibfd, obfd) \ BFD_SEND (ibfd, _bfd_copy_private_bfd_data, \ (ibfd, obfd)) +boolean +bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); + +#define bfd_merge_private_bfd_data(ibfd, obfd) \ + BFD_SEND (ibfd, _bfd_merge_private_bfd_data, \ + (ibfd, obfd)) +boolean +bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags)); + +#define bfd_set_private_flags(abfd, flags) \ + BFD_SEND (abfd, _bfd_set_private_flags, \ + (abfd, flags)) #define bfd_sizeof_headers(abfd, reloc) \ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc)) @@ -1839,13 +2110,12 @@ bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); #define bfd_stat_arch_elt(abfd, stat) \ BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +#define bfd_update_armap_timestamp(abfd) \ + BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) + #define bfd_set_arch_mach(abfd, arch, mach)\ BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) -#define bfd_get_relocated_section_contents(abfd, link_info, link_order, data, relocateable, symbols) \ - BFD_SEND (abfd, _bfd_get_relocated_section_contents, \ - (abfd, link_info, link_order, data, relocateable, symbols)) - #define bfd_relax_section(abfd, section, link_info, again) \ BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) @@ -1864,6 +2134,9 @@ bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); #define bfd_get_dynamic_symtab_upper_bound(abfd) \ BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) +#define bfd_print_private_bfd_data(abfd, file)\ + BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) + #define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) @@ -1873,25 +2146,27 @@ bfd_copy_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); #define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) -symindex +extern bfd_byte *bfd_get_relocated_section_contents + PARAMS ((bfd *, struct bfd_link_info *, + struct bfd_link_order *, bfd_byte *, + boolean, asymbol **)); + +symindex bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym)); -boolean +boolean bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head)); bfd * -bfd_get_elt_at_index PARAMS ((bfd *archive, int index)); - -bfd * bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous)); CONST char * bfd_core_file_failing_command PARAMS ((bfd *abfd)); -int +int bfd_core_file_failing_signal PARAMS ((bfd *abfd)); -boolean +boolean core_file_matches_executable_p PARAMS ((bfd *core_bfd, bfd *exec_bfd)); @@ -1926,8 +2201,14 @@ enum bfd_flavour { bfd_target_oasys_flavour, bfd_target_tekhex_flavour, bfd_target_srec_flavour, + bfd_target_ihex_flavour, bfd_target_som_flavour, - bfd_target_os9k_flavour}; + bfd_target_os9k_flavour, + bfd_target_versados_flavour, + bfd_target_msdos_flavour +}; + +enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; /* Forward declaration. */ typedef struct bfd_link_info _bfd_link_info; @@ -1936,14 +2217,13 @@ typedef struct bfd_target { char *name; enum bfd_flavour flavour; - boolean byteorder_big_p; - boolean header_byteorder_big_p; - flagword object_flags; + enum bfd_endian byteorder; + enum bfd_endian header_byteorder; + flagword object_flags; flagword section_flags; char symbol_leading_char; - char ar_pad_char; + char ar_pad_char; unsigned short ar_max_namelen; - unsigned int align_power_min; bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *)); bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *)); void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); @@ -1971,7 +2251,9 @@ typedef struct bfd_target CAT(NAME,_close_and_cleanup),\ CAT(NAME,_bfd_free_cached_info),\ CAT(NAME,_new_section_hook),\ -CAT(NAME,_get_section_contents) +CAT(NAME,_get_section_contents),\ +CAT(NAME,_get_section_contents_in_window) + /* Called when the BFD is being closed to do any necessary cleanup. */ boolean (*_close_and_cleanup) PARAMS ((bfd *)); /* Ask the BFD to free all cached information. */ @@ -1979,20 +2261,39 @@ CAT(NAME,_get_section_contents) /* Called when a new section is created. */ boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); /* Read the contents of a section. */ - boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, + boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); + boolean (*_bfd_get_section_contents_in_window) + PARAMS ((bfd *, sec_ptr, bfd_window *, + file_ptr, bfd_size_type)); /* Entry points to copy private data. */ #define BFD_JUMP_TABLE_COPY(NAME)\ CAT(NAME,_bfd_copy_private_bfd_data),\ -CAT(NAME,_bfd_copy_private_section_data) +CAT(NAME,_bfd_merge_private_bfd_data),\ +CAT(NAME,_bfd_copy_private_section_data),\ +CAT(NAME,_bfd_copy_private_symbol_data),\ +CAT(NAME,_bfd_set_private_flags),\ +CAT(NAME,_bfd_print_private_bfd_data)\ /* Called to copy BFD general private data from one object file to another. */ boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)); + /* Called to merge BFD general private data from one object file + to a common output file when linking. */ + boolean (*_bfd_merge_private_bfd_data) PARAMS ((bfd *, bfd *)); /* Called to copy BFD private section data from one object file to another. */ boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr, bfd *, sec_ptr)); + /* Called to copy BFD private symbol data from one symbol + to another. */ + boolean (*_bfd_copy_private_symbol_data) PARAMS ((bfd *, asymbol *, + bfd *, asymbol *)); + /* Called to set private backend flags */ + boolean (*_bfd_set_private_flags) PARAMS ((bfd *, flagword)); + + /* Called to print private BFD data */ + boolean (*_bfd_print_private_bfd_data) PARAMS ((bfd *, PTR)); /* Core file entry points. */ #define BFD_JUMP_TABLE_CORE(NAME)\ @@ -2007,20 +2308,30 @@ CAT(NAME,_core_file_matches_executable_p) #define BFD_JUMP_TABLE_ARCHIVE(NAME)\ CAT(NAME,_slurp_armap),\ CAT(NAME,_slurp_extended_name_table),\ +CAT(NAME,_construct_extended_name_table),\ CAT(NAME,_truncate_arname),\ CAT(NAME,_write_armap),\ +CAT(NAME,_read_ar_hdr),\ CAT(NAME,_openr_next_archived_file),\ -CAT(NAME,_generic_stat_arch_elt) +CAT(NAME,_get_elt_at_index),\ +CAT(NAME,_generic_stat_arch_elt),\ +CAT(NAME,_update_armap_timestamp) boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); + boolean (*_bfd_construct_extended_name_table) + PARAMS ((bfd *, char **, bfd_size_type *, const char **)); void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); - boolean (*write_armap) PARAMS ((bfd *arch, + boolean (*write_armap) PARAMS ((bfd *arch, unsigned int elength, struct orl *map, - unsigned int orl_count, + unsigned int orl_count, int stridx)); - bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); - int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); + PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *)); + bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); +#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i)) + bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex)); + int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); + boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *)); /* Entry points used for symbols. */ #define BFD_JUMP_TABLE_SYMBOLS(NAME)\ @@ -2032,7 +2343,9 @@ CAT(NAME,_get_symbol_info),\ CAT(NAME,_bfd_is_local_label),\ CAT(NAME,_get_lineno),\ CAT(NAME,_find_nearest_line),\ -CAT(NAME,_bfd_make_debug_symbol) +CAT(NAME,_bfd_make_debug_symbol),\ +CAT(NAME,_read_minisymbols),\ +CAT(NAME,_minisymbol_to_symbol) long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *)); long (*_bfd_canonicalize_symtab) PARAMS ((bfd *, struct symbol_cache_entry **)); @@ -2056,10 +2369,18 @@ CAT(NAME,_bfd_make_debug_symbol) /* Back-door to allow format-aware applications to create debug symbols while using BFD for everything else. Currently used by the assembler when creating COFF files. */ - asymbol * (*_bfd_make_debug_symbol) PARAMS (( + asymbol * (*_bfd_make_debug_symbol) PARAMS (( bfd *abfd, void *ptr, unsigned long size)); +#define bfd_read_minisymbols(b, d, m, s) \ + BFD_SEND (b, _read_minisymbols, (b, d, m, s)) + long (*_read_minisymbols) PARAMS ((bfd *, boolean, PTR *, + unsigned int *)); +#define bfd_minisymbol_to_symbol(b, d, m, f) \ + BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) + asymbol *(*_minisymbol_to_symbol) PARAMS ((bfd *, boolean, const PTR, + asymbol *)); /* Routines for relocs. */ #define BFD_JUMP_TABLE_RELOCS(NAME)\ @@ -2070,7 +2391,7 @@ CAT(NAME,_bfd_reloc_type_lookup) long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, struct symbol_cache_entry **)); /* See documentation on reloc types. */ - CONST struct reloc_howto_struct * + reloc_howto_type * (*reloc_type_lookup) PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); @@ -2090,7 +2411,8 @@ CAT(NAME,_bfd_get_relocated_section_contents),\ CAT(NAME,_bfd_relax_section),\ CAT(NAME,_bfd_link_hash_table_create),\ CAT(NAME,_bfd_link_add_symbols),\ -CAT(NAME,_bfd_final_link) +CAT(NAME,_bfd_final_link),\ +CAT(NAME,_bfd_link_split_section) int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, @@ -2111,6 +2433,9 @@ CAT(NAME,_bfd_final_link) section of the BFD. */ boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *)); + /* Should this section be split up into smaller pieces during linking. */ + boolean (*_bfd_link_split_section) PARAMS ((bfd *, struct sec *)); + /* Routines to handle dynamic symbols and relocs. */ #define BFD_JUMP_TABLE_DYNAMIC(NAME)\ CAT(NAME,_get_dynamic_symtab_upper_bound),\ @@ -2136,16 +2461,19 @@ bfd_find_target PARAMS ((CONST char *target_name, bfd *abfd)); const char ** bfd_target_list PARAMS ((void)); -boolean +boolean bfd_check_format PARAMS ((bfd *abfd, bfd_format format)); -boolean +boolean bfd_check_format_matches PARAMS ((bfd *abfd, bfd_format format, char ***matching)); -boolean +boolean bfd_set_format PARAMS ((bfd *abfd, bfd_format format)); CONST char * bfd_format_string PARAMS ((bfd_format format)); +#ifdef __cplusplus +} +#endif #endif diff --git a/gnu/usr.bin/gdb/bfd/cache.c b/gnu/usr.bin/gdb/bfd/cache.c deleted file mode 100644 index fc02122..0000000 --- a/gnu/usr.bin/gdb/bfd/cache.c +++ /dev/null @@ -1,343 +0,0 @@ -/* BFD library -- caching of file descriptors. - Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc. - Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com). - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - File caching - - The file caching mechanism is embedded within BFD and allows - the application to open as many BFDs as it wants without - regard to the underlying operating system's file descriptor - limit (often as low as 20 open files). The module in - <<cache.c>> maintains a least recently used list of - <<BFD_CACHE_MAX_OPEN>> files, and exports the name - <<bfd_cache_lookup>>, which runs around and makes sure that - the required BFD is open. If not, then it chooses a file to - close, closes it and opens the one wanted, returning its file - handle. - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static void insert PARAMS ((bfd *)); -static void snip PARAMS ((bfd *)); -static boolean close_one PARAMS ((void)); -static boolean bfd_cache_delete PARAMS ((bfd *)); - -/* -INTERNAL_FUNCTION - BFD_CACHE_MAX_OPEN macro - -DESCRIPTION - The maximum number of files which the cache will keep open at - one time. - -.#define BFD_CACHE_MAX_OPEN 10 - -*/ - -/* The number of BFD files we have open. */ - -static int open_files; - -/* -INTERNAL_FUNCTION - bfd_last_cache - -SYNOPSIS - extern bfd *bfd_last_cache; - -DESCRIPTION - Zero, or a pointer to the topmost BFD on the chain. This is - used by the <<bfd_cache_lookup>> macro in @file{libbfd.h} to - determine when it can avoid a function call. -*/ - -bfd *bfd_last_cache; - -/* - INTERNAL_FUNCTION - bfd_cache_lookup - - DESCRIPTION - Check to see if the required BFD is the same as the last one - looked up. If so, then it can use the stream in the BFD with - impunity, since it can't have changed since the last lookup; - otherwise, it has to perform the complicated lookup function. - - .#define bfd_cache_lookup(x) \ - . ((x)==bfd_last_cache? \ - . (FILE*)(bfd_last_cache->iostream): \ - . bfd_cache_lookup_worker(x)) - - - */ - -/* Insert a BFD into the cache. */ - -static INLINE void -insert (abfd) - bfd *abfd; -{ - if (bfd_last_cache == NULL) - { - abfd->lru_next = abfd; - abfd->lru_prev = abfd; - } - else - { - abfd->lru_next = bfd_last_cache; - abfd->lru_prev = bfd_last_cache->lru_prev; - abfd->lru_prev->lru_next = abfd; - abfd->lru_next->lru_prev = abfd; - } - bfd_last_cache = abfd; -} - -/* Remove a BFD from the cache. */ - -static INLINE void -snip (abfd) - bfd *abfd; -{ - abfd->lru_prev->lru_next = abfd->lru_next; - abfd->lru_next->lru_prev = abfd->lru_prev; - if (abfd == bfd_last_cache) - { - bfd_last_cache = abfd->lru_next; - if (abfd == bfd_last_cache) - bfd_last_cache = NULL; - } -} - -/* We need to open a new file, and the cache is full. Find the least - recently used cacheable BFD and close it. */ - -static boolean -close_one () -{ - register bfd *kill; - - if (bfd_last_cache == NULL) - kill = NULL; - else - { - for (kill = bfd_last_cache->lru_prev; - ! kill->cacheable; - kill = kill->lru_prev) - { - if (kill == bfd_last_cache) - { - kill = NULL; - break; - } - } - } - - if (kill == NULL) - { - /* There are no open cacheable BFD's. */ - return true; - } - - kill->where = ftell ((FILE *) kill->iostream); - - return bfd_cache_delete (kill); -} - -/* Close a BFD and remove it from the cache. */ - -static boolean -bfd_cache_delete (abfd) - bfd *abfd; -{ - boolean ret; - - if (fclose ((FILE *) abfd->iostream) == 0) - ret = true; - else - { - ret = false; - bfd_set_error (bfd_error_system_call); - } - - snip (abfd); - - abfd->iostream = NULL; - --open_files; - - return ret; -} - -/* -INTERNAL_FUNCTION - bfd_cache_init - -SYNOPSIS - boolean bfd_cache_init (bfd *abfd); - -DESCRIPTION - Add a newly opened BFD to the cache. -*/ - -boolean -bfd_cache_init (abfd) - bfd *abfd; -{ - BFD_ASSERT (abfd->iostream != NULL); - if (open_files >= BFD_CACHE_MAX_OPEN) - { - if (! close_one ()) - return false; - } - insert (abfd); - ++open_files; - return true; -} - -/* -INTERNAL_FUNCTION - bfd_cache_close - -SYNOPSIS - boolean bfd_cache_close (bfd *abfd); - -DESCRIPTION - Remove the BFD @var{abfd} from the cache. If the attached file is open, - then close it too. - -RETURNS - <<false>> is returned if closing the file fails, <<true>> is - returned if all is well. -*/ - -boolean -bfd_cache_close (abfd) - bfd *abfd; -{ - if (abfd->iostream == NULL) - return true; - - return bfd_cache_delete (abfd); -} - -/* -INTERNAL_FUNCTION - bfd_open_file - -SYNOPSIS - FILE* bfd_open_file(bfd *abfd); - -DESCRIPTION - Call the OS to open a file for @var{abfd}. Return the <<FILE *>> - (possibly <<NULL>>) that results from this operation. Set up the - BFD so that future accesses know the file is open. If the <<FILE *>> - returned is <<NULL>>, then it won't have been put in the - cache, so it won't have to be removed from it. -*/ - -FILE * -bfd_open_file (abfd) - bfd *abfd; -{ - abfd->cacheable = true; /* Allow it to be closed later. */ - - if (open_files >= BFD_CACHE_MAX_OPEN) - { - if (! close_one ()) - return NULL; - } - - switch (abfd->direction) - { - case read_direction: - case no_direction: - abfd->iostream = (char *) fopen (abfd->filename, FOPEN_RB); - break; - case both_direction: - case write_direction: - if (abfd->opened_once == true) - { - abfd->iostream = (char *) fopen (abfd->filename, FOPEN_RUB); - if (abfd->iostream == NULL) - abfd->iostream = (char *) fopen (abfd->filename, FOPEN_WUB); - } - else - { - /*open for creat */ - abfd->iostream = (char *) fopen (abfd->filename, FOPEN_WB); - abfd->opened_once = true; - } - break; - } - - if (abfd->iostream != NULL) - { - if (! bfd_cache_init (abfd)) - return NULL; - } - - return (FILE *) abfd->iostream; -} - -/* -INTERNAL_FUNCTION - bfd_cache_lookup_worker - -SYNOPSIS - FILE *bfd_cache_lookup_worker(bfd *abfd); - -DESCRIPTION - Called when the macro <<bfd_cache_lookup>> fails to find a - quick answer. Find a file descriptor for @var{abfd}. If - necessary, it open it. If there are already more than - <<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to - avoid running out of file descriptors. -*/ - -FILE * -bfd_cache_lookup_worker (abfd) - bfd *abfd; -{ - if (abfd->my_archive) - abfd = abfd->my_archive; - - if (abfd->iostream != NULL) - { - /* Move the file to the start of the cache. */ - if (abfd != bfd_last_cache) - { - snip (abfd); - insert (abfd); - } - } - else - { - if (bfd_open_file (abfd) == NULL) - return NULL; - if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0) - return NULL; - } - - return (FILE *) abfd->iostream; -} diff --git a/gnu/usr.bin/gdb/bfd/coff-i386.c b/gnu/usr.bin/gdb/bfd/coff-i386.c deleted file mode 100644 index aaac075..0000000 --- a/gnu/usr.bin/gdb/bfd/coff-i386.c +++ /dev/null @@ -1,354 +0,0 @@ -/* BFD back-end for Intel 386 COFF files. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/i386.h" -#include "coff/internal.h" -#include "libcoff.h" - -static bfd_reloc_status_type coff_i386_reloc PARAMS ((bfd *abfd, - arelent *reloc_entry, - asymbol *symbol, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message)); - -/* The page size is a guess based on ELF. */ -#define COFF_PAGE_SIZE 0x1000 - -/* For some reason when using i386 COFF the value stored in the .text - section for a reference to a common symbol is the value itself plus - any desired offset. Ian Taylor, Cygnus Support. */ - -/* If we are producing relocateable output, we need to do some - adjustments to the object file that are not done by the - bfd_perform_relocation function. This function is called by every - reloc type to make any required adjustments. */ - -static bfd_reloc_status_type -coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - symvalue diff; - - if (output_bfd == (bfd *) NULL) - return bfd_reloc_continue; - - if (bfd_is_com_section (symbol->section)) - { - /* We are relocating a common symbol. The current value in the - object file is ORIG + OFFSET, where ORIG is the value of the - common symbol as seen by the object file when it was compiled - (this may be zero if the symbol was undefined) and OFFSET is - the offset into the common symbol (normally zero, but may be - non-zero when referring to a field in a common structure). - ORIG is the negative of reloc_entry->addend, which is set by - the CALC_ADDEND macro below. We want to replace the value in - the object file with NEW + OFFSET, where NEW is the value of - the common symbol which we are going to put in the final - object file. NEW is symbol->value. */ - diff = symbol->value + reloc_entry->addend; - } - else - { - /* For some reason bfd_perform_relocation always effectively - ignores the addend for a COFF target when producing - relocateable output. This seems to be always wrong for 386 - COFF, so we handle the addend here instead. */ - diff = reloc_entry->addend; - } - -#define DOIT(x) \ - x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) & howto->dst_mask)) - - if (diff != 0) - { - const reloc_howto_type *howto = reloc_entry->howto; - unsigned char *addr = (unsigned char *) data + reloc_entry->address; - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, addr); - DOIT (x); - bfd_put_8 (abfd, x, addr); - } - break; - - case 1: - { - short x = bfd_get_16 (abfd, addr); - DOIT (x); - bfd_put_16 (abfd, x, addr); - } - break; - - case 2: - { - long x = bfd_get_32 (abfd, addr); - DOIT (x); - bfd_put_32 (abfd, x, addr); - } - break; - - default: - abort (); - } - } - - /* Now let bfd_perform_relocation finish everything up. */ - return bfd_reloc_continue; -} - -static reloc_howto_type howto_table[] = -{ - {0}, - {1}, - {2}, - {3}, - {4}, - {5}, - HOWTO (R_DIR32, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "dir32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - {7}, - {010}, - {011}, - {012}, - {013}, - {014}, - {015}, - {016}, - HOWTO (R_RELBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - false), /* pcrel_offset */ - HOWTO (R_RELWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - HOWTO (R_RELLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - false, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_bitfield, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false), /* pcrel_offset */ - HOWTO (R_PCRBYTE, /* type */ - 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ - 8, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP8", /* name */ - true, /* partial_inplace */ - 0x000000ff, /* src_mask */ - 0x000000ff, /* dst_mask */ - false), /* pcrel_offset */ - HOWTO (R_PCRWORD, /* type */ - 0, /* rightshift */ - 1, /* size (0 = byte, 1 = short, 2 = long) */ - 16, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP16", /* name */ - true, /* partial_inplace */ - 0x0000ffff, /* src_mask */ - 0x0000ffff, /* dst_mask */ - false), /* pcrel_offset */ - HOWTO (R_PCRLONG, /* type */ - 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ - 0, /* bitpos */ - complain_overflow_signed, /* complain_on_overflow */ - coff_i386_reloc, /* special_function */ - "DISP32", /* name */ - true, /* partial_inplace */ - 0xffffffff, /* src_mask */ - 0xffffffff, /* dst_mask */ - false) /* pcrel_offset */ -}; - -/* Turn a howto into a reloc nunmber */ - -#define SELECT_RELOC(x,howto) { x.r_type = howto->type; } -#define BADMAG(x) I386BADMAG(x) -#define I386 1 /* Customize coffcode.h */ - -#define RTYPE2HOWTO(cache_ptr, dst) \ - cache_ptr->howto = howto_table + (dst)->r_type; - -/* On SCO Unix 3.2.2 the native assembler generates two .data - sections. We handle that by renaming the second one to .data2. It - does no harm to do this for any 386 COFF target. */ -#define TWO_DATA_SECS - -/* For 386 COFF a STYP_NOLOAD | STYP_BSS section is part of a shared - library. On some other COFF targets STYP_BSS is normally - STYP_NOLOAD. */ -#define BSS_NOLOAD_IS_SHARED_LIBRARY - -/* Compute the addend of a reloc. If the reloc is to a common symbol, - the object file contains the value of the common symbol. By the - time this is called, the linker may be using a different symbol - from a different object file with a different value. Therefore, we - hack wildly to locate the original symbol from this file so that we - can make the correct adjustment. This macro sets coffsym to the - symbol from the original file, and uses it to set the addend value - correctly. If this is not a common symbol, the usual addend - calculation is done, except that an additional tweak is needed for - PC relative relocs. - FIXME: This macro refers to symbols and asect; these are from the - calling function, not the macro arguments. */ - -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = - coffsym->native->u.syment.n_value; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - if (ptr && howto_table[reloc.r_type].pc_relative) \ - cache_ptr->addend += asect->vma; \ - } - -#include "coffcode.h" - -static const bfd_target * -i3coff_object_p(a) - bfd *a; -{ - return coff_object_p(a); -} - -const bfd_target -#ifdef TARGET_SYM - TARGET_SYM = -#else - i386coff_vec = -#endif -{ -#ifdef TARGET_NAME - TARGET_NAME, -#else - "coff-i386", /* name */ -#endif - bfd_target_coff_flavour, - false, /* data byte order is little */ - false, /* header byte order is little */ - - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - '/', /* ar_pad_char */ - 15, /* ar_max_namelen */ - - 2, /* minimum alignment power */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - -/* Note that we allow an object file to be treated as a core file as well. */ - {_bfd_dummy_target, i3coff_object_p, /* bfd_check_format */ - bfd_generic_archive_p, i3coff_object_p}, - {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */ - bfd_false}, - {bfd_false, coff_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, - - BFD_JUMP_TABLE_GENERIC (coff), - BFD_JUMP_TABLE_COPY (coff), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (coff), - BFD_JUMP_TABLE_RELOCS (coff), - BFD_JUMP_TABLE_WRITE (coff), - BFD_JUMP_TABLE_LINK (coff), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - COFF_SWAP_TABLE, -}; diff --git a/gnu/usr.bin/gdb/bfd/coffcode.h b/gnu/usr.bin/gdb/bfd/coffcode.h deleted file mode 100644 index 206a381..0000000 --- a/gnu/usr.bin/gdb/bfd/coffcode.h +++ /dev/null @@ -1,2544 +0,0 @@ -/* Support for the generic parts of most COFF variants, for BFD. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -Most of this hacked by Steve Chamberlain, - sac@cygnus.com -*/ -/* - -SECTION - coff backends - - BFD supports a number of different flavours of coff format. - The major differences between formats are the sizes and - alignments of fields in structures on disk, and the occasional - extra field. - - Coff in all its varieties is implemented with a few common - files and a number of implementation specific files. For - example, The 88k bcs coff format is implemented in the file - @file{coff-m88k.c}. This file @code{#include}s - @file{coff/m88k.h} which defines the external structure of the - coff format for the 88k, and @file{coff/internal.h} which - defines the internal structure. @file{coff-m88k.c} also - defines the relocations used by the 88k format - @xref{Relocations}. - - The Intel i960 processor version of coff is implemented in - @file{coff-i960.c}. This file has the same structure as - @file{coff-m88k.c}, except that it includes @file{coff/i960.h} - rather than @file{coff-m88k.h}. - -SUBSECTION - Porting to a new version of coff - - The recommended method is to select from the existing - implementations the version of coff which is most like the one - you want to use. For example, we'll say that i386 coff is - the one you select, and that your coff flavour is called foo. - Copy @file{i386coff.c} to @file{foocoff.c}, copy - @file{../include/coff/i386.h} to @file{../include/coff/foo.h}, - and add the lines to @file{targets.c} and @file{Makefile.in} - so that your new back end is used. Alter the shapes of the - structures in @file{../include/coff/foo.h} so that they match - what you need. You will probably also have to add - @code{#ifdef}s to the code in @file{coff/internal.h} and - @file{coffcode.h} if your version of coff is too wild. - - You can verify that your new BFD backend works quite simply by - building @file{objdump} from the @file{binutils} directory, - and making sure that its version of what's going on and your - host system's idea (assuming it has the pretty standard coff - dump utility, usually called @code{att-dump} or just - @code{dump}) are the same. Then clean up your code, and send - what you've done to Cygnus. Then your stuff will be in the - next release, and you won't have to keep integrating it. - -SUBSECTION - How the coff backend works - -SUBSUBSECTION - File layout - - The Coff backend is split into generic routines that are - applicable to any Coff target and routines that are specific - to a particular target. The target-specific routines are - further split into ones which are basically the same for all - Coff targets except that they use the external symbol format - or use different values for certain constants. - - The generic routines are in @file{coffgen.c}. These routines - work for any Coff target. They use some hooks into the target - specific code; the hooks are in a @code{bfd_coff_backend_data} - structure, one of which exists for each target. - - The essentially similar target-specific routines are in - @file{coffcode.h}. This header file includes executable C code. - The various Coff targets first include the appropriate Coff - header file, make any special defines that are needed, and - then include @file{coffcode.h}. - - Some of the Coff targets then also have additional routines in - the target source file itself. - - For example, @file{coff-i960.c} includes - @file{coff/internal.h} and @file{coff/i960.h}. It then - defines a few constants, such as @code{I960}, and includes - @file{coffcode.h}. Since the i960 has complex relocation - types, @file{coff-i960.c} also includes some code to - manipulate the i960 relocs. This code is not in - @file{coffcode.h} because it would not be used by any other - target. - -SUBSUBSECTION - Bit twiddling - - Each flavour of coff supported in BFD has its own header file - describing the external layout of the structures. There is also - an internal description of the coff layout, in - @file{coff/internal.h}. A major function of the - coff backend is swapping the bytes and twiddling the bits to - translate the external form of the structures into the normal - internal form. This is all performed in the - @code{bfd_swap}_@i{thing}_@i{direction} routines. Some - elements are different sizes between different versions of - coff; it is the duty of the coff version specific include file - to override the definitions of various packing routines in - @file{coffcode.h}. E.g., the size of line number entry in coff is - sometimes 16 bits, and sometimes 32 bits. @code{#define}ing - @code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the - correct one. No doubt, some day someone will find a version of - coff which has a varying field size not catered to at the - moment. To port BFD, that person will have to add more @code{#defines}. - Three of the bit twiddling routines are exported to - @code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in} - and @code{coff_swap_linno_in}. @code{GDB} reads the symbol - table on its own, but uses BFD to fix things up. More of the - bit twiddlers are exported for @code{gas}; - @code{coff_swap_aux_out}, @code{coff_swap_sym_out}, - @code{coff_swap_lineno_out}, @code{coff_swap_reloc_out}, - @code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out}, - @code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track - of all the symbol table and reloc drudgery itself, thereby - saving the internal BFD overhead, but uses BFD to swap things - on the way out, making cross ports much safer. Doing so also - allows BFD (and thus the linker) to use the same header files - as @code{gas}, which makes one avenue to disaster disappear. - -SUBSUBSECTION - Symbol reading - - The simple canonical form for symbols used by BFD is not rich - enough to keep all the information available in a coff symbol - table. The back end gets around this problem by keeping the original - symbol table around, "behind the scenes". - - When a symbol table is requested (through a call to - @code{bfd_canonicalize_symtab}), a request gets through to - @code{coff_get_normalized_symtab}. This reads the symbol table from - the coff file and swaps all the structures inside into the - internal form. It also fixes up all the pointers in the table - (represented in the file by offsets from the first symbol in - the table) into physical pointers to elements in the new - internal table. This involves some work since the meanings of - fields change depending upon context: a field that is a - pointer to another structure in the symbol table at one moment - may be the size in bytes of a structure at the next. Another - pass is made over the table. All symbols which mark file names - (<<C_FILE>> symbols) are modified so that the internal - string points to the value in the auxent (the real filename) - rather than the normal text associated with the symbol - (@code{".file"}). - - At this time the symbol names are moved around. Coff stores - all symbols less than nine characters long physically - within the symbol table; longer strings are kept at the end of - the file in the string table. This pass moves all strings - into memory and replaces them with pointers to the strings. - - - The symbol table is massaged once again, this time to create - the canonical table used by the BFD application. Each symbol - is inspected in turn, and a decision made (using the - @code{sclass} field) about the various flags to set in the - @code{asymbol}. @xref{Symbols}. The generated canonical table - shares strings with the hidden internal symbol table. - - Any linenumbers are read from the coff file too, and attached - to the symbols which own the functions the linenumbers belong to. - -SUBSUBSECTION - Symbol writing - - Writing a symbol to a coff file which didn't come from a coff - file will lose any debugging information. The @code{asymbol} - structure remembers the BFD from which the symbol was taken, and on - output the back end makes sure that the same destination target as - source target is present. - - When the symbols have come from a coff file then all the - debugging information is preserved. - - Symbol tables are provided for writing to the back end in a - vector of pointers to pointers. This allows applications like - the linker to accumulate and output large symbol tables - without having to do too much byte copying. - - This function runs through the provided symbol table and - patches each symbol marked as a file place holder - (@code{C_FILE}) to point to the next file place holder in the - list. It also marks each @code{offset} field in the list with - the offset from the first symbol of the current symbol. - - Another function of this procedure is to turn the canonical - value form of BFD into the form used by coff. Internally, BFD - expects symbol values to be offsets from a section base; so a - symbol physically at 0x120, but in a section starting at - 0x100, would have the value 0x20. Coff expects symbols to - contain their final value, so symbols have their values - changed at this point to reflect their sum with their owning - section. This transformation uses the - <<output_section>> field of the @code{asymbol}'s - @code{asection} @xref{Sections}. - - o <<coff_mangle_symbols>> - - This routine runs though the provided symbol table and uses - the offsets generated by the previous pass and the pointers - generated when the symbol table was read in to create the - structured hierachy required by coff. It changes each pointer - to a symbol into the index into the symbol table of the asymbol. - - o <<coff_write_symbols>> - - This routine runs through the symbol table and patches up the - symbols from their internal form into the coff way, calls the - bit twiddlers, and writes out the table to the file. - -*/ - -/* -INTERNAL_DEFINITION - coff_symbol_type - -DESCRIPTION - The hidden information for an <<asymbol>> is described in a - <<combined_entry_type>>: - -CODE_FRAGMENT -. -.typedef struct coff_ptr_struct -.{ -. -. {* Remembers the offset from the first symbol in the file for -. this symbol. Generated by coff_renumber_symbols. *} -.unsigned int offset; -. -. {* Should the value of this symbol be renumbered. Used for -. XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. *} -.unsigned int fix_value : 1; -. -. {* Should the tag field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} -.unsigned int fix_tag : 1; -. -. {* Should the endidx field of this symbol be renumbered. -. Created by coff_pointerize_aux. *} -.unsigned int fix_end : 1; -. -. {* Should the x_csect.x_scnlen field be renumbered. -. Created by coff_slurp_symbol_table. *} -.unsigned int fix_scnlen : 1; -. -. {* The container for the symbol structure as read and translated -. from the file. *} -. -.union { -. union internal_auxent auxent; -. struct internal_syment syment; -. } u; -.} combined_entry_type; -. -. -.{* Each canonical asymbol really looks like this: *} -. -.typedef struct coff_symbol_struct -.{ -. {* The actual symbol which the rest of BFD works with *} -.asymbol symbol; -. -. {* A pointer to the hidden information for this symbol *} -.combined_entry_type *native; -. -. {* A pointer to the linenumber information for this symbol *} -.struct lineno_cache_entry *lineno; -. -. {* Have the line numbers been relocated yet ? *} -.boolean done_lineno; -.} coff_symbol_type; - - -*/ - -#include "coffswap.h" - -/* void warning(); */ - -/* - * Return a word with STYP_* (scnhdr.s_flags) flags set to represent the - * incoming SEC_* flags. The inverse of this function is styp_to_sec_flags(). - * NOTE: If you add to/change this routine, you should mirror the changes - * in styp_to_sec_flags(). - */ -static long -sec_to_styp_flags (sec_name, sec_flags) - CONST char *sec_name; - flagword sec_flags; -{ - long styp_flags = 0; - - if (!strcmp (sec_name, _TEXT)) - { - styp_flags = STYP_TEXT; - } - else if (!strcmp (sec_name, _DATA)) - { - styp_flags = STYP_DATA; -#ifdef TWO_DATA_SECS - } - else if (!strcmp (sec_name, ".data2")) - { - styp_flags = STYP_DATA; -#endif /* TWO_DATA_SECS */ - } - else if (!strcmp (sec_name, _BSS)) - { - styp_flags = STYP_BSS; -#ifdef _COMMENT - } - else if (!strcmp (sec_name, _COMMENT)) - { - styp_flags = STYP_INFO; -#endif /* _COMMENT */ -#ifdef _LIB - } - else if (!strcmp (sec_name, _LIB)) - { - styp_flags = STYP_LIB; -#endif /* _LIB */ -#ifdef _LIT - } - else if (!strcmp (sec_name, _LIT)) - { - styp_flags = STYP_LIT; -#endif /* _LIT */ - } - else if (!strcmp (sec_name, ".debug")) - { -#ifdef STYP_DEBUG - styp_flags = STYP_DEBUG; -#else - styp_flags = STYP_INFO; -#endif - } - else if (!strcmp (sec_name, ".stab") - || !strncmp (sec_name, ".stabstr", 8)) - { - styp_flags = STYP_INFO; - } - /* Try and figure out what it should be */ - else if (sec_flags & SEC_CODE) - { - styp_flags = STYP_TEXT; - } - else if (sec_flags & SEC_DATA) - { - styp_flags = STYP_DATA; - } - else if (sec_flags & SEC_READONLY) - { -#ifdef STYP_LIT /* 29k readonly text/data section */ - styp_flags = STYP_LIT; -#else - styp_flags = STYP_TEXT; -#endif /* STYP_LIT */ - } - else if (sec_flags & SEC_LOAD) - { - styp_flags = STYP_TEXT; - } - else if (sec_flags & SEC_ALLOC) - { - styp_flags = STYP_BSS; - } - -#ifdef STYP_NOLOAD - if ((sec_flags & (SEC_NEVER_LOAD | SEC_COFF_SHARED_LIBRARY)) != 0) - styp_flags |= STYP_NOLOAD; -#endif - - return (styp_flags); -} -/* - * Return a word with SEC_* flags set to represent the incoming - * STYP_* flags (from scnhdr.s_flags). The inverse of this - * function is sec_to_styp_flags(). - * NOTE: If you add to/change this routine, you should mirror the changes - * in sec_to_styp_flags(). - */ -static flagword -styp_to_sec_flags (abfd, hdr) - bfd * abfd; - PTR hdr; -{ - struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; - flagword sec_flags = 0; - -#ifdef STYP_NOLOAD - if (styp_flags & STYP_NOLOAD) - { - sec_flags |= SEC_NEVER_LOAD; - } -#endif /* STYP_NOLOAD */ - - /* For 386 COFF, at least, an unloadable text or data section is - actually a shared library section. */ - if (styp_flags & STYP_TEXT) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - } - else if (styp_flags & STYP_DATA) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - } - else if (styp_flags & STYP_BSS) - { -#ifdef BSS_NOLOAD_IS_SHARED_LIBRARY - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_ALLOC | SEC_COFF_SHARED_LIBRARY; - else -#endif - sec_flags |= SEC_ALLOC; - } - else if (styp_flags & STYP_INFO) - { - /* We mark these as SEC_DEBUGGING, but only if COFF_PAGE_SIZE is - defined. coff_compute_section_file_positions uses - COFF_PAGE_SIZE to ensure that the low order bits of the - section VMA and the file offset match. If we don't know - COFF_PAGE_SIZE, we can't ensure the correct correspondence, - and demand page loading of the file will fail. */ -#ifdef COFF_PAGE_SIZE - sec_flags |= SEC_DEBUGGING; -#endif - } - else - { - sec_flags |= SEC_ALLOC | SEC_LOAD; - } - -#ifdef STYP_LIT /* A29k readonly text/data section type */ - if ((styp_flags & STYP_LIT) == STYP_LIT) - { - sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY); - } -#endif /* STYP_LIT */ -#ifdef STYP_OTHER_LOAD /* Other loaded sections */ - if (styp_flags & STYP_OTHER_LOAD) - { - sec_flags = (SEC_LOAD | SEC_ALLOC); - } -#endif /* STYP_SDATA */ - - return (sec_flags); -} - -#define get_index(symbol) ((long) (symbol)->udata) - -/* -INTERNAL_DEFINITION - bfd_coff_backend_data - -CODE_FRAGMENT - -Special entry points for gdb to swap in coff symbol table parts: -.typedef struct -.{ -. void (*_bfd_coff_swap_aux_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. int type, -. int class, -. int indaux, -. int numaux, -. PTR in)); -. -. void (*_bfd_coff_swap_sym_in) PARAMS (( -. bfd *abfd , -. PTR ext, -. PTR in)); -. -. void (*_bfd_coff_swap_lineno_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. - -Special entry points for gas to swap out coff parts: - -. unsigned int (*_bfd_coff_swap_aux_out) PARAMS (( -. bfd *abfd, -. PTR in, -. int type, -. int class, -. int indaux, -. int numaux, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_sym_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_lineno_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR ext)); -. -. unsigned int (*_bfd_coff_swap_reloc_out) PARAMS (( -. bfd *abfd, -. PTR src, -. PTR dst)); -. -. unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. -. unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. -. unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS (( -. bfd *abfd, -. PTR in, -. PTR out)); -. - -Special entry points for generic COFF routines to call target -dependent COFF routines: - -. unsigned int _bfd_filhsz; -. unsigned int _bfd_aoutsz; -. unsigned int _bfd_scnhsz; -. unsigned int _bfd_symesz; -. unsigned int _bfd_auxesz; -. unsigned int _bfd_linesz; -. boolean _bfd_coff_long_filenames; -. void (*_bfd_coff_swap_filehdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. void (*_bfd_coff_swap_aouthdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. void (*_bfd_coff_swap_scnhdr_in) PARAMS (( -. bfd *abfd, -. PTR ext, -. PTR in)); -. boolean (*_bfd_coff_bad_format_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr)); -. boolean (*_bfd_coff_set_arch_mach_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr)); -. PTR (*_bfd_coff_mkobject_hook) PARAMS (( -. bfd *abfd, -. PTR internal_filehdr, -. PTR internal_aouthdr)); -. flagword (*_bfd_styp_to_sec_flags_hook) PARAMS (( -. bfd *abfd, -. PTR internal_scnhdr)); -. asection *(*_bfd_make_section_hook) PARAMS (( -. bfd *abfd, -. char *name)); -. void (*_bfd_set_alignment_hook) PARAMS (( -. bfd *abfd, -. asection *sec, -. PTR internal_scnhdr)); -. boolean (*_bfd_coff_slurp_symbol_table) PARAMS (( -. bfd *abfd)); -. boolean (*_bfd_coff_symname_in_debug) PARAMS (( -. bfd *abfd, -. struct internal_syment *sym)); -. void (*_bfd_coff_reloc16_extra_cases) PARAMS (( -. bfd *abfd, -. struct bfd_link_info *link_info, -. struct bfd_link_order *link_order, -. arelent *reloc, -. bfd_byte *data, -. unsigned int *src_ptr, -. unsigned int *dst_ptr)); -. int (*_bfd_coff_reloc16_estimate) PARAMS (( -. bfd *abfd, -. asection *input_section, -. arelent *r, -. unsigned int shrink, -. struct bfd_link_info *link_info)); -. -.} bfd_coff_backend_data; -. -.#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) -. -.#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ -. ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) -. -.#define bfd_coff_swap_sym_in(a,e,i) \ -. ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) -. -.#define bfd_coff_swap_lineno_in(a,e,i) \ -. ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) -. -.#define bfd_coff_swap_reloc_out(abfd, i, o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) -. -.#define bfd_coff_swap_lineno_out(abfd, i, o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) -. -.#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ -. ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) -. -.#define bfd_coff_swap_sym_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) -. -.#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) -. -.#define bfd_coff_swap_filehdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) -. -.#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) -. -.#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) -.#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) -.#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) -.#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) -.#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) -.#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) -.#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) -.#define bfd_coff_swap_filehdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) -. -.#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) -. -.#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ -. ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) -. -.#define bfd_coff_bad_format_hook(abfd, filehdr) \ -. ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) -. -.#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ -. ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) -.#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ -. ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr)) -. -.#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr)\ -. ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr)) -. -.#define bfd_coff_make_section_hook(abfd, name)\ -. ((coff_backend_info (abfd)->_bfd_make_section_hook) (abfd, name)) -. -.#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ -. ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) -. -.#define bfd_coff_slurp_symbol_table(abfd)\ -. ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) -. -.#define bfd_coff_symname_in_debug(abfd, sym)\ -. ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) -. -.#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)\ -. ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ -. (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) -. -.#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ -. ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ -. (abfd, section, reloc, shrink, link_info)) -. -*/ - -/* See whether the magic number matches. */ - -static boolean -coff_bad_format_hook (abfd, filehdr) - bfd * abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - if (BADMAG (*internal_f)) - return false; - - /* if the optional header is NULL or not the correct size then - quit; the only difference I can see between m88k dgux headers (MC88DMAGIC) - and Intel 960 readwrite headers (I960WRMAGIC) is that the - optional header is of a different size. - - But the mips keeps extra stuff in it's opthdr, so dont check - when doing that - */ - -#if defined(M88) || defined(I960) - if (internal_f->f_opthdr != 0 && AOUTSZ != internal_f->f_opthdr) - return false; -#endif - - return true; -} - -static asection * -coff_make_section_hook (abfd, name) - bfd * abfd; - char *name; -{ -#ifdef TWO_DATA_SECS - /* FIXME: This predates the call to bfd_make_section_anyway - in make_a_section_from_file, and can probably go away. */ - /* On SCO a file created by the Microsoft assembler can have two - .data sections. We use .data2 for the second one. */ - if (strcmp (name, _DATA) == 0) - return bfd_make_section (abfd, ".data2"); -#endif - return (asection *) NULL; -} - -/* - initialize a section structure with information peculiar to this - particular implementation of coff -*/ - -static boolean -coff_new_section_hook (abfd, section) - bfd * abfd; - asection * section; -{ - section->alignment_power = abfd->xvec->align_power_min; - /* Allocate aux records for section symbols, to store size and - related info. - - @@ Shouldn't use constant multiplier here! */ - coffsymbol (section->symbol)->native = - (combined_entry_type *) bfd_zalloc (abfd, - sizeof (combined_entry_type) * 10); - -#ifdef COFF_SPARC - /* This is to allow double-word operations on addresses in data or bss. */ - if (strcmp (section->name, ".data") == 0 - || strcmp (section->name, ".bss") == 0) - section->alignment_power = 3; -#endif /* COFF_SPARC */ - - return true; -} - - -#ifdef I960 - -/* Set the alignment of a BFD section. */ - -static void -coff_set_alignment_hook (abfd, section, scnhdr) - bfd * abfd; - asection * section; - PTR scnhdr; -{ - struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr; - unsigned int i; - - for (i = 0; i < 32; i++) - if ((1 << i) >= hdr->s_align) - break; - section->alignment_power = i; -} - -#else /* ! I960 */ - -#define coff_set_alignment_hook \ - ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void) - -#endif /* ! I960 */ - -static boolean -coff_mkobject (abfd) - bfd * abfd; -{ - coff_data_type *coff; - - abfd->tdata.coff_obj_data = (struct coff_tdata *) bfd_zalloc (abfd, sizeof (coff_data_type)); - if (abfd->tdata.coff_obj_data == 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - coff = coff_data (abfd); - coff->symbols = (coff_symbol_type *) NULL; - coff->conversion_table = (unsigned int *) NULL; - coff->raw_syments = (struct coff_ptr_struct *) NULL; - coff->raw_linenos = (struct lineno *) NULL; - coff->relocbase = 0; -/* make_abs_section(abfd);*/ - return true; -} - -/* Create the COFF backend specific information. */ - -static PTR -coff_mkobject_hook (abfd, filehdr, aouthdr) - bfd * abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - coff_data_type *coff; - - if (coff_mkobject (abfd) == false) - return NULL; - - coff = coff_data (abfd); - - coff->sym_filepos = internal_f->f_symptr; - coff->flags = internal_f->f_flags; - - /* These members communicate important constants about the symbol - table to GDB's symbol-reading code. These `constants' - unfortunately vary among coff implementations... */ - coff->local_n_btmask = N_BTMASK; - coff->local_n_btshft = N_BTSHFT; - coff->local_n_tmask = N_TMASK; - coff->local_n_tshift = N_TSHIFT; - coff->local_symesz = SYMESZ; - coff->local_auxesz = AUXESZ; - coff->local_linesz = LINESZ; - - return (PTR) coff; -} - -/* Determine the machine architecture and type. FIXME: This is target - dependent because the magic numbers are defined in the target - dependent header files. But there is no particular need for this. - If the magic numbers were moved to a separate file, this function - would be target independent and would also be much more successful - at linking together COFF files for different architectures. */ - -static boolean -coff_set_arch_mach_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - long machine; - enum bfd_architecture arch; - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - - machine = 0; - switch (internal_f->f_magic) - { -#ifdef I386MAGIC - case I386MAGIC: - case I386PTXMAGIC: - case I386AIXMAGIC: /* Danbury PS/2 AIX C Compiler */ - case LYNXCOFFMAGIC: /* shadows the m68k Lynx number below, sigh */ - arch = bfd_arch_i386; - machine = 0; - break; -#endif - -#ifdef A29K_MAGIC_BIG - case A29K_MAGIC_BIG: - case A29K_MAGIC_LITTLE: - arch = bfd_arch_a29k; - machine = 0; - break; -#endif - -#ifdef MC68MAGIC - case MC68MAGIC: - case M68MAGIC: -#ifdef MC68KBCSMAGIC - case MC68KBCSMAGIC: -#endif -#ifdef APOLLOM68KMAGIC - case APOLLOM68KMAGIC: -#endif -#ifdef LYNXCOFFMAGIC - case LYNXCOFFMAGIC: -#endif - arch = bfd_arch_m68k; - machine = 68020; - break; -#endif -#ifdef MC88MAGIC - case MC88MAGIC: - case MC88DMAGIC: - case MC88OMAGIC: - arch = bfd_arch_m88k; - machine = 88100; - break; -#endif -#ifdef Z8KMAGIC - case Z8KMAGIC: - arch = bfd_arch_z8k; - switch (internal_f->f_flags & F_MACHMASK) - { - case F_Z8001: - machine = bfd_mach_z8001; - break; - case F_Z8002: - machine = bfd_mach_z8002; - break; - default: - return false; - } - break; -#endif -#ifdef I960 -#ifdef I960ROMAGIC - case I960ROMAGIC: - case I960RWMAGIC: - arch = bfd_arch_i960; - switch (F_I960TYPE & internal_f->f_flags) - { - default: - case F_I960CORE: - machine = bfd_mach_i960_core; - break; - case F_I960KB: - machine = bfd_mach_i960_kb_sb; - break; - case F_I960MC: - machine = bfd_mach_i960_mc; - break; - case F_I960XA: - machine = bfd_mach_i960_xa; - break; - case F_I960CA: - machine = bfd_mach_i960_ca; - break; - case F_I960KA: - machine = bfd_mach_i960_ka_sa; - break; - } - break; -#endif -#endif - -#ifdef U802ROMAGIC - case U802ROMAGIC: - case U802WRMAGIC: - case U802TOCMAGIC: - arch = bfd_arch_rs6000; - machine = 6000; - break; -#endif - -#ifdef WE32KMAGIC - case WE32KMAGIC: - arch = bfd_arch_we32k; - machine = 0; - break; -#endif - -#ifdef H8300MAGIC - case H8300MAGIC: - arch = bfd_arch_h8300; - machine = bfd_mach_h8300; - /* !! FIXME this probably isn't the right place for this */ - abfd->flags |= BFD_IS_RELAXABLE; - break; -#endif - -#ifdef H8300HMAGIC - case H8300HMAGIC: - arch = bfd_arch_h8300; - machine = bfd_mach_h8300h; - /* !! FIXME this probably isn't the right place for this */ - abfd->flags |= BFD_IS_RELAXABLE; - break; -#endif - -#ifdef SH_ARCH_MAGIC - case SH_ARCH_MAGIC: - arch = bfd_arch_sh; - machine = 0; - break; -#endif - -#ifdef H8500MAGIC - case H8500MAGIC: - arch = bfd_arch_h8500; - machine = 0; - break; -#endif - -#ifdef SPARCMAGIC - case SPARCMAGIC: -#ifdef LYNXCOFFMAGIC - case LYNXCOFFMAGIC: -#endif - arch = bfd_arch_sparc; - machine = 0; - break; -#endif - - default: /* Unreadable input file type */ - arch = bfd_arch_obscure; - break; - } - - bfd_default_set_arch_mach (abfd, arch, machine); - return true; -} - -#ifdef SYMNAME_IN_DEBUG - -static boolean -symname_in_debug_hook (abfd, sym) - bfd * abfd; - struct internal_syment *sym; -{ - return SYMNAME_IN_DEBUG (sym) ? true : false; -} - -#else - -#define symname_in_debug_hook \ - (boolean (*) PARAMS ((bfd *, struct internal_syment *))) bfd_false - -#endif - -/* -SUBSUBSECTION - Writing relocations - - To write relocations, the back end steps though the - canonical relocation table and create an - @code{internal_reloc}. The symbol index to use is removed from - the @code{offset} field in the symbol table supplied. The - address comes directly from the sum of the section base - address and the relocation offset; the type is dug directly - from the howto field. Then the @code{internal_reloc} is - swapped into the shape of an @code{external_reloc} and written - out to disk. - -*/ - -static boolean -coff_write_relocs (abfd) - bfd * abfd; -{ - asection *s; - for (s = abfd->sections; s != (asection *) NULL; s = s->next) - { - unsigned int i; - struct external_reloc dst; - - arelent **p = s->orelocation; - if (bfd_seek (abfd, s->rel_filepos, SEEK_SET) != 0) - return false; - for (i = 0; i < s->reloc_count; i++) - { - struct internal_reloc n; - arelent *q = p[i]; - memset ((PTR) & n, 0, sizeof (n)); - - n.r_vaddr = q->address + s->vma; - -#ifdef R_IHCONST - /* The 29k const/consth reloc pair is a real kludge. The consth - part doesn't have a symbol; it has an offset. So rebuilt - that here. */ - if (q->howto->type == R_IHCONST) - n.r_symndx = q->addend; - else -#endif - if (q->sym_ptr_ptr) - { - if (q->sym_ptr_ptr == bfd_abs_section_ptr->symbol_ptr_ptr) - /* This is a relocation relative to the absolute symbol. */ - n.r_symndx = -1; - else - { - n.r_symndx = get_index ((*(q->sym_ptr_ptr))); - /* Take notice if the symbol reloc points to a symbol - we don't have in our symbol table. What should we - do for this?? */ - if (n.r_symndx > obj_conv_table_size (abfd)) - abort (); - } - } - -#ifdef SWAP_OUT_RELOC_OFFSET - n.r_offset = q->addend; -#endif - -#ifdef SELECT_RELOC - /* Work out reloc type from what is required */ - SELECT_RELOC (n, q->howto); -#else - n.r_type = q->howto->type; -#endif - coff_swap_reloc_out (abfd, &n, &dst); - if (bfd_write ((PTR) & dst, 1, RELSZ, abfd) != RELSZ) - return false; - } - } - - return true; -} - -/* Set flags and magic number of a coff file from architecture and machine - type. Result is true if we can represent the arch&type, false if not. */ - -static boolean -coff_set_flags (abfd, magicp, flagsp) - bfd * abfd; - unsigned *magicp; - unsigned short *flagsp; -{ - switch (bfd_get_arch (abfd)) - { -#ifdef Z8KMAGIC - case bfd_arch_z8k: - *magicp = Z8KMAGIC; - switch (bfd_get_mach (abfd)) - { - case bfd_mach_z8001: - *flagsp = F_Z8001; - break; - case bfd_mach_z8002: - *flagsp = F_Z8002; - break; - default: - return false; - } - return true; -#endif -#ifdef I960ROMAGIC - - case bfd_arch_i960: - - { - unsigned flags; - *magicp = I960ROMAGIC; - /* - ((bfd_get_file_flags(abfd) & WP_TEXT) ? I960ROMAGIC : - I960RWMAGIC); FIXME??? - */ - switch (bfd_get_mach (abfd)) - { - case bfd_mach_i960_core: - flags = F_I960CORE; - break; - case bfd_mach_i960_kb_sb: - flags = F_I960KB; - break; - case bfd_mach_i960_mc: - flags = F_I960MC; - break; - case bfd_mach_i960_xa: - flags = F_I960XA; - break; - case bfd_mach_i960_ca: - flags = F_I960CA; - break; - case bfd_mach_i960_ka_sa: - flags = F_I960KA; - break; - default: - return false; - } - *flagsp = flags; - return true; - } - break; -#endif -#ifdef I386MAGIC - case bfd_arch_i386: - *magicp = I386MAGIC; -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif -#ifdef MC68MAGIC - case bfd_arch_m68k: -#ifdef APOLLOM68KMAGIC - *magicp = APOLLO_COFF_VERSION_NUMBER; -#else - *magicp = MC68MAGIC; -#endif -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif - -#ifdef MC88MAGIC - case bfd_arch_m88k: - *magicp = MC88OMAGIC; - return true; - break; -#endif -#ifdef H8300MAGIC - case bfd_arch_h8300: - switch (bfd_get_mach (abfd)) - { - case bfd_mach_h8300: - *magicp = H8300MAGIC; - return true; - case bfd_mach_h8300h: - *magicp = H8300HMAGIC; - return true; - } - break; -#endif - -#ifdef SH_ARCH_MAGIC - case bfd_arch_sh: - *magicp = SH_ARCH_MAGIC; - return true; - break; -#endif - -#ifdef SPARCMAGIC - case bfd_arch_sparc: - *magicp = SPARCMAGIC; -#ifdef LYNXOS - /* Just overwrite the usual value if we're doing Lynx. */ - *magicp = LYNXCOFFMAGIC; -#endif - return true; - break; -#endif - -#ifdef H8500MAGIC - case bfd_arch_h8500: - *magicp = H8500MAGIC; - return true; - break; -#endif -#ifdef A29K_MAGIC_BIG - case bfd_arch_a29k: - if (abfd->xvec->byteorder_big_p) - *magicp = A29K_MAGIC_BIG; - else - *magicp = A29K_MAGIC_LITTLE; - return true; - break; -#endif - -#ifdef WE32KMAGIC - case bfd_arch_we32k: - *magicp = WE32KMAGIC; - return true; - break; -#endif - -#ifdef U802TOCMAGIC - case bfd_arch_rs6000: - case bfd_arch_powerpc: - *magicp = U802TOCMAGIC; - return true; - break; -#endif - - default: /* Unknown architecture */ - /* return false; -- fall through to "return false" below, to avoid - "statement never reached" errors on the one below. */ - break; - } - - return false; -} - - -static boolean -coff_set_arch_mach (abfd, arch, machine) - bfd * abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - unsigned dummy1; - unsigned short dummy2; - - if (! bfd_default_set_arch_mach (abfd, arch, machine)) - return false; - - if (arch != bfd_arch_unknown && - coff_set_flags (abfd, &dummy1, &dummy2) != true) - return false; /* We can't represent this type */ - - return true; /* We're easy ... */ -} - - -/* Calculate the file position for each section. */ - -static void -coff_compute_section_file_positions (abfd) - bfd * abfd; -{ - asection *current; - asection *previous = (asection *) NULL; - file_ptr sofar = FILHSZ; -#ifndef I960 - file_ptr old_sofar; -#endif - if (bfd_get_start_address (abfd)) - { - /* A start address may have been added to the original file. In this - case it will need an optional header to record it. */ - abfd->flags |= EXEC_P; - } - - if (abfd->flags & EXEC_P) - sofar += AOUTSZ; - - sofar += abfd->section_count * SCNHSZ; - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - - /* Only deal with sections which have contents */ - if (!(current->flags & SEC_HAS_CONTENTS)) - continue; - - /* Align the sections in the file to the same boundary on - which they are aligned in virtual memory. I960 doesn't - do this (FIXME) so we can stay in sync with Intel. 960 - doesn't yet page from files... */ -#ifndef I960 - { - /* make sure this section is aligned on the right boundary - by - padding the previous section up if necessary */ - - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - if (previous != (asection *) NULL) - { - previous->_raw_size += sofar - old_sofar; - } - } - -#endif - -#ifdef COFF_PAGE_SIZE - /* In demand paged files the low order bits of the file offset - must match the low order bits of the virtual address. */ - if ((abfd->flags & D_PAGED) != 0) - sofar += (current->vma - sofar) % COFF_PAGE_SIZE; -#endif - - current->filepos = sofar; - - sofar += current->_raw_size; -#ifndef I960 - /* make sure that this section is of the right size too */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << current->alignment_power); - current->_raw_size += sofar - old_sofar; -#endif - -#ifdef _LIB - /* Force .lib sections to start at zero. The vma is then - incremented in coff_set_section_contents. This is right for - SVR3.2. */ - if (strcmp (current->name, _LIB) == 0) - bfd_set_section_vma (abfd, current, 0); -#endif - - previous = current; - } - obj_relocbase (abfd) = sofar; -} - -#ifndef RS6000COFF_C - -/* If .file, .text, .data, .bss symbols are missing, add them. */ -/* @@ Should we only be adding missing symbols, or overriding the aux - values for existing section symbols? */ -static boolean -coff_add_missing_symbols (abfd) - bfd *abfd; -{ - unsigned int nsyms = bfd_get_symcount (abfd); - asymbol **sympp = abfd->outsymbols; - asymbol **sympp2; - unsigned int i; - int need_text = 1, need_data = 1, need_bss = 1, need_file = 1; - - for (i = 0; i < nsyms; i++) - { - coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]); - CONST char *name; - if (csym) - { - /* only do this if there is a coff representation of the input - symbol */ - if (csym->native && csym->native->u.syment.n_sclass == C_FILE) - { - need_file = 0; - continue; - } - name = csym->symbol.name; - if (!name) - continue; - if (!strcmp (name, _TEXT)) - need_text = 0; -#ifdef APOLLO_M68 - else if (!strcmp (name, ".wtext")) - need_text = 0; -#endif - else if (!strcmp (name, _DATA)) - need_data = 0; - else if (!strcmp (name, _BSS)) - need_bss = 0; - } - } - /* Now i == bfd_get_symcount (abfd). */ - /* @@ For now, don't deal with .file symbol. */ - need_file = 0; - - if (!need_text && !need_data && !need_bss && !need_file) - return true; - nsyms += need_text + need_data + need_bss + need_file; - sympp2 = (asymbol **) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *)); - if (!sympp2) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memcpy (sympp2, sympp, i * sizeof (asymbol *)); - if (need_file) - { - /* @@ Generate fake .file symbol, in sympp2[i], and increment i. */ - abort (); - } - if (need_text) - sympp2[i++] = coff_section_symbol (abfd, _TEXT); - if (need_data) - sympp2[i++] = coff_section_symbol (abfd, _DATA); - if (need_bss) - sympp2[i++] = coff_section_symbol (abfd, _BSS); - BFD_ASSERT (i == nsyms); - bfd_set_symtab (abfd, sympp2, nsyms); - return true; -} - -#endif /* ! defined (RS6000COFF_C) */ - -/* SUPPRESS 558 */ -/* SUPPRESS 529 */ -static boolean -coff_write_object_contents (abfd) - bfd * abfd; -{ - asection *current; - unsigned int count; - - boolean hasrelocs = false; - boolean haslinno = false; - file_ptr reloc_base; - file_ptr lineno_base; - file_ptr sym_base; - file_ptr scn_base; - file_ptr data_base; - unsigned long reloc_size = 0; - unsigned long lnno_size = 0; - asection *text_sec = NULL; - asection *data_sec = NULL; - asection *bss_sec = NULL; - - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - - bfd_set_error (bfd_error_system_call); - /* Number the output sections, starting from one on the first section - with a name which doesn't start with a *. - @@ The code doesn't make this check. Is it supposed to be done, - or isn't it?? */ - count = 1; - for (current = abfd->sections; current != (asection *) NULL; - current = current->next) - { - current->target_index = count; - count++; - } - - if (abfd->output_has_begun == false) - { - coff_compute_section_file_positions (abfd); - } - - if (abfd->sections != (asection *) NULL) - { - scn_base = abfd->sections->filepos; - } - else - { - scn_base = 0; - } - if (bfd_seek (abfd, scn_base, SEEK_SET) != 0) - return false; - reloc_base = obj_relocbase (abfd); - - /* Make a pass through the symbol table to count line number entries and - put them into the correct asections */ - - lnno_size = coff_count_linenumbers (abfd) * LINESZ; - data_base = scn_base; - - /* Work out the size of the reloc and linno areas */ - - for (current = abfd->sections; current != NULL; current = - current->next) - { - /* We give section headers to +ve indexes */ - if (current->target_index > 0) - { - - reloc_size += current->reloc_count * RELSZ; - data_base += SCNHSZ; - } - - } - - lineno_base = reloc_base + reloc_size; - sym_base = lineno_base + lnno_size; - - /* Indicate in each section->line_filepos its actual file address */ - for (current = abfd->sections; current != NULL; current = - current->next) - { - if (current->target_index > 0) - { - - if (current->lineno_count) - { - current->line_filepos = lineno_base; - current->moving_line_filepos = lineno_base; - lineno_base += current->lineno_count * LINESZ; - } - else - { - current->line_filepos = 0; - } - if (current->reloc_count) - { - current->rel_filepos = reloc_base; - reloc_base += current->reloc_count * RELSZ; - } - else - { - current->rel_filepos = 0; - } - } - } - - - - /* Write section headers to the file. */ - internal_f.f_nscns = 0; - if (bfd_seek (abfd, - (file_ptr) ((abfd->flags & EXEC_P) ? - (FILHSZ + AOUTSZ) : FILHSZ), - SEEK_SET) - != 0) - return false; - - { -#if 0 - unsigned int pad = abfd->flags & D_PAGED ? data_base : 0; -#endif - unsigned int pad = 0; - - for (current = abfd->sections; - current != NULL; - current = current->next) - { - struct internal_scnhdr section; - if (current->target_index > 0) - { - internal_f.f_nscns++; - strncpy (&(section.s_name[0]), current->name, 8); -#ifdef _LIB - /* Always set s_vaddr of .lib to 0. This is right for SVR3.2 - Ian Taylor <ian@cygnus.com>. */ - if (strcmp (current->name, _LIB) == 0) - section.s_vaddr = 0; - else -#endif - section.s_vaddr = current->lma + pad; - section.s_paddr = current->lma + pad; - section.s_size = current->_raw_size - pad; - /* - If this section has no size or is unloadable then the scnptr - will be 0 too - */ - if (current->_raw_size - pad == 0 || - (current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - { - section.s_scnptr = 0; - } - else - { - section.s_scnptr = current->filepos; - } - section.s_relptr = current->rel_filepos; - section.s_lnnoptr = current->line_filepos; - section.s_nreloc = current->reloc_count; - section.s_nlnno = current->lineno_count; - if (current->reloc_count != 0) - hasrelocs = true; - if (current->lineno_count != 0) - haslinno = true; - - section.s_flags = sec_to_styp_flags (current->name, current->flags); - - if (!strcmp (current->name, _TEXT)) - { - text_sec = current; - } - else if (!strcmp (current->name, _DATA)) - { - data_sec = current; -#ifdef TWO_DATA_SECS - } - else if (!strcmp (current->name, ".data2")) - { - data_sec = current; -#endif /* TWO_DATA_SECS */ - } - else if (!strcmp (current->name, _BSS)) - { - bss_sec = current; - } - -#ifdef I960 - section.s_align = (current->alignment_power - ? 1 << current->alignment_power - : 0); - -#endif - { - SCNHDR buff; - - coff_swap_scnhdr_out (abfd, §ion, &buff); - if (bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ) - return false; - - } - - pad = 0; - } - } - } - - - /* OK, now set up the filehdr... */ - - /* Don't include the internal abs section in the section count */ - - /* - We will NOT put a fucking timestamp in the header here. Every time you - put it back, I will come in and take it out again. I'm sorry. This - field does not belong here. We fill it with a 0 so it compares the - same but is not a reasonable time. -- gnu@cygnus.com - */ - internal_f.f_timdat = 0; - - if (bfd_get_symcount (abfd) != 0) - internal_f.f_symptr = sym_base; - else - internal_f.f_symptr = 0; - - internal_f.f_flags = 0; - - if (abfd->flags & EXEC_P) - internal_f.f_opthdr = AOUTSZ; - else - internal_f.f_opthdr = 0; - - if (!hasrelocs) - internal_f.f_flags |= F_RELFLG; - if (!haslinno) - internal_f.f_flags |= F_LNNO; - if (0 == bfd_get_symcount (abfd)) - internal_f.f_flags |= F_LSYMS; - if (abfd->flags & EXEC_P) - internal_f.f_flags |= F_EXEC; - - if (!abfd->xvec->byteorder_big_p) - internal_f.f_flags |= F_AR32WR; - else - internal_f.f_flags |= F_AR32W; - - /* - FIXME, should do something about the other byte orders and - architectures. - */ - - memset (&internal_a, 0, sizeof internal_a); - - /* Set up architecture-dependent stuff */ - - { - unsigned int magic = 0; - unsigned short flags = 0; - coff_set_flags (abfd, &magic, &flags); - internal_f.f_magic = magic; - internal_f.f_flags |= flags; - /* ...and the "opt"hdr... */ - -#ifdef A29K -#ifdef ULTRA3 /* NYU's machine */ - /* FIXME: This is a bogus check. I really want to see if there - * is a .shbss or a .shdata section, if so then set the magic - * number to indicate a shared data executable. - */ - if (internal_f.f_nscns >= 7) - internal_a.magic = SHMAGIC; /* Shared magic */ - else -#endif /* ULTRA3 */ - internal_a.magic = NMAGIC;/* Assume separate i/d */ -#define __A_MAGIC_SET__ -#endif /* A29K */ -#ifdef I960 - internal_a.magic = (magic == I960ROMAGIC ? NMAGIC : OMAGIC); -#define __A_MAGIC_SET__ -#endif /* I960 */ -#if M88 -#define __A_MAGIC_SET__ - internal_a.magic = PAGEMAGICBCS; -#endif /* M88 */ - -#if APOLLO_M68 -#define __A_MAGIC_SET__ - internal_a.magic = APOLLO_COFF_VERSION_NUMBER; -#endif - -#if M68 || WE32K -#define __A_MAGIC_SET__ - /* Never was anything here for the 68k */ -#endif /* M68 || WE32K */ - -#if I386 -#define __A_MAGIC_SET__ - internal_a.magic = ZMAGIC; -#endif /* I386 */ - -#if RS6000COFF_C -#define __A_MAGIC_SET__ - internal_a.magic = (abfd->flags & D_PAGED) ? RS6K_AOUTHDR_ZMAGIC : - (abfd->flags & WP_TEXT) ? RS6K_AOUTHDR_NMAGIC : - RS6K_AOUTHDR_OMAGIC; -#endif - -#ifndef __A_MAGIC_SET__ -#include "Your aouthdr magic number is not being set!" -#else -#undef __A_MAGIC_SET__ -#endif - } - /* Now should write relocs, strings, syms */ - obj_sym_filepos (abfd) = sym_base; - - if (bfd_get_symcount (abfd) != 0) - { -#ifndef RS6000COFF_C - if (!coff_add_missing_symbols (abfd)) - return false; -#endif - if (!coff_renumber_symbols (abfd)) - return false; - coff_mangle_symbols (abfd); - if (! coff_write_symbols (abfd)) - return false; - if (! coff_write_linenumbers (abfd)) - return false; - if (! coff_write_relocs (abfd)) - return false; - } - if (text_sec) - { - internal_a.tsize = bfd_get_section_size_before_reloc (text_sec); - internal_a.text_start = internal_a.tsize ? text_sec->vma : 0; - } - if (data_sec) - { - internal_a.dsize = bfd_get_section_size_before_reloc (data_sec); - internal_a.data_start = internal_a.dsize ? data_sec->vma : 0; - } - if (bss_sec) - { - internal_a.bsize = bfd_get_section_size_before_reloc (bss_sec); - } - - internal_a.entry = bfd_get_start_address (abfd); - internal_f.f_nsyms = bfd_get_symcount (abfd); - - /* now write them */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - return false; - { - FILHDR buff; - coff_swap_filehdr_out (abfd, (PTR) & internal_f, (PTR) & buff); - if (bfd_write ((PTR) & buff, 1, FILHSZ, abfd) != FILHSZ) - return false; - } - if (abfd->flags & EXEC_P) - { - AOUTHDR buff; - coff_swap_aouthdr_out (abfd, (PTR) & internal_a, (PTR) & buff); - if (bfd_write ((PTR) & buff, 1, AOUTSZ, abfd) != AOUTSZ) - return false; - } - return true; -} - -static boolean -coff_set_section_contents (abfd, section, location, offset, count) - bfd * abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (abfd->output_has_begun == false) /* set by bfd.c handler */ - coff_compute_section_file_positions (abfd); - -#ifdef _LIB - /* If this is a .lib section, bump the vma address so that it - winds up being the number of .lib sections output. This is - right for SVR3.2. Shared libraries should probably get more - generic support. Ian Taylor <ian@cygnus.com>. */ - if (strcmp (section->name, _LIB) == 0) - ++section->lma; -#endif - - /* Don't write out bss sections - one way to do this is to - see if the filepos has not been set. */ - if (section->filepos == 0) - return true; - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0) - return false; - - if (count != 0) - { - return (bfd_write (location, 1, count, abfd) == count) ? true : false; - } - return true; -} -#if 0 -static boolean -coff_close_and_cleanup (abfd) - bfd *abfd; -{ - if (!bfd_read_p (abfd)) - switch (abfd->format) - { - case bfd_archive: - if (!_bfd_write_archive_contents (abfd)) - return false; - break; - case bfd_object: - if (!coff_write_object_contents (abfd)) - return false; - break; - default: - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* We depend on bfd_close to free all the memory on the obstack. */ - /* FIXME if bfd_release is not using obstacks! */ - return true; -} - -#endif - -static PTR -buy_and_read (abfd, where, seek_direction, size) - bfd *abfd; - file_ptr where; - int seek_direction; - size_t size; -{ - PTR area = (PTR) bfd_alloc (abfd, size); - if (!area) - { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } - if (bfd_seek (abfd, where, seek_direction) != 0 - || bfd_read (area, 1, size, abfd) != size) - return (NULL); - return (area); -} /* buy_and_read() */ - -/* -SUBSUBSECTION - Reading linenumbers - - Creating the linenumber table is done by reading in the entire - coff linenumber table, and creating another table for internal use. - - A coff linenumber table is structured so that each function - is marked as having a line number of 0. Each line within the - function is an offset from the first line in the function. The - base of the line number information for the table is stored in - the symbol associated with the function. - - The information is copied from the external to the internal - table, and each symbol which marks a function is marked by - pointing its... - - How does this work ? - -*/ - -static boolean -coff_slurp_line_table (abfd, asect) - bfd *abfd; - asection *asect; -{ - LINENO *native_lineno; - alent *lineno_cache; - - BFD_ASSERT (asect->lineno == (alent *) NULL); - - native_lineno = (LINENO *) buy_and_read (abfd, - asect->line_filepos, - SEEK_SET, - (size_t) (LINESZ * - asect->lineno_count)); - lineno_cache = - (alent *) bfd_alloc (abfd, (size_t) ((asect->lineno_count + 1) * sizeof (alent))); - if (lineno_cache == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - else - { - unsigned int counter = 0; - alent *cache_ptr = lineno_cache; - LINENO *src = native_lineno; - - while (counter < asect->lineno_count) - { - struct internal_lineno dst; - coff_swap_lineno_in (abfd, src, &dst); - cache_ptr->line_number = dst.l_lnno; - - if (cache_ptr->line_number == 0) - { - coff_symbol_type *sym = - (coff_symbol_type *) (dst.l_addr.l_symndx - + obj_raw_syments (abfd))->u.syment._n._n_n._n_zeroes; - cache_ptr->u.sym = (asymbol *) sym; - sym->lineno = cache_ptr; - } - else - { - cache_ptr->u.offset = dst.l_addr.l_paddr - - bfd_section_vma (abfd, asect); - } /* If no linenumber expect a symbol index */ - - cache_ptr++; - src++; - counter++; - } - cache_ptr->line_number = 0; - - } - asect->lineno = lineno_cache; - /* FIXME, free native_lineno here, or use alloca or something. */ - return true; -} - -static boolean -coff_slurp_symbol_table (abfd) - bfd * abfd; -{ - combined_entry_type *native_symbols; - coff_symbol_type *cached_area; - unsigned int *table_ptr; - - unsigned int number_of_symbols = 0; - if (obj_symbols (abfd)) - return true; - if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0) - return false; - - /* Read in the symbol table */ - if ((native_symbols = coff_get_normalized_symtab (abfd)) == NULL) - { - return (false); - } /* on error */ - - /* Allocate enough room for all the symbols in cached form */ - cached_area = - (coff_symbol_type *) - bfd_alloc (abfd, (size_t) (bfd_get_symcount (abfd) * sizeof (coff_symbol_type))); - - if (cached_area == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } /* on error */ - table_ptr = - (unsigned int *) - bfd_alloc (abfd, (size_t) (bfd_get_symcount (abfd) * sizeof (unsigned int))); - - if (table_ptr == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - else - { - coff_symbol_type *dst = cached_area; - unsigned int last_native_index = bfd_get_symcount (abfd); - unsigned int this_index = 0; - while (this_index < last_native_index) - { - combined_entry_type *src = native_symbols + this_index; - table_ptr[this_index] = number_of_symbols; - dst->symbol.the_bfd = abfd; - - dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset); - /* We use the native name field to point to the cached field. */ - src->u.syment._n._n_n._n_zeroes = (long) dst; - dst->symbol.section = coff_section_from_bfd_index (abfd, - src->u.syment.n_scnum); - dst->symbol.flags = 0; - dst->done_lineno = false; - - switch (src->u.syment.n_sclass) - { -#ifdef I960 - case C_LEAFEXT: -#if 0 - dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma; - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.flags |= BSF_NOT_AT_END; -#endif - /* Fall through to next case */ - -#endif - - case C_EXT: -#ifdef RS6000COFF_C - case C_HIDEXT: -#endif - if ((src->u.syment.n_scnum) == 0) - { - if ((src->u.syment.n_value) == 0) - { - dst->symbol.section = bfd_und_section_ptr; - dst->symbol.value = 0; - } - else - { - dst->symbol.section = bfd_com_section_ptr; - dst->symbol.value = (src->u.syment.n_value); - } - } - else - { - /* - Base the value as an index from the base of the - section - */ - - dst->symbol.flags = BSF_EXPORT | BSF_GLOBAL; - dst->symbol.value = src->u.syment.n_value - dst->symbol.section->vma; - - if (ISFCN ((src->u.syment.n_type))) - { - /* - A function ext does not go at the end of a file - */ - dst->symbol.flags |= BSF_NOT_AT_END; - } - } - -#ifdef RS6000COFF_C - /* If this symbol has a csect aux of type LD, the scnlen field - is actually the index of the containing csect symbol. We - need to pointerize it. */ - if (src->u.syment.n_numaux > 0) - { - combined_entry_type *aux; - - aux = src + src->u.syment.n_numaux - 1; - if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD) - { - aux->u.auxent.x_csect.x_scnlen.p = - native_symbols + aux->u.auxent.x_csect.x_scnlen.l; - aux->fix_scnlen = 1; - } - } -#endif - - break; - - case C_STAT: /* static */ -#ifdef I960 - case C_LEAFSTAT: /* static leaf procedure */ -#endif - case C_LABEL: /* label */ - if (src->u.syment.n_scnum == -2) - dst->symbol.flags = BSF_DEBUGGING; - else - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section, if - there is one - */ - if (dst->symbol.section) - dst->symbol.value = (src->u.syment.n_value) - - dst->symbol.section->vma; - else - dst->symbol.value = (src->u.syment.n_value); - break; - - case C_MOS: /* member of structure */ - case C_EOS: /* end of structure */ -#ifdef NOTDEF /* C_AUTOARG has the same value */ -#ifdef C_GLBLREG - case C_GLBLREG: /* A29k-specific storage class */ -#endif -#endif - case C_REGPARM: /* register parameter */ - case C_REG: /* register variable */ -#ifdef C_AUTOARG - case C_AUTOARG: /* 960-specific storage class */ -#endif - case C_TPDEF: /* type definition */ - case C_ARG: - case C_AUTO: /* automatic variable */ - case C_FIELD: /* bit field */ - case C_ENTAG: /* enumeration tag */ - case C_MOE: /* member of enumeration */ - case C_MOU: /* member of union */ - case C_UNTAG: /* union tag */ - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - - case C_FILE: /* file name */ - case C_STRTAG: /* structure tag */ -#ifdef RS6000COFF_C - case C_BINCL: /* beginning of include file */ - case C_EINCL: /* ending of include file */ - case C_GSYM: - case C_LSYM: - case C_PSYM: - case C_RSYM: - case C_RPSYM: - case C_STSYM: - case C_DECL: - case C_ENTRY: - case C_FUN: - case C_ESTAT: -#endif - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - -#ifdef RS6000COFF_C - case C_BSTAT: - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = src->u.syment.n_value; - - /* The value is actually a symbol index. Save a pointer to - the symbol instead of the index. FIXME: This should use a - union. */ - src->u.syment.n_value = - (long) (native_symbols + src->u.syment.n_value); - src->fix_value = 1; - break; -#endif - - case C_BLOCK: /* ".bb" or ".eb" */ - case C_FCN: /* ".bf" or ".ef" */ - case C_EFCN: /* physical end of function */ - dst->symbol.flags = BSF_LOCAL; - /* - Base the value as an index from the base of the section - */ - dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma; - break; - - case C_NULL: - case C_EXTDEF: /* external definition */ - case C_ULABEL: /* undefined label */ - case C_USTATIC: /* undefined static */ - case C_LINE: /* line # reformatted as symbol table entry */ - case C_ALIAS: /* duplicate tag */ - case C_HIDDEN: /* ext symbol in dmert public lib */ - default: - - fprintf (stderr, "Unrecognized storage class %d (assuming debugging)\n for %s symbol `%s'\n", - src->u.syment.n_sclass, dst->symbol.section->name, - dst->symbol.name); -/* abort();*/ - dst->symbol.flags = BSF_DEBUGGING; - dst->symbol.value = (src->u.syment.n_value); - break; - } - -/* BFD_ASSERT(dst->symbol.flags != 0);*/ - - dst->native = src; - - dst->symbol.udata = 0; - dst->lineno = (alent *) NULL; - this_index += (src->u.syment.n_numaux) + 1; - dst++; - number_of_symbols++; - } /* walk the native symtab */ - } /* bfdize the native symtab */ - - obj_symbols (abfd) = cached_area; - obj_raw_syments (abfd) = native_symbols; - - obj_conv_table_size (abfd) = bfd_get_symcount (abfd); - bfd_get_symcount (abfd) = number_of_symbols; - obj_convert (abfd) = table_ptr; - /* Slurp the line tables for each section too */ - { - asection *p; - p = abfd->sections; - while (p) - { - coff_slurp_line_table (abfd, p); - p = p->next; - } - } - return true; -} /* coff_slurp_symbol_table() */ - -/* -SUBSUBSECTION - Reading relocations - - Coff relocations are easily transformed into the internal BFD form - (@code{arelent}). - - Reading a coff relocation table is done in the following stages: - - o Read the entire coff relocation table into memory. - - o Process each relocation in turn; first swap it from the - external to the internal form. - - o Turn the symbol referenced in the relocation's symbol index - into a pointer into the canonical symbol table. - This table is the same as the one returned by a call to - @code{bfd_canonicalize_symtab}. The back end will call that - routine and save the result if a canonicalization hasn't been done. - - o The reloc index is turned into a pointer to a howto - structure, in a back end specific way. For instance, the 386 - and 960 use the @code{r_type} to directly produce an index - into a howto table vector; the 88k subtracts a number from the - @code{r_type} field and creates an addend field. - - -*/ - -#ifndef CALC_ADDEND -#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ - { \ - coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \ - if (ptr && bfd_asymbol_bfd (ptr) != abfd) \ - coffsym = (obj_symbols (abfd) \ - + (cache_ptr->sym_ptr_ptr - symbols)); \ - else if (ptr) \ - coffsym = coff_symbol_from (abfd, ptr); \ - if (coffsym != (coff_symbol_type *) NULL \ - && coffsym->native->u.syment.n_scnum == 0) \ - cache_ptr->addend = 0; \ - else if (ptr && bfd_asymbol_bfd (ptr) == abfd \ - && ptr->section != (asection *) NULL) \ - cache_ptr->addend = - (ptr->section->vma + ptr->value); \ - else \ - cache_ptr->addend = 0; \ - } -#endif - -static boolean -coff_slurp_reloc_table (abfd, asect, symbols) - bfd * abfd; - sec_ptr asect; - asymbol ** symbols; -{ - RELOC *native_relocs; - arelent *reloc_cache; - arelent *cache_ptr; - - unsigned int idx; - - if (asect->relocation) - return true; - if (asect->reloc_count == 0) - return true; - if (asect->flags & SEC_CONSTRUCTOR) - return true; - if (!coff_slurp_symbol_table (abfd)) - return false; - native_relocs = - (RELOC *) buy_and_read (abfd, - asect->rel_filepos, - SEEK_SET, - (size_t) (RELSZ * - asect->reloc_count)); - reloc_cache = (arelent *) - bfd_alloc (abfd, (size_t) (asect->reloc_count * sizeof (arelent))); - - if (reloc_cache == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - - for (idx = 0; idx < asect->reloc_count; idx++) - { -#ifdef RELOC_PROCESSING - struct internal_reloc dst; - struct external_reloc *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - bfd_swap_reloc_in (abfd, src, &dst); - - RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); -#else - struct internal_reloc dst; - asymbol *ptr; - struct external_reloc *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - - bfd_swap_reloc_in (abfd, src, &dst); - - - cache_ptr->address = dst.r_vaddr; - - if (dst.r_symndx != -1) - { - /* @@ Should never be greater than count of symbols! */ - if (dst.r_symndx >= obj_conv_table_size (abfd)) - abort (); - cache_ptr->sym_ptr_ptr = symbols + obj_convert (abfd)[dst.r_symndx]; - ptr = *(cache_ptr->sym_ptr_ptr); - } - else - { - cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - ptr = 0; - } - - /* The symbols definitions that we have read in have been - relocated as if their sections started at 0. But the offsets - refering to the symbols in the raw data have not been - modified, so we have to have a negative addend to compensate. - - Note that symbols which used to be common must be left alone */ - - /* Calculate any reloc addend by looking at the symbol */ - CALC_ADDEND (abfd, ptr, dst, cache_ptr); - - cache_ptr->address -= asect->vma; -/* !! cache_ptr->section = (asection *) NULL;*/ - - /* Fill in the cache_ptr->howto field from dst.r_type */ - RTYPE2HOWTO (cache_ptr, &dst); -#endif - - } - - asect->relocation = reloc_cache; - return true; -} - - -/* This is stupid. This function should be a boolean predicate. */ -static long -coff_canonicalize_reloc (abfd, section, relptr, symbols) - bfd * abfd; - sec_ptr section; - arelent ** relptr; - asymbol ** symbols; -{ - arelent *tblptr = section->relocation; - unsigned int count = 0; - - - if (section->flags & SEC_CONSTRUCTOR) - { - /* this section has relocs made up by us, they are not in the - file, so take them out of their chain and place them into - the data area provided */ - arelent_chain *chain = section->constructor_chain; - for (count = 0; count < section->reloc_count; count++) - { - *relptr++ = &chain->relent; - chain = chain->next; - } - - } - else - { - if (! coff_slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - - for (; count++ < section->reloc_count;) - *relptr++ = tblptr++; - - - } - *relptr = 0; - return section->reloc_count; -} - -#ifdef GNU960 -file_ptr -coff_sym_filepos (abfd) - bfd *abfd; -{ - return obj_sym_filepos (abfd); -} -#endif - -#ifndef coff_reloc16_estimate -#define coff_reloc16_estimate dummy_reloc16_estimate - -static int -dummy_reloc16_estimate (abfd, input_section, reloc, shrink, link_info) - bfd *abfd; - asection *input_section; - arelent *reloc; - unsigned int shrink; - struct bfd_link_info *link_info; -{ - abort (); -} - -#endif - -#ifndef coff_reloc16_extra_cases -#define coff_reloc16_extra_cases dummy_reloc16_extra_cases -/* This works even if abort is not declared in any header file. */ -static void -dummy_reloc16_extra_cases (abfd, link_info, link_order, reloc, data, src_ptr, - dst_ptr) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - arelent *reloc; - bfd_byte *data; - unsigned int *src_ptr; - unsigned int *dst_ptr; -{ - fprintf (stderr, "%s\n", reloc->howto->name); - abort (); -} -#endif - -static CONST bfd_coff_backend_data bfd_coff_std_swap_table = -{ - coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, - coff_swap_aux_out, coff_swap_sym_out, - coff_swap_lineno_out, coff_swap_reloc_out, - coff_swap_filehdr_out, coff_swap_aouthdr_out, - coff_swap_scnhdr_out, - FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, LINESZ, -#ifdef COFF_LONG_FILENAMES - true, -#else - false, -#endif - coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in, - coff_bad_format_hook, coff_set_arch_mach_hook, coff_mkobject_hook, - styp_to_sec_flags, coff_make_section_hook, coff_set_alignment_hook, - coff_slurp_symbol_table, symname_in_debug_hook, - coff_reloc16_extra_cases, coff_reloc16_estimate -}; - -#define coff_close_and_cleanup _bfd_generic_close_and_cleanup -#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define coff_get_section_contents _bfd_generic_get_section_contents - -#define coff_bfd_copy_private_section_data \ - _bfd_generic_bfd_copy_private_section_data -#define coff_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data - -#ifndef coff_bfd_is_local_label -#define coff_bfd_is_local_label bfd_generic_is_local_label -#endif - -/* The reloc lookup routine must be supplied by each individual COFF - backend. */ -#ifndef coff_bfd_reloc_type_lookup -#define coff_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup -#endif - -#define coff_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define coff_bfd_relax_section bfd_generic_relax_section -#define coff_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define coff_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define coff_bfd_final_link _bfd_generic_final_link diff --git a/gnu/usr.bin/gdb/bfd/coffgen.c b/gnu/usr.bin/gdb/bfd/coffgen.c deleted file mode 100644 index e81f45b..0000000 --- a/gnu/usr.bin/gdb/bfd/coffgen.c +++ /dev/null @@ -1,1693 +0,0 @@ -/* Support for the generic parts of COFF, for BFD. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Most of this hacked by Steve Chamberlain, sac@cygnus.com. - Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ - -/* This file contains COFF code that is not dependent on any - particular COFF target. There is only one version of this file in - libbfd.a, so no target specific code may be put in here. Or, to - put it another way, - - ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE ********** - - If you need to add some target specific behaviour, add a new hook - function to bfd_coff_backend_data. - - Some of these functions are also called by the ECOFF routines. - Those functions may not use any COFF specific information, such as - coff_data (abfd). */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "coff/internal.h" -#include "libcoff.h" - -static boolean coff_write_symbol PARAMS ((bfd *, asymbol *, - combined_entry_type *, - unsigned int *)); -static boolean coff_write_alien_symbol PARAMS ((bfd *, asymbol *, - unsigned int *)); -static boolean coff_write_native_symbol PARAMS ((bfd *, coff_symbol_type *, - unsigned int *)); - -static asection bfd_debug_section = { "*DEBUG*" }; - -/* Take a section header read from a coff file (in HOST byte order), - and make a BFD "section" out of it. This is used by ECOFF. */ -static boolean -make_a_section_from_file (abfd, hdr, target_index) - bfd *abfd; - struct internal_scnhdr *hdr; - unsigned int target_index; -{ - asection *return_section; - char *name; - - /* Assorted wastage to null-terminate the name, thanks AT&T! */ - name = bfd_alloc(abfd, sizeof (hdr->s_name)+1); - if (name == NULL) { - bfd_set_error (bfd_error_no_memory); - return false; - } - strncpy(name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); - name[sizeof (hdr->s_name)] = 0; - - return_section = bfd_make_section(abfd, name); - if (return_section == NULL) - return_section = bfd_coff_make_section_hook (abfd, name); - - /* Handle several sections of the same name. For example, if an executable - has two .bss sections, GDB better be able to find both of them - (PR 3562). */ - if (return_section == NULL) - return_section = bfd_make_section_anyway (abfd, name); - - if (return_section == NULL) - return false; - - /* s_paddr is presumed to be = to s_vaddr */ - - return_section->vma = hdr->s_vaddr; - return_section->_raw_size = hdr->s_size; - return_section->filepos = hdr->s_scnptr; - return_section->rel_filepos = hdr->s_relptr; - return_section->reloc_count = hdr->s_nreloc; - - bfd_coff_set_alignment_hook (abfd, return_section, hdr); - - return_section->line_filepos = hdr->s_lnnoptr; - - return_section->lineno_count = hdr->s_nlnno; - return_section->userdata = NULL; - return_section->next = (asection *) NULL; - return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr); - - return_section->target_index = target_index; - - /* At least on i386-coff, the line number count for a shared library - section must be ignored. */ - if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) - return_section->lineno_count = 0; - - if (hdr->s_nreloc != 0) - return_section->flags |= SEC_RELOC; - /* FIXME: should this check 'hdr->s_size > 0' */ - if (hdr->s_scnptr != 0) - return_section->flags |= SEC_HAS_CONTENTS; - return true; -} - -/* Read in a COFF object and make it into a BFD. This is used by - ECOFF as well. */ - -static const bfd_target * -coff_real_object_p (abfd, nscns, internal_f, internal_a) - bfd *abfd; - unsigned nscns; - struct internal_filehdr *internal_f; - struct internal_aouthdr *internal_a; -{ - PTR tdata; - size_t readsize; /* length of file_info */ - unsigned int scnhsz; - char *external_sections; - - /* Build a play area */ - tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); - if (tdata == NULL) - return 0; - - scnhsz = bfd_coff_scnhsz (abfd); - readsize = nscns * scnhsz; - external_sections = (char *)bfd_alloc(abfd, readsize); - if (!external_sections) - { - bfd_set_error (bfd_error_no_memory); - goto fail; - } - - if (bfd_read((PTR)external_sections, 1, readsize, abfd) != readsize) { - goto fail; - } - - /* Now copy data as required; construct all asections etc */ - if (nscns != 0) { - unsigned int i; - for (i = 0; i < nscns; i++) { - struct internal_scnhdr tmp; - bfd_coff_swap_scnhdr_in(abfd, (PTR) (external_sections + i * scnhsz), - (PTR) &tmp); - make_a_section_from_file(abfd,&tmp, i+1); - } - } - -/* make_abs_section(abfd);*/ - - if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false) - goto fail; - - if (!(internal_f->f_flags & F_RELFLG)) - abfd->flags |= HAS_RELOC; - if ((internal_f->f_flags & F_EXEC)) - abfd->flags |= EXEC_P; - if (!(internal_f->f_flags & F_LNNO)) - abfd->flags |= HAS_LINENO; - if (!(internal_f->f_flags & F_LSYMS)) - abfd->flags |= HAS_LOCALS; - - /* FIXME: How can we set D_PAGED correctly? */ - if ((internal_f->f_flags & F_EXEC) != 0) - abfd->flags |= D_PAGED; - - bfd_get_symcount(abfd) = internal_f->f_nsyms; - if (internal_f->f_nsyms) - abfd->flags |= HAS_SYMS; - - if (internal_a != (struct internal_aouthdr *) NULL) - bfd_get_start_address (abfd) = internal_a->entry; - else - bfd_get_start_address (abfd) = 0; - - return abfd->xvec; - fail: - bfd_release(abfd, tdata); - return (const bfd_target *)NULL; -} - -/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is - not a COFF file. This is also used by ECOFF. */ - -const bfd_target * -coff_object_p (abfd) - bfd *abfd; -{ - unsigned int filhsz; - unsigned int aoutsz; - int nscns; - PTR filehdr; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - - /* figure out how much to read */ - filhsz = bfd_coff_filhsz (abfd); - aoutsz = bfd_coff_aoutsz (abfd); - - filehdr = bfd_alloc (abfd, filhsz); - if (filehdr == NULL) - return 0; - if (bfd_read(filehdr, 1, filhsz, abfd) != filhsz) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return 0; - } - bfd_coff_swap_filehdr_in(abfd, filehdr, &internal_f); - bfd_release (abfd, filehdr); - - if (bfd_coff_bad_format_hook (abfd, &internal_f) == false) { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - nscns =internal_f.f_nscns; - - if (internal_f.f_opthdr) { - PTR opthdr; - - opthdr = bfd_alloc (abfd, aoutsz); - if (opthdr == NULL) - return 0;; - if (bfd_read(opthdr, 1,aoutsz, abfd) != aoutsz) { - return 0; - } - bfd_coff_swap_aouthdr_in(abfd, opthdr, (PTR)&internal_a); - } - - /* Seek past the opt hdr stuff */ - if (bfd_seek(abfd, (file_ptr) (internal_f.f_opthdr + filhsz), SEEK_SET) - != 0) - return NULL; - - return coff_real_object_p(abfd, nscns, &internal_f, - (internal_f.f_opthdr != 0 - ? &internal_a - : (struct internal_aouthdr *) NULL)); -} - -/* Get the BFD section from a COFF symbol section number. */ - -asection * -coff_section_from_bfd_index (abfd, index) - bfd *abfd; - int index; -{ - struct sec *answer = abfd->sections; - - if (index == N_ABS) - { - return bfd_abs_section_ptr; - } - if (index == N_UNDEF) - { - return bfd_und_section_ptr; - } - if(index == N_DEBUG) - { - return &bfd_debug_section; - - } - - while (answer) { - if (answer->target_index == index) - return answer; - answer = answer->next; - } - - /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a - has a bad symbol table in biglitpow.o. */ - return bfd_und_section_ptr; -} - -/* Get the upper bound of a COFF symbol table. */ - -long -coff_get_symtab_upper_bound(abfd) -bfd *abfd; -{ - if (!bfd_coff_slurp_symbol_table(abfd)) - return -1; - - return (bfd_get_symcount(abfd) + 1) * (sizeof(coff_symbol_type *)); -} - - -/* Canonicalize a COFF symbol table. */ - -long -coff_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int counter = 0; - coff_symbol_type *symbase; - coff_symbol_type **location = (coff_symbol_type **) (alocation); - if (!bfd_coff_slurp_symbol_table(abfd)) - return -1; - - symbase = obj_symbols(abfd); - while (counter < bfd_get_symcount(abfd)) - { - /* This nasty code looks at the symbol to decide whether or - not it is descibes a constructor/destructor entry point. It - is structured this way to (hopefully) speed non matches */ -#if 0 - if (0 && symbase->symbol.name[9] == '$') - { - bfd_constructor_entry(abfd, - (asymbol **)location, - symbase->symbol.name[10] == 'I' ? - "CTOR" : "DTOR"); - } -#endif - *(location++) = symbase++; - counter++; - } - *location++ = 0; - return bfd_get_symcount(abfd); -} - -/* Set lineno_count for the output sections of a COFF file. */ - -int -coff_count_linenumbers (abfd) - bfd *abfd; -{ - unsigned int limit = bfd_get_symcount(abfd); - unsigned int i; - int total = 0; - asymbol **p; - { - asection *s = abfd->sections->output_section; - while (s) { - BFD_ASSERT(s->lineno_count == 0); - s = s->next; - } - } - - - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) { - asymbol *q_maybe = *p; - if (bfd_asymbol_flavour(q_maybe) == bfd_target_coff_flavour) { - coff_symbol_type *q = coffsymbol(q_maybe); - if (q->lineno) { - /* - This symbol has a linenumber, increment the owning - section's linenumber count - */ - alent *l = q->lineno; - q->symbol.section->output_section->lineno_count++; - total ++; - l++; - while (l->line_number) { - total ++; - q->symbol.section->output_section->lineno_count++; - l++; - } - } - } - } - return total; -} - -/* Takes a bfd and a symbol, returns a pointer to the coff specific - area of the symbol if there is one. */ - -/*ARGSUSED*/ -coff_symbol_type * -coff_symbol_from (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - if (bfd_asymbol_flavour(symbol) != bfd_target_coff_flavour) - return (coff_symbol_type *)NULL; - - if (bfd_asymbol_bfd(symbol)->tdata.coff_obj_data == (coff_data_type*)NULL) - return (coff_symbol_type *)NULL; - - return (coff_symbol_type *) symbol; -} - -static void -fixup_symbol_value (coff_symbol_ptr, syment) - coff_symbol_type *coff_symbol_ptr; - struct internal_syment *syment; -{ - - /* Normalize the symbol flags */ - if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) { - /* a common symbol is undefined with a value */ - syment->n_scnum = N_UNDEF; - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) { - syment->n_value = coff_symbol_ptr->symbol.value; - } - else if (bfd_is_und_section (coff_symbol_ptr->symbol.section)) { - syment->n_scnum = N_UNDEF; - syment->n_value = 0; - } - else { - if (coff_symbol_ptr->symbol.section) { - syment->n_scnum = - coff_symbol_ptr->symbol.section->output_section->target_index; - - syment->n_value = - coff_symbol_ptr->symbol.value + - coff_symbol_ptr->symbol.section->output_offset + - coff_symbol_ptr->symbol.section->output_section->vma; - } - else { - BFD_ASSERT(0); - /* This can happen, but I don't know why yet (steve@cygnus.com) */ - syment->n_scnum = N_ABS; - syment->n_value = coff_symbol_ptr->symbol.value; - } - } -} - -/* run through all the symbols in the symbol table and work out what - their indexes into the symbol table will be when output - - Coff requires that each C_FILE symbol points to the next one in the - chain, and that the last one points to the first external symbol. We - do that here too. - -*/ -boolean -coff_renumber_symbols (bfd_ptr) - bfd *bfd_ptr; -{ - unsigned int symbol_count = bfd_get_symcount(bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int native_index = 0; - struct internal_syment *last_file = (struct internal_syment *)NULL; - unsigned int symbol_index; - - /* COFF demands that undefined symbols come after all other symbols. - Since we don't need to impose this extra knowledge on all our client - programs, deal with that here. Sort the symbol table; just move the - undefined symbols to the end, leaving the rest alone. */ - /* @@ Do we have some condition we could test for, so we don't always - have to do this? I don't think relocatability is quite right, but - I'm not certain. [raeburn:19920508.1711EST] */ - { - asymbol **newsyms; - int i; - - newsyms = (asymbol **) bfd_alloc_by_size_t (bfd_ptr, - sizeof (asymbol *) - * (symbol_count + 1)); - if (!newsyms) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - bfd_ptr->outsymbols = newsyms; - for (i = 0; i < symbol_count; i++) - if (! bfd_is_und_section (symbol_ptr_ptr[i]->section)) - *newsyms++ = symbol_ptr_ptr[i]; - for (i = 0; i < symbol_count; i++) - if (bfd_is_und_section (symbol_ptr_ptr[i]->section)) - *newsyms++ = symbol_ptr_ptr[i]; - *newsyms = (asymbol *) NULL; - symbol_ptr_ptr = bfd_ptr->outsymbols; - } - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]); - if (coff_symbol_ptr && coff_symbol_ptr->native) { - combined_entry_type *s = coff_symbol_ptr->native; - int i; - - if (s->u.syment.n_sclass == C_FILE) - { - if (last_file != (struct internal_syment *)NULL) { - last_file->n_value = native_index; - } - last_file = &(s->u.syment); - } - else { - - /* Modify the symbol values according to their section and - type */ - - fixup_symbol_value(coff_symbol_ptr, &(s->u.syment)); - } - for (i = 0; i < s->u.syment.n_numaux + 1; i++) { - s[i].offset = native_index ++; - } - } - else { - native_index++; - } - } - obj_conv_table_size (bfd_ptr) = native_index; - return true; -} - -/* - Run thorough the symbol table again, and fix it so that all pointers to - entries are changed to the entries' index in the output symbol table. - -*/ -void -coff_mangle_symbols (bfd_ptr) - bfd *bfd_ptr; -{ - unsigned int symbol_count = bfd_get_symcount (bfd_ptr); - asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; - unsigned int symbol_index; - - for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) - { - coff_symbol_type *coff_symbol_ptr = - coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); - - if (coff_symbol_ptr && coff_symbol_ptr->native) - { - int i; - combined_entry_type *s = coff_symbol_ptr->native; - - if (s->fix_value) - { - /* FIXME: We should use a union here. */ - s->u.syment.n_value = - ((combined_entry_type *) s->u.syment.n_value)->offset; - s->fix_value = 0; - } - for (i = 0; i < s->u.syment.n_numaux ; i++) - { - combined_entry_type *a = s + i + 1; - if (a->fix_tag) - { - a->u.auxent.x_sym.x_tagndx.l = - a->u.auxent.x_sym.x_tagndx.p->offset; - a->fix_tag = 0; - } - if (a->fix_end) - { - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = - a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; - a->fix_end = 0; - } - if (a->fix_scnlen) - { - a->u.auxent.x_csect.x_scnlen.l = - a->u.auxent.x_csect.x_scnlen.p->offset; - a->fix_scnlen = 0; - } - } - } - } -} - -static bfd_size_type string_size; -static bfd_size_type debug_string_size; -static asection *debug_string_section; - -static void -coff_fix_symbol_name (abfd, symbol, native) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; -{ - unsigned int name_length; - union internal_auxent *auxent; - char * name = ( char *)(symbol->name); - - if (name == (char *) NULL) { - /* coff symbols always have names, so we'll make one up */ - symbol->name = "strange"; - name = (char *)symbol->name; - } - name_length = strlen(name); - - if (native->u.syment.n_sclass == C_FILE) { - strncpy(native->u.syment._n._n_name, ".file", SYMNMLEN); - auxent = &(native+1)->u.auxent; - - if (bfd_coff_long_filenames (abfd)) { - if (name_length <= FILNMLEN) { - strncpy(auxent->x_file.x_fname, name, FILNMLEN); - } - else { - auxent->x_file.x_n.x_offset = string_size + 4; - auxent->x_file.x_n.x_zeroes = 0; - string_size += name_length + 1; - } - } - else { - strncpy(auxent->x_file.x_fname, name, FILNMLEN); - if (name_length > FILNMLEN) { - name[FILNMLEN] = '\0'; - } - } - } - else - { /* NOT A C_FILE SYMBOL */ - if (name_length <= SYMNMLEN) - { - /* This name will fit into the symbol neatly */ - strncpy(native->u.syment._n._n_name, symbol->name, SYMNMLEN); - } - else if (! bfd_coff_symname_in_debug (abfd, &native->u.syment)) - { - native->u.syment._n._n_n._n_offset = string_size + 4; - native->u.syment._n._n_n._n_zeroes = 0; - string_size += name_length + 1; - } - else - { - long filepos; - bfd_byte buf[2]; - - /* This name should be written into the .debug section. For - some reason each name is preceded by a two byte length - and also followed by a null byte. FIXME: We assume that - the .debug section has already been created, and that it - is large enough. */ - if (debug_string_section == (asection *) NULL) - debug_string_section = bfd_get_section_by_name (abfd, ".debug"); - filepos = bfd_tell (abfd); - bfd_put_16 (abfd, name_length + 1, buf); - if (! bfd_set_section_contents (abfd, - debug_string_section, - (PTR) buf, - (file_ptr) debug_string_size, - (bfd_size_type) 2) - || ! bfd_set_section_contents (abfd, - debug_string_section, - (PTR) symbol->name, - (file_ptr) debug_string_size + 2, - (bfd_size_type) name_length + 1)) - abort (); - if (bfd_seek (abfd, filepos, SEEK_SET) != 0) - abort (); - native->u.syment._n._n_n._n_offset = debug_string_size + 2; - native->u.syment._n._n_n._n_zeroes = 0; - debug_string_size += name_length + 3; - } - } -} - -/* We need to keep track of the symbol index so that when we write out - the relocs we can get the index for a symbol. This method is a - hack. FIXME. */ - -#define set_index(symbol, idx) ((symbol)->udata = (PTR) (idx)) - -/* Write a symbol out to a COFF file. */ - -static boolean -coff_write_symbol (abfd, symbol, native, written) - bfd *abfd; - asymbol *symbol; - combined_entry_type *native; - unsigned int *written; -{ - unsigned int numaux = native->u.syment.n_numaux; - int type = native->u.syment.n_type; - int class = native->u.syment.n_sclass; - PTR buf; - bfd_size_type symesz; - - /* @@ bfd_debug_section isn't accessible outside this file, but we - know that C_FILE symbols belong there. So move them. */ - if (native->u.syment.n_sclass == C_FILE) - symbol->section = &bfd_debug_section; - - if (bfd_is_abs_section (symbol->section)) - { - native->u.syment.n_scnum = N_ABS; - } - else if (symbol->section == &bfd_debug_section) - { - native->u.syment.n_scnum = N_DEBUG; - } - else if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - } - else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - } - - coff_fix_symbol_name (abfd, symbol, native); - - symesz = bfd_coff_symesz (abfd); - buf = bfd_alloc (abfd, symesz); - if (!buf) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - bfd_coff_swap_sym_out (abfd, &native->u.syment, buf); - if (bfd_write (buf, 1, symesz, abfd) != symesz) - return false; - bfd_release (abfd, buf); - - if (native->u.syment.n_numaux > 0) - { - bfd_size_type auxesz; - unsigned int j; - - auxesz = bfd_coff_auxesz (abfd); - buf = bfd_alloc (abfd, auxesz); - if (!buf) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - for (j = 0; j < native->u.syment.n_numaux; j++) - { - bfd_coff_swap_aux_out (abfd, - &((native + j + 1)->u.auxent), - type, - class, - j, - native->u.syment.n_numaux, - buf); - if (bfd_write (buf, 1, auxesz, abfd)!= auxesz) - return false; - } - bfd_release (abfd, buf); - } - - /* Store the index for use when we write out the relocs. */ - set_index (symbol, *written); - - *written += numaux + 1; - return true; -} - -/* Write out a symbol to a COFF file that does not come from a COFF - file originally. This symbol may have been created by the linker, - or we may be linking a non COFF file to a COFF file. */ - -static boolean -coff_write_alien_symbol (abfd, symbol, written) - bfd *abfd; - asymbol *symbol; - unsigned int *written; -{ - combined_entry_type *native; - combined_entry_type dummy; - - native = &dummy; - native->u.syment.n_type = T_NULL; - native->u.syment.n_flags = 0; - if (bfd_is_und_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (bfd_is_com_section (symbol->section)) - { - native->u.syment.n_scnum = N_UNDEF; - native->u.syment.n_value = symbol->value; - } - else if (symbol->flags & BSF_DEBUGGING) - { - /* Remove the symbol name so that it does not take up any space. - COFF won't know what to do with it anyhow. */ - symbol->name = ""; - } - else - { - native->u.syment.n_scnum = - symbol->section->output_section->target_index; - native->u.syment.n_value = (symbol->value - + symbol->section->output_section->vma - + symbol->section->output_offset); - - /* Copy the any flags from the the file header into the symbol. - FIXME: Why? */ - { - coff_symbol_type *c = coff_symbol_from (abfd, symbol); - if (c != (coff_symbol_type *) NULL) - native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; - } - } - - native->u.syment.n_type = 0; - if (symbol->flags & BSF_LOCAL) - native->u.syment.n_sclass = C_STAT; - else - native->u.syment.n_sclass = C_EXT; - native->u.syment.n_numaux = 0; - - return coff_write_symbol (abfd, symbol, native, written); -} - -/* Write a native symbol to a COFF file. */ - -static boolean -coff_write_native_symbol (abfd, symbol, written) - bfd *abfd; - coff_symbol_type *symbol; - unsigned int *written; -{ - combined_entry_type *native = symbol->native; - alent *lineno = symbol->lineno; - - /* If this symbol has an associated line number, we must store the - symbol index in the line number field. We also tag the auxent to - point to the right place in the lineno table. */ - if (lineno && !symbol->done_lineno) - { - unsigned int count = 0; - lineno[count].u.offset = *written; - if (native->u.syment.n_numaux) - { - union internal_auxent *a = &((native+1)->u.auxent); - - a->x_sym.x_fcnary.x_fcn.x_lnnoptr = - symbol->symbol.section->output_section->moving_line_filepos; - } - - /* Count and relocate all other linenumbers. */ - count++; - while (lineno[count].line_number != 0) - { -#if 0 - /* 13 april 92. sac - I've been told this, but still need proof: - > The second bug is also in `bfd/coffcode.h'. This bug - > causes the linker to screw up the pc-relocations for - > all the line numbers in COFF code. This bug isn't only - > specific to A29K implementations, but affects all - > systems using COFF format binaries. Note that in COFF - > object files, the line number core offsets output by - > the assembler are relative to the start of each - > procedure, not to the start of the .text section. This - > patch relocates the line numbers relative to the - > `native->u.syment.n_value' instead of the section - > virtual address. - > modular!olson@cs.arizona.edu (Jon Olson) - */ - lineno[count].u.offset += native->u.syment.n_value; -#else - lineno[count].u.offset += - (symbol->symbol.section->output_section->vma - + symbol->symbol.section->output_offset); -#endif - count++; - } - symbol->done_lineno = true; - - symbol->symbol.section->output_section->moving_line_filepos += - count * bfd_coff_linesz (abfd); - } - - return coff_write_symbol (abfd, &(symbol->symbol), native, written); -} - -/* Write out the COFF symbols. */ - -boolean -coff_write_symbols (abfd) - bfd *abfd; -{ - unsigned int i; - unsigned int limit = bfd_get_symcount(abfd); - unsigned int written = 0; - asymbol **p; - - string_size = 0; - debug_string_size = 0; - - /* Seek to the right place */ - if (bfd_seek (abfd, obj_sym_filepos(abfd), SEEK_SET) != 0) - return false; - - /* Output all the symbols we have */ - - written = 0; - for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) - { - asymbol *symbol = *p; - coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); - - if (c_symbol == (coff_symbol_type *) NULL - || c_symbol->native == (combined_entry_type *)NULL) - { - if (! coff_write_alien_symbol (abfd, symbol, &written)) - return false; - } - else - { - if (! coff_write_native_symbol (abfd, c_symbol, &written)) - return false; - } - } - - bfd_get_symcount (abfd) = written; - - /* Now write out strings */ - - if (string_size != 0) - { - unsigned int size = string_size + 4; - bfd_byte buffer[4]; - - bfd_h_put_32 (abfd, size, buffer); - if (bfd_write ((PTR) buffer, 1, sizeof (buffer), abfd) != sizeof (buffer)) - return false; - for (p = abfd->outsymbols, i = 0; - i < limit; - i++, p++) - { - asymbol *q = *p; - size_t name_length = strlen (q->name); - coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); - size_t maxlen; - - /* Figure out whether the symbol name should go in the string - table. Symbol names that are short enough are stored - directly in the syment structure. File names permit a - different, longer, length in the syment structure. On - XCOFF, some symbol names are stored in the .debug section - rather than in the string table. */ - - if (c_symbol == NULL - || c_symbol->native == NULL) - { - /* This is not a COFF symbol, so it certainly is not a - file name, nor does it go in the .debug section. */ - maxlen = SYMNMLEN; - } - else if (bfd_coff_symname_in_debug (abfd, - &c_symbol->native->u.syment)) - { - /* This symbol name is in the XCOFF .debug section. - Don't write it into the string table. */ - maxlen = name_length; - } - else if (c_symbol->native->u.syment.n_sclass == C_FILE) - maxlen = FILNMLEN; - else - maxlen = SYMNMLEN; - - if (name_length > maxlen) - { - if (bfd_write ((PTR) (q->name), 1, name_length + 1, abfd) - != name_length + 1) - return false; - } - } - } - else - { - /* We would normally not write anything here, but we'll write - out 4 so that any stupid coff reader which tries to read the - string table even when there isn't one won't croak. */ - unsigned int size = 4; - bfd_byte buffer[4]; - - bfd_h_put_32 (abfd, size, buffer); - if (bfd_write ((PTR) buffer, 1, 4, abfd) != 4) - return false; - } - - /* Make sure the .debug section was created to be the correct size. - We should create it ourselves on the fly, but we don't because - BFD won't let us write to any section until we know how large all - the sections are. We could still do it by making another pass - over the symbols. FIXME. */ - BFD_ASSERT (debug_string_size == 0 - || (debug_string_section != (asection *) NULL - && (BFD_ALIGN (debug_string_size, - 1 << debug_string_section->alignment_power) - == bfd_section_size (abfd, debug_string_section)))); - - return true; -} - -boolean -coff_write_linenumbers (abfd) - bfd *abfd; -{ - asection *s; - bfd_size_type linesz; - PTR buff; - - linesz = bfd_coff_linesz (abfd); - buff = bfd_alloc (abfd, linesz); - if (!buff) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - for (s = abfd->sections; s != (asection *) NULL; s = s->next) { - if (s->lineno_count) { - asymbol **q = abfd->outsymbols; - if (bfd_seek(abfd, s->line_filepos, SEEK_SET) != 0) - return false; - /* Find all the linenumbers in this section */ - while (*q) { - asymbol *p = *q; - if (p->section->output_section == s) { - alent *l = - BFD_SEND(bfd_asymbol_bfd(p), _get_lineno, (bfd_asymbol_bfd(p), p)); - if (l) { - /* Found a linenumber entry, output */ - struct internal_lineno out; - memset( (PTR)&out, 0, sizeof(out)); - out.l_lnno = 0; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out(abfd, &out, buff); - if (bfd_write(buff, 1, linesz, abfd) != linesz) - return false; - l++; - while (l->line_number) { - out.l_lnno = l->line_number; - out.l_addr.l_symndx = l->u.offset; - bfd_coff_swap_lineno_out(abfd, &out, buff); - if (bfd_write(buff, 1, linesz, abfd) != linesz) - return false; - l++; - } - } - } - q++; - } - } - } - bfd_release (abfd, buff); - return true; -} - -/*ARGSUSED*/ -alent * -coff_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - return coffsymbol(symbol)->lineno; -} - -asymbol * -coff_section_symbol (abfd, name) - bfd *abfd; - char *name; -{ - asection *sec = bfd_make_section_old_way (abfd, name); - asymbol *sym; - combined_entry_type *csym; - - sym = sec->symbol; - csym = coff_symbol_from (abfd, sym)->native; - /* Make sure back-end COFF stuff is there. */ - if (csym == 0) - { - struct foo { - coff_symbol_type sym; - /* @@FIXME This shouldn't use a fixed size!! */ - combined_entry_type e[10]; - }; - struct foo *f; - f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f)); - if (!f) - { - bfd_set_error (bfd_error_no_error); - return NULL; - } - memset ((char *) f, 0, sizeof (*f)); - coff_symbol_from (abfd, sym)->native = csym = f->e; - } - csym[0].u.syment.n_sclass = C_STAT; - csym[0].u.syment.n_numaux = 1; -/* SF_SET_STATICS (sym); @@ ??? */ - csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size; - csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count; - csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count; - - if (sec->output_section == NULL) - { - sec->output_section = sec; - sec->output_offset = 0; - } - - return sym; -} - -/* This function transforms the offsets into the symbol table into - pointers to syments. */ - -static void -coff_pointerize_aux (abfd, table_base, type, class, auxent) - bfd *abfd; - combined_entry_type *table_base; - int type; - int class; - combined_entry_type *auxent; -{ - /* Don't bother if this is a file or a section */ - if (class == C_STAT && type == T_NULL) return; - if (class == C_FILE) return; - - /* Otherwise patch up */ -#define N_TMASK coff_data (abfd)->local_n_tmask -#define N_BTSHFT coff_data (abfd)->local_n_btshft - if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) { - auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base + - auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; - auxent->fix_end = 1; - } - /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can - generate one, so we must be careful to ignore it. */ - if (auxent->u.auxent.x_sym.x_tagndx.l > 0) { - auxent->u.auxent.x_sym.x_tagndx.p = - table_base + auxent->u.auxent.x_sym.x_tagndx.l; - auxent->fix_tag = 1; - } -} - -static char * -build_string_table (abfd) - bfd *abfd; -{ - char string_table_size_buffer[4]; - unsigned int string_table_size; - char *string_table; - - /* At this point we should be "seek"'d to the end of the - symbols === the symbol table size. */ - if (bfd_read((char *) string_table_size_buffer, - sizeof(string_table_size_buffer), - 1, abfd) != sizeof(string_table_size)) - return (NULL); - - string_table_size = bfd_h_get_32(abfd, (bfd_byte *) string_table_size_buffer); - - if ((string_table = (PTR) bfd_alloc(abfd, string_table_size -= 4)) == NULL) { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } /* on mallocation error */ - if (bfd_read(string_table, string_table_size, 1, abfd) != string_table_size) - return (NULL); - return string_table; -} - -/* Allocate space for the ".debug" section, and read it. - We did not read the debug section until now, because - we didn't want to go to the trouble until someone needed it. */ - -static char * -build_debug_section (abfd) - bfd *abfd; -{ - char *debug_section; - long position; - - asection *sect = bfd_get_section_by_name (abfd, ".debug"); - - if (!sect) { - bfd_set_error (bfd_error_no_debug_section); - return NULL; - } - - debug_section = (PTR) bfd_alloc (abfd, - bfd_get_section_size_before_reloc (sect)); - if (debug_section == NULL) { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Seek to the beginning of the `.debug' section and read it. - Save the current position first; it is needed by our caller. - Then read debug section and reset the file pointer. */ - - position = bfd_tell (abfd); - if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0 - || (bfd_read (debug_section, - bfd_get_section_size_before_reloc (sect), 1, abfd) - != bfd_get_section_size_before_reloc(sect)) - || bfd_seek (abfd, position, SEEK_SET) != 0) - return NULL; - return debug_section; -} - - -/* Return a pointer to a malloc'd copy of 'name'. 'name' may not be - \0-terminated, but will not exceed 'maxlen' characters. The copy *will* - be \0-terminated. */ -static char * -copy_name (abfd, name, maxlen) - bfd *abfd; - char *name; - int maxlen; -{ - int len; - char *newname; - - for (len = 0; len < maxlen; ++len) { - if (name[len] == '\0') { - break; - } - } - - if ((newname = (PTR) bfd_alloc(abfd, len+1)) == NULL) { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } - strncpy(newname, name, len); - newname[len] = '\0'; - return newname; -} - -/* Read a symbol table into freshly bfd_allocated memory, swap it, and - knit the symbol names into a normalized form. By normalized here I - mean that all symbols have an n_offset pointer that points to a null- - terminated string. */ - -combined_entry_type * -coff_get_normalized_symtab (abfd) - bfd *abfd; -{ - combined_entry_type *internal; - combined_entry_type *internal_ptr; - combined_entry_type *symbol_ptr; - combined_entry_type *internal_end; - bfd_size_type symesz; - PTR raw; - char *raw_src; - char *raw_end; - char *string_table = NULL; - char *debug_section = NULL; - unsigned long size; - - unsigned int raw_size; - if (obj_raw_syments(abfd) != (combined_entry_type *)NULL) { - return obj_raw_syments(abfd); - } - if ((size = bfd_get_symcount(abfd) * sizeof(combined_entry_type)) == 0) { - bfd_set_error (bfd_error_no_symbols); - return (NULL); - } - - internal = (combined_entry_type *)bfd_alloc(abfd, size); - if (!internal) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - internal_end = internal + bfd_get_symcount(abfd); - - symesz = bfd_coff_symesz (abfd); - raw_size = bfd_get_symcount(abfd) * symesz; - raw = bfd_alloc(abfd,raw_size); - if (!raw) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - if (bfd_seek(abfd, obj_sym_filepos(abfd), SEEK_SET) == -1 - || bfd_read(raw, raw_size, 1, abfd) != raw_size) - return (NULL); - /* mark the end of the symbols */ - raw_end = (char *) raw + bfd_get_symcount(abfd) * symesz; - /* - FIXME SOMEDAY. A string table size of zero is very weird, but - probably possible. If one shows up, it will probably kill us. - */ - - /* Swap all the raw entries */ - for (raw_src = (char *) raw, internal_ptr = internal; - raw_src < raw_end; - raw_src += symesz, internal_ptr++) { - - unsigned int i; - bfd_coff_swap_sym_in(abfd, (PTR)raw_src, (PTR)&internal_ptr->u.syment); - internal_ptr->fix_value = 0; - internal_ptr->fix_tag = 0; - internal_ptr->fix_end = 0; - internal_ptr->fix_scnlen = 0; - symbol_ptr = internal_ptr; - - for (i = 0; - i < symbol_ptr->u.syment.n_numaux; - i++) - { - internal_ptr++; - raw_src += symesz; - - internal_ptr->fix_value = 0; - internal_ptr->fix_tag = 0; - internal_ptr->fix_end = 0; - internal_ptr->fix_scnlen = 0; - bfd_coff_swap_aux_in(abfd, (PTR) raw_src, - symbol_ptr->u.syment.n_type, - symbol_ptr->u.syment.n_sclass, - i, symbol_ptr->u.syment.n_numaux, - &(internal_ptr->u.auxent)); - /* Remember that bal entries arn't pointerized */ - if (i != 1 || symbol_ptr->u.syment.n_sclass != C_LEAFPROC) - { - - coff_pointerize_aux(abfd, - internal, - symbol_ptr->u.syment.n_type, - symbol_ptr->u.syment.n_sclass, - internal_ptr); - } - - } - } - - /* Free all the raw stuff */ - bfd_release(abfd, raw); - - for (internal_ptr = internal; internal_ptr < internal_end; - internal_ptr ++) - { - if (internal_ptr->u.syment.n_sclass == C_FILE) { - /* make a file symbol point to the name in the auxent, since - the text ".file" is redundant */ - if ((internal_ptr+1)->u.auxent.x_file.x_n.x_zeroes == 0) { - /* the filename is a long one, point into the string table */ - if (string_table == NULL) { - string_table = build_string_table(abfd); - } - - internal_ptr->u.syment._n._n_n._n_offset = - (long) (string_table - 4 + - (internal_ptr+1)->u.auxent.x_file.x_n.x_offset); - } - else { - /* ordinary short filename, put into memory anyway */ - internal_ptr->u.syment._n._n_n._n_offset = (long) - copy_name(abfd, (internal_ptr+1)->u.auxent.x_file.x_fname, - FILNMLEN); - } - } - else { - if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) { - /* This is a "short" name. Make it long. */ - unsigned long i = 0; - char *newstring = NULL; - - /* find the length of this string without walking into memory - that isn't ours. */ - for (i = 0; i < 8; ++i) { - if (internal_ptr->u.syment._n._n_name[i] == '\0') { - break; - } /* if end of string */ - } /* possible lengths of this string. */ - - if ((newstring = (PTR) bfd_alloc(abfd, ++i)) == NULL) { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } /* on error */ - memset(newstring, 0, i); - strncpy(newstring, internal_ptr->u.syment._n._n_name, i-1); - internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring; - internal_ptr->u.syment._n._n_n._n_zeroes = 0; - } - else if (internal_ptr->u.syment._n._n_n._n_offset == 0) - internal_ptr->u.syment._n._n_n._n_offset = (long int) ""; - else if (!bfd_coff_symname_in_debug(abfd, &internal_ptr->u.syment)) { - /* Long name already. Point symbol at the string in the table. */ - if (string_table == NULL) { - string_table = build_string_table(abfd); - } - internal_ptr->u.syment._n._n_n._n_offset = (long int) - (string_table - 4 + internal_ptr->u.syment._n._n_n._n_offset); - } - else { - /* Long name in debug section. Very similar. */ - if (debug_section == NULL) { - debug_section = build_debug_section(abfd); - } - internal_ptr->u.syment._n._n_n._n_offset = (long int) - (debug_section + internal_ptr->u.syment._n._n_n._n_offset); - } - } - internal_ptr += internal_ptr->u.syment.n_numaux; - } - - obj_raw_syments(abfd) = internal; - obj_raw_syment_count(abfd) = internal_ptr - internal; - - return (internal); -} /* coff_get_normalized_symtab() */ - -long -coff_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - if (bfd_get_format(abfd) != bfd_object) { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - return (asect->reloc_count + 1) * sizeof(arelent *); -} - -asymbol * -coff_make_empty_symbol (abfd) - bfd *abfd; -{ - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type)); - if (new == NULL) { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } /* on error */ - memset (new, 0, sizeof *new); - new->symbol.section = 0; - new->native = 0; - new->lineno = (alent *) NULL; - new->done_lineno = false; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Make a debugging symbol. */ - -asymbol * -coff_bfd_make_debug_symbol (abfd, ptr, sz) - bfd *abfd; - PTR ptr; - unsigned long sz; -{ - coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type)); - if (new == NULL) { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } /* on error */ - /* @@ This shouldn't be using a constant multiplier. */ - new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10); - if (!new->native) - { - bfd_set_error (bfd_error_no_memory); - return (NULL); - } /* on error */ - new->symbol.section = &bfd_debug_section; - new->lineno = (alent *) NULL; - new->done_lineno = false; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/*ARGSUSED*/ -void -coff_get_symbol_info (abfd, symbol, ret) - bfd *abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/* Print out information about COFF symbol. */ - -void -coff_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - - case bfd_print_symbol_more: - fprintf (file, "coff %s %s", - coffsymbol(symbol)->native ? "n" : "g", - coffsymbol(symbol)->lineno ? "l" : " "); - break; - - case bfd_print_symbol_all: - if (coffsymbol(symbol)->native) - { - unsigned int aux; - combined_entry_type *combined = coffsymbol (symbol)->native; - combined_entry_type *root = obj_raw_syments (abfd); - struct lineno_cache_entry *l = coffsymbol(symbol)->lineno; - - fprintf (file,"[%3d]", combined - root); - - fprintf (file, - "(sc %2d)(fl 0x%02x)(ty %3x)(sc %3d) (nx %d) 0x%08lx %s", - combined->u.syment.n_scnum, - combined->u.syment.n_flags, - combined->u.syment.n_type, - combined->u.syment.n_sclass, - combined->u.syment.n_numaux, - (unsigned long) combined->u.syment.n_value, - symbol->name); - - for (aux = 0; aux < combined->u.syment.n_numaux; aux++) - { - combined_entry_type *auxp = combined + aux + 1; - long tagndx; - - if (auxp->fix_tag) - tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root; - else - tagndx = auxp->u.auxent.x_sym.x_tagndx.l; - - fprintf (file, "\n"); - switch (combined->u.syment.n_sclass) - { - case C_FILE: - fprintf (file, "File "); - break; - default: - - fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, - auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size, - tagndx); - break; - } - } - - if (l) - { - fprintf (file, "\n%s :", l->u.sym->name); - l++; - while (l->line_number) - { - fprintf (file, "\n%4d : 0x%lx", - l->line_number, - ((unsigned long) - (l->u.offset + symbol->section->vma))); - l++; - } - } - } - else - { - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s %s %s", - symbol->section->name, - coffsymbol(symbol)->native ? "n" : "g", - coffsymbol(symbol)->lineno ? "l" : " ", - symbol->name); - } - } -} - -/* Provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. */ - -/*ARGSUSED*/ -boolean -coff_find_nearest_line (abfd, section, ignore_symbols, offset, filename_ptr, - functionname_ptr, line_ptr) - bfd *abfd; - asection *section; - asymbol **ignore_symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - static bfd *cache_abfd; - static asection *cache_section; - static bfd_vma cache_offset; - static unsigned int cache_i; - static CONST char *cache_function; - static unsigned int line_base = 0; - - unsigned int i = 0; - coff_data_type *cof = coff_data(abfd); - /* Run through the raw syments if available */ - combined_entry_type *p; - alent *l; - - - *filename_ptr = 0; - *functionname_ptr = 0; - *line_ptr = 0; - - /* Don't try and find line numbers in a non coff file */ - if (abfd->xvec->flavour != bfd_target_coff_flavour) - return false; - - if (cof == NULL) - return false; - - p = cof->raw_syments; - - for (i = 0; i < cof->raw_syment_count; i++) { - if (p->u.syment.n_sclass == C_FILE) { - /* File name has been moved into symbol */ - *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; - break; - } - p += 1 + p->u.syment.n_numaux; - } - /* Now wander though the raw linenumbers of the section */ - /* - If this is the same BFD as we were previously called with and this is - the same section, and the offset we want is further down then we can - prime the lookup loop - */ - if (abfd == cache_abfd && - section == cache_section && - offset >= cache_offset) { - i = cache_i; - *functionname_ptr = cache_function; - } - else { - i = 0; - } - l = §ion->lineno[i]; - - for (; i < section->lineno_count; i++) { - if (l->line_number == 0) { - /* Get the symbol this line number points at */ - coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); - if (coff->symbol.value > offset) - break; - *functionname_ptr = coff->symbol.name; - if (coff->native) { - combined_entry_type *s = coff->native; - s = s + 1 + s->u.syment.n_numaux; - /* - S should now point to the .bf of the function - */ - if (s->u.syment.n_numaux) { - /* - The linenumber is stored in the auxent - */ - union internal_auxent *a = &((s + 1)->u.auxent); - line_base = a->x_sym.x_misc.x_lnsz.x_lnno; - *line_ptr = line_base; - } - } - } - else { - if (l->u.offset > offset) - break; - *line_ptr = l->line_number + line_base - 1; - } - l++; - } - - cache_abfd = abfd; - cache_section = section; - cache_offset = offset; - cache_i = i; - cache_function = *functionname_ptr; - - return true; -} - -int -coff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - size_t size; - - if (reloc == false) { - size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); - } - else { - size = bfd_coff_filhsz (abfd); - } - - size += abfd->section_count * bfd_coff_scnhsz (abfd); - return size; -} diff --git a/gnu/usr.bin/gdb/bfd/coffswap.h b/gnu/usr.bin/gdb/bfd/coffswap.h deleted file mode 100644 index f047a9a..0000000 --- a/gnu/usr.bin/gdb/bfd/coffswap.h +++ /dev/null @@ -1,741 +0,0 @@ -/* Generic COFF swapping routines, for BFD. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This file contains routines used to swap COFF data. It is a header - file because the details of swapping depend on the details of the - structures used by each COFF implementation. This is included by - coffcode.h, as well as by the ECOFF backend. - - Any file which uses this must first include "coff/internal.h" and - "coff/CPU.h". The functions will then be correct for that CPU. */ - -#define PUTWORD bfd_h_put_32 -#define PUTHALF bfd_h_put_16 -#define PUTBYTE bfd_h_put_8 - -#ifndef GET_FCN_LNNOPTR -#define GET_FCN_LNNOPTR(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif - -#ifndef GET_FCN_ENDNDX -#define GET_FCN_ENDNDX(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif - -#ifndef PUT_FCN_LNNOPTR -#define PUT_FCN_LNNOPTR(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr) -#endif -#ifndef PUT_FCN_ENDNDX -#define PUT_FCN_ENDNDX(abfd, in, ext) PUTWORD(abfd, in, (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx) -#endif -#ifndef GET_LNSZ_LNNO -#define GET_LNSZ_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef GET_LNSZ_SIZE -#define GET_LNSZ_SIZE(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef PUT_LNSZ_LNNO -#define PUT_LNSZ_LNNO(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno) -#endif -#ifndef PUT_LNSZ_SIZE -#define PUT_LNSZ_SIZE(abfd, in, ext) bfd_h_put_16(abfd, in, (bfd_byte*) ext->x_sym.x_misc.x_lnsz.x_size) -#endif -#ifndef GET_SCN_SCNLEN -#define GET_SCN_SCNLEN(abfd, ext) bfd_h_get_32(abfd, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef GET_SCN_NRELOC -#define GET_SCN_NRELOC(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef GET_SCN_NLINNO -#define GET_SCN_NLINNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *)ext->x_scn.x_nlinno) -#endif -#ifndef PUT_SCN_SCNLEN -#define PUT_SCN_SCNLEN(abfd,in, ext) bfd_h_put_32(abfd, in, (bfd_byte *) ext->x_scn.x_scnlen) -#endif -#ifndef PUT_SCN_NRELOC -#define PUT_SCN_NRELOC(abfd,in, ext) bfd_h_put_16(abfd, in, (bfd_byte *)ext->x_scn.x_nreloc) -#endif -#ifndef PUT_SCN_NLINNO -#define PUT_SCN_NLINNO(abfd,in, ext) bfd_h_put_16(abfd,in, (bfd_byte *) ext->x_scn.x_nlinno) -#endif -#ifndef GET_LINENO_LNNO -#define GET_LINENO_LNNO(abfd, ext) bfd_h_get_16(abfd, (bfd_byte *) (ext->l_lnno)); -#endif -#ifndef PUT_LINENO_LNNO -#define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_16(abfd,val, (bfd_byte *) (ext->l_lnno)); -#endif - -/* The f_symptr field in the filehdr is sometimes 64 bits. */ -#ifndef GET_FILEHDR_SYMPTR -#define GET_FILEHDR_SYMPTR bfd_h_get_32 -#endif -#ifndef PUT_FILEHDR_SYMPTR -#define PUT_FILEHDR_SYMPTR bfd_h_put_32 -#endif - -/* Some fields in the aouthdr are sometimes 64 bits. */ -#ifndef GET_AOUTHDR_TSIZE -#define GET_AOUTHDR_TSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TSIZE -#define PUT_AOUTHDR_TSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DSIZE -#define GET_AOUTHDR_DSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DSIZE -#define PUT_AOUTHDR_DSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_BSIZE -#define GET_AOUTHDR_BSIZE bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_BSIZE -#define PUT_AOUTHDR_BSIZE bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_ENTRY -#define GET_AOUTHDR_ENTRY bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_ENTRY -#define PUT_AOUTHDR_ENTRY bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_TEXT_START -#define GET_AOUTHDR_TEXT_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_TEXT_START -#define PUT_AOUTHDR_TEXT_START bfd_h_put_32 -#endif -#ifndef GET_AOUTHDR_DATA_START -#define GET_AOUTHDR_DATA_START bfd_h_get_32 -#endif -#ifndef PUT_AOUTHDR_DATA_START -#define PUT_AOUTHDR_DATA_START bfd_h_put_32 -#endif - -/* Some fields in the scnhdr are sometimes 64 bits. */ -#ifndef GET_SCNHDR_PADDR -#define GET_SCNHDR_PADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_PADDR -#define PUT_SCNHDR_PADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_VADDR -#define GET_SCNHDR_VADDR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_VADDR -#define PUT_SCNHDR_VADDR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SIZE -#define GET_SCNHDR_SIZE bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SIZE -#define PUT_SCNHDR_SIZE bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_SCNPTR -#define GET_SCNHDR_SCNPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_SCNPTR -#define PUT_SCNHDR_SCNPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_RELPTR -#define GET_SCNHDR_RELPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_RELPTR -#define PUT_SCNHDR_RELPTR bfd_h_put_32 -#endif -#ifndef GET_SCNHDR_LNNOPTR -#define GET_SCNHDR_LNNOPTR bfd_h_get_32 -#endif -#ifndef PUT_SCNHDR_LNNOPTR -#define PUT_SCNHDR_LNNOPTR bfd_h_put_32 -#endif - -#ifndef NO_COFF_RELOCS - -static void -bfd_swap_reloc_in (abfd, reloc_src, reloc_dst) - bfd *abfd; - RELOC *reloc_src; - struct internal_reloc *reloc_dst; -{ - reloc_dst->r_vaddr = bfd_h_get_32(abfd, (bfd_byte *)reloc_src->r_vaddr); - reloc_dst->r_symndx = bfd_h_get_signed_32(abfd, (bfd_byte *) reloc_src->r_symndx); - -#ifdef RS6000COFF_C - reloc_dst->r_type = bfd_h_get_8(abfd, reloc_src->r_type); - reloc_dst->r_size = bfd_h_get_8(abfd, reloc_src->r_size); -#else - reloc_dst->r_type = bfd_h_get_16(abfd, (bfd_byte *) reloc_src->r_type); -#endif - -#ifdef SWAP_IN_RELOC_OFFSET - reloc_dst->r_offset = SWAP_IN_RELOC_OFFSET(abfd, - (bfd_byte *) reloc_src->r_offset); -#endif -} - - -static unsigned int -coff_swap_reloc_out (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - struct internal_reloc *reloc_src = (struct internal_reloc *)src; - struct external_reloc *reloc_dst = (struct external_reloc *)dst; - bfd_h_put_32(abfd, reloc_src->r_vaddr, (bfd_byte *) reloc_dst->r_vaddr); - bfd_h_put_32(abfd, reloc_src->r_symndx, (bfd_byte *) reloc_dst->r_symndx); - -#ifdef RS6000COFF_C - bfd_h_put_8 (abfd, reloc_src->r_type, (bfd_byte *) reloc_dst->r_type); - bfd_h_put_8 (abfd, reloc_src->r_size, (bfd_byte *) reloc_dst->r_size); -#else - bfd_h_put_16(abfd, reloc_src->r_type, (bfd_byte *) - reloc_dst->r_type); -#endif - -#ifdef SWAP_OUT_RELOC_OFFSET - SWAP_OUT_RELOC_OFFSET(abfd, - reloc_src->r_offset, - (bfd_byte *) reloc_dst->r_offset); -#endif -#ifdef SWAP_OUT_RELOC_EXTRA - SWAP_OUT_RELOC_EXTRA(abfd,reloc_src, reloc_dst); -#endif - - return sizeof(struct external_reloc); -} - -#endif /* NO_COFF_RELOCS */ - -static void -coff_swap_filehdr_in (abfd, src, dst) - bfd *abfd; - PTR src; - PTR dst; -{ - FILHDR *filehdr_src = (FILHDR *) src; - struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst; - filehdr_dst->f_magic = bfd_h_get_16(abfd, (bfd_byte *) filehdr_src->f_magic); - filehdr_dst->f_nscns = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_nscns); - filehdr_dst->f_timdat = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_timdat); - filehdr_dst->f_symptr = - GET_FILEHDR_SYMPTR (abfd, (bfd_byte *) filehdr_src->f_symptr); - filehdr_dst->f_nsyms = bfd_h_get_32(abfd, (bfd_byte *)filehdr_src-> f_nsyms); - filehdr_dst->f_opthdr = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_opthdr); - filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); -} - -static unsigned int -coff_swap_filehdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_filehdr *filehdr_in = (struct internal_filehdr *)in; - FILHDR *filehdr_out = (FILHDR *)out; - bfd_h_put_16(abfd, filehdr_in->f_magic, (bfd_byte *) filehdr_out->f_magic); - bfd_h_put_16(abfd, filehdr_in->f_nscns, (bfd_byte *) filehdr_out->f_nscns); - bfd_h_put_32(abfd, filehdr_in->f_timdat, (bfd_byte *) filehdr_out->f_timdat); - PUT_FILEHDR_SYMPTR (abfd, (bfd_vma) filehdr_in->f_symptr, - (bfd_byte *) filehdr_out->f_symptr); - bfd_h_put_32(abfd, filehdr_in->f_nsyms, (bfd_byte *) filehdr_out->f_nsyms); - bfd_h_put_16(abfd, filehdr_in->f_opthdr, (bfd_byte *) filehdr_out->f_opthdr); - bfd_h_put_16(abfd, filehdr_in->f_flags, (bfd_byte *) filehdr_out->f_flags); - return sizeof(FILHDR); -} - - -#ifndef NO_COFF_SYMBOLS - -static void -coff_swap_sym_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - SYMENT *ext = (SYMENT *)ext1; - struct internal_syment *in = (struct internal_syment *)in1; - - if( ext->e.e_name[0] == 0) { - in->_n._n_n._n_zeroes = 0; - in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN); -#endif - } - in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); - in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2){ - in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type); - } - else { - in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type); - } - in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass); - in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux); -} - -static unsigned int -coff_swap_sym_out (abfd, inp, extp) - bfd *abfd; - PTR inp; - PTR extp; -{ - struct internal_syment *in = (struct internal_syment *)inp; - SYMENT *ext =(SYMENT *)extp; - if(in->_n._n_name[0] == 0) { - bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes); - bfd_h_put_32(abfd, in->_n._n_n._n_offset, (bfd_byte *) ext->e.e.e_offset); - } - else { -#if SYMNMLEN != E_SYMNMLEN - -> Error, we need to cope with truncating or extending SYMNMLEN!; -#else - memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN); -#endif - } - bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value); - bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum); - if (sizeof(ext->e_type) == 2) - { - bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - else - { - bfd_h_put_32(abfd, in->n_type , (bfd_byte *) ext->e_type); - } - bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass); - bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux); - return sizeof(SYMENT); -} - -static void -coff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1) - bfd *abfd; - PTR ext1; - int type; - int class; - int indx; - int numaux; - PTR in1; -{ - AUXENT *ext = (AUXENT *)ext1; - union internal_auxent *in = (union internal_auxent *)in1; - - switch (class) { - case C_FILE: - if (ext->x_file.x_fname[0] == 0) { - in->x_file.x_n.x_zeroes = 0; - in->x_file.x_n.x_offset = - bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset); - } else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN); -#endif - } - return; - - /* RS/6000 "csect" auxents */ -#ifdef RS6000COFF_C - case C_EXT: - case C_HIDEXT: - if (indx + 1 == numaux) - { - in->x_csect.x_scnlen.l = bfd_h_get_32 (abfd, ext->x_csect.x_scnlen); - in->x_csect.x_parmhash = bfd_h_get_32 (abfd, - ext->x_csect.x_parmhash); - in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash); - /* We don't have to hack bitfields in x_smtyp because it's - defined by shifts-and-ands, which are equivalent on all - byte orders. */ - in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp); - in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas); - in->x_csect.x_stab = bfd_h_get_32 (abfd, ext->x_csect.x_stab); - in->x_csect.x_snstab = bfd_h_get_16 (abfd, ext->x_csect.x_snstab); - return; - } - break; -#endif - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - in->x_scn.x_scnlen = GET_SCN_SCNLEN(abfd, ext); - in->x_scn.x_nreloc = GET_SCN_NRELOC(abfd, ext); - in->x_scn.x_nlinno = GET_SCN_NLINNO(abfd, ext); - return; - } - break; - } - - in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (ISARY(type)) { -#if DIMNUM != E_DIMNUM - -> Error, we need to cope with truncating or extending DIMNUM!; -#else - in->x_sym.x_fcnary.x_ary.x_dimen[0] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - in->x_sym.x_fcnary.x_ary.x_dimen[1] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - in->x_sym.x_fcnary.x_ary.x_dimen[2] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - in->x_sym.x_fcnary.x_ary.x_dimen[3] = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]); -#endif - } - if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR(abfd, ext); - in->x_sym.x_fcnary.x_fcn.x_endndx.l = GET_FCN_ENDNDX(abfd, ext); - } - - if (ISFCN(type)) { - in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize); - } - else { - in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO(abfd, ext); - in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE(abfd, ext); - } -} - -static unsigned int -coff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp) - bfd *abfd; - PTR inp; - int type; - int class; - int indx; - int numaux; - PTR extp; -{ - union internal_auxent *in = (union internal_auxent *)inp; - AUXENT *ext = (AUXENT *)extp; - - memset((PTR)ext, 0, AUXESZ); - switch (class) { - case C_FILE: - if (in->x_file.x_fname[0] == 0) { - PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes); - PUTWORD(abfd, - in->x_file.x_n.x_offset, - (bfd_byte *) ext->x_file.x_n.x_offset); - } - else { -#if FILNMLEN != E_FILNMLEN - -> Error, we need to cope with truncating or extending FILNMLEN!; -#else - memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN); -#endif - } - return sizeof (AUXENT); - -#ifdef RS6000COFF_C - /* RS/6000 "csect" auxents */ - case C_EXT: - case C_HIDEXT: - if (indx + 1 == numaux) - { - PUTWORD (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen); - PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash); - PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash); - /* We don't have to hack bitfields in x_smtyp because it's - defined by shifts-and-ands, which are equivalent on all - byte orders. */ - PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp); - PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas); - PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab); - PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab); - return sizeof (AUXENT); - } - break; -#endif - - case C_STAT: -#ifdef C_LEAFSTAT - case C_LEAFSTAT: -#endif - case C_HIDDEN: - if (type == T_NULL) { - PUT_SCN_SCNLEN(abfd, in->x_scn.x_scnlen, ext); - PUT_SCN_NRELOC(abfd, in->x_scn.x_nreloc, ext); - PUT_SCN_NLINNO(abfd, in->x_scn.x_nlinno, ext); - return sizeof (AUXENT); - } - break; - } - - PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); -#ifndef NO_TVNDX - bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); -#endif - - if (class == C_BLOCK || ISFCN(type) || ISTAG(class)) { - PUT_FCN_LNNOPTR(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, ext); - PUT_FCN_ENDNDX(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, ext); - } - - if (ISFCN(type)) { - PUTWORD(abfd, in->x_sym.x_misc.x_fsize, (bfd_byte *) ext->x_sym.x_misc.x_fsize); - } - else { - if (ISARY(type)) { -#if DIMNUM != E_DIMNUM - -> Error, we need to cope with truncating or extending DIMNUM!; -#else - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - bfd_h_put_16(abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], (bfd_byte *)ext->x_sym.x_fcnary.x_ary.x_dimen[3]); -#endif - } - PUT_LNSZ_LNNO(abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext); - PUT_LNSZ_SIZE(abfd, in->x_sym.x_misc.x_lnsz.x_size, ext); - } - return sizeof(AUXENT); -} - -#endif /* NO_COFF_SYMBOLS */ - -#ifndef NO_COFF_LINENOS - -static void -coff_swap_lineno_in (abfd, ext1, in1) - bfd *abfd; - PTR ext1; - PTR in1; -{ - LINENO *ext = (LINENO *)ext1; - struct internal_lineno *in = (struct internal_lineno *)in1; - - in->l_addr.l_symndx = bfd_h_get_32(abfd, (bfd_byte *) ext->l_addr.l_symndx); - in->l_lnno = GET_LINENO_LNNO(abfd, ext); -} - -static unsigned int -coff_swap_lineno_out (abfd, inp, outp) - bfd *abfd; - PTR inp; - PTR outp; -{ - struct internal_lineno *in = (struct internal_lineno *)inp; - struct external_lineno *ext = (struct external_lineno *)outp; - PUTWORD(abfd, in->l_addr.l_symndx, (bfd_byte *) - ext->l_addr.l_symndx); - - PUT_LINENO_LNNO (abfd, in->l_lnno, ext); - return sizeof(struct external_lineno); -} - -#endif /* NO_COFF_LINENOS */ - - -static void -coff_swap_aouthdr_in (abfd, aouthdr_ext1, aouthdr_int1) - bfd *abfd; - PTR aouthdr_ext1; - PTR aouthdr_int1; -{ - AOUTHDR *aouthdr_ext = (AOUTHDR *) aouthdr_ext1; - struct internal_aouthdr *aouthdr_int = (struct internal_aouthdr *)aouthdr_int1; - - aouthdr_int->magic = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->magic); - aouthdr_int->vstamp = bfd_h_get_16(abfd, (bfd_byte *) aouthdr_ext->vstamp); - aouthdr_int->tsize = - GET_AOUTHDR_TSIZE (abfd, (bfd_byte *) aouthdr_ext->tsize); - aouthdr_int->dsize = - GET_AOUTHDR_DSIZE (abfd, (bfd_byte *) aouthdr_ext->dsize); - aouthdr_int->bsize = - GET_AOUTHDR_BSIZE (abfd, (bfd_byte *) aouthdr_ext->bsize); - aouthdr_int->entry = - GET_AOUTHDR_ENTRY (abfd, (bfd_byte *) aouthdr_ext->entry); - aouthdr_int->text_start = - GET_AOUTHDR_TEXT_START (abfd, (bfd_byte *) aouthdr_ext->text_start); - aouthdr_int->data_start = - GET_AOUTHDR_DATA_START (abfd, (bfd_byte *) aouthdr_ext->data_start); - -#ifdef I960 - aouthdr_int->tagentries = bfd_h_get_32(abfd, (bfd_byte *) aouthdr_ext->tagentries); -#endif - -#ifdef APOLLO_M68 - bfd_h_put_32(abfd, aouthdr_int->o_inlib, (bfd_byte *) aouthdr_ext->o_inlib); - bfd_h_put_32(abfd, aouthdr_int->o_sri, (bfd_byte *) aouthdr_ext->o_sri); - bfd_h_put_32(abfd, aouthdr_int->vid[0], (bfd_byte *) aouthdr_ext->vid); - bfd_h_put_32(abfd, aouthdr_int->vid[1], (bfd_byte *) aouthdr_ext->vid + 4); -#endif - - -#ifdef RS6000COFF_C - aouthdr_int->o_toc = bfd_h_get_32(abfd, aouthdr_ext->o_toc); - aouthdr_int->o_snentry = bfd_h_get_16(abfd, aouthdr_ext->o_snentry); - aouthdr_int->o_sntext = bfd_h_get_16(abfd, aouthdr_ext->o_sntext); - aouthdr_int->o_sndata = bfd_h_get_16(abfd, aouthdr_ext->o_sndata); - aouthdr_int->o_sntoc = bfd_h_get_16(abfd, aouthdr_ext->o_sntoc); - aouthdr_int->o_snloader = bfd_h_get_16(abfd, aouthdr_ext->o_snloader); - aouthdr_int->o_snbss = bfd_h_get_16(abfd, aouthdr_ext->o_snbss); - aouthdr_int->o_algntext = bfd_h_get_16(abfd, aouthdr_ext->o_algntext); - aouthdr_int->o_algndata = bfd_h_get_16(abfd, aouthdr_ext->o_algndata); - aouthdr_int->o_modtype = bfd_h_get_16(abfd, aouthdr_ext->o_modtype); - aouthdr_int->o_maxstack = bfd_h_get_32(abfd, aouthdr_ext->o_maxstack); -#endif - -#ifdef MIPSECOFF - aouthdr_int->bss_start = bfd_h_get_32(abfd, aouthdr_ext->bss_start); - aouthdr_int->gp_value = bfd_h_get_32(abfd, aouthdr_ext->gp_value); - aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask); - aouthdr_int->cprmask[0] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[0]); - aouthdr_int->cprmask[1] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[1]); - aouthdr_int->cprmask[2] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[2]); - aouthdr_int->cprmask[3] = bfd_h_get_32(abfd, aouthdr_ext->cprmask[3]); -#endif - -#ifdef ALPHAECOFF - aouthdr_int->bss_start = bfd_h_get_64(abfd, aouthdr_ext->bss_start); - aouthdr_int->gp_value = bfd_h_get_64(abfd, aouthdr_ext->gp_value); - aouthdr_int->gprmask = bfd_h_get_32(abfd, aouthdr_ext->gprmask); - aouthdr_int->fprmask = bfd_h_get_32(abfd, aouthdr_ext->fprmask); -#endif -} - -static unsigned int -coff_swap_aouthdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *)in; - AOUTHDR *aouthdr_out = (AOUTHDR *)out; - - bfd_h_put_16(abfd, aouthdr_in->magic, (bfd_byte *) aouthdr_out->magic); - bfd_h_put_16(abfd, aouthdr_in->vstamp, (bfd_byte *) aouthdr_out->vstamp); - PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, (bfd_byte *) aouthdr_out->tsize); - PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, (bfd_byte *) aouthdr_out->dsize); - PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, (bfd_byte *) aouthdr_out->bsize); - PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, (bfd_byte *) aouthdr_out->entry); - PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start, - (bfd_byte *) aouthdr_out->text_start); - PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start, - (bfd_byte *) aouthdr_out->data_start); -#ifdef I960 - bfd_h_put_32(abfd, aouthdr_in->tagentries, (bfd_byte *) aouthdr_out->tagentries); -#endif - -#ifdef MIPSECOFF - bfd_h_put_32(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start); - bfd_h_put_32(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value); - bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask); - bfd_h_put_32(abfd, aouthdr_in->cprmask[0], (bfd_byte *) aouthdr_out->cprmask[0]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[1], (bfd_byte *) aouthdr_out->cprmask[1]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[2], (bfd_byte *) aouthdr_out->cprmask[2]); - bfd_h_put_32(abfd, aouthdr_in->cprmask[3], (bfd_byte *) aouthdr_out->cprmask[3]); -#endif - -#ifdef ALPHAECOFF - /* FIXME: What does bldrev mean? */ - bfd_h_put_16(abfd, (bfd_vma) 2, (bfd_byte *) aouthdr_out->bldrev); - bfd_h_put_16(abfd, (bfd_vma) 0, (bfd_byte *) aouthdr_out->padding); - bfd_h_put_64(abfd, aouthdr_in->bss_start, (bfd_byte *) aouthdr_out->bss_start); - bfd_h_put_64(abfd, aouthdr_in->gp_value, (bfd_byte *) aouthdr_out->gp_value); - bfd_h_put_32(abfd, aouthdr_in->gprmask, (bfd_byte *) aouthdr_out->gprmask); - bfd_h_put_32(abfd, aouthdr_in->fprmask, (bfd_byte *) aouthdr_out->fprmask); -#endif - - return sizeof(AOUTHDR); -} - -static void -coff_swap_scnhdr_in (abfd, ext, in) - bfd *abfd; - PTR ext; - PTR in; -{ - SCNHDR *scnhdr_ext = (SCNHDR *) ext; - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in; - - memcpy(scnhdr_int->s_name, scnhdr_ext->s_name, sizeof(scnhdr_int->s_name)); - scnhdr_int->s_vaddr = - GET_SCNHDR_VADDR (abfd, (bfd_byte *) scnhdr_ext->s_vaddr); - scnhdr_int->s_paddr = - GET_SCNHDR_PADDR (abfd, (bfd_byte *) scnhdr_ext->s_paddr); - scnhdr_int->s_size = - GET_SCNHDR_SIZE (abfd, (bfd_byte *) scnhdr_ext->s_size); - - scnhdr_int->s_scnptr = - GET_SCNHDR_SCNPTR (abfd, (bfd_byte *) scnhdr_ext->s_scnptr); - scnhdr_int->s_relptr = - GET_SCNHDR_RELPTR (abfd, (bfd_byte *) scnhdr_ext->s_relptr); - scnhdr_int->s_lnnoptr = - GET_SCNHDR_LNNOPTR (abfd, (bfd_byte *) scnhdr_ext->s_lnnoptr); - scnhdr_int->s_flags = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_flags); -#if defined(M88) - scnhdr_int->s_nreloc = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); -#else - scnhdr_int->s_nreloc = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nreloc); - scnhdr_int->s_nlnno = bfd_h_get_16(abfd, (bfd_byte *) scnhdr_ext->s_nlnno); -#endif -#ifdef I960 - scnhdr_int->s_align = bfd_h_get_32(abfd, (bfd_byte *) scnhdr_ext->s_align); -#endif -} - -static unsigned int -coff_swap_scnhdr_out (abfd, in, out) - bfd *abfd; - PTR in; - PTR out; -{ - struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *)in; - SCNHDR *scnhdr_ext = (SCNHDR *)out; - - memcpy(scnhdr_ext->s_name, scnhdr_int->s_name, sizeof(scnhdr_int->s_name)); - PUT_SCNHDR_VADDR (abfd, scnhdr_int->s_vaddr, - (bfd_byte *) scnhdr_ext->s_vaddr); - PUT_SCNHDR_PADDR (abfd, scnhdr_int->s_paddr, - (bfd_byte *) scnhdr_ext->s_paddr); - PUT_SCNHDR_SIZE (abfd, scnhdr_int->s_size, - (bfd_byte *) scnhdr_ext->s_size); - PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr, - (bfd_byte *) scnhdr_ext->s_scnptr); - PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr, - (bfd_byte *) scnhdr_ext->s_relptr); - PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr, - (bfd_byte *) scnhdr_ext->s_lnnoptr); - PUTWORD(abfd, scnhdr_int->s_flags, (bfd_byte *) scnhdr_ext->s_flags); -#if defined(M88) - PUTWORD(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - PUTWORD(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); -#else - PUTHALF(abfd, scnhdr_int->s_nlnno, (bfd_byte *) scnhdr_ext->s_nlnno); - PUTHALF(abfd, scnhdr_int->s_nreloc, (bfd_byte *) scnhdr_ext->s_nreloc); -#endif - -#if defined(I960) - PUTWORD(abfd, scnhdr_int->s_align, (bfd_byte *) scnhdr_ext->s_align); -#endif - return sizeof(SCNHDR); -} diff --git a/gnu/usr.bin/gdb/bfd/config.h b/gnu/usr.bin/gdb/bfd/config.h new file mode 100644 index 0000000..e039382 --- /dev/null +++ b/gnu/usr.bin/gdb/bfd/config.h @@ -0,0 +1,68 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Whether malloc must be declared even if <stdlib.h> is included. */ +/* #undef NEED_DECLARATION_MALLOC */ + +/* Whether free must be declared even if <stdlib.h> is included. */ +/* #undef NEED_DECLARATION_FREE */ + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Do we need to use the b modifier when opening binary files? */ +/* #undef USE_BINARY_FOPEN */ + +/* Name of host specific header file to include in trad-core.c. */ +#define TRAD_HEADER "i386freebsd.h" + +/* Define only if <sys/procfs.h> is available *and* it defines prstatus_t. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Do we really want to use mmap if it's available? */ +/* #undef USE_MMAP */ + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the madvise function. */ +#define HAVE_MADVISE 1 + +/* Define if you have the mprotect function. */ +#define HAVE_MPROTECT 1 + +/* Define if you have the valloc function. */ +#define HAVE_VALLOC 1 + +/* Define if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the <stddef.h> header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the <sys/file.h> header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 diff --git a/gnu/usr.bin/gdb/bfd/core.c b/gnu/usr.bin/gdb/bfd/core.c deleted file mode 100644 index 5d88a49..0000000 --- a/gnu/usr.bin/gdb/bfd/core.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Core file generic interface routines for BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - Core files - -DESCRIPTION - These are functions pertaining to core files. -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* -FUNCTION - bfd_core_file_failing_command - -SYNOPSIS - CONST char *bfd_core_file_failing_command(bfd *abfd); - -DESCRIPTION - Return a read-only string explaining which program was running - when it failed and produced the core file @var{abfd}. - -*/ - -CONST char * -bfd_core_file_failing_command (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - return BFD_SEND (abfd, _core_file_failing_command, (abfd)); -} - -/* -FUNCTION - bfd_core_file_failing_signal - -SYNOPSIS - int bfd_core_file_failing_signal(bfd *abfd); - -DESCRIPTION - Returns the signal number which caused the core dump which - generated the file the BFD @var{abfd} is attached to. -*/ - -int -bfd_core_file_failing_signal (abfd) - bfd *abfd; -{ - if (abfd->format != bfd_core) { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - return BFD_SEND (abfd, _core_file_failing_signal, (abfd)); -} - - -/* -FUNCTION - core_file_matches_executable_p - -SYNOPSIS - boolean core_file_matches_executable_p - (bfd *core_bfd, bfd *exec_bfd); - -DESCRIPTION - Return <<true>> if the core file attached to @var{core_bfd} - was generated by a run of the executable file attached to - @var{exec_bfd}, <<false>> otherwise. -*/ -boolean -core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) { - bfd_set_error (bfd_error_wrong_format); - return false; - } - - return BFD_SEND (core_bfd, _core_file_matches_executable_p, - (core_bfd, exec_bfd)); -} diff --git a/gnu/usr.bin/gdb/bfd/cpu-i386.c b/gnu/usr.bin/gdb/bfd/cpu-i386.c deleted file mode 100644 index bf67df2..0000000 --- a/gnu/usr.bin/gdb/bfd/cpu-i386.c +++ /dev/null @@ -1,44 +0,0 @@ -/* BFD support for the Intel 386 architecture. - Copyright 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static bfd_arch_info_type arch_info_struct = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - 0, /* only 1 machine */ - "i386", - "i386", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; - -void -bfd_i386_arch () -{ - bfd_arch_linkin(&arch_info_struct); -} diff --git a/gnu/usr.bin/gdb/bfd/ctor.c b/gnu/usr.bin/gdb/bfd/ctor.c deleted file mode 100644 index c9c2e32..0000000 --- a/gnu/usr.bin/gdb/bfd/ctor.c +++ /dev/null @@ -1,155 +0,0 @@ -/* BFD library support routines for constructors - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - - Hacked by Steve Chamberlain of Cygnus Support. With some help from - Judy Chamberlain too. - - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - Constructors - - Classes in C++ have @dfn{constructors} and @dfn{destructors}. These - are functions which are called automatically by the language - whenever data of a class is created or destroyed. Class data - which is static may also be have a type which requires - `construction'; the contructor must be called before the data - can be referenced, so the contructor must be called before the - program begins. - - The common solution to this problem is for the compiler to - call a magic function as the first statement before <<main>>. - This magic function (often called <<__main>>) runs around - calling the constructors for all the things needing it. - - With COFF, the compiler has a bargain with the linker et al. - All constructors are given strange names; for example, - <<__GLOBAL__$I$foo>> might be the label of a contructor for - the class @var{foo}. The solution on unfortunate systems - (most System V machines) is to perform a partial link on all - the <<.o>> files, do an <<nm>> on the result, run <<awk>> or some - such over the result looking for strange <<__GLOBAL__$>> - symbols, generate a C program from this, compile it, and link - with the partially linked input. This process is usually - called <<collect>>. - - Some versions of <<a.out>> use something called the - <<set_vector>> mechanism. The constructor symbols are output - from the compiler with a special stab code saying that they - are constructors, and the linker can deal with them directly. - - BFD allows applications (i.e., the linker) to deal with - constructor information independently of their external - implementation by providing a set of entry points for the - indiviual object back ends to call to maintain a database - of the contructor information. The application can - interrogate the database to find out what it wants. The - construction data essential for the linker to be able to - perform its job are: - - o asymbol - - The asymbol of the contructor entry point contains all the - information necessary to call the function. - - o table id - - The type of symbol, i.e., is it a constructor, a destructor or - something else someone dreamed up to make our lives difficult. - - The constructor module takes this information and builds extra - sections attached to the BFDs which own the entry points. It - creates these sections as if they were tables of pointers to - the entry points, and builds relocation entries to go with - them so that the tables can be relocated along with the data - they reference. - - These sections are marked with a special bit - (<<SEC_CONSTRUCTOR>>), which the linker notices and does with - what it wants. - -*/ - -#include <bfd.h> -#include <sysdep.h> -#include <libbfd.h> - - - -/* -INTERNAL_FUNCTION - bfd_constructor_entry - -SYNOPSIS - boolean bfd_constructor_entry(bfd *abfd, - asymbol **symbol_ptr_ptr, - CONST char*type); - - -DESCRIPTION - @var{symbol_ptr_ptr} describes the - function to be called; @var{type} descibes the xtor type, - e.g., something like "CTOR" or "DTOR" would be fine. @var{abfd} - is the BFD which owns the function. Create a section - called "CTOR" or "DTOR" or whatever if the BFD doesn't already - have one, and grow a relocation table for the entry points as - they accumulate. - - Return <<true>> if successful, <<false>> if out of memory. - -*/ - - -boolean -bfd_constructor_entry (abfd, symbol_ptr_ptr, type) - bfd *abfd; - asymbol **symbol_ptr_ptr; - CONST char *type; -{ - /* Look up the section we're using to store the table in */ - asection *rel_section = bfd_get_section_by_name (abfd, type); - if (rel_section == (asection *)NULL) { - rel_section = bfd_make_section (abfd, type); - rel_section->flags = SEC_CONSTRUCTOR; - rel_section->alignment_power = 2; - } - - /* Create a relocation into the section which references the entry - point */ - { - arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, - sizeof(arelent_chain)); - if (!reloc) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - -/* reloc->relent.section = (asection *)NULL;*/ - reloc->relent.addend = 0; - - reloc->relent.sym_ptr_ptr = symbol_ptr_ptr; - reloc->next = rel_section->constructor_chain; - rel_section->constructor_chain = reloc; - reloc->relent.address = rel_section->_cooked_size; - /* ask the cpu which howto to use */ - reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR); - rel_section->_cooked_size += sizeof(int *); - rel_section->reloc_count++; - } - return true; -} diff --git a/gnu/usr.bin/gdb/bfd/ecoff.c b/gnu/usr.bin/gdb/bfd/ecoff.c deleted file mode 100644 index ca71e7e..0000000 --- a/gnu/usr.bin/gdb/bfd/ecoff.c +++ /dev/null @@ -1,4953 +0,0 @@ -/* Generic ECOFF (Extended-COFF) routines. - Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Original version by Per Bothner. - Full support added by Ian Lance Taylor, ian@cygnus.com. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "aout/ar.h" -#include "aout/ranlib.h" - -/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines - some other stuff which we don't want and which conflicts with stuff - we do want. */ -#include "libaout.h" -#include "aout/aout64.h" -#undef N_ABS -#undef exec_hdr -#undef obj_sym_filepos - -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" -#include "libcoff.h" -#include "libecoff.h" - -/* Prototypes for static functions. */ - -static int ecoff_get_magic PARAMS ((bfd *abfd)); -static long ecoff_sec_to_styp_flags PARAMS ((const char *name, - flagword flags)); -static boolean ecoff_slurp_symbolic_header PARAMS ((bfd *abfd)); -static boolean ecoff_set_symbol_info PARAMS ((bfd *abfd, SYMR *ecoff_sym, - asymbol *asym, int ext, - asymbol **indirect_ptr_ptr)); -static void ecoff_emit_aggregate PARAMS ((bfd *abfd, FDR *fdr, - char *string, - RNDXR *rndx, long isym, - const char *which)); -static char *ecoff_type_to_string PARAMS ((bfd *abfd, FDR *fdr, - unsigned int indx)); -static boolean ecoff_slurp_reloc_table PARAMS ((bfd *abfd, asection *section, - asymbol **symbols)); -static void ecoff_compute_section_file_positions PARAMS ((bfd *abfd)); -static bfd_size_type ecoff_compute_reloc_file_positions PARAMS ((bfd *abfd)); -static boolean ecoff_get_extr PARAMS ((asymbol *, EXTR *)); -static void ecoff_set_index PARAMS ((asymbol *, bfd_size_type)); -static unsigned int ecoff_armap_hash PARAMS ((CONST char *s, - unsigned int *rehash, - unsigned int size, - unsigned int hlog)); - -/* This stuff is somewhat copied from coffcode.h. */ - -static asection bfd_debug_section = { "*DEBUG*" }; - -/* Create an ECOFF object. */ - -boolean -_bfd_ecoff_mkobject (abfd) - bfd *abfd; -{ - abfd->tdata.ecoff_obj_data = ((struct ecoff_tdata *) - bfd_zalloc (abfd, sizeof (ecoff_data_type))); - if (abfd->tdata.ecoff_obj_data == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - return true; -} - -/* This is a hook called by coff_real_object_p to create any backend - specific information. */ - -PTR -_bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr) - bfd *abfd; - PTR filehdr; - PTR aouthdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr; - ecoff_data_type *ecoff; - - if (_bfd_ecoff_mkobject (abfd) == false) - return NULL; - - ecoff = ecoff_data (abfd); - ecoff->gp_size = 8; - ecoff->sym_filepos = internal_f->f_symptr; - - if (internal_a != (struct internal_aouthdr *) NULL) - { - int i; - - ecoff->text_start = internal_a->text_start; - ecoff->text_end = internal_a->text_start + internal_a->tsize; - ecoff->gp = internal_a->gp_value; - ecoff->gprmask = internal_a->gprmask; - for (i = 0; i < 4; i++) - ecoff->cprmask[i] = internal_a->cprmask[i]; - ecoff->fprmask = internal_a->fprmask; - if (internal_a->magic == ECOFF_AOUT_ZMAGIC) - abfd->flags |= D_PAGED; - } - - /* It turns out that no special action is required by the MIPS or - Alpha ECOFF backends. They have different information in the - a.out header, but we just copy it all (e.g., gprmask, cprmask and - fprmask) and let the swapping routines ensure that only relevant - information is written out. */ - - return (PTR) ecoff; -} - -/* This is a hook needed by SCO COFF, but we have nothing to do. */ - -/*ARGSUSED*/ -asection * -_bfd_ecoff_make_section_hook (abfd, name) - bfd *abfd; - char *name; -{ - return (asection *) NULL; -} - -/* Initialize a new section. */ - -boolean -_bfd_ecoff_new_section_hook (abfd, section) - bfd *abfd; - asection *section; -{ - /* For the .pdata section, which has a special meaning on the Alpha, - we set the alignment to 8. We correct this later in - ecoff_compute_section_file_positions. We do this hackery because - we need to know the exact unaligned size of the .pdata section in - order to set the lnnoptr field correctly. */ - if (strcmp (section->name, _PDATA) == 0) - section->alignment_power = 3; - else - section->alignment_power = abfd->xvec->align_power_min; - - if (strcmp (section->name, _TEXT) == 0) - section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - else if (strcmp (section->name, _DATA) == 0 - || strcmp (section->name, _SDATA) == 0) - section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - else if (strcmp (section->name, _RDATA) == 0 - || strcmp (section->name, _LIT8) == 0 - || strcmp (section->name, _LIT4) == 0) - section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; - else if (strcmp (section->name, _BSS) == 0 - || strcmp (section->name, _SBSS) == 0) - section->flags |= SEC_ALLOC; - else if (strcmp (section->name, _LIB) == 0) - { - /* An Irix 4 shared libary. */ - section->flags |= SEC_COFF_SHARED_LIBRARY; - } - - /* Probably any other section name is SEC_NEVER_LOAD, but I'm - uncertain about .init on some systems and I don't know how shared - libraries work. */ - - return true; -} - -/* Determine the machine architecture and type. This is called from - the generic COFF routines. It is the inverse of ecoff_get_magic, - below. This could be an ECOFF backend routine, with one version - for each target, but there aren't all that many ECOFF targets. */ - -boolean -_bfd_ecoff_set_arch_mach_hook (abfd, filehdr) - bfd *abfd; - PTR filehdr; -{ - struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr; - enum bfd_architecture arch; - unsigned long mach; - - switch (internal_f->f_magic) - { - case MIPS_MAGIC_1: - case MIPS_MAGIC_LITTLE: - case MIPS_MAGIC_BIG: - arch = bfd_arch_mips; - mach = 3000; - break; - - case MIPS_MAGIC_LITTLE2: - case MIPS_MAGIC_BIG2: - /* MIPS ISA level 2: the r6000 */ - arch = bfd_arch_mips; - mach = 6000; - break; - - case MIPS_MAGIC_LITTLE3: - case MIPS_MAGIC_BIG3: - /* MIPS ISA level 3: the r4000 */ - arch = bfd_arch_mips; - mach = 4000; - break; - - case ALPHA_MAGIC: - arch = bfd_arch_alpha; - mach = 0; - break; - - default: - arch = bfd_arch_obscure; - mach = 0; - break; - } - - return bfd_default_set_arch_mach (abfd, arch, mach); -} - -/* Get the magic number to use based on the architecture and machine. - This is the inverse of _bfd_ecoff_set_arch_mach_hook, above. */ - -static int -ecoff_get_magic (abfd) - bfd *abfd; -{ - int big, little; - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_mips: - switch (bfd_get_mach (abfd)) - { - default: - case 0: - case 3000: - big = MIPS_MAGIC_BIG; - little = MIPS_MAGIC_LITTLE; - break; - - case 6000: - big = MIPS_MAGIC_BIG2; - little = MIPS_MAGIC_LITTLE2; - break; - - case 4000: - big = MIPS_MAGIC_BIG3; - little = MIPS_MAGIC_LITTLE3; - break; - } - - return abfd->xvec->byteorder_big_p ? big : little; - - case bfd_arch_alpha: - return ALPHA_MAGIC; - - default: - abort (); - return 0; - } -} - -/* Get the section s_flags to use for a section. */ - -static long -ecoff_sec_to_styp_flags (name, flags) - const char *name; - flagword flags; -{ - long styp; - - styp = 0; - - if (strcmp (name, _TEXT) == 0) - styp = STYP_TEXT; - else if (strcmp (name, _DATA) == 0) - styp = STYP_DATA; - else if (strcmp (name, _SDATA) == 0) - styp = STYP_SDATA; - else if (strcmp (name, _RDATA) == 0) - styp = STYP_RDATA; - else if (strcmp (name, _LITA) == 0) - styp = STYP_LITA; - else if (strcmp (name, _LIT8) == 0) - styp = STYP_LIT8; - else if (strcmp (name, _LIT4) == 0) - styp = STYP_LIT4; - else if (strcmp (name, _BSS) == 0) - styp = STYP_BSS; - else if (strcmp (name, _SBSS) == 0) - styp = STYP_SBSS; - else if (strcmp (name, _INIT) == 0) - styp = STYP_ECOFF_INIT; - else if (strcmp (name, _FINI) == 0) - styp = STYP_ECOFF_FINI; - else if (strcmp (name, _PDATA) == 0) - styp = STYP_PDATA; - else if (strcmp (name, _XDATA) == 0) - styp = STYP_XDATA; - else if (strcmp (name, _LIB) == 0) - styp = STYP_ECOFF_LIB; - else if (flags & SEC_CODE) - styp = STYP_TEXT; - else if (flags & SEC_DATA) - styp = STYP_DATA; - else if (flags & SEC_READONLY) - styp = STYP_RDATA; - else if (flags & SEC_LOAD) - styp = STYP_REG; - else - styp = STYP_BSS; - - if (flags & SEC_NEVER_LOAD) - styp |= STYP_NOLOAD; - - return styp; -} - -/* Get the BFD flags to use for a section. */ - -/*ARGSUSED*/ -flagword -_bfd_ecoff_styp_to_sec_flags (abfd, hdr) - bfd *abfd; - PTR hdr; -{ - struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr; - long styp_flags = internal_s->s_flags; - flagword sec_flags=0; - - if (styp_flags & STYP_NOLOAD) - sec_flags |= SEC_NEVER_LOAD; - - /* For 386 COFF, at least, an unloadable text or data section is - actually a shared library section. */ - if ((styp_flags & STYP_TEXT) - || (styp_flags & STYP_ECOFF_INIT) - || (styp_flags & STYP_ECOFF_FINI)) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC; - } - else if ((styp_flags & STYP_DATA) - || (styp_flags & STYP_RDATA) - || (styp_flags & STYP_SDATA) - || styp_flags == STYP_PDATA - || styp_flags == STYP_XDATA) - { - if (sec_flags & SEC_NEVER_LOAD) - sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY; - else - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC; - if ((styp_flags & STYP_RDATA) - || styp_flags == STYP_PDATA) - sec_flags |= SEC_READONLY; - } - else if ((styp_flags & STYP_BSS) - || (styp_flags & STYP_SBSS)) - { - sec_flags |= SEC_ALLOC; - } - else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT) - { - sec_flags |= SEC_NEVER_LOAD; - } - else if ((styp_flags & STYP_LITA) - || (styp_flags & STYP_LIT8) - || (styp_flags & STYP_LIT4)) - { - sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY; - } - else if (styp_flags & STYP_ECOFF_LIB) - { - sec_flags |= SEC_COFF_SHARED_LIBRARY; - } - else - { - sec_flags |= SEC_ALLOC | SEC_LOAD; - } - - return sec_flags; -} - -/* Routines to swap auxiliary information in and out. I am assuming - that the auxiliary information format is always going to be target - independent. */ - -/* Swap in a type information record. - BIGEND says whether AUX symbols are big-endian or little-endian; this - info comes from the file header record (fh-fBigendian). */ - -void -_bfd_ecoff_swap_tir_in (bigend, ext_copy, intern) - int bigend; - const struct tir_ext *ext_copy; - TIR *intern; -{ - struct tir_ext ext[1]; - - *ext = *ext_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG); - intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG); - intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG) - >> TIR_BITS1_BT_SH_BIG; - intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG) - >> TIR_BITS_TQ4_SH_BIG; - intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG) - >> TIR_BITS_TQ5_SH_BIG; - intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG) - >> TIR_BITS_TQ0_SH_BIG; - intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG) - >> TIR_BITS_TQ1_SH_BIG; - intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG) - >> TIR_BITS_TQ2_SH_BIG; - intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG) - >> TIR_BITS_TQ3_SH_BIG; - } else { - intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE); - intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE); - intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE) - >> TIR_BITS1_BT_SH_LITTLE; - intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE) - >> TIR_BITS_TQ4_SH_LITTLE; - intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE) - >> TIR_BITS_TQ5_SH_LITTLE; - intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE) - >> TIR_BITS_TQ0_SH_LITTLE; - intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE) - >> TIR_BITS_TQ1_SH_LITTLE; - intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE) - >> TIR_BITS_TQ2_SH_LITTLE; - intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE) - >> TIR_BITS_TQ3_SH_LITTLE; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a type information record. - BIGEND says whether AUX symbols are big-endian or little-endian; this - info comes from the file header record (fh-fBigendian). */ - -void -_bfd_ecoff_swap_tir_out (bigend, intern_copy, ext) - int bigend; - const TIR *intern_copy; - struct tir_ext *ext; -{ - TIR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0) - | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0) - | ((intern->bt << TIR_BITS1_BT_SH_BIG) - & TIR_BITS1_BT_BIG)); - ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG) - & TIR_BITS_TQ4_BIG) - | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG) - & TIR_BITS_TQ5_BIG)); - ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG) - & TIR_BITS_TQ0_BIG) - | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG) - & TIR_BITS_TQ1_BIG)); - ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG) - & TIR_BITS_TQ2_BIG) - | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG) - & TIR_BITS_TQ3_BIG)); - } else { - ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0) - | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0) - | ((intern->bt << TIR_BITS1_BT_SH_LITTLE) - & TIR_BITS1_BT_LITTLE)); - ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE) - & TIR_BITS_TQ4_LITTLE) - | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE) - & TIR_BITS_TQ5_LITTLE)); - ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE) - & TIR_BITS_TQ0_LITTLE) - | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE) - & TIR_BITS_TQ1_LITTLE)); - ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE) - & TIR_BITS_TQ2_LITTLE) - | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE) - & TIR_BITS_TQ3_LITTLE)); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap in a relative symbol record. BIGEND says whether it is in - big-endian or little-endian format.*/ - -void -_bfd_ecoff_swap_rndx_in (bigend, ext_copy, intern) - int bigend; - const struct rndx_ext *ext_copy; - RNDXR *intern; -{ - struct rndx_ext ext[1]; - - *ext = *ext_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG) - | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG) - >> RNDX_BITS1_RFD_SH_BIG); - intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG) - << RNDX_BITS1_INDEX_SH_LEFT_BIG) - | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG) - | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG); - } else { - intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE) - | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE) - << RNDX_BITS1_RFD_SH_LEFT_LITTLE); - intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE) - >> RNDX_BITS1_INDEX_SH_LITTLE) - | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE) - | ((unsigned int) ext->r_bits[3] - << RNDX_BITS3_INDEX_SH_LEFT_LITTLE); - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Swap out a relative symbol record. BIGEND says whether it is in - big-endian or little-endian format.*/ - -void -_bfd_ecoff_swap_rndx_out (bigend, intern_copy, ext) - int bigend; - const RNDXR *intern_copy; - struct rndx_ext *ext; -{ - RNDXR intern[1]; - - *intern = *intern_copy; /* Make it reasonable to do in-place. */ - - /* now the fun stuff... */ - if (bigend) { - ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG; - ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG) - & RNDX_BITS1_RFD_BIG) - | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG) - & RNDX_BITS1_INDEX_BIG)); - ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG; - ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG; - } else { - ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE; - ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE) - & RNDX_BITS1_RFD_LITTLE) - | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE) - & RNDX_BITS1_INDEX_LITTLE)); - ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE; - ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE; - } - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort(); -#endif -} - -/* Read in the symbolic header for an ECOFF object file. */ - -static boolean -ecoff_slurp_symbolic_header (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - bfd_size_type external_hdr_size; - PTR raw = NULL; - HDRR *internal_symhdr; - - /* See if we've already read it in. */ - if (ecoff_data (abfd)->debug_info.symbolic_header.magic == - backend->debug_swap.sym_magic) - return true; - - /* See whether there is a symbolic header. */ - if (ecoff_data (abfd)->sym_filepos == 0) - { - bfd_get_symcount (abfd) = 0; - return true; - } - - /* At this point bfd_get_symcount (abfd) holds the number of symbols - as read from the file header, but on ECOFF this is always the - size of the symbolic information header. It would be cleaner to - handle this when we first read the file in coffgen.c. */ - external_hdr_size = backend->debug_swap.external_hdr_size; - if (bfd_get_symcount (abfd) != external_hdr_size) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Read the symbolic information header. */ - raw = (PTR) malloc ((size_t) external_hdr_size); - if (raw == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) == -1 - || (bfd_read (raw, external_hdr_size, 1, abfd) - != external_hdr_size)) - goto error_return; - internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr); - - if (internal_symhdr->magic != backend->debug_swap.sym_magic) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - /* Now we can get the correct number of symbols. */ - bfd_get_symcount (abfd) = (internal_symhdr->isymMax - + internal_symhdr->iextMax); - - if (raw != NULL) - free (raw); - return true; - error_return: - if (raw != NULL) - free (raw); - return false; -} - -/* Read in and swap the important symbolic information for an ECOFF - object file. This is called by gdb via the read_debug_info entry - point in the backend structure. */ - -/*ARGSUSED*/ -boolean -_bfd_ecoff_slurp_symbolic_info (abfd, ignore, debug) - bfd *abfd; - asection *ignore; - struct ecoff_debug_info *debug; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - HDRR *internal_symhdr; - bfd_size_type raw_base; - bfd_size_type raw_size; - PTR raw; - bfd_size_type external_fdr_size; - char *fraw_src; - char *fraw_end; - struct fdr *fdr_ptr; - bfd_size_type raw_end; - bfd_size_type cb_end; - - BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info); - - /* Check whether we've already gotten it, and whether there's any to - get. */ - if (ecoff_data (abfd)->raw_syments != (PTR) NULL) - return true; - if (ecoff_data (abfd)->sym_filepos == 0) - { - bfd_get_symcount (abfd) = 0; - return true; - } - - if (! ecoff_slurp_symbolic_header (abfd)) - return false; - - internal_symhdr = &debug->symbolic_header; - - /* Read all the symbolic information at once. */ - raw_base = (ecoff_data (abfd)->sym_filepos - + backend->debug_swap.external_hdr_size); - - /* Alpha ecoff makes the determination of raw_size difficult. It has - an undocumented debug data section between the symhdr and the first - documented section. And the ordering of the sections varies between - statically and dynamically linked executables. - If bfd supports SEEK_END someday, this code could be simplified. */ - - raw_end = 0; - -#define UPDATE_RAW_END(start, count, size) \ - cb_end = internal_symhdr->start + internal_symhdr->count * (size); \ - if (cb_end > raw_end) \ - raw_end = cb_end - - UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char)); - UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size); - UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size); - UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size); - UPDATE_RAW_END (cbOptOffset, ioptMax, backend->debug_swap.external_opt_size); - UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext)); - UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char)); - UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char)); - UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size); - UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size); - UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size); - -#undef UPDATE_RAW_END - - raw_size = raw_end - raw_base; - if (raw_size == 0) - { - ecoff_data (abfd)->sym_filepos = 0; - return true; - } - raw = (PTR) bfd_alloc (abfd, raw_size); - if (raw == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (bfd_seek (abfd, - (ecoff_data (abfd)->sym_filepos - + backend->debug_swap.external_hdr_size), - SEEK_SET) != 0 - || bfd_read (raw, raw_size, 1, abfd) != raw_size) - { - bfd_release (abfd, raw); - return false; - } - - ecoff_data (abfd)->raw_syments = raw; - - /* Get pointers for the numeric offsets in the HDRR structure. */ -#define FIX(off1, off2, type) \ - if (internal_symhdr->off1 == 0) \ - debug->off2 = (type) NULL; \ - else \ - debug->off2 = (type) ((char *) raw \ - + internal_symhdr->off1 \ - - raw_base) - FIX (cbLineOffset, line, unsigned char *); - FIX (cbDnOffset, external_dnr, PTR); - FIX (cbPdOffset, external_pdr, PTR); - FIX (cbSymOffset, external_sym, PTR); - FIX (cbOptOffset, external_opt, PTR); - FIX (cbAuxOffset, external_aux, union aux_ext *); - FIX (cbSsOffset, ss, char *); - FIX (cbSsExtOffset, ssext, char *); - FIX (cbFdOffset, external_fdr, PTR); - FIX (cbRfdOffset, external_rfd, PTR); - FIX (cbExtOffset, external_ext, PTR); -#undef FIX - - /* I don't want to always swap all the data, because it will just - waste time and most programs will never look at it. The only - time the linker needs most of the debugging information swapped - is when linking big-endian and little-endian MIPS object files - together, which is not a common occurrence. - - We need to look at the fdr to deal with a lot of information in - the symbols, so we swap them here. */ - debug->fdr = (struct fdr *) bfd_alloc (abfd, - (internal_symhdr->ifdMax * - sizeof (struct fdr))); - if (debug->fdr == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - external_fdr_size = backend->debug_swap.external_fdr_size; - fdr_ptr = debug->fdr; - fraw_src = (char *) debug->external_fdr; - fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size; - for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) - (*backend->debug_swap.swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); - - return true; -} - -/* ECOFF symbol table routines. The ECOFF symbol table is described - in gcc/mips-tfile.c. */ - -/* ECOFF uses two common sections. One is the usual one, and the - other is for small objects. All the small objects are kept - together, and then referenced via the gp pointer, which yields - faster assembler code. This is what we use for the small common - section. */ -static asection ecoff_scom_section; -static asymbol ecoff_scom_symbol; -static asymbol *ecoff_scom_symbol_ptr; - -/* Create an empty symbol. */ - -asymbol * -_bfd_ecoff_make_empty_symbol (abfd) - bfd *abfd; -{ - ecoff_symbol_type *new; - - new = (ecoff_symbol_type *) bfd_alloc (abfd, sizeof (ecoff_symbol_type)); - if (new == (ecoff_symbol_type *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (asymbol *) NULL; - } - memset ((PTR) new, 0, sizeof *new); - new->symbol.section = (asection *) NULL; - new->fdr = (FDR *) NULL; - new->local = false; - new->native = NULL; - new->symbol.the_bfd = abfd; - return &new->symbol; -} - -/* Set the BFD flags and section for an ECOFF symbol. */ - -static boolean -ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, indirect_ptr_ptr) - bfd *abfd; - SYMR *ecoff_sym; - asymbol *asym; - int ext; - asymbol **indirect_ptr_ptr; -{ - asym->the_bfd = abfd; - asym->value = ecoff_sym->value; - asym->section = &bfd_debug_section; - asym->udata = NULL; - - /* An indirect symbol requires two consecutive stabs symbols. */ - if (*indirect_ptr_ptr != (asymbol *) NULL) - { - BFD_ASSERT (ECOFF_IS_STAB (ecoff_sym)); - - /* @@ Stuffing pointers into integers is a no-no. - We can usually get away with it if the integer is - large enough though. */ - if (sizeof (asym) > sizeof (bfd_vma)) - abort (); - (*indirect_ptr_ptr)->value = (bfd_vma) asym; - - asym->flags = BSF_DEBUGGING; - asym->section = bfd_und_section_ptr; - *indirect_ptr_ptr = NULL; - return true; - } - - if (ECOFF_IS_STAB (ecoff_sym) - && (ECOFF_UNMARK_STAB (ecoff_sym->index) | N_EXT) == (N_INDR | N_EXT)) - { - asym->flags = BSF_DEBUGGING | BSF_INDIRECT; - asym->section = bfd_ind_section_ptr; - /* Pass this symbol on to the next call to this function. */ - *indirect_ptr_ptr = asym; - return true; - } - - /* Most symbol types are just for debugging. */ - switch (ecoff_sym->st) - { - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - break; - case stNil: - if (ECOFF_IS_STAB (ecoff_sym)) - { - asym->flags = BSF_DEBUGGING; - return true; - } - break; - default: - asym->flags = BSF_DEBUGGING; - return true; - } - - if (ext) - asym->flags = BSF_EXPORT | BSF_GLOBAL; - else - asym->flags = BSF_LOCAL; - switch (ecoff_sym->sc) - { - case scNil: - /* Used for compiler generated labels. Leave them in the - debugging section, and mark them as local. If BSF_DEBUGGING - is set, then nm does not display them for some reason. If no - flags are set then the linker whines about them. */ - asym->flags = BSF_LOCAL; - break; - case scText: - asym->section = bfd_make_section_old_way (abfd, ".text"); - asym->value -= asym->section->vma; - break; - case scData: - asym->section = bfd_make_section_old_way (abfd, ".data"); - asym->value -= asym->section->vma; - break; - case scBss: - asym->section = bfd_make_section_old_way (abfd, ".bss"); - asym->value -= asym->section->vma; - break; - case scRegister: - asym->flags = BSF_DEBUGGING; - break; - case scAbs: - asym->section = bfd_abs_section_ptr; - break; - case scUndefined: - asym->section = bfd_und_section_ptr; - asym->flags = 0; - asym->value = 0; - break; - case scCdbLocal: - case scBits: - case scCdbSystem: - case scRegImage: - case scInfo: - case scUserStruct: - asym->flags = BSF_DEBUGGING; - break; - case scSData: - asym->section = bfd_make_section_old_way (abfd, ".sdata"); - asym->value -= asym->section->vma; - break; - case scSBss: - asym->section = bfd_make_section_old_way (abfd, ".sbss"); - asym->value -= asym->section->vma; - break; - case scRData: - asym->section = bfd_make_section_old_way (abfd, ".rdata"); - asym->value -= asym->section->vma; - break; - case scVar: - asym->flags = BSF_DEBUGGING; - break; - case scCommon: - if (asym->value > ecoff_data (abfd)->gp_size) - { - asym->section = bfd_com_section_ptr; - asym->flags = 0; - break; - } - /* Fall through. */ - case scSCommon: - if (ecoff_scom_section.name == NULL) - { - /* Initialize the small common section. */ - ecoff_scom_section.name = SCOMMON; - ecoff_scom_section.flags = SEC_IS_COMMON; - ecoff_scom_section.output_section = &ecoff_scom_section; - ecoff_scom_section.symbol = &ecoff_scom_symbol; - ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; - ecoff_scom_symbol.name = SCOMMON; - ecoff_scom_symbol.flags = BSF_SECTION_SYM; - ecoff_scom_symbol.section = &ecoff_scom_section; - ecoff_scom_symbol_ptr = &ecoff_scom_symbol; - } - asym->section = &ecoff_scom_section; - asym->flags = 0; - break; - case scVarRegister: - case scVariant: - asym->flags = BSF_DEBUGGING; - break; - case scSUndefined: - asym->section = bfd_und_section_ptr; - asym->flags = 0; - asym->value = 0; - break; - case scInit: - asym->section = bfd_make_section_old_way (abfd, ".init"); - asym->value -= asym->section->vma; - break; - case scBasedVar: - case scXData: - case scPData: - asym->flags = BSF_DEBUGGING; - break; - case scFini: - asym->section = bfd_make_section_old_way (abfd, ".fini"); - asym->value -= asym->section->vma; - break; - default: - break; - } - - /* Look for special constructors symbols and make relocation entries - in a special construction section. These are produced by the - -fgnu-linker argument to g++. */ - if (ECOFF_IS_STAB (ecoff_sym)) - { - switch (ECOFF_UNMARK_STAB (ecoff_sym->index)) - { - default: - break; - - case N_SETA: - case N_SETT: - case N_SETD: - case N_SETB: - { - const char *name; - asection *section; - arelent_chain *reloc_chain; - unsigned int bitsize; - - /* Get a section with the same name as the symbol (usually - __CTOR_LIST__ or __DTOR_LIST__). FIXME: gcc uses the - name ___CTOR_LIST (three underscores). We need - __CTOR_LIST (two underscores), since ECOFF doesn't use - a leading underscore. This should be handled by gcc, - but instead we do it here. Actually, this should all - be done differently anyhow. */ - name = bfd_asymbol_name (asym); - if (name[0] == '_' && name[1] == '_' && name[2] == '_') - { - ++name; - asym->name = name; - } - section = bfd_get_section_by_name (abfd, name); - if (section == (asection *) NULL) - { - char *copy; - - copy = (char *) bfd_alloc (abfd, strlen (name) + 1); - if (!copy) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - strcpy (copy, name); - section = bfd_make_section (abfd, copy); - } - - /* Build a reloc pointing to this constructor. */ - reloc_chain = - (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain)); - if (!reloc_chain) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - reloc_chain->relent.sym_ptr_ptr = - bfd_get_section (asym)->symbol_ptr_ptr; - reloc_chain->relent.address = section->_raw_size; - reloc_chain->relent.addend = asym->value; - reloc_chain->relent.howto = - ecoff_backend (abfd)->constructor_reloc; - - /* Set up the constructor section to hold the reloc. */ - section->flags = SEC_CONSTRUCTOR; - ++section->reloc_count; - - /* Constructor sections must be rounded to a boundary - based on the bitsize. These are not real sections-- - they are handled specially by the linker--so the ECOFF - 16 byte alignment restriction does not apply. */ - bitsize = ecoff_backend (abfd)->constructor_bitsize; - section->alignment_power = 1; - while ((1 << section->alignment_power) < bitsize / 8) - ++section->alignment_power; - - reloc_chain->next = section->constructor_chain; - section->constructor_chain = reloc_chain; - section->_raw_size += bitsize / 8; - - /* Mark the symbol as a constructor. */ - asym->flags |= BSF_CONSTRUCTOR; - } - break; - } - } - return true; -} - -/* Read an ECOFF symbol table. */ - -boolean -_bfd_ecoff_slurp_symbol_table (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - const bfd_size_type external_ext_size - = backend->debug_swap.external_ext_size; - const bfd_size_type external_sym_size - = backend->debug_swap.external_sym_size; - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = backend->debug_swap.swap_sym_in; - bfd_size_type internal_size; - ecoff_symbol_type *internal; - ecoff_symbol_type *internal_ptr; - asymbol *indirect_ptr; - char *eraw_src; - char *eraw_end; - FDR *fdr_ptr; - FDR *fdr_end; - - /* If we've already read in the symbol table, do nothing. */ - if (ecoff_data (abfd)->canonical_symbols != NULL) - return true; - - /* Get the symbolic information. */ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, - &ecoff_data (abfd)->debug_info)) - return false; - if (bfd_get_symcount (abfd) == 0) - return true; - - internal_size = bfd_get_symcount (abfd) * sizeof (ecoff_symbol_type); - internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size); - if (internal == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - internal_ptr = internal; - indirect_ptr = NULL; - eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext; - eraw_end = (eraw_src - + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax - * external_ext_size)); - for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++) - { - EXTR internal_esym; - - (*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym); - internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext - + internal_esym.asym.iss); - if (!ecoff_set_symbol_info (abfd, &internal_esym.asym, - &internal_ptr->symbol, 1, &indirect_ptr)) - return false; - /* The alpha uses a negative ifd field for section symbols. */ - if (internal_esym.ifd >= 0) - internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr - + internal_esym.ifd); - else - internal_ptr->fdr = NULL; - internal_ptr->local = false; - internal_ptr->native = (PTR) eraw_src; - } - BFD_ASSERT (indirect_ptr == (asymbol *) NULL); - - /* The local symbols must be accessed via the fdr's, because the - string and aux indices are relative to the fdr information. */ - fdr_ptr = ecoff_data (abfd)->debug_info.fdr; - fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax; - for (; fdr_ptr < fdr_end; fdr_ptr++) - { - char *lraw_src; - char *lraw_end; - - lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym - + fdr_ptr->isymBase * external_sym_size); - lraw_end = lraw_src + fdr_ptr->csym * external_sym_size; - for (; - lraw_src < lraw_end; - lraw_src += external_sym_size, internal_ptr++) - { - SYMR internal_sym; - - (*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym); - internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss - + fdr_ptr->issBase - + internal_sym.iss); - if (!ecoff_set_symbol_info (abfd, &internal_sym, - &internal_ptr->symbol, 0, &indirect_ptr)) - return false; - internal_ptr->fdr = fdr_ptr; - internal_ptr->local = true; - internal_ptr->native = (PTR) lraw_src; - } - } - BFD_ASSERT (indirect_ptr == (asymbol *) NULL); - - ecoff_data (abfd)->canonical_symbols = internal; - - return true; -} - -/* Return the amount of space needed for the canonical symbols. */ - -long -_bfd_ecoff_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, - &ecoff_data (abfd)->debug_info)) - return -1; - - if (bfd_get_symcount (abfd) == 0) - return 0; - - return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *)); -} - -/* Get the canonical symbols. */ - -long -_bfd_ecoff_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - unsigned int counter = 0; - ecoff_symbol_type *symbase; - ecoff_symbol_type **location = (ecoff_symbol_type **) alocation; - - if (_bfd_ecoff_slurp_symbol_table (abfd) == false) - return -1; - if (bfd_get_symcount (abfd) == 0) - return 0; - - symbase = ecoff_data (abfd)->canonical_symbols; - while (counter < bfd_get_symcount (abfd)) - { - *(location++) = symbase++; - counter++; - } - *location++ = (ecoff_symbol_type *) NULL; - return bfd_get_symcount (abfd); -} - -/* Turn ECOFF type information into a printable string. - ecoff_emit_aggregate and ecoff_type_to_string are from - gcc/mips-tdump.c, with swapping added and used_ptr removed. */ - -/* Write aggregate information to a string. */ - -static void -ecoff_emit_aggregate (abfd, fdr, string, rndx, isym, which) - bfd *abfd; - FDR *fdr; - char *string; - RNDXR *rndx; - long isym; - const char *which; -{ - const struct ecoff_debug_swap * const debug_swap = - &ecoff_backend (abfd)->debug_swap; - struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info; - unsigned int ifd = rndx->rfd; - unsigned int indx = rndx->index; - const char *name; - - if (ifd == 0xfff) - ifd = isym; - - /* An ifd of -1 is an opaque type. An escaped index of 0 is a - struct return type of a procedure compiled without -g. */ - if (ifd == 0xffffffff - || (rndx->rfd == 0xfff && indx == 0)) - name = "<undefined>"; - else if (indx == indexNil) - name = "<no name>"; - else - { - SYMR sym; - - if (debug_info->external_rfd == NULL) - fdr = debug_info->fdr + ifd; - else - { - RFDT rfd; - - (*debug_swap->swap_rfd_in) (abfd, - ((char *) debug_info->external_rfd - + ((fdr->rfdBase + ifd) - * debug_swap->external_rfd_size)), - &rfd); - fdr = debug_info->fdr + rfd; - } - - indx += fdr->isymBase; - - (*debug_swap->swap_sym_in) (abfd, - ((char *) debug_info->external_sym - + indx * debug_swap->external_sym_size), - &sym); - - name = debug_info->ss + fdr->issBase + sym.iss; - } - - sprintf (string, - "%s %s { ifd = %u, index = %lu }", - which, name, ifd, - ((long) indx - + debug_info->symbolic_header.iextMax)); -} - -/* Convert the type information to string format. */ - -static char * -ecoff_type_to_string (abfd, fdr, indx) - bfd *abfd; - FDR *fdr; - unsigned int indx; -{ - union aux_ext *aux_ptr; - int bigendian; - AUXU u; - struct qual { - unsigned int type; - int low_bound; - int high_bound; - int stride; - } qualifiers[7]; - unsigned int basic_type; - int i; - static char buffer1[1024]; - static char buffer2[1024]; - char *p1 = buffer1; - char *p2 = buffer2; - RNDXR rndx; - - aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase; - bigendian = fdr->fBigendian; - - for (i = 0; i < 7; i++) - { - qualifiers[i].low_bound = 0; - qualifiers[i].high_bound = 0; - qualifiers[i].stride = 0; - } - - if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == -1) - return "-1 (no type)"; - _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti); - - basic_type = u.ti.bt; - qualifiers[0].type = u.ti.tq0; - qualifiers[1].type = u.ti.tq1; - qualifiers[2].type = u.ti.tq2; - qualifiers[3].type = u.ti.tq3; - qualifiers[4].type = u.ti.tq4; - qualifiers[5].type = u.ti.tq5; - qualifiers[6].type = tqNil; - - /* - * Go get the basic type. - */ - switch (basic_type) - { - case btNil: /* undefined */ - strcpy (p1, "nil"); - break; - - case btAdr: /* address - integer same size as pointer */ - strcpy (p1, "address"); - break; - - case btChar: /* character */ - strcpy (p1, "char"); - break; - - case btUChar: /* unsigned character */ - strcpy (p1, "unsigned char"); - break; - - case btShort: /* short */ - strcpy (p1, "short"); - break; - - case btUShort: /* unsigned short */ - strcpy (p1, "unsigned short"); - break; - - case btInt: /* int */ - strcpy (p1, "int"); - break; - - case btUInt: /* unsigned int */ - strcpy (p1, "unsigned int"); - break; - - case btLong: /* long */ - strcpy (p1, "long"); - break; - - case btULong: /* unsigned long */ - strcpy (p1, "unsigned long"); - break; - - case btFloat: /* float (real) */ - strcpy (p1, "float"); - break; - - case btDouble: /* Double (real) */ - strcpy (p1, "double"); - break; - - /* Structures add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to struct def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btStruct: /* Structure (Record) */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "struct"); - indx++; /* skip aux words */ - break; - - /* Unions add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to union def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btUnion: /* Union */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "union"); - indx++; /* skip aux words */ - break; - - /* Enumerations add 1-2 aux words: - 1st word is [ST_RFDESCAPE, offset] pointer to enum def; - 2nd word is file index if 1st word rfd is ST_RFDESCAPE. */ - - case btEnum: /* Enumeration */ - _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx); - ecoff_emit_aggregate (abfd, fdr, p1, &rndx, - (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]), - "enum"); - indx++; /* skip aux words */ - break; - - case btTypedef: /* defined via a typedef, isymRef points */ - strcpy (p1, "typedef"); - break; - - case btRange: /* subrange of int */ - strcpy (p1, "subrange"); - break; - - case btSet: /* pascal sets */ - strcpy (p1, "set"); - break; - - case btComplex: /* fortran complex */ - strcpy (p1, "complex"); - break; - - case btDComplex: /* fortran double complex */ - strcpy (p1, "double complex"); - break; - - case btIndirect: /* forward or unnamed typedef */ - strcpy (p1, "forward/unamed typedef"); - break; - - case btFixedDec: /* Fixed Decimal */ - strcpy (p1, "fixed decimal"); - break; - - case btFloatDec: /* Float Decimal */ - strcpy (p1, "float decimal"); - break; - - case btString: /* Varying Length Character String */ - strcpy (p1, "string"); - break; - - case btBit: /* Aligned Bit String */ - strcpy (p1, "bit"); - break; - - case btPicture: /* Picture */ - strcpy (p1, "picture"); - break; - - case btVoid: /* Void */ - strcpy (p1, "void"); - break; - - default: - sprintf (p1, "Unknown basic type %d", (int) basic_type); - break; - } - - p1 += strlen (buffer1); - - /* - * If this is a bitfield, get the bitsize. - */ - if (u.ti.fBitfield) - { - int bitsize; - - bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]); - sprintf (p1, " : %d", bitsize); - p1 += strlen (buffer1); - } - - - /* - * Deal with any qualifiers. - */ - if (qualifiers[0].type != tqNil) - { - /* - * Snarf up any array bounds in the correct order. Arrays - * store 5 successive words in the aux. table: - * word 0 RNDXR to type of the bounds (ie, int) - * word 1 Current file descriptor index - * word 2 low bound - * word 3 high bound (or -1 if []) - * word 4 stride size in bits - */ - for (i = 0; i < 7; i++) - { - if (qualifiers[i].type == tqArray) - { - qualifiers[i].low_bound = - AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]); - qualifiers[i].high_bound = - AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]); - qualifiers[i].stride = - AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]); - indx += 5; - } - } - - /* - * Now print out the qualifiers. - */ - for (i = 0; i < 6; i++) - { - switch (qualifiers[i].type) - { - case tqNil: - case tqMax: - break; - - case tqPtr: - strcpy (p2, "ptr to "); - p2 += sizeof ("ptr to ")-1; - break; - - case tqVol: - strcpy (p2, "volatile "); - p2 += sizeof ("volatile ")-1; - break; - - case tqFar: - strcpy (p2, "far "); - p2 += sizeof ("far ")-1; - break; - - case tqProc: - strcpy (p2, "func. ret. "); - p2 += sizeof ("func. ret. "); - break; - - case tqArray: - { - int first_array = i; - int j; - - /* Print array bounds reversed (ie, in the order the C - programmer writes them). C is such a fun language.... */ - - while (i < 5 && qualifiers[i+1].type == tqArray) - i++; - - for (j = i; j >= first_array; j--) - { - strcpy (p2, "array ["); - p2 += sizeof ("array [")-1; - if (qualifiers[j].low_bound != 0) - sprintf (p2, - "%ld:%ld {%ld bits}", - (long) qualifiers[j].low_bound, - (long) qualifiers[j].high_bound, - (long) qualifiers[j].stride); - - else if (qualifiers[j].high_bound != -1) - sprintf (p2, - "%ld {%ld bits}", - (long) (qualifiers[j].high_bound + 1), - (long) (qualifiers[j].stride)); - - else - sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride)); - - p2 += strlen (p2); - strcpy (p2, "] of "); - p2 += sizeof ("] of ")-1; - } - } - break; - } - } - } - - strcpy (p2, buffer1); - return buffer2; -} - -/* Return information about ECOFF symbol SYMBOL in RET. */ - -/*ARGSUSED*/ -void -_bfd_ecoff_get_symbol_info (abfd, symbol, ret) - bfd *abfd; /* Ignored. */ - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/* Print information about an ECOFF symbol. */ - -void -_bfd_ecoff_print_symbol (abfd, filep, symbol, how) - bfd *abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - const struct ecoff_debug_swap * const debug_swap - = &ecoff_backend (abfd)->debug_swap; - FILE *file = (FILE *)filep; - - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - if (ecoffsymbol (symbol)->local) - { - SYMR ecoff_sym; - - (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_sym); - fprintf (file, "ecoff local "); - fprintf_vma (file, (bfd_vma) ecoff_sym.value); - fprintf (file, " %x %x", (unsigned) ecoff_sym.st, - (unsigned) ecoff_sym.sc); - } - else - { - EXTR ecoff_ext; - - (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext); - fprintf (file, "ecoff extern "); - fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); - fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st, - (unsigned) ecoff_ext.asym.sc); - } - break; - case bfd_print_symbol_all: - /* Print out the symbols in a reasonable way */ - { - char type; - int pos; - EXTR ecoff_ext; - char jmptbl; - char cobol_main; - char weakext; - - if (ecoffsymbol (symbol)->local) - { - (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext.asym); - type = 'l'; - pos = ((((char *) ecoffsymbol (symbol)->native - - (char *) ecoff_data (abfd)->debug_info.external_sym) - / debug_swap->external_sym_size) - + ecoff_data (abfd)->debug_info.symbolic_header.iextMax); - jmptbl = ' '; - cobol_main = ' '; - weakext = ' '; - } - else - { - (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native, - &ecoff_ext); - type = 'e'; - pos = (((char *) ecoffsymbol (symbol)->native - - (char *) ecoff_data (abfd)->debug_info.external_ext) - / debug_swap->external_ext_size); - jmptbl = ecoff_ext.jmptbl ? 'j' : ' '; - cobol_main = ecoff_ext.cobol_main ? 'c' : ' '; - weakext = ecoff_ext.weakext ? 'w' : ' '; - } - - fprintf (file, "[%3d] %c ", - pos, type); - fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value); - fprintf (file, " st %x sc %x indx %x %c%c%c %s", - (unsigned) ecoff_ext.asym.st, - (unsigned) ecoff_ext.asym.sc, - (unsigned) ecoff_ext.asym.index, - jmptbl, cobol_main, weakext, - symbol->name); - - if (ecoffsymbol (symbol)->fdr != NULL - && ecoff_ext.asym.index != indexNil) - { - FDR *fdr; - unsigned int indx; - int bigendian; - bfd_size_type sym_base; - union aux_ext *aux_base; - - fdr = ecoffsymbol (symbol)->fdr; - indx = ecoff_ext.asym.index; - - /* sym_base is used to map the fdr relative indices which - appear in the file to the position number which we are - using. */ - sym_base = fdr->isymBase; - if (ecoffsymbol (symbol)->local) - sym_base += - ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - - /* aux_base is the start of the aux entries for this file; - asym.index is an offset from this. */ - aux_base = (ecoff_data (abfd)->debug_info.external_aux - + fdr->iauxBase); - - /* The aux entries are stored in host byte order; the - order is indicated by a bit in the fdr. */ - bigendian = fdr->fBigendian; - - /* This switch is basically from gcc/mips-tdump.c */ - switch (ecoff_ext.asym.st) - { - case stNil: - case stLabel: - break; - - case stFile: - case stBlock: - fprintf (file, "\n End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stEnd: - if (ecoff_ext.asym.sc == scText - || ecoff_ext.asym.sc == scInfo) - fprintf (file, "\n First symbol: %ld", - (long) (indx + sym_base)); - else - fprintf (file, "\n First symbol: %ld", - ((long) - (AUX_GET_ISYM (bigendian, - &aux_base[ecoff_ext.asym.index]) - + sym_base))); - break; - - case stProc: - case stStaticProc: - if (ECOFF_IS_STAB (&ecoff_ext.asym)) - ; - else if (ecoffsymbol (symbol)->local) - fprintf (file, "\n End+1 symbol: %-7ld Type: %s", - ((long) - (AUX_GET_ISYM (bigendian, - &aux_base[ecoff_ext.asym.index]) - + sym_base)), - ecoff_type_to_string (abfd, fdr, indx + 1)); - else - fprintf (file, "\n Local symbol: %ld", - ((long) indx - + (long) sym_base - + (ecoff_data (abfd) - ->debug_info.symbolic_header.iextMax))); - break; - - case stStruct: - fprintf (file, "\n struct; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stUnion: - fprintf (file, "\n union; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - case stEnum: - fprintf (file, "\n enum; End+1 symbol: %ld", - (long) (indx + sym_base)); - break; - - default: - if (! ECOFF_IS_STAB (&ecoff_ext.asym)) - fprintf (file, "\n Type: %s", - ecoff_type_to_string (abfd, fdr, indx)); - break; - } - } - } - break; - } -} - -/* Read in the relocs for a section. */ - -static boolean -ecoff_slurp_reloc_table (abfd, section, symbols) - bfd *abfd; - asection *section; - asymbol **symbols; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - arelent *internal_relocs; - bfd_size_type external_reloc_size; - bfd_size_type external_relocs_size; - char *external_relocs; - arelent *rptr; - unsigned int i; - - if (section->relocation != (arelent *) NULL - || section->reloc_count == 0 - || (section->flags & SEC_CONSTRUCTOR) != 0) - return true; - - if (_bfd_ecoff_slurp_symbol_table (abfd) == false) - return false; - - internal_relocs = (arelent *) bfd_alloc (abfd, - (sizeof (arelent) - * section->reloc_count)); - external_reloc_size = backend->external_reloc_size; - external_relocs_size = external_reloc_size * section->reloc_count; - external_relocs = (char *) bfd_alloc (abfd, external_relocs_size); - if (internal_relocs == (arelent *) NULL - || external_relocs == (char *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0) - return false; - if (bfd_read (external_relocs, 1, external_relocs_size, abfd) - != external_relocs_size) - return false; - - for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++) - { - struct internal_reloc intern; - - (*backend->swap_reloc_in) (abfd, - external_relocs + i * external_reloc_size, - &intern); - - if (intern.r_extern) - { - /* r_symndx is an index into the external symbols. */ - BFD_ASSERT (intern.r_symndx >= 0 - && (intern.r_symndx - < (ecoff_data (abfd) - ->debug_info.symbolic_header.iextMax))); - rptr->sym_ptr_ptr = symbols + intern.r_symndx; - rptr->addend = 0; - } - else if (intern.r_symndx == RELOC_SECTION_NONE - || intern.r_symndx == RELOC_SECTION_ABS) - { - rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - rptr->addend = 0; - } - else - { - CONST char *sec_name; - asection *sec; - - /* r_symndx is a section key. */ - switch (intern.r_symndx) - { - case RELOC_SECTION_TEXT: sec_name = ".text"; break; - case RELOC_SECTION_RDATA: sec_name = ".rdata"; break; - case RELOC_SECTION_DATA: sec_name = ".data"; break; - case RELOC_SECTION_SDATA: sec_name = ".sdata"; break; - case RELOC_SECTION_SBSS: sec_name = ".sbss"; break; - case RELOC_SECTION_BSS: sec_name = ".bss"; break; - case RELOC_SECTION_INIT: sec_name = ".init"; break; - case RELOC_SECTION_LIT8: sec_name = ".lit8"; break; - case RELOC_SECTION_LIT4: sec_name = ".lit4"; break; - case RELOC_SECTION_XDATA: sec_name = ".xdata"; break; - case RELOC_SECTION_PDATA: sec_name = ".pdata"; break; - case RELOC_SECTION_FINI: sec_name = ".fini"; break; - case RELOC_SECTION_LITA: sec_name = ".lita"; break; - default: abort (); - } - - sec = bfd_get_section_by_name (abfd, sec_name); - if (sec == (asection *) NULL) - abort (); - rptr->sym_ptr_ptr = sec->symbol_ptr_ptr; - - rptr->addend = - bfd_get_section_vma (abfd, sec); - } - - rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section); - - /* Let the backend select the howto field and do any other - required processing. */ - (*backend->adjust_reloc_in) (abfd, &intern, rptr); - } - - bfd_release (abfd, external_relocs); - - section->relocation = internal_relocs; - - return true; -} - -/* Get a canonical list of relocs. */ - -long -_bfd_ecoff_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - asection *section; - arelent **relptr; - asymbol **symbols; -{ - unsigned int count; - - if (section->flags & SEC_CONSTRUCTOR) - { - arelent_chain *chain; - - /* This section has relocs made up by us, not the file, so take - them out of their chain and place them into the data area - provided. */ - for (count = 0, chain = section->constructor_chain; - count < section->reloc_count; - count++, chain = chain->next) - *relptr++ = &chain->relent; - } - else - { - arelent *tblptr; - - if (ecoff_slurp_reloc_table (abfd, section, symbols) == false) - return -1; - - tblptr = section->relocation; - - for (count = 0; count < section->reloc_count; count++) - *relptr++ = tblptr++; - } - - *relptr = (arelent *) NULL; - - return section->reloc_count; -} - -/* Provided a BFD, a section and an offset into the section, calculate - and return the name of the source file and the line nearest to the - wanted location. */ - -/*ARGSUSED*/ -boolean -_bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset, - filename_ptr, functionname_ptr, retline_ptr) - bfd *abfd; - asection *section; - asymbol **ignore_symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *retline_ptr; -{ - const struct ecoff_debug_swap * const debug_swap - = &ecoff_backend (abfd)->debug_swap; - FDR *fdr_ptr; - FDR *fdr_start; - FDR *fdr_end; - FDR *fdr_hold; - bfd_size_type external_pdr_size; - char *pdr_ptr; - char *pdr_end; - PDR pdr; - bfd_vma first_off; - unsigned char *line_ptr; - unsigned char *line_end; - int lineno; - - /* If we're not in the .text section, we don't have any line - numbers. */ - if (strcmp (section->name, _TEXT) != 0 - || offset < ecoff_data (abfd)->text_start - || offset >= ecoff_data (abfd)->text_end) - return false; - - /* Make sure we have the FDR's. */ - if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, - &ecoff_data (abfd)->debug_info) - || bfd_get_symcount (abfd) == 0) - return false; - - /* Each file descriptor (FDR) has a memory address. Here we track - down which FDR we want. The FDR's are stored in increasing - memory order. If speed is ever important, this can become a - binary search. We must ignore FDR's with no PDR entries; they - will have the adr of the FDR before or after them. */ - fdr_start = ecoff_data (abfd)->debug_info.fdr; - fdr_end = fdr_start + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax; - fdr_hold = (FDR *) NULL; - for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++) - { - if (fdr_ptr->cpd == 0) - continue; - if (offset < fdr_ptr->adr) - break; - fdr_hold = fdr_ptr; - } - if (fdr_hold == (FDR *) NULL) - return false; - fdr_ptr = fdr_hold; - - /* Each FDR has a list of procedure descriptors (PDR). PDR's also - have an address, which is relative to the FDR address, and are - also stored in increasing memory order. */ - offset -= fdr_ptr->adr; - external_pdr_size = debug_swap->external_pdr_size; - pdr_ptr = ((char *) ecoff_data (abfd)->debug_info.external_pdr - + fdr_ptr->ipdFirst * external_pdr_size); - pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size; - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - if (offset < pdr.adr) - return false; - - /* The address of the first PDR is an offset which applies to the - addresses of all the PDR's. */ - first_off = pdr.adr; - - for (pdr_ptr += external_pdr_size; - pdr_ptr < pdr_end; - pdr_ptr += external_pdr_size) - { - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - if (offset < pdr.adr) - break; - } - - /* Now we can look for the actual line number. The line numbers are - stored in a very funky format, which I won't try to describe. - Note that right here pdr_ptr and pdr hold the PDR *after* the one - we want; we need this to compute line_end. */ - line_end = ecoff_data (abfd)->debug_info.line; - if (pdr_ptr == pdr_end) - line_end += fdr_ptr->cbLineOffset + fdr_ptr->cbLine; - else - line_end += fdr_ptr->cbLineOffset + pdr.cbLineOffset; - - /* Now change pdr and pdr_ptr to the one we want. */ - pdr_ptr -= external_pdr_size; - (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr); - - offset -= pdr.adr - first_off; - lineno = pdr.lnLow; - line_ptr = (ecoff_data (abfd)->debug_info.line - + fdr_ptr->cbLineOffset - + pdr.cbLineOffset); - while (line_ptr < line_end) - { - int delta; - int count; - - delta = *line_ptr >> 4; - if (delta >= 0x8) - delta -= 0x10; - count = (*line_ptr & 0xf) + 1; - ++line_ptr; - if (delta == -8) - { - delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff); - if (delta >= 0x8000) - delta -= 0x10000; - line_ptr += 2; - } - lineno += delta; - if (offset < count * 4) - break; - offset -= count * 4; - } - - /* If fdr_ptr->rss is -1, then this file does not have full symbols, - at least according to gdb/mipsread.c. */ - if (fdr_ptr->rss == -1) - { - *filename_ptr = NULL; - if (pdr.isym == -1) - *functionname_ptr = NULL; - else - { - EXTR proc_ext; - - (*debug_swap->swap_ext_in) - (abfd, - ((char *) ecoff_data (abfd)->debug_info.external_ext - + pdr.isym * debug_swap->external_ext_size), - &proc_ext); - *functionname_ptr = (ecoff_data (abfd)->debug_info.ssext - + proc_ext.asym.iss); - } - } - else - { - SYMR proc_sym; - - *filename_ptr = (ecoff_data (abfd)->debug_info.ss - + fdr_ptr->issBase - + fdr_ptr->rss); - (*debug_swap->swap_sym_in) - (abfd, - ((char *) ecoff_data (abfd)->debug_info.external_sym - + (fdr_ptr->isymBase + pdr.isym) * debug_swap->external_sym_size), - &proc_sym); - *functionname_ptr = (ecoff_data (abfd)->debug_info.ss - + fdr_ptr->issBase - + proc_sym.iss); - } - if (lineno == ilineNil) - lineno = 0; - *retline_ptr = lineno; - return true; -} - -/* Copy private BFD data. This is called by objcopy and strip. We - use it to copy the ECOFF debugging information from one BFD to the - other. It would be theoretically possible to represent the ECOFF - debugging information in the symbol table. However, it would be a - lot of work, and there would be little gain (gas, gdb, and ld - already access the ECOFF debugging information via the - ecoff_debug_info structure, and that structure would have to be - retained in order to support ECOFF debugging in MIPS ELF). - - The debugging information for the ECOFF external symbols comes from - the symbol table, so this function only handles the other debugging - information. */ - -boolean -_bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; -{ - struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info; - struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info; - register int i; - asymbol **sym_ptr_ptr; - size_t c; - boolean local; - - /* This function is selected based on the input vector. We only - want to copy information over if the output BFD also uses ECOFF - format. */ - if (bfd_get_flavour (obfd) != bfd_target_ecoff_flavour) - return true; - - /* Copy the GP value and the register masks. */ - ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp; - ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask; - ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask; - for (i = 0; i < 3; i++) - ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i]; - - /* Copy the version stamp. */ - oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp; - - /* If there are no symbols, don't copy any debugging information. */ - c = bfd_get_symcount (obfd); - sym_ptr_ptr = bfd_get_outsymbols (obfd); - if (c == 0 || sym_ptr_ptr == (asymbol **) NULL) - return true; - - /* See if there are any local symbols. */ - local = false; - for (; c > 0; c--, sym_ptr_ptr++) - { - if (ecoffsymbol (*sym_ptr_ptr)->local) - { - local = true; - break; - } - } - - if (local) - { - /* There are some local symbols. We just bring over all the - debugging information. FIXME: This is not quite the right - thing to do. If the user has asked us to discard all - debugging information, then we are probably going to wind up - keeping it because there will probably be some local symbol - which objcopy did not discard. We should actually break - apart the debugging information and only keep that which - applies to the symbols we want to keep. */ - oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax; - oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine; - oinfo->line = iinfo->line; - - oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax; - oinfo->external_dnr = iinfo->external_dnr; - - oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax; - oinfo->external_pdr = iinfo->external_pdr; - - oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax; - oinfo->external_sym = iinfo->external_sym; - - oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax; - oinfo->external_opt = iinfo->external_opt; - - oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax; - oinfo->external_aux = iinfo->external_aux; - - oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax; - oinfo->ss = iinfo->ss; - - oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax; - oinfo->external_fdr = iinfo->external_fdr; - - oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd; - oinfo->external_rfd = iinfo->external_rfd; - } - else - { - /* We are discarding all the local symbol information. Look - through the external symbols and remove all references to FDR - or aux information. */ - c = bfd_get_symcount (obfd); - sym_ptr_ptr = bfd_get_outsymbols (obfd); - for (; c > 0; c--, sym_ptr_ptr++) - { - EXTR esym; - - (*(ecoff_backend (obfd)->debug_swap.swap_ext_in)) - (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym); - esym.ifd = ifdNil; - esym.asym.index = indexNil; - (*(ecoff_backend (obfd)->debug_swap.swap_ext_out)) - (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native); - } - } - - return true; -} - -/* Set the architecture. The supported architecture is stored in the - backend pointer. We always set the architecture anyhow, since many - callers ignore the return value. */ - -boolean -_bfd_ecoff_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - bfd_default_set_arch_mach (abfd, arch, machine); - return arch == ecoff_backend (abfd)->arch; -} - -/* Get the size of the section headers. */ - -/*ARGSUSED*/ -int -_bfd_ecoff_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - asection *current; - int c; - int ret; - - c = 0; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - ++c; - - ret = (bfd_coff_filhsz (abfd) - + bfd_coff_aoutsz (abfd) - + c * bfd_coff_scnhsz (abfd)); - return BFD_ALIGN (ret, 16); -} - -/* Get the contents of a section. */ - -boolean -_bfd_ecoff_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - return _bfd_generic_get_section_contents (abfd, section, location, - offset, count); -} - -/* Calculate the file position for each section, and set - reloc_filepos. */ - -static void -ecoff_compute_section_file_positions (abfd) - bfd *abfd; -{ - asection *current; - file_ptr sofar; - file_ptr old_sofar; - boolean first_data; - - sofar = _bfd_ecoff_sizeof_headers (abfd, false); - - first_data = true; - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - unsigned int alignment_power; - - /* Only deal with sections which have contents */ - if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) == 0) - continue; - - /* For the Alpha ECOFF .pdata section the lnnoptr field is - supposed to indicate the number of .pdata entries that are - really in the section. Each entry is 8 bytes. We store this - away in line_filepos before increasing the section size. */ - if (strcmp (current->name, _PDATA) != 0) - alignment_power = current->alignment_power; - else - { - current->line_filepos = current->_raw_size / 8; - alignment_power = 4; - } - - /* On Ultrix, the data sections in an executable file must be - aligned to a page boundary within the file. This does not - affect the section size, though. FIXME: Does this work for - other platforms? It requires some modification for the - Alpha, because .rdata on the Alpha goes with the text, not - the data. */ - if ((abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0 - && first_data != false - && (current->flags & SEC_CODE) == 0 - && (! ecoff_backend (abfd)->rdata_in_text - || strcmp (current->name, _RDATA) != 0) - && strcmp (current->name, _PDATA) != 0) - { - const bfd_vma round = ecoff_backend (abfd)->round; - - sofar = (sofar + round - 1) &~ (round - 1); - first_data = false; - } - else if (strcmp (current->name, _LIB) == 0) - { - const bfd_vma round = ecoff_backend (abfd)->round; - /* On Irix 4, the location of contents of the .lib section - from a shared library section is also rounded up to a - page boundary. */ - - sofar = (sofar + round - 1) &~ (round - 1); - } - - /* Align the sections in the file to the same boundary on - which they are aligned in virtual memory. */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << alignment_power); - - current->filepos = sofar; - - sofar += current->_raw_size; - - /* make sure that this section is of the right size too */ - old_sofar = sofar; - sofar = BFD_ALIGN (sofar, 1 << alignment_power); - current->_raw_size += sofar - old_sofar; - } - - ecoff_data (abfd)->reloc_filepos = sofar; -} - -/* Determine the location of the relocs for all the sections in the - output file, as well as the location of the symbolic debugging - information. */ - -static bfd_size_type -ecoff_compute_reloc_file_positions (abfd) - bfd *abfd; -{ - const bfd_size_type external_reloc_size = - ecoff_backend (abfd)->external_reloc_size; - file_ptr reloc_base; - bfd_size_type reloc_size; - asection *current; - file_ptr sym_base; - - if (! abfd->output_has_begun) - { - ecoff_compute_section_file_positions (abfd); - abfd->output_has_begun = true; - } - - reloc_base = ecoff_data (abfd)->reloc_filepos; - - reloc_size = 0; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - { - if (current->reloc_count == 0) - current->rel_filepos = 0; - else - { - bfd_size_type relsize; - - current->rel_filepos = reloc_base; - relsize = current->reloc_count * external_reloc_size; - reloc_size += relsize; - reloc_base += relsize; - } - } - - sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size; - - /* At least on Ultrix, the symbol table of an executable file must - be aligned to a page boundary. FIXME: Is this true on other - platforms? */ - if ((abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0) - sym_base = ((sym_base + ecoff_backend (abfd)->round - 1) - &~ (ecoff_backend (abfd)->round - 1)); - - ecoff_data (abfd)->sym_filepos = sym_base; - - return reloc_size; -} - -/* Set the contents of a section. */ - -boolean -_bfd_ecoff_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - /* This must be done first, because bfd_set_section_contents is - going to set output_has_begun to true. */ - if (abfd->output_has_begun == false) - ecoff_compute_section_file_positions (abfd); - - /* If this is a .lib section, bump the vma address so that it winds - up being the number of .lib sections output. This is right for - Irix 4. Ian Taylor <ian@cygnus.com>. */ - if (strcmp (section->name, _LIB) == 0) - ++section->vma; - - if (count == 0) - return true; - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0 - || bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -/* Get the GP value for an ECOFF file. This is a hook used by - nlmconv. */ - -bfd_vma -bfd_ecoff_get_gp_value (abfd) - bfd *abfd; -{ - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return 0; - } - - return ecoff_data (abfd)->gp; -} - -/* Set the GP value for an ECOFF file. This is a hook used by the - assembler. */ - -boolean -bfd_ecoff_set_gp_value (abfd, gp_value) - bfd *abfd; - bfd_vma gp_value; -{ - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - ecoff_data (abfd)->gp = gp_value; - - return true; -} - -/* Set the register masks for an ECOFF file. This is a hook used by - the assembler. */ - -boolean -bfd_ecoff_set_regmasks (abfd, gprmask, fprmask, cprmask) - bfd *abfd; - unsigned long gprmask; - unsigned long fprmask; - unsigned long *cprmask; -{ - ecoff_data_type *tdata; - - if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour - || bfd_get_format (abfd) != bfd_object) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - tdata = ecoff_data (abfd); - tdata->gprmask = gprmask; - tdata->fprmask = fprmask; - if (cprmask != (unsigned long *) NULL) - { - register int i; - - for (i = 0; i < 3; i++) - tdata->cprmask[i] = cprmask[i]; - } - - return true; -} - -/* Get ECOFF EXTR information for an external symbol. This function - is passed to bfd_ecoff_debug_externals. */ - -static boolean -ecoff_get_extr (sym, esym) - asymbol *sym; - EXTR *esym; -{ - ecoff_symbol_type *ecoff_sym_ptr; - bfd *input_bfd; - - if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour - || ecoffsymbol (sym)->native == NULL) - { - /* Don't include debugging, local, or section symbols. */ - if ((sym->flags & BSF_DEBUGGING) != 0 - || (sym->flags & BSF_LOCAL) != 0 - || (sym->flags & BSF_SECTION_SYM) != 0) - return false; - - esym->jmptbl = 0; - esym->cobol_main = 0; - esym->weakext = 0; - esym->reserved = 0; - esym->ifd = ifdNil; - /* FIXME: we can do better than this for st and sc. */ - esym->asym.st = stGlobal; - esym->asym.sc = scAbs; - esym->asym.reserved = 0; - esym->asym.index = indexNil; - return true; - } - - ecoff_sym_ptr = ecoffsymbol (sym); - - if (ecoff_sym_ptr->local) - return false; - - input_bfd = bfd_asymbol_bfd (sym); - (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in)) - (input_bfd, ecoff_sym_ptr->native, esym); - - /* If the symbol was defined by the linker, then esym will be - undefined but sym will not be. Get a better class for such a - symbol. */ - if ((esym->asym.sc == scUndefined - || esym->asym.sc == scSUndefined) - && ! bfd_is_und_section (bfd_get_section (sym))) - esym->asym.sc = scAbs; - - /* Adjust the FDR index for the symbol by that used for the input - BFD. */ - if (esym->ifd != -1) - { - struct ecoff_debug_info *input_debug; - - input_debug = &ecoff_data (input_bfd)->debug_info; - BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax); - if (input_debug->ifdmap != (RFDT *) NULL) - esym->ifd = input_debug->ifdmap[esym->ifd]; - } - - return true; -} - -/* Set the external symbol index. This routine is passed to - bfd_ecoff_debug_externals. */ - -static void -ecoff_set_index (sym, indx) - asymbol *sym; - bfd_size_type indx; -{ - ecoff_set_sym_index (sym, indx); -} - -/* Write out an ECOFF file. */ - -boolean -_bfd_ecoff_write_object_contents (abfd) - bfd *abfd; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - const bfd_vma round = backend->round; - const bfd_size_type filhsz = bfd_coff_filhsz (abfd); - const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd); - const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd); - const bfd_size_type external_hdr_size - = backend->debug_swap.external_hdr_size; - const bfd_size_type external_reloc_size = backend->external_reloc_size; - void (* const adjust_reloc_out) PARAMS ((bfd *, - const arelent *, - struct internal_reloc *)) - = backend->adjust_reloc_out; - void (* const swap_reloc_out) PARAMS ((bfd *, - const struct internal_reloc *, - PTR)) - = backend->swap_reloc_out; - struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; - HDRR * const symhdr = &debug->symbolic_header; - asection *current; - unsigned int count; - bfd_size_type reloc_size; - bfd_size_type text_size; - bfd_vma text_start; - boolean set_text_start; - bfd_size_type data_size; - bfd_vma data_start; - boolean set_data_start; - bfd_size_type bss_size; - PTR buff = NULL; - PTR reloc_buff = NULL; - struct internal_filehdr internal_f; - struct internal_aouthdr internal_a; - int i; - - /* Determine where the sections and relocs will go in the output - file. */ - reloc_size = ecoff_compute_reloc_file_positions (abfd); - - count = 1; - for (current = abfd->sections; - current != (asection *)NULL; - current = current->next) - { - current->target_index = count; - ++count; - } - - if ((abfd->flags & D_PAGED) != 0) - text_size = _bfd_ecoff_sizeof_headers (abfd, false); - else - text_size = 0; - text_start = 0; - set_text_start = false; - data_size = 0; - data_start = 0; - set_data_start = false; - bss_size = 0; - - /* Write section headers to the file. */ - - /* Allocate buff big enough to hold a section header, - file header, or a.out header. */ - { - bfd_size_type siz; - siz = scnhsz; - if (siz < filhsz) - siz = filhsz; - if (siz < aoutsz) - siz = aoutsz; - buff = (PTR) malloc (siz); - if (buff == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - } - - internal_f.f_nscns = 0; - if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0) - goto error_return; - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - struct internal_scnhdr section; - bfd_vma vma; - - ++internal_f.f_nscns; - - strncpy (section.s_name, current->name, sizeof section.s_name); - - /* This seems to be correct for Irix 4 shared libraries. */ - vma = bfd_get_section_vma (abfd, current); - if (strcmp (current->name, _LIB) == 0) - section.s_vaddr = 0; - else - section.s_vaddr = vma; - - section.s_paddr = vma; - section.s_size = bfd_get_section_size_before_reloc (current); - - /* If this section is unloadable then the scnptr will be 0. */ - if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0) - section.s_scnptr = 0; - else - section.s_scnptr = current->filepos; - section.s_relptr = current->rel_filepos; - - /* FIXME: the lnnoptr of the .sbss or .sdata section of an - object file produced by the assembler is supposed to point to - information about how much room is required by objects of - various different sizes. I think this only matters if we - want the linker to compute the best size to use, or - something. I don't know what happens if the information is - not present. */ - if (strcmp (current->name, _PDATA) != 0) - section.s_lnnoptr = 0; - else - { - /* The Alpha ECOFF .pdata section uses the lnnoptr field to - hold the number of entries in the section (each entry is - 8 bytes). We stored this in the line_filepos field in - ecoff_compute_section_file_positions. */ - section.s_lnnoptr = current->line_filepos; - } - - section.s_nreloc = current->reloc_count; - section.s_nlnno = 0; - section.s_flags = ecoff_sec_to_styp_flags (current->name, - current->flags); - - bfd_coff_swap_scnhdr_out (abfd, (PTR) §ion, buff); - if (bfd_write (buff, 1, scnhsz, abfd) != scnhsz) - goto error_return; - - if ((section.s_flags & STYP_TEXT) != 0 - || ((section.s_flags & STYP_RDATA) != 0 - && backend->rdata_in_text) - || strcmp (current->name, _PDATA) == 0) - { - text_size += bfd_get_section_size_before_reloc (current); - if (! set_text_start || text_start > vma) - { - text_start = vma; - set_text_start = true; - } - } - else if ((section.s_flags & STYP_RDATA) != 0 - || (section.s_flags & STYP_DATA) != 0 - || (section.s_flags & STYP_LITA) != 0 - || (section.s_flags & STYP_LIT8) != 0 - || (section.s_flags & STYP_LIT4) != 0 - || (section.s_flags & STYP_SDATA) != 0 - || strcmp (current->name, _XDATA) == 0) - { - data_size += bfd_get_section_size_before_reloc (current); - if (! set_data_start || data_start > vma) - { - data_start = vma; - set_data_start = true; - } - } - else if ((section.s_flags & STYP_BSS) != 0 - || (section.s_flags & STYP_SBSS) != 0) - bss_size += bfd_get_section_size_before_reloc (current); - else if ((section.s_flags & STYP_ECOFF_LIB) != 0) - /* Do nothing */ ; - else - abort (); - } - - /* Set up the file header. */ - - internal_f.f_magic = ecoff_get_magic (abfd); - - /* We will NOT put a fucking timestamp in the header here. Every - time you put it back, I will come in and take it out again. I'm - sorry. This field does not belong here. We fill it with a 0 so - it compares the same but is not a reasonable time. -- - gnu@cygnus.com. */ - internal_f.f_timdat = 0; - - if (bfd_get_symcount (abfd) != 0) - { - /* The ECOFF f_nsyms field is not actually the number of - symbols, it's the size of symbolic information header. */ - internal_f.f_nsyms = external_hdr_size; - internal_f.f_symptr = ecoff_data (abfd)->sym_filepos; - } - else - { - internal_f.f_nsyms = 0; - internal_f.f_symptr = 0; - } - - internal_f.f_opthdr = aoutsz; - - internal_f.f_flags = F_LNNO; - if (reloc_size == 0) - internal_f.f_flags |= F_RELFLG; - if (bfd_get_symcount (abfd) == 0) - internal_f.f_flags |= F_LSYMS; - if (abfd->flags & EXEC_P) - internal_f.f_flags |= F_EXEC; - - if (! abfd->xvec->byteorder_big_p) - internal_f.f_flags |= F_AR32WR; - else - internal_f.f_flags |= F_AR32W; - - /* Set up the ``optional'' header. */ - if ((abfd->flags & D_PAGED) != 0) - internal_a.magic = ECOFF_AOUT_ZMAGIC; - else - internal_a.magic = ECOFF_AOUT_OMAGIC; - - /* FIXME: Is this really correct? */ - internal_a.vstamp = symhdr->vstamp; - - /* At least on Ultrix, these have to be rounded to page boundaries. - FIXME: Is this true on other platforms? */ - if ((abfd->flags & D_PAGED) != 0) - { - internal_a.tsize = (text_size + round - 1) &~ (round - 1); - internal_a.text_start = text_start &~ (round - 1); - internal_a.dsize = (data_size + round - 1) &~ (round - 1); - internal_a.data_start = data_start &~ (round - 1); - } - else - { - internal_a.tsize = text_size; - internal_a.text_start = text_start; - internal_a.dsize = data_size; - internal_a.data_start = data_start; - } - - /* On Ultrix, the initial portions of the .sbss and .bss segments - are at the end of the data section. The bsize field in the - optional header records how many bss bytes are required beyond - those in the data section. The value is not rounded to a page - boundary. */ - if (bss_size < internal_a.dsize - data_size) - bss_size = 0; - else - bss_size -= internal_a.dsize - data_size; - internal_a.bsize = bss_size; - internal_a.bss_start = internal_a.data_start + internal_a.dsize; - - internal_a.entry = bfd_get_start_address (abfd); - - internal_a.gp_value = ecoff_data (abfd)->gp; - - internal_a.gprmask = ecoff_data (abfd)->gprmask; - internal_a.fprmask = ecoff_data (abfd)->fprmask; - for (i = 0; i < 4; i++) - internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i]; - - /* Write out the file header and the optional header. */ - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - goto error_return; - - bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, buff); - if (bfd_write (buff, 1, filhsz, abfd) != filhsz) - goto error_return; - - bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, buff); - if (bfd_write (buff, 1, aoutsz, abfd) != aoutsz) - goto error_return; - - /* Build the external symbol information. This must be done before - writing out the relocs so that we know the symbol indices. We - don't do this if this BFD was created by the backend linker, - since it will have already handled the symbols and relocs. */ - if (! ecoff_data (abfd)->linker) - { - symhdr->iextMax = 0; - symhdr->issExtMax = 0; - debug->external_ext = debug->external_ext_end = NULL; - debug->ssext = debug->ssext_end = NULL; - if (bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap, - (((abfd->flags & EXEC_P) == 0) - ? true : false), - ecoff_get_extr, ecoff_set_index) - == false) - goto error_return; - - /* Write out the relocs. */ - for (current = abfd->sections; - current != (asection *) NULL; - current = current->next) - { - arelent **reloc_ptr_ptr; - arelent **reloc_end; - char *out_ptr; - - if (current->reloc_count == 0) - continue; - - reloc_buff = - bfd_alloc (abfd, current->reloc_count * external_reloc_size); - if (reloc_buff == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - reloc_ptr_ptr = current->orelocation; - reloc_end = reloc_ptr_ptr + current->reloc_count; - out_ptr = (char *) reloc_buff; - for (; - reloc_ptr_ptr < reloc_end; - reloc_ptr_ptr++, out_ptr += external_reloc_size) - { - arelent *reloc; - asymbol *sym; - struct internal_reloc in; - - memset ((PTR) &in, 0, sizeof in); - - reloc = *reloc_ptr_ptr; - sym = *reloc->sym_ptr_ptr; - - in.r_vaddr = (reloc->address - + bfd_get_section_vma (abfd, current)); - in.r_type = reloc->howto->type; - - if ((sym->flags & BSF_SECTION_SYM) == 0) - { - in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr); - in.r_extern = 1; - } - else - { - CONST char *name; - - name = bfd_get_section_name (abfd, bfd_get_section (sym)); - if (strcmp (name, ".text") == 0) - in.r_symndx = RELOC_SECTION_TEXT; - else if (strcmp (name, ".rdata") == 0) - in.r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".data") == 0) - in.r_symndx = RELOC_SECTION_DATA; - else if (strcmp (name, ".sdata") == 0) - in.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - in.r_symndx = RELOC_SECTION_SBSS; - else if (strcmp (name, ".bss") == 0) - in.r_symndx = RELOC_SECTION_BSS; - else if (strcmp (name, ".init") == 0) - in.r_symndx = RELOC_SECTION_INIT; - else if (strcmp (name, ".lit8") == 0) - in.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - in.r_symndx = RELOC_SECTION_LIT4; - else if (strcmp (name, ".xdata") == 0) - in.r_symndx = RELOC_SECTION_XDATA; - else if (strcmp (name, ".pdata") == 0) - in.r_symndx = RELOC_SECTION_PDATA; - else if (strcmp (name, ".fini") == 0) - in.r_symndx = RELOC_SECTION_FINI; - else if (strcmp (name, ".lita") == 0) - in.r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, "*ABS*") == 0) - in.r_symndx = RELOC_SECTION_ABS; - else - abort (); - in.r_extern = 0; - } - - (*adjust_reloc_out) (abfd, reloc, &in); - - (*swap_reloc_out) (abfd, &in, (PTR) out_ptr); - } - - if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0) - goto error_return; - if (bfd_write (reloc_buff, - external_reloc_size, current->reloc_count, abfd) - != external_reloc_size * current->reloc_count) - goto error_return; - bfd_release (abfd, reloc_buff); - reloc_buff = NULL; - } - - /* Write out the symbolic debugging information. */ - if (bfd_get_symcount (abfd) > 0) - { - /* Write out the debugging information. */ - if (bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap, - ecoff_data (abfd)->sym_filepos) - == false) - goto error_return; - } - } - - /* The .bss section of a demand paged executable must receive an - entire page. If there are symbols, the symbols will start on the - next page. If there are no symbols, we must fill out the page by - hand. */ - if (bfd_get_symcount (abfd) == 0 - && (abfd->flags & EXEC_P) != 0 - && (abfd->flags & D_PAGED) != 0) - { - char c; - - if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, - SEEK_SET) != 0) - goto error_return; - if (bfd_read (&c, 1, 1, abfd) == 0) - c = 0; - if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1, - SEEK_SET) != 0) - goto error_return; - if (bfd_write (&c, 1, 1, abfd) != 1) - goto error_return; - } - - if (reloc_buff != NULL) - bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); - return true; - error_return: - if (reloc_buff != NULL) - bfd_release (abfd, reloc_buff); - if (buff != NULL) - free (buff); - return false; -} - -/* Archive handling. ECOFF uses what appears to be a unique type of - archive header (armap). The byte ordering of the armap and the - contents are encoded in the name of the armap itself. At least for - now, we only support archives with the same byte ordering in the - armap and the contents. - - The first four bytes in the armap are the number of symbol - definitions. This is always a power of two. - - This is followed by the symbol definitions. Each symbol definition - occupies 8 bytes. The first four bytes are the offset from the - start of the armap strings to the null-terminated string naming - this symbol. The second four bytes are the file offset to the - archive member which defines this symbol. If the second four bytes - are 0, then this is not actually a symbol definition, and it should - be ignored. - - The symbols are hashed into the armap with a closed hashing scheme. - See the functions below for the details of the algorithm. - - After the symbol definitions comes four bytes holding the size of - the string table, followed by the string table itself. */ - -/* The name of an archive headers looks like this: - __________E[BL]E[BL]_ (with a trailing space). - The trailing space is changed to an X if the archive is changed to - indicate that the armap is out of date. - - The Alpha seems to use ________64E[BL]E[BL]_. */ - -#define ARMAP_BIG_ENDIAN 'B' -#define ARMAP_LITTLE_ENDIAN 'L' -#define ARMAP_MARKER 'E' -#define ARMAP_START_LENGTH 10 -#define ARMAP_HEADER_MARKER_INDEX 10 -#define ARMAP_HEADER_ENDIAN_INDEX 11 -#define ARMAP_OBJECT_MARKER_INDEX 12 -#define ARMAP_OBJECT_ENDIAN_INDEX 13 -#define ARMAP_END_INDEX 14 -#define ARMAP_END "_ " - -/* This is a magic number used in the hashing algorithm. */ -#define ARMAP_HASH_MAGIC 0x9dd68ab5 - -/* This returns the hash value to use for a string. It also sets - *REHASH to the rehash adjustment if the first slot is taken. SIZE - is the number of entries in the hash table, and HLOG is the log - base 2 of SIZE. */ - -static unsigned int -ecoff_armap_hash (s, rehash, size, hlog) - CONST char *s; - unsigned int *rehash; - unsigned int size; - unsigned int hlog; -{ - unsigned int hash; - - hash = *s++; - while (*s != '\0') - hash = ((hash >> 27) | (hash << 5)) + *s++; - hash *= ARMAP_HASH_MAGIC; - *rehash = (hash & (size - 1)) | 1; - return hash >> (32 - hlog); -} - -/* Read in the armap. */ - -boolean -_bfd_ecoff_slurp_armap (abfd) - bfd *abfd; -{ - char nextname[17]; - unsigned int i; - struct areltdata *mapdata; - bfd_size_type parsed_size; - char *raw_armap; - struct artdata *ardata; - unsigned int count; - char *raw_ptr; - struct symdef *symdef_ptr; - char *stringbase; - - /* Get the name of the first element. */ - i = bfd_read ((PTR) nextname, 1, 16, abfd); - if (i == 0) - return true; - if (i != 16) - return false; - - if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0) - return false; - - /* Irix 4.0.5F apparently can use either an ECOFF armap or a - standard COFF armap. We could move the ECOFF armap stuff into - bfd_slurp_armap, but that seems inappropriate since no other - target uses this format. Instead, we check directly for a COFF - armap. */ - if (strncmp (nextname, "/ ", 16) == 0) - return bfd_slurp_armap (abfd); - - /* See if the first element is an armap. */ - if (strncmp (nextname, ecoff_backend (abfd)->armap_start, - ARMAP_START_LENGTH) != 0 - || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER - || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN - && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) - || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER - || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN - && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN) - || strncmp (nextname + ARMAP_END_INDEX, - ARMAP_END, sizeof ARMAP_END - 1) != 0) - { - bfd_has_map (abfd) = false; - return true; - } - - /* Make sure we have the right byte ordering. */ - if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) - ^ (abfd->xvec->header_byteorder_big_p != false)) - || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN) - ^ (abfd->xvec->byteorder_big_p != false))) - { - bfd_set_error (bfd_error_wrong_format); - return false; - } - - /* Read in the armap. */ - ardata = bfd_ardata (abfd); - mapdata = _bfd_snarf_ar_hdr (abfd); - if (mapdata == (struct areltdata *) NULL) - return false; - parsed_size = mapdata->parsed_size; - bfd_release (abfd, (PTR) mapdata); - - raw_armap = (char *) bfd_alloc (abfd, parsed_size); - if (raw_armap == (char *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - if (bfd_read ((PTR) raw_armap, 1, parsed_size, abfd) != parsed_size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_malformed_archive); - bfd_release (abfd, (PTR) raw_armap); - return false; - } - - ardata->tdata = (PTR) raw_armap; - - count = bfd_h_get_32 (abfd, (PTR) raw_armap); - - ardata->symdef_count = 0; - ardata->cache = (struct ar_cache *) NULL; - - /* This code used to overlay the symdefs over the raw archive data, - but that doesn't work on a 64 bit host. */ - - stringbase = raw_armap + count * 8 + 8; - -#ifdef CHECK_ARMAP_HASH - { - unsigned int hlog; - - /* Double check that I have the hashing algorithm right by making - sure that every symbol can be looked up successfully. */ - hlog = 0; - for (i = 1; i < count; i <<= 1) - hlog++; - BFD_ASSERT (i == count); - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - { - unsigned int name_offset, file_offset; - unsigned int hash, rehash, srch; - - name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr); - file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)); - if (file_offset == 0) - continue; - hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count, - hlog); - if (hash == i) - continue; - - /* See if we can rehash to this location. */ - for (srch = (hash + rehash) & (count - 1); - srch != hash && srch != i; - srch = (srch + rehash) & (count - 1)) - BFD_ASSERT (bfd_h_get_32 (abfd, (PTR) (raw_armap + 8 + srch * 8)) - != 0); - BFD_ASSERT (srch == i); - } - } - -#endif /* CHECK_ARMAP_HASH */ - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - if (bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)) != 0) - ++ardata->symdef_count; - - symdef_ptr = ((struct symdef *) - bfd_alloc (abfd, - ardata->symdef_count * sizeof (struct symdef))); - if (!symdef_ptr) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - ardata->symdefs = (carsym *) symdef_ptr; - - raw_ptr = raw_armap + 4; - for (i = 0; i < count; i++, raw_ptr += 8) - { - unsigned int name_offset, file_offset; - - file_offset = bfd_h_get_32 (abfd, (PTR) (raw_ptr + 4)); - if (file_offset == 0) - continue; - name_offset = bfd_h_get_32 (abfd, (PTR) raw_ptr); - symdef_ptr->s.name = stringbase + name_offset; - symdef_ptr->file_offset = file_offset; - ++symdef_ptr; - } - - ardata->first_file_filepos = bfd_tell (abfd); - /* Pad to an even boundary. */ - ardata->first_file_filepos += ardata->first_file_filepos % 2; - - bfd_has_map (abfd) = true; - - return true; -} - -/* Write out an armap. */ - -boolean -_bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx) - bfd *abfd; - unsigned int elength; - struct orl *map; - unsigned int orl_count; - int stridx; -{ - unsigned int hashsize, hashlog; - unsigned int symdefsize; - int padit; - unsigned int stringsize; - unsigned int mapsize; - file_ptr firstreal; - struct ar_hdr hdr; - struct stat statbuf; - unsigned int i; - bfd_byte temp[4]; - bfd_byte *hashtable; - bfd *current; - bfd *last_elt; - - /* Ultrix appears to use as a hash table size the least power of two - greater than twice the number of entries. */ - for (hashlog = 0; (1 << hashlog) <= 2 * orl_count; hashlog++) - ; - hashsize = 1 << hashlog; - - symdefsize = hashsize * 8; - padit = stridx % 2; - stringsize = stridx + padit; - - /* Include 8 bytes to store symdefsize and stringsize in output. */ - mapsize = symdefsize + stringsize + 8; - - firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength; - - memset ((PTR) &hdr, 0, sizeof hdr); - - /* Work out the ECOFF armap name. */ - strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start); - hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER; - hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] = - (abfd->xvec->header_byteorder_big_p - ? ARMAP_BIG_ENDIAN - : ARMAP_LITTLE_ENDIAN); - hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER; - hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] = - abfd->xvec->byteorder_big_p ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN; - memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1); - - /* Write the timestamp of the archive header to be just a little bit - later than the timestamp of the file, otherwise the linker will - complain that the index is out of date. Actually, the Ultrix - linker just checks the archive name; the GNU linker may check the - date. */ - stat (abfd->filename, &statbuf); - sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60)); - - /* The DECstation uses zeroes for the uid, gid and mode of the - armap. */ - hdr.ar_uid[0] = '0'; - hdr.ar_gid[0] = '0'; - hdr.ar_mode[0] = '0'; - - sprintf (hdr.ar_size, "%-10d", (int) mapsize); - - hdr.ar_fmag[0] = '`'; - hdr.ar_fmag[1] = '\012'; - - /* Turn all null bytes in the header into spaces. */ - for (i = 0; i < sizeof (struct ar_hdr); i++) - if (((char *)(&hdr))[i] == '\0') - (((char *)(&hdr))[i]) = ' '; - - if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), abfd) - != sizeof (struct ar_hdr)) - return false; - - bfd_h_put_32 (abfd, (bfd_vma) hashsize, temp); - if (bfd_write ((PTR) temp, 1, 4, abfd) != 4) - return false; - - hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize); - if (!hashtable) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - current = abfd->archive_head; - last_elt = current; - for (i = 0; i < orl_count; i++) - { - unsigned int hash, rehash; - - /* Advance firstreal to the file position of this archive - element. */ - if (((bfd *) map[i].pos) != last_elt) - { - do - { - firstreal += arelt_size (current) + sizeof (struct ar_hdr); - firstreal += firstreal % 2; - current = current->next; - } - while (current != (bfd *) map[i].pos); - } - - last_elt = current; - - hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog); - if (bfd_h_get_32 (abfd, (PTR) (hashtable + (hash * 8) + 4)) != 0) - { - unsigned int srch; - - /* The desired slot is already taken. */ - for (srch = (hash + rehash) & (hashsize - 1); - srch != hash; - srch = (srch + rehash) & (hashsize - 1)) - if (bfd_h_get_32 (abfd, (PTR) (hashtable + (srch * 8) + 4)) == 0) - break; - - BFD_ASSERT (srch != hash); - - hash = srch; - } - - bfd_h_put_32 (abfd, (bfd_vma) map[i].namidx, - (PTR) (hashtable + hash * 8)); - bfd_h_put_32 (abfd, (bfd_vma) firstreal, - (PTR) (hashtable + hash * 8 + 4)); - } - - if (bfd_write ((PTR) hashtable, 1, symdefsize, abfd) != symdefsize) - return false; - - bfd_release (abfd, hashtable); - - /* Now write the strings. */ - bfd_h_put_32 (abfd, (bfd_vma) stringsize, temp); - if (bfd_write ((PTR) temp, 1, 4, abfd) != 4) - return false; - for (i = 0; i < orl_count; i++) - { - bfd_size_type len; - - len = strlen (*map[i].name) + 1; - if (bfd_write ((PTR) (*map[i].name), 1, len, abfd) != len) - return false; - } - - /* The spec sez this should be a newline. But in order to be - bug-compatible for DECstation ar we use a null. */ - if (padit) - { - if (bfd_write ("", 1, 1, abfd) != 1) - return false; - } - - return true; -} - -/* See whether this BFD is an archive. If it is, read in the armap - and the extended name table. */ - -const bfd_target * -_bfd_ecoff_archive_p (abfd) - bfd *abfd; -{ - char armag[SARMAG + 1]; - - if (bfd_read ((PTR) armag, 1, SARMAG, abfd) != SARMAG - || strncmp (armag, ARMAG, SARMAG) != 0) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return (const bfd_target *) NULL; - } - - /* We are setting bfd_ardata(abfd) here, but since bfd_ardata - involves a cast, we can't do it as the left operand of - assignment. */ - abfd->tdata.aout_ar_data = - (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata)); - - if (bfd_ardata (abfd) == (struct artdata *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (const bfd_target *) NULL; - } - - bfd_ardata (abfd)->first_file_filepos = SARMAG; - bfd_ardata (abfd)->cache = NULL; - bfd_ardata (abfd)->archive_head = NULL; - bfd_ardata (abfd)->symdefs = NULL; - bfd_ardata (abfd)->extended_names = NULL; - bfd_ardata (abfd)->tdata = NULL; - - if (_bfd_ecoff_slurp_armap (abfd) == false - || _bfd_ecoff_slurp_extended_name_table (abfd) == false) - { - bfd_release (abfd, bfd_ardata (abfd)); - abfd->tdata.aout_ar_data = (struct artdata *) NULL; - return (const bfd_target *) NULL; - } - - return abfd->xvec; -} - -/* ECOFF linker code. */ - -static struct bfd_hash_entry *ecoff_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); -static boolean ecoff_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean ecoff_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean ecoff_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean ecoff_link_add_externals - PARAMS ((bfd *, struct bfd_link_info *, PTR, char *)); - -/* Routine to create an entry in an ECOFF link hash table. */ - -static struct bfd_hash_entry * -ecoff_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ecoff_link_hash_entry *ret = (struct ecoff_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct ecoff_link_hash_entry *) NULL) - ret = ((struct ecoff_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry))); - if (ret == (struct ecoff_link_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct ecoff_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Set local fields. */ - ret->indx = -1; - ret->abfd = NULL; - ret->written = 0; - ret->small = 0; - } - memset ((PTR) &ret->esym, 0, sizeof ret->esym); - - return (struct bfd_hash_entry *) ret; -} - -/* Create an ECOFF link hash table. */ - -struct bfd_link_hash_table * -_bfd_ecoff_bfd_link_hash_table_create (abfd) - bfd *abfd; -{ - struct ecoff_link_hash_table *ret; - - ret = ((struct ecoff_link_hash_table *) - malloc (sizeof (struct ecoff_link_hash_table))); - if (!ret) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - if (! _bfd_link_hash_table_init (&ret->root, abfd, - ecoff_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Look up an entry in an ECOFF link hash table. */ - -#define ecoff_link_hash_lookup(table, string, create, copy, follow) \ - ((struct ecoff_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an ECOFF link hash table. */ - -#define ecoff_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the ECOFF link hash table from the info structure. This is - just a cast. */ - -#define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash)) - -/* Given an ECOFF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -_bfd_ecoff_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return ecoff_link_add_object_symbols (abfd, info); - case bfd_archive: - return ecoff_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add the symbols from an archive file to the global hash table. - This looks through the undefined symbols, looks each one up in the - archive hash table, and adds any associated object file. We do not - use _bfd_generic_link_add_archive_symbols because ECOFF archives - already have a hash table, so there is no reason to construct - another one. */ - -static boolean -ecoff_link_add_archive_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - const bfd_byte *raw_armap; - struct bfd_link_hash_entry **pundef; - unsigned int armap_count; - unsigned int armap_log; - unsigned int i; - const bfd_byte *hashtable; - const char *stringbase; - - if (! bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* If we don't have any raw data for this archive, as can happen on - Irix 4.0.5F, we call the generic routine. - FIXME: We should be more clever about this, since someday tdata - may get to something for a generic archive. */ - raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata; - if (raw_armap == (bfd_byte *) NULL) - return (_bfd_generic_link_add_archive_symbols - (abfd, info, ecoff_link_check_archive_element)); - - armap_count = bfd_h_get_32 (abfd, raw_armap); - - armap_log = 0; - for (i = 1; i < armap_count; i <<= 1) - armap_log++; - BFD_ASSERT (i == armap_count); - - hashtable = raw_armap + 4; - stringbase = (const char *) raw_armap + armap_count * 8 + 8; - - /* Look through the list of undefined symbols. */ - pundef = &info->hash->undefs; - while (*pundef != (struct bfd_link_hash_entry *) NULL) - { - struct bfd_link_hash_entry *h; - unsigned int hash, rehash; - unsigned int file_offset; - const char *name; - bfd *element; - - h = *pundef; - - /* When a symbol is defined, it is not necessarily removed from - the list. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - { - /* Remove this entry from the list, for general cleanliness - and because we are going to look through the list again - if we search any more libraries. We can't remove the - entry if it is the tail, because that would lose any - entries we add to the list later on. */ - if (*pundef != info->hash->undefs_tail) - *pundef = (*pundef)->next; - else - pundef = &(*pundef)->next; - continue; - } - - /* Native ECOFF linkers do not pull in archive elements merely - to satisfy common definitions, so neither do we. We leave - them on the list, though, in case we are linking against some - other object format. */ - if (h->type != bfd_link_hash_undefined) - { - pundef = &(*pundef)->next; - continue; - } - - /* Look for this symbol in the archive hash table. */ - hash = ecoff_armap_hash (h->root.string, &rehash, armap_count, - armap_log); - - file_offset = bfd_h_get_32 (abfd, hashtable + (hash * 8) + 4); - if (file_offset == 0) - { - /* Nothing in this slot. */ - pundef = &(*pundef)->next; - continue; - } - - name = stringbase + bfd_h_get_32 (abfd, hashtable + (hash * 8)); - if (name[0] != h->root.string[0] - || strcmp (name, h->root.string) != 0) - { - unsigned int srch; - boolean found; - - /* That was the wrong symbol. Try rehashing. */ - found = false; - for (srch = (hash + rehash) & (armap_count - 1); - srch != hash; - srch = (srch + rehash) & (armap_count - 1)) - { - file_offset = bfd_h_get_32 (abfd, hashtable + (srch * 8) + 4); - if (file_offset == 0) - break; - name = stringbase + bfd_h_get_32 (abfd, hashtable + (srch * 8)); - if (name[0] == h->root.string[0] - && strcmp (name, h->root.string) == 0) - { - found = true; - break; - } - } - - if (! found) - { - pundef = &(*pundef)->next; - continue; - } - - hash = srch; - } - - element = _bfd_get_elt_at_filepos (abfd, file_offset); - if (element == (bfd *) NULL) - return false; - - if (! bfd_check_format (element, bfd_object)) - return false; - - /* Unlike the generic linker, we know that this element provides - a definition for an undefined symbol and we know that we want - to include it. We don't need to check anything. */ - if (! (*info->callbacks->add_archive_element) (info, element, name)) - return false; - if (! ecoff_link_add_object_symbols (element, info)) - return false; - - pundef = &(*pundef)->next; - } - - return true; -} - -/* This is called if we used _bfd_generic_link_add_archive_symbols - because we were not dealing with an ECOFF archive. */ - -static boolean -ecoff_link_check_archive_element (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - HDRR *symhdr; - bfd_size_type external_ext_size; - PTR external_ext = NULL; - size_t esize; - char *ssext = NULL; - char *ext_ptr; - char *ext_end; - - *pneeded = false; - - if (! ecoff_slurp_symbolic_header (abfd)) - goto error_return; - - /* If there are no symbols, we don't want it. */ - if (bfd_get_symcount (abfd) == 0) - goto successful_return; - - symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - - /* Read in the external symbols and external strings. */ - external_ext_size = backend->debug_swap.external_ext_size; - esize = symhdr->iextMax * external_ext_size; - external_ext = (PTR) malloc (esize); - if (external_ext == NULL && esize != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0 - || bfd_read (external_ext, 1, esize, abfd) != esize) - goto error_return; - - ssext = (char *) malloc (symhdr->issExtMax); - if (ssext == NULL && symhdr->issExtMax != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0 - || bfd_read (ssext, 1, symhdr->issExtMax, abfd) != symhdr->issExtMax) - goto error_return; - - /* Look through the external symbols to see if they define some - symbol that is currently undefined. */ - ext_ptr = (char *) external_ext; - ext_end = ext_ptr + esize; - for (; ext_ptr < ext_end; ext_ptr += external_ext_size) - { - EXTR esym; - boolean def; - const char *name; - struct bfd_link_hash_entry *h; - - (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym); - - /* See if this symbol defines something. */ - if (esym.asym.st != stGlobal - && esym.asym.st != stLabel - && esym.asym.st != stProc) - continue; - - switch (esym.asym.sc) - { - case scText: - case scData: - case scBss: - case scAbs: - case scSData: - case scSBss: - case scRData: - case scCommon: - case scSCommon: - case scInit: - case scFini: - def = true; - break; - default: - def = false; - break; - } - - if (! def) - continue; - - name = ssext + esym.asym.iss; - h = bfd_link_hash_lookup (info->hash, name, false, false, true); - - /* Unlike the generic linker, we do not pull in elements because - of common symbols. */ - if (h == (struct bfd_link_hash_entry *) NULL - || h->type != bfd_link_hash_undefined) - continue; - - /* Include this element. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, name)) - goto error_return; - if (! ecoff_link_add_externals (abfd, info, external_ext, ssext)) - goto error_return; - - *pneeded = true; - goto successful_return; - } - - successful_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return true; - error_return: - if (external_ext != NULL) - free (external_ext); - if (ssext != NULL) - free (ssext); - return false; -} - -/* Add symbols from an ECOFF object file to the global linker hash - table. */ - -static boolean -ecoff_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - HDRR *symhdr; - bfd_size_type external_ext_size; - PTR external_ext = NULL; - size_t esize; - char *ssext = NULL; - boolean result; - - if (! ecoff_slurp_symbolic_header (abfd)) - return false; - - /* If there are no symbols, we don't want it. */ - if (bfd_get_symcount (abfd) == 0) - return true; - - symhdr = &ecoff_data (abfd)->debug_info.symbolic_header; - - /* Read in the external symbols and external strings. */ - external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size; - esize = symhdr->iextMax * external_ext_size; - external_ext = (PTR) malloc (esize); - if (external_ext == NULL && esize != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0 - || bfd_read (external_ext, 1, esize, abfd) != esize) - goto error_return; - - ssext = (char *) malloc (symhdr->issExtMax); - if (ssext == NULL && symhdr->issExtMax != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0 - || bfd_read (ssext, 1, symhdr->issExtMax, abfd) != symhdr->issExtMax) - goto error_return; - - result = ecoff_link_add_externals (abfd, info, external_ext, ssext); - - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); - return result; - - error_return: - if (ssext != NULL) - free (ssext); - if (external_ext != NULL) - free (external_ext); - return false; -} - -/* Add the external symbols of an object file to the global linker - hash table. The external symbols and strings we are passed are - just allocated on the stack, and will be discarded. We must - explicitly save any information we may need later on in the link. - We do not want to read the external symbol information again. */ - -static boolean -ecoff_link_add_externals (abfd, info, external_ext, ssext) - bfd *abfd; - struct bfd_link_info *info; - PTR external_ext; - char *ssext; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *)) - = backend->debug_swap.swap_ext_in; - bfd_size_type external_ext_size = backend->debug_swap.external_ext_size; - unsigned long ext_count; - struct ecoff_link_hash_entry **sym_hash; - char *ext_ptr; - char *ext_end; - - ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax; - - sym_hash = ((struct ecoff_link_hash_entry **) - bfd_alloc (abfd, - ext_count * sizeof (struct bfd_link_hash_entry *))); - if (!sym_hash) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - ecoff_data (abfd)->sym_hashes = sym_hash; - - ext_ptr = (char *) external_ext; - ext_end = ext_ptr + ext_count * external_ext_size; - for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++) - { - EXTR esym; - boolean skip; - bfd_vma value; - asection *section; - const char *name; - struct ecoff_link_hash_entry *h; - - *sym_hash = NULL; - - (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym); - - /* Skip debugging symbols. */ - skip = false; - switch (esym.asym.st) - { - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - break; - default: - skip = true; - break; - } - - if (skip) - continue; - - /* Get the information for this symbol. */ - value = esym.asym.value; - switch (esym.asym.sc) - { - default: - case scNil: - case scRegister: - case scCdbLocal: - case scBits: - case scCdbSystem: - case scRegImage: - case scInfo: - case scUserStruct: - case scVar: - case scVarRegister: - case scVariant: - case scBasedVar: - case scXData: - case scPData: - section = NULL; - break; - case scText: - section = bfd_make_section_old_way (abfd, ".text"); - value -= section->vma; - break; - case scData: - section = bfd_make_section_old_way (abfd, ".data"); - value -= section->vma; - break; - case scBss: - section = bfd_make_section_old_way (abfd, ".bss"); - value -= section->vma; - break; - case scAbs: - section = bfd_abs_section_ptr; - break; - case scUndefined: - section = bfd_und_section_ptr; - break; - case scSData: - section = bfd_make_section_old_way (abfd, ".sdata"); - value -= section->vma; - break; - case scSBss: - section = bfd_make_section_old_way (abfd, ".sbss"); - value -= section->vma; - break; - case scRData: - section = bfd_make_section_old_way (abfd, ".rdata"); - value -= section->vma; - break; - case scCommon: - if (value > ecoff_data (abfd)->gp_size) - { - section = bfd_com_section_ptr; - break; - } - /* Fall through. */ - case scSCommon: - if (ecoff_scom_section.name == NULL) - { - /* Initialize the small common section. */ - ecoff_scom_section.name = SCOMMON; - ecoff_scom_section.flags = SEC_IS_COMMON; - ecoff_scom_section.output_section = &ecoff_scom_section; - ecoff_scom_section.symbol = &ecoff_scom_symbol; - ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr; - ecoff_scom_symbol.name = SCOMMON; - ecoff_scom_symbol.flags = BSF_SECTION_SYM; - ecoff_scom_symbol.section = &ecoff_scom_section; - ecoff_scom_symbol_ptr = &ecoff_scom_symbol; - } - section = &ecoff_scom_section; - break; - case scSUndefined: - section = bfd_und_section_ptr; - break; - case scInit: - section = bfd_make_section_old_way (abfd, ".init"); - value -= section->vma; - break; - case scFini: - section = bfd_make_section_old_way (abfd, ".fini"); - value -= section->vma; - break; - } - - if (section == (asection *) NULL) - continue; - - name = ssext + esym.asym.iss; - - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, BSF_GLOBAL, section, value, - (const char *) NULL, true, true, - (struct bfd_link_hash_entry **) &h))) - return false; - - *sym_hash = h; - - /* If we are building an ECOFF hash table, save the external - symbol information. */ - if (info->hash->creator->flavour == bfd_get_flavour (abfd)) - { - if (h->abfd == (bfd *) NULL - || (! bfd_is_und_section (section) - && (! bfd_is_com_section (section) - || h->root.type != bfd_link_hash_defined))) - { - h->abfd = abfd; - h->esym = esym; - } - - /* Remember whether this symbol was small undefined. */ - if (esym.asym.sc == scSUndefined) - h->small = 1; - - /* If this symbol was ever small undefined, it needs to wind - up in a GP relative section. We can't control the - section of a defined symbol, but we can control the - section of a common symbol. This case is actually needed - on Ultrix 4.2 to handle the symbol cred in -lckrb. */ - if (h->small - && h->root.type == bfd_link_hash_common - && strcmp (h->root.u.c.section->name, SCOMMON) != 0) - { - h->root.u.c.section = bfd_make_section_old_way (abfd, SCOMMON); - h->root.u.c.section->flags = SEC_ALLOC; - if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scSCommon; - } - } - } - - return true; -} - -/* ECOFF final link routines. */ - -static boolean ecoff_final_link_debug_accumulate - PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *, - PTR handle)); -static boolean ecoff_link_write_external - PARAMS ((struct ecoff_link_hash_entry *, PTR)); -static boolean ecoff_indirect_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); -static boolean ecoff_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* ECOFF final link routine. This looks through all the input BFDs - and gathers together all the debugging information, and then - processes all the link order information. This may cause it to - close and reopen some input BFDs; I'll see how bad this is. */ - -boolean -_bfd_ecoff_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - const struct ecoff_backend_data * const backend = ecoff_backend (abfd); - struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info; - HDRR *symhdr; - PTR handle; - register bfd *input_bfd; - asection *o; - struct bfd_link_order *p; - - /* We accumulate the debugging information counts in the symbolic - header. */ - symhdr = &debug->symbolic_header; - symhdr->vstamp = 0; - symhdr->ilineMax = 0; - symhdr->cbLine = 0; - symhdr->idnMax = 0; - symhdr->ipdMax = 0; - symhdr->isymMax = 0; - symhdr->ioptMax = 0; - symhdr->iauxMax = 0; - symhdr->issMax = 0; - symhdr->issExtMax = 0; - symhdr->ifdMax = 0; - symhdr->crfd = 0; - symhdr->iextMax = 0; - - /* We accumulate the debugging information itself in the debug_info - structure. */ - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->ssext = debug->ssext_end = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - debug->external_ext = debug->external_ext_end = NULL; - - handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info); - if (handle == (PTR) NULL) - return false; - - /* Accumulate the debugging symbols from each input BFD. */ - for (input_bfd = info->input_bfds; - input_bfd != (bfd *) NULL; - input_bfd = input_bfd->link_next) - { - boolean ret; - - if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour) - { - /* Abitrarily set the symbolic header vstamp to the vstamp - of the first object file in the link. */ - if (symhdr->vstamp == 0) - symhdr->vstamp - = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp; - ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info, - handle); - } - else - ret = bfd_ecoff_debug_accumulate_other (handle, abfd, - debug, &backend->debug_swap, - input_bfd, info); - if (! ret) - return false; - - /* Combine the register masks. */ - ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask; - ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask; - ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0]; - ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1]; - ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2]; - ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3]; - } - - /* Write out the external symbols. */ - ecoff_link_hash_traverse (ecoff_hash_table (info), - ecoff_link_write_external, - (PTR) abfd); - - if (info->relocateable) - { - /* We need to make a pass over the link_orders to count up the - number of relocations we will need to output, so that we know - how much space they will take up. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - o->reloc_count = 0; - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - if (p->type == bfd_indirect_link_order) - o->reloc_count += p->u.indirect.section->reloc_count; - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - } - } - - /* Compute the reloc and symbol file positions. */ - ecoff_compute_reloc_file_positions (abfd); - - /* Write out the debugging information. */ - if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug, - &backend->debug_swap, info, - ecoff_data (abfd)->sym_filepos)) - return false; - - bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info); - - if (info->relocateable) - { - /* Now reset the reloc_count field of the sections in the output - BFD to 0, so that we can use them to keep track of how many - relocs we have output thus far. */ - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - o->reloc_count = 0; - } - - /* Get a value for the GP register. */ - if (ecoff_data (abfd)->gp == 0) - { - struct bfd_link_hash_entry *h; - - h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true); - if (h != (struct bfd_link_hash_entry *) NULL - && h->type == bfd_link_hash_defined) - ecoff_data (abfd)->gp = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); - else if (info->relocateable) - { - bfd_vma lo; - - /* Make up a value. */ - lo = (bfd_vma) -1; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - if (o->vma < lo - && (strcmp (o->name, _SBSS) == 0 - || strcmp (o->name, _SDATA) == 0 - || strcmp (o->name, _LIT4) == 0 - || strcmp (o->name, _LIT8) == 0 - || strcmp (o->name, _LITA) == 0)) - lo = o->vma; - } - ecoff_data (abfd)->gp = lo + 0x8000; - } - else - { - /* If the relocate_section function needs to do a reloc - involving the GP value, it should make a reloc_dangerous - callback to warn that GP is not defined. */ - } - } - - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_ecoff_flavour)) - { - if (! ecoff_indirect_link_order (abfd, info, o, p)) - return false; - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! ecoff_reloc_link_order (abfd, info, o, p)) - return false; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; - } - } - } - - bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax; - - ecoff_data (abfd)->linker = true; - - return true; -} - -/* Accumulate the debugging information for an input BFD into the - output BFD. This must read in the symbolic information of the - input BFD. */ - -static boolean -ecoff_final_link_debug_accumulate (output_bfd, input_bfd, info, handle) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - PTR handle; -{ - struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info; - const struct ecoff_debug_swap * const swap = - &ecoff_backend (input_bfd)->debug_swap; - HDRR *symhdr = &debug->symbolic_header; - boolean ret; - -#define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ - { \ - debug->ptr = (type) malloc (size * symhdr->count); \ - if (debug->ptr == NULL) \ - { \ - bfd_set_error (bfd_error_no_memory); \ - ret = false; \ - goto return_something; \ - } \ - if ((bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) \ - != 0) \ - || (bfd_read (debug->ptr, size, symhdr->count, \ - input_bfd) != size * symhdr->count)) \ - { \ - ret = false; \ - goto return_something; \ - } \ - } - - /* If raw_syments is not NULL, then the data was already by read by - _bfd_ecoff_slurp_symbolic_info. */ - if (ecoff_data (input_bfd)->raw_syments == NULL) - { - READ (line, cbLineOffset, cbLine, sizeof (unsigned char), - unsigned char *); - READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); - READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); - READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); - READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); - READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), - union aux_ext *); - READ (ss, cbSsOffset, issMax, sizeof (char), char *); - READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); - READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); - } -#undef READ - - /* We do not read the external strings or the external symbols. */ - - ret = (bfd_ecoff_debug_accumulate - (handle, output_bfd, &ecoff_data (output_bfd)->debug_info, - &ecoff_backend (output_bfd)->debug_swap, - input_bfd, debug, swap, info)); - - return_something: - if (ecoff_data (input_bfd)->raw_syments == NULL) - { - if (debug->line != NULL) - free (debug->line); - if (debug->external_dnr != NULL) - free (debug->external_dnr); - if (debug->external_pdr != NULL) - free (debug->external_pdr); - if (debug->external_sym != NULL) - free (debug->external_sym); - if (debug->external_opt != NULL) - free (debug->external_opt); - if (debug->external_aux != NULL) - free (debug->external_aux); - if (debug->ss != NULL) - free (debug->ss); - if (debug->external_fdr != NULL) - free (debug->external_fdr); - if (debug->external_rfd != NULL) - free (debug->external_rfd); - - /* Make sure we don't accidentally follow one of these pointers - into freed memory. */ - debug->line = NULL; - debug->external_dnr = NULL; - debug->external_pdr = NULL; - debug->external_sym = NULL; - debug->external_opt = NULL; - debug->external_aux = NULL; - debug->ss = NULL; - debug->external_fdr = NULL; - debug->external_rfd = NULL; - } - - return ret; -} - -/* Put out information for an external symbol. These come only from - the hash table. */ - -static boolean -ecoff_link_write_external (h, data) - struct ecoff_link_hash_entry *h; - PTR data; -{ - bfd *output_bfd = (bfd *) data; - - /* FIXME: We should check if this symbol is being stripped. */ - - if (h->written) - return true; - - if (h->abfd == (bfd *) NULL) - { - h->esym.jmptbl = 0; - h->esym.cobol_main = 0; - h->esym.weakext = 0; - h->esym.reserved = 0; - h->esym.ifd = ifdNil; - h->esym.asym.value = 0; - h->esym.asym.st = stGlobal; - - if (h->root.type != bfd_link_hash_defined) - h->esym.asym.sc = scAbs; - else - { - asection *output_section; - const char *name; - - output_section = h->root.u.def.section->output_section; - name = bfd_section_name (output_section->owner, output_section); - - if (strcmp (name, _TEXT) == 0) - h->esym.asym.sc = scText; - else if (strcmp (name, _DATA) == 0) - h->esym.asym.sc = scData; - else if (strcmp (name, _SDATA) == 0) - h->esym.asym.sc = scSData; - else if (strcmp (name, _RDATA) == 0) - h->esym.asym.sc = scRData; - else if (strcmp (name, _BSS) == 0) - h->esym.asym.sc = scBss; - else if (strcmp (name, _SBSS) == 0) - h->esym.asym.sc = scSBss; - else if (strcmp (name, _INIT) == 0) - h->esym.asym.sc = scInit; - else if (strcmp (name, _FINI) == 0) - h->esym.asym.sc = scFini; - else if (strcmp (name, _PDATA) == 0) - h->esym.asym.sc = scPData; - else if (strcmp (name, _XDATA) == 0) - h->esym.asym.sc = scXData; - else - h->esym.asym.sc = scAbs; - } - - h->esym.asym.reserved = 0; - h->esym.asym.index = indexNil; - } - else if (h->esym.ifd != -1) - { - struct ecoff_debug_info *debug; - - /* Adjust the FDR index for the symbol by that used for the - input BFD. */ - debug = &ecoff_data (h->abfd)->debug_info; - BFD_ASSERT (h->esym.ifd >= 0 - && h->esym.ifd < debug->symbolic_header.ifdMax); - h->esym.ifd = debug->ifdmap[h->esym.ifd]; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - case bfd_link_hash_weak: - if (h->esym.asym.sc != scUndefined - && h->esym.asym.sc != scSUndefined) - h->esym.asym.sc = scUndefined; - break; - case bfd_link_hash_defined: - if (h->esym.asym.sc == scUndefined - || h->esym.asym.sc == scSUndefined) - h->esym.asym.sc = scAbs; - else if (h->esym.asym.sc == scCommon) - h->esym.asym.sc = scBss; - else if (h->esym.asym.sc == scSCommon) - h->esym.asym.sc = scSBss; - h->esym.asym.value = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - break; - case bfd_link_hash_common: - if (h->esym.asym.sc != scCommon - && h->esym.asym.sc != scSCommon) - h->esym.asym.sc = scCommon; - h->esym.asym.value = h->root.u.c.size; - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: Ignore these for now. The circumstances under which - they should be written out are not clear to me. */ - return true; - } - - /* bfd_ecoff_debug_one_external uses iextMax to keep track of the - symbol number. */ - h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax; - h->written = 1; - - return (bfd_ecoff_debug_one_external - (output_bfd, &ecoff_data (output_bfd)->debug_info, - &ecoff_backend (output_bfd)->debug_swap, h->root.root.string, - &h->esym)); -} - -/* Relocate and write an ECOFF section into an ECOFF output file. */ - -static boolean -ecoff_indirect_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - asection *input_section; - bfd *input_bfd; - struct ecoff_section_tdata *section_tdata; - bfd_size_type raw_size; - bfd_size_type cooked_size; - bfd_byte *contents = NULL; - bfd_size_type external_reloc_size; - bfd_size_type external_relocs_size; - PTR external_relocs = NULL; - - BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); - - if (link_order->size == 0) - return true; - - input_section = link_order->u.indirect.section; - input_bfd = input_section->owner; - section_tdata = ecoff_section_data (input_bfd, input_section); - - raw_size = input_section->_raw_size; - cooked_size = input_section->_cooked_size; - if (cooked_size == 0) - cooked_size = raw_size; - - BFD_ASSERT (input_section->output_section == output_section); - BFD_ASSERT (input_section->output_offset == link_order->offset); - BFD_ASSERT (cooked_size == link_order->size); - - /* Get the section contents. We allocate memory for the larger of - the size before relocating and the size after relocating. */ - contents = (bfd_byte *) malloc (raw_size >= cooked_size - ? raw_size - : cooked_size); - if (contents == NULL && raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - /* If we are relaxing, the contents may have already been read into - memory, in which case we copy them into our new buffer. We don't - simply reuse the old buffer in case cooked_size > raw_size. */ - if (section_tdata != (struct ecoff_section_tdata *) NULL - && section_tdata->contents != (bfd_byte *) NULL) - memcpy (contents, section_tdata->contents, raw_size); - else - { - if (! bfd_get_section_contents (input_bfd, input_section, - (PTR) contents, - (file_ptr) 0, raw_size)) - goto error_return; - } - - /* Get the relocs. If we are relaxing MIPS code, they will already - have been read in. Otherwise, we read them in now. */ - external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size; - external_relocs_size = external_reloc_size * input_section->reloc_count; - - if (section_tdata != (struct ecoff_section_tdata *) NULL) - external_relocs = section_tdata->external_relocs; - else - { - external_relocs = (PTR) malloc (external_relocs_size); - if (external_relocs == NULL && external_relocs_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0 - || (bfd_read (external_relocs, 1, external_relocs_size, input_bfd) - != external_relocs_size)) - goto error_return; - } - - /* Relocate the section contents. */ - if (! ((*ecoff_backend (input_bfd)->relocate_section) - (output_bfd, info, input_bfd, input_section, contents, - external_relocs))) - goto error_return; - - /* Write out the relocated section. */ - if (! bfd_set_section_contents (output_bfd, - output_section, - (PTR) contents, - input_section->output_offset, - cooked_size)) - goto error_return; - - /* If we are producing relocateable output, the relocs were - modified, and we write them out now. We use the reloc_count - field of output_section to keep track of the number of relocs we - have output so far. */ - if (info->relocateable) - { - if (bfd_seek (output_bfd, - (output_section->rel_filepos + - output_section->reloc_count * external_reloc_size), - SEEK_SET) != 0 - || (bfd_write (external_relocs, 1, external_relocs_size, output_bfd) - != external_relocs_size)) - goto error_return; - output_section->reloc_count += input_section->reloc_count; - } - - if (contents != NULL) - free (contents); - if (external_relocs != NULL && section_tdata == NULL) - free (external_relocs); - return true; - - error_return: - if (contents != NULL) - free (contents); - if (external_relocs != NULL && section_tdata == NULL) - free (external_relocs); - return false; -} - -/* Generate a reloc when linking an ECOFF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static boolean -ecoff_reloc_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - arelent rel; - struct internal_reloc in; - bfd_size_type external_reloc_size; - bfd_byte *rbuf; - boolean ok; - - /* We set up an arelent to pass to the backend adjust_reloc_out - routine. */ - rel.address = link_order->offset; - - rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (rel.howto == (const reloc_howto_type *) NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - if (link_order->type == bfd_section_reloc_link_order) - rel.sym_ptr_ptr = link_order->u.reloc.p->u.section->symbol_ptr_ptr; - else - { - /* We can't set up a reloc against a symbol correctly, because - we have no asymbol structure. Currently no adjust_reloc_out - routine cases. */ - rel.sym_ptr_ptr = (asymbol **) NULL; - } - - /* All ECOFF relocs are in-place. Put the addend into the object - file. */ - - BFD_ASSERT (rel.howto->partial_inplace); - if (link_order->u.reloc.p->addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (rel.howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - rstat = _bfd_relocate_contents (rel.howto, output_bfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - rel.howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - rel.addend = 0; - - /* Move the information into a internal_reloc structure. */ - in.r_vaddr = (rel.address - + bfd_get_section_vma (output_bfd, output_section)); - in.r_type = rel.howto->type; - - if (link_order->type == bfd_symbol_reloc_link_order) - { - struct ecoff_link_hash_entry *h; - - h = ecoff_link_hash_lookup (ecoff_hash_table (info), - link_order->u.reloc.p->u.name, - false, false, true); - if (h != (struct ecoff_link_hash_entry *) NULL - && h->indx != -1) - in.r_symndx = h->indx; - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - in.r_symndx = 0; - } - in.r_extern = 1; - } - else - { - CONST char *name; - - name = bfd_get_section_name (output_bfd, - link_order->u.reloc.p->u.section); - if (strcmp (name, ".text") == 0) - in.r_symndx = RELOC_SECTION_TEXT; - else if (strcmp (name, ".rdata") == 0) - in.r_symndx = RELOC_SECTION_RDATA; - else if (strcmp (name, ".data") == 0) - in.r_symndx = RELOC_SECTION_DATA; - else if (strcmp (name, ".sdata") == 0) - in.r_symndx = RELOC_SECTION_SDATA; - else if (strcmp (name, ".sbss") == 0) - in.r_symndx = RELOC_SECTION_SBSS; - else if (strcmp (name, ".bss") == 0) - in.r_symndx = RELOC_SECTION_BSS; - else if (strcmp (name, ".init") == 0) - in.r_symndx = RELOC_SECTION_INIT; - else if (strcmp (name, ".lit8") == 0) - in.r_symndx = RELOC_SECTION_LIT8; - else if (strcmp (name, ".lit4") == 0) - in.r_symndx = RELOC_SECTION_LIT4; - else if (strcmp (name, ".xdata") == 0) - in.r_symndx = RELOC_SECTION_XDATA; - else if (strcmp (name, ".pdata") == 0) - in.r_symndx = RELOC_SECTION_PDATA; - else if (strcmp (name, ".fini") == 0) - in.r_symndx = RELOC_SECTION_FINI; - else if (strcmp (name, ".lita") == 0) - in.r_symndx = RELOC_SECTION_LITA; - else if (strcmp (name, "*ABS*") == 0) - in.r_symndx = RELOC_SECTION_ABS; - else - abort (); - in.r_extern = 0; - } - - /* Let the BFD backend adjust the reloc. */ - (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in); - - /* Get some memory and swap out the reloc. */ - external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size; - rbuf = (bfd_byte *) malloc (external_reloc_size); - if (rbuf == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (PTR) rbuf); - - ok = (bfd_seek (output_bfd, - (output_section->rel_filepos + - output_section->reloc_count * external_reloc_size), - SEEK_SET) == 0 - && (bfd_write ((PTR) rbuf, 1, external_reloc_size, output_bfd) - == external_reloc_size)); - - if (ok) - ++output_section->reloc_count; - - free (rbuf); - - return ok; -} diff --git a/gnu/usr.bin/gdb/bfd/ecofflink.c b/gnu/usr.bin/gdb/bfd/ecofflink.c deleted file mode 100644 index f42025e..0000000 --- a/gnu/usr.bin/gdb/bfd/ecofflink.c +++ /dev/null @@ -1,1616 +0,0 @@ -/* Routines to link ECOFF debugging information. - Copyright 1993 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "obstack.h" -#include "coff/internal.h" -#include "coff/sym.h" -#include "coff/symconst.h" -#include "coff/ecoff.h" - -static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend, - size_t need)); -static struct bfd_hash_entry *string_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); -static void ecoff_align_debug PARAMS ((bfd *abfd, - struct ecoff_debug_info *debug, - const struct ecoff_debug_swap *swap)); -static boolean ecoff_write_symhdr PARAMS ((bfd *, struct ecoff_debug_info *, - const struct ecoff_debug_swap *, - file_ptr where)); - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* The minimum amount of data to allocate. */ -#define ALLOC_SIZE (4064) - -/* Add bytes to a buffer. Return success. */ - -static boolean -ecoff_add_bytes (buf, bufend, need) - char **buf; - char **bufend; - size_t need; -{ - size_t have; - size_t want; - char *newbuf; - - have = *bufend - *buf; - if (have > need) - want = ALLOC_SIZE; - else - { - want = need - have; - if (want < ALLOC_SIZE) - want = ALLOC_SIZE; - } - if (*buf == NULL) - newbuf = (char *) malloc (have + want); - else - newbuf = (char *) realloc (*buf, have + want); - if (newbuf == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - *buf = newbuf; - *bufend = *buf + have + want; - return true; -} - -/* We keep a hash table which maps strings to numbers. We use it to - map FDR names to indices in the output file, and to map local - strings when combining stabs debugging information. */ - -struct string_hash_entry -{ - struct bfd_hash_entry root; - /* FDR index or string table offset. */ - long val; - /* Next entry in string table. */ - struct string_hash_entry *next; -}; - -struct string_hash_table -{ - struct bfd_hash_table table; -}; - -/* Routine to create an entry in a string hash table. */ - -static struct bfd_hash_entry * -string_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct string_hash_entry *ret = (struct string_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct string_hash_entry *) NULL) - ret = ((struct string_hash_entry *) - bfd_hash_allocate (table, sizeof (struct string_hash_entry))); - if (ret == (struct string_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct string_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->val = -1; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in an string hash table. */ - -#define string_hash_lookup(t, string, create, copy) \ - ((struct string_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* We can't afford to read in all the debugging information when we do - a link. Instead, we build a list of these structures to show how - different parts of the input file map to the output file. */ - -struct shuffle -{ - /* The next entry in this linked list. */ - struct shuffle *next; - /* The length of the information. */ - unsigned long size; - /* Whether this information comes from a file or not. */ - boolean filep; - union - { - struct - { - /* The BFD the data comes from. */ - bfd *input_bfd; - /* The offset within input_bfd. */ - file_ptr offset; - } file; - /* The data to be written out. */ - PTR memory; - } u; -}; - -/* This structure holds information across calls to - bfd_ecoff_debug_accumulate. */ - -struct accumulate -{ - /* The FDR hash table. */ - struct string_hash_table fdr_hash; - /* The strings hash table. */ - struct string_hash_table str_hash; - /* Linked lists describing how to shuffle the input debug - information into the output file. We keep a pointer to both the - head and the tail. */ - struct shuffle *line; - struct shuffle *line_end; - struct shuffle *pdr; - struct shuffle *pdr_end; - struct shuffle *sym; - struct shuffle *sym_end; - struct shuffle *opt; - struct shuffle *opt_end; - struct shuffle *aux; - struct shuffle *aux_end; - struct shuffle *ss; - struct shuffle *ss_end; - struct string_hash_entry *ss_hash; - struct string_hash_entry *ss_hash_end; - struct shuffle *fdr; - struct shuffle *fdr_end; - struct shuffle *rfd; - struct shuffle *rfd_end; - /* The size of the largest file shuffle. */ - unsigned long largest_file_shuffle; - /* An obstack for debugging information. */ - struct obstack memory; -}; - -/* Add a file entry to a shuffle list. */ - -static boolean add_file_shuffle PARAMS ((struct accumulate *, - struct shuffle **, - struct shuffle **, bfd *, file_ptr, - unsigned long)); - -static boolean -add_file_shuffle (ainfo, head, tail, input_bfd, offset, size) - struct accumulate *ainfo; - struct shuffle **head; - struct shuffle **tail; - bfd *input_bfd; - file_ptr offset; - unsigned long size; -{ - struct shuffle *n; - - if (*tail != (struct shuffle *) NULL - && (*tail)->filep - && (*tail)->u.file.input_bfd == input_bfd - && (*tail)->u.file.offset + (*tail)->size == offset) - { - /* Just merge this entry onto the existing one. */ - (*tail)->size += size; - if ((*tail)->size > ainfo->largest_file_shuffle) - ainfo->largest_file_shuffle = (*tail)->size; - return true; - } - - n = (struct shuffle *) obstack_alloc (&ainfo->memory, - sizeof (struct shuffle)); - if (!n) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - n->next = NULL; - n->size = size; - n->filep = true; - n->u.file.input_bfd = input_bfd; - n->u.file.offset = offset; - if (*head == (struct shuffle *) NULL) - *head = n; - if (*tail != (struct shuffle *) NULL) - (*tail)->next = n; - *tail = n; - if (size > ainfo->largest_file_shuffle) - ainfo->largest_file_shuffle = size; - return true; -} - -/* Add a memory entry to a shuffle list. */ - -static boolean add_memory_shuffle PARAMS ((struct accumulate *, - struct shuffle **head, - struct shuffle **tail, - bfd_byte *data, unsigned long size)); - -static boolean -add_memory_shuffle (ainfo, head, tail, data, size) - struct accumulate *ainfo; - struct shuffle **head; - struct shuffle **tail; - bfd_byte *data; - unsigned long size; -{ - struct shuffle *n; - - n = (struct shuffle *) obstack_alloc (&ainfo->memory, - sizeof (struct shuffle)); - if (!n) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - n->next = NULL; - n->size = size; - n->filep = false; - n->u.memory = (PTR) data; - if (*head == (struct shuffle *) NULL) - *head = n; - if (*tail != (struct shuffle *) NULL) - (*tail)->next = n; - *tail = n; - return true; -} - -/* Initialize the FDR hash table. This returns a handle which is then - passed in to bfd_ecoff_debug_accumulate, et. al. */ - -/*ARGSUSED*/ -PTR -bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info) - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo; - - ainfo = (struct accumulate *) malloc (sizeof (struct accumulate)); - if (!ainfo) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc, - 1021)) - return NULL; - - ainfo->line = NULL; - ainfo->line_end = NULL; - ainfo->pdr = NULL; - ainfo->pdr_end = NULL; - ainfo->sym = NULL; - ainfo->sym_end = NULL; - ainfo->opt = NULL; - ainfo->opt_end = NULL; - ainfo->aux = NULL; - ainfo->aux_end = NULL; - ainfo->ss = NULL; - ainfo->ss_end = NULL; - ainfo->ss_hash = NULL; - ainfo->ss_hash_end = NULL; - ainfo->fdr = NULL; - ainfo->fdr_end = NULL; - ainfo->rfd = NULL; - ainfo->rfd_end = NULL; - - ainfo->largest_file_shuffle = 0; - - if (! info->relocateable) - { - if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc)) - return NULL; - - /* The first entry in the string table is the empty string. */ - output_debug->symbolic_header.issMax = 1; - } - - if (!obstack_begin (&ainfo->memory, 4050)) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - return (PTR) ainfo; -} - -/* Free the accumulated debugging information. */ - -/*ARGSUSED*/ -void -bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - - bfd_hash_table_free (&ainfo->fdr_hash.table); - - if (! info->relocateable) - bfd_hash_table_free (&ainfo->str_hash.table); - - obstack_free (&ainfo->memory, (PTR) NULL); - - free (ainfo); -} - -/* Accumulate the debugging information from INPUT_BFD into - OUTPUT_BFD. The INPUT_DEBUG argument points to some ECOFF - debugging information which we want to link into the information - pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and - INPUT_SWAP point to the swapping information needed. INFO is the - linker information structure. HANDLE is returned by - bfd_ecoff_debug_init. */ - -/*ARGSUSED*/ -boolean -bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap, - input_bfd, input_debug, input_swap, - info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - bfd *input_bfd; - struct ecoff_debug_info *input_debug; - const struct ecoff_debug_swap *input_swap; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) - = input_swap->swap_sym_in; - void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *)) - = input_swap->swap_rfd_in; - void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR)) - = output_swap->swap_sym_out; - void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR)) - = output_swap->swap_fdr_out; - void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR)) - = output_swap->swap_rfd_out; - bfd_size_type external_pdr_size = output_swap->external_pdr_size; - bfd_size_type external_sym_size = output_swap->external_sym_size; - bfd_size_type external_opt_size = output_swap->external_opt_size; - bfd_size_type external_fdr_size = output_swap->external_fdr_size; - bfd_size_type external_rfd_size = output_swap->external_rfd_size; - HDRR * const output_symhdr = &output_debug->symbolic_header; - HDRR * const input_symhdr = &input_debug->symbolic_header; - bfd_vma section_adjust[scMax]; - asection *sec; - bfd_byte *fdr_start; - bfd_byte *fdr_ptr; - bfd_byte *fdr_end; - bfd_size_type fdr_add; - unsigned int copied; - RFDT i; - unsigned long sz; - bfd_byte *rfd_out; - bfd_byte *rfd_in; - bfd_byte *rfd_end; - long newrfdbase = 0; - long oldrfdbase = 0; - bfd_byte *fdr_out; - - /* Use section_adjust to hold the value to add to a symbol in a - particular section. */ - memset ((PTR) section_adjust, 0, sizeof section_adjust); - -#define SET(name, indx) \ - sec = bfd_get_section_by_name (input_bfd, name); \ - if (sec != NULL) \ - section_adjust[indx] = (sec->output_section->vma \ - + sec->output_offset \ - - sec->vma); - - SET (".text", scText); - SET (".data", scData); - SET (".bss", scBss); - SET (".sdata", scSData); - SET (".sbss", scSBss); - /* scRdata section may be either .rdata or .rodata. */ - SET (".rdata", scRData); - SET (".rodata", scRData); - SET (".init", scInit); - SET (".fini", scFini); - -#undef SET - - /* Find all the debugging information based on the FDR's. We need - to handle them whether they are swapped or not. */ - if (input_debug->fdr != (FDR *) NULL) - { - fdr_start = (bfd_byte *) input_debug->fdr; - fdr_add = sizeof (FDR); - } - else - { - fdr_start = (bfd_byte *) input_debug->external_fdr; - fdr_add = input_swap->external_fdr_size; - } - fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add; - - input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, - (input_symhdr->ifdMax - * sizeof (RFDT))); - - sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size; - rfd_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!input_debug->ifdmap || !rfd_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz)) - return false; - - copied = 0; - - /* Look through the FDR's to see which ones we are going to include - in the final output. We do not want duplicate FDR information - for header files, because ECOFF debugging is often very large. - When we find an FDR with no line information which can be merged, - we look it up in a hash table to ensure that we only include it - once. We keep a table mapping FDR numbers to the final number - they get with the BFD, so that we can refer to it when we write - out the external symbols. */ - for (fdr_ptr = fdr_start, i = 0; - fdr_ptr < fdr_end; - fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size) - { - FDR fdr; - - if (input_debug->fdr != (FDR *) NULL) - fdr = *(FDR *) fdr_ptr; - else - (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); - - /* See if this FDR can be merged with an existing one. */ - if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge) - { - const char *name; - char *lookup; - struct string_hash_entry *fh; - - /* We look up a string formed from the file name and the - number of symbols. Sometimes an include file will - conditionally define a typedef or something based on the - order of include files. Using the number of symbols as a - hash reduces the chance that we will merge symbol - information that should not be merged. */ - name = input_debug->ss + fdr.issBase + fdr.rss; - - lookup = (char *) malloc (strlen (name) + 20); - if (lookup == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - sprintf (lookup, "%s %lx", name, fdr.csym); - - fh = string_hash_lookup (&ainfo->fdr_hash, lookup, true, true); - free (lookup); - if (fh == (struct string_hash_entry *) NULL) - return false; - - if (fh->val != -1) - { - input_debug->ifdmap[i] = fh->val; - (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, - (PTR) rfd_out); - - /* Don't copy this FDR. */ - continue; - } - - fh->val = output_symhdr->ifdMax + copied; - } - - input_debug->ifdmap[i] = output_symhdr->ifdMax + copied; - (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out); - ++copied; - } - - newrfdbase = output_symhdr->crfd; - output_symhdr->crfd += input_symhdr->ifdMax; - - /* Copy over any existing RFD's. RFD's are only created by the - linker, so this will only happen for input files which are the - result of a partial link. */ - rfd_in = (bfd_byte *) input_debug->external_rfd; - rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size; - for (; - rfd_in < rfd_end; - rfd_in += input_swap->external_rfd_size) - { - RFDT rfd; - - (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd); - BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax); - rfd = input_debug->ifdmap[rfd]; - (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out); - rfd_out += external_rfd_size; - } - - oldrfdbase = output_symhdr->crfd; - output_symhdr->crfd += input_symhdr->crfd; - - /* Look through the FDR's and copy over all associated debugging - information. */ - sz = copied * external_fdr_size; - fdr_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!fdr_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz)) - return false; - for (fdr_ptr = fdr_start, i = 0; - fdr_ptr < fdr_end; - fdr_ptr += fdr_add, i++) - { - FDR fdr; - bfd_vma fdr_adr; - bfd_byte *sym_out; - bfd_byte *lraw_src; - bfd_byte *lraw_end; - boolean fgotfilename; - - if (input_debug->ifdmap[i] < output_symhdr->ifdMax) - { - /* We are not copying this FDR. */ - continue; - } - - if (input_debug->fdr != (FDR *) NULL) - fdr = *(FDR *) fdr_ptr; - else - (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr); - - fdr_adr = fdr.adr; - - /* Adjust the FDR address for any changes that may have been - made by relaxing. */ - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - struct ecoff_value_adjust *adjust; - - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (fdr_adr >= adjust->start - && fdr_adr < adjust->end) - fdr.adr += adjust->adjust; - } - - /* FIXME: It is conceivable that this FDR points to the .init or - .fini section, in which case this will not do the right - thing. */ - fdr.adr += section_adjust[scText]; - - /* Swap in the local symbols, adjust their values, and swap them - out again. */ - fgotfilename = false; - sz = fdr.csym * external_sym_size; - sym_out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!sym_out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out, - sz)) - return false; - lraw_src = ((bfd_byte *) input_debug->external_sym - + fdr.isymBase * input_swap->external_sym_size); - lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size; - for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size) - { - SYMR internal_sym; - - (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym); - - BFD_ASSERT (internal_sym.sc != scCommon - && internal_sym.sc != scSCommon); - - /* Adjust the symbol value if appropriate. */ - switch (internal_sym.st) - { - case stNil: - if (ECOFF_IS_STAB (&internal_sym)) - break; - /* Fall through. */ - case stGlobal: - case stStatic: - case stLabel: - case stProc: - case stStaticProc: - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - bfd_vma value; - struct ecoff_value_adjust *adjust; - - value = internal_sym.value; - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (value >= adjust->start - && value < adjust->end) - internal_sym.value += adjust->adjust; - } - internal_sym.value += section_adjust[internal_sym.sc]; - break; - - default: - break; - } - - /* If we are doing a final link, we hash all the strings in - the local symbol table together. This reduces the amount - of space required by debugging information. We don't do - this when performing a relocateable link because it would - prevent us from easily merging different FDR's. */ - if (! info->relocateable) - { - boolean ffilename; - const char *name; - - if (! fgotfilename && internal_sym.iss == fdr.rss) - ffilename = true; - else - ffilename = false; - - /* Hash the name into the string table. */ - name = input_debug->ss + fdr.issBase + internal_sym.iss; - if (*name == '\0') - internal_sym.iss = 0; - else - { - struct string_hash_entry *sh; - - sh = string_hash_lookup (&ainfo->str_hash, name, true, true); - if (sh == (struct string_hash_entry *) NULL) - return false; - if (sh->val == -1) - { - sh->val = output_symhdr->issMax; - output_symhdr->issMax += strlen (name) + 1; - if (ainfo->ss_hash == (struct string_hash_entry *) NULL) - ainfo->ss_hash = sh; - if (ainfo->ss_hash_end - != (struct string_hash_entry *) NULL) - ainfo->ss_hash_end->next = sh; - ainfo->ss_hash_end = sh; - } - internal_sym.iss = sh->val; - } - - if (ffilename) - { - fdr.rss = internal_sym.iss; - fgotfilename = true; - } - } - - (*swap_sym_out) (output_bfd, &internal_sym, sym_out); - sym_out += external_sym_size; - } - - fdr.isymBase = output_symhdr->isymMax; - output_symhdr->isymMax += fdr.csym; - - /* Copy the information that does not need swapping. */ - - /* FIXME: If we are relaxing, we need to adjust the line - numbers. Frankly, forget it. Anybody using stabs debugging - information will not use this line number information, and - stabs are adjusted correctly. */ - if (fdr.cbLine > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end, - input_bfd, - input_symhdr->cbLineOffset + fdr.cbLineOffset, - fdr.cbLine)) - return false; - fdr.ilineBase = output_symhdr->ilineMax; - fdr.cbLineOffset = output_symhdr->cbLine; - output_symhdr->ilineMax += fdr.cline; - output_symhdr->cbLine += fdr.cbLine; - } - if (fdr.caux > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end, - input_bfd, - (input_symhdr->cbAuxOffset - + fdr.iauxBase * sizeof (union aux_ext)), - fdr.caux * sizeof (union aux_ext))) - return false; - fdr.iauxBase = output_symhdr->iauxMax; - output_symhdr->iauxMax += fdr.caux; - } - if (! info->relocateable) - { - - /* When are are hashing strings, we lie about the number of - strings attached to each FDR. We need to set cbSs - because some versions of dbx apparently use it to decide - how much of the string table to read in. */ - fdr.issBase = 0; - fdr.cbSs = output_symhdr->issMax; - } - else if (fdr.cbSs > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, - input_bfd, - input_symhdr->cbSsOffset + fdr.issBase, - fdr.cbSs)) - return false; - fdr.issBase = output_symhdr->issMax; - output_symhdr->issMax += fdr.cbSs; - } - - if ((output_bfd->xvec->header_byteorder_big_p - == input_bfd->xvec->header_byteorder_big_p) - && input_debug->adjust == (struct ecoff_value_adjust *) NULL) - { - /* The two BFD's have the same endianness, and we don't have - to adjust the PDR addresses, so simply copying the - information will suffice. */ - BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size); - if (fdr.cpd > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, - input_bfd, - (input_symhdr->cbPdOffset - + fdr.ipdFirst * external_pdr_size), - fdr.cpd * external_pdr_size)) - return false; - } - BFD_ASSERT (external_opt_size == input_swap->external_opt_size); - if (fdr.copt > 0) - { - if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, - input_bfd, - (input_symhdr->cbOptOffset - + fdr.ioptBase * external_opt_size), - fdr.copt * external_opt_size)) - return false; - } - } - else - { - bfd_size_type outsz, insz; - bfd_byte *in; - bfd_byte *end; - bfd_byte *out; - - /* The two BFD's have different endianness, so we must swap - everything in and out. This code would always work, but - it would be unnecessarily slow in the normal case. */ - outsz = external_pdr_size; - insz = input_swap->external_pdr_size; - in = ((bfd_byte *) input_debug->external_pdr - + fdr.ipdFirst * insz); - end = in + fdr.cpd * insz; - sz = fdr.cpd * outsz; - out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out, - sz)) - return false; - for (; in < end; in += insz, out += outsz) - { - PDR pdr; - - (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr); - - /* If we have been relaxing, we may have to adjust the - address. */ - if (input_debug->adjust != (struct ecoff_value_adjust *) NULL) - { - bfd_vma adr; - struct ecoff_value_adjust *adjust; - - adr = fdr_adr + pdr.adr; - for (adjust = input_debug->adjust; - adjust != (struct ecoff_value_adjust *) NULL; - adjust = adjust->next) - if (adr >= adjust->start - && adr < adjust->end) - pdr.adr += adjust->adjust; - } - - (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out); - } - - /* Swap over the optimization information. */ - outsz = external_opt_size; - insz = input_swap->external_opt_size; - in = ((bfd_byte *) input_debug->external_opt - + fdr.ioptBase * insz); - end = in + fdr.copt * insz; - sz = fdr.copt * outsz; - out = (bfd_byte *) obstack_alloc (&ainfo->memory, sz); - if (!out) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out, - sz)) - return false; - for (; in < end; in += insz, out += outsz) - { - OPTR opt; - - (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt); - (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out); - } - } - - fdr.ipdFirst = output_symhdr->ipdMax; - output_symhdr->ipdMax += fdr.cpd; - fdr.ioptBase = output_symhdr->ioptMax; - output_symhdr->ioptMax += fdr.copt; - - if (fdr.crfd <= 0) - { - /* Point this FDR at the table of RFD's we created. */ - fdr.rfdBase = newrfdbase; - fdr.crfd = input_symhdr->ifdMax; - } - else - { - /* Point this FDR at the remapped RFD's. */ - fdr.rfdBase += oldrfdbase; - } - - (*swap_fdr_out) (output_bfd, &fdr, fdr_out); - fdr_out += external_fdr_size; - ++output_symhdr->ifdMax; - } - - return true; -} - -/* Add a string to the debugging information we are accumulating. - Return the offset from the fdr string base. */ - -static long ecoff_add_string PARAMS ((struct accumulate *, - struct bfd_link_info *, - struct ecoff_debug_info *, - FDR *fdr, const char *string)); - -static long -ecoff_add_string (ainfo, info, debug, fdr, string) - struct accumulate *ainfo; - struct bfd_link_info *info; - struct ecoff_debug_info *debug; - FDR *fdr; - const char *string; -{ - HDRR *symhdr; - size_t len; - bfd_size_type ret; - - symhdr = &debug->symbolic_header; - len = strlen (string); - if (info->relocateable) - { - if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string, - len + 1)) - return -1; - ret = symhdr->issMax; - symhdr->issMax += len + 1; - fdr->cbSs += len + 1; - } - else - { - struct string_hash_entry *sh; - - sh = string_hash_lookup (&ainfo->str_hash, string, true, true); - if (sh == (struct string_hash_entry *) NULL) - return -1; - if (sh->val == -1) - { - sh->val = symhdr->issMax; - symhdr->issMax += len + 1; - if (ainfo->ss_hash == (struct string_hash_entry *) NULL) - ainfo->ss_hash = sh; - if (ainfo->ss_hash_end - != (struct string_hash_entry *) NULL) - ainfo->ss_hash_end->next = sh; - ainfo->ss_hash_end = sh; - } - ret = sh->val; - } - - return ret; -} - -/* Add debugging information from a non-ECOFF file. */ - -boolean -bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug, - output_swap, input_bfd, info) - PTR handle; - bfd *output_bfd; - struct ecoff_debug_info *output_debug; - const struct ecoff_debug_swap *output_swap; - bfd *input_bfd; - struct bfd_link_info *info; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR)) - = output_swap->swap_sym_out; - HDRR *output_symhdr = &output_debug->symbolic_header; - FDR fdr; - asection *sec; - asymbol **symbols; - asymbol **sym_ptr; - asymbol **sym_end; - long symsize; - long symcount; - PTR external_fdr; - - memset ((PTR) &fdr, 0, sizeof fdr); - - sec = bfd_get_section_by_name (input_bfd, ".text"); - if (sec != NULL) - fdr.adr = sec->output_section->vma + sec->output_offset; - else - { - /* FIXME: What about .init or .fini? */ - fdr.adr = 0; - } - - fdr.issBase = output_symhdr->issMax; - fdr.cbSs = 0; - fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr, - bfd_get_filename (input_bfd)); - if (fdr.rss == -1) - return false; - fdr.isymBase = output_symhdr->isymMax; - - /* Get the local symbols from the input BFD. */ - symsize = bfd_get_symtab_upper_bound (input_bfd); - if (symsize < 0) - return false; - symbols = (asymbol **) bfd_alloc (output_bfd, symsize); - if (symbols == (asymbol **) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - symcount = bfd_canonicalize_symtab (input_bfd, symbols); - if (symcount < 0) - return false; - sym_end = symbols + symcount; - - /* Handle the local symbols. Any external symbols are handled - separately. */ - fdr.csym = 0; - for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++) - { - SYMR internal_sym; - PTR external_sym; - - if (((*sym_ptr)->flags & BSF_EXPORT) != 0) - continue; - memset ((PTR) &internal_sym, 0, sizeof internal_sym); - internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr, - (*sym_ptr)->name); - - if (internal_sym.iss == -1) - return false; - if (bfd_is_com_section ((*sym_ptr)->section) - || bfd_is_und_section ((*sym_ptr)->section)) - internal_sym.value = (*sym_ptr)->value; - else - internal_sym.value = ((*sym_ptr)->value - + (*sym_ptr)->section->output_offset - + (*sym_ptr)->section->output_section->vma); - internal_sym.st = stNil; - internal_sym.sc = scUndefined; - internal_sym.index = indexNil; - - external_sym = (PTR) obstack_alloc (&ainfo->memory, - output_swap->external_sym_size); - if (!external_sym) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - (*swap_sym_out) (output_bfd, &internal_sym, external_sym); - add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, - external_sym, output_swap->external_sym_size); - ++fdr.csym; - ++output_symhdr->isymMax; - } - - bfd_release (output_bfd, (PTR) symbols); - - /* Leave everything else in the FDR zeroed out. This will cause - the lang field to be langC. The fBigendian field will - indicate little endian format, but it doesn't matter because - it only applies to aux fields and there are none. */ - external_fdr = (PTR) obstack_alloc (&ainfo->memory, - output_swap->external_fdr_size); - if (!external_fdr) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr); - add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, - external_fdr, output_swap->external_fdr_size); - - ++output_symhdr->ifdMax; - - return true; -} - -/* Set up ECOFF debugging information for the external symbols. - FIXME: This is done using a memory buffer, but it should be - probably be changed to use a shuffle structure. The assembler uses - this interface, so that must be changed to do something else. */ - -boolean -bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr, - set_index) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - boolean relocateable; - boolean (*get_extr) PARAMS ((asymbol *, EXTR *)); - void (*set_index) PARAMS ((asymbol *, bfd_size_type)); -{ - HDRR * const symhdr = &debug->symbolic_header; - asymbol **sym_ptr_ptr; - size_t c; - - sym_ptr_ptr = bfd_get_outsymbols (abfd); - if (sym_ptr_ptr == NULL) - return true; - - for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++) - { - asymbol *sym_ptr; - EXTR esym; - - sym_ptr = *sym_ptr_ptr; - - /* Get the external symbol information. */ - if ((*get_extr) (sym_ptr, &esym) == false) - continue; - - /* If we're producing an executable, move common symbols into - bss. */ - if (relocateable == false) - { - if (esym.asym.sc == scCommon) - esym.asym.sc = scBss; - else if (esym.asym.sc == scSCommon) - esym.asym.sc = scSBss; - } - - if (bfd_is_com_section (sym_ptr->section) - || bfd_is_und_section (sym_ptr->section) - || sym_ptr->section->output_section == (asection *) NULL) - { - /* FIXME: gas does not keep the value of a small undefined - symbol in the symbol itself, because of relocation - problems. */ - if (esym.asym.sc != scSUndefined - || esym.asym.value == 0 - || sym_ptr->value != 0) - esym.asym.value = sym_ptr->value; - } - else - esym.asym.value = (sym_ptr->value - + sym_ptr->section->output_offset - + sym_ptr->section->output_section->vma); - - if (set_index) - (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax); - - if (! bfd_ecoff_debug_one_external (abfd, debug, swap, - sym_ptr->name, &esym)) - return false; - } - - return true; -} - -/* Add a single external symbol to the debugging information. */ - -boolean -bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - const char *name; - EXTR *esym; -{ - const bfd_size_type external_ext_size = swap->external_ext_size; - void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR)) - = swap->swap_ext_out; - HDRR * const symhdr = &debug->symbolic_header; - size_t namelen; - - namelen = strlen (name); - - if (debug->ssext_end - debug->ssext - < symhdr->issExtMax + namelen + 1) - { - if (ecoff_add_bytes ((char **) &debug->ssext, - (char **) &debug->ssext_end, - symhdr->issExtMax + namelen + 1) - == false) - return false; - } - if ((char *) debug->external_ext_end - (char *) debug->external_ext - < (symhdr->iextMax + 1) * external_ext_size) - { - if (ecoff_add_bytes ((char **) &debug->external_ext, - (char **) &debug->external_ext_end, - (symhdr->iextMax + 1) * external_ext_size) - == false) - return false; - } - - esym->asym.iss = symhdr->issExtMax; - - (*swap_ext_out) (abfd, esym, - ((char *) debug->external_ext - + symhdr->iextMax * swap->external_ext_size)); - - ++symhdr->iextMax; - - strcpy (debug->ssext + symhdr->issExtMax, name); - symhdr->issExtMax += namelen + 1; - - return true; -} - -/* Align the ECOFF debugging information. */ - -/*ARGSUSED*/ -static void -ecoff_align_debug (abfd, debug, swap) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; -{ - HDRR * const symhdr = &debug->symbolic_header; - bfd_size_type debug_align, aux_align, rfd_align; - size_t add; - - /* Adjust the counts so that structures are aligned. */ - debug_align = swap->debug_align; - aux_align = debug_align / sizeof (union aux_ext); - rfd_align = debug_align / swap->external_rfd_size; - - add = debug_align - (symhdr->cbLine & (debug_align - 1)); - if (add != debug_align) - { - if (debug->line != (unsigned char *) NULL) - memset ((PTR) (debug->line + symhdr->cbLine), 0, add); - symhdr->cbLine += add; - } - - add = debug_align - (symhdr->issMax & (debug_align - 1)); - if (add != debug_align) - { - if (debug->ss != (char *) NULL) - memset ((PTR) (debug->ss + symhdr->issMax), 0, add); - symhdr->issMax += add; - } - - add = debug_align - (symhdr->issExtMax & (debug_align - 1)); - if (add != debug_align) - { - if (debug->ssext != (char *) NULL) - memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add); - symhdr->issExtMax += add; - } - - add = aux_align - (symhdr->iauxMax & (aux_align - 1)); - if (add != aux_align) - { - if (debug->external_aux != (union aux_ext *) NULL) - memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0, - add * sizeof (union aux_ext)); - symhdr->iauxMax += add; - } - - add = rfd_align - (symhdr->crfd & (rfd_align - 1)); - if (add != rfd_align) - { - if (debug->external_rfd != (PTR) NULL) - memset ((PTR) ((char *) debug->external_rfd - + symhdr->crfd * swap->external_rfd_size), - 0, add * swap->external_rfd_size); - symhdr->crfd += add; - } -} - -/* Return the size required by the ECOFF debugging information. */ - -bfd_size_type -bfd_ecoff_debug_size (abfd, debug, swap) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; -{ - bfd_size_type tot; - - ecoff_align_debug (abfd, debug, swap); - tot = swap->external_hdr_size; - -#define ADD(count, size) \ - tot += debug->symbolic_header.count * size - - ADD (cbLine, sizeof (unsigned char)); - ADD (idnMax, swap->external_dnr_size); - ADD (ipdMax, swap->external_pdr_size); - ADD (isymMax, swap->external_sym_size); - ADD (ioptMax, swap->external_opt_size); - ADD (iauxMax, sizeof (union aux_ext)); - ADD (issMax, sizeof (char)); - ADD (issExtMax, sizeof (char)); - ADD (ifdMax, swap->external_fdr_size); - ADD (crfd, swap->external_rfd_size); - ADD (iextMax, swap->external_ext_size); - -#undef ADD - - return tot; -} - -/* Write out the ECOFF symbolic header, given the file position it is - going to be placed at. This assumes that the counts are set - correctly. */ - -static boolean -ecoff_write_symhdr (abfd, debug, swap, where) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - file_ptr where; -{ - HDRR * const symhdr = &debug->symbolic_header; - char *buff = NULL; - - ecoff_align_debug (abfd, debug, swap); - - /* Go to the right location in the file. */ - if (bfd_seek (abfd, where, SEEK_SET) != 0) - return false; - - where += swap->external_hdr_size; - - symhdr->magic = swap->sym_magic; - - /* Fill in the file offsets. */ -#define SET(offset, count, size) \ - if (symhdr->count == 0) \ - symhdr->offset = 0; \ - else \ - { \ - symhdr->offset = where; \ - where += symhdr->count * size; \ - } - - SET (cbLineOffset, cbLine, sizeof (unsigned char)); - SET (cbDnOffset, idnMax, swap->external_dnr_size); - SET (cbPdOffset, ipdMax, swap->external_pdr_size); - SET (cbSymOffset, isymMax, swap->external_sym_size); - SET (cbOptOffset, ioptMax, swap->external_opt_size); - SET (cbAuxOffset, iauxMax, sizeof (union aux_ext)); - SET (cbSsOffset, issMax, sizeof (char)); - SET (cbSsExtOffset, issExtMax, sizeof (char)); - SET (cbFdOffset, ifdMax, swap->external_fdr_size); - SET (cbRfdOffset, crfd, swap->external_rfd_size); - SET (cbExtOffset, iextMax, swap->external_ext_size); -#undef SET - - buff = (PTR) malloc (swap->external_hdr_size); - if (buff == NULL && swap->external_hdr_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - (*swap->swap_hdr_out) (abfd, symhdr, buff); - if (bfd_write (buff, 1, swap->external_hdr_size, abfd) - != swap->external_hdr_size) - goto error_return; - - if (buff != NULL) - free (buff); - return true; - error_return: - if (buff != NULL) - free (buff); - return false; -} - -/* Write out the ECOFF debugging information. This function assumes - that the information (the pointers and counts) in *DEBUG have been - set correctly. WHERE is the position in the file to write the - information to. This function fills in the file offsets in the - symbolic header. */ - -boolean -bfd_ecoff_write_debug (abfd, debug, swap, where) - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - file_ptr where; -{ - HDRR * const symhdr = &debug->symbolic_header; - - if (! ecoff_write_symhdr (abfd, debug, swap, where)) - return false; - -#define WRITE(ptr, count, size, offset) \ - BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \ - if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \ - != size * symhdr->count) \ - return false; - - WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset); - WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset); - WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset); - WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset); - WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset); - WRITE (external_aux, iauxMax, sizeof (union aux_ext), cbAuxOffset); - WRITE (ss, issMax, sizeof (char), cbSsOffset); - WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset); - WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset); - WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset); - WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset); -#undef WRITE - - return true; -} - -/* Write out a shuffle list. */ - -static boolean ecoff_write_shuffle PARAMS ((bfd *, - const struct ecoff_debug_swap *, - struct shuffle *, PTR space)); - -static boolean -ecoff_write_shuffle (abfd, swap, shuffle, space) - bfd *abfd; - const struct ecoff_debug_swap *swap; - struct shuffle *shuffle; - PTR space; -{ - register struct shuffle *l; - unsigned long total; - - total = 0; - for (l = shuffle; l != (struct shuffle *) NULL; l = l->next) - { - if (! l->filep) - { - if (bfd_write (l->u.memory, 1, l->size, abfd) != l->size) - return false; - } - else - { - if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0 - || bfd_read (space, 1, l->size, l->u.file.input_bfd) != l->size - || bfd_write (space, 1, l->size, abfd) != l->size) - return false; - } - total += l->size; - } - - if ((total & (swap->debug_align - 1)) != 0) - { - int i; - bfd_byte *s; - - i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) malloc (i); - if (s == NULL && i != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - return false; - } - free (s); - } - - return true; -} - -/* Write out debugging information using accumulated linker - information. */ - -boolean -bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where) - PTR handle; - bfd *abfd; - struct ecoff_debug_info *debug; - const struct ecoff_debug_swap *swap; - struct bfd_link_info *info; - file_ptr where; -{ - struct accumulate *ainfo = (struct accumulate *) handle; - PTR space = NULL; - - if (! ecoff_write_symhdr (abfd, debug, swap, where)) - goto error_return; - - space = (PTR) malloc (ainfo->largest_file_shuffle); - if (space == NULL && ainfo->largest_file_shuffle != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space)) - goto error_return; - - /* The string table is written out from the hash table if this is a - final link. */ - if (info->relocateable) - { - BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL); - if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space)) - goto error_return; - } - else - { - unsigned long total; - bfd_byte null; - struct string_hash_entry *sh; - - BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL); - null = 0; - if (bfd_write ((PTR) &null, 1, 1, abfd) != 1) - goto error_return; - total = 1; - BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1); - for (sh = ainfo->ss_hash; - sh != (struct string_hash_entry *) NULL; - sh = sh->next) - { - size_t len; - - len = strlen (sh->root.string); - if (bfd_write ((PTR) sh->root.string, 1, len + 1, abfd) != len + 1) - goto error_return; - total += len + 1; - } - - if ((total & (swap->debug_align - 1)) != 0) - { - int i; - bfd_byte *s; - - i = swap->debug_align - (total & (swap->debug_align - 1)); - s = (bfd_byte *) malloc (i); - if (s == NULL && i != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - goto error_return; - } - free (s); - } - } - - /* The external strings and symbol are not converted over to using - shuffles. FIXME: They probably should be. */ - if (bfd_write (debug->ssext, 1, debug->symbolic_header.issExtMax, abfd) - != debug->symbolic_header.issExtMax) - goto error_return; - if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0) - { - int i; - bfd_byte *s; - - i = (swap->debug_align - - (debug->symbolic_header.issExtMax & (swap->debug_align - 1))); - s = (bfd_byte *) malloc (i); - if (s == NULL && i != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - memset ((PTR) s, 0, i); - if (bfd_write ((PTR) s, 1, i, abfd) != i) - { - free (s); - goto error_return; - } - free (s); - } - - if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space) - || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space)) - goto error_return; - - BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0 - || debug->symbolic_header.cbExtOffset == bfd_tell (abfd)); - - if (bfd_write (debug->external_ext, swap->external_ext_size, - debug->symbolic_header.iextMax, abfd) - != debug->symbolic_header.iextMax * swap->external_ext_size) - goto error_return; - - if (space != NULL) - free (space); - return true; - - error_return: - if (space != NULL) - free (space); - return false; -} diff --git a/gnu/usr.bin/gdb/bfd/elf.c b/gnu/usr.bin/gdb/bfd/elf.c deleted file mode 100644 index af3e202..0000000 --- a/gnu/usr.bin/gdb/bfd/elf.c +++ /dev/null @@ -1,397 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* - -SECTION - ELF backends - - BFD support for ELF formats is being worked on. - Currently, the best supported back ends are for sparc and i386 - (running svr4 or Solaris 2). - - Documentation of the internals of the support code still needs - to be written. The code is changing quickly enough that we - haven't bothered yet. - */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#define ARCH_SIZE 0 -#include "libelf.h" - -/* Standard ELF hash function. Do not change this function; you will - cause invalid hash tables to be generated. (Well, you would if this - were being used yet.) */ -unsigned long -bfd_elf_hash (name) - CONST unsigned char *name; -{ - unsigned long h = 0; - unsigned long g; - int ch; - - while ((ch = *name++) != '\0') - { - h = (h << 4) + ch; - if ((g = (h & 0xf0000000)) != 0) - { - h ^= g >> 24; - h &= ~g; - } - } - return h; -} - -/* Read a specified number of bytes at a specified offset in an ELF - file, into a newly allocated buffer, and return a pointer to the - buffer. */ - -static char * -elf_read (abfd, offset, size) - bfd * abfd; - long offset; - int size; -{ - char *buf; - - if ((buf = bfd_alloc (abfd, size)) == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - if (bfd_seek (abfd, offset, SEEK_SET) == -1) - return NULL; - if (bfd_read ((PTR) buf, size, 1, abfd) != size) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_file_truncated); - return NULL; - } - return buf; -} - -boolean -elf_mkobject (abfd) - bfd * abfd; -{ - /* this just does initialization */ - /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ - elf_tdata (abfd) = (struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); - if (elf_tdata (abfd) == 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - /* since everything is done at close time, do we need any - initialization? */ - - return true; -} - -char * -elf_get_str_section (abfd, shindex) - bfd * abfd; - unsigned int shindex; -{ - Elf_Internal_Shdr **i_shdrp; - char *shstrtab = NULL; - unsigned int offset; - unsigned int shstrtabsize; - - i_shdrp = elf_elfsections (abfd); - if (i_shdrp == 0 || i_shdrp[shindex] == 0) - return 0; - - shstrtab = i_shdrp[shindex]->rawdata; - if (shstrtab == NULL) - { - /* No cached one, attempt to read, and cache what we read. */ - offset = i_shdrp[shindex]->sh_offset; - shstrtabsize = i_shdrp[shindex]->sh_size; - shstrtab = elf_read (abfd, offset, shstrtabsize); - i_shdrp[shindex]->rawdata = (void *) shstrtab; - } - return shstrtab; -} - -char * -elf_string_from_elf_section (abfd, shindex, strindex) - bfd * abfd; - unsigned int shindex; - unsigned int strindex; -{ - Elf_Internal_Shdr *hdr; - - if (strindex == 0) - return ""; - - hdr = elf_elfsections (abfd)[shindex]; - - if (!hdr->rawdata - && elf_get_str_section (abfd, shindex) == NULL) - return NULL; - - return ((char *) hdr->rawdata) + strindex; -} - -/* Make a BFD section from an ELF section. We store a pointer to the - BFD section in the rawdata field of the header. */ - -boolean -_bfd_elf_make_section_from_shdr (abfd, hdr, name) - bfd *abfd; - Elf_Internal_Shdr *hdr; - const char *name; -{ - asection *newsect; - flagword flags; - - if (hdr->rawdata != NULL) - { - BFD_ASSERT (strcmp (name, ((asection *) hdr->rawdata)->name) == 0); - return true; - } - - newsect = bfd_make_section_anyway (abfd, name); - if (newsect == NULL) - return false; - - newsect->filepos = hdr->sh_offset; - - if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr) - || ! bfd_set_section_size (abfd, newsect, hdr->sh_size) - || ! bfd_set_section_alignment (abfd, newsect, - bfd_log2 (hdr->sh_addralign))) - return false; - - flags = SEC_NO_FLAGS; - if (hdr->sh_type != SHT_NOBITS) - flags |= SEC_HAS_CONTENTS; - if ((hdr->sh_flags & SHF_ALLOC) != 0) - { - flags |= SEC_ALLOC; - if (hdr->sh_type != SHT_NOBITS) - flags |= SEC_LOAD; - } - if ((hdr->sh_flags & SHF_WRITE) == 0) - flags |= SEC_READONLY; - if ((hdr->sh_flags & SHF_EXECINSTR) != 0) - flags |= SEC_CODE; - else if ((flags & SEC_LOAD) != 0) - flags |= SEC_DATA; - - /* The debugging sections appear to be recognized only by name, not - any sort of flag. */ - if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0 - || strncmp (name, ".line", sizeof ".line" - 1) == 0 - || strncmp (name, ".stab", sizeof ".stab" - 1) == 0) - flags |= SEC_DEBUGGING; - - if (! bfd_set_section_flags (abfd, newsect, flags)) - return false; - - hdr->rawdata = (PTR) newsect; - elf_section_data (newsect)->this_hdr = *hdr; - - return true; -} - -/* -INTERNAL_FUNCTION - bfd_elf_find_section - -SYNOPSIS - struct elf_internal_shdr *bfd_elf_find_section (bfd *abfd, char *name); - -DESCRIPTION - Helper functions for GDB to locate the string tables. - Since BFD hides string tables from callers, GDB needs to use an - internal hook to find them. Sun's .stabstr, in particular, - isn't even pointed to by the .stab section, so ordinary - mechanisms wouldn't work to find it, even if we had some. -*/ - -struct elf_internal_shdr * -bfd_elf_find_section (abfd, name) - bfd * abfd; - char *name; -{ - Elf_Internal_Shdr **i_shdrp; - char *shstrtab; - unsigned int max; - unsigned int i; - - i_shdrp = elf_elfsections (abfd); - if (i_shdrp != NULL) - { - shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx); - if (shstrtab != NULL) - { - max = elf_elfheader (abfd)->e_shnum; - for (i = 1; i < max; i++) - if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name)) - return i_shdrp[i]; - } - } - return 0; -} - -const char *const bfd_elf_section_type_names[] = { - "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB", - "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE", - "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM", -}; - -/* ELF relocs are against symbols. If we are producing relocateable - output, and the reloc is against an external symbol, and nothing - has given us any additional addend, the resulting reloc will also - be against the same symbol. In such a case, we don't want to - change anything about the way the reloc is handled, since it will - all be done at final link time. Rather than put special case code - into bfd_perform_relocation, all the reloc types use this howto - function. It just short circuits the reloc if producing - relocateable output against an external symbol. */ - -/*ARGSUSED*/ -bfd_reloc_status_type -bfd_elf_generic_reloc (abfd, - reloc_entry, - symbol, - data, - input_section, - output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0 - && (! reloc_entry->howto->partial_inplace - || reloc_entry->addend == 0)) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - return bfd_reloc_continue; -} - -/* Create an entry in an ELF linker hash table. */ - -struct bfd_hash_entry * -_bfd_elf_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct elf_link_hash_entry *) NULL) - ret = ((struct elf_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry))); - if (ret == (struct elf_link_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_hash_entry *) ret; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct elf_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct elf_link_hash_entry *) NULL) - { - /* Set local fields. */ - ret->indx = -1; - ret->size = 0; - ret->align = 0; - ret->dynindx = -1; - ret->dynstr_index = 0; - ret->weakdef = NULL; - ret->type = STT_NOTYPE; - ret->elf_link_hash_flags = 0; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize an ELF linker hash table. */ - -boolean -_bfd_elf_link_hash_table_init (table, abfd, newfunc) - struct elf_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - table->dynobj = NULL; - table->dynsymcount = 0; - table->dynstr = NULL; - table->bucketcount = 0; - return _bfd_link_hash_table_init (&table->root, abfd, newfunc); -} - -/* Create an ELF linker hash table. */ - -struct bfd_link_hash_table * -_bfd_elf_link_hash_table_create (abfd) - bfd *abfd; -{ - struct elf_link_hash_table *ret; - - ret = ((struct elf_link_hash_table *) - bfd_alloc (abfd, sizeof (struct elf_link_hash_table))); - if (ret == (struct elf_link_hash_table *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - if (! _bfd_elf_link_hash_table_init (ret, abfd, _bfd_elf_link_hash_newfunc)) - { - bfd_release (abfd, ret); - return NULL; - } - - return &ret->root; -} - -/* This is a hook for the ELF emulation code in the generic linker to - tell the backend linker what file name to use for the DT_NEEDED - entry for a dynamic object. */ - -void -bfd_elf_set_dt_needed_name (abfd, name) - bfd *abfd; - const char *name; -{ - elf_dt_needed_name (abfd) = name; -} diff --git a/gnu/usr.bin/gdb/bfd/elf32-i386.c b/gnu/usr.bin/gdb/bfd/elf32-i386.c deleted file mode 100644 index d2b1ebac..0000000 --- a/gnu/usr.bin/gdb/bfd/elf32-i386.c +++ /dev/null @@ -1,931 +0,0 @@ -/* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "libelf.h" - -static CONST struct reloc_howto_struct *elf_i386_reloc_type_lookup - PARAMS ((bfd *, bfd_reloc_code_real_type)); -static void elf_i386_info_to_howto - PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); -static void elf_i386_info_to_howto_rel - PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); -static boolean elf_i386_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_i386_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_i386_allocate_dynamic_section - PARAMS ((bfd *, const char *)); -static boolean elf_i386_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_i386_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **, char *)); -static boolean elf_i386_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static boolean elf_i386_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); - -#define USE_REL 1 /* 386 uses REL relocations instead of RELA */ - -enum reloc_type - { - R_386_NONE = 0, - R_386_32, - R_386_PC32, - R_386_GOT32, - R_386_PLT32, - R_386_COPY, - R_386_GLOB_DAT, - R_386_JUMP_SLOT, - R_386_RELATIVE, - R_386_GOTOFF, - R_386_GOTPC, - R_386_max - }; - -#if 0 -static CONST char *CONST reloc_type_names[] = -{ - "R_386_NONE", - "R_386_32", - "R_386_PC32", - "R_386_GOT32", - "R_386_PLT32", - "R_386_COPY", - "R_386_GLOB_DAT", - "R_386_JUMP_SLOT", - "R_386_RELATIVE", - "R_386_GOTOFF", - "R_386_GOTPC", -}; -#endif - -static reloc_howto_type elf_howto_table[]= -{ - HOWTO(R_386_NONE, 0,0, 0,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_NONE", true,0x00000000,0x00000000,false), - HOWTO(R_386_32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PC32, 0,2,32,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC32", true,0xffffffff,0xffffffff,true), - HOWTO(R_386_GOT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOT32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_PLT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PLT32", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_COPY, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_COPY", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GLOB_DAT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GLOB_DAT", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_JUMP_SLOT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_JUMP_SLOT",true,0xffffffff,0xffffffff,false), - HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false), - HOWTO(R_386_GOTPC, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,false), -}; - -#ifdef DEBUG_GEN_RELOC -#define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) -#else -#define TRACE(str) -#endif - -static CONST struct reloc_howto_struct * -elf_i386_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_NONE: - TRACE ("BFD_RELOC_NONE"); - return &elf_howto_table[ (int)R_386_NONE ]; - - case BFD_RELOC_32: - TRACE ("BFD_RELOC_32"); - return &elf_howto_table[ (int)R_386_32 ]; - - case BFD_RELOC_32_PCREL: - TRACE ("BFD_RELOC_PC32"); - return &elf_howto_table[ (int)R_386_PC32 ]; - - case BFD_RELOC_386_GOT32: - TRACE ("BFD_RELOC_386_GOT32"); - return &elf_howto_table[ (int)R_386_GOT32 ]; - - case BFD_RELOC_386_PLT32: - TRACE ("BFD_RELOC_386_PLT32"); - return &elf_howto_table[ (int)R_386_PLT32 ]; - - case BFD_RELOC_386_COPY: - TRACE ("BFD_RELOC_386_COPY"); - return &elf_howto_table[ (int)R_386_COPY ]; - - case BFD_RELOC_386_GLOB_DAT: - TRACE ("BFD_RELOC_386_GLOB_DAT"); - return &elf_howto_table[ (int)R_386_GLOB_DAT ]; - - case BFD_RELOC_386_JUMP_SLOT: - TRACE ("BFD_RELOC_386_JUMP_SLOT"); - return &elf_howto_table[ (int)R_386_JUMP_SLOT ]; - - case BFD_RELOC_386_RELATIVE: - TRACE ("BFD_RELOC_386_RELATIVE"); - return &elf_howto_table[ (int)R_386_RELATIVE ]; - - case BFD_RELOC_386_GOTOFF: - TRACE ("BFD_RELOC_386_GOTOFF"); - return &elf_howto_table[ (int)R_386_GOTOFF ]; - - case BFD_RELOC_386_GOTPC: - TRACE ("BFD_RELOC_386_GOTPC"); - return &elf_howto_table[ (int)R_386_GOTPC ]; - - default: - break; - } - - TRACE ("Unknown"); - return 0; -} - -static void -elf_i386_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rela *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -static void -elf_i386_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf32_Internal_Rel *dst; -{ - BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); - - cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; -} - -/* Functions for the i386 ELF linker. */ - -/* The name of the dynamic interpreter. This is put in the .interp - section. */ - -#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1" - -/* The size in bytes of an entry in the procedure linkage table. */ - -#define PLT_ENTRY_SIZE 16 - -/* The first entry in an absolute procedure linkage table looks like - this. See the SVR4 ABI i386 supplement to see how this works. */ - -static bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x35, /* pushl contents of address */ - 0, 0, 0, 0, /* replaced with address of .got + 4. */ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of .got + 8. */ - 0, 0, 0, 0 /* pad out to 16 bytes. */ -}; - -/* Subsequent entries in an absolute procedure linkage table look like - this. */ - -static bfd_byte elf_i386_plt_entry[PLT_ENTRY_SIZE] = -{ - 0xff, 0x25, /* jmp indirect */ - 0, 0, 0, 0, /* replaced with address of this symbol in .got. */ - 0x68, /* pushl immediate */ - 0, 0, 0, 0, /* replaced with offset into relocation table. */ - 0xe9, /* jmp relative */ - 0, 0, 0, 0 /* replaced with offset to start of .plt. */ -}; - -/* Create dynamic sections when linking against a dynamic object. */ - -static boolean -elf_i386_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - - /* We need to create .plt, .rel.plt, .got, .dynbss, and .rel.bss - sections. */ - - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - s = bfd_make_section (abfd, ".plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY | SEC_CODE) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - s = bfd_make_section (abfd, ".rel.plt"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - s = bfd_make_section (abfd, ".got"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got - section. We don't do this in the linker script because we don't - want to define the symbol if we are not creating a global offset - table. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - - /* The first three global offset table entries are reserved. */ - s->_raw_size += 3 * 4; - - /* The .dynbss section is a place to put symbols which are defined - by dynamic objects, are referenced by regular objects, and are - not functions. We must allocate space for them in the process - image and use a R_386_COPY reloc to tell the dynamic linker to - initialize them at run time. The linker script puts the .dynbss - section into the .bss section of the final image. */ - s = bfd_make_section (abfd, ".dynbss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, SEC_ALLOC)) - return false; - - /* The .rel.bss section holds copy relocs. This section is not - normally needed. We need to create it here, though, so that the - linker will map it to an output section. If it turns out not to - be needed, we can discard it later. */ - s = bfd_make_section (abfd, ".rel.bss"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, 2)) - return false; - - return true; -} - -/* Adjust a symbol defined by a dynamic object and referenced by a - regular object. The current definition is in some section of the - dynamic object, but we're not including those sections. We have to - change the definition to something the rest of the link can - understand. */ - -static boolean -elf_i386_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - bfd *dynobj; - asection *s; - unsigned int power_of_two; - size_t align; - - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && h->root.type == bfd_link_hash_defined - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour) - && (elf_elfheader (h->root.u.def.section->owner)->e_type - == ET_DYN) - && h->root.u.def.section->output_section == NULL); - - /* If this is a function, put it in the procedure linkage table. We - will fill in the contents of the procedure linkage table later, - when we know the address of the .got section. */ - if (h->type == STT_FUNC) - { - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size += PLT_ENTRY_SIZE; - - /* Set the symbol to this location in the .plt. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got section. */ - - s = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (s != NULL); - s->_raw_size += 4; - - /* We also need to make an entry in the .rel.plt section. */ - - s = bfd_get_section_by_name (dynobj, ".rel.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf32_External_Rel); - - return true; - } - - /* If this is a weak symbol, and there is a real definition, the - processor independent code will have arranged for us to see the - real definition first, and we can just use the same value. */ - if (h->weakdef != NULL) - { - BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined); - h->root.u.def.section = h->weakdef->root.u.def.section; - h->root.u.def.value = h->weakdef->root.u.def.value; - h->align = (bfd_size_type) -1; - return true; - } - - /* This is a reference to a symbol defined by a dynamic object which - is not a function. We must allocate it in our .dynbss section, - which will become part of the .bss section of the executable. - There will be an entry for this symbol in the .dynsym section. - The dynamic object will contain position independent code, so all - references from the dynamic object to this symbol will go through - the global offset table. The dynamic linker will use the .dynsym - entry to determine the address it must put in the global offset - table, so both the dynamic object and the regular object will - refer to the same memory location for the variable. */ - - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); - - /* If the symbol is currently defined in the .bss section of the - dynamic object, then it is OK to simply initialize it to zero. - If the symbol is in some other section, we must generate a - R_386_COPY reloc to tell the dynamic linker to copy the initial - value out of the dynamic object and into the runtime process - image. We need to remember the offset into the .rel.bss section - we are going to use, and we coopt the align field for this - purpose (the align field is only used for common symbols, and - these symbols are always defined). It would be cleaner to use a - new field, but that would waste memory. */ - if ((h->root.u.def.section->flags & SEC_LOAD) == 0) - h->align = (bfd_size_type) -1; - else - { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rel.bss"); - BFD_ASSERT (srel != NULL); - h->align = srel->_raw_size; - srel->_raw_size += sizeof (Elf32_External_Rel); - } - - /* We need to figure out the alignment required for this symbol. I - have no idea how ELF linkers handle this. */ - switch (h->size) - { - case 0: - case 1: - power_of_two = 0; - align = 1; - break; - case 2: - power_of_two = 1; - align = 2; - break; - case 3: - case 4: - power_of_two = 2; - align = 4; - break; - case 5: - case 6: - case 7: - case 8: - power_of_two = 3; - align = 8; - break; - default: - power_of_two = 4; - align = 16; - break; - } - - /* Apply the required alignment. */ - s->_raw_size = BFD_ALIGN (s->_raw_size, align); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) - { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) - return false; - } - - /* Define the symbol as being at this point in the section. */ - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; - - /* Increment the section size to make room for the symbol. */ - s->_raw_size += h->size; - - return true; -} - -/* Allocate contents for a section. */ - -static INLINE boolean -elf_i386_allocate_dynamic_section (dynobj, name) - bfd *dynobj; - const char *name; -{ - register asection *s; - - s = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (s != NULL); - s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - return true; -} - -/* Set the sizes of the dynamic sections. */ - -static boolean -elf_i386_size_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - asection *s; - - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); - - /* Set the contents of the .interp section to the interpreter. */ - if (! info->shared) - { - s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); - s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; - s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; - } - - /* The adjust_dynamic_symbol entry point has determined the sizes of - the various dynamic sections. Allocate some memory for them to - hold contents. */ - if (! elf_i386_allocate_dynamic_section (dynobj, ".plt") - || ! elf_i386_allocate_dynamic_section (dynobj, ".rel.plt") - || ! elf_i386_allocate_dynamic_section (dynobj, ".got") - || ! elf_i386_allocate_dynamic_section (dynobj, ".rel.bss")) - return false; - - /* Add some entries to the .dynamic section. We fill in the values - later, in elf_i386_finish_dynamic_sections, but we must add the - entries now so that we get the correct size for the .dynamic - section. The DT_DEBUG entry is filled in by the dynamic linker - and used by the debugger. */ - if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)) - return false; - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - if (s->_raw_size != 0) - { - if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL) - || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)) - return false; - } - - /* If we didn't need the .rel.bss section, then discard it from the - output file. This is a hack. We don't bother to do it for the - other sections because they normally are needed. */ - s = bfd_get_section_by_name (dynobj, ".rel.bss"); - BFD_ASSERT (s != NULL); - if (s->_raw_size == 0) - { - asection **spp; - - for (spp = &s->output_section->owner->sections; - *spp != s->output_section; - spp = &(*spp)->next) - ; - *spp = s->output_section->next; - --s->output_section->owner->section_count; - } - else - { - if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0) - || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT, - sizeof (Elf32_External_Rel))) - return false; - } - - return true; -} - -/* Relocate an i386 ELF section. */ - -static boolean -elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, - contents, relocs, local_syms, local_sections, - output_names) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; - char *output_names; -{ - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - - rel = relocs; - relend = relocs + input_section->reloc_count; - for (; rel < relend; rel++) - { - int r_type; - const reloc_howto_type *howto; - long r_symndx; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; - asection *sec; - bfd_vma relocation; - bfd_reloc_status_type r; - - r_type = ELF32_R_TYPE (rel->r_info); - if (r_type < 0 || r_type >= (int) R_386_max) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - howto = elf_howto_table + r_type; - - r_symndx = ELF32_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - bfd_vma val; - - sec = local_sections[r_symndx]; - val = bfd_get_32 (input_bfd, contents + rel->r_offset); - val += sec->output_offset + sym->st_value; - bfd_put_32 (input_bfd, val, contents + rel->r_offset); - } - } - - continue; - } - - /* This is a final link. */ - h = NULL; - sym = NULL; - sec = NULL; - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - sec = local_sections[r_symndx]; - relocation = (sec->output_section->vma - + sec->output_offset - + sym->st_value); - } - else - { - long indx; - - indx = r_symndx - symtab_hdr->sh_info; - h = elf_sym_hashes (input_bfd)[indx]; - if (h->root.type == bfd_link_hash_defined) - { - sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); - } - else if (h->root.type == bfd_link_hash_weak) - relocation = 0; - else - { - if (! ((*info->callbacks->undefined_symbol) - (info, h->root.root.string, input_bfd, - input_section, rel->r_offset))) - return false; - relocation = 0; - } - } - - r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rel->r_offset, - relocation, (bfd_vma) 0); - - if (r != bfd_reloc_ok) - { - switch (r) - { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = output_names + sym->st_name; - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rel->r_offset))) - return false; - } - break; - } - } - } - - return true; -} - -/* Finish up dynamic symbol handling. We set the contents of various - dynamic sections here. */ - -static boolean -elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd; - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; -{ - /* If this symbol is not defined by a dynamic object, or is not - referenced by a regular object, ignore it. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - { - /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ - if (strcmp (h->root.root.string, "_DYNAMIC") == 0 - || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) - sym->st_shndx = SHN_ABS; - return true; - } - - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - BFD_ASSERT (h->dynindx != -1); - - if (h->type == STT_FUNC) - { - asection *splt; - asection *sgot; - asection *srel; - bfd_vma plt_index; - bfd_vma got_offset; - Elf_Internal_Rel rel; - - splt = h->root.u.def.section; - BFD_ASSERT (strcmp (bfd_get_section_name (splt->owner, splt), ".plt") - == 0); - sgot = bfd_get_section_by_name (splt->owner, ".got"); - BFD_ASSERT (sgot != NULL); - srel = bfd_get_section_by_name (splt->owner, ".rel.plt"); - BFD_ASSERT (srel != NULL); - - /* FIXME: This only handles an absolute procedure linkage table. - When producing a dynamic object, we need to generate a - position independent procedure linkage table. */ - - /* Get the index in the procedure linkage table which - corresponds to this symbol. This is the index of this symbol - in all the symbols for which we are making plt entries. The - first entry in the procedure linkage table is reserved. */ - plt_index = h->root.u.def.value / PLT_ENTRY_SIZE - 1; - - /* Get the offset into the .got table of the entry that - corresponds to this function. Each .got entry is 4 bytes. - The first three are reserved. */ - got_offset = (plt_index + 3) * 4; - - /* Fill in the entry in the procedure linkage table. */ - memcpy (splt->contents + h->root.u.def.value, elf_i386_plt_entry, - PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset - + got_offset), - splt->contents + h->root.u.def.value + 2); - bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rel), - splt->contents + h->root.u.def.value + 7); - bfd_put_32 (output_bfd, - (h->root.u.def.value + PLT_ENTRY_SIZE), - splt->contents + h->root.u.def.value + 12); - - /* Fill in the entry in the global offset table. */ - bfd_put_32 (output_bfd, - (splt->output_section->vma - + splt->output_offset - + h->root.u.def.value - + 6), - sgot->contents + got_offset); - - /* Fill in the entry in the .rel.plt section. */ - rel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + got_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) srel->contents - + plt_index)); - - /* Mark the symbol as undefined, rather than as defined in the - .plt section. Leave the value alone. */ - sym->st_shndx = SHN_UNDEF; - } - else - { - /* This is not a function. We have already allocated memory for - it in the .bss section (via .dynbss). All we have to do here - is create a COPY reloc if required. */ - if (h->align != (bfd_size_type) -1) - { - asection *s; - Elf_Internal_Rel rel; - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rel.bss"); - BFD_ASSERT (s != NULL); - - rel.r_offset = (h->root.u.def.value - + h->root.u.def.section->output_section->vma - + h->root.u.def.section->output_offset); - rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY); - bfd_elf32_swap_reloc_out (output_bfd, &rel, - ((Elf32_External_Rel *) - (s->contents + h->align))); - } - } - - return true; -} - -/* Finish up the dynamic sections. */ - -static boolean -elf_i386_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; -{ - asection *splt; - asection *sgot; - asection *sdyn; - Elf32_External_Dyn *dyncon, *dynconend; - - splt = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".plt"); - sgot = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".got"); - sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".dynamic"); - BFD_ASSERT (splt != NULL && sgot != NULL && sdyn != NULL); - - dyncon = (Elf32_External_Dyn *) sdyn->contents; - dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - boolean size; - - bfd_elf32_swap_dyn_in (elf_hash_table (info)->dynobj, dyncon, &dyn); - - /* My reading of the SVR4 ABI indicates that the procedure - linkage table relocs (DT_JMPREL) should be included in the - overall relocs (DT_REL). This is what Solaris does. - However, UnixWare can not handle that case. Therefore, we - override the DT_REL and DT_RELSZ entries here to make them - not include the JMPREL relocs. */ - - switch (dyn.d_tag) - { - case DT_PLTGOT: name = ".got"; size = false; break; - case DT_PLTRELSZ: name = ".rel.plt"; size = true; break; - case DT_JMPREL: name = ".rel.plt"; size = false; break; - case DT_REL: name = ".rel.bss"; size = false; break; - case DT_RELSZ: name = ".rel.bss"; size = true; break; - default: name = NULL; size = false; break; - } - - if (name != NULL) - { - asection *s; - - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - if (! size) - dyn.d_un.d_ptr = s->vma; - else - { - if (s->_cooked_size != 0) - dyn.d_un.d_val = s->_cooked_size; - else - dyn.d_un.d_val = s->_raw_size; - } - bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); - } - } - - /* Fill in the first entry in the procedure linkage table. */ - if (splt->_raw_size > 0) - { - memcpy (splt->contents, elf_i386_plt0_entry, PLT_ENTRY_SIZE); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 4, - splt->contents + 2); - bfd_put_32 (output_bfd, - sgot->output_section->vma + sgot->output_offset + 8, - splt->contents + 8); - } - - /* Fill in the first three entries in the global offset table. */ - if (sgot->_raw_size > 0) - { - bfd_put_32 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 4); - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + 8); - } - - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4; - - /* UnixWare sets the entsize of .plt to 4, although that doesn't - really seem like the right value. */ - elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4; - - return true; -} - -#define TARGET_LITTLE_SYM bfd_elf32_i386_vec -#define TARGET_LITTLE_NAME "elf32-i386" -#define ELF_ARCH bfd_arch_i386 -#define ELF_MACHINE_CODE EM_386 -#define elf_info_to_howto elf_i386_info_to_howto -#define elf_info_to_howto_rel elf_i386_info_to_howto_rel -#define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup -#define ELF_MAXPAGESIZE 0x1000 -#define elf_backend_create_dynamic_sections \ - elf_i386_create_dynamic_sections -#define elf_backend_adjust_dynamic_symbol \ - elf_i386_adjust_dynamic_symbol -#define elf_backend_size_dynamic_sections \ - elf_i386_size_dynamic_sections -#define elf_backend_relocate_section elf_i386_relocate_section -#define elf_backend_finish_dynamic_symbol \ - elf_i386_finish_dynamic_symbol -#define elf_backend_finish_dynamic_sections \ - elf_i386_finish_dynamic_sections - -#include "elf32-target.h" diff --git a/gnu/usr.bin/gdb/bfd/elf32-target.h b/gnu/usr.bin/gdb/bfd/elf32-target.h deleted file mode 100644 index 344683e..0000000 --- a/gnu/usr.bin/gdb/bfd/elf32-target.h +++ /dev/null @@ -1,358 +0,0 @@ -/* Target definitions for 32-bit ELF - Copyright 1993, 1994 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This structure contains everything that BFD knows about a target. - It includes things like its byte order, name, what routines to call - to do various operations, etc. Every BFD points to a target structure - with its "xvec" member. - - There are two such structures here: one for big-endian machines and - one for little-endian machines. */ - -#define bfd_elf32_close_and_cleanup _bfd_generic_close_and_cleanup -#define bfd_elf32_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#ifndef bfd_elf32_get_section_contents -#define bfd_elf32_get_section_contents _bfd_generic_get_section_contents -#endif - -#define bfd_elf32_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define bfd_elf32_bfd_relax_section bfd_generic_relax_section -#define bfd_elf32_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr) - -#ifndef bfd_elf32_bfd_copy_private_section_data -#define bfd_elf32_bfd_copy_private_section_data \ - ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true) -#endif -#ifndef bfd_elf32_bfd_copy_private_bfd_data -#define bfd_elf32_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#endif -#ifndef bfd_elf32_bfd_is_local_label -#define bfd_elf32_bfd_is_local_label bfd_generic_is_local_label -#endif - -#ifndef bfd_elf32_get_dynamic_reloc_upper_bound -#define bfd_elf32_get_dynamic_reloc_upper_bound \ - _bfd_nodynamic_get_dynamic_reloc_upper_bound -#endif -#ifndef bfd_elf32_canonicalize_dynamic_reloc -#define bfd_elf32_canonicalize_dynamic_reloc \ - _bfd_nodynamic_canonicalize_dynamic_reloc -#endif - -#ifdef elf_backend_relocate_section -#ifndef bfd_elf32_bfd_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create -#endif -#else /* ! defined (elf_backend_relocate_section) */ -/* If no backend relocate_section routine, use the generic linker. */ -#ifndef bfd_elf32_bfd_link_hash_table_create -#define bfd_elf32_bfd_link_hash_table_create \ - _bfd_generic_link_hash_table_create -#endif -#ifndef bfd_elf32_bfd_link_add_symbols -#define bfd_elf32_bfd_link_add_symbols _bfd_generic_link_add_symbols -#endif -#ifndef bfd_elf32_bfd_final_link -#define bfd_elf32_bfd_final_link _bfd_generic_final_link -#endif -#endif /* ! defined (elf_backend_relocate_section) */ - -#ifndef elf_info_to_howto_rel -#define elf_info_to_howto_rel 0 -#endif - -#ifndef ELF_MAXPAGESIZE -#define ELF_MAXPAGESIZE 1 -#endif - -#ifndef elf_backend_collect -#define elf_backend_collect false -#endif - -#ifndef elf_backend_sym_is_global -#define elf_backend_sym_is_global 0 -#endif -#ifndef elf_backend_object_p -#define elf_backend_object_p 0 -#endif -#ifndef elf_backend_symbol_processing -#define elf_backend_symbol_processing 0 -#endif -#ifndef elf_backend_symbol_table_processing -#define elf_backend_symbol_table_processing 0 -#endif -#ifndef elf_backend_section_processing -#define elf_backend_section_processing 0 -#endif -#ifndef elf_backend_section_from_shdr -#define elf_backend_section_from_shdr 0 -#endif -#ifndef elf_backend_fake_sections -#define elf_backend_fake_sections 0 -#endif -#ifndef elf_backend_section_from_bfd_section -#define elf_backend_section_from_bfd_section 0 -#endif -#ifndef elf_backend_add_symbol_hook -#define elf_backend_add_symbol_hook 0 -#endif -#ifndef elf_backend_link_output_symbol_hook -#define elf_backend_link_output_symbol_hook 0 -#endif -#ifndef elf_backend_create_dynamic_sections -#define elf_backend_create_dynamic_sections 0 -#endif -#ifndef elf_backend_adjust_dynamic_symbol -#define elf_backend_adjust_dynamic_symbol 0 -#endif -#ifndef elf_backend_size_dynamic_sections -#define elf_backend_size_dynamic_sections 0 -#endif -#ifndef elf_backend_relocate_section -#define elf_backend_relocate_section 0 -#endif -#ifndef elf_backend_finish_dynamic_symbol -#define elf_backend_finish_dynamic_symbol 0 -#endif -#ifndef elf_backend_finish_dynamic_sections -#define elf_backend_finish_dynamic_sections 0 -#endif -#ifndef elf_backend_begin_write_processing -#define elf_backend_begin_write_processing 0 -#endif -#ifndef elf_backend_final_write_processing -#define elf_backend_final_write_processing 0 -#endif -#ifndef elf_backend_ecoff_debug_swap -#define elf_backend_ecoff_debug_swap 0 -#endif - -static CONST struct elf_backend_data elf32_bed = -{ -#ifdef USE_REL - 0, /* use_rela_p */ -#else - 1, /* use_rela_p */ -#endif - 0, /* elf_64_p */ - ELF_ARCH, /* arch */ - ELF_MACHINE_CODE, /* elf_machine_code */ - ELF_MAXPAGESIZE, /* maxpagesize */ - elf_backend_collect, - elf_info_to_howto, - elf_info_to_howto_rel, - elf_backend_sym_is_global, - elf_backend_object_p, - elf_backend_symbol_processing, - elf_backend_symbol_table_processing, - elf_backend_section_processing, - elf_backend_section_from_shdr, - elf_backend_fake_sections, - elf_backend_section_from_bfd_section, - elf_backend_add_symbol_hook, - elf_backend_link_output_symbol_hook, - elf_backend_create_dynamic_sections, - elf_backend_adjust_dynamic_symbol, - elf_backend_size_dynamic_sections, - elf_backend_relocate_section, - elf_backend_finish_dynamic_symbol, - elf_backend_finish_dynamic_sections, - elf_backend_begin_write_processing, - elf_backend_final_write_processing, - elf_backend_ecoff_debug_swap -}; - -#ifdef TARGET_BIG_SYM -const bfd_target TARGET_BIG_SYM = -{ - /* name: identify kind of target */ - TARGET_BIG_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder_big_p: data is big endian */ - true, - - /* header_byteorder_big_p: header is also big endian */ - true, - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* align_power_min: minimum alignment restriction for any section - FIXME: this value may be target machine dependent */ - 3, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elf32_object_p, /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - bfd_elf32_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elf_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elf32_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elf32), - BFD_JUMP_TABLE_COPY (bfd_elf32), - BFD_JUMP_TABLE_CORE (bfd_elf32), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elf32), - BFD_JUMP_TABLE_RELOCS (bfd_elf32), - BFD_JUMP_TABLE_WRITE (bfd_elf32), - BFD_JUMP_TABLE_LINK (bfd_elf32), - BFD_JUMP_TABLE_DYNAMIC (bfd_elf32), - - /* backend_data: */ - (PTR) &elf32_bed, -}; -#endif - -#ifdef TARGET_LITTLE_SYM -const bfd_target TARGET_LITTLE_SYM = -{ - /* name: identify kind of target */ - TARGET_LITTLE_NAME, - - /* flavour: general indication about file */ - bfd_target_elf_flavour, - - /* byteorder_big_p: data is big endian */ - false, /* Nope -- this one's little endian */ - - /* header_byteorder_big_p: header is also big endian */ - false, /* Nope -- this one's little endian */ - - /* object_flags: mask of all file flags */ - (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | - DYNAMIC | WP_TEXT | D_PAGED), - - /* section_flags: mask of all section flags */ - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | - SEC_CODE | SEC_DATA | SEC_DEBUGGING), - - /* leading_symbol_char: is the first char of a user symbol - predictable, and if so what is it */ - 0, - - /* ar_pad_char: pad character for filenames within an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and/or os and should be independently tunable */ - '/', - - /* ar_max_namelen: maximum number of characters in an archive header - FIXME: this really has nothing to do with ELF, this is a characteristic - of the archiver and should be independently tunable. This value is - a WAG (wild a** guess) */ - 14, - - /* align_power_min: minimum alignment restriction for any section - FIXME: this value may be target machine dependent */ - 3, - - /* Routines to byte-swap various sized integers from the data sections */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* Routines to byte-swap various sized integers from the file headers */ - bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, - bfd_getl16, bfd_getl_signed_16, bfd_putl16, - - /* bfd_check_format: check the format of a file being read */ - { _bfd_dummy_target, /* unknown format */ - bfd_elf32_object_p, /* assembler/linker output (object file) */ - bfd_generic_archive_p, /* an archive */ - bfd_elf32_core_file_p /* a core file */ - }, - - /* bfd_set_format: set the format of a file being written */ - { bfd_false, - bfd_elf_mkobject, - _bfd_generic_mkarchive, - bfd_false - }, - - /* bfd_write_contents: write cached information into a file being written */ - { bfd_false, - bfd_elf32_write_object_contents, - _bfd_write_archive_contents, - bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (bfd_elf32), - BFD_JUMP_TABLE_COPY (bfd_elf32), - BFD_JUMP_TABLE_CORE (bfd_elf32), - BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), - BFD_JUMP_TABLE_SYMBOLS (bfd_elf32), - BFD_JUMP_TABLE_RELOCS (bfd_elf32), - BFD_JUMP_TABLE_WRITE (bfd_elf32), - BFD_JUMP_TABLE_LINK (bfd_elf32), - BFD_JUMP_TABLE_DYNAMIC (bfd_elf32), - - /* backend_data: */ - (PTR) &elf32_bed, -}; -#endif diff --git a/gnu/usr.bin/gdb/bfd/elf32.c b/gnu/usr.bin/gdb/bfd/elf32.c deleted file mode 100644 index 862dd2d..0000000 --- a/gnu/usr.bin/gdb/bfd/elf32.c +++ /dev/null @@ -1,23 +0,0 @@ -/* ELF 32-bit executable support for BFD. - Copyright 1993 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#define ARCH_SIZE 32 - - -#include "elfcode.h" diff --git a/gnu/usr.bin/gdb/bfd/elfcode.h b/gnu/usr.bin/gdb/bfd/elfcode.h deleted file mode 100644 index ab38ab9..0000000 --- a/gnu/usr.bin/gdb/bfd/elfcode.h +++ /dev/null @@ -1,6351 +0,0 @@ -/* ELF executable support for BFD. - Copyright 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - - Written by Fred Fish @ Cygnus Support, from information published - in "UNIX System V Release 4, Programmers Guide: ANSI C and - Programming Support Tools". Sufficient support for gdb. - - Rewritten by Mark Eichin @ Cygnus Support, from information - published in "System V Application Binary Interface", chapters 4 - and 5, as well as the various "Processor Supplement" documents - derived from it. Added support for assembler and other object file - utilities. Further work done by Ken Raeburn (Cygnus Support), Michael - Meissner (Open Software Foundation), and Peter Hoogenboom (University - of Utah) to finish and extend this. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Problems and other issues to resolve. - - (1) BFD expects there to be some fixed number of "sections" in - the object file. I.E. there is a "section_count" variable in the - bfd structure which contains the number of sections. However, ELF - supports multiple "views" of a file. In particular, with current - implementations, executable files typically have two tables, a - program header table and a section header table, both of which - partition the executable. - - In ELF-speak, the "linking view" of the file uses the section header - table to access "sections" within the file, and the "execution view" - uses the program header table to access "segments" within the file. - "Segments" typically may contain all the data from one or more - "sections". - - Note that the section header table is optional in ELF executables, - but it is this information that is most useful to gdb. If the - section header table is missing, then gdb should probably try - to make do with the program header table. (FIXME) - - (2) The code in this file is compiled twice, once in 32-bit mode and - once in 64-bit mode. More of it should be made size-independent - and moved into elf.c. - - (3) ELF section symbols are handled rather sloppily now. This should - be cleaned up, and ELF section symbols reconciled with BFD section - symbols. - - (4) We need a published spec for 64-bit ELF. We've got some stuff here - that we're using for SPARC V9 64-bit chips, but don't assume that - it's cast in stone. - */ - -#include <string.h> /* For strrchr and friends */ -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -#include "libelf.h" - -/* Renaming structures, typedefs, macros and functions to be size-specific. */ -#define Elf_External_Ehdr NAME(Elf,External_Ehdr) -#define Elf_External_Sym NAME(Elf,External_Sym) -#define Elf_External_Shdr NAME(Elf,External_Shdr) -#define Elf_External_Phdr NAME(Elf,External_Phdr) -#define Elf_External_Rel NAME(Elf,External_Rel) -#define Elf_External_Rela NAME(Elf,External_Rela) -#define Elf_External_Dyn NAME(Elf,External_Dyn) - -#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) -#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) -#define elf_core_file_matches_executable_p \ - NAME(bfd_elf,core_file_matches_executable_p) -#define elf_object_p NAME(bfd_elf,object_p) -#define elf_core_file_p NAME(bfd_elf,core_file_p) -#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) -#define elf_get_dynamic_symtab_upper_bound \ - NAME(bfd_elf,get_dynamic_symtab_upper_bound) -#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in) -#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in) -#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out) -#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out) -#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in) -#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out) -#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in) -#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) -#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) -#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) -#define elf_get_symtab NAME(bfd_elf,get_symtab) -#define elf_canonicalize_dynamic_symtab \ - NAME(bfd_elf,canonicalize_dynamic_symtab) -#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) -#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) -#define elf_print_symbol NAME(bfd_elf,print_symbol) -#define elf_get_lineno NAME(bfd_elf,get_lineno) -#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach) -#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line) -#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers) -#define elf_set_section_contents NAME(bfd_elf,set_section_contents) -#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) -#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) -#define elf_new_section_hook NAME(bfd_elf,new_section_hook) -#define write_relocs NAME(bfd_elf,_write_relocs) -#define elf_find_section NAME(bfd_elf,find_section) -#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) -#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) -#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) - -#if ARCH_SIZE == 64 -#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF64_R_SYM(X) -#define ELF_R_TYPE(X) ELF64_R_TYPE(X) -#define ELFCLASS ELFCLASS64 -#define FILE_ALIGN 8 -#define LOG_FILE_ALIGN 3 -#endif -#if ARCH_SIZE == 32 -#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y) -#define ELF_R_SYM(X) ELF32_R_SYM(X) -#define ELF_R_TYPE(X) ELF32_R_TYPE(X) -#define ELFCLASS ELFCLASS32 -#define FILE_ALIGN 4 -#define LOG_FILE_ALIGN 2 -#endif - -/* Forward declarations of static functions */ - -static unsigned long bfd_add_to_strtab - PARAMS ((bfd *, struct strtab *, const char *)); -static asection *section_from_elf_index PARAMS ((bfd *, unsigned int)); - -static int elf_section_from_bfd_section PARAMS ((bfd *, struct sec *)); - -static long elf_slurp_symbol_table PARAMS ((bfd *, asymbol **, boolean)); - -static boolean elf_slurp_reloc_table PARAMS ((bfd *, asection *, asymbol **)); - -static int elf_symbol_from_bfd_symbol PARAMS ((bfd *, - struct symbol_cache_entry **)); - -static boolean elf_compute_section_file_positions - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean prep_headers PARAMS ((bfd *)); -static void elf_fake_sections PARAMS ((bfd *, asection *, PTR)); -static boolean assign_section_numbers PARAMS ((bfd *)); -static file_ptr align_file_position PARAMS ((file_ptr)); -static file_ptr assign_file_position_for_section - PARAMS ((Elf_Internal_Shdr *, file_ptr, boolean)); -static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean)); -static void assign_file_positions_for_relocs PARAMS ((bfd *)); -static bfd_size_type get_program_header_size PARAMS ((bfd *)); -static file_ptr map_program_segments - PARAMS ((bfd *, file_ptr, Elf_Internal_Shdr *, bfd_size_type)); - -static boolean elf_map_symbols PARAMS ((bfd *)); -static boolean swap_out_syms PARAMS ((bfd *)); - -static boolean bfd_section_from_shdr PARAMS ((bfd *, unsigned int shindex)); - -#ifdef DEBUG -static void elf_debug_section PARAMS ((char *, int, Elf_Internal_Shdr *)); -static void elf_debug_file PARAMS ((Elf_Internal_Ehdr *)); -#endif - -#define elf_string_from_elf_strtab(abfd,strindex) \ - elf_string_from_elf_section(abfd,elf_elfheader(abfd)->e_shstrndx,strindex) - - -/* Structure swapping routines */ - -/* Should perhaps use put_offset, put_word, etc. For now, the two versions - can be handled by explicitly specifying 32 bits or "the long type". */ -#if ARCH_SIZE == 64 -#define put_word bfd_h_put_64 -#define get_word bfd_h_get_64 -#endif -#if ARCH_SIZE == 32 -#define put_word bfd_h_put_32 -#define get_word bfd_h_get_32 -#endif - -/* Translate an ELF symbol in external format into an ELF symbol in internal - format. */ - -void -elf_swap_symbol_in (abfd, src, dst) - bfd *abfd; - Elf_External_Sym *src; - Elf_Internal_Sym *dst; -{ - dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name); - dst->st_value = get_word (abfd, (bfd_byte *) src->st_value); - dst->st_size = get_word (abfd, (bfd_byte *) src->st_size); - dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info); - dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other); - dst->st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src->st_shndx); -} - -/* Translate an ELF symbol in internal format into an ELF symbol in external - format. */ - -void -elf_swap_symbol_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Sym *src; - Elf_External_Sym *dst; -{ - bfd_h_put_32 (abfd, src->st_name, dst->st_name); - put_word (abfd, src->st_value, dst->st_value); - put_word (abfd, src->st_size, dst->st_size); - bfd_h_put_8 (abfd, src->st_info, dst->st_info); - bfd_h_put_8 (abfd, src->st_other, dst->st_other); - bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx); -} - - -/* Translate an ELF file header in external format into an ELF file header in - internal format. */ - -static void -elf_swap_ehdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Ehdr *src; - Elf_Internal_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type); - dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine); - dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version); - dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry); - dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff); - dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff); - dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags); - dst->e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_ehsize); - dst->e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phentsize); - dst->e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phnum); - dst->e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shentsize); - dst->e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shnum); - dst->e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shstrndx); -} - -/* Translate an ELF file header in internal format into an ELF file header in - external format. */ - -static void -elf_swap_ehdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Ehdr *src; - Elf_External_Ehdr *dst; -{ - memcpy (dst->e_ident, src->e_ident, EI_NIDENT); - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_16 (abfd, src->e_type, dst->e_type); - bfd_h_put_16 (abfd, src->e_machine, dst->e_machine); - bfd_h_put_32 (abfd, src->e_version, dst->e_version); - put_word (abfd, src->e_entry, dst->e_entry); - put_word (abfd, src->e_phoff, dst->e_phoff); - put_word (abfd, src->e_shoff, dst->e_shoff); - bfd_h_put_32 (abfd, src->e_flags, dst->e_flags); - bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize); - bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize); - bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum); - bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize); - bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum); - bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx); -} - - -/* Translate an ELF section header table entry in external format into an - ELF section header table entry in internal format. */ - -static void -elf_swap_shdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Shdr *src; - Elf_Internal_Shdr *dst; -{ - dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); - dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type); - dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags); - dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr); - dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset); - dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size); - dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link); - dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info); - dst->sh_addralign = get_word (abfd, (bfd_byte *) src->sh_addralign); - dst->sh_entsize = get_word (abfd, (bfd_byte *) src->sh_entsize); - /* we haven't done any processing on it yet, so... */ - dst->rawdata = (void *) 0; -} - -/* Translate an ELF section header table entry in internal format into an - ELF section header table entry in external format. */ - -static void -elf_swap_shdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Shdr *src; - Elf_External_Shdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->sh_name, dst->sh_name); - bfd_h_put_32 (abfd, src->sh_type, dst->sh_type); - put_word (abfd, src->sh_flags, dst->sh_flags); - put_word (abfd, src->sh_addr, dst->sh_addr); - put_word (abfd, src->sh_offset, dst->sh_offset); - put_word (abfd, src->sh_size, dst->sh_size); - bfd_h_put_32 (abfd, src->sh_link, dst->sh_link); - bfd_h_put_32 (abfd, src->sh_info, dst->sh_info); - put_word (abfd, src->sh_addralign, dst->sh_addralign); - put_word (abfd, src->sh_entsize, dst->sh_entsize); -} - - -/* Translate an ELF program header table entry in external format into an - ELF program header table entry in internal format. */ - -static void -elf_swap_phdr_in (abfd, src, dst) - bfd *abfd; - Elf_External_Phdr *src; - Elf_Internal_Phdr *dst; -{ - dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); - dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags); - dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset); - dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr); - dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr); - dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz); - dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz); - dst->p_align = get_word (abfd, (bfd_byte *) src->p_align); -} - -static void -elf_swap_phdr_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Phdr *src; - Elf_External_Phdr *dst; -{ - /* note that all elements of dst are *arrays of unsigned char* already... */ - bfd_h_put_32 (abfd, src->p_type, dst->p_type); - put_word (abfd, src->p_offset, dst->p_offset); - put_word (abfd, src->p_vaddr, dst->p_vaddr); - put_word (abfd, src->p_paddr, dst->p_paddr); - put_word (abfd, src->p_filesz, dst->p_filesz); - put_word (abfd, src->p_memsz, dst->p_memsz); - bfd_h_put_32 (abfd, src->p_flags, dst->p_flags); - put_word (abfd, src->p_align, dst->p_align); -} - -/* Translate an ELF reloc from external format to internal format. */ -INLINE void -elf_swap_reloc_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rel *src; - Elf_Internal_Rel *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); -} - -INLINE void -elf_swap_reloca_in (abfd, src, dst) - bfd *abfd; - Elf_External_Rela *src; - Elf_Internal_Rela *dst; -{ - dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); - dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); - dst->r_addend = get_word (abfd, (bfd_byte *) src->r_addend); -} - -/* Translate an ELF reloc from internal format to external format. */ -INLINE void -elf_swap_reloc_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rel *src; - Elf_External_Rel *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); -} - -INLINE void -elf_swap_reloca_out (abfd, src, dst) - bfd *abfd; - Elf_Internal_Rela *src; - Elf_External_Rela *dst; -{ - put_word (abfd, src->r_offset, dst->r_offset); - put_word (abfd, src->r_info, dst->r_info); - put_word (abfd, src->r_addend, dst->r_addend); -} - -INLINE void -elf_swap_dyn_in (abfd, src, dst) - bfd *abfd; - const Elf_External_Dyn *src; - Elf_Internal_Dyn *dst; -{ - dst->d_tag = get_word (abfd, src->d_tag); - dst->d_un.d_val = get_word (abfd, src->d_un.d_val); -} - -INLINE void -elf_swap_dyn_out (abfd, src, dst) - bfd *abfd; - const Elf_Internal_Dyn *src; - Elf_External_Dyn *dst; -{ - put_word (abfd, src->d_tag, dst->d_tag); - put_word (abfd, src->d_un.d_val, dst->d_un.d_val); -} - -/* String table creation/manipulation routines */ - -static struct strtab * -bfd_new_strtab (abfd) - bfd *abfd; -{ - struct strtab *ss; - - ss = (struct strtab *) malloc (sizeof (struct strtab)); - if (!ss) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - ss->tab = malloc (1); - if (!ss->tab) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - *ss->tab = 0; - ss->nentries = 0; - ss->length = 1; - - return ss; -} - -static unsigned long -bfd_add_to_strtab (abfd, ss, str) - bfd *abfd; - struct strtab *ss; - const char *str; -{ - /* should search first, but for now: */ - /* include the trailing NUL */ - int ln = strlen (str) + 1; - - /* FIXME: This is slow. Also, we could combine this with the a.out - string table building and use a hash table, although it might not - be worth it since ELF symbols don't include debugging information - and thus have much less overlap. */ - ss->tab = realloc (ss->tab, ss->length + ln); - if (ss->tab == NULL) - { - bfd_set_error (bfd_error_no_memory); - return (unsigned long) -1; - } - - strcpy (ss->tab + ss->length, str); - ss->nentries++; - ss->length += ln; - - return ss->length - ln; -} - -static int -bfd_add_2_to_strtab (abfd, ss, str, str2) - bfd *abfd; - struct strtab *ss; - char *str; - CONST char *str2; -{ - /* should search first, but for now: */ - /* include the trailing NUL */ - int ln = strlen (str) + strlen (str2) + 1; - - /* should this be using obstacks? */ - if (ss->length) - ss->tab = realloc (ss->tab, ss->length + ln); - else - ss->tab = malloc (ln); - - BFD_ASSERT (ss->tab != 0); /* FIXME */ - strcpy (ss->tab + ss->length, str); - strcpy (ss->tab + ss->length + strlen (str), str2); - ss->nentries++; - ss->length += ln; - - return ss->length - ln; -} - -/* ELF .o/exec file reading */ - -/* Create a new bfd section from an ELF section header. */ - -static boolean -bfd_section_from_shdr (abfd, shindex) - bfd *abfd; - unsigned int shindex; -{ - Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex]; - Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); - char *name; - - name = elf_string_from_elf_strtab (abfd, hdr->sh_name); - - switch (hdr->sh_type) - { - case SHT_NULL: - /* Inactive section. Throw it away. */ - return true; - - case SHT_PROGBITS: /* Normal section with contents. */ - case SHT_DYNAMIC: /* Dynamic linking information. */ - case SHT_NOBITS: /* .bss section. */ - case SHT_HASH: /* .hash section. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_SYMTAB: /* A symbol table */ - if (elf_onesymtab (abfd) == shindex) - return true; - - BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym)); - BFD_ASSERT (elf_onesymtab (abfd) == 0); - elf_onesymtab (abfd) = shindex; - elf_tdata (abfd)->symtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_hdr; - abfd->flags |= HAS_SYMS; - return true; - - case SHT_DYNSYM: /* A dynamic symbol table */ - if (elf_dynsymtab (abfd) == shindex) - return true; - - BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym)); - BFD_ASSERT (elf_dynsymtab (abfd) == 0); - elf_dynsymtab (abfd) = shindex; - elf_tdata (abfd)->dynsymtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->dynsymtab_hdr; - abfd->flags |= HAS_SYMS; - - /* Besides being a symbol table, we also treat this as a regular - section, so that objcopy can handle it. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_STRTAB: /* A string table */ - if (hdr->rawdata != NULL) - return true; - if (ehdr->e_shstrndx == shindex) - { - elf_tdata (abfd)->shstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr; - hdr->rawdata = (PTR) & elf_tdata (abfd)->shstrtab_hdr; - return true; - } - { - unsigned int i; - - for (i = 1; i < ehdr->e_shnum; i++) - { - Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i]; - if (hdr2->sh_link == shindex) - { - if (! bfd_section_from_shdr (abfd, i)) - return false; - if (elf_onesymtab (abfd) == i) - { - elf_tdata (abfd)->strtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = - &elf_tdata (abfd)->strtab_hdr; - return true; - } - if (elf_dynsymtab (abfd) == i) - { - elf_tdata (abfd)->dynstrtab_hdr = *hdr; - elf_elfsections (abfd)[shindex] = - &elf_tdata (abfd)->dynstrtab_hdr; - /* We also treat this as a regular section, so - that objcopy can handle it. */ - break; - } -#if 0 /* Not handling other string tables specially right now. */ - hdr2 = elf_elfsections (abfd)[i]; /* in case it moved */ - /* We have a strtab for some random other section. */ - newsect = (asection *) hdr2->rawdata; - if (!newsect) - break; - hdr->rawdata = (PTR) newsect; - hdr2 = &elf_section_data (newsect)->str_hdr; - *hdr2 = *hdr; - elf_elfsections (abfd)[shindex] = hdr2; -#endif - } - } - } - - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - case SHT_REL: - case SHT_RELA: - /* *These* do a lot of work -- but build no sections! */ - { - asection *target_sect; - Elf_Internal_Shdr *hdr2; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - - /* Get the symbol table. */ - if (! bfd_section_from_shdr (abfd, hdr->sh_link)) - return false; - - /* If this reloc section does not use the main symbol table we - don't treat it as a reloc section. BFD can't adequately - represent such a section, so at least for now, we don't - try. We just present it as a normal section. */ - if (hdr->sh_link != elf_onesymtab (abfd)) - return _bfd_elf_make_section_from_shdr (abfd, hdr, name); - - /* Don't allow REL relocations on a machine that uses RELA and - vice versa. */ - /* @@ Actually, the generic ABI does suggest that both might be - used in one file. But the four ABI Processor Supplements I - have access to right now all specify that only one is used on - each of those architectures. It's conceivable that, e.g., a - bunch of absolute 32-bit relocs might be more compact in REL - form even on a RELA machine... */ - BFD_ASSERT (use_rela_p - ? (hdr->sh_type == SHT_RELA - && hdr->sh_entsize == sizeof (Elf_External_Rela)) - : (hdr->sh_type == SHT_REL - && hdr->sh_entsize == sizeof (Elf_External_Rel))); - - if (! bfd_section_from_shdr (abfd, hdr->sh_info)) - return false; - target_sect = section_from_elf_index (abfd, hdr->sh_info); - if (target_sect == NULL - || elf_section_data (target_sect) == NULL) - return false; - - hdr2 = &elf_section_data (target_sect)->rel_hdr; - *hdr2 = *hdr; - elf_elfsections (abfd)[shindex] = hdr2; - target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize; - target_sect->flags |= SEC_RELOC; - target_sect->relocation = NULL; - target_sect->rel_filepos = hdr->sh_offset; - abfd->flags |= HAS_RELOC; - return true; - } - break; - - case SHT_NOTE: -#if 0 - fprintf (stderr, "Note Sections not yet supported.\n"); - BFD_FAIL (); -#endif - break; - - case SHT_SHLIB: -#if 0 - fprintf (stderr, "SHLIB Sections not supported (and non conforming.)\n"); -#endif - return true; - - default: - /* Check for any processor-specific section types. */ - { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_section_from_shdr) - (*bed->elf_backend_section_from_shdr) (abfd, hdr, name); - } - break; - } - - return true; -} - -boolean -elf_new_section_hook (abfd, sec) - bfd *abfd - ; - asection *sec; -{ - struct bfd_elf_section_data *sdata; - - sdata = (struct bfd_elf_section_data *) bfd_alloc (abfd, sizeof (*sdata)); - if (!sdata) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - sec->used_by_bfd = (PTR) sdata; - memset (sdata, 0, sizeof (*sdata)); - return true; -} - -/* Create a new bfd section from an ELF program header. - - Since program segments have no names, we generate a synthetic name - of the form segment<NUM>, where NUM is generally the index in the - program header table. For segments that are split (see below) we - generate the names segment<NUM>a and segment<NUM>b. - - Note that some program segments may have a file size that is different than - (less than) the memory size. All this means is that at execution the - system must allocate the amount of memory specified by the memory size, - but only initialize it with the first "file size" bytes read from the - file. This would occur for example, with program segments consisting - of combined data+bss. - - To handle the above situation, this routine generates TWO bfd sections - for the single program segment. The first has the length specified by - the file size of the segment, and the second has the length specified - by the difference between the two sizes. In effect, the segment is split - into it's initialized and uninitialized parts. - - */ - -static boolean -bfd_section_from_phdr (abfd, hdr, index) - bfd *abfd; - Elf_Internal_Phdr *hdr; - int index; -{ - asection *newsect; - char *name; - char namebuf[64]; - int split; - - split = ((hdr->p_memsz > 0) && - (hdr->p_filesz > 0) && - (hdr->p_memsz > hdr->p_filesz)); - sprintf (namebuf, split ? "segment%da" : "segment%d", index); - name = bfd_alloc (abfd, strlen (namebuf) + 1); - if (!name) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - strcpy (name, namebuf); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return false; - newsect->vma = hdr->p_vaddr; - newsect->_raw_size = hdr->p_filesz; - newsect->filepos = hdr->p_offset; - newsect->flags |= SEC_HAS_CONTENTS; - if (hdr->p_type == PT_LOAD) - { - newsect->flags |= SEC_ALLOC; - newsect->flags |= SEC_LOAD; - if (hdr->p_flags & PF_X) - { - /* FIXME: all we known is that it has execute PERMISSION, - may be data. */ - newsect->flags |= SEC_CODE; - } - } - if (!(hdr->p_flags & PF_W)) - { - newsect->flags |= SEC_READONLY; - } - - if (split) - { - sprintf (namebuf, "segment%db", index); - name = bfd_alloc (abfd, strlen (namebuf) + 1); - if (!name) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - strcpy (name, namebuf); - newsect = bfd_make_section (abfd, name); - if (newsect == NULL) - return false; - newsect->vma = hdr->p_vaddr + hdr->p_filesz; - newsect->_raw_size = hdr->p_memsz - hdr->p_filesz; - if (hdr->p_type == PT_LOAD) - { - newsect->flags |= SEC_ALLOC; - if (hdr->p_flags & PF_X) - newsect->flags |= SEC_CODE; - } - if (!(hdr->p_flags & PF_W)) - newsect->flags |= SEC_READONLY; - } - - return true; -} - -/* Begin processing a given object. - - First we validate the file by reading in the ELF header and checking - the magic number. */ - -static INLINE boolean -elf_file_p (x_ehdrp) - Elf_External_Ehdr *x_ehdrp; -{ - return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) - && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) - && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2) - && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); -} - -/* Check to see if the file associated with ABFD matches the target vector - that ABFD points to. - - Note that we may be called several times with the same ABFD, but different - target vectors, most of which will not match. We have to avoid leaving - any side effects in ABFD, or any data it points to (like tdata), if the - file does not match the target vector. */ - -const bfd_target * -elf_object_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr x_shdr; /* Section header table entry, external form */ - Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */ - unsigned int shindex; - char *shstrtab; /* Internal copy of section header stringtab */ - struct elf_backend_data *ebd; - struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); - struct elf_obj_tdata *new_tdata = NULL; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - goto got_wrong_format_error; - else - goto got_no_match; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - section header table (FIXME: See comments re sections at top of this - file). */ - - if ((elf_file_p (&x_ehdr) == false) || - (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) || - (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)) - goto got_wrong_format_error; - - /* Check that file's byte order matches xvec's */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (!abfd->xvec->header_byteorder_big_p) - goto got_wrong_format_error; - break; - case ELFDATA2LSB: /* Little-endian */ - if (abfd->xvec->header_byteorder_big_p) - goto got_wrong_format_error; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto got_wrong_format_error; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - new_tdata = ((struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))); - if (new_tdata == NULL) - goto got_no_memory_error; - elf_tdata (abfd) = new_tdata; - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - /* If there is no section header table, we're hosed. */ - if (i_ehdrp->e_shoff == 0) - goto got_wrong_format_error; - - /* As a simple sanity check, verify that the what BFD thinks is the - size of each section header table entry actually matches the size - recorded in the file. */ - if (i_ehdrp->e_shentsize != sizeof (x_shdr)) - goto got_wrong_format_error; - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto got_wrong_format_error; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto got_wrong_format_error; - } - } - } - - if (i_ehdrp->e_type == ET_EXEC) - abfd->flags |= EXEC_P; - else if (i_ehdrp->e_type == ET_DYN) - abfd->flags |= DYNAMIC; - - if (i_ehdrp->e_phnum > 0) - abfd->flags |= D_PAGED; - - if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)) - goto got_no_match; - - /* Remember the entry point specified in the ELF file header. */ - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - /* Allocate space for a copy of the section header table in - internal form, seek to the section header table in the file, - read it in, and convert it to internal form. */ - i_shdrp = ((Elf_Internal_Shdr *) - bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum)); - elf_elfsections (abfd) = ((Elf_Internal_Shdr **) - bfd_alloc (abfd, - sizeof (i_shdrp) * i_ehdrp->e_shnum)); - if (!i_shdrp || !elf_elfsections (abfd)) - goto got_no_memory_error; - if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0) - goto got_no_match; - for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) - { - if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr)) - goto got_no_match; - elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); - elf_elfsections (abfd)[shindex] = i_shdrp + shindex; - } - if (i_ehdrp->e_shstrndx) - { - if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) - goto got_no_match; - } - - /* Read in the string table containing the names of the sections. We - will need the base pointer to this table later. */ - /* We read this inline now, so that we don't have to go through - bfd_section_from_shdr with it (since this particular strtab is - used to find all of the ELF section names.) */ - - shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx); - if (!shstrtab) - goto got_no_match; - - /* Once all of the section headers have been read and converted, we - can start processing them. Note that the first section header is - a dummy placeholder entry, so we ignore it. */ - - for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) - { - if (! bfd_section_from_shdr (abfd, shindex)) - goto got_no_match; - } - - /* Let the backend double check the format and override global - information. */ - if (ebd->elf_backend_object_p) - { - if ((*ebd->elf_backend_object_p) (abfd) == false) - goto got_wrong_format_error; - } - - return (abfd->xvec); - -got_wrong_format_error: - bfd_set_error (bfd_error_wrong_format); - goto got_no_match; -got_no_memory_error: - bfd_set_error (bfd_error_no_memory); - goto got_no_match; -got_no_match: - if (new_tdata != NULL - && new_tdata->elf_sect_ptr != NULL) - bfd_release (abfd, new_tdata->elf_sect_ptr); - if (i_shdrp != NULL) - bfd_release (abfd, i_shdrp); - if (new_tdata != NULL) - bfd_release (abfd, new_tdata); - elf_tdata (abfd) = preserved_tdata; - return (NULL); -} - - -/* ELF .o/exec file writing */ - -/* Takes a bfd and a symbol, returns a pointer to the elf specific area - of the symbol if there is one. */ -static INLINE elf_symbol_type * -elf_symbol_from (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - if (symbol->the_bfd->xvec->flavour != bfd_target_elf_flavour) - return 0; - - if (symbol->the_bfd->tdata.elf_obj_data == (struct elf_obj_tdata *) NULL) - return 0; - - return (elf_symbol_type *) symbol; -} - -void -write_relocs (abfd, sec, xxx) - bfd *abfd; - asection *sec; - PTR xxx; -{ - Elf_Internal_Shdr *rela_hdr; - Elf_External_Rela *outbound_relocas; - Elf_External_Rel *outbound_relocs; - int idx; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - asymbol *last_sym = 0; - int last_sym_idx = 9999999; /* should always be written before use */ - - if ((sec->flags & SEC_RELOC) == 0) - return; - - /* The linker backend writes the relocs out itself, and sets the - reloc_count field to zero to inhibit writing them here. Also, - sometimes the SEC_RELOC flag gets set even when there aren't any - relocs. */ - if (sec->reloc_count == 0) - return; - - rela_hdr = &elf_section_data (sec)->rel_hdr; - - rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; - rela_hdr->contents = (void *) bfd_alloc (abfd, rela_hdr->sh_size); - if (!rela_hdr->contents) - { - bfd_set_error (bfd_error_no_memory); - abort (); /* FIXME */ - } - - /* orelocation has the data, reloc_count has the count... */ - if (use_rela_p) - { - outbound_relocas = (Elf_External_Rela *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rela dst_rela; - Elf_External_Rela *src_rela; - arelent *ptr; - asymbol *sym; - int n; - - ptr = sec->orelocation[idx]; - src_rela = outbound_relocas + idx; - if (!(abfd->flags & EXEC_P)) - dst_rela.r_offset = ptr->address - sec->vma; - else - dst_rela.r_offset = ptr->address; - - sym = *ptr->sym_ptr_ptr; - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - last_sym_idx = n = elf_symbol_from_bfd_symbol (abfd, &sym); - } - dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type); - - dst_rela.r_addend = ptr->addend; - elf_swap_reloca_out (abfd, &dst_rela, src_rela); - } - } - else - /* REL relocations */ - { - outbound_relocs = (Elf_External_Rel *) rela_hdr->contents; - - for (idx = 0; idx < sec->reloc_count; idx++) - { - Elf_Internal_Rel dst_rel; - Elf_External_Rel *src_rel; - arelent *ptr; - int n; - asymbol *sym; - - ptr = sec->orelocation[idx]; - sym = *ptr->sym_ptr_ptr; - src_rel = outbound_relocs + idx; - if (!(abfd->flags & EXEC_P)) - dst_rel.r_offset = ptr->address - sec->vma; - else - dst_rel.r_offset = ptr->address; - - if (sym == last_sym) - n = last_sym_idx; - else - { - last_sym = sym; - last_sym_idx = n = elf_symbol_from_bfd_symbol (abfd, &sym); - } - dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type); - - elf_swap_reloc_out (abfd, &dst_rel, src_rel); - } - } -} - -/* Set up an ELF internal section header for a section. */ - -/*ARGSUSED*/ -static void -elf_fake_sections (abfd, asect, ignore) - bfd *abfd; - asection *asect; - PTR ignore; -{ - Elf_Internal_Shdr *this_hdr; - - this_hdr = &elf_section_data (asect)->this_hdr; - - this_hdr->sh_name = bfd_add_to_strtab (abfd, elf_shstrtab (abfd), - asect->name); - if (this_hdr->sh_name == (unsigned long) -1) - abort (); /* FIXME */ - - this_hdr->sh_flags = 0; - if ((asect->flags & SEC_ALLOC) != 0) - this_hdr->sh_addr = asect->vma; - else - this_hdr->sh_addr = 0; - this_hdr->sh_offset = 0; - this_hdr->sh_size = asect->_raw_size; - this_hdr->sh_link = 0; - this_hdr->sh_info = 0; - this_hdr->sh_addralign = 1 << asect->alignment_power; - this_hdr->sh_entsize = 0; - - this_hdr->rawdata = (PTR) asect; - this_hdr->contents = NULL; - this_hdr->size = 0; - - /* FIXME: This should not be based on section names. */ - if (strcmp (asect->name, ".dynstr") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if (strcmp (asect->name, ".hash") == 0) - { - this_hdr->sh_type = SHT_HASH; - this_hdr->sh_entsize = ARCH_SIZE / 8; - } - else if (strcmp (asect->name, ".dynsym") == 0) - { - this_hdr->sh_type = SHT_DYNSYM; - this_hdr->sh_entsize = sizeof (Elf_External_Sym); - } - else if (strcmp (asect->name, ".dynamic") == 0) - { - this_hdr->sh_type = SHT_DYNAMIC; - this_hdr->sh_entsize = sizeof (Elf_External_Dyn); - } - else if (strncmp (asect->name, ".rel.", 5) == 0) - { - this_hdr->sh_type = SHT_REL; - this_hdr->sh_entsize = sizeof (Elf_External_Rel); - } - else if (strncmp (asect->name, ".rela.", 6) == 0) - { - this_hdr->sh_type = SHT_RELA; - this_hdr->sh_entsize = sizeof (Elf_External_Rela); - } - else if (strcmp (asect->name, ".note") == 0) - this_hdr->sh_type = SHT_NOTE; - else if (strncmp (asect->name, ".stab", 5) == 0 - && strcmp (asect->name + strlen (asect->name) - 3, "str") == 0) - this_hdr->sh_type = SHT_STRTAB; - else if ((asect->flags & SEC_ALLOC) != 0 - && (asect->flags & SEC_LOAD) != 0) - this_hdr->sh_type = SHT_PROGBITS; - else if ((asect->flags & SEC_ALLOC) != 0 - && ((asect->flags & SEC_LOAD) == 0)) - { - BFD_ASSERT (strcmp (asect->name, ".bss") == 0 - || strcmp (asect->name, ".sbss") == 0); - this_hdr->sh_type = SHT_NOBITS; - } - else - { - /* Who knows? */ - this_hdr->sh_type = SHT_PROGBITS; - } - - if ((asect->flags & SEC_ALLOC) != 0) - this_hdr->sh_flags |= SHF_ALLOC; - if ((asect->flags & SEC_READONLY) == 0) - this_hdr->sh_flags |= SHF_WRITE; - if ((asect->flags & SEC_CODE) != 0) - this_hdr->sh_flags |= SHF_EXECINSTR; - - /* Check for processor-specific section types. */ - { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_fake_sections) - (*bed->elf_backend_fake_sections) (abfd, this_hdr, asect); - } - - /* If the section has relocs, set up a section header for the - SHT_REL[A] section. */ - if ((asect->flags & SEC_RELOC) != 0) - { - Elf_Internal_Shdr *rela_hdr; - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - - rela_hdr = &elf_section_data (asect)->rel_hdr; - rela_hdr->sh_name = - bfd_add_2_to_strtab (abfd, elf_shstrtab (abfd), - use_rela_p ? ".rela" : ".rel", - asect->name); - rela_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL; - rela_hdr->sh_entsize = (use_rela_p - ? sizeof (Elf_External_Rela) - : sizeof (Elf_External_Rel)); - rela_hdr->sh_addralign = FILE_ALIGN; - rela_hdr->sh_flags = 0; - rela_hdr->sh_addr = 0; - rela_hdr->sh_size = 0; - rela_hdr->sh_offset = 0; - rela_hdr->size = 0; - } -} - -/* Assign all ELF section numbers. The dummy first section is handled here - too. The link/info pointers for the standard section types are filled - in here too, while we're at it. */ - -static boolean -assign_section_numbers (abfd) - bfd *abfd; -{ - struct elf_obj_tdata *t = elf_tdata (abfd); - asection *sec; - unsigned int section_number; - Elf_Internal_Shdr **i_shdrp; - - section_number = 1; - - for (sec = abfd->sections; sec; sec = sec->next) - { - struct bfd_elf_section_data *d = elf_section_data (sec); - - d->this_idx = section_number++; - if ((sec->flags & SEC_RELOC) == 0) - d->rel_idx = 0; - else - d->rel_idx = section_number++; - } - - t->shstrtab_section = section_number++; - elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; - t->shstrtab_hdr.sh_size = elf_shstrtab (abfd)->length; - t->shstrtab_hdr.contents = (PTR) elf_shstrtab (abfd)->tab; - - if (abfd->symcount > 0) - { - t->symtab_section = section_number++; - t->strtab_section = section_number++; - } - - elf_elfheader (abfd)->e_shnum = section_number; - - /* Set up the list of section header pointers, in agreement with the - indices. */ - i_shdrp = ((Elf_Internal_Shdr **) - bfd_alloc (abfd, section_number * sizeof (Elf_Internal_Shdr *))); - if (i_shdrp == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - i_shdrp[0] = ((Elf_Internal_Shdr *) - bfd_alloc (abfd, sizeof (Elf_Internal_Shdr))); - if (i_shdrp[0] == NULL) - { - bfd_release (abfd, i_shdrp); - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (i_shdrp[0], 0, sizeof (Elf_Internal_Shdr)); - - elf_elfsections (abfd) = i_shdrp; - - i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr; - if (abfd->symcount > 0) - { - i_shdrp[t->symtab_section] = &t->symtab_hdr; - i_shdrp[t->strtab_section] = &t->strtab_hdr; - t->symtab_hdr.sh_link = t->strtab_section; - } - for (sec = abfd->sections; sec; sec = sec->next) - { - struct bfd_elf_section_data *d = elf_section_data (sec); - asection *s; - const char *name; - - i_shdrp[d->this_idx] = &d->this_hdr; - if (d->rel_idx != 0) - i_shdrp[d->rel_idx] = &d->rel_hdr; - - /* Fill in the sh_link and sh_info fields while we're at it. */ - - /* sh_link of a reloc section is the section index of the symbol - table. sh_info is the section index of the section to which - the relocation entries apply. */ - if (d->rel_idx != 0) - { - d->rel_hdr.sh_link = t->symtab_section; - d->rel_hdr.sh_info = d->this_idx; - } - - switch (d->this_hdr.sh_type) - { - case SHT_REL: - case SHT_RELA: - /* A reloc section which we are treating as a normal BFD - section. sh_link is the section index of the symbol - table. sh_info is the section index of the section to - which the relocation entries apply. We assume that an - allocated reloc section uses the dynamic symbol table. - FIXME: How can we be sure? */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - - /* We look up the section the relocs apply to by name. */ - name = sec->name; - if (d->this_hdr.sh_type == SHT_REL) - name += 4; - else - name += 5; - s = bfd_get_section_by_name (abfd, name); - if (s != NULL) - d->this_hdr.sh_info = elf_section_data (s)->this_idx; - break; - - case SHT_STRTAB: - /* We assume that a section named .stab*str is a stabs - string section. We look for a section with the same name - but without the trailing ``str'', and set its sh_link - field to point to this section. */ - if (strncmp (sec->name, ".stab", sizeof ".stab" - 1) == 0 - && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0) - { - size_t len; - char *alc; - - len = strlen (sec->name); - alc = (char *) malloc (len - 2); - if (alc == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - strncpy (alc, sec->name, len - 3); - alc[len - 3] = '\0'; - s = bfd_get_section_by_name (abfd, alc); - free (alc); - if (s != NULL) - { - elf_section_data (s)->this_hdr.sh_link = d->this_idx; - - /* This is a .stab section. */ - elf_section_data (s)->this_hdr.sh_entsize = - 4 + 2 * (ARCH_SIZE / 8); - } - } - break; - - case SHT_DYNAMIC: - case SHT_DYNSYM: - /* sh_link is the section header index of the string table - used for the dynamic entries or symbol table. */ - s = bfd_get_section_by_name (abfd, ".dynstr"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - - case SHT_HASH: - /* sh_link is the section header index of the symbol table - this hash table is for. */ - s = bfd_get_section_by_name (abfd, ".dynsym"); - if (s != NULL) - d->this_hdr.sh_link = elf_section_data (s)->this_idx; - break; - } - } - - return true; -} - -/* Map symbol from it's internal number to the external number, moving - all local symbols to be at the head of the list. */ - -static INLINE int -sym_is_global (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - /* If the backend has a special mapping, use it. */ - if (get_elf_backend_data (abfd)->elf_backend_sym_is_global) - return ((*get_elf_backend_data (abfd)->elf_backend_sym_is_global) - (abfd, sym)); - - if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) - { - if (sym->flags & BSF_LOCAL) - abort (); - return 1; - } - if (sym->section == 0) - { - /* Is this valid? */ - abort (); - - return 1; - } - if (bfd_is_und_section (sym->section)) - return 1; - if (bfd_is_com_section (sym->section)) - return 1; - if (sym->flags & (BSF_LOCAL | BSF_SECTION_SYM | BSF_FILE)) - return 0; - return 0; -} - -static boolean -elf_map_symbols (abfd) - bfd *abfd; -{ - int symcount = bfd_get_symcount (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - asymbol **sect_syms; - int num_locals = 0; - int num_globals = 0; - int num_locals2 = 0; - int num_globals2 = 0; - int max_index = 0; - int num_sections = 0; - Elf_Sym_Extra *sym_extra; - int idx; - asection *asect; - -#ifdef DEBUG - fprintf (stderr, "elf_map_symbols\n"); - fflush (stderr); -#endif - - /* Add local symbols for each section for which there are relocs. - FIXME: How can we tell which sections have relocs at this point? - Will reloc_count always be accurate? Actually, I think most ELF - targets create section symbols for all sections anyhow. */ - for (asect = abfd->sections; asect; asect = asect->next) - { - if (max_index < asect->index) - max_index = asect->index; - } - - max_index++; - elf_num_section_syms (abfd) = max_index; - sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *)); - elf_section_syms (abfd) = sect_syms; - - if (sect_syms == 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - for (asect = abfd->sections; asect; asect = asect->next) - { - asymbol *sym = bfd_make_empty_symbol (abfd); - if (!sym) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - sym->the_bfd = abfd; - sym->name = asect->name; - sym->value = asect->vma; - sym->flags = BSF_SECTION_SYM; - sym->section = asect; - sect_syms[asect->index] = sym; - num_sections++; -#ifdef DEBUG - fprintf (stderr, - "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n", - asect->name, (long) asect->vma, asect->index, (long) asect); -#endif - } - - if (num_sections) - { - if (syms) - syms = (asymbol **) bfd_realloc (abfd, syms, - ((symcount + num_sections + 1) - * sizeof (asymbol *))); - else - syms = (asymbol **) bfd_alloc (abfd, - (num_sections + 1) * sizeof (asymbol *)); - if (!syms) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - for (asect = abfd->sections; asect; asect = asect->next) - { - if (sect_syms[asect->index]) - syms[symcount++] = sect_syms[asect->index]; - } - - syms[symcount] = (asymbol *) 0; - bfd_set_symtab (abfd, syms, symcount); - } - - elf_sym_extra (abfd) = sym_extra - = (Elf_Sym_Extra *) bfd_alloc (abfd, symcount * sizeof (Elf_Sym_Extra)); - if (!sym_extra) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* Identify and classify all of the symbols. */ - for (idx = 0; idx < symcount; idx++) - { - if (!sym_is_global (abfd, syms[idx])) - num_locals++; - else - num_globals++; - } - - /* Now provide mapping information. Add +1 for skipping over the - dummy symbol. */ - for (idx = 0; idx < symcount; idx++) - { - syms[idx]->udata = (PTR) & sym_extra[idx]; - if (!sym_is_global (abfd, syms[idx])) - sym_extra[idx].elf_sym_num = 1 + num_locals2++; - else - sym_extra[idx].elf_sym_num = 1 + num_locals + num_globals2++; - } - - elf_num_locals (abfd) = num_locals; - elf_num_globals (abfd) = num_globals; - return true; -} - -/* Compute the file positions we are going to put the sections at, and - otherwise prepare to begin writing out the ELF file. If LINK_INFO - is not NULL, this is being called by the ELF backend linker. */ - -static boolean -elf_compute_section_file_positions (abfd, link_info) - bfd *abfd; - struct bfd_link_info *link_info; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Shdr *shstrtab_hdr; - - if (abfd->output_has_begun) - return true; - - /* Do any elf backend specific processing first. */ - if (bed->elf_backend_begin_write_processing) - (*bed->elf_backend_begin_write_processing) (abfd, link_info); - - if (! prep_headers (abfd)) - return false; - - bfd_map_over_sections (abfd, elf_fake_sections, 0); - - if (!assign_section_numbers (abfd)) - return false; - - /* The backend linker builds symbol table information itself. */ - if (link_info == NULL) - { - if (! swap_out_syms (abfd)) - return false; - } - - shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr; - /* sh_name was set in prep_headers. */ - shstrtab_hdr->sh_type = SHT_STRTAB; - shstrtab_hdr->sh_flags = 0; - shstrtab_hdr->sh_addr = 0; - shstrtab_hdr->sh_size = elf_shstrtab (abfd)->length; - shstrtab_hdr->sh_entsize = 0; - shstrtab_hdr->sh_link = 0; - shstrtab_hdr->sh_info = 0; - /* sh_offset is set in assign_file_positions_for_symtabs_and_strtabs. */ - shstrtab_hdr->sh_addralign = 1; - shstrtab_hdr->contents = (PTR) elf_shstrtab (abfd)->tab; - - if (!assign_file_positions_except_relocs (abfd, - link_info == NULL ? true : false)) - return false; - - abfd->output_has_begun = true; - - return true; -} - - -/* Align to the maximum file alignment that could be required for any - ELF data structure. */ - -static INLINE file_ptr -align_file_position (off) - file_ptr off; -{ - return (off + FILE_ALIGN - 1) & ~(FILE_ALIGN - 1); -} - -/* Assign a file position to a section, optionally aligning to the - required section alignment. */ - -static INLINE file_ptr -assign_file_position_for_section (i_shdrp, offset, align) - Elf_Internal_Shdr *i_shdrp; - file_ptr offset; - boolean align; -{ - if (align) - { - unsigned int al; - - al = i_shdrp->sh_addralign; - if (al > 1) - offset = BFD_ALIGN (offset, al); - } - i_shdrp->sh_offset = offset; - if (i_shdrp->rawdata != NULL) - ((asection *) i_shdrp->rawdata)->filepos = offset; - if (i_shdrp->sh_type != SHT_NOBITS) - offset += i_shdrp->sh_size; - return offset; -} - -/* Get the size of the program header. This is called by the linker - before any of the section VMA's are set, so it can't calculate the - correct value for a strange memory layout. */ - -static bfd_size_type -get_program_header_size (abfd) - bfd *abfd; -{ - size_t segs; - asection *s; - - /* Assume we will need exactly two PT_LOAD segments: one for text - and one for data. */ - segs = 2; - - s = bfd_get_section_by_name (abfd, ".interp"); - if (s != NULL && (s->flags & SEC_LOAD) != 0) - { - /* If we have a loadable interpreter section, we need a - PT_INTERP segment. In this case, assume we also need a - PT_PHDR segment, although that may not be true for all - targets. */ - segs += 2; - } - - if (bfd_get_section_by_name (abfd, ".dynamic") != NULL) - { - /* We need a PT_DYNAMIC segment. */ - ++segs; - } - - return segs * sizeof (Elf_External_Phdr); -} - -/* Create the program header. OFF is the file offset where the - program header should be written. FIRST is the first loadable ELF - section. PHDR_SIZE is the size of the program header as returned - by get_program_header_size. */ - -static file_ptr -map_program_segments (abfd, off, first, phdr_size) - bfd *abfd; - file_ptr off; - Elf_Internal_Shdr *first; - bfd_size_type phdr_size; -{ - Elf_Internal_Phdr phdrs[10]; - unsigned int phdr_count; - Elf_Internal_Phdr *phdr; - int phdr_size_adjust; - unsigned int i; - Elf_Internal_Shdr **hdrpp; - asection *sinterp, *sdyn; - unsigned int last_type; - Elf_Internal_Ehdr *i_ehdrp; - - BFD_ASSERT ((abfd->flags & EXEC_P) != 0); - BFD_ASSERT (phdr_size / sizeof (Elf_Internal_Phdr) - <= sizeof phdrs / sizeof (phdrs[0])); - - phdr_count = 0; - phdr = phdrs; - - phdr_size_adjust = 0; - - /* If we have a loadable .interp section, we must create a PT_INTERP - segment which must precede all PT_LOAD segments. We assume that - we must also create a PT_PHDR segment, although that may not be - true for all targets. */ - sinterp = bfd_get_section_by_name (abfd, ".interp"); - if (sinterp != NULL && (sinterp->flags & SEC_LOAD) != 0) - { - BFD_ASSERT (first != NULL); - - phdr->p_type = PT_PHDR; - - phdr->p_offset = off; - - /* Account for any adjustment made because of the alignment of - the first loadable section. */ - phdr_size_adjust = (first->sh_offset - phdr_size) - off; - BFD_ASSERT (phdr_size_adjust >= 0 && phdr_size_adjust < 128); - - /* The program header precedes all loadable sections. This lets - us compute its loadable address. This depends on the linker - script. */ - phdr->p_vaddr = first->sh_addr - (phdr_size + phdr_size_adjust); - - phdr->p_paddr = 0; - phdr->p_filesz = phdr_size; - phdr->p_memsz = phdr_size; - - /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */ - phdr->p_flags = PF_R | PF_X; - - phdr->p_align = FILE_ALIGN; - BFD_ASSERT ((phdr->p_vaddr - phdr->p_offset) % FILE_ALIGN == 0); - - /* Include the ELF header in the first loadable segment. */ - phdr_size_adjust += off; - - ++phdr_count; - ++phdr; - - phdr->p_type = PT_INTERP; - phdr->p_offset = sinterp->filepos; - phdr->p_vaddr = sinterp->vma; - phdr->p_paddr = 0; - phdr->p_filesz = sinterp->_raw_size; - phdr->p_memsz = sinterp->_raw_size; - phdr->p_flags = PF_R; - phdr->p_align = 1 << bfd_get_section_alignment (abfd, sinterp); - - ++phdr_count; - ++phdr; - } - - /* Look through the sections to see how they will be divided into - program segments. The sections must be arranged in order by - sh_addr for this to work correctly. */ - phdr->p_type = PT_NULL; - last_type = SHT_PROGBITS; - for (i = 1, hdrpp = elf_elfsections (abfd) + 1; - i < elf_elfheader (abfd)->e_shnum; - i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - - /* Ignore any section which will not be part of the process - image. */ - if ((hdr->sh_flags & SHF_ALLOC) == 0) - continue; - - /* If this section fits in the segment we are constructing, add - it in. */ - if (phdr->p_type != PT_NULL - && (hdr->sh_offset - (phdr->p_offset + phdr->p_memsz) - == hdr->sh_addr - (phdr->p_vaddr + phdr->p_memsz)) - && (last_type != SHT_NOBITS || hdr->sh_type == SHT_NOBITS)) - { - bfd_size_type adjust; - - adjust = hdr->sh_addr - (phdr->p_vaddr + phdr->p_memsz); - phdr->p_memsz += hdr->sh_size + adjust; - if (hdr->sh_type != SHT_NOBITS) - phdr->p_filesz += hdr->sh_size + adjust; - if ((hdr->sh_flags & SHF_WRITE) != 0) - phdr->p_flags |= PF_W; - if ((hdr->sh_flags & SHF_EXECINSTR) != 0) - phdr->p_flags |= PF_X; - last_type = hdr->sh_type; - continue; - } - - /* If we have a segment, move to the next one. */ - if (phdr->p_type != PT_NULL) - { - ++phdr; - ++phdr_count; - } - - /* Start a new segment. */ - phdr->p_type = PT_LOAD; - phdr->p_offset = hdr->sh_offset; - phdr->p_vaddr = hdr->sh_addr; - phdr->p_paddr = 0; - if (hdr->sh_type == SHT_NOBITS) - phdr->p_filesz = 0; - else - phdr->p_filesz = hdr->sh_size; - phdr->p_memsz = hdr->sh_size; - phdr->p_flags = PF_R; - if ((hdr->sh_flags & SHF_WRITE) != 0) - phdr->p_flags |= PF_W; - if ((hdr->sh_flags & SHF_EXECINSTR) != 0) - phdr->p_flags |= PF_X; - phdr->p_align = get_elf_backend_data (abfd)->maxpagesize; - - if (hdr == first - && sinterp != NULL - && (sinterp->flags & SEC_LOAD) != 0) - { - phdr->p_offset -= phdr_size + phdr_size_adjust; - phdr->p_vaddr -= phdr_size + phdr_size_adjust; - phdr->p_filesz += phdr_size + phdr_size_adjust; - phdr->p_memsz += phdr_size + phdr_size_adjust; - } - - last_type = hdr->sh_type; - } - - if (phdr->p_type != PT_NULL) - { - ++phdr; - ++phdr_count; - } - - /* If we have a .dynamic section, create a PT_DYNAMIC segment. */ - sdyn = bfd_get_section_by_name (abfd, ".dynamic"); - if (sdyn != NULL && (sdyn->flags & SEC_LOAD) != 0) - { - phdr->p_type = PT_DYNAMIC; - phdr->p_offset = sdyn->filepos; - phdr->p_vaddr = sdyn->vma; - phdr->p_paddr = 0; - phdr->p_filesz = sdyn->_raw_size; - phdr->p_memsz = sdyn->_raw_size; - phdr->p_flags = PF_R; - if ((sdyn->flags & SEC_READONLY) == 0) - phdr->p_flags |= PF_W; - if ((sdyn->flags & SEC_CODE) != 0) - phdr->p_flags |= PF_X; - phdr->p_align = 1 << bfd_get_section_alignment (abfd, sdyn); - - ++phdr; - ++phdr_count; - } - - /* Make sure the return value from get_program_header_size matches - what we computed here. */ - if (phdr_count != phdr_size / sizeof (Elf_External_Phdr)) - abort (); - - /* Set up program header information. */ - i_ehdrp = elf_elfheader (abfd); - i_ehdrp->e_phentsize = sizeof (Elf_External_Phdr); - i_ehdrp->e_phoff = off; - i_ehdrp->e_phnum = phdr_count; - - /* Save the program headers away. I don't think anybody uses this - information right now. */ - elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *) - bfd_alloc (abfd, - (phdr_count - * sizeof (Elf_Internal_Phdr)))); - if (elf_tdata (abfd)->phdr == NULL && phdr_count != 0) - { - bfd_set_error (bfd_error_no_memory); - return (file_ptr) -1; - } - memcpy (elf_tdata (abfd)->phdr, phdrs, - phdr_count * sizeof (Elf_Internal_Phdr)); - - /* Write out the program headers. */ - if (bfd_seek (abfd, off, SEEK_SET) != 0) - return (file_ptr) -1; - - for (i = 0, phdr = phdrs; i < phdr_count; i++, phdr++) - { - Elf_External_Phdr extphdr; - - elf_swap_phdr_out (abfd, phdr, &extphdr); - if (bfd_write (&extphdr, sizeof (Elf_External_Phdr), 1, abfd) - != sizeof (Elf_External_Phdr)) - return (file_ptr) -1; - } - - return off + phdr_count * sizeof (Elf_External_Phdr); -} - -/* Work out the file positions of all the sections. This is called by - elf_compute_section_file_positions. All the section sizes and VMAs - must be known before this is called. - - We do not consider reloc sections at this point, unless they form - part of the loadable image. Reloc sections are assigned file - positions in assign_file_positions_for_relocs, which is called by - write_object_contents and final_link. - - If DOSYMS is false, we do not assign file positions for the symbol - table or the string table. */ - -static boolean -assign_file_positions_except_relocs (abfd, dosyms) - bfd *abfd; - boolean dosyms; -{ - struct elf_obj_tdata * const tdata = elf_tdata (abfd); - Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd); - Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd); - file_ptr off; - - /* Start after the ELF header. */ - off = i_ehdrp->e_ehsize; - - if ((abfd->flags & EXEC_P) == 0) - { - Elf_Internal_Shdr **hdrpp; - unsigned int i; - - /* We are not creating an executable, which means that we are - not creating a program header, and that the actual order of - the sections in the file is unimportant. */ - for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - { - hdr->sh_offset = -1; - continue; - } - if (! dosyms - && (i == tdata->symtab_section - || i == tdata->strtab_section)) - { - hdr->sh_offset = -1; - continue; - } - - off = assign_file_position_for_section (hdr, off, true); - } - } - else - { - file_ptr phdr_off; - bfd_size_type phdr_size; - bfd_vma maxpagesize; - Elf_Internal_Shdr **hdrpp; - unsigned int i; - Elf_Internal_Shdr *first; - file_ptr phdr_map; - - /* We are creating an executable. We must create a program - header. We can't actually create the program header until we - have set the file positions for the sections, but we can - figure out how big it is going to be. */ - off = align_file_position (off); - phdr_size = get_program_header_size (abfd); - if (phdr_size == (file_ptr) -1) - return false; - phdr_off = off; - off += phdr_size; - - maxpagesize = get_elf_backend_data (abfd)->maxpagesize; - if (maxpagesize == 0) - maxpagesize = 1; - - /* FIXME: We might want to sort the sections on the sh_addr - field here. For now, we just assume that the linker will - create the sections in an appropriate order. */ - - /* Assign file positions in two passes. In the first pass, we - assign a file position to every section which forms part of - the executable image. */ - first = NULL; - for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if ((hdr->sh_flags & SHF_ALLOC) == 0) - continue; - - if (first == NULL) - first = hdr; - - if ((abfd->flags & D_PAGED) != 0) - { - /* The section VMA must equal the file position modulo - the page size. This is required by the program - header. */ - off += (hdr->sh_addr - off) % maxpagesize; - } - - off = assign_file_position_for_section (hdr, off, false); - } - - /* Assign file positions to all the sections which do not form - part of the loadable image, except for the relocs. */ - for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++) - { - Elf_Internal_Shdr *hdr; - - hdr = *hdrpp; - if ((hdr->sh_flags & SHF_ALLOC) != 0) - continue; - if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) - { - hdr->sh_offset = -1; - continue; - } - if (! dosyms - && (i == tdata->symtab_section - || i == tdata->strtab_section)) - { - hdr->sh_offset = -1; - continue; - } - - off = assign_file_position_for_section (hdr, off, true); - } - - phdr_map = map_program_segments (abfd, phdr_off, first, phdr_size); - if (phdr_map == (file_ptr) -1) - return false; - BFD_ASSERT (phdr_map == phdr_off + phdr_size); - } - - /* Place the section headers. */ - off = align_file_position (off); - i_ehdrp->e_shoff = off; - off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; - - elf_tdata (abfd)->next_file_pos = off; - - return true; -} - -static boolean -prep_headers (abfd) - bfd *abfd; -{ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - int count; - struct strtab *shstrtab; - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - - shstrtab = bfd_new_strtab (abfd); - if (!shstrtab) - return false; - - elf_shstrtab (abfd) = shstrtab; - - i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; - i_ehdrp->e_ident[EI_MAG1] = ELFMAG1; - i_ehdrp->e_ident[EI_MAG2] = ELFMAG2; - i_ehdrp->e_ident[EI_MAG3] = ELFMAG3; - - i_ehdrp->e_ident[EI_CLASS] = ELFCLASS; - i_ehdrp->e_ident[EI_DATA] = - abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB; - i_ehdrp->e_ident[EI_VERSION] = EV_CURRENT; - - for (count = EI_PAD; count < EI_NIDENT; count++) - i_ehdrp->e_ident[count] = 0; - - if ((abfd->flags & DYNAMIC) != 0) - i_ehdrp->e_type = ET_DYN; - else if ((abfd->flags & EXEC_P) != 0) - i_ehdrp->e_type = ET_EXEC; - else - i_ehdrp->e_type = ET_REL; - - switch (bfd_get_arch (abfd)) - { - case bfd_arch_unknown: - i_ehdrp->e_machine = EM_NONE; - break; - case bfd_arch_sparc: -#if ARCH_SIZE == 64 - i_ehdrp->e_machine = EM_SPARC64; -#else - i_ehdrp->e_machine = EM_SPARC; -#endif - break; - case bfd_arch_i386: - i_ehdrp->e_machine = EM_386; - break; - case bfd_arch_m68k: - i_ehdrp->e_machine = EM_68K; - break; - case bfd_arch_m88k: - i_ehdrp->e_machine = EM_88K; - break; - case bfd_arch_i860: - i_ehdrp->e_machine = EM_860; - break; - case bfd_arch_mips: /* MIPS Rxxxx */ - i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */ - break; - case bfd_arch_hppa: - i_ehdrp->e_machine = EM_PARISC; - break; - case bfd_arch_powerpc: - i_ehdrp->e_machine = EM_CYGNUS_POWERPC; - break; - /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ - default: - i_ehdrp->e_machine = EM_NONE; - } - i_ehdrp->e_version = EV_CURRENT; - i_ehdrp->e_ehsize = sizeof (Elf_External_Ehdr); - - /* no program header, for now. */ - i_ehdrp->e_phoff = 0; - i_ehdrp->e_phentsize = 0; - i_ehdrp->e_phnum = 0; - - /* each bfd section is section header entry */ - i_ehdrp->e_entry = bfd_get_start_address (abfd); - i_ehdrp->e_shentsize = sizeof (Elf_External_Shdr); - - /* if we're building an executable, we'll need a program header table */ - if (abfd->flags & EXEC_P) - { - /* it all happens later */ -#if 0 - i_ehdrp->e_phentsize = sizeof (Elf_External_Phdr); - - /* elf_build_phdrs() returns a (NULL-terminated) array of - Elf_Internal_Phdrs */ - i_phdrp = elf_build_phdrs (abfd, i_ehdrp, i_shdrp, &i_ehdrp->e_phnum); - i_ehdrp->e_phoff = outbase; - outbase += i_ehdrp->e_phentsize * i_ehdrp->e_phnum; -#endif - } - else - { - i_ehdrp->e_phentsize = 0; - i_phdrp = 0; - i_ehdrp->e_phoff = 0; - } - - elf_tdata (abfd)->symtab_hdr.sh_name = bfd_add_to_strtab (abfd, shstrtab, - ".symtab"); - elf_tdata (abfd)->strtab_hdr.sh_name = bfd_add_to_strtab (abfd, shstrtab, - ".strtab"); - elf_tdata (abfd)->shstrtab_hdr.sh_name = bfd_add_to_strtab (abfd, shstrtab, - ".shstrtab"); - if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1 - || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1) - return false; - - return true; -} - -static boolean -swap_out_syms (abfd) - bfd *abfd; -{ - if (!elf_map_symbols (abfd)) - return false; - - /* Dump out the symtabs. */ - { - int symcount = bfd_get_symcount (abfd); - asymbol **syms = bfd_get_outsymbols (abfd); - struct strtab *stt = bfd_new_strtab (abfd); - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - Elf_External_Sym *outbound_syms; - int idx; - - if (!stt) - return false; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); - symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1); - symtab_hdr->sh_info = elf_num_locals (abfd) + 1; - symtab_hdr->sh_addralign = FILE_ALIGN; - - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - symstrtab_hdr->sh_type = SHT_STRTAB; - - outbound_syms = (Elf_External_Sym *) - bfd_alloc (abfd, (1 + symcount) * sizeof (Elf_External_Sym)); - if (!outbound_syms) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - /* now generate the data (for "contents") */ - { - /* Fill in zeroth symbol and swap it out. */ - Elf_Internal_Sym sym; - sym.st_name = 0; - sym.st_value = 0; - sym.st_size = 0; - sym.st_info = 0; - sym.st_other = 0; - sym.st_shndx = SHN_UNDEF; - elf_swap_symbol_out (abfd, &sym, outbound_syms); - } - for (idx = 0; idx < symcount; idx++) - { - Elf_Internal_Sym sym; - bfd_vma value = syms[idx]->value; - elf_symbol_type *type_ptr; - - if (syms[idx]->flags & BSF_SECTION_SYM) - /* Section symbols have no names. */ - sym.st_name = 0; - else - { - sym.st_name = bfd_add_to_strtab (abfd, stt, syms[idx]->name); - if (sym.st_name == (unsigned long) -1) - return false; - } - - type_ptr = elf_symbol_from (abfd, syms[idx]); - - if (bfd_is_com_section (syms[idx]->section)) - { - /* ELF common symbols put the alignment into the `value' field, - and the size into the `size' field. This is backwards from - how BFD handles it, so reverse it here. */ - sym.st_size = value; - sym.st_value = type_ptr ? type_ptr->internal_elf_sym.st_value : 16; - sym.st_shndx = elf_section_from_bfd_section (abfd, - syms[idx]->section); - } - else - { - asection *sec = syms[idx]->section; - int shndx; - - if (sec->output_section) - { - value += sec->output_offset; - sec = sec->output_section; - } - value += sec->vma; - sym.st_value = value; - sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0; - sym.st_shndx = shndx = elf_section_from_bfd_section (abfd, sec); - if (shndx == -1) - { - asection *sec2; - /* Writing this would be a hell of a lot easier if we had - some decent documentation on bfd, and knew what to expect - of the library, and what to demand of applications. For - example, it appears that `objcopy' might not set the - section of a symbol to be a section that is actually in - the output file. */ - sec2 = bfd_get_section_by_name (abfd, sec->name); - BFD_ASSERT (sec2 != 0); - sym.st_shndx = shndx = elf_section_from_bfd_section (abfd, sec2); - BFD_ASSERT (shndx != -1); - } - } - - if (bfd_is_com_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT); - else if (bfd_is_und_section (syms[idx]->section)) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE); - else if (syms[idx]->flags & BSF_SECTION_SYM) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - else if (syms[idx]->flags & BSF_FILE) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - else - { - int bind = STB_LOCAL; - int type = STT_OBJECT; - unsigned int flags = syms[idx]->flags; - - if (flags & BSF_LOCAL) - bind = STB_LOCAL; - else if (flags & BSF_WEAK) - bind = STB_WEAK; - else if (flags & BSF_GLOBAL) - bind = STB_GLOBAL; - - if (flags & BSF_FUNCTION) - type = STT_FUNC; - - sym.st_info = ELF_ST_INFO (bind, type); - } - - sym.st_other = 0; - elf_swap_symbol_out (abfd, &sym, - (outbound_syms - + elf_sym_extra (abfd)[idx].elf_sym_num)); - } - - symtab_hdr->contents = (PTR) outbound_syms; - symstrtab_hdr->contents = (PTR) stt->tab; - symstrtab_hdr->sh_size = stt->length; - symstrtab_hdr->sh_type = SHT_STRTAB; - - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - symstrtab_hdr->sh_addralign = 1; - symstrtab_hdr->size = 0; - } - - return true; -} - -static boolean -write_shdrs_and_ehdr (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Shdr *x_shdrp; /* Section header table, external form */ - Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - unsigned int count; - struct strtab *shstrtab; - - i_ehdrp = elf_elfheader (abfd); - i_shdrp = elf_elfsections (abfd); - shstrtab = elf_shstrtab (abfd); - - /* swap the header before spitting it out... */ - -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) - != sizeof (x_ehdr))) - return false; - - /* at this point we've concocted all the ELF sections... */ - x_shdrp = (Elf_External_Shdr *) - bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); - if (!x_shdrp) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - for (count = 0; count < i_ehdrp->e_shnum; count++) - { -#if DEBUG & 2 - elf_debug_section (shstrtab->tab + i_shdrp[count]->sh_name, count, - i_shdrp[count]); -#endif - elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count); - } - if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 - || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd) - != sizeof (*x_shdrp) * i_ehdrp->e_shnum)) - return false; - - /* need to dump the string table too... */ - - return true; -} - -/* Assign file positions for all the reloc sections which are not part - of the loadable file image. */ - -static void -assign_file_positions_for_relocs (abfd) - bfd *abfd; -{ - file_ptr off; - unsigned int i; - Elf_Internal_Shdr **shdrpp; - - off = elf_tdata (abfd)->next_file_pos; - - for (i = 1, shdrpp = elf_elfsections (abfd) + 1; - i < elf_elfheader (abfd)->e_shnum; - i++, shdrpp++) - { - Elf_Internal_Shdr *shdrp; - - shdrp = *shdrpp; - if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA) - && shdrp->sh_offset == -1) - off = assign_file_position_for_section (shdrp, off, true); - } - - elf_tdata (abfd)->next_file_pos = off; -} - -boolean -NAME(bfd_elf,write_object_contents) (abfd) - bfd *abfd; -{ - struct elf_backend_data *bed = get_elf_backend_data (abfd); - Elf_Internal_Ehdr *i_ehdrp; - Elf_Internal_Shdr **i_shdrp; - unsigned int count; - - if (! abfd->output_has_begun - && ! elf_compute_section_file_positions (abfd, - (struct bfd_link_info *) NULL)) - return false; - - i_shdrp = elf_elfsections (abfd); - i_ehdrp = elf_elfheader (abfd); - - bfd_map_over_sections (abfd, write_relocs, (PTR) 0); - assign_file_positions_for_relocs (abfd); - - /* After writing the headers, we need to write the sections too... */ - for (count = 1; count < i_ehdrp->e_shnum; count++) - { - if (bed->elf_backend_section_processing) - (*bed->elf_backend_section_processing) (abfd, i_shdrp[count]); - if (i_shdrp[count]->contents) - { - if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0 - || (bfd_write (i_shdrp[count]->contents, i_shdrp[count]->sh_size, - 1, abfd) - != i_shdrp[count]->sh_size)) - return false; - } - } - - if (bed->elf_backend_final_write_processing) - (*bed->elf_backend_final_write_processing) (abfd, NULL); - - return write_shdrs_and_ehdr (abfd); -} - -/* Given an index of a section, retrieve a pointer to it. Note - that for our purposes, sections are indexed by {1, 2, ...} with - 0 being an illegal index. */ - -/* In the original, each ELF section went into exactly one BFD - section. This doesn't really make sense, so we need a real mapping. - The mapping has to hide in the Elf_Internal_Shdr since asection - doesn't have anything like a tdata field... */ - -static asection * -section_from_elf_index (abfd, index) - bfd *abfd; - unsigned int index; -{ - /* @@ Is bfd_com_section_ptr really correct in all the places it could - be returned from this routine? */ - - if (index == SHN_ABS) - return bfd_com_section_ptr; /* not abs? */ - if (index == SHN_COMMON) - return bfd_com_section_ptr; - - if (index >= elf_elfheader (abfd)->e_shnum) - return NULL; - - { - Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[index]; - - switch (hdr->sh_type) - { - /* ELF sections that map to BFD sections */ - case SHT_PROGBITS: - case SHT_NOBITS: - case SHT_HASH: - case SHT_DYNAMIC: - if (hdr->rawdata == NULL) - { - if (! bfd_section_from_shdr (abfd, index)) - return NULL; - } - return (struct sec *) hdr->rawdata; - - default: - return bfd_abs_section_ptr; - } - } -} - -/* given a section, search the header to find them... */ -static int -elf_section_from_bfd_section (abfd, asect) - bfd *abfd; - struct sec *asect; -{ - Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd); - int index; - Elf_Internal_Shdr *hdr; - int maxindex = elf_elfheader (abfd)->e_shnum; - - if (asect->owner == NULL) - { - if (bfd_is_abs_section (asect)) - return SHN_ABS; - if (bfd_is_com_section (asect)) - return SHN_COMMON; - if (bfd_is_und_section (asect)) - return SHN_UNDEF; - return -1; - } - - BFD_ASSERT (asect->owner == abfd); - - for (index = 0; index < maxindex; index++) - { - hdr = i_shdrp[index]; - switch (hdr->sh_type) - { - /* ELF sections that map to BFD sections */ - case SHT_PROGBITS: - case SHT_NOBITS: - case SHT_NOTE: - case SHT_HASH: - case SHT_DYNAMIC: - case SHT_DYNSYM: - if (hdr->rawdata) - { - if (((struct sec *) (hdr->rawdata)) == asect) - return index; - } - break; - - case SHT_REL: - case SHT_RELA: - /* We sometimes map a reloc section to a BFD section. */ - if (hdr->sh_link != elf_onesymtab (abfd) - && (asection *) hdr->rawdata == asect) - return index; - break; - - case SHT_STRTAB: - /* We map most string tables to BFD sections. */ - if (index != elf_elfheader (abfd)->e_shstrndx - && index != elf_onesymtab (abfd) - && (asection *) hdr->rawdata == asect) - return index; - - /* FALL THROUGH */ - default: - { - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (bed->elf_backend_section_from_bfd_section) - { - int retval; - - retval = index; - if ((*bed->elf_backend_section_from_bfd_section) - (abfd, hdr, asect, &retval)) - return retval; - } - } - break; - } - } - return -1; -} - -/* given a symbol, return the bfd index for that symbol. */ -static int -elf_symbol_from_bfd_symbol (abfd, asym_ptr_ptr) - bfd *abfd; - struct symbol_cache_entry **asym_ptr_ptr; -{ - struct symbol_cache_entry *asym_ptr = *asym_ptr_ptr; - int idx; - flagword flags = asym_ptr->flags; - - /* When gas creates relocations against local labels, it creates its - own symbol for the section, but does put the symbol into the - symbol chain, so udata is 0. When the linker is generating - relocatable output, this section symbol may be for one of the - input sections rather than the output section. */ - if (asym_ptr->udata == (PTR) 0 - && (flags & BSF_SECTION_SYM) - && asym_ptr->section) - { - int indx; - - if (asym_ptr->section->output_section != NULL) - indx = asym_ptr->section->output_section->index; - else - indx = asym_ptr->section->index; - if (elf_section_syms (abfd)[indx]) - asym_ptr->udata = elf_section_syms (abfd)[indx]->udata; - } - - if (asym_ptr->udata) - idx = ((Elf_Sym_Extra *) asym_ptr->udata)->elf_sym_num; - else - { - abort (); - } - -#if DEBUG & 4 - { - - fprintf (stderr, - "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx %s\n", - (long) asym_ptr, asym_ptr->name, idx, flags, elf_symbol_flags (flags)); - fflush (stderr); - } -#endif - - return idx; -} - -static long -elf_slurp_symbol_table (abfd, symptrs, dynamic) - bfd *abfd; - asymbol **symptrs; /* Buffer for generated bfd symbols */ - boolean dynamic; -{ - Elf_Internal_Shdr *hdr; - long symcount; /* Number of external ELF symbols */ - elf_symbol_type *sym; /* Pointer to current bfd symbol */ - elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ - Elf_Internal_Sym i_sym; - Elf_External_Sym *x_symp = NULL; - - /* Read each raw ELF symbol, converting from external ELF form to - internal ELF form, and then using the information to create a - canonical bfd symbol table entry. - - Note that we allocate the initial bfd canonical symbol buffer - based on a one-to-one mapping of the ELF symbols to canonical - symbols. We actually use all the ELF symbols, so there will be no - space left over at the end. When we have all the symbols, we - build the caller's pointer vector. */ - - if (dynamic) - hdr = &elf_tdata (abfd)->dynsymtab_hdr; - else - hdr = &elf_tdata (abfd)->symtab_hdr; - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - if (symcount == 0) - sym = symbase = NULL; - else - { - long i; - - if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) - return -1; - - symbase = ((elf_symbol_type *) - bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type))); - if (symbase == (elf_symbol_type *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return -1; - } - sym = symbase; - - /* Temporarily allocate room for the raw ELF symbols. */ - x_symp = ((Elf_External_Sym *) - malloc (symcount * sizeof (Elf_External_Sym))); - if (x_symp == NULL && symcount != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) - != symcount * sizeof (Elf_External_Sym)) - goto error_return; - /* Skip first symbol, which is a null dummy. */ - for (i = 1; i < symcount; i++) - { - elf_swap_symbol_in (abfd, x_symp + i, &i_sym); - memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym)); -#ifdef ELF_KEEP_EXTSYM - memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym)); -#endif - sym->symbol.the_bfd = abfd; - - sym->symbol.name = elf_string_from_elf_section (abfd, hdr->sh_link, - i_sym.st_name); - - sym->symbol.value = i_sym.st_value; - - if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERVE) - { - sym->symbol.section = section_from_elf_index (abfd, - i_sym.st_shndx); - if (sym->symbol.section == NULL) - { - /* This symbol is in a section for which we did not - create a BFD section. Just use bfd_abs_section, - although it is wrong. FIXME. */ - sym->symbol.section = bfd_abs_section_ptr; - } - } - else if (i_sym.st_shndx == SHN_ABS) - { - sym->symbol.section = bfd_abs_section_ptr; - } - else if (i_sym.st_shndx == SHN_COMMON) - { - sym->symbol.section = bfd_com_section_ptr; - /* Elf puts the alignment into the `value' field, and - the size into the `size' field. BFD wants to see the - size in the value field, and doesn't care (at the - moment) about the alignment. */ - sym->symbol.value = i_sym.st_size; - } - else if (i_sym.st_shndx == SHN_UNDEF) - { - sym->symbol.section = bfd_und_section_ptr; - } - else - sym->symbol.section = bfd_abs_section_ptr; - - sym->symbol.value -= sym->symbol.section->vma; - - switch (ELF_ST_BIND (i_sym.st_info)) - { - case STB_LOCAL: - sym->symbol.flags |= BSF_LOCAL; - break; - case STB_GLOBAL: - sym->symbol.flags |= BSF_GLOBAL; - break; - case STB_WEAK: - sym->symbol.flags |= BSF_WEAK; - break; - } - - switch (ELF_ST_TYPE (i_sym.st_info)) - { - case STT_SECTION: - sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING; - break; - case STT_FILE: - sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING; - break; - case STT_FUNC: - sym->symbol.flags |= BSF_FUNCTION; - break; - } - - if (dynamic) - sym->symbol.flags |= BSF_DYNAMIC; - - /* Do some backend-specific processing on this symbol. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_processing) - (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol); - } - - sym++; - } - } - - /* Do some backend-specific processing on this symbol table. */ - { - struct elf_backend_data *ebd = get_elf_backend_data (abfd); - if (ebd->elf_backend_symbol_table_processing) - (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount); - } - - /* We rely on the zalloc to clear out the final symbol entry. */ - - symcount = sym - symbase; - - /* Fill in the user's symbol pointer vector if needed. */ - if (symptrs) - { - long l = symcount; - - sym = symbase; - while (l-- > 0) - { - *symptrs++ = &sym->symbol; - sym++; - } - *symptrs = 0; /* Final null pointer */ - } - - if (x_symp != NULL) - free (x_symp); - return symcount; -error_return: - if (x_symp != NULL) - free (x_symp); - return -1; -} - -/* Return the number of bytes required to hold the symtab vector. - - Note that we base it on the count plus 1, since we will null terminate - the vector allocated based on this size. However, the ELF symbol table - always has a dummy entry as symbol #0, so it ends up even. */ - -long -elf_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; - - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *)); - - return symtab_size; -} - -long -elf_get_dynamic_symtab_upper_bound (abfd) - bfd *abfd; -{ - long symcount; - long symtab_size; - Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr; - - if (elf_dynsymtab (abfd) == 0) - { - bfd_set_error (bfd_error_invalid_operation); - return -1; - } - - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - symtab_size = (symcount - 1 + 1) * (sizeof (asymbol *)); - - return symtab_size; -} - -long -elf_get_reloc_upper_bound (abfd, asect) - bfd *abfd; - sec_ptr asect; -{ - return (asect->reloc_count + 1) * sizeof (arelent *); -} - -/* Read in and swap the external relocs. */ - -static boolean -elf_slurp_reloc_table (abfd, asect, symbols) - bfd *abfd; - asection *asect; - asymbol **symbols; -{ - struct elf_backend_data * const ebd = get_elf_backend_data (abfd); - struct bfd_elf_section_data * const d = elf_section_data (asect); - PTR allocated = NULL; - bfd_byte *native_relocs; - arelent *relents; - arelent *relent; - unsigned int i; - int entsize; - - if (asect->relocation != NULL) - return true; - - BFD_ASSERT (asect->rel_filepos == d->rel_hdr.sh_offset - && (asect->reloc_count - == d->rel_hdr.sh_size / d->rel_hdr.sh_entsize)); - - native_relocs = (bfd_byte *) elf_section_data (asect)->relocs; - if (native_relocs == NULL) - { - allocated = (PTR) malloc (d->rel_hdr.sh_size); - if (allocated == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0 - || (bfd_read (allocated, 1, d->rel_hdr.sh_size, abfd) - != d->rel_hdr.sh_size)) - goto error_return; - - native_relocs = (bfd_byte *) allocated; - } - - relents = ((arelent *) - bfd_alloc (abfd, asect->reloc_count * sizeof (arelent))); - if (relents == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - entsize = d->rel_hdr.sh_entsize; - BFD_ASSERT (entsize == sizeof (Elf_External_Rel) - || entsize == sizeof (Elf_External_Rela)); - - for (i = 0, relent = relents; - i < asect->reloc_count; - i++, relent++, native_relocs += entsize) - { - Elf_Internal_Rela rela; - Elf_Internal_Rel rel; - - if (entsize == sizeof (Elf_External_Rela)) - elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela); - else - { - elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel); - rela.r_offset = rel.r_offset; - rela.r_info = rel.r_info; - rela.r_addend = 0; - } - - /* The address of an ELF reloc is section relative for an object - file, and absolute for an executable file or shared library. - The address of a BFD reloc is always section relative. */ - if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) - relent->address = rela.r_offset; - else - relent->address = rela.r_offset - asect->vma; - - if (ELF_R_SYM (rela.r_info) == 0) - relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; - else - { - asymbol **ps, *s; - - ps = symbols + ELF_R_SYM (rela.r_info) - 1; - s = *ps; - - /* Canonicalize ELF section symbols. FIXME: Why? */ - if ((s->flags & BSF_SECTION_SYM) == 0) - relent->sym_ptr_ptr = ps; - else - relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; - } - - relent->addend = rela.r_addend; - - if (entsize == sizeof (Elf_External_Rela)) - (*ebd->elf_info_to_howto) (abfd, relent, &rela); - else - (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel); - } - - asect->relocation = relents; - - if (allocated != NULL) - free (allocated); - - return true; - - error_return: - if (allocated != NULL) - free (allocated); - return false; -} - -#ifdef DEBUG -static void -elf_debug_section (str, num, hdr) - char *str; - int num; - Elf_Internal_Shdr *hdr; -{ - fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, str, (long) hdr); - fprintf (stderr, - "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", - (long) hdr->sh_name, - (long) hdr->sh_type, - (long) hdr->sh_flags); - fprintf (stderr, - "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n", - (long) hdr->sh_addr, - (long) hdr->sh_offset, - (long) hdr->sh_size); - fprintf (stderr, - "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n", - (long) hdr->sh_link, - (long) hdr->sh_info, - (long) hdr->sh_addralign); - fprintf (stderr, "sh_entsize = %ld\n", - (long) hdr->sh_entsize); - fprintf (stderr, "rawdata = 0x%.8lx\n", (long) hdr->rawdata); - fprintf (stderr, "contents = 0x%.8lx\n", (long) hdr->contents); - fprintf (stderr, "size = %ld\n", (long) hdr->size); - fflush (stderr); -} - -static void -elf_debug_file (ehdrp) - Elf_Internal_Ehdr *ehdrp; -{ - fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); - fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); - fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum); - fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize); - fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff); - fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); - fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); -} -#endif - -/* Canonicalize the relocs. */ - -long -elf_canonicalize_reloc (abfd, section, relptr, symbols) - bfd *abfd; - sec_ptr section; - arelent **relptr; - asymbol **symbols; -{ - arelent *tblptr; - unsigned int i; - - if (! elf_slurp_reloc_table (abfd, section, symbols)) - return -1; - - tblptr = section->relocation; - for (i = 0; i < section->reloc_count; i++) - *relptr++ = tblptr++; - - *relptr = NULL; - - return section->reloc_count; -} - -long -elf_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - long symcount = elf_slurp_symbol_table (abfd, alocation, false); - - if (symcount >= 0) - bfd_get_symcount (abfd) = symcount; - return symcount; -} - -long -elf_canonicalize_dynamic_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - return elf_slurp_symbol_table (abfd, alocation, true); -} - -asymbol * -elf_make_empty_symbol (abfd) - bfd *abfd; -{ - elf_symbol_type *newsym; - - newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (elf_symbol_type)); - if (!newsym) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - else - { - newsym->symbol.the_bfd = abfd; - return &newsym->symbol; - } -} - -void -elf_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -void -elf_print_symbol (ignore_abfd, filep, symbol, how) - bfd *ignore_abfd; - PTR filep; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) filep; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - case bfd_print_symbol_more: - fprintf (file, "elf "); - fprintf_vma (file, symbol->value); - fprintf (file, " %lx", (long) symbol->flags); - break; - case bfd_print_symbol_all: - { - CONST char *section_name; - section_name = symbol->section ? symbol->section->name : "(*none*)"; - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %s\t%s", - section_name, - symbol->name); - } - break; - } - -} - -alent * -elf_get_lineno (ignore_abfd, symbol) - bfd *ignore_abfd; - asymbol *symbol; -{ - fprintf (stderr, "elf_get_lineno unimplemented\n"); - fflush (stderr); - BFD_FAIL (); - return NULL; -} - -boolean -elf_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - /* If this isn't the right architecture for this backend, and this - isn't the generic backend, fail. */ - if (arch != get_elf_backend_data (abfd)->arch - && arch != bfd_arch_unknown - && get_elf_backend_data (abfd)->arch != bfd_arch_unknown) - return false; - - return bfd_default_set_arch_mach (abfd, arch, machine); -} - -boolean -elf_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; - asection *section; - asymbol **symbols; - bfd_vma offset; - CONST char **filename_ptr; - CONST char **functionname_ptr; - unsigned int *line_ptr; -{ - return false; -} - -int -elf_sizeof_headers (abfd, reloc) - bfd *abfd; - boolean reloc; -{ - int ret; - - ret = sizeof (Elf_External_Ehdr); - if (! reloc) - ret += get_program_header_size (abfd); - return ret; -} - -boolean -elf_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - Elf_Internal_Shdr *hdr; - - if (! abfd->output_has_begun - && ! elf_compute_section_file_positions (abfd, - (struct bfd_link_info *) NULL)) - return false; - - hdr = &elf_section_data (section)->this_hdr; - - if (bfd_seek (abfd, hdr->sh_offset + offset, SEEK_SET) == -1) - return false; - if (bfd_write (location, 1, count, abfd) != count) - return false; - - return true; -} - -void -elf_no_info_to_howto (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rela *dst; -{ - fprintf (stderr, "elf RELA relocation support for target machine unimplemented\n"); - fflush (stderr); - BFD_FAIL (); -} - -void -elf_no_info_to_howto_rel (abfd, cache_ptr, dst) - bfd *abfd; - arelent *cache_ptr; - Elf_Internal_Rel *dst; -{ - fprintf (stderr, "elf REL relocation support for target machine unimplemented\n"); - fflush (stderr); - BFD_FAIL (); -} - - -/* Core file support */ - -#ifdef HAVE_PROCFS /* Some core file support requires host /proc files */ -#include <sys/procfs.h> -#else -#define bfd_prstatus(abfd, descdata, descsz, filepos) true -#define bfd_fpregset(abfd, descdata, descsz, filepos) true -#define bfd_prpsinfo(abfd, descdata, descsz, filepos) true -#endif - -#ifdef HAVE_PROCFS - -static boolean -bfd_prstatus (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - prstatus_t *status = (prstatus_t *) 0; - - if (descsz == sizeof (prstatus_t)) - { - newsect = bfd_make_section (abfd, ".reg"); - if (newsect == NULL) - return false; - newsect->_raw_size = sizeof (status->pr_reg); - newsect->filepos = filepos + (long) &status->pr_reg; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL) - { - memcpy (core_prstatus (abfd), descdata, descsz); - } - } - return true; -} - -/* Stash a copy of the prpsinfo structure away for future use. */ - -static boolean -bfd_prpsinfo (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - if (descsz == sizeof (prpsinfo_t)) - { - if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memcpy (core_prpsinfo (abfd), descdata, descsz); - } - return true; -} - -static boolean -bfd_fpregset (abfd, descdata, descsz, filepos) - bfd *abfd; - char *descdata; - int descsz; - long filepos; -{ - asection *newsect; - - newsect = bfd_make_section (abfd, ".reg2"); - if (newsect == NULL) - return false; - newsect->_raw_size = descsz; - newsect->filepos = filepos; - newsect->flags = SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - return true; -} - -#endif /* HAVE_PROCFS */ - -/* Return a pointer to the args (including the command name) that were - seen by the program that generated the core dump. Note that for - some reason, a spurious space is tacked onto the end of the args - in some (at least one anyway) implementations, so strip it off if - it exists. */ - -char * -elf_core_file_failing_command (abfd) - bfd *abfd; -{ -#ifdef HAVE_PROCFS - if (core_prpsinfo (abfd)) - { - prpsinfo_t *p = core_prpsinfo (abfd); - char *scan = p->pr_psargs; - while (*scan++) - {; - } - scan -= 2; - if ((scan > p->pr_psargs) && (*scan == ' ')) - { - *scan = '\000'; - } - return p->pr_psargs; - } -#endif - return NULL; -} - -/* Return the number of the signal that caused the core dump. Presumably, - since we have a core file, we got a signal of some kind, so don't bother - checking the other process status fields, just return the signal number. - */ - -int -elf_core_file_failing_signal (abfd) - bfd *abfd; -{ -#ifdef HAVE_PROCFS - if (core_prstatus (abfd)) - { - return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig; - } -#endif - return -1; -} - -/* Check to see if the core file could reasonably be expected to have - come for the current executable file. Note that by default we return - true unless we find something that indicates that there might be a - problem. - */ - -boolean -elf_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd; - bfd *exec_bfd; -{ -#ifdef HAVE_PROCFS - char *corename; - char *execname; -#endif - - /* First, xvecs must match since both are ELF files for the same target. */ - - if (core_bfd->xvec != exec_bfd->xvec) - { - bfd_set_error (bfd_error_system_call); - return false; - } - -#ifdef HAVE_PROCFS - - /* If no prpsinfo, just return true. Otherwise, grab the last component - of the exec'd pathname from the prpsinfo. */ - - if (core_prpsinfo (core_bfd)) - { - corename = (((struct prpsinfo *) core_prpsinfo (core_bfd))->pr_fname); - } - else - { - return true; - } - - /* Find the last component of the executable pathname. */ - - if ((execname = strrchr (exec_bfd->filename, '/')) != NULL) - { - execname++; - } - else - { - execname = (char *) exec_bfd->filename; - } - - /* See if they match */ - - return strcmp (execname, corename) ? false : true; - -#else - - return true; - -#endif /* HAVE_PROCFS */ -} - -/* ELF core files contain a segment of type PT_NOTE, that holds much of - the information that would normally be available from the /proc interface - for the process, at the time the process dumped core. Currently this - includes copies of the prstatus, prpsinfo, and fpregset structures. - - Since these structures are potentially machine dependent in size and - ordering, bfd provides two levels of support for them. The first level, - available on all machines since it does not require that the host - have /proc support or the relevant include files, is to create a bfd - section for each of the prstatus, prpsinfo, and fpregset structures, - without any interpretation of their contents. With just this support, - the bfd client will have to interpret the structures itself. Even with - /proc support, it might want these full structures for it's own reasons. - - In the second level of support, where HAVE_PROCFS is defined, bfd will - pick apart the structures to gather some additional information that - clients may want, such as the general register set, the name of the - exec'ed file and its arguments, the signal (if any) that caused the - core dump, etc. - - */ - -static boolean -elf_corefile_note (abfd, hdr) - bfd *abfd; - Elf_Internal_Phdr *hdr; -{ - Elf_External_Note *x_note_p; /* Elf note, external form */ - Elf_Internal_Note i_note; /* Elf note, internal form */ - char *buf = NULL; /* Entire note segment contents */ - char *namedata; /* Name portion of the note */ - char *descdata; /* Descriptor portion of the note */ - char *sectname; /* Name to use for new section */ - long filepos; /* File offset to descriptor data */ - asection *newsect; - - if (hdr->p_filesz > 0 - && (buf = (char *) malloc (hdr->p_filesz)) != NULL - && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1 - && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz) - { - x_note_p = (Elf_External_Note *) buf; - while ((char *) x_note_p < (buf + hdr->p_filesz)) - { - i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz); - i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz); - i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type); - namedata = x_note_p->name; - descdata = namedata + BFD_ALIGN (i_note.namesz, 4); - filepos = hdr->p_offset + (descdata - buf); - switch (i_note.type) - { - case NT_PRSTATUS: - /* process descdata as prstatus info */ - if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prstatus"; - break; - case NT_FPREGSET: - /* process descdata as fpregset info */ - if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".fpregset"; - break; - case NT_PRPSINFO: - /* process descdata as prpsinfo */ - if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos)) - return false; - sectname = ".prpsinfo"; - break; - default: - /* Unknown descriptor, just ignore it. */ - sectname = NULL; - break; - } - if (sectname != NULL) - { - newsect = bfd_make_section (abfd, sectname); - if (newsect == NULL) - return false; - newsect->_raw_size = i_note.descsz; - newsect->filepos = filepos; - newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS; - newsect->alignment_power = 2; - } - x_note_p = (Elf_External_Note *) - (descdata + BFD_ALIGN (i_note.descsz, 4)); - } - } - if (buf != NULL) - { - free (buf); - } - else if (hdr->p_filesz > 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - return true; - -} - -/* Core files are simply standard ELF formatted files that partition - the file using the execution view of the file (program header table) - rather than the linking view. In fact, there is no section header - table in a core file. - - The process status information (including the contents of the general - register set) and the floating point register set are stored in a - segment of type PT_NOTE. We handcraft a couple of extra bfd sections - that allow standard bfd access to the general registers (.reg) and the - floating point registers (.reg2). - - */ - -const bfd_target * -elf_core_file_p (abfd) - bfd *abfd; -{ - Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ - Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ - Elf_External_Phdr x_phdr; /* Program header table entry, external form */ - Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ - unsigned int phindex; - struct elf_backend_data *ebd; - - /* Read in the ELF header in external format. */ - - if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* Now check to see if we have a valid ELF file, and one that BFD can - make use of. The magic number must match, the address size ('class') - and byte-swapping must match our XVEC entry, and it must have a - program header table (FIXME: See comments re segments at top of this - file). */ - - if (elf_file_p (&x_ehdr) == false) - { - wrong: - bfd_set_error (bfd_error_wrong_format); - return NULL; - } - - /* FIXME, Check EI_VERSION here ! */ - - { -#if ARCH_SIZE == 32 - int desired_address_size = ELFCLASS32; -#endif -#if ARCH_SIZE == 64 - int desired_address_size = ELFCLASS64; -#endif - - if (x_ehdr.e_ident[EI_CLASS] != desired_address_size) - goto wrong; - } - - /* Switch xvec to match the specified byte order. */ - switch (x_ehdr.e_ident[EI_DATA]) - { - case ELFDATA2MSB: /* Big-endian */ - if (abfd->xvec->byteorder_big_p == false) - goto wrong; - break; - case ELFDATA2LSB: /* Little-endian */ - if (abfd->xvec->byteorder_big_p == true) - goto wrong; - break; - case ELFDATANONE: /* No data encoding specified */ - default: /* Unknown data encoding specified */ - goto wrong; - } - - /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - elf_tdata (abfd) = - (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); - if (elf_tdata (abfd) == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* FIXME, `wrong' returns from this point onward, leak memory. */ - - /* Now that we know the byte order, swap in the rest of the header */ - i_ehdrp = elf_elfheader (abfd); - elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); -#if DEBUG & 1 - elf_debug_file (i_ehdrp); -#endif - - ebd = get_elf_backend_data (abfd); - - /* Check that the ELF e_machine field matches what this particular - BFD format expects. */ - if (ebd->elf_machine_code != i_ehdrp->e_machine) - { - const bfd_target * const *target_ptr; - - if (ebd->elf_machine_code != EM_NONE) - goto wrong; - - /* This is the generic ELF target. Let it match any ELF target - for which we do not have a specific backend. */ - for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) - { - struct elf_backend_data *back; - - if ((*target_ptr)->flavour != bfd_target_elf_flavour) - continue; - back = (struct elf_backend_data *) (*target_ptr)->backend_data; - if (back->elf_machine_code == i_ehdrp->e_machine) - { - /* target_ptr is an ELF backend which matches this - object file, so reject the generic ELF target. */ - goto wrong; - } - } - } - - /* If there is no program header, or the type is not a core file, then - we are hosed. */ - if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE) - goto wrong; - - /* Allocate space for a copy of the program header table in - internal form, seek to the program header table in the file, - read it in, and convert it to internal form. As a simple sanity - check, verify that the what BFD thinks is the size of each program - header table entry actually matches the size recorded in the file. */ - - if (i_ehdrp->e_phentsize != sizeof (x_phdr)) - goto wrong; - i_phdrp = (Elf_Internal_Phdr *) - bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum); - if (!i_phdrp) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1) - return NULL; - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd) - != sizeof (x_phdr)) - return NULL; - elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex); - } - - /* Once all of the program headers have been read and converted, we - can start processing them. */ - - for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++) - { - bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); - if ((i_phdrp + phindex)->p_type == PT_NOTE) - { - if (! elf_corefile_note (abfd, i_phdrp + phindex)) - return NULL; - } - } - - /* Remember the entry point specified in the ELF file header. */ - - bfd_get_start_address (abfd) = i_ehdrp->e_entry; - - return abfd->xvec; -} - -/* ELF linker code. */ - -static boolean elf_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -static INLINE boolean elf_link_record_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static boolean elf_link_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static boolean elf_adjust_dynamic_symbol - PARAMS ((struct elf_link_hash_entry *, PTR)); - -/* Given an ELF BFD, add symbols to the global hash table as - appropriate. */ - -boolean -elf_bfd_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - switch (bfd_get_format (abfd)) - { - case bfd_object: - return elf_link_add_object_symbols (abfd, info); - case bfd_archive: - return elf_link_add_archive_symbols (abfd, info); - default: - bfd_set_error (bfd_error_wrong_format); - return false; - } -} - -/* Add symbols from an ELF archive file to the linker hash table. We - don't use _bfd_generic_link_add_archive_symbols because of a - problem which arises on UnixWare. The UnixWare libc.so is an - archive which includes an entry libc.so.1 which defines a bunch of - symbols. The libc.so archive also includes a number of other - object files, which also define symbols, some of which are the same - as those defined in libc.so.1. Correct linking requires that we - consider each object file in turn, and include it if it defines any - symbols we need. _bfd_generic_link_add_archive_symbols does not do - this; it looks through the list of undefined symbols, and includes - any object file which defines them. When this algorithm is used on - UnixWare, it winds up pulling in libc.so.1 early and defining a - bunch of symbols. This means that some of the other objects in the - archive are not included in the link, which is incorrect since they - precede libc.so.1 in the archive. - - Fortunately, ELF archive handling is simpler than that done by - _bfd_generic_link_add_archive_symbols, which has to allow for a.out - oddities. In ELF, if we find a symbol in the archive map, and the - symbol is currently undefined, we know that we must pull in that - object file. - - Unfortunately, we do have to make multiple passes over the symbol - table until nothing further is resolved. */ - -static boolean -elf_link_add_archive_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - symindex c; - boolean *defined = NULL; - boolean *included = NULL; - carsym *symdefs; - boolean loop; - - if (! bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - /* Keep track of all symbols we know to be already defined, and all - files we know to be already included. This is to speed up the - second and subsequent passes. */ - c = bfd_ardata (abfd)->symdef_count; - if (c == 0) - return true; - defined = (boolean *) malloc (c * sizeof (boolean)); - included = (boolean *) malloc (c * sizeof (boolean)); - if (defined == (boolean *) NULL || included == (boolean *) NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - memset (defined, 0, c * sizeof (boolean)); - memset (included, 0, c * sizeof (boolean)); - - symdefs = bfd_ardata (abfd)->symdefs; - - do - { - file_ptr last; - symindex i; - carsym *symdef; - carsym *symdefend; - - loop = false; - last = -1; - - symdef = symdefs; - symdefend = symdef + c; - for (i = 0; symdef < symdefend; symdef++, i++) - { - struct elf_link_hash_entry *h; - bfd *element; - struct bfd_link_hash_entry *undefs_tail; - symindex mark; - - if (defined[i] || included[i]) - continue; - if (symdef->file_offset == last) - { - included[i] = true; - continue; - } - - h = elf_link_hash_lookup (elf_hash_table (info), symdef->name, - false, false, false); - if (h == (struct elf_link_hash_entry *) NULL) - continue; - if (h->root.type != bfd_link_hash_undefined) - { - defined[i] = true; - continue; - } - - /* We need to include this archive member. */ - - element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); - if (element == (bfd *) NULL) - goto error_return; - - if (! bfd_check_format (element, bfd_object)) - goto error_return; - - /* Doublecheck that we have not included this object - already--it should be impossible, but there may be - something wrong with the archive. */ - if (element->archive_pass != 0) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - element->archive_pass = 1; - - undefs_tail = info->hash->undefs_tail; - - if (! (*info->callbacks->add_archive_element) (info, element, - symdef->name)) - goto error_return; - if (! elf_link_add_object_symbols (element, info)) - goto error_return; - - /* If there are any new undefined symbols, we need to make - another pass through the archive in order to see whether - they can be defined. FIXME: This isn't perfect, because - common symbols wind up on undefs_tail and because an - undefined symbol which is defined later on in this pass - does not require another pass. This isn't a bug, but it - does make the code less efficient than it could be. */ - if (undefs_tail != info->hash->undefs_tail) - loop = true; - - /* Look backward to mark all symbols from this object file - which we have already seen in this pass. */ - mark = i; - do - { - included[mark] = true; - if (mark == 0) - break; - --mark; - } - while (symdefs[mark].file_offset == symdef->file_offset); - - /* We mark subsequent symbols from this object file as we go - on through the loop. */ - last = symdef->file_offset; - } - } - while (loop); - - free (defined); - free (included); - - return true; - - error_return: - if (defined != (boolean *) NULL) - free (defined); - if (included != (boolean *) NULL) - free (included); - return false; -} - -/* Record a new dynamic symbol. We record the dynamic symbols as we - read the input files, since we need to have a list of all of them - before we can determine the final sizes of the output sections. */ - -static INLINE boolean -elf_link_record_dynamic_symbol (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - if (h->dynindx == -1) - { - h->dynindx = elf_hash_table (info)->dynsymcount; - ++elf_hash_table (info)->dynsymcount; - h->dynstr_index = bfd_add_to_strtab (elf_hash_table (info)->dynobj, - elf_hash_table (info)->dynstr, - h->root.root.string); - if (h->dynstr_index == (unsigned long) -1) - return false; - } - - return true; -} - -/* Add symbols from an ELF object file to the linker hash table. */ - -static boolean -elf_link_add_object_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - boolean (*add_symbol_hook) PARAMS ((bfd *, struct bfd_link_info *, - const Elf_Internal_Sym *, - const char **, flagword *, - asection **, bfd_vma *)); - boolean collect; - Elf_Internal_Shdr *hdr; - size_t symcount; - size_t extsymcount; - size_t extsymoff; - Elf_External_Sym *buf = NULL; - struct elf_link_hash_entry **sym_hash; - boolean dynamic; - Elf_External_Dyn *dynbuf = NULL; - struct elf_link_hash_entry *weaks; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - - add_symbol_hook = get_elf_backend_data (abfd)->elf_add_symbol_hook; - collect = get_elf_backend_data (abfd)->collect; - - hdr = &elf_tdata (abfd)->symtab_hdr; - symcount = hdr->sh_size / sizeof (Elf_External_Sym); - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - if (elf_bad_symtab (abfd)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - buf = (Elf_External_Sym *) malloc (extsymcount * sizeof (Elf_External_Sym)); - if (buf == NULL && extsymcount != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - /* We store a pointer to the hash table entry for each external - symbol. */ - sym_hash = ((struct elf_link_hash_entry **) - bfd_alloc (abfd, - extsymcount * sizeof (struct elf_link_hash_entry *))); - if (sym_hash == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - elf_sym_hashes (abfd) = sym_hash; - - if (elf_elfheader (abfd)->e_type != ET_DYN) - { - dynamic = false; - - /* If we are creating a shared library, create all the dynamic - sections immediately. We need to attach them to something, - so we attach them to this BFD, provided it is the right - format. FIXME: If there are no input BFD's of the same - format as the output, we can't make a shared library. */ - if (info->shared - && elf_hash_table (info)->dynobj == NULL - && abfd->xvec == info->hash->creator) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - elf_hash_table (info)->dynobj = abfd; - } - } - else - { - asection *s; - const char *name; - unsigned long strindex; - - dynamic = true; - - /* You can't use -r against a dynamic object. There's no hope - of using a dynamic object which does not exactly match the - format of the output file. */ - if (info->relocateable - || info->hash->creator != abfd->xvec) - { - bfd_set_error (bfd_error_invalid_operation); - goto error_return; - } - - /* Find the name to use in a DT_NEEDED entry that refers to this - object. If the object has a DT_SONAME entry, we use it. - Otherwise, if the generic linker stuck something in - elf_dt_needed_name, we use that. Otherwise, we just use the - file name. */ - name = bfd_get_filename (abfd); - if (elf_dt_needed_name (abfd) != NULL) - name = elf_dt_needed_name (abfd); - s = bfd_get_section_by_name (abfd, ".dynamic"); - if (s != NULL) - { - Elf_External_Dyn *extdyn; - Elf_External_Dyn *extdynend; - - dynbuf = (Elf_External_Dyn *) malloc (s->_raw_size); - if (dynbuf == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf, - (file_ptr) 0, s->_raw_size)) - goto error_return; - - extdyn = dynbuf; - extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn); - for (; extdyn < extdynend; extdyn++) - { - Elf_Internal_Dyn dyn; - - elf_swap_dyn_in (abfd, extdyn, &dyn); - if (dyn.d_tag == DT_SONAME) - { - int elfsec; - unsigned long link; - - elfsec = elf_section_from_bfd_section (abfd, s); - if (elfsec == -1) - goto error_return; - link = elf_elfsections (abfd)[elfsec]->sh_link; - name = elf_string_from_elf_section (abfd, link, - dyn.d_un.d_val); - if (name == NULL) - goto error_return; - - break; - } - } - - free (dynbuf); - dynbuf = NULL; - } - - /* We do not want to include any of the sections in a dynamic - object in the output file. We hack by simply clobbering the - list of sections in the BFD. This could be handled more - cleanly by, say, a new section flag; the existing - SEC_NEVER_LOAD flag is not the one we want, because that one - still implies that the section takes up space in the output - file. */ - abfd->sections = NULL; - - /* If this is the first dynamic object found in the link, create - the special sections required for dynamic linking. We need - to put them somewhere, and attaching them to the first - dynamic object is as good place as any. */ - if (elf_hash_table (info)->dynobj == NULL) - { - if (! elf_link_create_dynamic_sections (abfd, info)) - goto error_return; - elf_hash_table (info)->dynobj = abfd; - } - - /* Add a DT_NEEDED entry for this dynamic object. */ - strindex = bfd_add_to_strtab (abfd, - elf_hash_table (info)->dynstr, - name); - - if (strindex == (unsigned long) -1) - goto error_return; - if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex)) - goto error_return; - } - - if (bfd_seek (abfd, - hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym), - SEEK_SET) != 0 - || (bfd_read ((PTR) buf, sizeof (Elf_External_Sym), extsymcount, abfd) - != extsymcount * sizeof (Elf_External_Sym))) - goto error_return; - - weaks = NULL; - - esymend = buf + extsymcount; - for (esym = buf; esym < esymend; esym++, sym_hash++) - { - Elf_Internal_Sym sym; - int bind; - bfd_vma value; - asection *sec; - flagword flags; - const char *name; - struct elf_link_hash_entry *h = NULL; - boolean definition; - - elf_swap_symbol_in (abfd, esym, &sym); - - flags = BSF_NO_FLAGS; - sec = NULL; - value = sym.st_value; - *sym_hash = NULL; - - bind = ELF_ST_BIND (sym.st_info); - if (bind == STB_LOCAL) - { - /* This should be impossible, since ELF requires that all - global symbols follow all local symbols, and that sh_info - point to the first global symbol. Unfortunatealy, Irix 5 - screws this up. */ - continue; - } - else if (bind == STB_GLOBAL) - flags = BSF_GLOBAL; - else if (bind == STB_WEAK) - flags = BSF_WEAK; - else - { - /* Leave it up to the processor backend. */ - } - - if (sym.st_shndx == SHN_UNDEF) - sec = bfd_und_section_ptr; - else if (sym.st_shndx > 0 && sym.st_shndx < SHN_LORESERVE) - { - sec = section_from_elf_index (abfd, sym.st_shndx); - if (sec == NULL) - goto error_return; - value -= sec->vma; - } - else if (sym.st_shndx == SHN_ABS) - sec = bfd_abs_section_ptr; - else if (sym.st_shndx == SHN_COMMON) - { - sec = bfd_com_section_ptr; - /* What ELF calls the size we call the value. What ELF - calls the value we call the alignment. */ - value = sym.st_size; - } - else - { - /* Leave it up to the processor backend. */ - } - - name = elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name); - if (name == (const char *) NULL) - goto error_return; - - if (add_symbol_hook) - { - if (! (*add_symbol_hook) (abfd, info, &sym, &name, &flags, &sec, - &value)) - goto error_return; - - /* The hook function sets the name to NULL if this symbol - should be skipped for some reason. */ - if (name == (const char *) NULL) - continue; - } - - /* Sanity check that all possibilities were handled. */ - if (flags == BSF_NO_FLAGS || sec == (asection *) NULL) - { - bfd_set_error (bfd_error_bad_value); - goto error_return; - } - - if (bfd_is_und_section (sec) - || bfd_is_com_section (sec)) - definition = false; - else - definition = true; - - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - /* We need to look up the symbol now in order to get some of - the dynamic object handling right. We pass the hash - table entry in to _bfd_generic_link_add_one_symbol so - that it does not have to look it up again. */ - h = elf_link_hash_lookup (elf_hash_table (info), name, - true, false, false); - if (h == NULL) - goto error_return; - *sym_hash = h; - - /* If we are looking at a dynamic object, and this is a - definition, we need to see if it has already been defined - by some other object. If it has, we want to use the - existing definition, and we do not want to report a - multiple symbol definition error; we do this by - clobbering sec to be bfd_und_section_ptr. */ - if (dynamic && definition) - { - if (h->root.type == bfd_link_hash_defined) - sec = bfd_und_section_ptr; - } - - /* Similarly, if we are not looking at a dynamic object, and - we have a definition, we want to override any definition - we may have from a dynamic object. Symbols from regular - files always take precedence over symbols from dynamic - objects, even if they are defined after the dynamic - object in the link. */ - if (! dynamic - && definition - && h->root.type == bfd_link_hash_defined - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (bfd_get_flavour (h->root.u.def.section->owner) - == bfd_target_elf_flavour) - && (elf_elfheader (h->root.u.def.section->owner)->e_type - == ET_DYN)) - { - /* Change the hash table entry to undefined, and let - _bfd_generic_link_add_one_symbol do the right thing - with the new definition. */ - h->root.type = bfd_link_hash_undefined; - h->root.u.undef.abfd = h->root.u.def.section->owner; - h->elf_link_hash_flags &=~ ELF_LINK_HASH_DEFINED_WEAK; - } - - /* If this is a weak definition which we are going to use, - and the symbol is currently undefined, record that the - definition is weak. */ - if (definition - && (flags & BSF_WEAK) != 0 - && ! bfd_is_und_section (sec) - && (h->root.type == bfd_link_hash_new - || h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_weak)) - h->elf_link_hash_flags |= ELF_LINK_HASH_DEFINED_WEAK; - } - - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, flags, sec, value, (const char *) NULL, - false, collect, (struct bfd_link_hash_entry **) sym_hash))) - goto error_return; - - if (dynamic - && definition - && (flags & BSF_WEAK) != 0 - && ELF_ST_TYPE (sym.st_info) != STT_FUNC - && (*sym_hash)->weakdef == NULL) - { - /* Keep a list of all weak defined non function symbols from - a dynamic object, using the weakdef field. Later in this - function we will set the weakdef field to the correct - value. We only put non-function symbols from dynamic - objects on this list, because that happens to be the only - time we need to know the normal symbol corresponding to a - weak symbol, and the information is time consuming to - figure out. If the weakdef field is not already NULL, - then this symbol was already defined by some previous - dynamic object, and we will be using that previous - definition anyhow. */ - - (*sym_hash)->weakdef = weaks; - weaks = *sym_hash; - } - - if (info->hash->creator->flavour == bfd_target_elf_flavour) - { - int old_flags; - boolean dynsym; - int new_flag; - - /* Remember the symbol size, type and alignment. */ - if (sym.st_size != 0) - { - /* FIXME: We should probably somehow give a warning if - the symbol size changes. */ - h->size = sym.st_size; - } - if (sym.st_shndx == SHN_COMMON - && sym.st_value > h->align) - h->align = sym.st_value; - if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE) - { - /* FIXME: We should probably somehow give a warning if - the symbol type changes. */ - h->type = ELF_ST_TYPE (sym.st_info); - } - - /* Set a flag in the hash table entry indicating the type of - reference or definition we just found. Keep a count of - the number of dynamic symbols we find. A dynamic symbol - is one which is referenced or defined by both a regular - object and a shared object, or one which is referenced or - defined by more than one shared object. */ - old_flags = h->elf_link_hash_flags; - dynsym = false; - if (! dynamic) - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_REGULAR; - else - new_flag = ELF_LINK_HASH_DEF_REGULAR; - if ((old_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0) - dynsym = true; - } - else - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_DYNAMIC; - else - new_flag = ELF_LINK_HASH_DEF_DYNAMIC; - if ((old_flags & new_flag) != 0) - { - if (! definition) - new_flag = ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE; - else - new_flag = ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE; - dynsym = true; - } - else - { - if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR - | ELF_LINK_HASH_REF_REGULAR)) != 0) - dynsym = true; - } - } - - h->elf_link_hash_flags |= new_flag; - if (dynsym && h->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h)) - goto error_return; - } - } - } - - /* Now set the weakdefs field correctly for all the weak defined - symbols we found. The only way to do this is to search all the - symbols. Since we only need the information for non functions in - dynamic objects, that's the only time we actually put anything on - the list WEAKS. We need this information so that if a regular - object refers to a symbol defined weakly in a dynamic object, the - real symbol in the dynamic object is also put in the dynamic - symbols; we also must arrange for both symbols to point to the - same memory location. We could handle the general case of symbol - aliasing, but a general symbol alias can only be generated in - assembler code, handling it correctly would be very time - consuming, and other ELF linkers don't handle general aliasing - either. */ - while (weaks != NULL) - { - struct elf_link_hash_entry *hlook; - asection *slook; - bfd_vma vlook; - struct elf_link_hash_entry **hpp; - struct elf_link_hash_entry **hppend; - - hlook = weaks; - weaks = hlook->weakdef; - hlook->weakdef = NULL; - - BFD_ASSERT (hlook->root.type == bfd_link_hash_defined); - slook = hlook->root.u.def.section; - vlook = hlook->root.u.def.value; - - hpp = elf_sym_hashes (abfd); - hppend = hpp + extsymcount; - for (; hpp < hppend; hpp++) - { - struct elf_link_hash_entry *h; - - h = *hpp; - if (h != hlook - && h->root.type == bfd_link_hash_defined - && h->root.u.def.section == slook - && h->root.u.def.value == vlook) - { - hlook->weakdef = h; - - /* If the weak definition is in the list of dynamic - symbols, make sure the real definition is put there - as well. */ - if (hlook->dynindx != -1 - && h->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h)) - goto error_return; - } - - break; - } - } - } - - if (buf != NULL) - free (buf); - - return true; - - error_return: - if (buf != NULL) - free (buf); - if (dynbuf != NULL) - free (dynbuf); - return false; -} - -/* Create some sections which will be filled in with dynamic linking - information. The ABFD argument is an input file which is a dynamic - object. The dynamic sections take up virtual memory space when the - final executable is run, so we need to create them before addresses - are assigned to the output sections. We work out the actual - contents and size of these sections later. */ - -static boolean -elf_link_create_dynamic_sections (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - flagword flags; - register asection *s; - struct elf_link_hash_entry *h; - struct elf_backend_data *bed; - - /* Note that we set the SEC_IN_MEMORY flag for all of these - sections. */ - flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; - - /* A dynamically linked executable has a .interp section, but a - shared library does not. */ - if (! info->shared) - { - s = bfd_make_section (abfd, ".interp"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - } - - s = bfd_make_section (abfd, ".dynamic"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* The special symbol _DYNAMIC is always set to the start of the - .dynamic section. This call occurs before we have processed the - symbols for any dynamic object, so we don't have to worry about - overriding a dynamic definition. We could set _DYNAMIC in a - linker script, but we only want to define it if we are, in fact, - creating a .dynamic section. We don't want to define it if there - is no .dynamic section, since on some ELF platforms the start up - code examines it to decide how to initialize the process. */ - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0, - (const char *) NULL, false, get_elf_backend_data (abfd)->collect, - (struct bfd_link_hash_entry **) &h))) - return false; - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - - s = bfd_make_section (abfd, ".dynsym"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* The first .dynsym symbol is a dummy. */ - elf_hash_table (info)->dynsymcount = 1; - - s = bfd_make_section (abfd, ".dynstr"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)) - return false; - - /* Create a strtab to hold the dynamic symbol names. */ - elf_hash_table (info)->dynstr = bfd_new_strtab (abfd); - if (elf_hash_table (info)->dynstr == NULL) - return false; - - s = bfd_make_section (abfd, ".hash"); - if (s == NULL - || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) - || ! bfd_set_section_alignment (abfd, s, LOG_FILE_ALIGN)) - return false; - - /* Let the backend create the rest of the sections. This lets the - backend set the right flags. The backend will normally create - the .got and .plt sections. */ - bed = get_elf_backend_data (abfd); - return (*bed->elf_backend_create_dynamic_sections) (abfd, info); -} - -/* Add an entry to the .dynamic table. */ - -boolean -elf_add_dynamic_entry (info, tag, val) - struct bfd_link_info *info; - bfd_vma tag; - bfd_vma val; -{ - Elf_Internal_Dyn dyn; - bfd *dynobj; - asection *s; - size_t newsize; - bfd_byte *newcontents; - - dynobj = elf_hash_table (info)->dynobj; - - s = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (s != NULL); - - newsize = s->_raw_size + sizeof (Elf_External_Dyn); - if (s->contents == NULL) - newcontents = (bfd_byte *) malloc (newsize); - else - newcontents = (bfd_byte *) realloc (s->contents, newsize); - if (newcontents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - dyn.d_tag = tag; - dyn.d_un.d_val = val; - elf_swap_dyn_out (dynobj, &dyn, - (Elf_External_Dyn *) (newcontents + s->_raw_size)); - - s->_raw_size = newsize; - s->contents = newcontents; - - return true; -} - -/* Record an assignment to a symbol made by a linker script. We need - this in case some dynamic object refers to this symbol. */ - -/*ARGSUSED*/ -boolean -NAME(bfd_elf,record_link_assignment) (output_bfd, info, name) - bfd *output_bfd; - struct bfd_link_info *info; - const char *name; -{ - struct elf_link_hash_entry *h; - - /* This is called after we have examined all the input objects. If - the symbol does not exist, it merely means that no object refers - to it, and we can just ignore it at this point. */ - h = elf_link_hash_lookup (elf_hash_table (info), name, - false, false, false); - if (h == NULL) - return true; - - h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; - - if ((h->elf_link_hash_flags & (ELF_LINK_HASH_DEF_DYNAMIC - | ELF_LINK_HASH_REF_DYNAMIC)) != 0 - && h->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h)) - return false; - - /* If this is a weak defined symbol, and we know a corresponding - real symbol from the same dynamic object, make sure the real - symbol is also made into a dynamic symbol. */ - if (h->weakdef != NULL - && h->weakdef->dynindx == -1) - { - if (! elf_link_record_dynamic_symbol (info, h->weakdef)) - return false; - } - } - - return true; -} - -/* Array used to determine the number of hash table buckets to use - based on the number of symbols there are. If there are fewer than - 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, - fewer than 37 we use 17 buckets, and so forth. We never use more - than 521 buckets. */ - -static const size_t elf_buckets[] = -{ - 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 0 -}; - -/* Set up the sizes and contents of the ELF dynamic sections. This is - called by the ELF linker emulation before_allocation routine. We - must set the sizes of the sections before the linker sets the - addresses of the various sections. */ - -boolean -NAME(bfd_elf,size_dynamic_sections) (output_bfd, info, sinterpptr) - bfd *output_bfd; - struct bfd_link_info *info; - asection **sinterpptr; -{ - bfd *dynobj; - size_t dynsymcount; - asection *s; - Elf_Internal_Sym isym; - size_t i; - size_t bucketcount; - struct elf_backend_data *bed; - - *sinterpptr = NULL; - - dynobj = elf_hash_table (info)->dynobj; - dynsymcount = elf_hash_table (info)->dynsymcount; - - /* If there were no dynamic objects in the link, there is nothing to - do here. */ - if (dynobj == NULL) - return true; - - *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (*sinterpptr != NULL || info->shared); - - /* Set the size of the .dynsym and .hash sections. We counted the - number of dynamic symbols in elf_link_add_object_symbols. We - will build the contents of .dynsym and .hash when we build the - final symbol table, because until then we do not know the correct - value to give the symbols. We built the .dynstr section as we - went along in elf_link_add_object_symbols. */ - s = bfd_get_section_by_name (dynobj, ".dynsym"); - BFD_ASSERT (s != NULL); - s->_raw_size = dynsymcount * sizeof (Elf_External_Sym); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - /* The first entry in .dynsym is a dummy symbol. */ - isym.st_value = 0; - isym.st_size = 0; - isym.st_name = 0; - isym.st_info = 0; - isym.st_other = 0; - isym.st_shndx = 0; - elf_swap_symbol_out (output_bfd, &isym, - (Elf_External_Sym *) s->contents); - - for (i = 0; elf_buckets[i] != 0; i++) - { - bucketcount = elf_buckets[i]; - if (dynsymcount < elf_buckets[i + 1]) - break; - } - - s = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (s != NULL); - s->_raw_size = (2 + bucketcount + dynsymcount) * (ARCH_SIZE / 8); - s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size); - if (s->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset (s->contents, 0, s->_raw_size); - - put_word (output_bfd, bucketcount, s->contents); - put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8)); - - elf_hash_table (info)->bucketcount = bucketcount; - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); - s->_raw_size = elf_hash_table (info)->dynstr->length; - s->contents = (unsigned char *) elf_hash_table (info)->dynstr->tab; - - /* Find all symbols which were defined in a dynamic object and make - the backend pick a reasonable value for them. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_adjust_dynamic_symbol, - (PTR) info); - - /* Add some entries to the .dynamic section. We fill in some of the - values later, in elf_bfd_final_link, but we must add the entries - now so that we know the final size of the .dynamic section. */ - if (bfd_get_section_by_name (output_bfd, ".init") != NULL) - { - if (! elf_add_dynamic_entry (info, DT_INIT, 0)) - return false; - } - if (bfd_get_section_by_name (output_bfd, ".fini") != NULL) - { - if (! elf_add_dynamic_entry (info, DT_FINI, 0)) - return false; - } - if (! elf_add_dynamic_entry (info, DT_HASH, 0) - || ! elf_add_dynamic_entry (info, DT_STRTAB, 0) - || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0) - || ! elf_add_dynamic_entry (info, DT_STRSZ, - elf_hash_table (info)->dynstr->length) - || ! elf_add_dynamic_entry (info, DT_SYMENT, - sizeof (Elf_External_Sym))) - return false; - - /* The backend must work out the sizes of all the other dynamic - sections. */ - bed = get_elf_backend_data (output_bfd); - if (! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) - return false; - - return elf_add_dynamic_entry (info, DT_NULL, 0); -} - -/* Make the backend pick a good value for a dynamic symbol. This is - called via elf_link_hash_traverse, and also calls itself - recursively. */ - -static boolean -elf_adjust_dynamic_symbol (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct bfd_link_info *info = (struct bfd_link_info *) data; - bfd *dynobj; - struct elf_backend_data *bed; - - /* If this symbol is not defined by a dynamic object, or is not - referenced by a regular object, ignore it. FIXME: Do we need to - worry about symbols which are defined by one dynamic object and - referenced by another one? */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - return true; - - /* If we've already adjusted this symbol, don't do it again. This - can happen via a recursive call. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0) - return true; - - /* Don't look at this symbol again. Note that we must set this - after checking the above conditions, because we may look at a - symbol once, decide not to do anything, and then get called - recursively later after REF_REGULAR is set below. */ - h->elf_link_hash_flags |= ELF_LINK_HASH_DYNAMIC_ADJUSTED; - - /* If this is a weak definition, and we know a real definition, and - the real symbol is not itself defined by a regular object file, - then get a good value for the real definition. We handle the - real symbol first, for the convenience of the backend routine. - - Note that there is a confusing case here. If the real definition - is defined by a regular object file, we don't get the real symbol - from the dynamic object, but we do get the weak symbol. If the - processor backend uses a COPY reloc, then if some routine in the - dynamic object changes the real symbol, we will not see that - change in the corresponding weak symbol. This is the way other - ELF linkers work as well, and seems to be a result of the shared - library model. - - I will clarify this issue. Most SVR4 shared libraries define the - variable _timezone and define timezone as a weak synonym. The - tzset call changes _timezone. If you write - extern int timezone; - int _timezone = 5; - int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } - you might expect that, since timezone is a synonym for _timezone, - the same number will print both times. However, if the processor - backend uses a COPY reloc, then actually timezone will be copied - into your process image, and, since you define _timezone - yourself, _timezone will not. Thus timezone and _timezone will - wind up at different memory locations. The tzset call will set - _timezone, leaving timezone unchanged. */ - - if (h->weakdef != NULL) - { - struct elf_link_hash_entry *weakdef; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - weakdef = h->weakdef; - BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined); - BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC); - if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - || (weakdef->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - { - /* This symbol is defined or referenced by a regular object - file, so we will not do anything special. Clear weakdef - for the convenience of the processor backend. */ - h->weakdef = NULL; - } - else - { - /* There is an implicit reference by a regular object file - via the weak symbol. */ - weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR; - if (! elf_adjust_dynamic_symbol (weakdef, (PTR) info)) - return false; - } - } - - dynobj = elf_hash_table (info)->dynobj; - bed = get_elf_backend_data (dynobj); - if (! (*bed->elf_backend_adjust_dynamic_symbol) (info, h)) - { - /* FIXME: No way to return error. */ - abort (); - } - - return true; -} - -/* Final phase of ELF linker. */ - -/* A structure we use to avoid passing large numbers of arguments. */ - -struct elf_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ - struct strtab *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ - asection *hash_sec; - /* Buffer large enough to hold contents of any section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any section. */ - PTR external_relocs; - /* Buffer large enough to hold internal relocs of any section. */ - Elf_Internal_Rela *internal_relocs; - /* Buffer large enough to hold external local symbols of any input - BFD. */ - Elf_External_Sym *external_syms; - /* Buffer large enough to hold internal local symbols of any input - BFD. */ - Elf_Internal_Sym *internal_syms; - /* Array large enough to hold a symbol index for each local symbol - of any input BFD. */ - long *indices; - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; - /* Buffer to hold swapped out symbols. */ - Elf_External_Sym *symbuf; - /* Number of swapped out symbols in buffer. */ - size_t symbuf_count; - /* Number of symbols which fit in symbuf. */ - size_t symbuf_size; -}; - -static boolean elf_link_output_sym - PARAMS ((struct elf_final_link_info *, const char *, - Elf_Internal_Sym *, asection *)); -static boolean elf_link_flush_output_syms - PARAMS ((struct elf_final_link_info *)); -static boolean elf_link_output_extsym - PARAMS ((struct elf_link_hash_entry *, PTR)); -static boolean elf_link_input_bfd - PARAMS ((struct elf_final_link_info *, bfd *)); -static boolean elf_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Do the final step of an ELF link. */ - -boolean -elf_bfd_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd *dynobj; - struct elf_final_link_info finfo; - register asection *o; - register struct bfd_link_order *p; - register bfd *sub; - size_t max_contents_size; - size_t max_external_reloc_size; - size_t max_internal_reloc_count; - size_t max_sym_count; - file_ptr off; - Elf_Internal_Sym elfsym; - unsigned int i; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - struct elf_backend_data *bed = get_elf_backend_data (abfd); - - if (info->shared) - { - fprintf (stderr, - "Generating ELF shared libraries is not yet supported\n"); - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - dynobj = elf_hash_table (info)->dynobj; - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.symstrtab = bfd_new_strtab (abfd); - if (finfo.symstrtab == NULL) - return false; - if (dynobj == NULL) - { - finfo.dynsym_sec = NULL; - finfo.hash_sec = NULL; - } - else - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); - if (finfo.dynsym_sec == NULL - || finfo.hash_sec == NULL) - abort (); - } - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - finfo.external_syms = NULL; - finfo.internal_syms = NULL; - finfo.indices = NULL; - finfo.sections = NULL; - finfo.symbuf = NULL; - finfo.symbuf_count = 0; - - /* Count up the number of relocations we will output for each output - section, so that we know the sizes of the reloc sections. We - also figure out some maximum sizes. */ - max_contents_size = 0; - max_external_reloc_size = 0; - max_internal_reloc_count = 0; - max_sym_count = 0; - for (o = abfd->sections; o != (asection *) NULL; o = o->next) - { - o->reloc_count = 0; - - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - - if (info->relocateable) - o->reloc_count += sec->reloc_count; - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->_cooked_size > max_contents_size) - max_contents_size = sec->_cooked_size; - - /* We are interested in just local symbols, not all - symbols. */ - if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour) - { - size_t sym_count; - - if (elf_bad_symtab (sec->owner)) - sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size - / sizeof (Elf_External_Sym)); - else - sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; - - if (sym_count > max_sym_count) - max_sym_count = sym_count; - - if ((sec->flags & SEC_RELOC) != 0) - { - size_t ext_size; - - ext_size = elf_section_data (sec)->rel_hdr.sh_size; - if (ext_size > max_external_reloc_size) - max_external_reloc_size = ext_size; - if (sec->reloc_count > max_internal_reloc_count) - max_internal_reloc_count = sec->reloc_count; - } - } - } - } - - if (o->reloc_count > 0) - o->flags |= SEC_RELOC; - else - { - /* Explicitly clear the SEC_RELOC flag. The linker tends to - set it (this is probably a bug) and if it is set - assign_section_numbers will create a reloc section. */ - o->flags &=~ SEC_RELOC; - } - } - - /* Figure out the file positions for everything but the symbol table - and the relocs. We set symcount to force assign_section_numbers - to create a symbol table. */ - abfd->symcount = info->strip == strip_all ? 0 : 1; - BFD_ASSERT (! abfd->output_has_begun); - if (! elf_compute_section_file_positions (abfd, info)) - goto error_return; - - /* That created the reloc sections. Set their sizes, and assign - them file positions, and allocate some buffers. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Shdr *rel_hdr; - register struct elf_link_hash_entry **p, **pend; - - rel_hdr = &elf_section_data (o)->rel_hdr; - - rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count; - - /* The contents field must last into write_object_contents, - so we allocate it with bfd_alloc rather than malloc. */ - rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size); - if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - p = ((struct elf_link_hash_entry **) - malloc (o->reloc_count - * sizeof (struct elf_link_hash_entry *))); - if (p == NULL && o->reloc_count != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - elf_section_data (o)->rel_hashes = p; - pend = p + o->reloc_count; - for (; p < pend; p++) - *p = NULL; - - /* Use the reloc_count field as an index when outputting the - relocs. */ - o->reloc_count = 0; - } - } - - assign_file_positions_for_relocs (abfd); - - /* We have now assigned file positions for all the sections except - .symtab and .strtab. We start the .symtab section at the current - file position, and write directly to it. We build the .strtab - section in memory. When we add .dynsym support, we will build - that in memory as well (.dynsym is smaller than .symtab). */ - abfd->symcount = 0; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - /* sh_name is set in prep_headers. */ - symtab_hdr->sh_type = SHT_SYMTAB; - symtab_hdr->sh_flags = 0; - symtab_hdr->sh_addr = 0; - symtab_hdr->sh_size = 0; - symtab_hdr->sh_entsize = sizeof (Elf_External_Sym); - /* sh_link is set in assign_section_numbers. */ - /* sh_info is set below. */ - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = 4; /* FIXME: system dependent? */ - - off = elf_tdata (abfd)->next_file_pos; - off = assign_file_position_for_section (symtab_hdr, off, true); - - /* Note that at this point elf_tdata (abfd)->next_file_pos is - incorrect. We do not yet know the size of the .symtab section. - We correct next_file_pos below, after we do know the size. */ - - /* Allocate a buffer to hold swapped out symbols. This is to avoid - continuously seeking to the right position in the file. */ - if (! info->keep_memory || max_sym_count < 20) - finfo.symbuf_size = 20; - else - finfo.symbuf_size = max_sym_count; - finfo.symbuf = ((Elf_External_Sym *) - malloc (finfo.symbuf_size * sizeof (Elf_External_Sym))); - if (finfo.symbuf == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - /* Start writing out the symbol table. The first symbol is always a - dummy symbol. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = 0; - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, bfd_und_section_ptr)) - goto error_return; - -#if 0 - /* Some standard ELF linkers do this, but we don't because it causes - bootstrap comparison failures. */ - /* Output a file symbol for the output file as the second symbol. - We output this even if we are discarding local symbols, although - I'm not sure if this is correct. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - elfsym.st_other = 0; - elfsym.st_shndx = SHN_ABS; - if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd), - &elfsym, bfd_abs_section_ptr)) - goto error_return; -#endif - - /* Output a symbol for each section. We output these even if we are - discarding local symbols, since they are used for relocs. These - symbols have no names. We store the index of each one in the - index field of the section, so that we can find it again when - outputting relocs. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - elfsym.st_other = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - o = section_from_elf_index (abfd, i); - if (! bfd_is_abs_section (o)) - o->target_index = abfd->symcount; - elfsym.st_shndx = i; - if (! elf_link_output_sym (&finfo, (const char *) NULL, - &elfsym, o)) - goto error_return; - } - - /* Allocate some memory to hold information read in from the input - files. */ - finfo.contents = (bfd_byte *) malloc (max_contents_size); - finfo.external_relocs = (PTR) malloc (max_external_reloc_size); - finfo.internal_relocs = ((Elf_Internal_Rela *) - malloc (max_internal_reloc_count - * sizeof (Elf_Internal_Rela))); - finfo.external_syms = ((Elf_External_Sym *) - malloc (max_sym_count * sizeof (Elf_External_Sym))); - finfo.internal_syms = ((Elf_Internal_Sym *) - malloc (max_sym_count * sizeof (Elf_Internal_Sym))); - finfo.indices = (long *) malloc (max_sym_count * sizeof (long)); - finfo.sections = (asection **) malloc (max_sym_count * sizeof (asection *)); - if ((finfo.contents == NULL && max_contents_size != 0) - || (finfo.external_relocs == NULL && max_external_reloc_size != 0) - || (finfo.internal_relocs == NULL && max_internal_reloc_count != 0) - || (finfo.external_syms == NULL && max_sym_count != 0) - || (finfo.internal_syms == NULL && max_sym_count != 0) - || (finfo.indices == NULL && max_sym_count != 0) - || (finfo.sections == NULL && max_sym_count != 0)) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - /* Since ELF permits relocations to be against local symbols, we - must have the local symbols available when we do the relocations. - Since we would rather only read the local symbols once, and we - would rather not keep them in memory, we handle all the - relocations for a single input file at the same time. - - Unfortunately, there is no way to know the total number of local - symbols until we have seen all of them, and the local symbol - indices precede the global symbol indices. This means that when - we are generating relocateable output, and we see a reloc against - a global symbol, we can not know the symbol index until we have - finished examining all the local symbols to see which ones we are - going to output. To deal with this, we keep the relocations in - memory, and don't output them until the end of the link. This is - an unfortunate waste of memory, but I don't see a good way around - it. Fortunately, it only happens when performing a relocateable - link, which is not the common case. FIXME: If keep_memory is set - we could write the relocs out and then read them again; I don't - know how bad the memory loss will be. */ - - for (sub = info->input_bfds; sub != NULL; sub = sub->next) - sub->output_has_begun = false; - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) - == bfd_target_elf_flavour)) - { - sub = p->u.indirect.section->owner; - if (! sub->output_has_begun) - { - if (! elf_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = true; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! elf_reloc_link_order (abfd, info, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* That wrote out all the local symbols. Finish up the symbol table - with the global symbols. */ - - /* The sh_info field records the index of the first non local - symbol. */ - symtab_hdr->sh_info = abfd->symcount; - if (dynobj != NULL) - elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 1; - - /* We get the global symbols from the hash table. */ - elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, - (PTR) &finfo); - - /* Flush all symbols to the file. */ - if (! elf_link_flush_output_syms (&finfo)) - return false; - - /* Now we know the size of the symtab section. */ - off += symtab_hdr->sh_size; - - /* Finish up the symbol string table (.strtab) section. */ - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - /* sh_name was set in prep_headers. */ - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_size = finfo.symstrtab->length; - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - /* sh_offset is set just below. */ - symstrtab_hdr->sh_addralign = 1; - symstrtab_hdr->contents = (PTR) finfo.symstrtab->tab; - - off = assign_file_position_for_section (symstrtab_hdr, off, true); - elf_tdata (abfd)->next_file_pos = off; - - /* Adjust the relocs to have the correct symbol indices. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *rel_hdr; - - if ((o->flags & SEC_RELOC) == 0) - continue; - - rel_hash = elf_section_data (o)->rel_hashes; - rel_hdr = &elf_section_data (o)->rel_hdr; - for (i = 0; i < o->reloc_count; i++, rel_hash++) - { - if (*rel_hash == NULL) - continue; - - BFD_ASSERT ((*rel_hash)->indx >= 0); - - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_Internal_Rel irel; - - erel = (Elf_External_Rel *) rel_hdr->contents + i; - elf_swap_reloc_in (abfd, erel, &irel); - irel.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irel.r_info)); - elf_swap_reloc_out (abfd, &irel, erel); - } - else - { - Elf_External_Rela *erela; - Elf_Internal_Rela irela; - - BFD_ASSERT (rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) rel_hdr->contents + i; - elf_swap_reloca_in (abfd, erela, &irela); - irela.r_info = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irela.r_info)); - elf_swap_reloca_out (abfd, &irela, erela); - } - } - - /* Set the reloc_count field to 0 to prevent write_relocs from - trying to swap the relocs out itself. */ - o->reloc_count = 0; - } - - /* If we are linking against a dynamic object, finish up the dynamic - linking information. */ - if (dynobj != NULL) - { - Elf_External_Dyn *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = (Elf_External_Dyn *) o->contents; - dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - elf_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - - case DT_INIT: - name = ".init"; - goto get_vma; - case DT_FINI: - name = ".fini"; - goto get_vma; - case DT_HASH: - name = ".hash"; - goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; - case DT_SYMTAB: - name = ".dynsym"; - get_vma: - o = bfd_get_section_by_name (abfd, name); - BFD_ASSERT (o != NULL); - dyn.d_un.d_ptr = o->vma; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - - case DT_REL: - case DT_RELA: - case DT_RELSZ: - case DT_RELASZ: - if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) - type = SHT_REL; - else - type = SHT_RELA; - dyn.d_un.d_val = 0; - for (i = 1; i < elf_elfheader (abfd)->e_shnum; i++) - { - Elf_Internal_Shdr *hdr; - - hdr = elf_elfsections (abfd)[i]; - if (hdr->sh_type == type - && (hdr->sh_flags & SHF_ALLOC) != 0) - { - if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) - dyn.d_un.d_val += hdr->sh_size; - else - { - if (dyn.d_un.d_val == 0 - || hdr->sh_addr < dyn.d_un.d_val) - dyn.d_un.d_val = hdr->sh_addr; - } - } - } - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - } - } - - if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) - goto error_return; - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0) - continue; - if ((o->flags & SEC_IN_MEMORY) == 0) - { - BFD_ASSERT (info->shared); - continue; - } - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, o->output_offset, - o->_raw_size)) - goto error_return; - } - } - - /* Now backend stuff. */ - if (bed->elf_backend_final_write_processing) - (*bed->elf_backend_final_write_processing) (abfd, NULL); - - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - return true; - - error_return: - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - return false; -} - -/* Add a symbol to the output symbol table. */ - -static boolean -elf_link_output_sym (finfo, name, elfsym, input_sec) - struct elf_final_link_info *finfo; - const char *name; - Elf_Internal_Sym *elfsym; - asection *input_sec; -{ - boolean (*output_symbol_hook) PARAMS ((bfd *, - struct bfd_link_info *info, - const char *, - Elf_Internal_Sym *, - asection *)); - - output_symbol_hook = get_elf_backend_data (finfo->output_bfd)-> - elf_backend_link_output_symbol_hook; - if (output_symbol_hook != NULL) - { - if (! ((*output_symbol_hook) - (finfo->output_bfd, finfo->info, name, elfsym, input_sec))) - return false; - } - - if (name == (const char *) NULL || *name == '\0') - elfsym->st_name = 0; - else - { - elfsym->st_name = bfd_add_to_strtab (finfo->output_bfd, - finfo->symstrtab, name); - if (elfsym->st_name == (unsigned long) -1) - return false; - } - - if (finfo->symbuf_count >= finfo->symbuf_size) - { - if (! elf_link_flush_output_syms (finfo)) - return false; - } - - elf_swap_symbol_out (finfo->output_bfd, elfsym, - finfo->symbuf + finfo->symbuf_count); - ++finfo->symbuf_count; - - ++finfo->output_bfd->symcount; - - return true; -} - -/* Flush the output symbols to the file. */ - -static boolean -elf_link_flush_output_syms (finfo) - struct elf_final_link_info *finfo; -{ - Elf_Internal_Shdr *symtab; - - symtab = &elf_tdata (finfo->output_bfd)->symtab_hdr; - - if (bfd_seek (finfo->output_bfd, symtab->sh_offset + symtab->sh_size, - SEEK_SET) != 0 - || (bfd_write ((PTR) finfo->symbuf, finfo->symbuf_count, - sizeof (Elf_External_Sym), finfo->output_bfd) - != finfo->symbuf_count * sizeof (Elf_External_Sym))) - return false; - - symtab->sh_size += finfo->symbuf_count * sizeof (Elf_External_Sym); - - finfo->symbuf_count = 0; - - return true; -} - -/* Add an external symbol to the symbol table. This is called from - the hash table traversal routine. */ - -static boolean -elf_link_output_extsym (h, data) - struct elf_link_hash_entry *h; - PTR data; -{ - struct elf_final_link_info *finfo = (struct elf_final_link_info *) data; - boolean strip; - Elf_Internal_Sym sym; - asection *input_sec; - - /* We don't want to output symbols that have never been mentioned by - a regular file, or that we have been told to strip. However, if - h->indx is set to -2, the symbol is used by a reloc and we must - output it. */ - if (h->indx == -2) - strip = false; - else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = true; - else if (finfo->info->strip == strip_all - || (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, - false, false) == NULL)) - strip = true; - else - strip = false; - - /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do. */ - if (strip && h->dynindx == -1) - return true; - - sym.st_value = 0; - sym.st_size = h->size; - sym.st_other = 0; - if (h->root.type == bfd_link_hash_weak - || (h->elf_link_hash_flags & ELF_LINK_HASH_DEFINED_WEAK) != 0) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - return false; - - case bfd_link_hash_undefined: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_weak: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_defined: - { - - input_sec = h->root.u.def.section; - if (input_sec->output_section != NULL) - { - sym.st_shndx = elf_section_from_bfd_section (finfo->output_bfd, - input_sec->output_section); - if (sym.st_shndx == (unsigned short) -1) - { - /* FIXME: No way to handle errors. */ - abort (); - } - - /* ELF symbols in relocateable files are section relative, - but in nonrelocateable files they are virtual - addresses. */ - sym.st_value = h->root.u.def.value + input_sec->output_offset; - if (! finfo->info->relocateable) - sym.st_value += input_sec->output_section->vma; - } - else - { - BFD_ASSERT (bfd_get_flavour (input_sec->owner) - == bfd_target_elf_flavour - && elf_elfheader (input_sec->owner)->e_type == ET_DYN); - sym.st_shndx = SHN_UNDEF; - input_sec = bfd_und_section_ptr; - } - } - break; - - case bfd_link_hash_common: - input_sec = bfd_com_section_ptr; - sym.st_shndx = SHN_COMMON; - if (h->align == 0) - sym.st_value = 1; - else - sym.st_value = h->align; - break; - - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* I have no idea how these should be handled. */ - return true; - } - - /* If this symbol should be put in the .dynsym section, then put it - there now. We have already know the symbol index. We also fill - in the entry in the .hash section. */ - if (h->dynindx != -1) - { - struct elf_backend_data *bed; - size_t bucketcount; - size_t bucket; - bfd_byte *bucketpos; - bfd_vma chain; - - sym.st_name = h->dynstr_index; - - /* Give the processor backend a chance to tweak the symbol - value, and also to finish up anything that needs to be done - for this symbol. */ - bed = get_elf_backend_data (finfo->output_bfd); - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (finfo->output_bfd, finfo->info, h, &sym))) - { - /* FIXME: No way to return error. */ - abort (); - } - - elf_swap_symbol_out (finfo->output_bfd, &sym, - ((Elf_External_Sym *) finfo->dynsym_sec->contents - + h->dynindx)); - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = bfd_elf_hash (h->root.root.string) % bucketcount; - bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * (ARCH_SIZE / 8)); - chain = get_word (finfo->output_bfd, bucketpos); - put_word (finfo->output_bfd, h->dynindx, bucketpos); - put_word (finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * (ARCH_SIZE / 8))); - } - - /* If we're stripping it, then it was just a dynamic symbol, and - there's nothing else to do. */ - if (strip) - return true; - - h->indx = finfo->output_bfd->symcount; - - if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec)) - { - /* FIXME: No way to return error. */ - abort (); - } - - return true; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. - This is so that we only have to read the local symbols once, and - don't have to keep them in memory. */ - -static boolean -elf_link_input_bfd (finfo, input_bfd) - struct elf_final_link_info *finfo; - bfd *input_bfd; -{ - boolean (*relocate_section) PARAMS ((bfd *, struct bfd_link_info *, - bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, - Elf_Internal_Sym *, - asection **, char *)); - bfd *output_bfd; - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - Elf_External_Sym *esym; - Elf_External_Sym *esymend; - Elf_Internal_Sym *isym; - long *pindex; - asection **ppsection; - asection *o; - - output_bfd = finfo->output_bfd; - relocate_section = - get_elf_backend_data (output_bfd)->elf_backend_relocate_section; - - /* If this is a dynamic object, we don't want to do anything here: - we don't want the local symbols, and we don't want the section - contents. */ - if (elf_elfheader (input_bfd)->e_type == ET_DYN) - return true; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / sizeof (Elf_External_Sym); - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - /* Read the local symbols. */ - if (locsymcount > 0 - && (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_read (finfo->external_syms, sizeof (Elf_External_Sym), - locsymcount, input_bfd) - != locsymcount * sizeof (Elf_External_Sym)))) - return false; - - /* Swap in the local symbols and write out the ones which we know - are going into the output file. */ - esym = finfo->external_syms; - esymend = esym + locsymcount; - isym = finfo->internal_syms; - pindex = finfo->indices; - ppsection = finfo->sections; - for (; esym < esymend; esym++, isym++, pindex++, ppsection++) - { - asection *isec; - const char *name; - bfd_vma oldval; - - elf_swap_symbol_in (input_bfd, esym, isym); - *pindex = -1; - - if (elf_bad_symtab (input_bfd)) - { - if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) - { - *ppsection = NULL; - continue; - } - } - - if (isym->st_shndx == SHN_UNDEF) - isec = bfd_und_section_ptr; - else if (isym->st_shndx > 0 && isym->st_shndx < SHN_LORESERVE) - { - isec = section_from_elf_index (input_bfd, isym->st_shndx); - if (isec == NULL) - return false; - } - else if (isym->st_shndx == SHN_ABS) - isec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - isec = bfd_com_section_ptr; - else - { - /* Who knows? */ - isec = NULL; - } - - *ppsection = isec; - - /* Don't output the first, undefined, symbol. */ - if (esym == finfo->external_syms) - continue; - - /* If we are stripping all symbols, we don't want to output this - one. */ - if (finfo->info->strip == strip_all) - continue; - - /* We never output section symbols. Instead, we use the section - symbol of the corresponding section in the output file. */ - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - continue; - - /* If we are discarding all local symbols, we don't want to - output this one. If we are generating a relocateable output - file, then some of the local symbols may be required by - relocs; we output them below as we discover that they are - needed. */ - if (finfo->info->discard == discard_all) - continue; - - /* Get the name of the symbol. */ - name = elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, - isym->st_name); - if (name == NULL) - return false; - - /* See if we are discarding symbols with this name. */ - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, false, false) - == NULL)) - || (finfo->info->discard == discard_l - && strncmp (name, finfo->info->lprefix, - finfo->info->lprefix_len) == 0)) - continue; - - /* If we get here, we are going to output this symbol. */ - - /* Adjust the section index for the output file. */ - isym->st_shndx = elf_section_from_bfd_section (output_bfd, - isec->output_section); - if (isym->st_shndx == (unsigned short) -1) - return false; - - *pindex = output_bfd->symcount; - - /* ELF symbols in relocateable files are section relative, but - in executable files they are virtual addresses. Note that - this code assumes that all ELF sections have an associated - BFD section with a reasonable value for output_offset; below - we assume that they also have a reasonable value for - output_section. Any special sections must be set up to meet - these requirements. */ - oldval = isym->st_value; - isym->st_value += isec->output_offset; - if (! finfo->info->relocateable) - isym->st_value += isec->output_section->vma; - - if (! elf_link_output_sym (finfo, name, isym, isec)) - return false; - - /* Restore the old value for reloc handling. */ - isym->st_value = oldval; - } - - /* Relocate the contents of each section. */ - for (o = input_bfd->sections; o != NULL; o = o->next) - { - Elf_Internal_Shdr *input_rel_hdr; - - if ((o->flags & SEC_HAS_CONTENTS) == 0) - continue; - - if ((o->flags & SEC_IN_MEMORY) != 0 - && input_bfd == elf_hash_table (finfo->info)->dynobj) - { - /* Section was created by elf_link_create_dynamic_sections. - FIXME: This test is fragile. */ - continue; - } - - /* Read the contents of the section. */ - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; - - if ((o->flags & SEC_RELOC) != 0) - { - PTR external_relocs; - - /* Get the external relocs. They may have been cached. */ - external_relocs = elf_section_data (o)->relocs; - if (external_relocs == NULL) - { - input_rel_hdr = &elf_section_data (o)->rel_hdr; - if ((bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) - != 0) - || (bfd_read (finfo->external_relocs, 1, - input_rel_hdr->sh_size, input_bfd) - != input_rel_hdr->sh_size)) - return false; - external_relocs = finfo->external_relocs; - } - - /* Swap in the relocs. For convenience, we always produce - an Elf_Internal_Rela array; if the relocs are Rel, we set - the addend to 0. */ - if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - Elf_External_Rel *erelend; - Elf_Internal_Rela *irela; - - erel = (Elf_External_Rel *) external_relocs; - erelend = erel + o->reloc_count; - irela = finfo->internal_relocs; - for (; erel < erelend; erel++, irela++) - { - Elf_Internal_Rel irel; - - elf_swap_reloc_in (input_bfd, erel, &irel); - irela->r_offset = irel.r_offset; - irela->r_info = irel.r_info; - irela->r_addend = 0; - } - } - else - { - Elf_External_Rela *erela; - Elf_External_Rela *erelaend; - Elf_Internal_Rela *irela; - - BFD_ASSERT (input_rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - - erela = (Elf_External_Rela *) external_relocs; - erelaend = erela + o->reloc_count; - irela = finfo->internal_relocs; - for (; erela < erelaend; erela++, irela++) - elf_swap_reloca_in (input_bfd, erela, irela); - } - - /* Relocate the section by invoking a back end routine. - - The back end routine is responsible for adjusting the - section contents as necessary, and (if using Rela relocs - and generating a relocateable output file) adjusting the - reloc addend as necessary. - - The back end routine does not have to worry about setting - the reloc address or the reloc symbol index. - - The back end routine is given a pointer to the swapped in - internal symbols, and can access the hash table entries - for the external symbols via elf_sym_hashes (input_bfd). - - When generating relocateable output, the back end routine - must handle STB_LOCAL/STT_SECTION symbols specially. The - output symbol is going to be a section symbol - corresponding to the output section, which will require - the addend to be adjusted. */ - - if (! (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, - finfo->contents, - finfo->internal_relocs, - finfo->internal_syms, - finfo->sections, - finfo->symstrtab->tab)) - return false; - - if (finfo->info->relocateable) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *output_rel_hdr; - - /* Adjust the reloc addresses and symbol indices. */ - - irela = finfo->internal_relocs; - irelaend = irela + o->reloc_count; - rel_hash = (elf_section_data (o->output_section)->rel_hashes - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, rel_hash++) - { - long r_symndx; - Elf_Internal_Sym *isym; - asection *sec; - - irela->r_offset += o->output_offset; - - r_symndx = ELF_R_SYM (irela->r_info); - - if (r_symndx == 0) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - long indx; - - /* This is a reloc against a global symbol. We - have not yet output all the local symbols, so - we do not know the symbol index of any global - symbol. We set the rel_hash entry for this - reloc to point to the global hash table entry - for this symbol. The symbol index is then - set at the end of elf_bfd_final_link. */ - indx = r_symndx - extsymoff; - *rel_hash = elf_sym_hashes (input_bfd)[indx]; - - /* Setting the index to -2 tells - elf_link_output_extsym that this symbol is - used by a reloc. */ - BFD_ASSERT ((*rel_hash)->indx < 0); - (*rel_hash)->indx = -2; - - continue; - } - - /* This is a reloc against a local symbol. */ - - *rel_hash = NULL; - isym = finfo->internal_syms + r_symndx; - sec = finfo->sections[r_symndx]; - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - { - /* I suppose the backend ought to fill in the - section of any STT_SECTION symbol against a - processor specific section. */ - if (sec != NULL && bfd_is_abs_section (sec)) - r_symndx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - r_symndx = sec->output_section->target_index; - if (r_symndx == 0) - abort (); - } - } - else - { - if (finfo->indices[r_symndx] == -1) - { - unsigned long link; - const char *name; - asection *osec; - - if (finfo->info->strip == strip_all) - { - /* You can't do ld -r -s. */ - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - /* This symbol was skipped earlier, but - since it is needed by a reloc, we - must output it now. */ - link = symtab_hdr->sh_link; - name = elf_string_from_elf_section (input_bfd, - link, - isym->st_name); - if (name == NULL) - return false; - - osec = sec->output_section; - isym->st_shndx = - elf_section_from_bfd_section (output_bfd, - osec); - if (isym->st_shndx == (unsigned short) -1) - return false; - - isym->st_value += sec->output_offset; - if (! finfo->info->relocateable) - isym->st_value += osec->vma; - - finfo->indices[r_symndx] = output_bfd->symcount; - - if (! elf_link_output_sym (finfo, name, isym, sec)) - return false; - } - - r_symndx = finfo->indices[r_symndx]; - } - - irela->r_info = ELF_R_INFO (r_symndx, - ELF_R_TYPE (irela->r_info)); - } - - /* Swap out the relocs. */ - output_rel_hdr = &elf_section_data (o->output_section)->rel_hdr; - BFD_ASSERT (output_rel_hdr->sh_entsize - == input_rel_hdr->sh_entsize); - irela = finfo->internal_relocs; - irelaend = irela + o->reloc_count; - if (input_rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - Elf_External_Rel *erel; - - erel = ((Elf_External_Rel *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erel++) - { - Elf_Internal_Rel irel; - - irel.r_offset = irela->r_offset; - irel.r_info = irela->r_info; - BFD_ASSERT (irela->r_addend == 0); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - } - else - { - Elf_External_Rela *erela; - - BFD_ASSERT (input_rel_hdr->sh_entsize - == sizeof (Elf_External_Rela)); - erela = ((Elf_External_Rela *) output_rel_hdr->contents - + o->output_section->reloc_count); - for (; irela < irelaend; irela++, erela++) - elf_swap_reloca_out (output_bfd, irela, erela); - } - - o->output_section->reloc_count += o->reloc_count; - } - } - - /* Write out the modified section contents. */ - if (! bfd_set_section_contents (output_bfd, o->output_section, - finfo->contents, o->output_offset, - (o->_cooked_size != 0 - ? o->_cooked_size - : o->_raw_size))) - return false; - } - - return true; -} - -/* Generate a reloc when linking an ELF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static boolean -elf_reloc_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - const reloc_howto_type *howto; - long indx; - bfd_vma offset; - struct elf_link_hash_entry **rel_hash_ptr; - Elf_Internal_Shdr *rel_hdr; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* If this is an inplace reloc, we must write the addend into the - object file. */ - if (howto->partial_inplace - && link_order->u.reloc.p->addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - rstat = _bfd_relocate_contents (howto, output_bfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - } - - /* Figure out the symbol index. */ - rel_hash_ptr = (elf_section_data (output_section)->rel_hashes - + output_section->reloc_count); - if (link_order->type == bfd_section_reloc_link_order) - { - indx = link_order->u.reloc.p->u.section->target_index; - if (indx == 0) - abort (); - *rel_hash_ptr = NULL; - } - else - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), - link_order->u.reloc.p->u.name, - false, false, true); - if (h != NULL) - { - /* Setting the index to -2 tells elf_link_output_extsym that - this symbol is used by a reloc. */ - h->indx = -2; - *rel_hash_ptr = h; - indx = 0; - } - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, (bfd *) NULL, - (asection *) NULL, (bfd_vma) 0))) - return false; - indx = 0; - } - } - - /* The address of a reloc is relative to the section in a - relocateable file, and is a virtual address in an executable - file. */ - offset = link_order->offset; - if (! info->relocateable) - offset += output_section->vma; - - rel_hdr = &elf_section_data (output_section)->rel_hdr; - - if (rel_hdr->sh_type == SHT_REL) - { - Elf_Internal_Rel irel; - Elf_External_Rel *erel; - - irel.r_offset = offset; - irel.r_info = ELF_R_INFO (indx, howto->type); - erel = ((Elf_External_Rel *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloc_out (output_bfd, &irel, erel); - } - else - { - Elf_Internal_Rela irela; - Elf_External_Rela *erela; - - irela.r_offset = offset; - irela.r_info = ELF_R_INFO (indx, howto->type); - irela.r_addend = link_order->u.reloc.p->addend; - erela = ((Elf_External_Rela *) rel_hdr->contents - + output_section->reloc_count); - elf_swap_reloca_out (output_bfd, &irela, erela); - } - - ++output_section->reloc_count; - - return true; -} diff --git a/gnu/usr.bin/gdb/bfd/format.c b/gnu/usr.bin/gdb/bfd/format.c deleted file mode 100644 index adee048..0000000 --- a/gnu/usr.bin/gdb/bfd/format.c +++ /dev/null @@ -1,318 +0,0 @@ -/* Generic BFD support for file formats. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - File formats - - A format is a BFD concept of high level file contents type. The - formats supported by BFD are: - - o <<bfd_object>> - - The BFD may contain data, symbols, relocations and debug info. - - o <<bfd_archive>> - - The BFD contains other BFDs and an optional index. - - o <<bfd_core>> - - The BFD contains the result of an executable core dump. - - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* IMPORT from targets.c. */ -extern const size_t _bfd_target_vector_entries; - -/* -FUNCTION - bfd_check_format - -SYNOPSIS - boolean bfd_check_format(bfd *abfd, bfd_format format); - -DESCRIPTION - Verify if the file attached to the BFD @var{abfd} is compatible - with the format @var{format} (i.e., one of <<bfd_object>>, - <<bfd_archive>> or <<bfd_core>>). - - If the BFD has been set to a specific target before the - call, only the named target and format combination is - checked. If the target has not been set, or has been set to - <<default>>, then all the known target backends is - interrogated to determine a match. If the default target - matches, it is used. If not, exactly one target must recognize - the file, or an error results. - - The function returns <<true>> on success, otherwise <<false>> - with one of the following error codes: - - o <<bfd_error_invalid_operation>> - - if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or - <<bfd_core>>. - - o <<bfd_error_system_call>> - - if an error occured during a read - even some file mismatches - can cause bfd_error_system_calls. - - o <<file_not_recognised>> - - none of the backends recognised the file format. - - o <<bfd_error_file_ambiguously_recognized>> - - more than one backend recognised the file format. -*/ - -boolean -bfd_check_format (abfd, format) - bfd *abfd; - bfd_format format; -{ - return bfd_check_format_matches (abfd, format, NULL); -} - -/* -FUNCTION - bfd_check_format_matches - -SYNOPSIS - boolean bfd_check_format_matches(bfd *abfd, bfd_format format, char ***matching); - -DESCRIPTION - Like <<bfd_check_format>>, except when it returns false with - <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that - case, if @var{matching} is not NULL, it will be filled in with - a NULL-terminated list of the names of the formats that matched, - allocated with <<malloc>>. - Then the user may choose a format and try again. - - When done with the list that @var{matching} points to, the caller - should free it. -*/ - -boolean -bfd_check_format_matches (abfd, format, matching) - bfd *abfd; - bfd_format format; - char ***matching; -{ - const bfd_target * const *target, *save_targ, *right_targ; - char **matching_vector = NULL; - int match_count; - - if (!bfd_read_p (abfd) || - ((int)(abfd->format) < (int)bfd_unknown) || - ((int)(abfd->format) >= (int)bfd_type_end)) { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (abfd->format != bfd_unknown) - return (abfd->format == format)? true: false; - - - /* Since the target type was defaulted, check them - all in the hope that one will be uniquely recognized. */ - - save_targ = abfd->xvec; - match_count = 0; - if (matching) - { - matching_vector = - (char **) malloc (sizeof (char *) * - (_bfd_target_vector_entries + 1)); - if (!matching_vector) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - matching_vector[0] = NULL; - *matching = matching_vector; - } - right_targ = 0; - - - /* presume the answer is yes */ - abfd->format = format; - - /* If the target type was explicitly specified, just check that target. */ - - if (!abfd->target_defaulted) { - if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0) /* rewind! */ - return false; - right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (right_targ) { - abfd->xvec = right_targ; /* Set the target as returned */ - if (matching) - free (matching_vector); - return true; /* File position has moved, BTW */ - } - } - - for (target = bfd_target_vector; *target != NULL; target++) { - const bfd_target *temp; - - abfd->xvec = *target; /* Change BFD's target temporarily */ - if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0) - return false; - /* If _bfd_check_format neglects to set bfd_error, assume bfd_error_wrong_format. - We didn't used to even pay any attention to bfd_error, so I suspect - that some _bfd_check_format might have this problem. */ - bfd_set_error (bfd_error_wrong_format); - temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (temp) { /* This format checks out as ok! */ - right_targ = temp; - if (matching) - { - matching_vector[match_count] = temp->name; - matching_vector[match_count + 1] = NULL; - } - match_count++; - /* If this is the default target, accept it, even if other targets - might match. People who want those other targets have to set - the GNUTARGET variable. */ - if (temp == bfd_default_vector[0]) - { - if (matching) - { - matching_vector[0] = temp->name; - matching_vector[1] = NULL; - } - match_count = 1; - break; - } -#ifdef GNU960 - /* Big- and little-endian b.out archives look the same, but it doesn't - * matter: there is no difference in their headers, and member file byte - * orders will (I hope) be handled appropriately by bfd. Ditto for big - * and little coff archives. And the 4 coff/b.out object formats are - * unambiguous. So accept the first match we find. - */ - break; -#endif - } else if (bfd_get_error () != bfd_error_wrong_format) { - abfd->xvec = save_targ; - abfd->format = bfd_unknown; - if (matching && bfd_get_error () != bfd_error_file_ambiguously_recognized) - free (matching_vector); - return false; - } - } - - if (match_count == 1) { - abfd->xvec = right_targ; /* Change BFD's target permanently */ - if (matching) - free (matching_vector); - return true; /* File position has moved, BTW */ - } - - abfd->xvec = save_targ; /* Restore original target type */ - abfd->format = bfd_unknown; /* Restore original format */ - if (match_count == 0) - { - bfd_set_error (bfd_error_file_not_recognized); - if (matching) - free (matching_vector); - } - else - bfd_set_error (bfd_error_file_ambiguously_recognized); - return false; -} - -/* -FUNCTION - bfd_set_format - -SYNOPSIS - boolean bfd_set_format(bfd *abfd, bfd_format format); - -DESCRIPTION - This function sets the file format of the BFD @var{abfd} to the - format @var{format}. If the target set in the BFD does not - support the format requested, the format is invalid, or the BFD - is not open for writing, then an error occurs. - -*/ - -boolean -bfd_set_format (abfd, format) - bfd *abfd; - bfd_format format; -{ - - if (bfd_read_p (abfd) || - ((int)abfd->format < (int)bfd_unknown) || - ((int)abfd->format >= (int)bfd_type_end)) { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - if (abfd->format != bfd_unknown) - return (abfd->format == format) ? true:false; - - /* presume the answer is yes */ - abfd->format = format; - - if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) { - abfd->format = bfd_unknown; - return false; - } - - return true; -} - - -/* -FUNCTION - bfd_format_string - -SYNOPSIS - CONST char *bfd_format_string(bfd_format format); - -DESCRIPTION - Return a pointer to a const string - <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>, - depending upon the value of @var{format}. -*/ - -CONST char * -bfd_format_string (format) - bfd_format format; -{ - if (((int)format <(int) bfd_unknown) - || ((int)format >=(int) bfd_type_end)) - return "invalid"; - - switch (format) { - case bfd_object: - return "object"; /* linker/assember/compiler output */ - case bfd_archive: - return "archive"; /* object archive file */ - case bfd_core: - return "core"; /* core dump */ - default: - return "unknown"; - } -} diff --git a/gnu/usr.bin/gdb/bfd/freebsd386.c b/gnu/usr.bin/gdb/bfd/freebsd386.c deleted file mode 100644 index 3b2633cf..0000000 --- a/gnu/usr.bin/gdb/bfd/freebsd386.c +++ /dev/null @@ -1,113 +0,0 @@ -/* BFD back-end for i386 a.out binaries under BSD. - Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This data should be correct for the format used under all the various - BSD ports for 386 machines. */ - -#define BYTES_IN_WORD 4 -#define ARCH 32 - -/* ZMAGIC files never have the header in the text. */ -#define N_HEADER_IN_TEXT(x) 0 - -/* ZMAGIC files start at address 0. This does not apply to QMAGIC. */ -#define TEXT_START_ADDR 0 - -#if 0 -#define PAGE_SIZE 4096 -#endif -#define SEGMENT_SIZE PAGE_SIZE - -#define DEFAULT_ARCH bfd_arch_i386 -#define MACHTYPE_OK(mtype) ((mtype) == M_386 || (mtype) == M_386_NETBSD || (mtype) == M_UNKNOWN) - -#define MY(OP) CAT(freebsd386_,OP) -#define TARGETNAME "a.out-freebsd-386" - -#define N_MAGIC(ex) \ - ((ex).a_info & 0xffff) -#define N_MACHTYPE(ex) \ - ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \ - ((ex).a_info >> 16) & 0x03ff ) -#define N_FLAGS(ex) \ - ( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \ - ((ex).a_info >> 26) & 0x3f ) -#define N_SET_INFO(ex,mag,mid,flag) \ - ( (ex).a_info = (((flag) & 0x3f) <<26) | (((mid) & 0x03ff) << 16) | \ - ((mag) & 0xffff) ) - -#define N_GETMAGIC_NET(ex) \ - (ntohl((ex).a_info) & 0xffff) -#define N_GETMID_NET(ex) \ - ((ntohl((ex).a_info) >> 16) & 0x03ff) -#define N_GETFLAG_NET(ex) \ - ((ntohl((ex).a_info) >> 26) & 0x3f) -#define N_SETMAGIC_NET(ex,mag,mid,flag) \ - ( (ex).a_info = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \ - (((mag)&0xffff)) ) ) - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" - -#define N_ALIGN(ex,x) \ - (N_MAGIC(ex) == ZMAGIC || N_MAGIC(ex) == QMAGIC || \ - N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \ - ((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1) : (x)) - -/* Valid magic number check. */ -#define N_BADMAG(ex) \ - (N_MAGIC(ex) != OMAGIC && N_MAGIC(ex) != NMAGIC && \ - N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC && \ - N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \ - N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC) - -/* Address of the bottom of the text segment. */ -#define N_TXTADDR(ex) \ - ((N_MAGIC(ex) == OMAGIC || N_MAGIC(ex) == NMAGIC || \ - N_MAGIC(ex) == ZMAGIC) ? 0 : PAGE_SIZE) - -/* Address of the bottom of the data segment. */ -#define N_DATADDR(ex) \ - N_ALIGN(ex, N_TXTADDR(ex) + (ex).a_text) - -/* Text segment offset. */ -#define N_TXTOFF(ex) \ - (N_MAGIC(ex) == ZMAGIC ? PAGE_SIZE : (N_MAGIC(ex) == QMAGIC || \ - N_GETMAGIC_NET(ex) == ZMAGIC) ? 0 : EXEC_BYTES_SIZE) - -/* Data segment offset. */ -#define N_DATOFF(ex) \ - N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text) - -/* Relocation table offset. */ -#define N_RELOFF(ex) \ - N_ALIGN(ex, N_DATOFF(ex) + (ex).a_data) - -/* Symbol table offset. */ -#define N_SYMOFF(ex) \ - (N_RELOFF(ex) + (ex).a_trsize + (ex).a_drsize) - -/* String table offset. */ -#define N_STROFF(ex) (N_SYMOFF(ex) + (ex).a_syms) - -#define NO_SWAP_MAGIC /* magic number already in correct endian format */ - -#include "aout-target.h" diff --git a/gnu/usr.bin/gdb/bfd/genlink.h b/gnu/usr.bin/gdb/bfd/genlink.h deleted file mode 100644 index 06f6bfc..0000000 --- a/gnu/usr.bin/gdb/bfd/genlink.h +++ /dev/null @@ -1,106 +0,0 @@ -/* genlink.h -- interface to the BFD generic linker - Copyright 1993, 1994 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef GENLINK_H -#define GENLINK_H - -/* This header file is internal to BFD. It describes the internal - structures and functions used by the BFD generic linker, in case - any of the more specific linkers want to use or call them. Note - that some functions, such as _bfd_generic_link_hash_table_create, - are declared in libbfd.h, because they are expected to be widely - used. The functions and structures in this file will probably only - be used by a few files besides linker.c itself. In fact, this file - is not particularly complete; I have only put in the interfaces I - actually needed. */ - -/* The generic linker uses a hash table which is a derived class of - the standard linker hash table, just as the other backend specific - linkers do. Do not confuse the generic linker hash table with the - standard BFD linker hash table it is built upon. */ - -/* Generic linker hash table entries. */ - -struct generic_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Whether this symbol has been written out. */ - boolean written; - /* Symbol from input BFD. */ - asymbol *sym; -}; - -/* Generic linker hash table. */ - -struct generic_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in an generic link hash table. */ - -#define _bfd_generic_link_hash_lookup(table, string, create, copy, follow) \ - ((struct generic_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an generic link hash table. */ - -#define _bfd_generic_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the generic link hash table from the info structure. This is - just a cast. */ - -#define _bfd_generic_hash_table(p) \ - ((struct generic_link_hash_table *) ((p)->hash)) - -/* The generic linker reads in the asymbol structures for an input BFD - and keeps them in the outsymbol and symcount fields. */ - -#define _bfd_generic_link_get_symbols(abfd) ((abfd)->outsymbols) -#define _bfd_generic_link_get_symcount(abfd) ((abfd)->symcount) - -/* Add the symbols of input_bfd to the symbols being built for - output_bfd. */ -extern boolean _bfd_generic_link_output_symbols - PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *, - size_t *psymalloc)); - -/* This structure is used to pass information to - _bfd_generic_link_write_global_symbol, which may be called via - _bfd_generic_link_hash_traverse. */ - -struct generic_write_global_symbol_info -{ - struct bfd_link_info *info; - bfd *output_bfd; - size_t *psymalloc; -}; - -/* Write out a single global symbol. This is expected to be called - via _bfd_generic_link_hash_traverse. The second argument must - actually be a struct generic_write_global_symbol_info *. */ -extern boolean _bfd_generic_link_write_global_symbol - PARAMS ((struct generic_link_hash_entry *, PTR)); - -#endif diff --git a/gnu/usr.bin/gdb/bfd/hash.c b/gnu/usr.bin/gdb/bfd/hash.c deleted file mode 100644 index 28d364c..0000000 --- a/gnu/usr.bin/gdb/bfd/hash.c +++ /dev/null @@ -1,470 +0,0 @@ -/* hash.c -- hash table routines for BFD - Copyright (C) 1993, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain <sac@cygnus.com> - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -/* -SECTION - Hash Tables - -@cindex Hash tables - BFD provides a simple set of hash table functions. Routines - are provided to initialize a hash table, to free a hash table, - to look up a string in a hash table and optionally create an - entry for it, and to traverse a hash table. There is - currently no routine to delete an string from a hash table. - - The basic hash table does not permit any data to be stored - with a string. However, a hash table is designed to present a - base class from which other types of hash tables may be - derived. These derived types may store additional information - with the string. Hash tables were implemented in this way, - rather than simply providing a data pointer in a hash table - entry, because they were designed for use by the linker back - ends. The linker may create thousands of hash table entries, - and the overhead of allocating private data and storing and - following pointers becomes noticeable. - - The basic hash table code is in <<hash.c>>. - -@menu -@* Creating and Freeing a Hash Table:: -@* Looking Up or Entering a String:: -@* Traversing a Hash Table:: -@* Deriving a New Hash Table Type:: -@end menu - -INODE -Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables -SUBSECTION - Creating and freeing a hash table - -@findex bfd_hash_table_init -@findex bfd_hash_table_init_n - To create a hash table, create an instance of a <<struct - bfd_hash_table>> (defined in <<bfd.h>>) and call - <<bfd_hash_table_init>> (if you know approximately how many - entries you will need, the function <<bfd_hash_table_init_n>>, - which takes a @var{size} argument, may be used). - <<bfd_hash_table_init>> returns <<false>> if some sort of - error occurs. - -@findex bfd_hash_newfunc - The function <<bfd_hash_table_init>> take as an argument a - function to use to create new entries. For a basic hash - table, use the function <<bfd_hash_newfunc>>. @xref{Deriving - a New Hash Table Type} for why you would want to use a - different value for this argument. - -@findex bfd_hash_allocate - <<bfd_hash_table_init>> will create an obstack which will be - used to allocate new entries. You may allocate memory on this - obstack using <<bfd_hash_allocate>>. - -@findex bfd_hash_table_free - Use <<bfd_hash_table_free>> to free up all the memory that has - been allocated for a hash table. This will not free up the - <<struct bfd_hash_table>> itself, which you must provide. - -INODE -Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables -SUBSECTION - Looking up or entering a string - -@findex bfd_hash_lookup - The function <<bfd_hash_lookup>> is used both to look up a - string in the hash table and to create a new entry. - - If the @var{create} argument is <<false>>, <<bfd_hash_lookup>> - will look up a string. If the string is found, it will - returns a pointer to a <<struct bfd_hash_entry>>. If the - string is not found in the table <<bfd_hash_lookup>> will - return <<NULL>>. You should not modify any of the fields in - the returns <<struct bfd_hash_entry>>. - - If the @var{create} argument is <<true>>, the string will be - entered into the hash table if it is not already there. - Either way a pointer to a <<struct bfd_hash_entry>> will be - returned, either to the existing structure or to a newly - created one. In this case, a <<NULL>> return means that an - error occurred. - - If the @var{create} argument is <<true>>, and a new entry is - created, the @var{copy} argument is used to decide whether to - copy the string onto the hash table obstack or not. If - @var{copy} is passed as <<false>>, you must be careful not to - deallocate or modify the string as long as the hash table - exists. - -INODE -Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables -SUBSECTION - Traversing a hash table - -@findex bfd_hash_traverse - The function <<bfd_hash_traverse>> may be used to traverse a - hash table, calling a function on each element. The traversal - is done in a random order. - - <<bfd_hash_traverse>> takes as arguments a function and a - generic <<void *>> pointer. The function is called with a - hash table entry (a <<struct bfd_hash_entry *>>) and the - generic pointer passed to <<bfd_hash_traverse>>. The function - must return a <<boolean>> value, which indicates whether to - continue traversing the hash table. If the function returns - <<false>>, <<bfd_hash_traverse>> will stop the traversal and - return immediately. - -INODE -Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables -SUBSECTION - Deriving a new hash table type - - Many uses of hash tables want to store additional information - which each entry in the hash table. Some also find it - convenient to store additional information with the hash table - itself. This may be done using a derived hash table. - - Since C is not an object oriented language, creating a derived - hash table requires sticking together some boilerplate - routines with a few differences specific to the type of hash - table you want to create. - - An example of a derived hash table is the linker hash table. - The structures for this are defined in <<bfdlink.h>>. The - functions are in <<linker.c>>. - - You may also derive a hash table from an already derived hash - table. For example, the a.out linker backend code uses a hash - table derived from the linker hash table. - -@menu -@* Define the Derived Structures:: -@* Write the Derived Creation Routine:: -@* Write Other Derived Routines:: -@end menu - -INODE -Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type -SUBSUBSECTION - Define the derived structures - - You must define a structure for an entry in the hash table, - and a structure for the hash table itself. - - The first field in the structure for an entry in the hash - table must be of the type used for an entry in the hash table - you are deriving from. If you are deriving from a basic hash - table this is <<struct bfd_hash_entry>>, which is defined in - <<bfd.h>>. The first field in the structure for the hash - table itself must be of the type of the hash table you are - deriving from itself. If you are deriving from a basic hash - table, this is <<struct bfd_hash_table>>. - - For example, the linker hash table defines <<struct - bfd_link_hash_entry>> (in <<bfdlink.h>>). The first field, - <<root>>, is of type <<struct bfd_hash_entry>>. Similarly, - the first field in <<struct bfd_link_hash_table>>, <<table>>, - is of type <<struct bfd_hash_table>>. - -INODE -Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type -SUBSUBSECTION - Write the derived creation routine - - You must write a routine which will create and initialize an - entry in the hash table. This routine is passed as the - function argument to <<bfd_hash_table_init>>. - - In order to permit other hash tables to be derived from the - hash table you are creating, this routine must be written in a - standard way. - - The first argument to the creation routine is a pointer to a - hash table entry. This may be <<NULL>>, in which case the - routine should allocate the right amount of space. Otherwise - the space has already been allocated by a hash table type - derived from this one. - - After allocating space, the creation routine must call the - creation routine of the hash table type it is derived from, - passing in a pointer to the space it just allocated. This - will initialize any fields used by the base hash table. - - Finally the creation routine must initialize any local fields - for the new hash table type. - - Here is a boilerplate example of a creation routine. - @var{function_name} is the name of the routine. - @var{entry_type} is the type of an entry in the hash table you - are creating. @var{base_newfunc} is the name of the creation - routine of the hash table type your hash table is derived - from. - -EXAMPLE - -.struct bfd_hash_entry * -.@var{function_name} (entry, table, string) -. struct bfd_hash_entry *entry; -. struct bfd_hash_table *table; -. const char *string; -.{ -. struct @var{entry_type} *ret = (@var{entry_type} *) entry; -. -. {* Allocate the structure if it has not already been allocated by a -. derived class. *} -. if (ret == (@var{entry_type} *) NULL) -. { -. ret = ((@var{entry_type} *) -. bfd_hash_allocate (table, sizeof (@var{entry_type}))); -. if (ret == (@var{entry_type} *) NULL) -. return NULL; -. } -. -. {* Call the allocation method of the base class. *} -. ret = ((@var{entry_type} *) -. @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); -. -. {* Initialize the local fields here. *} -. -. return (struct bfd_hash_entry *) ret; -.} - -DESCRIPTION - The creation routine for the linker hash table, which is in - <<linker.c>>, looks just like this example. - @var{function_name} is <<_bfd_link_hash_newfunc>>. - @var{entry_type} is <<struct bfd_link_hash_entry>>. - @var{base_newfunc} is <<bfd_hash_newfunc>>, the creation - routine for a basic hash table. - - <<_bfd_link_hash_newfunc>> also initializes the local fields - in a linker hash table entry: <<type>>, <<written>> and - <<next>>. - -INODE -Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type -SUBSUBSECTION - Write other derived routines - - You will want to write other routines for your new hash table, - as well. - - You will want an initialization routine which calls the - initialization routine of the hash table you are deriving from - and initializes any other local fields. For the linker hash - table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>. - - You will want a lookup routine which calls the lookup routine - of the hash table you are deriving from and casts the result. - The linker hash table uses <<bfd_link_hash_lookup>> in - <<linker.c>> (this actually takes an additional argument which - it uses to decide how to return the looked up value). - - You may want a traversal routine. This should just call the - traversal routine of the hash table you are deriving from with - appropriate casts. The linker hash table uses - <<bfd_link_hash_traverse>> in <<linker.c>>. - - These routines may simply be defined as macros. For example, - the a.out backend linker hash table, which is derived from the - linker hash table, uses macros for the lookup and traversal - routines. These are <<aout_link_hash_lookup>> and - <<aout_link_hash_traverse>> in aoutx.h. -*/ - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* The default number of entries to use when creating a hash table. */ -#define DEFAULT_SIZE (4051) - -/* Create a new hash table, given a number of entries. */ - -boolean -bfd_hash_table_init_n (table, newfunc, size) - struct bfd_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); - unsigned int size; -{ - unsigned int alloc; - - alloc = size * sizeof (struct bfd_hash_entry *); - if (!obstack_begin (&table->memory, alloc)) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - table->table = ((struct bfd_hash_entry **) - obstack_alloc (&table->memory, alloc)); - if (!table->table) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memset ((PTR) table->table, 0, alloc); - table->size = size; - table->newfunc = newfunc; - return true; -} - -/* Create a new hash table with the default number of entries. */ - -boolean -bfd_hash_table_init (table, newfunc) - struct bfd_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE); -} - -/* Free a hash table. */ - -void -bfd_hash_table_free (table) - struct bfd_hash_table *table; -{ - obstack_free (&table->memory, (PTR) NULL); -} - -/* Look up a string in a hash table. */ - -struct bfd_hash_entry * -bfd_hash_lookup (table, string, create, copy) - struct bfd_hash_table *table; - const char *string; - boolean create; - boolean copy; -{ - register const unsigned char *s; - register unsigned long hash; - register unsigned int c; - struct bfd_hash_entry *hashp; - unsigned int len; - unsigned int index; - - hash = 0; - len = 0; - s = (const unsigned char *) string; - while ((c = *s++) != '\0') - { - hash += c + (c << 17); - hash ^= hash >> 2; - ++len; - } - hash += len + (len << 17); - hash ^= hash >> 2; - - index = hash % table->size; - for (hashp = table->table[index]; - hashp != (struct bfd_hash_entry *) NULL; - hashp = hashp->next) - { - if (hashp->hash == hash - && strcmp (hashp->string, string) == 0) - return hashp; - } - - if (! create) - return (struct bfd_hash_entry *) NULL; - - hashp = (*table->newfunc) ((struct bfd_hash_entry *) NULL, table, string); - if (hashp == (struct bfd_hash_entry *) NULL) - return (struct bfd_hash_entry *) NULL; - if (copy) - { - char *new; - - new = (char *) obstack_alloc (&table->memory, len + 1); - if (!new) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_hash_entry *) NULL; - } - strcpy (new, string); - string = new; - } - hashp->string = string; - hashp->hash = hash; - hashp->next = table->table[index]; - table->table[index] = hashp; - - return hashp; -} - -/* Base method for creating a new hash table entry. */ - -/*ARGSUSED*/ -struct bfd_hash_entry * -bfd_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - if (entry == (struct bfd_hash_entry *) NULL) - entry = ((struct bfd_hash_entry *) - bfd_hash_allocate (table, sizeof (struct bfd_hash_entry))); - return entry; -} - -/* Allocate space in a hash table. */ - -PTR -bfd_hash_allocate (table, size) - struct bfd_hash_table *table; - unsigned int size; -{ - PTR ret; - - ret = obstack_alloc (&table->memory, size); - if (ret == NULL && size != 0) - bfd_set_error (bfd_error_no_memory); - return ret; -} - -/* Traverse a hash table. */ - -void -bfd_hash_traverse (table, func, info) - struct bfd_hash_table *table; - boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR)); - PTR info; -{ - unsigned int i; - - for (i = 0; i < table->size; i++) - { - struct bfd_hash_entry *p; - - for (p = table->table[i]; p != NULL; p = p->next) - { - if (! (*func) (p, info)) - return; - } - } -} diff --git a/gnu/usr.bin/gdb/bfd/i386aout.c b/gnu/usr.bin/gdb/bfd/i386aout.c deleted file mode 100644 index 4af12ba..0000000 --- a/gnu/usr.bin/gdb/bfd/i386aout.c +++ /dev/null @@ -1,68 +0,0 @@ -/* BFD back-end for i386 a.out binaries. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* The only 386 aout system we have here is GO32 from DJ. - These numbers make BFD work with that. If your aout 386 system - doesn't work with these, we'll have to split them into different - files. Send me (sac@cygnus.com) the runes to make it work on your - system, and I'll stick it in for the next release. */ - -#define N_HEADER_IN_TEXT(x) 0 -#define BYTES_IN_WORD 4 - -#define N_TXTOFF(x) 0x20 -#define N_TXTADDR(x) (N_MAGIC(x)==ZMAGIC ? 0x1020 : 0) - -#define N_TXTSIZE(x) ((x).a_text) -#if 0 -#define N_DATADDR(x) (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+(x).a_text) : (SEGMENT_SIZE + ((0x1020+(x).a_text-1) & ~(SEGMENT_SIZE-1)))) -#define NOSUBEXECB - -#define PAGE_SIZE 4096 -#endif -#define SEGMENT_SIZE 0x400000 -#define DEFAULT_ARCH bfd_arch_i386 - -#define MY(OP) CAT(i386aout_,OP) -#define TARGETNAME "a.out-i386" -#define NO_WRITE_HEADER_KLUDGE 1 - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" -static boolean MY(set_sizes)(); -#define MY_backend_data &MY(backend_data) -static CONST struct aout_backend_data MY(backend_data) = { - 0, /* zmagic contiguous */ - 1, /* text incl header */ - 0, /* exec_hdr_flags */ - 0, /* text vma? */ - MY(set_sizes), - 1, /* exec header not counted */ - 0, /* add_dynamic_symbols */ - 0, /* add_one_symbol */ - 0, /* link_dynamic_object */ - 0, /* write_dynamic_symbol */ - 0, /* check_dynamic_reloc */ - 0 /* finish_dynamic_link */ -}; - -#include "aout-target.h" diff --git a/gnu/usr.bin/gdb/bfd/i386freebsd.h b/gnu/usr.bin/gdb/bfd/i386freebsd.h new file mode 100644 index 0000000..af011311 --- /dev/null +++ b/gnu/usr.bin/gdb/bfd/i386freebsd.h @@ -0,0 +1,23 @@ +/* Intel 386 running any FreeBSD Unix */ + +#include <machine/param.h> +#include <machine/vmparam.h> + +#define NBPG PAGE_SIZE +#define HOST_PAGE_SIZE NBPG +#define HOST_MACHINE_ARCH bfd_arch_i386 +#define HOST_TEXT_START_ADDR USRTEXT + +/* Jolitz suggested defining HOST_STACK_END_ADDR to + (u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on + both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */ + +/* This seems to be the right thing for FreeBSD and BSDI */ +#define HOST_STACK_END_ADDR USRSTACK + +/* BSDI defines this too (PST) */ +#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr) + +#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \ + ((core_bfd)->tdata.trad_core_data->u.u_sig) +#define u_comm u_kproc.kp_proc.p_comm diff --git a/gnu/usr.bin/gdb/bfd/init.c b/gnu/usr.bin/gdb/bfd/init.c deleted file mode 100644 index 3b93262..0000000 --- a/gnu/usr.bin/gdb/bfd/init.c +++ /dev/null @@ -1,79 +0,0 @@ -/* bfd initialization stuff - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -extern void bfd_section_init (); - -static boolean initialized = false; - -/* -SECTION - Initialization - - These are the functions that handle initializing a BFD. -*/ - -/* -FUNCTION - bfd_init - -SYNOPSIS - void bfd_init(void); - -DESCRIPTION - This routine must be called before any other BFD function to - initialize magical internal data structures. -*/ - -void -bfd_init () -{ - if (initialized == false) { - initialized = true; - - bfd_arch_init(); - } -} - - -/* -INTERNAL_FUNCTION - bfd_check_init - -SYNOPSIS - void bfd_check_init(void); - -DESCRIPTION - This routine is called before any other BFD function using - initialized data. It ensures that the structures have - been initialized. Soon this function will go away, and the BFD - library will assume that <<bfd_init>> has been called. -*/ - -void -bfd_check_init () -{ - if (initialized == false) { - bfd_init(); - } -} diff --git a/gnu/usr.bin/gdb/bfd/libaout.h b/gnu/usr.bin/gdb/bfd/libaout.h deleted file mode 100644 index 7a66f65..0000000 --- a/gnu/usr.bin/gdb/bfd/libaout.h +++ /dev/null @@ -1,578 +0,0 @@ -/* BFD back-end data structures for a.out (and similar) files. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef LIBAOUT_H -#define LIBAOUT_H - -/* We try to encapsulate the differences in the various a.out file - variants in a few routines, and otherwise share large masses of code. - This means we only have to fix bugs in one place, most of the time. */ - -#include "bfdlink.h" - -/* Parameterize the a.out code based on whether it is being built - for a 32-bit architecture or a 64-bit architecture. */ -#if ARCH_SIZE==64 -#define GET_WORD bfd_h_get_64 -#define GET_SWORD bfd_h_get_signed_64 -#define PUT_WORD bfd_h_put_64 -#ifndef NAME -#define NAME(x,y) CAT3(x,_64_,y) -#endif -#define JNAME(x) CAT(x,_64) -#define BYTES_IN_WORD 8 -#else /* ARCH_SIZE == 32 */ -#define GET_WORD bfd_h_get_32 -#define GET_SWORD bfd_h_get_signed_32 -#define PUT_WORD bfd_h_put_32 -#ifndef NAME -#define NAME(x,y) CAT3(x,_32_,y) -#endif -#define JNAME(x) CAT(x,_32) -#define BYTES_IN_WORD 4 -#endif /* ARCH_SIZE==32 */ - -/* Declare at file level, since used in parameter lists, which have - weird scope. */ -struct external_exec; -struct external_nlist; -struct reloc_ext_external; -struct reloc_std_external; - -/* a.out backend linker hash table entries. */ - -struct aout_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Whether this symbol has been written out. */ - boolean written; - /* Symbol index in output file. */ - int indx; -}; - -/* a.out backend linker hash table. */ - -struct aout_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Look up an entry in an a.out link hash table. */ - -#define aout_link_hash_lookup(table, string, create, copy, follow) \ - ((struct aout_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow))) - -/* Traverse an a.out link hash table. */ - -#define aout_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the a.out link hash table from the info structure. This is - just a cast. */ - -#define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash)) - -/* Back-end information for various a.out targets. */ -struct aout_backend_data -{ - /* Are ZMAGIC files mapped contiguously? If so, the text section may - need more padding, if the segment size (granularity for memory access - control) is larger than the page size. */ - unsigned char zmagic_mapped_contiguous; - /* If this flag is set, ZMAGIC/NMAGIC file headers get mapped in with the - text section, which starts immediately after the file header. - If not, the text section starts on the next page. */ - unsigned char text_includes_header; - - /* The value to pass to N_SET_FLAGS. */ - unsigned char exec_hdr_flags; - - /* If the text section VMA isn't specified, and we need an absolute - address, use this as the default. If we're producing a relocatable - file, zero is always used. */ - /* ?? Perhaps a callback would be a better choice? Will this do anything - reasonable for a format that handles multiple CPUs with different - load addresses for each? */ - bfd_vma default_text_vma; - - /* Callback for setting the page and segment sizes, if they can't be - trivially determined from the architecture. */ - boolean (*set_sizes) PARAMS ((bfd *)); - - /* zmagic files only. For go32, the length of the exec header contributes - to the size of the text section in the file for alignment purposes but - does *not* get counted in the length of the text section. */ - unsigned char exec_header_not_counted; - - /* Callback from the add symbols phase of the linker code to handle - a dynamic object. */ - boolean (*add_dynamic_symbols) PARAMS ((bfd *, struct bfd_link_info *)); - - /* Callback from the add symbols phase of the linker code to handle - adding a single symbol to the global linker hash table. */ - boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *, - const char *, flagword, asection *, - bfd_vma, const char *, boolean, - boolean, - struct bfd_link_hash_entry **)); - - /* Called to handle linking a dynamic object. */ - boolean (*link_dynamic_object) PARAMS ((struct bfd_link_info *, bfd *)); - - /* Called for each global symbol being written out by the linker. - This should write out the dynamic symbol information. */ - boolean (*write_dynamic_symbol) PARAMS ((bfd *, struct bfd_link_info *, - struct aout_link_hash_entry *)); - - /* This callback is called by the linker for each reloc against an - external symbol. RELOC is a pointer to the unswapped reloc. If - *SKIP is set to true, the reloc will be skipped. */ - boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *info, - bfd *input_bfd, - asection *input_section, - struct aout_link_hash_entry *h, - PTR reloc, boolean *skip)); - - /* Called at the end of a link to finish up any dynamic linking - information. */ - boolean (*finish_dynamic_link) PARAMS ((bfd *, struct bfd_link_info *)); -}; -#define aout_backend_info(abfd) \ - ((CONST struct aout_backend_data *)((abfd)->xvec->backend_data)) - -/* This is the layout in memory of a "struct exec" while we process it. - All 'lengths' are given as a number of bytes. - All 'alignments' are for relinkable files only; an alignment of - 'n' indicates the corresponding segment must begin at an - address that is a multiple of (2**n). */ - -struct internal_exec -{ - long a_info; /* Magic number and flags, packed */ - bfd_vma a_text; /* length of text, in bytes */ - bfd_vma a_data; /* length of data, in bytes */ - bfd_vma a_bss; /* length of uninitialized data area in mem */ - bfd_vma a_syms; /* length of symbol table data in file */ - bfd_vma a_entry; /* start address */ - bfd_vma a_trsize; /* length of text's relocation info, in bytes */ - bfd_vma a_drsize; /* length of data's relocation info, in bytes */ - /* Added for i960 */ - bfd_vma a_tload; /* Text runtime load address */ - bfd_vma a_dload; /* Data runtime load address */ - unsigned char a_talign; /* Alignment of text segment */ - unsigned char a_dalign; /* Alignment of data segment */ - unsigned char a_balign; /* Alignment of bss segment */ - char a_relaxable; /* Enough info for linker relax */ -}; - -/* Magic number is written -< MSB > -3130292827262524232221201918171615141312111009080706050403020100 -< FLAGS >< MACHINE TYPE >< MAGIC NUMBER > -*/ -/* Magic number for NetBSD is -<MSB > -3130292827262524232221201918171615141312111009080706050403020100 -< FLAGS >< >< MAGIC NUMBER > -*/ - -enum machine_type { - M_UNKNOWN = 0, - M_68010 = 1, - M_68020 = 2, - M_SPARC = 3, - /* skip a bunch so we don't run into any of suns numbers */ - /* make these up for the ns32k*/ - M_NS32032 = (64), /* ns32032 running ? */ - M_NS32532 = (64 + 5), /* ns32532 running mach */ - - M_386 = 100, - M_29K = 101, /* AMD 29000 */ - M_386_DYNIX = 102, /* Sequent running dynix */ - M_386_NETBSD = 134, /* NetBSD/386 binary */ - M_532_NETBSD = 137, /* MetBSD/523 binary */ - M_MIPS1 = 151, /* MIPS R2000/R3000 binary */ - M_MIPS2 = 152, /* MIPS R4000/R6000 binary */ - M_HP200 = 200, /* HP 200 (68010) BSD binary */ - M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */ - M_HPUX = (0x20c % 256)/* HP 200/300 HPUX binary */ -}; - -#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000) - -#ifndef N_MAGIC -# define N_MAGIC(exec) ((exec).a_info & 0xffff) -#endif - -#ifndef N_MACHTYPE -# define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff)) -#endif - -#ifndef N_FLAGS -# define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff) -#endif - -#ifndef N_SET_INFO -# define N_SET_INFO(exec, magic, type, flags) \ -((exec).a_info = ((magic) & 0xffff) \ - | (((int)(type) & 0xff) << 16) \ - | (((flags) & 0xff) << 24)) -#endif - -#ifndef N_SET_DYNAMIC -# define N_SET_DYNAMIC(exec, dynamic) \ -((exec).a_info = (dynamic) ? ((exec).a_info | 0x80000000) : \ -((exec).a_info & 0x7fffffff)) -#endif - -#ifndef N_SET_MAGIC -# define N_SET_MAGIC(exec, magic) \ -((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff))) -#endif - -#ifndef N_SET_MACHTYPE -# define N_SET_MACHTYPE(exec, machtype) \ -((exec).a_info = \ - ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16)) -#endif - -#ifndef N_SET_FLAGS -# define N_SET_FLAGS(exec, flags) \ -((exec).a_info = \ - ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24)) -#endif - -typedef struct aout_symbol { - asymbol symbol; - short desc; - char other; - unsigned char type; -} aout_symbol_type; - -/* The `tdata' struct for all a.out-like object file formats. - Various things depend on this struct being around any time an a.out - file is being handled. An example is dbxread.c in GDB. */ - -struct aoutdata { - struct internal_exec *hdr; /* exec file header */ - aout_symbol_type *symbols; /* symtab for input bfd */ - - /* For ease, we do this */ - asection *textsec; - asection *datasec; - asection *bsssec; - - /* We remember these offsets so that after check_file_format, we have - no dependencies on the particular format of the exec_hdr. */ - file_ptr sym_filepos; - file_ptr str_filepos; - - /* Size of a relocation entry in external form */ - unsigned reloc_entry_size; - - /* Size of a symbol table entry in external form */ - unsigned symbol_entry_size; - - /* Page size - needed for alignment of demand paged files. */ - unsigned long page_size; - - /* Segment size - needed for alignment of demand paged files. */ - unsigned long segment_size; - - /* Zmagic disk block size - need to align the start of the text - section in ZMAGIC binaries. Normally the same as page_size. */ - unsigned long zmagic_disk_block_size; - - unsigned exec_bytes_size; - unsigned vma_adjusted : 1; - - /* used when a bfd supports several highly similar formats */ - enum - { - default_format = 0, - /* Used on HP 9000/300 running HP/UX. See hp300hpux.c. */ - gnu_encap_format, - /* Used on Linux, 386BSD, etc. See include/aout/aout64.h. */ - q_magic_format - } subformat; - - enum - { - undecided_magic = 0, - z_magic, - o_magic, - n_magic - } magic; - - /* The external symbol information. */ - struct external_nlist *external_syms; - bfd_size_type external_sym_count; - char *external_strings; - bfd_size_type external_string_size; - struct aout_link_hash_entry **sym_hashes; - - /* A pointer for shared library information. */ - PTR dynamic_info; -}; - -struct aout_data_struct { - struct aoutdata a; - struct internal_exec e; -}; - -#define adata(bfd) ((bfd)->tdata.aout_data->a) -#define exec_hdr(bfd) (adata(bfd).hdr) -#define obj_aout_symbols(bfd) (adata(bfd).symbols) -#define obj_textsec(bfd) (adata(bfd).textsec) -#define obj_datasec(bfd) (adata(bfd).datasec) -#define obj_bsssec(bfd) (adata(bfd).bsssec) -#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos) -#define obj_str_filepos(bfd) (adata(bfd).str_filepos) -#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size) -#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size) -#define obj_aout_subformat(bfd) (adata(bfd).subformat) -#define obj_aout_external_syms(bfd) (adata(bfd).external_syms) -#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count) -#define obj_aout_external_strings(bfd) (adata(bfd).external_strings) -#define obj_aout_external_string_size(bfd) (adata(bfd).external_string_size) -#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes) -#define obj_aout_dynamic_info(bfd) (adata(bfd).dynamic_info) - -/* We take the address of the first element of an asymbol to ensure that the - macro is only ever applied to an asymbol */ -#define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd)) - -/* Information we keep for each a.out section. This is currently only - used by the a.out backend linker. */ - -struct aout_section_data_struct -{ - /* The unswapped relocation entries for this section. */ - PTR relocs; -}; - -#define aout_section_data(s) \ - ((struct aout_section_data_struct *) (s)->used_by_bfd) - -/* Prototype declarations for functions defined in aoutx.h */ - -boolean -NAME(aout,squirt_out_relocs) PARAMS ((bfd *abfd, asection *section)); - -boolean -NAME(aout,make_sections) PARAMS ((bfd *)); - -const bfd_target * -NAME(aout,some_aout_object_p) PARAMS ((bfd *abfd, - struct internal_exec *execp, - const bfd_target *(*callback)(bfd *))); - -boolean -NAME(aout,mkobject) PARAMS ((bfd *abfd)); - -enum machine_type -NAME(aout,machine_type) PARAMS ((enum bfd_architecture arch, - unsigned long machine, - boolean *unknown)); - -boolean -NAME(aout,set_arch_mach) PARAMS ((bfd *abfd, enum bfd_architecture arch, - unsigned long machine)); - -boolean -NAME(aout,new_section_hook) PARAMS ((bfd *abfd, asection *newsect)); - -boolean -NAME(aout,set_section_contents) PARAMS ((bfd *abfd, sec_ptr section, - PTR location, file_ptr offset, bfd_size_type count)); - -asymbol * -NAME(aout,make_empty_symbol) PARAMS ((bfd *abfd)); - -boolean -NAME(aout,translate_symbol_table) PARAMS ((bfd *, aout_symbol_type *, - struct external_nlist *, - bfd_size_type, char *, - bfd_size_type, - boolean dynamic)); - -boolean -NAME(aout,slurp_symbol_table) PARAMS ((bfd *abfd)); - -boolean -NAME(aout,write_syms) PARAMS ((bfd *abfd)); - -void -NAME(aout,reclaim_symbol_table) PARAMS ((bfd *abfd)); - -long -NAME(aout,get_symtab_upper_bound) PARAMS ((bfd *abfd)); - -long -NAME(aout,get_symtab) PARAMS ((bfd *abfd, asymbol **location)); - -void -NAME(aout,swap_ext_reloc_in) PARAMS ((bfd *, struct reloc_ext_external *, - arelent *, asymbol **)); -void -NAME(aout,swap_std_reloc_in) PARAMS ((bfd *, struct reloc_std_external *, - arelent *, asymbol **)); - -boolean -NAME(aout,slurp_reloc_table) PARAMS ((bfd *abfd, sec_ptr asect, - asymbol **symbols)); - -long -NAME(aout,canonicalize_reloc) PARAMS ((bfd *abfd, sec_ptr section, - arelent **relptr, asymbol **symbols)); - -long -NAME(aout,get_reloc_upper_bound) PARAMS ((bfd *abfd, sec_ptr asect)); - -void -NAME(aout,reclaim_reloc) PARAMS ((bfd *ignore_abfd, sec_ptr ignore)); - -alent * -NAME(aout,get_lineno) PARAMS ((bfd *ignore_abfd, asymbol *ignore_symbol)); - -void -NAME(aout,print_symbol) PARAMS ((bfd *ignore_abfd, PTR file, - asymbol *symbol, bfd_print_symbol_type how)); - -void -NAME(aout,get_symbol_info) PARAMS ((bfd *ignore_abfd, - asymbol *symbol, symbol_info *ret)); - -boolean -NAME(aout,find_nearest_line) PARAMS ((bfd *abfd, asection *section, - asymbol **symbols, bfd_vma offset, CONST char **filename_ptr, - CONST char **functionname_ptr, unsigned int *line_ptr)); - -int -NAME(aout,sizeof_headers) PARAMS ((bfd *abfd, boolean exec)); - -boolean -NAME(aout,adjust_sizes_and_vmas) PARAMS ((bfd *abfd, - bfd_size_type *text_size, file_ptr *text_end)); - -void -NAME(aout,swap_exec_header_in) PARAMS ((bfd *abfd, - struct external_exec *raw_bytes, struct internal_exec *execp)); - -void -NAME(aout,swap_exec_header_out) PARAMS ((bfd *abfd, - struct internal_exec *execp, struct external_exec *raw_bytes)); - -struct bfd_hash_entry * -NAME(aout,link_hash_newfunc) - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); - -boolean -NAME(aout,link_hash_table_init) - PARAMS ((struct aout_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -struct bfd_link_hash_table * -NAME(aout,link_hash_table_create) PARAMS ((bfd *)); - -boolean -NAME(aout,link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *)); - -boolean -NAME(aout,final_link) PARAMS ((bfd *, struct bfd_link_info *, - void (*) (bfd *, file_ptr *, file_ptr *, - file_ptr *))); - -boolean -NAME(aout,bfd_free_cached_info) PARAMS ((bfd *)); - -/* Prototypes for functions in stab-syms.c. */ - -CONST char * -aout_stab_name PARAMS ((int code)); - -/* A.out uses the generic versions of these routines... */ - -#define aout_32_get_section_contents _bfd_generic_get_section_contents - -#define aout_64_get_section_contents _bfd_generic_get_section_contents -#ifndef NO_WRITE_HEADER_KLUDGE -#define NO_WRITE_HEADER_KLUDGE 0 -#endif - -#ifndef aout_32_bfd_is_local_label -#define aout_32_bfd_is_local_label bfd_generic_is_local_label -#endif - -#ifndef WRITE_HEADERS -#define WRITE_HEADERS(abfd, execp) \ - { \ - bfd_size_type text_size; /* dummy vars */ \ - file_ptr text_end; \ - if (adata(abfd).magic == undecided_magic) \ - NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \ - \ - execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE; \ - execp->a_entry = bfd_get_start_address (abfd); \ - \ - execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ - obj_reloc_entry_size (abfd)); \ - NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ - \ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return false; \ - if (bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd) \ - != EXEC_BYTES_SIZE) \ - return false; \ - /* Now write out reloc info, followed by syms and strings */ \ - \ - if (bfd_get_outsymbols (abfd) != (asymbol **) NULL \ - && bfd_get_symcount (abfd) != 0) \ - { \ - if (bfd_seek (abfd, (file_ptr)(N_SYMOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (! NAME(aout,write_syms)(abfd)) return false; \ - \ - if (bfd_seek (abfd, (file_ptr)(N_TRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) \ - return false; \ - if (bfd_seek (abfd, (file_ptr)(N_DRELOFF(*execp)), SEEK_SET) \ - != 0) \ - return false; \ - \ - if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) \ - return false; \ - } \ - } -#endif - -#endif /* ! defined (LIBAOUT_H) */ diff --git a/gnu/usr.bin/gdb/bfd/libbfd.c b/gnu/usr.bin/gdb/bfd/libbfd.c deleted file mode 100644 index 031f08f..0000000 --- a/gnu/usr.bin/gdb/bfd/libbfd.c +++ /dev/null @@ -1,880 +0,0 @@ -/* Assorted BFD support routines, only used internally. - Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* -SECTION - Internal functions - -DESCRIPTION - These routines are used within BFD. - They are not intended for export, but are documented here for - completeness. -*/ - -/* A routine which is used in target vectors for unsupported - operations. */ - -/*ARGSUSED*/ -boolean -bfd_false (ignore) - bfd *ignore; -{ - bfd_set_error (bfd_error_invalid_operation); - return false; -} - -/* A routine which is used in target vectors for supported operations - which do not actually do anything. */ - -/*ARGSUSED*/ -boolean -bfd_true (ignore) - bfd *ignore; -{ - return true; -} - -/* A routine which is used in target vectors for unsupported - operations which return a pointer value. */ - -/*ARGSUSED*/ -PTR -bfd_nullvoidptr (ignore) - bfd *ignore; -{ - bfd_set_error (bfd_error_invalid_operation); - return NULL; -} - -/*ARGSUSED*/ -int -bfd_0 (ignore) - bfd *ignore; -{ - return 0; -} - -/*ARGSUSED*/ -unsigned int -bfd_0u (ignore) - bfd *ignore; -{ - return 0; -} - -/*ARGUSED*/ -long -bfd_0l (ignore) - bfd *ignore; -{ - return 0; -} - -/* A routine which is used in target vectors for unsupported - operations which return -1 on error. */ - -/*ARGSUSED*/ -long -_bfd_n1 (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return -1; -} - -/*ARGSUSED*/ -void -bfd_void (ignore) - bfd *ignore; -{ -} - -/*ARGSUSED*/ -boolean -_bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd) - bfd *ignore_core_bfd; - bfd *ignore_exec_bfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return false; -} - -/* Routine to handle core_file_failing_command entry point for targets - without core file support. */ - -/*ARGSUSED*/ -char * -_bfd_nocore_core_file_failing_command (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return (char *)NULL; -} - -/* Routine to handle core_file_failing_signal entry point for targets - without core file support. */ - -/*ARGSUSED*/ -int -_bfd_nocore_core_file_failing_signal (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_invalid_operation); - return 0; -} - -/*ARGSUSED*/ -const bfd_target * -_bfd_dummy_target (ignore_abfd) - bfd *ignore_abfd; -{ - bfd_set_error (bfd_error_wrong_format); - return 0; -} - - -#ifndef bfd_zmalloc -/* allocate and clear storage */ - -char * -bfd_zmalloc (size) - bfd_size_type size; -{ - char *ptr = (char *) malloc ((size_t) size); - - if (ptr && size) - memset(ptr, 0, (size_t) size); - - return ptr; -} -#endif /* bfd_zmalloc */ - -/* Some IO code */ - - -/* Note that archive entries don't have streams; they share their parent's. - This allows someone to play with the iostream behind BFD's back. - - Also, note that the origin pointer points to the beginning of a file's - contents (0 for non-archive elements). For archive entries this is the - first octet in the file, NOT the beginning of the archive header. */ - -static -int -real_read (where, a,b, file) - PTR where; - int a; - int b; - FILE *file; -{ - return fread(where, a,b,file); -} - -/* Return value is amount read (FIXME: how are errors and end of file dealt - with? We never call bfd_set_error, which is probably a mistake). */ - -bfd_size_type -bfd_read (ptr, size, nitems, abfd) - PTR ptr; - bfd_size_type size; - bfd_size_type nitems; - bfd *abfd; -{ - int nread; - nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX - if (nread > 0) - abfd->where += nread; -#endif - - /* Set bfd_error if we did not read as much data as we expected. - - If the read failed due to an error set the bfd_error_system_call, - else set bfd_error_file_truncated. - - A BFD backend may wish to override bfd_error_file_truncated to - provide something more useful (eg. no_symbols or wrong_format). */ - if (nread < (int)(size * nitems)) - { - if (ferror (bfd_cache_lookup (abfd))) - bfd_set_error (bfd_error_system_call); - else - bfd_set_error (bfd_error_file_truncated); - } - - return nread; -} - -bfd_size_type -bfd_write (ptr, size, nitems, abfd) - CONST PTR ptr; - bfd_size_type size; - bfd_size_type nitems; - bfd *abfd; -{ - int nwrote = fwrite (ptr, 1, (int) (size * nitems), bfd_cache_lookup (abfd)); -#ifdef FILE_OFFSET_IS_CHAR_INDEX - if (nwrote > 0) - abfd->where += nwrote; -#endif - if (nwrote != size * nitems) - { -#ifdef ENOSPC - if (nwrote >= 0) - errno = ENOSPC; -#endif - bfd_set_error (bfd_error_system_call); - } - return nwrote; -} - -/* -INTERNAL_FUNCTION - bfd_write_bigendian_4byte_int - -SYNOPSIS - void bfd_write_bigendian_4byte_int(bfd *abfd, int i); - -DESCRIPTION - Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big - endian order regardless of what else is going on. This is useful in - archives. - -*/ -void -bfd_write_bigendian_4byte_int (abfd, i) - bfd *abfd; - int i; -{ - bfd_byte buffer[4]; - bfd_putb32(i, buffer); - if (bfd_write((PTR)buffer, 4, 1, abfd) != 4) - abort (); -} - -long -bfd_tell (abfd) - bfd *abfd; -{ - file_ptr ptr; - - ptr = ftell (bfd_cache_lookup(abfd)); - - if (abfd->my_archive) - ptr -= abfd->origin; - abfd->where = ptr; - return ptr; -} - -int -bfd_flush (abfd) - bfd *abfd; -{ - return fflush (bfd_cache_lookup(abfd)); -} - -int -bfd_stat (abfd, statbuf) - bfd *abfd; - struct stat *statbuf; -{ - return fstat (fileno(bfd_cache_lookup(abfd)), statbuf); -} - -/* Returns 0 for success, nonzero for failure (in which case bfd_get_error - can retrieve the error code). */ - -int -bfd_seek (abfd, position, direction) - bfd * CONST abfd; - CONST file_ptr position; - CONST int direction; -{ - int result; - FILE *f; - file_ptr file_position; - /* For the time being, a BFD may not seek to it's end. The problem - is that we don't easily have a way to recognize the end of an - element in an archive. */ - - BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR); - - if (direction == SEEK_CUR && position == 0) - return 0; -#ifdef FILE_OFFSET_IS_CHAR_INDEX - if (abfd->format != bfd_archive && abfd->my_archive == 0) - { -#if 0 - /* Explanation for this code: I'm only about 95+% sure that the above - conditions are sufficient and that all i/o calls are properly - adjusting the `where' field. So this is sort of an `assert' - that the `where' field is correct. If we can go a while without - tripping the abort, we can probably safely disable this code, - so that the real optimizations happen. */ - file_ptr where_am_i_now; - where_am_i_now = ftell (bfd_cache_lookup (abfd)); - if (abfd->my_archive) - where_am_i_now -= abfd->origin; - if (where_am_i_now != abfd->where) - abort (); -#endif - if (direction == SEEK_SET && position == abfd->where) - return 0; - } - else - { - /* We need something smarter to optimize access to archives. - Currently, anything inside an archive is read via the file - handle for the archive. Which means that a bfd_seek on one - component affects the `current position' in the archive, as - well as in any other component. - - It might be sufficient to put a spike through the cache - abstraction, and look to the archive for the file position, - but I think we should try for something cleaner. - - In the meantime, no optimization for archives. */ - } -#endif - - f = bfd_cache_lookup (abfd); - file_position = position; - if (direction == SEEK_SET && abfd->my_archive != NULL) - file_position += abfd->origin; - - result = fseek (f, file_position, direction); - - if (result != 0) - { - /* Force redetermination of `where' field. */ - bfd_tell (abfd); - bfd_set_error (bfd_error_system_call); - } - else - { -#ifdef FILE_OFFSET_IS_CHAR_INDEX - /* Adjust `where' field. */ - if (direction == SEEK_SET) - abfd->where = position; - else - abfd->where += position; -#endif - } - return result; -} - -/** Make a string table */ - -/*>bfd.h< - Add string to table pointed to by table, at location starting with free_ptr. - resizes the table if necessary (if it's NULL, creates it, ignoring - table_length). Updates free_ptr, table, table_length */ - -boolean -bfd_add_to_string_table (table, new_string, table_length, free_ptr) - char **table; - char *new_string; - unsigned int *table_length; - char **free_ptr; -{ - size_t string_length = strlen (new_string) + 1; /* include null here */ - char *base = *table; - size_t space_length = *table_length; - unsigned int offset = (base ? *free_ptr - base : 0); - - if (base == NULL) { - /* Avoid a useless regrow if we can (but of course we still - take it next time). */ - space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ? - DEFAULT_STRING_SPACE_SIZE : string_length+1); - base = bfd_zmalloc ((bfd_size_type) space_length); - - if (base == NULL) { - bfd_set_error (bfd_error_no_memory); - return false; - } - } - - if ((size_t)(offset + string_length) >= space_length) { - /* Make sure we will have enough space */ - while ((size_t)(offset + string_length) >= space_length) - space_length += space_length/2; /* grow by 50% */ - - base = (char *) realloc (base, space_length); - if (base == NULL) { - bfd_set_error (bfd_error_no_memory); - return false; - } - - } - - memcpy (base + offset, new_string, string_length); - *table = base; - *table_length = space_length; - *free_ptr = base + offset + string_length; - - return true; -} - -/** The do-it-yourself (byte) sex-change kit */ - -/* The middle letter e.g. get<b>short indicates Big or Little endian - target machine. It doesn't matter what the byte order of the host - machine is; these routines work for either. */ - -/* FIXME: Should these take a count argument? - Answer (gnu@cygnus.com): No, but perhaps they should be inline - functions in swap.h #ifdef __GNUC__. - Gprof them later and find out. */ - -/* -FUNCTION - bfd_put_size -FUNCTION - bfd_get_size - -DESCRIPTION - These macros as used for reading and writing raw data in - sections; each access (except for bytes) is vectored through - the target format of the BFD and mangled accordingly. The - mangling performs any necessary endian translations and - removes alignment restrictions. Note that types accepted and - returned by these macros are identical so they can be swapped - around in macros---for example, @file{libaout.h} defines <<GET_WORD>> - to either <<bfd_get_32>> or <<bfd_get_64>>. - - In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a - system without prototypes, the caller is responsible for making - sure that is true, with a cast if necessary. We don't cast - them in the macro definitions because that would prevent <<lint>> - or <<gcc -Wall>> from detecting sins such as passing a pointer. - To detect calling these with less than a <<bfd_vma>>, use - <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s. - -. -.{* Byte swapping macros for user section data. *} -. -.#define bfd_put_8(abfd, val, ptr) \ -. (*((unsigned char *)(ptr)) = (unsigned char)(val)) -.#define bfd_put_signed_8 \ -. bfd_put_8 -.#define bfd_get_8(abfd, ptr) \ -. (*(unsigned char *)(ptr)) -.#define bfd_get_signed_8(abfd, ptr) \ -. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80) -. -.#define bfd_put_16(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx16, ((val),(ptr))) -.#define bfd_put_signed_16 \ -. bfd_put_16 -.#define bfd_get_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx16, (ptr)) -.#define bfd_get_signed_16(abfd, ptr) \ -. BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) -. -.#define bfd_put_32(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx32, ((val),(ptr))) -.#define bfd_put_signed_32 \ -. bfd_put_32 -.#define bfd_get_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx32, (ptr)) -.#define bfd_get_signed_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx_signed_32, (ptr)) -. -.#define bfd_put_64(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_putx64, ((val), (ptr))) -.#define bfd_put_signed_64 \ -. bfd_put_64 -.#define bfd_get_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx64, (ptr)) -.#define bfd_get_signed_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_getx_signed_64, (ptr)) -. -*/ - -/* -FUNCTION - bfd_h_put_size - bfd_h_get_size - -DESCRIPTION - These macros have the same function as their <<bfd_get_x>> - bretheren, except that they are used for removing information - for the header records of object files. Believe it or not, - some object files keep their header records in big endian - order and their data in little endian order. -. -.{* Byte swapping macros for file header data. *} -. -.#define bfd_h_put_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_put_signed_8(abfd, val, ptr) \ -. bfd_put_8 (abfd, val, ptr) -.#define bfd_h_get_8(abfd, ptr) \ -. bfd_get_8 (abfd, ptr) -.#define bfd_h_get_signed_8(abfd, ptr) \ -. bfd_get_signed_8 (abfd, ptr) -. -.#define bfd_h_put_16(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx16,(val,ptr)) -.#define bfd_h_put_signed_16 \ -. bfd_h_put_16 -.#define bfd_h_get_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx16,(ptr)) -.#define bfd_h_get_signed_16(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr)) -. -.#define bfd_h_put_32(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx32,(val,ptr)) -.#define bfd_h_put_signed_32 \ -. bfd_h_put_32 -.#define bfd_h_get_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx32,(ptr)) -.#define bfd_h_get_signed_32(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr)) -. -.#define bfd_h_put_64(abfd, val, ptr) \ -. BFD_SEND(abfd, bfd_h_putx64,(val, ptr)) -.#define bfd_h_put_signed_64 \ -. bfd_h_put_64 -.#define bfd_h_get_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx64,(ptr)) -.#define bfd_h_get_signed_64(abfd, ptr) \ -. BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr)) -. -*/ - -/* Sign extension to bfd_signed_vma. */ -#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) -#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000) -#define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32) -#define COERCE64(x) \ - (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) - -bfd_vma -bfd_getb16 (addr) - register const bfd_byte *addr; -{ - return (addr[0] << 8) | addr[1]; -} - -bfd_vma -bfd_getl16 (addr) - register const bfd_byte *addr; -{ - return (addr[1] << 8) | addr[0]; -} - -bfd_signed_vma -bfd_getb_signed_16 (addr) - register const bfd_byte *addr; -{ - return COERCE16((addr[0] << 8) | addr[1]); -} - -bfd_signed_vma -bfd_getl_signed_16 (addr) - register const bfd_byte *addr; -{ - return COERCE16((addr[1] << 8) | addr[0]); -} - -void -bfd_putb16 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte)(data >> 8); - addr[1] = (bfd_byte )data; -} - -void -bfd_putl16 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte )data; - addr[1] = (bfd_byte)(data >> 8); -} - -bfd_vma -bfd_getb32 (addr) - register const bfd_byte *addr; -{ - return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]; -} - -bfd_vma -bfd_getl32 (addr) - register const bfd_byte *addr; -{ - return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]; -} - -bfd_signed_vma -bfd_getb_signed_32 (addr) - register const bfd_byte *addr; -{ - return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8) - | addr[2]) << 8 | addr[3]); -} - -bfd_signed_vma -bfd_getl_signed_32 (addr) - register const bfd_byte *addr; -{ - return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]); -} - -bfd_vma -bfd_getb64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - - high= ((((((((addr[0]) << 8) | - addr[1]) << 8) | - addr[2]) << 8) | - addr[3]) ); - - low = (((((((((bfd_vma)addr[4]) << 8) | - addr[5]) << 8) | - addr[6]) << 8) | - addr[7])); - - return high << 32 | low; -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_vma -bfd_getl64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - high= (((((((addr[7] << 8) | - addr[6]) << 8) | - addr[5]) << 8) | - addr[4])); - - low = ((((((((bfd_vma)addr[3] << 8) | - addr[2]) << 8) | - addr[1]) << 8) | - addr[0]) ); - - return high << 32 | low; -#else - BFD_FAIL(); - return 0; -#endif - -} - -bfd_signed_vma -bfd_getb_signed_64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - - high= ((((((((addr[0]) << 8) | - addr[1]) << 8) | - addr[2]) << 8) | - addr[3]) ); - - low = (((((((((bfd_vma)addr[4]) << 8) | - addr[5]) << 8) | - addr[6]) << 8) | - addr[7])); - - return COERCE64(high << 32 | low); -#else - BFD_FAIL(); - return 0; -#endif -} - -bfd_signed_vma -bfd_getl_signed_64 (addr) - register const bfd_byte *addr; -{ -#ifdef BFD64 - bfd_vma low, high; - high= (((((((addr[7] << 8) | - addr[6]) << 8) | - addr[5]) << 8) | - addr[4])); - - low = ((((((((bfd_vma)addr[3] << 8) | - addr[2]) << 8) | - addr[1]) << 8) | - addr[0]) ); - - return COERCE64(high << 32 | low); -#else - BFD_FAIL(); - return 0; -#endif -} - -void -bfd_putb32 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte)(data >> 24); - addr[1] = (bfd_byte)(data >> 16); - addr[2] = (bfd_byte)(data >> 8); - addr[3] = (bfd_byte)data; -} - -void -bfd_putl32 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ - addr[0] = (bfd_byte)data; - addr[1] = (bfd_byte)(data >> 8); - addr[2] = (bfd_byte)(data >> 16); - addr[3] = (bfd_byte)(data >> 24); -} - -void -bfd_putb64 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ -#ifdef BFD64 - addr[0] = (bfd_byte)(data >> (7*8)); - addr[1] = (bfd_byte)(data >> (6*8)); - addr[2] = (bfd_byte)(data >> (5*8)); - addr[3] = (bfd_byte)(data >> (4*8)); - addr[4] = (bfd_byte)(data >> (3*8)); - addr[5] = (bfd_byte)(data >> (2*8)); - addr[6] = (bfd_byte)(data >> (1*8)); - addr[7] = (bfd_byte)(data >> (0*8)); -#else - BFD_FAIL(); -#endif -} - -void -bfd_putl64 (data, addr) - bfd_vma data; - register bfd_byte *addr; -{ -#ifdef BFD64 - addr[7] = (bfd_byte)(data >> (7*8)); - addr[6] = (bfd_byte)(data >> (6*8)); - addr[5] = (bfd_byte)(data >> (5*8)); - addr[4] = (bfd_byte)(data >> (4*8)); - addr[3] = (bfd_byte)(data >> (3*8)); - addr[2] = (bfd_byte)(data >> (2*8)); - addr[1] = (bfd_byte)(data >> (1*8)); - addr[0] = (bfd_byte)(data >> (0*8)); -#else - BFD_FAIL(); -#endif -} - -/* Default implementation */ - -boolean -_bfd_generic_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count == 0) - return true; - if ((bfd_size_type)(offset+count) > section->_raw_size - || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1 - || bfd_read(location, (bfd_size_type)1, count, abfd) != count) - return (false); /* on error */ - return (true); -} - -/* This generic function can only be used in implementations where creating - NEW sections is disallowed. It is useful in patching existing sections - in read-write files, though. See other set_section_contents functions - to see why it doesn't work for new sections. */ -boolean -_bfd_generic_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (count == 0) - return true; - - if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1 - || bfd_write (location, (bfd_size_type) 1, count, abfd) != count) - return false; - - return true; -} - -/* -INTERNAL_FUNCTION - bfd_log2 - -SYNOPSIS - unsigned int bfd_log2(bfd_vma x); - -DESCRIPTION - Return the log base 2 of the value supplied, rounded up. E.g., an - @var{x} of 1025 returns 11. -*/ - -unsigned -bfd_log2(x) - bfd_vma x; -{ - unsigned result = 0; - while ( (bfd_vma)(1<< result) < x) - result++; - return result; -} - -boolean -bfd_generic_is_local_label (abfd, sym) - bfd *abfd; - asymbol *sym; -{ - char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.'; - - return (sym->name[0] == locals_prefix); -} - diff --git a/gnu/usr.bin/gdb/bfd/libbfd.h b/gnu/usr.bin/gdb/bfd/libbfd.h deleted file mode 100644 index 89e4c81..0000000 --- a/gnu/usr.bin/gdb/bfd/libbfd.h +++ /dev/null @@ -1,488 +0,0 @@ -/* libbfd.h -- Declarations used by bfd library *implementation*. - (This include file is not for users of the library.) - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -** NOTE: libbfd.h is a GENERATED file. Don't change it; instead, -** change libbfd-in.h or the other BFD source files processed to -** generate this file. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Align an address upward to a boundary, expressed as a number of bytes. - E.g. align to an 8-byte boundary with argument of 8. */ -#define BFD_ALIGN(this, boundary) \ - ((( (this) + ((boundary) -1)) & (~((boundary)-1)))) - -/* If you want to read and write large blocks, you might want to do it - in quanta of this amount */ -#define DEFAULT_BUFFERSIZE 8192 - -/* Set a tdata field. Can't use the other macros for this, since they - do casts, and casting to the left of assignment isn't portable. */ -#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v)) - -/* tdata for an archive. For an input archive, cache - needs to be free()'d. For an output archive, symdefs do. */ - -struct artdata { - file_ptr first_file_filepos; - /* Speed up searching the armap */ - struct ar_cache *cache; - bfd *archive_head; /* Only interesting in output routines */ - carsym *symdefs; /* the symdef entries */ - symindex symdef_count; /* how many there are */ - char *extended_names; /* clever intel extension */ - /* when more compilers are standard C, this can be a time_t */ - long armap_timestamp; /* Timestamp value written into armap. - This is used for BSD archives to check - that the timestamp is recent enough - for the BSD linker to not complain, - just before we finish writing an - archive. */ - file_ptr armap_datepos; /* Position within archive to seek to - rewrite the date field. */ - PTR tdata; /* Backend specific information. */ -}; - -#define bfd_ardata(bfd) ((bfd)->tdata.aout_ar_data) - -/* Goes in bfd's arelt_data slot */ -struct areltdata { - char * arch_header; /* it's actually a string */ - unsigned int parsed_size; /* octets of filesize not including ar_hdr */ - char *filename; /* null-terminated */ -}; - -#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size) - -char *bfd_zmalloc PARAMS ((bfd_size_type size)); - -/* These routines allocate and free things on the BFD's obstack. Note - that realloc can never occur in place. */ - -PTR bfd_alloc PARAMS ((bfd *abfd, size_t size)); -PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size)); -PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t size)); -void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size)); -PTR bfd_alloc_finish PARAMS ((bfd *abfd)); -PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted)); - -#define bfd_release(x,y) (void) obstack_free(&(x->memory),y) - - -bfd_size_type bfd_read PARAMS ((PTR ptr, bfd_size_type size, - bfd_size_type nitems, bfd *abfd)); -bfd_size_type bfd_write PARAMS ((CONST PTR ptr, bfd_size_type size, - bfd_size_type nitems, bfd *abfd)); -int bfd_seek PARAMS ((bfd* CONST abfd, CONST file_ptr fp, - CONST int direction)); -long bfd_tell PARAMS ((bfd *abfd)); - -int bfd_flush PARAMS ((bfd *abfd)); -int bfd_stat PARAMS ((bfd *abfd, struct stat *)); - -bfd * _bfd_create_empty_archive_element_shell PARAMS ((bfd *obfd)); -bfd * _bfd_look_for_bfd_in_cache PARAMS ((bfd *arch_bfd, file_ptr index)); -boolean _bfd_add_bfd_to_archive_cache PARAMS ((bfd *, file_ptr, bfd *)); -boolean _bfd_generic_mkarchive PARAMS ((bfd *abfd)); -struct areltdata *_bfd_snarf_ar_hdr PARAMS ((bfd *abfd)); -const bfd_target *bfd_generic_archive_p PARAMS ((bfd *abfd)); -boolean bfd_slurp_armap PARAMS ((bfd *abfd)); -boolean bfd_slurp_bsd_armap_f2 PARAMS ((bfd *abfd)); -#define bfd_slurp_bsd_armap bfd_slurp_armap -#define bfd_slurp_coff_armap bfd_slurp_armap -boolean _bfd_slurp_extended_name_table PARAMS ((bfd *abfd)); -boolean _bfd_write_archive_contents PARAMS ((bfd *abfd)); -bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos)); -bfd * _bfd_new_bfd PARAMS ((void)); - -#define DEFAULT_STRING_SPACE_SIZE 0x2000 -boolean bfd_add_to_string_table PARAMS ((char **table, char *new_string, - unsigned int *table_length, - char **free_ptr)); - -boolean bfd_false PARAMS ((bfd *ignore)); -boolean bfd_true PARAMS ((bfd *ignore)); -PTR bfd_nullvoidptr PARAMS ((bfd *ignore)); -int bfd_0 PARAMS ((bfd *ignore)); -unsigned int bfd_0u PARAMS ((bfd *ignore)); -long bfd_0l PARAMS ((bfd *ignore)); -long _bfd_n1 PARAMS ((bfd *ignore)); -void bfd_void PARAMS ((bfd *ignore)); - -bfd *_bfd_new_bfd_contained_in PARAMS ((bfd *)); -const bfd_target *_bfd_dummy_target PARAMS ((bfd *abfd)); - -void bfd_dont_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_bsd_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); -void bfd_gnu_truncate_arname PARAMS ((bfd *abfd, CONST char *filename, - char *hdr)); - -boolean bsd_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength, - struct orl *map, unsigned int orl_count, int stridx)); - -bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive, - bfd *last_file)); - -int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); - - -/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use - BFD_JUMP_TABLE_GENERIC (_bfd_generic). */ - -#define _bfd_generic_close_and_cleanup bfd_true -#define _bfd_generic_bfd_free_cached_info bfd_true -#define _bfd_generic_new_section_hook \ - ((boolean (*) PARAMS ((bfd *, asection *))) bfd_true) -extern boolean _bfd_generic_get_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr offset, - bfd_size_type count)); - -/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use - BFD_JUMP_TABLE_COPY (_bfd_generic). */ - -#define _bfd_generic_bfd_copy_private_bfd_data \ - ((boolean (*) PARAMS ((bfd *, bfd *))) bfd_true) -#define _bfd_generic_bfd_copy_private_section_data \ - ((boolean (*) PARAMS ((bfd *, asection *, bfd *, asection *))) bfd_true) - -/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file - support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */ - -extern char *_bfd_nocore_core_file_failing_command PARAMS ((bfd *)); -extern int _bfd_nocore_core_file_failing_signal PARAMS ((bfd *)); -extern boolean _bfd_nocore_core_file_matches_executable_p - PARAMS ((bfd *, bfd *)); - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE when there is no archive - file support. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive). */ - -#define _bfd_noarchive_slurp_armap bfd_false -#define _bfd_noarchive_slurp_extended_name_table bfd_false -#define _bfd_noarchive_truncate_arname \ - ((void (*) PARAMS ((bfd *, const char *, char *))) bfd_void) -#define _bfd_noarchive_write_armap \ - ((boolean (*) \ - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ - bfd_false) -#define _bfd_noarchive_openr_next_archived_file \ - ((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr) -#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get BSD style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd). */ - -#define _bfd_archive_bsd_slurp_armap bfd_slurp_bsd_armap -#define _bfd_archive_bsd_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -#define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname -#define _bfd_archive_bsd_write_armap bsd_write_armap -#define _bfd_archive_bsd_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_bsd_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt - -/* Routines to use for BFD_JUMP_TABLE_ARCHIVE to get COFF style - archives. Use BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff). */ - -#define _bfd_archive_coff_slurp_armap bfd_slurp_coff_armap -#define _bfd_archive_coff_slurp_extended_name_table \ - _bfd_slurp_extended_name_table -#define _bfd_archive_coff_truncate_arname bfd_dont_truncate_arname -#define _bfd_archive_coff_write_armap coff_write_armap -#define _bfd_archive_coff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_archive_coff_generic_stat_arch_elt \ - bfd_generic_stat_arch_elt - -/* Routines to use for BFD_JUMP_TABLE_SYMBOLS where there is no symbol - support. Use BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols). */ - -#define _bfd_nosymbols_get_symtab_upper_bound _bfd_n1 -#define _bfd_nosymbols_get_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nosymbols_make_empty_symbol \ - ((asymbol *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nosymbols_print_symbol \ - ((void (*) PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type))) bfd_void) -#define _bfd_nosymbols_get_symbol_info \ - ((void (*) PARAMS ((bfd *, asymbol *, symbol_info *))) bfd_void) -#define _bfd_nosymbols_bfd_is_local_label \ - ((boolean (*) PARAMS ((bfd *, asymbol *))) bfd_false) -#define _bfd_nosymbols_get_lineno \ - ((alent *(*) PARAMS ((bfd *, asymbol *))) bfd_nullvoidptr) -#define _bfd_nosymbols_find_nearest_line \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, asymbol **, bfd_vma, const char **, \ - const char **, unsigned int *))) \ - bfd_false) -#define _bfd_nosymbols_bfd_make_debug_symbol \ - ((asymbol *(*) PARAMS ((bfd *, PTR, unsigned long))) bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_RELOCS when there is no reloc - support. Use BFD_JUMP_TABLE_RELOCS (_bfd_norelocs). */ - -#define _bfd_norelocs_get_reloc_upper_bound \ - ((long (*) PARAMS ((bfd *, asection *))) _bfd_n1) -#define _bfd_norelocs_canonicalize_reloc \ - ((long (*) PARAMS ((bfd *, asection *, arelent **, asymbol **))) _bfd_n1) -#define _bfd_norelocs_bfd_reloc_type_lookup \ - ((const reloc_howto_type *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) \ - bfd_nullvoidptr) - -/* Routines to use for BFD_JUMP_TABLE_WRITE for targets which may not - be written. Use BFD_JUMP_TABLE_WRITE (_bfd_nowrite). */ - -#define _bfd_nowrite_set_arch_mach \ - ((boolean (*) PARAMS ((bfd *, enum bfd_architecture, unsigned long))) \ - bfd_false) -#define _bfd_nowrite_set_section_contents \ - ((boolean (*) PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type))) \ - bfd_false) - -/* Generic routines to use for BFD_JUMP_TABLE_WRITE. Use - BFD_JUMP_TABLE_WRITE (_bfd_generic). */ - -#define _bfd_generic_set_arch_mach bfd_default_set_arch_mach -extern boolean _bfd_generic_set_section_contents - PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type)); - -/* Routines to use for BFD_JUMP_TABLE_LINK for targets which do not - support linking. Use BFD_JUMP_TABLE_LINK (_bfd_nolink). */ - -#define _bfd_nolink_sizeof_headers ((int (*) PARAMS ((bfd *, boolean))) bfd_0) -#define _bfd_nolink_bfd_get_relocated_section_contents \ - ((bfd_byte *(*) \ - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, \ - bfd_byte *, boolean, asymbol **))) \ - bfd_nullvoidptr) -#define _bfd_nolink_bfd_relax_section \ - ((boolean (*) \ - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *))) \ - bfd_false) -#define _bfd_nolink_bfd_link_hash_table_create \ - ((struct bfd_link_hash_table *(*) PARAMS ((bfd *))) bfd_nullvoidptr) -#define _bfd_nolink_bfd_link_add_symbols \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) -#define _bfd_nolink_bfd_final_link \ - ((boolean (*) PARAMS ((bfd *, struct bfd_link_info *))) bfd_false) - -/* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not - have dynamic symbols or relocs. Use BFD_JUMP_TABLE_DYNAMIC - (_bfd_nodynamic). */ - -#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_symtab \ - ((long (*) PARAMS ((bfd *, asymbol **))) _bfd_n1) -#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 -#define _bfd_nodynamic_canonicalize_dynamic_reloc \ - ((long (*) PARAMS ((bfd *, arelent **, asymbol **))) _bfd_n1) - -/* Generic routine to determine of the given symbol is a local - label. */ -extern boolean bfd_generic_is_local_label PARAMS ((bfd *, asymbol *)); - -/* A routine to create entries for a bfd_link_hash_table. */ -extern struct bfd_hash_entry *_bfd_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string)); - -/* Initialize a bfd_link_hash_table. */ -extern boolean _bfd_link_hash_table_init - PARAMS ((struct bfd_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Generic link hash table creation routine. */ -extern struct bfd_link_hash_table *_bfd_generic_link_hash_table_create - PARAMS ((bfd *)); - -/* Generic add symbol routine. */ -extern boolean _bfd_generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic add symbol routine. This version is used by targets for - which the linker must collect constructors and destructors by name, - as the collect2 program does. */ -extern boolean _bfd_generic_link_add_symbols_collect - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic archive add symbol routine. */ -extern boolean _bfd_generic_link_add_archive_symbols - PARAMS ((bfd *, struct bfd_link_info *, - boolean (*checkfn) (bfd *, struct bfd_link_info *, boolean *))); - -/* Forward declaration to avoid prototype errors. */ -typedef struct bfd_link_hash_entry _bfd_link_hash_entry; - -/* Generic routine to add a single symbol. */ -extern boolean _bfd_generic_link_add_one_symbol - PARAMS ((struct bfd_link_info *, bfd *, const char *name, flagword, - asection *, bfd_vma, const char *, boolean copy, - boolean constructor, struct bfd_link_hash_entry **)); - -/* Generic link routine. */ -extern boolean _bfd_generic_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Generic reloc_link_order processing routine. */ -extern boolean _bfd_generic_reloc_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Default link order processing routine. */ -extern boolean _bfd_default_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* Count the number of reloc entries in a link order list. */ -extern unsigned int _bfd_count_link_order_relocs - PARAMS ((struct bfd_link_order *)); - -/* Final link relocation routine. */ -extern bfd_reloc_status_type _bfd_final_link_relocate - PARAMS ((const reloc_howto_type *, bfd *, asection *, bfd_byte *, - bfd_vma address, bfd_vma value, bfd_vma addend)); - -/* Relocate a particular location by a howto and a value. */ -extern bfd_reloc_status_type _bfd_relocate_contents - PARAMS ((const reloc_howto_type *, bfd *, bfd_vma, bfd_byte *)); - -/* Macros to tell if bfds are read or write enabled. - - Note that bfds open for read may be scribbled into if the fd passed - to bfd_fdopenr is actually open both for read and write - simultaneously. However an output bfd will never be open for - read. Therefore sometimes you want to check bfd_read_p or - !bfd_read_p, and only sometimes bfd_write_p. -*/ - -#define bfd_read_p(abfd) ((abfd)->direction == read_direction || (abfd)->direction == both_direction) -#define bfd_write_p(abfd) ((abfd)->direction == write_direction || (abfd)->direction == both_direction) - -void bfd_assert PARAMS ((char*,int)); - -#define BFD_ASSERT(x) \ -{ if (!(x)) bfd_assert(__FILE__,__LINE__); } - -#define BFD_FAIL() \ -{ bfd_assert(__FILE__,__LINE__); } - -FILE * bfd_cache_lookup_worker PARAMS ((bfd *)); - -extern bfd *bfd_last_cache; - -/* Now Steve, what's the story here? */ -#ifdef lint -#define itos(x) "l" -#define stoi(x) 1 -#else -#define itos(x) ((char*)(x)) -#define stoi(x) ((int)(x)) -#endif - -/* List of supported target vectors, and the default vector (if - bfd_default_vector[0] is NULL, there is no default). */ -extern const bfd_target * const bfd_target_vector[]; -extern const bfd_target * const bfd_default_vector[]; - -/* And more follows */ - -void -bfd_check_init PARAMS ((void)); - -void -bfd_write_bigendian_4byte_int PARAMS ((bfd *abfd, int i)); - -unsigned int -bfd_log2 PARAMS ((bfd_vma x)); - -#define BFD_CACHE_MAX_OPEN 10 -extern bfd *bfd_last_cache; - -#define bfd_cache_lookup(x) \ - ((x)==bfd_last_cache? \ - (FILE*)(bfd_last_cache->iostream): \ - bfd_cache_lookup_worker(x)) -boolean -bfd_cache_init PARAMS ((bfd *abfd)); - -boolean -bfd_cache_close PARAMS ((bfd *abfd)); - -FILE* -bfd_open_file PARAMS ((bfd *abfd)); - -FILE * -bfd_cache_lookup_worker PARAMS ((bfd *abfd)); - -boolean -bfd_constructor_entry PARAMS ((bfd *abfd, - asymbol **symbol_ptr_ptr, - CONST char*type)); - -const struct reloc_howto_struct * -bfd_default_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); - -boolean -bfd_generic_relax_section - PARAMS ((bfd *abfd, - asection *section, - struct bfd_link_info *, - boolean *)); - -bfd_byte * - -bfd_generic_get_relocated_section_contents PARAMS ((bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - boolean relocateable, - asymbol **symbols)); - -extern bfd_arch_info_type bfd_default_arch_struct; -boolean -bfd_default_set_arch_mach PARAMS ((bfd *abfd, - enum bfd_architecture arch, - unsigned long mach)); - -void -bfd_arch_init PARAMS ((void)); - -void -bfd_arch_linkin PARAMS ((bfd_arch_info_type *ptr)); - -CONST bfd_arch_info_type * -bfd_default_compatible - PARAMS ((CONST bfd_arch_info_type *a, - CONST bfd_arch_info_type *b)); - -boolean -bfd_default_scan PARAMS ((CONST struct bfd_arch_info *info, CONST char *string)); - -struct elf_internal_shdr * -bfd_elf_find_section PARAMS ((bfd *abfd, char *name)); - diff --git a/gnu/usr.bin/gdb/bfd/libcoff.h b/gnu/usr.bin/gdb/bfd/libcoff.h deleted file mode 100644 index a564f11..0000000 --- a/gnu/usr.bin/gdb/bfd/libcoff.h +++ /dev/null @@ -1,369 +0,0 @@ -/* BFD COFF object file private structure. - Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* Object file tdata; access macros */ - -#define coff_data(bfd) ((bfd)->tdata.coff_obj_data) -#define exec_hdr(bfd) (coff_data(bfd)->hdr) -#define obj_symbols(bfd) (coff_data(bfd)->symbols) -#define obj_sym_filepos(bfd) (coff_data(bfd)->sym_filepos) - -#define obj_relocbase(bfd) (coff_data(bfd)->relocbase) -#define obj_raw_syments(bfd) (coff_data(bfd)->raw_syments) -#define obj_raw_syment_count(bfd) (coff_data(bfd)->raw_syment_count) -#define obj_convert(bfd) (coff_data(bfd)->conversion_table) -#define obj_conv_table_size(bfd) (coff_data(bfd)->conv_table_size) -#if CFILE_STUFF -#define obj_symbol_slew(bfd) (coff_data(bfd)->symbol_index_slew) -#else -#define obj_symbol_slew(bfd) 0 -#endif - - -/* `Tdata' information kept for COFF files. */ - -typedef struct coff_tdata -{ - struct coff_symbol_struct *symbols; /* symtab for input bfd */ - unsigned int *conversion_table; - int conv_table_size; - file_ptr sym_filepos; - - long symbol_index_slew; /* used during read to mark whether a - C_FILE symbol as been added. */ - - struct coff_ptr_struct *raw_syments; - struct lineno *raw_linenos; - unsigned int raw_syment_count; - unsigned short flags; - - /* These are only valid once writing has begun */ - long int relocbase; - - /* These members communicate important constants about the symbol table - to GDB's symbol-reading code. These `constants' unfortunately vary - from coff implementation to implementation... */ - unsigned local_n_btmask; - unsigned local_n_btshft; - unsigned local_n_tmask; - unsigned local_n_tshift; - unsigned local_symesz; - unsigned local_auxesz; - unsigned local_linesz; -} coff_data_type; - -/* We take the address of the first element of a asymbol to ensure that the - * macro is only ever applied to an asymbol. */ -#define coffsymbol(asymbol) ((coff_symbol_type *)(&((asymbol)->the_bfd))) - -/* Functions in coffgen.c. */ -extern const bfd_target *coff_object_p PARAMS ((bfd *)); -extern struct sec *coff_section_from_bfd_index PARAMS ((bfd *, int)); -extern long coff_get_symtab_upper_bound PARAMS ((bfd *)); -extern long coff_get_symtab PARAMS ((bfd *, asymbol **)); -extern int coff_count_linenumbers PARAMS ((bfd *)); -extern struct coff_symbol_struct *coff_symbol_from PARAMS ((bfd *, asymbol *)); -extern boolean coff_renumber_symbols PARAMS ((bfd *)); -extern void coff_mangle_symbols PARAMS ((bfd *)); -extern boolean coff_write_symbols PARAMS ((bfd *)); -extern boolean coff_write_linenumbers PARAMS ((bfd *)); -extern alent *coff_get_lineno PARAMS ((bfd *, asymbol *)); -extern asymbol *coff_section_symbol PARAMS ((bfd *, char *)); -extern struct coff_ptr_struct *coff_get_normalized_symtab PARAMS ((bfd *)); -extern long coff_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern asymbol *coff_make_empty_symbol PARAMS ((bfd *)); -extern void coff_print_symbol PARAMS ((bfd *, PTR filep, asymbol *, - bfd_print_symbol_type how)); -extern void coff_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *ret)); -extern asymbol *coff_bfd_make_debug_symbol PARAMS ((bfd *, PTR, - unsigned long)); -extern boolean coff_find_nearest_line PARAMS ((bfd *, - asection *, - asymbol **, - bfd_vma offset, - CONST char **filename_ptr, - CONST char **functionname_ptr, - unsigned int *line_ptr)); -extern int coff_sizeof_headers PARAMS ((bfd *, boolean reloc)); -extern boolean bfd_coff_reloc16_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); -extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, - bfd_byte *, boolean relocateable, asymbol **)); -extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *, - struct bfd_link_info *, - asection *)); -extern void bfd_perform_slip PARAMS ((bfd *abfd, unsigned int slip, - asection *input_section, - bfd_vma val)); - -/* And more taken from the source .. */ - -typedef struct coff_ptr_struct -{ - - /* Remembers the offset from the first symbol in the file for - this symbol. Generated by coff_renumber_symbols. */ -unsigned int offset; - - /* Should the value of this symbol be renumbered. Used for - XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */ -unsigned int fix_value : 1; - - /* Should the tag field of this symbol be renumbered. - Created by coff_pointerize_aux. */ -unsigned int fix_tag : 1; - - /* Should the endidx field of this symbol be renumbered. - Created by coff_pointerize_aux. */ -unsigned int fix_end : 1; - - /* Should the x_csect.x_scnlen field be renumbered. - Created by coff_slurp_symbol_table. */ -unsigned int fix_scnlen : 1; - - /* The container for the symbol structure as read and translated - from the file. */ - -union { - union internal_auxent auxent; - struct internal_syment syment; - } u; -} combined_entry_type; - - - /* Each canonical asymbol really looks like this: */ - -typedef struct coff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ -asymbol symbol; - - /* A pointer to the hidden information for this symbol */ -combined_entry_type *native; - - /* A pointer to the linenumber information for this symbol */ -struct lineno_cache_entry *lineno; - - /* Have the line numbers been relocated yet ? */ -boolean done_lineno; -} coff_symbol_type; -typedef struct -{ - void (*_bfd_coff_swap_aux_in) PARAMS (( - bfd *abfd, - PTR ext, - int type, - int class, - int indaux, - int numaux, - PTR in)); - - void (*_bfd_coff_swap_sym_in) PARAMS (( - bfd *abfd , - PTR ext, - PTR in)); - - void (*_bfd_coff_swap_lineno_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - - unsigned int (*_bfd_coff_swap_aux_out) PARAMS (( - bfd *abfd, - PTR in, - int type, - int class, - int indaux, - int numaux, - PTR ext)); - - unsigned int (*_bfd_coff_swap_sym_out) PARAMS (( - bfd *abfd, - PTR in, - PTR ext)); - - unsigned int (*_bfd_coff_swap_lineno_out) PARAMS (( - bfd *abfd, - PTR in, - PTR ext)); - - unsigned int (*_bfd_coff_swap_reloc_out) PARAMS (( - bfd *abfd, - PTR src, - PTR dst)); - - unsigned int (*_bfd_coff_swap_filehdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int (*_bfd_coff_swap_aouthdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int (*_bfd_coff_swap_scnhdr_out) PARAMS (( - bfd *abfd, - PTR in, - PTR out)); - - unsigned int _bfd_filhsz; - unsigned int _bfd_aoutsz; - unsigned int _bfd_scnhsz; - unsigned int _bfd_symesz; - unsigned int _bfd_auxesz; - unsigned int _bfd_linesz; - boolean _bfd_coff_long_filenames; - void (*_bfd_coff_swap_filehdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - void (*_bfd_coff_swap_aouthdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - void (*_bfd_coff_swap_scnhdr_in) PARAMS (( - bfd *abfd, - PTR ext, - PTR in)); - boolean (*_bfd_coff_bad_format_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr)); - boolean (*_bfd_coff_set_arch_mach_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr)); - PTR (*_bfd_coff_mkobject_hook) PARAMS (( - bfd *abfd, - PTR internal_filehdr, - PTR internal_aouthdr)); - flagword (*_bfd_styp_to_sec_flags_hook) PARAMS (( - bfd *abfd, - PTR internal_scnhdr)); - asection *(*_bfd_make_section_hook) PARAMS (( - bfd *abfd, - char *name)); - void (*_bfd_set_alignment_hook) PARAMS (( - bfd *abfd, - asection *sec, - PTR internal_scnhdr)); - boolean (*_bfd_coff_slurp_symbol_table) PARAMS (( - bfd *abfd)); - boolean (*_bfd_coff_symname_in_debug) PARAMS (( - bfd *abfd, - struct internal_syment *sym)); - void (*_bfd_coff_reloc16_extra_cases) PARAMS (( - bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - arelent *reloc, - bfd_byte *data, - unsigned int *src_ptr, - unsigned int *dst_ptr)); - int (*_bfd_coff_reloc16_estimate) PARAMS (( - bfd *abfd, - asection *input_section, - arelent *r, - unsigned int shrink, - struct bfd_link_info *link_info)); - -} bfd_coff_backend_data; - -#define coff_backend_info(abfd) ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) - -#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ - ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) - -#define bfd_coff_swap_sym_in(a,e,i) \ - ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) - -#define bfd_coff_swap_lineno_in(a,e,i) \ - ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) - -#define bfd_coff_swap_reloc_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) - -#define bfd_coff_swap_lineno_out(abfd, i, o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) - -#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ - ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) - -#define bfd_coff_swap_sym_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) - -#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) - -#define bfd_coff_swap_filehdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) - -#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) -#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) -#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) -#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) -#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) -#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) -#define bfd_coff_long_filenames(abfd) (coff_backend_info (abfd)->_bfd_coff_long_filenames) -#define bfd_coff_swap_filehdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) - -#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) - -#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ - ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) - -#define bfd_coff_bad_format_hook(abfd, filehdr) \ - ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) - -#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ - ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) -#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ - ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook) (abfd, filehdr, aouthdr)) - -#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr)\ - ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook) (abfd, scnhdr)) - -#define bfd_coff_make_section_hook(abfd, name)\ - ((coff_backend_info (abfd)->_bfd_make_section_hook) (abfd, name)) - -#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ - ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) - -#define bfd_coff_slurp_symbol_table(abfd)\ - ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) - -#define bfd_coff_symname_in_debug(abfd, sym)\ - ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) - -#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)\ - ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ - (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) - -#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ - ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ - (abfd, section, reloc, shrink, link_info)) - diff --git a/gnu/usr.bin/gdb/bfd/libecoff.h b/gnu/usr.bin/gdb/bfd/libecoff.h deleted file mode 100644 index 2f7b852..0000000 --- a/gnu/usr.bin/gdb/bfd/libecoff.h +++ /dev/null @@ -1,297 +0,0 @@ -/* BFD ECOFF object file private structure. - Copyright (C) 1993 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfdlink.h" - -#ifndef ECOFF_H -#include "coff/ecoff.h" -#endif - -/* This is the backend information kept for ECOFF files. This - structure is constant for a particular backend. The first element - is the COFF backend data structure, so that ECOFF targets can use - the generic COFF code. */ - -#define ecoff_backend(abfd) \ - ((struct ecoff_backend_data *) (abfd)->xvec->backend_data) - -struct ecoff_backend_data -{ - /* COFF backend information. This must be the first field. */ - bfd_coff_backend_data coff; - /* Supported architecture. */ - enum bfd_architecture arch; - /* Initial portion of armap string. */ - const char *armap_start; - /* The page boundary used to align sections in a demand-paged - executable file. E.g., 0x1000. */ - bfd_vma round; - /* True if the .rdata section is part of the text segment, as on the - Alpha. False if .rdata is part of the data segment, as on the - MIPS. */ - boolean rdata_in_text; - /* Bitsize of constructor entries. */ - unsigned int constructor_bitsize; - /* Reloc to use for constructor entries. */ - CONST struct reloc_howto_struct *constructor_reloc; - /* How to swap debugging information. */ - struct ecoff_debug_swap debug_swap; - /* External reloc size. */ - bfd_size_type external_reloc_size; - /* Reloc swapping functions. */ - void (*swap_reloc_in) PARAMS ((bfd *, PTR, struct internal_reloc *)); - void (*swap_reloc_out) PARAMS ((bfd *, const struct internal_reloc *, PTR)); - /* Backend reloc tweaking. */ - void (*adjust_reloc_in) PARAMS ((bfd *, const struct internal_reloc *, - arelent *)); - void (*adjust_reloc_out) PARAMS ((bfd *, const arelent *, - struct internal_reloc *)); - /* Relocate section contents while linking. */ - boolean (*relocate_section) PARAMS ((bfd *output_bfd, struct bfd_link_info *, - bfd *input_bfd, asection *input_section, - bfd_byte *contents, - PTR external_relocs)); -}; - -/* This is the target specific information kept for ECOFF files. */ - -#define ecoff_data(abfd) ((abfd)->tdata.ecoff_obj_data) - -typedef struct ecoff_tdata -{ - /* The reloc file position, set by - ecoff_compute_section_file_positions. */ - file_ptr reloc_filepos; - - /* The symbol table file position, set by _bfd_ecoff_mkobject_hook. */ - file_ptr sym_filepos; - - /* The start and end of the text segment. Only valid for an - existing file, not for one we are creating. */ - unsigned long text_start; - unsigned long text_end; - - /* The cached gp value. This is used when relocating. */ - bfd_vma gp; - - /* The maximum size of objects to optimize using gp. This is - typically set by the -G option to the compiler, assembler or - linker. */ - int gp_size; - - /* The register masks. When linking, all the masks found in the - input files are combined into the masks of the output file. - These are not all used for all targets, but that's OK, because - the relevant ones are the only ones swapped in and out. */ - unsigned long gprmask; - unsigned long fprmask; - unsigned long cprmask[4]; - - /* The ECOFF symbolic debugging information. */ - struct ecoff_debug_info debug_info; - - /* The unswapped ECOFF symbolic information. */ - PTR raw_syments; - - /* The canonical BFD symbols. */ - struct ecoff_symbol_struct *canonical_symbols; - - /* A mapping from external symbol numbers to entries in the linker - hash table, used when linking. */ - struct ecoff_link_hash_entry **sym_hashes; - - /* A mapping from reloc symbol indices to sections, used when - linking. */ - asection **symndx_to_section; - - /* True if this BFD was written by the backend linker. */ - boolean linker; - -} ecoff_data_type; - -/* Each canonical asymbol really looks like this. */ - -typedef struct ecoff_symbol_struct -{ - /* The actual symbol which the rest of BFD works with */ - asymbol symbol; - - /* The fdr for this symbol. */ - FDR *fdr; - - /* true if this is a local symbol rather than an external one. */ - boolean local; - - /* A pointer to the unswapped hidden information for this symbol. - This is either a struct sym_ext or a struct ext_ext, depending on - the value of the local field above. */ - PTR native; -} ecoff_symbol_type; - -/* We take the address of the first element of a asymbol to ensure that the - macro is only ever applied to an asymbol. */ -#define ecoffsymbol(asymbol) ((ecoff_symbol_type *) (&((asymbol)->the_bfd))) - -/* This is a hack borrowed from coffcode.h; we need to save the index - of an external symbol when we write it out so that can set the - symbol index correctly when we write out the relocs. */ -#define ecoff_get_sym_index(symbol) ((unsigned long) (symbol)->udata) -#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata = (PTR) (idx)) - -/* When generating MIPS embedded PIC code, the linker relaxes the code - to turn PC relative branches into longer code sequences when the PC - relative branch is out of range. This involves reading the relocs - in bfd_relax_section as well as in bfd_final_link, and requires the - code to keep track of which relocs have been expanded. A pointer - to this structure is put in the used_by_bfd pointer of a section to - keep track of this information. The user_by_bfd pointer will be - NULL if the information was not needed. */ - -struct ecoff_section_tdata -{ - /* The unswapped relocs for this section. These are stored in - memory so the input file does not have to be read twice. */ - PTR external_relocs; - - /* The contents of the section. These bytes may or may not be saved - in memory, but if it is this is a pointer to them. */ - bfd_byte *contents; - - /* Offset adjustments for PC relative branches. A number other than - 1 is an addend for a PC relative branch, or a switch table entry - which is the difference of two .text locations; this addend - arises because the branch or difference crosses one or more - branches which were expanded into a larger code sequence. A 1 - means that this branch was itself expanded into a larger code - sequence. 1 is not a possible offset, since all offsets must be - multiples of the instruction size, which is 4; also, the only - relocs with non-zero offsets will be PC relative branches or - switch table entries within the same object file. If this field - is NULL, no branches were expanded and no offsets are required. - Otherwise there are as many entries as there are relocs in the - section, and the entry for any reloc that is not PC relative is - zero. */ - long *offsets; -}; - -/* An accessor macro for the ecoff_section_tdata structure. */ -#define ecoff_section_data(abfd, sec) \ - ((struct ecoff_section_tdata *) (sec)->used_by_bfd) - -/* ECOFF linker hash table entries. */ - -struct ecoff_link_hash_entry -{ - struct bfd_link_hash_entry root; - /* Symbol index in output file. */ - long indx; - /* BFD that ext field value came from. */ - bfd *abfd; - /* ECOFF external symbol information. */ - EXTR esym; - /* Nonzero if this symbol has been written out. */ - char written; - /* Nonzero if this symbol was referred to as small undefined. */ - char small; -}; - -/* ECOFF linker hash table. */ - -struct ecoff_link_hash_table -{ - struct bfd_link_hash_table root; -}; - -/* Make an ECOFF object. */ -extern boolean _bfd_ecoff_mkobject PARAMS ((bfd *)); - -/* Read in the ECOFF symbolic debugging information. */ -extern boolean _bfd_ecoff_slurp_symbolic_info - PARAMS ((bfd *, asection *, struct ecoff_debug_info *)); - -/* Generic ECOFF BFD backend vectors. */ - -extern boolean _bfd_ecoff_write_object_contents PARAMS ((bfd *abfd)); -extern const bfd_target *_bfd_ecoff_archive_p PARAMS ((bfd *abfd)); - -#define _bfd_ecoff_close_and_cleanup _bfd_generic_close_and_cleanup -#define _bfd_ecoff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -extern boolean _bfd_ecoff_new_section_hook - PARAMS ((bfd *, asection *)); -extern boolean _bfd_ecoff_get_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type)); - -extern boolean _bfd_ecoff_bfd_copy_private_bfd_data PARAMS ((bfd *, bfd *)); -#define _bfd_ecoff_bfd_copy_private_section_data \ - _bfd_generic_bfd_copy_private_section_data - -extern boolean _bfd_ecoff_slurp_armap PARAMS ((bfd *abfd)); -#define _bfd_ecoff_slurp_extended_name_table _bfd_slurp_extended_name_table -#define _bfd_ecoff_truncate_arname bfd_dont_truncate_arname -extern boolean _bfd_ecoff_write_armap - PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); -#define _bfd_ecoff_openr_next_archived_file \ - bfd_generic_openr_next_archived_file -#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt - -extern long _bfd_ecoff_get_symtab_upper_bound PARAMS ((bfd *abfd)); -extern long _bfd_ecoff_get_symtab PARAMS ((bfd *abfd, asymbol **alocation)); -extern asymbol *_bfd_ecoff_make_empty_symbol PARAMS ((bfd *abfd)); -extern void _bfd_ecoff_print_symbol - PARAMS ((bfd *, PTR filep, asymbol *, bfd_print_symbol_type)); -extern void _bfd_ecoff_get_symbol_info - PARAMS ((bfd *, asymbol *, symbol_info *)); -#define _bfd_ecoff_bfd_is_local_label bfd_generic_is_local_label -#define _bfd_ecoff_get_lineno _bfd_nosymbols_get_lineno -extern boolean _bfd_ecoff_find_nearest_line - PARAMS ((bfd *, asection *, asymbol **, bfd_vma offset, - const char **filename_ptr, const char **fnname_ptr, - unsigned int *retline_ptr)); -#define _bfd_ecoff_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol - -#define _bfd_ecoff_get_reloc_upper_bound coff_get_reloc_upper_bound -extern long _bfd_ecoff_canonicalize_reloc - PARAMS ((bfd *, asection *, arelent **, asymbol **symbols)); -/* ecoff_bfd_reloc_type_lookup defined by backend. */ - -extern boolean _bfd_ecoff_set_arch_mach - PARAMS ((bfd *, enum bfd_architecture, unsigned long machine)); -extern boolean _bfd_ecoff_set_section_contents - PARAMS ((bfd *, asection *, PTR location, file_ptr, bfd_size_type)); - -extern int _bfd_ecoff_sizeof_headers PARAMS ((bfd *abfd, boolean reloc)); -/* ecoff_bfd_get_relocated_section_contents defined by backend. */ -/* ecoff_bfd_relax_section defined by backend. */ -extern struct bfd_link_hash_table *_bfd_ecoff_bfd_link_hash_table_create - PARAMS ((bfd *)); -extern boolean _bfd_ecoff_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean _bfd_ecoff_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -/* Hook functions for the generic COFF section reading code. */ - -extern PTR _bfd_ecoff_mkobject_hook PARAMS ((bfd *, PTR filehdr, PTR aouthdr)); -extern asection *_bfd_ecoff_make_section_hook PARAMS ((bfd *abfd, char *name)); -#define _bfd_ecoff_set_alignment_hook \ - ((void (*) PARAMS ((bfd *, asection *, PTR))) bfd_void) -extern boolean _bfd_ecoff_set_arch_mach_hook PARAMS ((bfd *abfd, PTR filehdr)); -extern flagword _bfd_ecoff_styp_to_sec_flags PARAMS ((bfd *abfd, PTR hdr)); -extern boolean _bfd_ecoff_slurp_symbol_table PARAMS ((bfd *abfd)); diff --git a/gnu/usr.bin/gdb/bfd/libelf.h b/gnu/usr.bin/gdb/bfd/libelf.h deleted file mode 100644 index cc6d8b8..0000000 --- a/gnu/usr.bin/gdb/bfd/libelf.h +++ /dev/null @@ -1,633 +0,0 @@ -/* BFD back-end data structures for ELF files. - Copyright (C) 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _LIBELF_H_ -#define _LIBELF_H_ 1 - -#include "elf/common.h" -#include "elf/internal.h" -#include "elf/external.h" -#include "bfdlink.h" - -/* If size isn't specified as 64 or 32, NAME macro should fail. */ -#ifndef NAME -#if ARCH_SIZE==64 -#define NAME(x,y) CAT4(x,64,_,y) -#endif -#if ARCH_SIZE==32 -#define NAME(x,y) CAT4(x,32,_,y) -#endif -#endif - -#ifndef NAME -#define NAME(x,y) CAT4(x,NOSIZE,_,y) -#endif - -#define ElfNAME(X) NAME(Elf,X) -#define elfNAME(X) NAME(elf,X) - -/* Information held for an ELF symbol. The first field is the - corresponding asymbol. Every symbol is an ELF file is actually a - pointer to this structure, although it is often handled as a - pointer to an asymbol. */ - -typedef struct -{ - /* The BFD symbol. */ - asymbol symbol; - /* ELF symbol information. */ - Elf_Internal_Sym internal_elf_sym; - /* Backend specific information. */ - union - { - unsigned int hppa_arg_reloc; - PTR mips_extr; - PTR any; - } - tc_data; -} elf_symbol_type; - -/* ELF linker hash table entries. */ - -struct elf_link_hash_entry -{ - struct bfd_link_hash_entry root; - - /* Symbol index in output file. This is initialized to -1. It is - set to -2 if the symbol is used by a reloc. */ - long indx; - - /* Symbol size. */ - bfd_size_type size; - - /* Symbol alignment (common symbols only). */ - bfd_size_type align; - - /* Symbol index as a dynamic symbol. Initialized to -1, and remains - -1 if this is not a dynamic symbol. */ - long dynindx; - - /* String table index in .dynstr if this is a dynamic symbol. */ - unsigned long dynstr_index; - - /* If this is a weak defined symbol from a dynamic object, this - field points to a defined symbol with the same value, if there is - one. Otherwise it is NULL. */ - struct elf_link_hash_entry *weakdef; - - /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */ - char type; - - /* Some flags; legal values follow. */ - unsigned char elf_link_hash_flags; - /* Symbol is referenced by a non-shared object. */ -#define ELF_LINK_HASH_REF_REGULAR 01 - /* Symbol is defined by a non-shared object. */ -#define ELF_LINK_HASH_DEF_REGULAR 02 - /* Symbol is referenced by a shared object. */ -#define ELF_LINK_HASH_REF_DYNAMIC 04 - /* Symbol is defined by a shared object. */ -#define ELF_LINK_HASH_DEF_DYNAMIC 010 - /* Symbol is referenced by two or more shared objects. */ -#define ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE 020 - /* Symbol is defined by two or more shared objects. */ -#define ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE 040 - /* Dynamic symbol has been adjustd. */ -#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 0100 - /* Symbol is defined as weak. */ -#define ELF_LINK_HASH_DEFINED_WEAK 0200 -}; - -/* ELF linker hash table. */ - -struct elf_link_hash_table -{ - struct bfd_link_hash_table root; - /* The first dynamic object found during a link. We create several - special input sections when linking against dynamic objects, and - we simply attach them to the first one found. */ - bfd *dynobj; - /* The number of symbols found in the link which must be put into - the .dynsym section. */ - size_t dynsymcount; - /* The string table of dynamic symbols, which becomes the .dynstr - section. */ - struct strtab *dynstr; - /* The number of buckets in the hash table in the .hash section. - This is based on the number of dynamic symbols. */ - size_t bucketcount; -}; - -/* Look up an entry in an ELF linker hash table. */ - -#define elf_link_hash_lookup(table, string, create, copy, follow) \ - ((struct elf_link_hash_entry *) \ - bfd_link_hash_lookup (&(table)->root, (string), (create), \ - (copy), (follow))) - -/* Traverse an ELF linker hash table. */ - -#define elf_link_hash_traverse(table, func, info) \ - (bfd_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \ - (info))) - -/* Get the ELF linker hash table from a link_info structure. */ - -#define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash)) - -/* Constant information held for an ELF backend. */ - -struct elf_backend_data -{ - /* Whether the backend uses REL or RELA relocations. FIXME: some - ELF backends use both. When we need to support one, this whole - approach will need to be changed. */ - int use_rela_p; - - /* Whether this backend is 64 bits or not. FIXME: Who cares? */ - int elf_64_p; - - /* The architecture for this backend. */ - enum bfd_architecture arch; - - /* The ELF machine code (EM_xxxx) for this backend. */ - int elf_machine_code; - - /* The maximum page size for this backend. */ - bfd_vma maxpagesize; - - /* This is true if the linker should act like collect and gather - global constructors and destructors by name. This is true for - MIPS ELF because the Irix 5 tools can not handle the .init - section. */ - boolean collect; - - /* A function to translate an ELF RELA relocation to a BFD arelent - structure. */ - void (*elf_info_to_howto) PARAMS ((bfd *, arelent *, - Elf_Internal_Rela *)); - - /* A function to translate an ELF REL relocation to a BFD arelent - structure. */ - void (*elf_info_to_howto_rel) PARAMS ((bfd *, arelent *, - Elf_Internal_Rel *)); - - /* A function to determine whether a symbol is global when - partitioning the symbol table into local and global symbols. - This should be NULL for most targets, in which case the correct - thing will be done. MIPS ELF, at least on the Irix 5, has - special requirements. */ - boolean (*elf_backend_sym_is_global) PARAMS ((bfd *, asymbol *)); - - /* The remaining functions are hooks which are called only if they - are not NULL. */ - - /* A function to permit a backend specific check on whether a - particular BFD format is relevant for an object file, and to - permit the backend to set any global information it wishes. When - this is called elf_elfheader is set, but anything else should be - used with caution. If this returns false, the check_format - routine will return a bfd_error_wrong_format error. */ - boolean (*elf_backend_object_p) PARAMS ((bfd *)); - - /* A function to do additional symbol processing when reading the - ELF symbol table. This is where any processor-specific special - section indices are handled. */ - void (*elf_backend_symbol_processing) PARAMS ((bfd *, asymbol *)); - - /* A function to do additional symbol processing after reading the - entire ELF symbol table. */ - boolean (*elf_backend_symbol_table_processing) PARAMS ((bfd *, - elf_symbol_type *, - int)); - - /* A function to do additional processing on the ELF section header - just before writing it out. This is used to set the flags and - type fields for some sections, or to actually write out data for - unusual sections. */ - boolean (*elf_backend_section_processing) PARAMS ((bfd *, - Elf32_Internal_Shdr *)); - - /* A function to handle unusual section types when creating BFD - sections from ELF sections. */ - boolean (*elf_backend_section_from_shdr) PARAMS ((bfd *, - Elf32_Internal_Shdr *, - char *)); - - /* A function to set up the ELF section header for a BFD section in - preparation for writing it out. This is where the flags and type - fields are set for unusual sections. */ - boolean (*elf_backend_fake_sections) PARAMS ((bfd *, Elf32_Internal_Shdr *, - asection *)); - - /* A function to get the ELF section index for a BFD section. If - this returns true, the section was found. If it is a normal ELF - section, *RETVAL should be left unchanged. If it is not a normal - ELF section *RETVAL should be set to the SHN_xxxx index. */ - boolean (*elf_backend_section_from_bfd_section) - PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *, int *retval)); - - /* If this field is not NULL, it is called by the add_symbols phase - of a link just before adding a symbol to the global linker hash - table. It may modify any of the fields as it wishes. If *NAME - is set to NULL, the symbol will be skipped rather than being - added to the hash table. This function is responsible for - handling all processor dependent symbol bindings and section - indices, and must set at least *FLAGS and *SEC for each processor - dependent case; failure to do so will cause a link error. */ - boolean (*elf_add_symbol_hook) - PARAMS ((bfd *abfd, struct bfd_link_info *info, - const Elf_Internal_Sym *, const char **name, - flagword *flags, asection **sec, bfd_vma *value)); - - /* If this field is not NULL, it is called by the elf_link_output_sym - phase of a link for each symbol which will appear in the object file. */ - boolean (*elf_backend_link_output_symbol_hook) - PARAMS ((bfd *, struct bfd_link_info *info, const char *, - Elf_Internal_Sym *, asection *)); - - /* The CREATE_DYNAMIC_SECTIONS function is called by the ELF backend - linker the first time it encounters a dynamic object in the link. - This function must create any sections required for dynamic - linking. The ABFD argument is a dynamic object. The .interp, - .dynamic, .dynsym, .dynstr, and .hash functions have already been - created, and this function may modify the section flags if - desired. This function will normally create the .got and .plt - sections, but different backends have different requirements. */ - boolean (*elf_backend_create_dynamic_sections) - PARAMS ((bfd *abfd, struct bfd_link_info *info)); - - /* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend - linker for every symbol which is defined by a dynamic object and - referenced by a regular object. This is called after all the - input files have been seen, but before the SIZE_DYNAMIC_SECTIONS - function has been called. The hash table entry should be - bfd_link_hash_defined, and it should be defined in a section from - a dynamic object. Dynamic object sections are not included in - the final link, and this function is responsible for changing the - value to something which the rest of the link can deal with. - This will normally involve adding an entry to the .plt or .got or - some such section, and setting the symbol to point to that. */ - boolean (*elf_backend_adjust_dynamic_symbol) - PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h)); - - /* The SIZE_DYNAMIC_SECTIONS function is called by the ELF backend - linker after all the linker input files have been seen but before - the sections sizes have been set. This is called after - ADJUST_DYNAMIC_SYMBOL has been called on all appropriate symbols. - It is only called when linking against a dynamic object. It must - set the sizes of the dynamic sections, and may fill in their - contents as well. The generic ELF linker can handle the .dynsym, - .dynstr and .hash sections. This function must handle the - .interp section and any sections created by the - CREATE_DYNAMIC_SECTIONS entry point. */ - boolean (*elf_backend_size_dynamic_sections) - PARAMS ((bfd *output_bfd, struct bfd_link_info *info)); - - /* The RELOCATE_SECTION function is called by the ELF backend linker - to handle the relocations for a section. - - The relocs are always passed as Rela structures; if the section - actually uses Rel structures, the r_addend field will always be - zero. - - This function is responsible for adjust the section contents as - necessary, and (if using Rela relocs and generating a - relocateable output file) adjusting the reloc addend as - necessary. - - This function does not have to worry about setting the reloc - address or the reloc symbol index. - - LOCAL_SYMS is a pointer to the swapped in local symbols. - - LOCAL_SECTIONS is an array giving the section in the input file - corresponding to the st_shndx field of each local symbol. - - The global hash table entry for the global symbols can be found - via elf_sym_hashes (input_bfd). - - When generating relocateable output, this function must handle - STB_LOCAL/STT_SECTION symbols specially. The output symbol is - going to be the section symbol corresponding to the output - section, which means that the addend must be adjusted - accordingly. */ - boolean (*elf_backend_relocate_section) - PARAMS ((bfd *output_bfd, struct bfd_link_info *info, - bfd *input_bfd, asection *input_section, bfd_byte *contents, - Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms, - asection **local_sections, char *output_names)); - - /* The FINISH_DYNAMIC_SYMBOL function is called by the ELF backend - linker just before it writes a symbol out to the .dynsym section. - The processor backend may make any required adjustment to the - symbol. It may also take the opportunity to set contents of the - dynamic sections. Note that FINISH_DYNAMIC_SYMBOL is called on - all .dynsym symbols, while ADJUST_DYNAMIC_SYMBOL is only called - on those symbols which are defined by a dynamic object. */ - boolean (*elf_backend_finish_dynamic_symbol) - PARAMS ((bfd *output_bfd, struct bfd_link_info *info, - struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)); - - /* The FINISH_DYNAMIC_SECTIONS function is called by the ELF backend - linker just before it writes all the dynamic sections out to the - output file. The FINISH_DYNAMIC_SYMBOL will have been called on - all dynamic symbols. */ - boolean (*elf_backend_finish_dynamic_sections) - PARAMS ((bfd *output_bfd, struct bfd_link_info *info)); - - /* A function to do any beginning processing needed for the ELF file - before building the ELF headers and computing file positions. */ - void (*elf_backend_begin_write_processing) - PARAMS ((bfd *, struct bfd_link_info *)); - - /* A function to do any final processing needed for the ELF file - before writing it out. */ - void (*elf_backend_final_write_processing) - PARAMS ((bfd *, struct bfd_link_info *)); - - /* The swapping table to use when dealing with ECOFF information. - Used for the MIPS ELF .mdebug section. */ - const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap; -}; - -struct elf_sym_extra -{ - int elf_sym_num; /* sym# after locals/globals are reordered */ -}; - -typedef struct elf_sym_extra Elf_Sym_Extra; - -/* Information stored for each BFD section in an ELF file. This - structure is allocated by elf_new_section_hook. */ - -struct bfd_elf_section_data { - /* The ELF header for this section. */ - Elf_Internal_Shdr this_hdr; - /* The ELF header for the reloc section associated with this - section, if any. */ - Elf_Internal_Shdr rel_hdr; - /* The ELF section number of this section. Only used for an output - file. */ - int this_idx; - /* The ELF section number of the reloc section associated with this - section, if any. Only used for an output file. */ - int rel_idx; - /* Used by the backend linker to store the symbol hash table entries - associated with relocs against global symbols. */ - struct elf_link_hash_entry **rel_hashes; - /* A pointer to the unswapped external relocs; this may be NULL. */ - PTR relocs; -}; - -#define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd) - -#define get_elf_backend_data(abfd) \ - ((struct elf_backend_data *) (abfd)->xvec->backend_data) - -struct strtab -{ - char *tab; - int nentries; - int length; -}; - -/* Some private data is stashed away for future use using the tdata pointer - in the bfd structure. */ - -struct elf_obj_tdata -{ - Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */ - Elf_Internal_Shdr **elf_sect_ptr; - Elf_Internal_Phdr *phdr; - struct strtab *strtab_ptr; - int num_locals; - int num_globals; - Elf_Sym_Extra *sym_extra; - asymbol **section_syms; /* STT_SECTION symbols for each section */ - int num_section_syms; /* number of section_syms allocated */ - Elf_Internal_Shdr symtab_hdr; - Elf_Internal_Shdr shstrtab_hdr; - Elf_Internal_Shdr strtab_hdr; - Elf_Internal_Shdr dynsymtab_hdr; - Elf_Internal_Shdr dynstrtab_hdr; - int symtab_section, shstrtab_section, strtab_section, dynsymtab_section; - file_ptr next_file_pos; - void *prstatus; /* The raw /proc prstatus structure */ - void *prpsinfo; /* The raw /proc prpsinfo structure */ - bfd_vma gp; /* The gp value (MIPS only, for now) */ - int gp_size; /* The gp size (MIPS only, for now) */ - - /* A mapping from external symbols to entries in the linker hash - table, used when linking. This is indexed by the symbol index - minus the sh_info field of the symbol table header. */ - struct elf_link_hash_entry **sym_hashes; - - /* The linker ELF emulation code needs to let the backend ELF linker - know what filename should be used for a dynamic object if the - dynamic object is found using a search. This field is used to - hold that information. */ - const char *dt_needed_name; - - /* Irix 5 often screws up the symbol table, sorting local symbols - after global symbols. This flag is set if the symbol table in - this BFD appears to be screwed up. If it is, we ignore the - sh_info field in the symbol table header, and always read all the - symbols. */ - boolean bad_symtab; -}; - -#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) -#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) -#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) -#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) -#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) -#define elf_dynsymtab(bfd) (elf_tdata(bfd) -> dynsymtab_section) -#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals) -#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals) -#define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra) -#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms) -#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms) -#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) -#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) -#define elf_gp(bfd) (elf_tdata(bfd) -> gp) -#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size) -#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes) -#define elf_dt_needed_name(bfd) (elf_tdata(bfd) -> dt_needed_name) -#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) - -extern char * elf_string_from_elf_section PARAMS ((bfd *, unsigned, unsigned)); -extern char * elf_get_str_section PARAMS ((bfd *, unsigned)); - -#define bfd_elf32_mkobject bfd_elf_mkobject -#define bfd_elf64_mkobject bfd_elf_mkobject -#define elf_mkobject bfd_elf_mkobject - -extern unsigned long bfd_elf_hash PARAMS ((CONST unsigned char *)); - -extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *, - arelent *, - asymbol *, - PTR, - asection *, - bfd *, - char **)); -extern boolean bfd_elf_mkobject PARAMS ((bfd *)); -extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *)); -extern boolean _bfd_elf_make_section_from_shdr - PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name)); -extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create - PARAMS ((bfd *)); -extern boolean _bfd_elf_link_hash_table_init - PARAMS ((struct elf_link_hash_table *, bfd *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -extern boolean bfd_elf32_write_object_contents PARAMS ((bfd *)); -extern boolean bfd_elf64_write_object_contents PARAMS ((bfd *)); - -extern const bfd_target *bfd_elf32_object_p PARAMS ((bfd *)); -extern const bfd_target *bfd_elf32_core_file_p PARAMS ((bfd *)); -extern char *bfd_elf32_core_file_failing_command PARAMS ((bfd *)); -extern int bfd_elf32_core_file_failing_signal PARAMS ((bfd *)); -extern boolean bfd_elf32_core_file_matches_executable_p PARAMS ((bfd *, - bfd *)); -extern boolean bfd_elf32_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, - bfd_size_type)); - -extern long bfd_elf32_get_symtab_upper_bound PARAMS ((bfd *)); -extern long bfd_elf32_get_symtab PARAMS ((bfd *, asymbol **)); -extern long bfd_elf32_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); -extern long bfd_elf32_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); -extern long bfd_elf32_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern long bfd_elf32_canonicalize_reloc PARAMS ((bfd *, sec_ptr, - arelent **, asymbol **)); -extern asymbol *bfd_elf32_make_empty_symbol PARAMS ((bfd *)); -extern void bfd_elf32_print_symbol PARAMS ((bfd *, PTR, asymbol *, - bfd_print_symbol_type)); -extern void bfd_elf32_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *)); -extern alent *bfd_elf32_get_lineno PARAMS ((bfd *, asymbol *)); -extern boolean bfd_elf32_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); -extern boolean bfd_elf32_find_nearest_line PARAMS ((bfd *, asection *, - asymbol **, - bfd_vma, CONST char **, - CONST char **, - unsigned int *)); -extern int bfd_elf32_sizeof_headers PARAMS ((bfd *, boolean)); -extern void bfd_elf32__write_relocs PARAMS ((bfd *, asection *, PTR)); -extern boolean bfd_elf32_new_section_hook PARAMS ((bfd *, asection *)); -extern boolean bfd_elf32_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_elf32_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -extern void bfd_elf32_swap_symbol_in - PARAMS ((bfd *, Elf32_External_Sym *, Elf_Internal_Sym *)); -extern void bfd_elf32_swap_symbol_out - PARAMS ((bfd *, Elf_Internal_Sym *, Elf32_External_Sym *)); -extern void bfd_elf32_swap_reloc_in - PARAMS ((bfd *, Elf32_External_Rel *, Elf_Internal_Rel *)); -extern void bfd_elf32_swap_reloc_out - PARAMS ((bfd *, Elf_Internal_Rel *, Elf32_External_Rel *)); -extern void bfd_elf32_swap_reloca_in - PARAMS ((bfd *, Elf32_External_Rela *, Elf_Internal_Rela *)); -extern void bfd_elf32_swap_reloca_out - PARAMS ((bfd *, Elf_Internal_Rela *, Elf32_External_Rela *)); -extern void bfd_elf32_swap_dyn_in - PARAMS ((bfd *, const Elf32_External_Dyn *, Elf_Internal_Dyn *)); -extern void bfd_elf32_swap_dyn_out - PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf32_External_Dyn *)); -extern boolean bfd_elf32_add_dynamic_entry - PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); - -/* If the target doesn't have reloc handling written yet: */ -extern void bfd_elf32_no_info_to_howto PARAMS ((bfd *, arelent *, - Elf32_Internal_Rela *)); - -extern const bfd_target *bfd_elf64_object_p PARAMS ((bfd *)); -extern const bfd_target *bfd_elf64_core_file_p PARAMS ((bfd *)); -extern char *bfd_elf64_core_file_failing_command PARAMS ((bfd *)); -extern int bfd_elf64_core_file_failing_signal PARAMS ((bfd *)); -extern boolean bfd_elf64_core_file_matches_executable_p PARAMS ((bfd *, - bfd *)); -extern boolean bfd_elf64_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, - file_ptr, - bfd_size_type)); - -extern long bfd_elf64_get_symtab_upper_bound PARAMS ((bfd *)); -extern long bfd_elf64_get_symtab PARAMS ((bfd *, asymbol **)); -extern long bfd_elf64_get_dynamic_symtab_upper_bound PARAMS ((bfd *)); -extern long bfd_elf64_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **)); -extern long bfd_elf64_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); -extern long bfd_elf64_canonicalize_reloc PARAMS ((bfd *, sec_ptr, - arelent **, asymbol **)); -extern asymbol *bfd_elf64_make_empty_symbol PARAMS ((bfd *)); -extern void bfd_elf64_print_symbol PARAMS ((bfd *, PTR, asymbol *, - bfd_print_symbol_type)); -extern void bfd_elf64_get_symbol_info PARAMS ((bfd *, asymbol *, - symbol_info *)); -extern alent *bfd_elf64_get_lineno PARAMS ((bfd *, asymbol *)); -extern boolean bfd_elf64_set_arch_mach PARAMS ((bfd *, enum bfd_architecture, - unsigned long)); -extern boolean bfd_elf64_find_nearest_line PARAMS ((bfd *, asection *, - asymbol **, - bfd_vma, CONST char **, - CONST char **, - unsigned int *)); -extern int bfd_elf64_sizeof_headers PARAMS ((bfd *, boolean)); -extern void bfd_elf64__write_relocs PARAMS ((bfd *, asection *, PTR)); -extern boolean bfd_elf64_new_section_hook PARAMS ((bfd *, asection *)); -extern boolean bfd_elf64_bfd_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *)); -extern boolean bfd_elf64_bfd_final_link - PARAMS ((bfd *, struct bfd_link_info *)); - -extern void bfd_elf64_swap_symbol_in - PARAMS ((bfd *, Elf64_External_Sym *, Elf_Internal_Sym *)); -extern void bfd_elf64_swap_symbol_out - PARAMS ((bfd *, Elf_Internal_Sym *, Elf64_External_Sym *)); -extern void bfd_elf64_swap_reloc_in - PARAMS ((bfd *, Elf64_External_Rel *, Elf_Internal_Rel *)); -extern void bfd_elf64_swap_reloc_out - PARAMS ((bfd *, Elf_Internal_Rel *, Elf64_External_Rel *)); -extern void bfd_elf64_swap_reloca_in - PARAMS ((bfd *, Elf64_External_Rela *, Elf_Internal_Rela *)); -extern void bfd_elf64_swap_reloca_out - PARAMS ((bfd *, Elf_Internal_Rela *, Elf64_External_Rela *)); -extern void bfd_elf64_swap_dyn_in - PARAMS ((bfd *, const Elf64_External_Dyn *, Elf_Internal_Dyn *)); -extern void bfd_elf64_swap_dyn_out - PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf64_External_Dyn *)); -extern boolean bfd_elf64_add_dynamic_entry - PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); - -/* If the target doesn't have reloc handling written yet: */ -extern void bfd_elf64_no_info_to_howto PARAMS ((bfd *, arelent *, - Elf64_Internal_Rela *)); - -#endif /* _LIBELF_H_ */ diff --git a/gnu/usr.bin/gdb/bfd/linker.c b/gnu/usr.bin/gdb/bfd/linker.c deleted file mode 100644 index 63391a2..0000000 --- a/gnu/usr.bin/gdb/bfd/linker.c +++ /dev/null @@ -1,2442 +0,0 @@ -/* linker.c -- BFD linker routines - Copyright (C) 1993, 94 Free Software Foundation, Inc. - Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "bfdlink.h" -#include "genlink.h" - -/* -SECTION - Linker Functions - -@cindex Linker - The linker uses three special entry points in the BFD target - vector. It is not necessary to write special routines for - these entry points when creating a new BFD back end, since - generic versions are provided. However, writing them can - speed up linking and make it use significantly less runtime - memory. - - The first routine creates a hash table used by the other - routines. The second routine adds the symbols from an object - file to the hash table. The third routine takes all the - object files and links them together to create the output - file. These routines are designed so that the linker proper - does not need to know anything about the symbols in the object - files that it is linking. The linker merely arranges the - sections as directed by the linker script and lets BFD handle - the details of symbols and relocs. - - The second routine and third routines are passed a pointer to - a <<struct bfd_link_info>> structure (defined in - <<bfdlink.h>>) which holds information relevant to the link, - including the linker hash table (which was created by the - first routine) and a set of callback functions to the linker - proper. - - The generic linker routines are in <<linker.c>>, and use the - header file <<genlink.h>>. As of this writing, the only back - ends which have implemented versions of these routines are - a.out (in <<aoutx.h>>) and ECOFF (in <<ecoff.c>>). The a.out - routines are used as examples throughout this section. - -@menu -@* Creating a Linker Hash Table:: -@* Adding Symbols to the Hash Table:: -@* Performing the Final Link:: -@end menu - -INODE -Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions -SUBSECTION - Creating a linker hash table - -@cindex _bfd_link_hash_table_create in target vector -@cindex target vector (_bfd_link_hash_table_create) - The linker routines must create a hash table, which must be - derived from <<struct bfd_link_hash_table>> described in - <<bfdlink.c>>. @xref{Hash Tables} for information on how to - create a derived hash table. This entry point is called using - the target vector of the linker output file. - - The <<_bfd_link_hash_table_create>> entry point must allocate - and initialize an instance of the desired hash table. If the - back end does not require any additional information to be - stored with the entries in the hash table, the entry point may - simply create a <<struct bfd_link_hash_table>>. Most likely, - however, some additional information will be needed. - - For example, with each entry in the hash table the a.out - linker keeps the index the symbol has in the final output file - (this index number is used so that when doing a relocateable - link the symbol index used in the output file can be quickly - filled in when copying over a reloc). The a.out linker code - defines the required structures and functions for a hash table - derived from <<struct bfd_link_hash_table>>. The a.out linker - hash table is created by the function - <<NAME(aout,link_hash_table_create)>>; it simply allocates - space for the hash table, initializes it, and returns a - pointer to it. - - When writing the linker routines for a new back end, you will - generally not know exactly which fields will be required until - you have finished. You should simply create a new hash table - which defines no additional fields, and then simply add fields - as they become necessary. - -INODE -Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions -SUBSECTION - Adding symbols to the hash table - -@cindex _bfd_link_add_symbols in target vector -@cindex target vector (_bfd_link_add_symbols) - The linker proper will call the <<_bfd_link_add_symbols>> - entry point for each object file or archive which is to be - linked (typically these are the files named on the command - line, but some may also come from the linker script). The - entry point is responsible for examining the file. For an - object file, BFD must add any relevant symbol information to - the hash table. For an archive, BFD must determine which - elements of the archive should be used and adding them to the - link. - - The a.out version of this entry point is - <<NAME(aout,link_add_symbols)>>. - -@menu -@* Differing file formats:: -@* Adding symbols from an object file:: -@* Adding symbols from an archive:: -@end menu - -INODE -Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table -SUBSUBSECTION - Differing file formats - - Normally all the files involved in a link will be of the same - format, but it is also possible to link together different - format object files, and the back end must support that. The - <<_bfd_link_add_symbols>> entry point is called via the target - vector of the file to be added. This has an important - consequence: the function may not assume that the hash table - is the type created by the corresponding - <<_bfd_link_hash_table_create>> vector. All the - <<_bfd_link_add_symbols>> function can assume about the hash - table is that it is derived from <<struct - bfd_link_hash_table>>. - - Sometimes the <<_bfd_link_add_symbols>> function must store - some information in the hash table entry to be used by the - <<_bfd_final_link>> function. In such a case the <<creator>> - field of the hash table must be checked to make sure that the - hash table was created by an object file of the same format. - - The <<_bfd_final_link>> routine must be prepared to handle a - hash entry without any extra information added by the - <<_bfd_link_add_symbols>> function. A hash entry without - extra information will also occur when the linker script - directs the linker to create a symbol. Note that, regardless - of how a hash table entry is added, all the fields will be - initialized to some sort of null value by the hash table entry - initialization function. - - See <<ecoff_link_add_externals>> for an example of how to - check the <<creator>> field before saving information (in this - case, the ECOFF external symbol debugging information) in a - hash table entry. - -INODE -Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an object file - - When the <<_bfd_link_add_symbols>> routine is passed an object - file, it must add all externally visible symbols in that - object file to the hash table. The actual work of adding the - symbol to the hash table is normally handled by the function - <<_bfd_generic_link_add_one_symbol>>. The - <<_bfd_link_add_symbols>> routine is responsible for reading - all the symbols from the object file and passing the correct - information to <<_bfd_generic_link_add_one_symbol>>. - - The <<_bfd_link_add_symbols>> routine should not use - <<bfd_canonicalize_symtab>> to read the symbols. The point of - providing this routine is to avoid the overhead of converting - the symbols into generic <<asymbol>> structures. - -@findex _bfd_generic_link_add_one_symbol - <<_bfd_generic_link_add_one_symbol>> handles the details of - combining common symbols, warning about multiple definitions, - and so forth. It takes arguments which describe the symbol to - add, notably symbol flags, a section, and an offset. The - symbol flags include such things as <<BSF_WEAK>> or - <<BSF_INDIRECT>>. The section is a section in the object - file, or something like <<bfd_und_section_ptr>> for an undefined - symbol or <<bfd_com_section_ptr>> for a common symbol. - - If the <<_bfd_final_link>> routine is also going to need to - read the symbol information, the <<_bfd_link_add_symbols>> - routine should save it somewhere attached to the object file - BFD. However, the information should only be saved if the - <<keep_memory>> field of the <<info>> argument is true, so - that the <<-no-keep-memory>> linker switch is effective. - - The a.out function which adds symbols from an object file is - <<aout_link_add_object_symbols>>, and most of the interesting - work is in <<aout_link_add_symbols>>. The latter saves - pointers to the hash tables entries created by - <<_bfd_generic_link_add_one_symbol>> indexed by symbol number, - so that the <<_bfd_final_link>> routine does not have to call - the hash table lookup routine to locate the entry. - -INODE -Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table -SUBSUBSECTION - Adding symbols from an archive - - When the <<_bfd_link_add_symbols>> routine is passed an - archive, it must look through the symbols defined by the - archive and decide which elements of the archive should be - included in the link. For each such element it must call the - <<add_archive_element>> linker callback, and it must add the - symbols from the object file to the linker hash table. - -@findex _bfd_generic_link_add_archive_symbols - In most cases the work of looking through the symbols in the - archive should be done by the - <<_bfd_generic_link_add_archive_symbols>> function. This - function builds a hash table from the archive symbol table and - looks through the list of undefined symbols to see which - elements should be included. - <<_bfd_generic_link_add_archive_symbols>> is passed a function - to call to make the final decision about adding an archive - element to the link and to do the actual work of adding the - symbols to the linker hash table. - - The function passed to - <<_bfd_generic_link_add_archive_symbols>> must read the - symbols of the archive element and decide whether the archive - element should be included in the link. If the element is to - be included, the <<add_archive_element>> linker callback - routine must be called with the element as an argument, and - the elements symbols must be added to the linker hash table - just as though the element had itself been passed to the - <<_bfd_link_add_symbols>> function. - - When the a.out <<_bfd_link_add_symbols>> function receives an - archive, it calls <<_bfd_generic_link_add_archive_symbols>> - passing <<aout_link_check_archive_element>> as the function - argument. <<aout_link_check_archive_element>> calls - <<aout_link_check_ar_symbols>>. If the latter decides to add - the element (an element is only added if it provides a real, - non-common, definition for a previously undefined or common - symbol) it calls the <<add_archive_element>> callback and then - <<aout_link_check_archive_element>> calls - <<aout_link_add_symbols>> to actually add the symbols to the - linker hash table. - - The ECOFF back end is unusual in that it does not normally - call <<_bfd_generic_link_add_archive_symbols>>, because ECOFF - archives already contain a hash table of symbols. The ECOFF - back end searches the archive itself to avoid the overhead of - creating a new hash table. - -INODE -Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions -SUBSECTION - Performing the final link - -@cindex _bfd_link_final_link in target vector -@cindex target vector (_bfd_final_link) - When all the input files have been processed, the linker calls - the <<_bfd_final_link>> entry point of the output BFD. This - routine is responsible for producing the final output file, - which has several aspects. It must relocate the contents of - the input sections and copy the data into the output sections. - It must build an output symbol table including any local - symbols from the input files and the global symbols from the - hash table. When producing relocateable output, it must - modify the input relocs and write them into the output file. - There may also be object format dependent work to be done. - - The linker will also call the <<write_object_contents>> entry - point when the BFD is closed. The two entry points must work - together in order to produce the correct output file. - - The details of how this works are inevitably dependent upon - the specific object file format. The a.out - <<_bfd_final_link>> routine is <<NAME(aout,final_link)>>. - -@menu -@* Information provided by the linker:: -@* Relocating the section contents:: -@* Writing the symbol table:: -@end menu - -INODE -Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link -SUBSUBSECTION - Information provided by the linker - - Before the linker calls the <<_bfd_final_link>> entry point, - it sets up some data structures for the function to use. - - The <<input_bfds>> field of the <<bfd_link_info>> structure - will point to a list of all the input files included in the - link. These files are linked through the <<link_next>> field - of the <<bfd>> structure. - - Each section in the output file will have a list of - <<link_order>> structures attached to the <<link_order_head>> - field (the <<link_order>> structure is defined in - <<bfdlink.h>>). These structures describe how to create the - contents of the output section in terms of the contents of - various input sections, fill constants, and, eventually, other - types of information. They also describe relocs that must be - created by the BFD backend, but do not correspond to any input - file; this is used to support -Ur, which builds constructors - while generating a relocateable object file. - -INODE -Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link -SUBSUBSECTION - Relocating the section contents - - The <<_bfd_final_link>> function should look through the - <<link_order>> structures attached to each section of the - output file. Each <<link_order>> structure should either be - handled specially, or it should be passed to the function - <<_bfd_default_link_order>> which will do the right thing - (<<_bfd_default_link_order>> is defined in <<linker.c>>). - - For efficiency, a <<link_order>> of type - <<bfd_indirect_link_order>> whose associated section belongs - to a BFD of the same format as the output BFD must be handled - specially. This type of <<link_order>> describes part of an - output section in terms of a section belonging to one of the - input files. The <<_bfd_final_link>> function should read the - contents of the section and any associated relocs, apply the - relocs to the section contents, and write out the modified - section contents. If performing a relocateable link, the - relocs themselves must also be modified and written out. - -@findex _bfd_relocate_contents -@findex _bfd_final_link_relocate - The functions <<_bfd_relocate_contents>> and - <<_bfd_final_link_relocate>> provide some general support for - performing the actual relocations, notably overflow checking. - Their arguments include information about the symbol the - relocation is against and a <<reloc_howto_type>> argument - which describes the relocation to perform. These functions - are defined in <<reloc.c>>. - - The a.out function which handles reading, relocating, and - writing section contents is <<aout_link_input_section>>. The - actual relocation is done in <<aout_link_input_section_std>> - and <<aout_link_input_section_ext>>. - -INODE -Writing the symbol table, , Relocating the section contents, Performing the Final Link -SUBSUBSECTION - Writing the symbol table - - The <<_bfd_final_link>> function must gather all the symbols - in the input files and write them out. It must also write out - all the symbols in the global hash table. This must be - controlled by the <<strip>> and <<discard>> fields of the - <<bfd_link_info>> structure. - - The local symbols of the input files will not have been - entered into the linker hash table. The <<_bfd_final_link>> - routine must consider each input file and include the symbols - in the output file. It may be convenient to do this when - looking through the <<link_order>> structures, or it may be - done by stepping through the <<input_bfds>> list. - - The <<_bfd_final_link>> routine must also traverse the global - hash table to gather all the externally visible symbols. It - is possible that most of the externally visible symbols may be - written out when considering the symbols of each input file, - but it is still necessary to traverse the hash table since the - linker script may have defined some symbols that are not in - any of the input files. The <<written>> field in the - <<bfd_link_hash_entry>> structure may be used to determine - which entries in the hash table have not already been written - out. - - The <<strip>> field of the <<bfd_link_info>> structure - controls which symbols are written out. The possible values - are listed in <<bfdlink.h>>. If the value is <<strip_some>>, - then the <<keep_hash>> field of the <<bfd_link_info>> - structure is a hash table of symbols to keep; each symbol - should be looked up in this hash table, and only symbols which - are present should be included in the output file. - - If the <<strip>> field of the <<bfd_link_info>> structure - permits local symbols to be written out, the <<discard>> field - is used to further controls which local symbols are included - in the output file. If the value is <<discard_l>>, then all - local symbols which begin with a certain prefix are discarded; - this prefix is described by the <<lprefix>> and - <<lprefix_len>> fields of the <<bfd_link_info>> structure. - - The a.out backend handles symbols by calling - <<aout_link_write_symbols>> on each input BFD and then - traversing the global hash table with the function - <<aout_link_write_other_symbol>>. It builds a string table - while writing out the symbols, which is written to the output - file at the end of <<NAME(aout,final_link)>>. -*/ - -static struct bfd_hash_entry *generic_link_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, - const char *)); -static boolean generic_link_read_symbols - PARAMS ((bfd *)); -static boolean generic_link_add_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); -static boolean generic_link_add_object_symbols - PARAMS ((bfd *, struct bfd_link_info *, boolean collect)); -static boolean generic_link_check_archive_element_no_collect - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean generic_link_check_archive_element_collect - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded)); -static boolean generic_link_check_archive_element - PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded, boolean collect)); -static boolean generic_link_add_symbol_list - PARAMS ((bfd *, struct bfd_link_info *, bfd_size_type count, asymbol **, - boolean collect)); -static boolean generic_add_output_symbol - PARAMS ((bfd *, size_t *psymalloc, asymbol *)); -static boolean default_fill_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); -static boolean default_indirect_link_order - PARAMS ((bfd *, struct bfd_link_info *, asection *, - struct bfd_link_order *)); - -/* The link hash table structure is defined in bfdlink.h. It provides - a base hash table which the backend specific hash tables are built - upon. */ - -/* Routine to create an entry in the link hash table. */ - -struct bfd_hash_entry * -_bfd_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct bfd_link_hash_entry *ret = (struct bfd_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct bfd_link_hash_entry *) NULL) - ret = ((struct bfd_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry))); - if (ret == (struct bfd_link_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct bfd_link_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->type = bfd_link_hash_new; - ret->next = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize a link hash table. The BFD argument is the one - responsible for creating this table. */ - -boolean -_bfd_link_hash_table_init (table, abfd, newfunc) - struct bfd_link_hash_table *table; - bfd *abfd; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - table->creator = abfd->xvec; - table->undefs = NULL; - table->undefs_tail = NULL; - return bfd_hash_table_init (&table->table, newfunc); -} - -/* Look up a symbol in a link hash table. If follow is true, we - follow bfd_link_hash_indirect and bfd_link_hash_warning links to - the real symbol. */ - -struct bfd_link_hash_entry * -bfd_link_hash_lookup (table, string, create, copy, follow) - struct bfd_link_hash_table *table; - const char *string; - boolean create; - boolean copy; - boolean follow; -{ - struct bfd_link_hash_entry *ret; - - ret = ((struct bfd_link_hash_entry *) - bfd_hash_lookup (&table->table, string, create, copy)); - - if (follow && ret != (struct bfd_link_hash_entry *) NULL) - { - while (ret->type == bfd_link_hash_indirect - || ret->type == bfd_link_hash_warning) - ret = ret->u.i.link; - } - - return ret; -} - -/* Traverse a generic link hash table. The only reason this is not a - macro is to do better type checking. This code presumes that an - argument passed as a struct bfd_hash_entry * may be caught as a - struct bfd_link_hash_entry * with no explicit cast required on the - call. */ - -void -bfd_link_hash_traverse (table, func, info) - struct bfd_link_hash_table *table; - boolean (*func) PARAMS ((struct bfd_link_hash_entry *, PTR)); - PTR info; -{ - bfd_hash_traverse (&table->table, - ((boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) - func), - info); -} - -/* Add a symbol to the linker hash table undefs list. */ - -INLINE void -bfd_link_add_undef (table, h) - struct bfd_link_hash_table *table; - struct bfd_link_hash_entry *h; -{ - BFD_ASSERT (h->next == NULL); - if (table->undefs_tail != (struct bfd_link_hash_entry *) NULL) - table->undefs_tail->next = h; - if (table->undefs == (struct bfd_link_hash_entry *) NULL) - table->undefs = h; - table->undefs_tail = h; -} - -/* Routine to create an entry in an generic link hash table. */ - -static struct bfd_hash_entry * -generic_link_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct generic_link_hash_entry *ret = - (struct generic_link_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct generic_link_hash_entry *) NULL) - ret = ((struct generic_link_hash_entry *) - bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry))); - if (ret == (struct generic_link_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct generic_link_hash_entry *) - _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - - if (ret) - { - /* Set local fields. */ - ret->written = false; - ret->sym = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Create an generic link hash table. */ - -struct bfd_link_hash_table * -_bfd_generic_link_hash_table_create (abfd) - bfd *abfd; -{ - struct generic_link_hash_table *ret; - - ret = ((struct generic_link_hash_table *) - malloc (sizeof (struct generic_link_hash_table))); - if (!ret) - { - bfd_set_error (bfd_error_no_memory); - return (struct bfd_link_hash_table *) NULL; - } - if (! _bfd_link_hash_table_init (&ret->root, abfd, - generic_link_hash_newfunc)) - { - free (ret); - return (struct bfd_link_hash_table *) NULL; - } - return &ret->root; -} - -/* Grab the symbols for an object file when doing a generic link. We - store the symbols in the outsymbols field. We need to keep them - around for the entire link to ensure that we only read them once. - If we read them multiple times, we might wind up with relocs and - the hash table pointing to different instances of the symbol - structure. */ - -static boolean -generic_link_read_symbols (abfd) - bfd *abfd; -{ - if (abfd->outsymbols == (asymbol **) NULL) - { - long symsize; - long symcount; - - symsize = bfd_get_symtab_upper_bound (abfd); - if (symsize < 0) - return false; - abfd->outsymbols = (asymbol **) bfd_alloc (abfd, symsize); - if (abfd->outsymbols == NULL && symsize != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - symcount = bfd_canonicalize_symtab (abfd, abfd->outsymbols); - if (symcount < 0) - return false; - abfd->symcount = symcount; - } - - return true; -} - -/* Generic function to add symbols to from an object file to the - global hash table. This version does not automatically collect - constructors by name. */ - -boolean -_bfd_generic_link_add_symbols (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - return generic_link_add_symbols (abfd, info, false); -} - -/* Generic function to add symbols from an object file to the global - hash table. This version automatically collects constructors by - name, as the collect2 program does. It should be used for any - target which does not provide some other mechanism for setting up - constructors and destructors; these are approximately those targets - for which gcc uses collect2 and do not support stabs. */ - -boolean -_bfd_generic_link_add_symbols_collect (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - return generic_link_add_symbols (abfd, info, true); -} - -/* Add symbols from an object file to the global hash table. */ - -static boolean -generic_link_add_symbols (abfd, info, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean collect; -{ - boolean ret; - - switch (bfd_get_format (abfd)) - { - case bfd_object: - ret = generic_link_add_object_symbols (abfd, info, collect); - break; - case bfd_archive: - ret = (_bfd_generic_link_add_archive_symbols - (abfd, info, - (collect - ? generic_link_check_archive_element_collect - : generic_link_check_archive_element_no_collect))); - break; - default: - bfd_set_error (bfd_error_wrong_format); - ret = false; - } - - return ret; -} - -/* Add symbols from an object file to the global hash table. */ - -static boolean -generic_link_add_object_symbols (abfd, info, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean collect; -{ - if (! generic_link_read_symbols (abfd)) - return false; - return generic_link_add_symbol_list (abfd, info, - _bfd_generic_link_get_symcount (abfd), - _bfd_generic_link_get_symbols (abfd), - collect); -} - -/* We build a hash table of all symbols defined in an archive. */ - -/* An archive symbol may be defined by multiple archive elements. - This linked list is used to hold the elements. */ - -struct archive_list -{ - struct archive_list *next; - int indx; -}; - -/* An entry in an archive hash table. */ - -struct archive_hash_entry -{ - struct bfd_hash_entry root; - /* Where the symbol is defined. */ - struct archive_list *defs; -}; - -/* An archive hash table itself. */ - -struct archive_hash_table -{ - struct bfd_hash_table table; -}; - -static struct bfd_hash_entry *archive_hash_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean archive_hash_table_init - PARAMS ((struct archive_hash_table *, - struct bfd_hash_entry *(*) (struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *))); - -/* Create a new entry for an archive hash table. */ - -static struct bfd_hash_entry * -archive_hash_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct archive_hash_entry *ret = (struct archive_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct archive_hash_entry *) NULL) - ret = ((struct archive_hash_entry *) - bfd_hash_allocate (table, sizeof (struct archive_hash_entry))); - if (ret == (struct archive_hash_entry *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - /* Call the allocation method of the superclass. */ - ret = ((struct archive_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - - if (ret) - { - /* Initialize the local fields. */ - ret->defs = (struct archive_list *) NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Initialize an archive hash table. */ - -static boolean -archive_hash_table_init (table, newfunc) - struct archive_hash_table *table; - struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, - struct bfd_hash_table *, - const char *)); -{ - return bfd_hash_table_init (&table->table, newfunc); -} - -/* Look up an entry in an archive hash table. */ - -#define archive_hash_lookup(t, string, create, copy) \ - ((struct archive_hash_entry *) \ - bfd_hash_lookup (&(t)->table, (string), (create), (copy))) - -/* Allocate space in an archive hash table. */ - -#define archive_hash_allocate(t, size) bfd_hash_allocate (&(t)->table, (size)) - -/* Free an archive hash table. */ - -#define archive_hash_table_free(t) bfd_hash_table_free (&(t)->table) - -/* Generic function to add symbols from an archive file to the global - hash file. This function presumes that the archive symbol table - has already been read in (this is normally done by the - bfd_check_format entry point). It looks through the undefined and - common symbols and searches the archive symbol table for them. If - it finds an entry, it includes the associated object file in the - link. - - The old linker looked through the archive symbol table for - undefined symbols. We do it the other way around, looking through - undefined symbols for symbols defined in the archive. The - advantage of the newer scheme is that we only have to look through - the list of undefined symbols once, whereas the old method had to - re-search the symbol table each time a new object file was added. - - The CHECKFN argument is used to see if an object file should be - included. CHECKFN should set *PNEEDED to true if the object file - should be included, and must also call the bfd_link_info - add_archive_element callback function and handle adding the symbols - to the global hash table. CHECKFN should only return false if some - sort of error occurs. - - For some formats, such as a.out, it is possible to look through an - object file but not actually include it in the link. The - archive_pass field in a BFD is used to avoid checking the symbols - of an object files too many times. When an object is included in - the link, archive_pass is set to -1. If an object is scanned but - not included, archive_pass is set to the pass number. The pass - number is incremented each time a new object file is included. The - pass number is used because when a new object file is included it - may create new undefined symbols which cause a previously examined - object file to be included. */ - -boolean -_bfd_generic_link_add_archive_symbols (abfd, info, checkfn) - bfd *abfd; - struct bfd_link_info *info; - boolean (*checkfn) PARAMS ((bfd *, struct bfd_link_info *, - boolean *pneeded)); -{ - carsym *arsyms; - carsym *arsym_end; - register carsym *arsym; - int pass; - struct archive_hash_table arsym_hash; - int indx; - struct bfd_link_hash_entry **pundef; - - if (! bfd_has_map (abfd)) - { - bfd_set_error (bfd_error_no_symbols); - return false; - } - - arsyms = bfd_ardata (abfd)->symdefs; - arsym_end = arsyms + bfd_ardata (abfd)->symdef_count; - - /* In order to quickly determine whether an symbol is defined in - this archive, we build a hash table of the symbols. */ - if (! archive_hash_table_init (&arsym_hash, archive_hash_newfunc)) - return false; - for (arsym = arsyms, indx = 0; arsym < arsym_end; arsym++, indx++) - { - struct archive_hash_entry *arh; - struct archive_list *l, **pp; - - arh = archive_hash_lookup (&arsym_hash, arsym->name, true, false); - if (arh == (struct archive_hash_entry *) NULL) - goto error_return; - l = ((struct archive_list *) - archive_hash_allocate (&arsym_hash, sizeof (struct archive_list))); - if (l == NULL) - goto error_return; - l->indx = indx; - for (pp = &arh->defs; - *pp != (struct archive_list *) NULL; - pp = &(*pp)->next) - ; - *pp = l; - l->next = NULL; - } - - /* The archive_pass field in the archive itself is used to - initialize PASS, sine we may search the same archive multiple - times. */ - pass = abfd->archive_pass; - if (pass == 0) - pass = 1; - - /* New undefined symbols are added to the end of the list, so we - only need to look through it once. */ - pundef = &info->hash->undefs; - while (*pundef != (struct bfd_link_hash_entry *) NULL) - { - struct bfd_link_hash_entry *h; - struct archive_hash_entry *arh; - struct archive_list *l; - - h = *pundef; - - /* When a symbol is defined, it is not necessarily removed from - the list. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - { - /* Remove this entry from the list, for general cleanliness - and because we are going to look through the list again - if we search any more libraries. We can't remove the - entry if it is the tail, because that would lose any - entries we add to the list later on (it would also cause - us to lose track of whether the symbol has been - referenced). */ - if (*pundef != info->hash->undefs_tail) - *pundef = (*pundef)->next; - else - pundef = &(*pundef)->next; - continue; - } - - /* Look for this symbol in the archive symbol map. */ - arh = archive_hash_lookup (&arsym_hash, h->root.string, false, false); - if (arh == (struct archive_hash_entry *) NULL) - { - pundef = &(*pundef)->next; - continue; - } - - /* Look at all the objects which define this symbol. */ - for (l = arh->defs; l != (struct archive_list *) NULL; l = l->next) - { - bfd *element; - boolean needed; - - /* If the symbol has gotten defined along the way, quit. */ - if (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common) - break; - - element = bfd_get_elt_at_index (abfd, l->indx); - if (element == (bfd *) NULL) - goto error_return; - - /* If we've already included this element, or if we've - already checked it on this pass, continue. */ - if (element->archive_pass == -1 - || element->archive_pass == pass) - continue; - - /* If we can't figure this element out, just ignore it. */ - if (! bfd_check_format (element, bfd_object)) - { - element->archive_pass = -1; - continue; - } - - /* CHECKFN will see if this element should be included, and - go ahead and include it if appropriate. */ - if (! (*checkfn) (element, info, &needed)) - goto error_return; - - if (! needed) - element->archive_pass = pass; - else - { - element->archive_pass = -1; - - /* Increment the pass count to show that we may need to - recheck object files which were already checked. */ - ++pass; - } - } - - pundef = &(*pundef)->next; - } - - archive_hash_table_free (&arsym_hash); - - /* Save PASS in case we are called again. */ - abfd->archive_pass = pass; - - return true; - - error_return: - archive_hash_table_free (&arsym_hash); - return false; -} - -/* See if we should include an archive element. This version is used - when we do not want to automatically collect constructors based on - the symbol name, presumably because we have some other mechanism - for finding them. */ - -static boolean -generic_link_check_archive_element_no_collect (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - return generic_link_check_archive_element (abfd, info, pneeded, false); -} - -/* See if we should include an archive element. This version is used - when we want to automatically collect constructors based on the - symbol name, as collect2 does. */ - -static boolean -generic_link_check_archive_element_collect (abfd, info, pneeded) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; -{ - return generic_link_check_archive_element (abfd, info, pneeded, true); -} - -/* See if we should include an archive element. Optionally collect - constructors. */ - -static boolean -generic_link_check_archive_element (abfd, info, pneeded, collect) - bfd *abfd; - struct bfd_link_info *info; - boolean *pneeded; - boolean collect; -{ - asymbol **pp, **ppend; - - *pneeded = false; - - if (! generic_link_read_symbols (abfd)) - return false; - - pp = _bfd_generic_link_get_symbols (abfd); - ppend = pp + _bfd_generic_link_get_symcount (abfd); - for (; pp < ppend; pp++) - { - asymbol *p; - struct bfd_link_hash_entry *h; - - p = *pp; - - /* We are only interested in globally visible symbols. */ - if (! bfd_is_com_section (p->section) - && (p->flags & (BSF_GLOBAL | BSF_INDIRECT | BSF_WEAK)) == 0) - continue; - - /* We are only interested if we know something about this - symbol, and it is undefined or common. An undefined weak - symbol (type bfd_link_hash_weak) is not considered to be a - reference when pulling files out of an archive. See the SVR4 - ABI, p. 4-27. */ - h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false, - false, true); - if (h == (struct bfd_link_hash_entry *) NULL - || (h->type != bfd_link_hash_undefined - && h->type != bfd_link_hash_common)) - continue; - - /* P is a symbol we are looking for. */ - - if (! bfd_is_com_section (p->section)) - { - bfd_size_type symcount; - asymbol **symbols; - - /* This object file defines this symbol, so pull it in. */ - if (! (*info->callbacks->add_archive_element) (info, abfd, - bfd_asymbol_name (p))) - return false; - symcount = _bfd_generic_link_get_symcount (abfd); - symbols = _bfd_generic_link_get_symbols (abfd); - if (! generic_link_add_symbol_list (abfd, info, symcount, - symbols, collect)) - return false; - *pneeded = true; - return true; - } - - /* P is a common symbol. */ - - if (h->type == bfd_link_hash_undefined) - { - bfd *symbfd; - - symbfd = h->u.undef.abfd; - if (symbfd == (bfd *) NULL) - { - /* This symbol was created as undefined from outside - BFD. We assume that we should link in the object - file. This is for the -u option in the linker. */ - if (! (*info->callbacks->add_archive_element) - (info, abfd, bfd_asymbol_name (p))) - return false; - *pneeded = true; - return true; - } - - /* Turn the symbol into a common symbol but do not link in - the object file. This is how a.out works. Object - formats that require different semantics must implement - this function differently. This symbol is already on the - undefs list. We add the section to a common section - attached to symbfd to ensure that it is in a BFD which - will be linked in. */ - h->type = bfd_link_hash_common; - h->u.c.size = bfd_asymbol_value (p); - if (p->section == bfd_com_section_ptr) - h->u.c.section = bfd_make_section_old_way (symbfd, "COMMON"); - else - h->u.c.section = bfd_make_section_old_way (symbfd, - p->section->name); - h->u.c.section->flags = SEC_ALLOC; - } - else - { - /* Adjust the size of the common symbol if necessary. This - is how a.out works. Object formats that require - different semantics must implement this function - differently. */ - if (bfd_asymbol_value (p) > h->u.c.size) - h->u.c.size = bfd_asymbol_value (p); - } - } - - /* This archive element is not needed. */ - return true; -} - -/* Add the symbols from an object file to the global hash table. ABFD - is the object file. INFO is the linker information. SYMBOL_COUNT - is the number of symbols. SYMBOLS is the list of symbols. COLLECT - is true if constructors should be automatically collected by name - as is done by collect2. */ - -static boolean -generic_link_add_symbol_list (abfd, info, symbol_count, symbols, collect) - bfd *abfd; - struct bfd_link_info *info; - bfd_size_type symbol_count; - asymbol **symbols; - boolean collect; -{ - asymbol **pp, **ppend; - - pp = symbols; - ppend = symbols + symbol_count; - for (; pp < ppend; pp++) - { - asymbol *p; - - p = *pp; - - if ((p->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (p)) - || bfd_is_com_section (bfd_get_section (p)) - || bfd_is_ind_section (bfd_get_section (p))) - { - const char *name; - const char *string; - struct generic_link_hash_entry *h; - - name = bfd_asymbol_name (p); - if ((p->flags & BSF_INDIRECT) != 0 - || bfd_is_ind_section (p->section)) - string = bfd_asymbol_name ((asymbol *) p->value); - else if ((p->flags & BSF_WARNING) != 0) - { - /* The name of P is actually the warning string, and the - value is actually a pointer to the symbol to warn - about. */ - string = name; - name = bfd_asymbol_name ((asymbol *) p->value); - } - else - string = NULL; - - h = NULL; - if (! (_bfd_generic_link_add_one_symbol - (info, abfd, name, p->flags, bfd_get_section (p), - p->value, string, false, collect, - (struct bfd_link_hash_entry **) &h))) - return false; - - /* Save the BFD symbol so that we don't lose any backend - specific information that may be attached to it. We only - want this one if it gives more information than the - existing one; we don't want to replace a defined symbol - with an undefined one. This routine may be called with a - hash table other than the generic hash table, so we only - do this if we are certain that the hash table is a - generic one. */ - if (info->hash->creator == abfd->xvec) - { - if (h->sym == (asymbol *) NULL - || (! bfd_is_und_section (bfd_get_section (p)) - && (! bfd_is_com_section (bfd_get_section (p)) - || bfd_is_und_section (bfd_get_section (h->sym))))) - { - h->sym = p; - /* BSF_OLD_COMMON is a hack to support COFF reloc - reading, and it should go away when the COFF - linker is switched to the new version. */ - if (bfd_is_com_section (bfd_get_section (p))) - p->flags |= BSF_OLD_COMMON; - } - - /* Store a back pointer from the symbol to the hash - table entry for the benefit of relaxation code until - it gets rewritten to not use asymbol structures. */ - p->udata = (PTR) h; - } - } - } - - return true; -} - -/* We use a state table to deal with adding symbols from an object - file. The first index into the state table describes the symbol - from the object file. The second index into the state table is the - type of the symbol in the hash table. */ - -/* The symbol from the object file is turned into one of these row - values. */ - -enum link_row -{ - UNDEF_ROW, /* Undefined. */ - UNDEFW_ROW, /* Weak undefined. */ - DEF_ROW, /* Defined. */ - DEFW_ROW, /* Weak defined. */ - COMMON_ROW, /* Common. */ - INDR_ROW, /* Indirect. */ - WARN_ROW, /* Warning. */ - SET_ROW /* Member of set. */ -}; - -/* apparently needed for Hitachi 3050R(HI-UX/WE2)? */ -#undef FAIL - -/* The actions to take in the state table. */ - -enum link_action -{ - FAIL, /* Abort. */ - UND, /* Mark symbol undefined. */ - WEAK, /* Mark symbol weak undefined. */ - DEF, /* Mark symbol defined. */ - COM, /* Mark symbol common. */ - REF, /* Mark defined symbol referenced. */ - CREF, /* Possibly warn about common reference to defined symbol. */ - CDEF, /* Define existing common symbol. */ - NOACT, /* No action. */ - BIG, /* Mark symbol common using largest size. */ - MDEF, /* Multiple definition error. */ - MIND, /* Multiple indirect symbols. */ - IND, /* Make indirect symbol. */ - SET, /* Add value to set. */ - MWARN, /* Make warning symbol. */ - WARN, /* Issue warning. */ - CWARN, /* Warn if referenced, else MWARN. */ - CYCLE, /* Repeat with symbol pointed to. */ - REFC, /* Mark indirect symbol referenced and then CYCLE. */ - WARNC /* Issue warning and then CYCLE. */ -}; - -/* The state table itself. The first index is a link_row and the - second index is a bfd_link_hash_type. */ - -static const enum link_action link_action[8][7] = -{ - /* current\prev new undef weak def com indr warn */ - /* UNDEF_ROW */ {UND, NOACT, NOACT, REF, NOACT, REFC, WARNC }, - /* UNDEFW_ROW */ {WEAK, WEAK, NOACT, REF, NOACT, REFC, WARNC }, - /* DEF_ROW */ {DEF, DEF, DEF, MDEF, CDEF, MDEF, CYCLE }, - /* DEFW_ROW */ {DEF, DEF, DEF, NOACT, NOACT, NOACT, CYCLE }, - /* COMMON_ROW */ {COM, COM, COM, CREF, BIG, MDEF, WARNC }, - /* INDR_ROW */ {IND, IND, IND, MDEF, MDEF, MIND, CYCLE }, - /* WARN_ROW */ {MWARN, WARN, WARN, CWARN, WARN, CWARN, CYCLE }, - /* SET_ROW */ {SET, SET, SET, SET, SET, CYCLE, CYCLE } -}; - -/* Most of the entries in the LINK_ACTION table are straightforward, - but a few are somewhat subtle. - - A reference to an indirect symbol (UNDEF_ROW/indr or - UNDEFW_ROW/indr) is counted as a reference both to the indirect - symbol and to the symbol the indirect symbol points to. - - A reference to a warning symbol (UNDEF_ROW/warn or UNDEFW_ROW/warn) - causes the warning to be issued. - - A common definition of an indirect symbol (COMMON_ROW/indr) is - treated as a multiple definition error. Likewise for an indirect - definition of a common symbol (INDR_ROW/com). - - An indirect definition of a warning (INDR_ROW/warn) does not cause - the warning to be issued. - - If a warning is created for an indirect symbol (WARN_ROW/indr) no - warning is created for the symbol the indirect symbol points to. - - Adding an entry to a set does not count as a reference to a set, - and no warning is issued (SET_ROW/warn). */ - -/* Add a symbol to the global hash table. - ABFD is the BFD the symbol comes from. - NAME is the name of the symbol. - FLAGS is the BSF_* bits associated with the symbol. - SECTION is the section in which the symbol is defined; this may be - bfd_und_section_ptr or bfd_com_section_ptr. - VALUE is the value of the symbol, relative to the section. - STRING is used for either an indirect symbol, in which case it is - the name of the symbol to indirect to, or a warning symbol, in - which case it is the warning string. - COPY is true if NAME or STRING must be copied into locally - allocated memory if they need to be saved. - COLLECT is true if we should automatically collect gcc constructor - or destructor names as collect2 does. - HASHP, if not NULL, is a place to store the created hash table - entry; if *HASHP is not NULL, the caller has already looked up - the hash table entry, and stored it in *HASHP. */ - -boolean -_bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, - string, copy, collect, hashp) - struct bfd_link_info *info; - bfd *abfd; - const char *name; - flagword flags; - asection *section; - bfd_vma value; - const char *string; - boolean copy; - boolean collect; - struct bfd_link_hash_entry **hashp; -{ - enum link_row row; - struct bfd_link_hash_entry *h; - boolean cycle; - - if (bfd_is_ind_section (section) - || (flags & BSF_INDIRECT) != 0) - row = INDR_ROW; - else if ((flags & BSF_WARNING) != 0) - row = WARN_ROW; - else if ((flags & BSF_CONSTRUCTOR) != 0) - row = SET_ROW; - else if (bfd_is_und_section (section)) - { - if ((flags & BSF_WEAK) != 0) - row = UNDEFW_ROW; - else - row = UNDEF_ROW; - } - else if ((flags & BSF_WEAK) != 0) - row = DEFW_ROW; - else if (bfd_is_com_section (section)) - row = COMMON_ROW; - else - row = DEF_ROW; - - if (hashp != NULL && *hashp != NULL) - { - h = *hashp; - BFD_ASSERT (strcmp (h->root.string, name) == 0); - } - else - { - h = bfd_link_hash_lookup (info->hash, name, true, copy, false); - if (h == NULL) - { - if (hashp != NULL) - *hashp = NULL; - return false; - } - } - - if (info->notice_hash != (struct bfd_hash_table *) NULL - && (bfd_hash_lookup (info->notice_hash, name, false, false) - != (struct bfd_hash_entry *) NULL)) - { - if (! (*info->callbacks->notice) (info, name, abfd, section, value)) - return false; - } - - if (hashp != (struct bfd_link_hash_entry **) NULL) - *hashp = h; - - do - { - enum link_action action; - - cycle = false; - action = link_action[(int) row][(int) h->type]; - switch (action) - { - case FAIL: - abort (); - - case NOACT: - /* Do nothing. */ - break; - - case UND: - /* Make a new undefined symbol. */ - h->type = bfd_link_hash_undefined; - h->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, h); - break; - - case WEAK: - /* Make a new weak undefined symbol. */ - h->type = bfd_link_hash_weak; - h->u.undef.abfd = abfd; - break; - - case CDEF: - /* We have found a definition for a symbol which was - previously common. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.c.section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_defined, (bfd_vma) 0))) - return false; - /* Fall through. */ - case DEF: - /* Define a symbol. */ - h->type = bfd_link_hash_defined; - h->u.def.section = section; - h->u.def.value = value; - - /* If we have been asked to, we act like collect2 and - identify all functions that might be global constructors - and destructors and pass them up in a callback. We only - do this for certain object file types, since many object - file types can handle this automatically. */ - if (collect && name[0] == '_') - { - const char *s; - - /* A constructor or destructor name starts like this: - _+GLOBAL_[_.$][ID][_.$] - where the first [_.$] and the second are the same - character (we accept any character there, in case a - new object file format comes along with even worse - naming restrictions). */ - -#define CONS_PREFIX "GLOBAL_" -#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1) - - s = name + 1; - while (*s == '_') - ++s; - if (s[0] == 'G' - && strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0) - { - char c; - - c = s[CONS_PREFIX_LEN + 1]; - if ((c == 'I' || c == 'D') - && s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2]) - { - if (! ((*info->callbacks->constructor) - (info, - c == 'I' ? true : false, - name, abfd, section, value))) - return false; - } - } - } - - break; - - case COM: - /* We have found a common definition for a symbol. */ - if (h->type == bfd_link_hash_new) - bfd_link_add_undef (info->hash, h); - h->type = bfd_link_hash_common; - h->u.c.size = value; - if (section == bfd_com_section_ptr) - { - h->u.c.section = bfd_make_section_old_way (abfd, "COMMON"); - h->u.c.section->flags = SEC_ALLOC; - } - else if (section->owner != abfd) - { - h->u.c.section = bfd_make_section_old_way (abfd, section->name); - h->u.c.section->flags = SEC_ALLOC; - } - else - h->u.c.section = section; - break; - - case REF: - /* A reference to a defined symbol. */ - if (h->next == NULL && info->hash->undefs_tail != h) - h->next = h; - break; - - case BIG: - /* We have found a common definition for a symbol which - already had a common definition. Use the maximum of the - two sizes. */ - BFD_ASSERT (h->type == bfd_link_hash_common); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.c.section->owner, bfd_link_hash_common, h->u.c.size, - abfd, bfd_link_hash_common, value))) - return false; - if (value > h->u.c.size) - h->u.c.size = value; - break; - - case CREF: - /* We have found a common definition for a symbol which was - already defined. */ - BFD_ASSERT (h->type == bfd_link_hash_defined); - if (! ((*info->callbacks->multiple_common) - (info, name, - h->u.def.section->owner, bfd_link_hash_defined, (bfd_vma) 0, - abfd, bfd_link_hash_common, value))) - return false; - break; - - case MIND: - /* Multiple indirect symbols. This is OK if they both point - to the same symbol. */ - if (strcmp (h->u.i.link->root.string, string) == 0) - break; - /* Fall through. */ - case MDEF: - /* Handle a multiple definition. */ - { - asection *msec; - bfd_vma mval; - - switch (h->type) - { - case bfd_link_hash_defined: - msec = h->u.def.section; - mval = h->u.def.value; - break; - case bfd_link_hash_common: - msec = bfd_com_section_ptr; - mval = h->u.c.size; - break; - case bfd_link_hash_indirect: - msec = bfd_ind_section_ptr; - mval = 0; - break; - default: - abort (); - } - - if (! ((*info->callbacks->multiple_definition) - (info, name, msec->owner, msec, mval, abfd, section, - value))) - return false; - } - break; - - case IND: - /* Create an indirect symbol. */ - { - struct bfd_link_hash_entry *inh; - - /* STRING is the name of the symbol we want to indirect - to. */ - inh = bfd_link_hash_lookup (info->hash, string, true, copy, - false); - if (inh == (struct bfd_link_hash_entry *) NULL) - return false; - if (inh->type == bfd_link_hash_new) - { - inh->type = bfd_link_hash_undefined; - inh->u.undef.abfd = abfd; - bfd_link_add_undef (info->hash, inh); - } - - /* If the indirect symbol has been referenced, we need to - push the reference down to the symbol we are - referencing. */ - if (h->type != bfd_link_hash_new) - { - row = UNDEF_ROW; - cycle = true; - } - - h->type = bfd_link_hash_indirect; - h->u.i.link = inh; - } - break; - - case SET: - /* Add an entry to a set. */ - if (! (*info->callbacks->add_to_set) (info, h, BFD_RELOC_CTOR, - abfd, section, value)) - return false; - break; - - case WARNC: - /* Issue a warning and cycle. */ - if (h->u.i.warning != NULL) - { - if (! (*info->callbacks->warning) (info, h->u.i.warning)) - return false; - /* Only issue a warning once. */ - h->u.i.warning = NULL; - } - /* Fall through. */ - case CYCLE: - /* Try again with the referenced symbol. */ - h = h->u.i.link; - cycle = true; - break; - - case REFC: - /* A reference to an indirect symbol. */ - if (h->next == NULL && info->hash->undefs_tail != h) - h->next = h; - h = h->u.i.link; - cycle = true; - break; - - case WARN: - /* Issue a warning. */ - if (! (*info->callbacks->warning) (info, string)) - return false; - break; - - case CWARN: - /* Warn if this symbol has been referenced already, - otherwise either add a warning or cycle. A symbol has - been referenced if the next field is not NULL, or it is - the tail of the undefined symbol list. The REF case - above helps to ensure this. */ - if (h->next != NULL || info->hash->undefs_tail == h) - { - if (! (*info->callbacks->warning) (info, string)) - return false; - break; - } - /* Fall through. */ - case MWARN: - /* Make a warning symbol. */ - { - struct bfd_link_hash_entry *sub; - - /* STRING is the warning to give. */ - sub = ((struct bfd_link_hash_entry *) - bfd_hash_allocate (&info->hash->table, - sizeof (struct bfd_link_hash_entry))); - if (!sub) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - *sub = *h; - h->type = bfd_link_hash_warning; - h->u.i.link = sub; - if (! copy) - h->u.i.warning = string; - else - { - char *w; - - w = bfd_hash_allocate (&info->hash->table, - strlen (string) + 1); - strcpy (w, string); - h->u.i.warning = w; - } - } - break; - } - } - while (cycle); - - return true; -} - -/* Generic final link routine. */ - -boolean -_bfd_generic_final_link (abfd, info) - bfd *abfd; - struct bfd_link_info *info; -{ - bfd *sub; - asection *o; - struct bfd_link_order *p; - size_t outsymalloc; - struct generic_write_global_symbol_info wginfo; - - abfd->outsymbols = (asymbol **) NULL; - abfd->symcount = 0; - outsymalloc = 0; - - /* Build the output symbol table. */ - for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next) - if (! _bfd_generic_link_output_symbols (abfd, sub, info, &outsymalloc)) - return false; - - /* Accumulate the global symbols. */ - wginfo.info = info; - wginfo.output_bfd = abfd; - wginfo.psymalloc = &outsymalloc; - _bfd_generic_link_hash_traverse (_bfd_generic_hash_table (info), - _bfd_generic_link_write_global_symbol, - (PTR) &wginfo); - - if (info->relocateable) - { - /* Allocate space for the output relocs for each section. */ - for (o = abfd->sections; - o != (asection *) NULL; - o = o->next) - { - o->reloc_count = 0; - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - ++o->reloc_count; - else if (p->type == bfd_indirect_link_order) - { - asection *input_section; - bfd *input_bfd; - long relsize; - arelent **relocs; - asymbol **symbols; - long reloc_count; - - input_section = p->u.indirect.section; - input_bfd = input_section->owner; - relsize = bfd_get_reloc_upper_bound (input_bfd, - input_section); - if (relsize < 0) - return false; - relocs = (arelent **) malloc ((size_t) relsize); - if (!relocs && relsize != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - symbols = _bfd_generic_link_get_symbols (input_bfd); - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - relocs, - symbols); - if (reloc_count < 0) - return false; - BFD_ASSERT (reloc_count == input_section->reloc_count); - o->reloc_count += reloc_count; - free (relocs); - } - } - if (o->reloc_count > 0) - { - o->orelocation = ((arelent **) - bfd_alloc (abfd, - (o->reloc_count - * sizeof (arelent *)))); - if (!o->orelocation) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - o->flags |= SEC_RELOC; - /* Reset the count so that it can be used as an index - when putting in the output relocs. */ - o->reloc_count = 0; - } - } - } - - /* Handle all the link order information for the sections. */ - for (o = abfd->sections; - o != (asection *) NULL; - o = o->next) - { - for (p = o->link_order_head; - p != (struct bfd_link_order *) NULL; - p = p->next) - { - switch (p->type) - { - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - if (! _bfd_generic_reloc_link_order (abfd, info, o, p)) - return false; - break; - default: - if (! _bfd_default_link_order (abfd, info, o, p)) - return false; - break; - } - } - } - - return true; -} - -/* Add an output symbol to the output BFD. */ - -static boolean -generic_add_output_symbol (output_bfd, psymalloc, sym) - bfd *output_bfd; - size_t *psymalloc; - asymbol *sym; -{ - if (output_bfd->symcount >= *psymalloc) - { - asymbol **newsyms; - - if (*psymalloc == 0) - *psymalloc = 124; - else - *psymalloc *= 2; - if (output_bfd->outsymbols == (asymbol **) NULL) - newsyms = (asymbol **) malloc (*psymalloc * sizeof (asymbol *)); - else - newsyms = (asymbol **) realloc (output_bfd->outsymbols, - *psymalloc * sizeof (asymbol *)); - if (newsyms == (asymbol **) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - output_bfd->outsymbols = newsyms; - } - - output_bfd->outsymbols[output_bfd->symcount] = sym; - ++output_bfd->symcount; - - return true; -} - -/* Handle the symbols for an input BFD. */ - -boolean -_bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc) - bfd *output_bfd; - bfd *input_bfd; - struct bfd_link_info *info; - size_t *psymalloc; -{ - asymbol **sym_ptr; - asymbol **sym_end; - - if (! generic_link_read_symbols (input_bfd)) - return false; - - /* Create a filename symbol if we are supposed to. */ - if (info->create_object_symbols_section != (asection *) NULL) - { - asection *sec; - - for (sec = input_bfd->sections; - sec != (asection *) NULL; - sec = sec->next) - { - if (sec->output_section == info->create_object_symbols_section) - { - asymbol *newsym; - - newsym = bfd_make_empty_symbol (input_bfd); - if (!newsym) - return false; - newsym->name = input_bfd->filename; - newsym->value = 0; - newsym->flags = BSF_LOCAL | BSF_FILE; - newsym->section = sec; - - if (! generic_add_output_symbol (output_bfd, psymalloc, - newsym)) - return false; - - break; - } - } - } - - /* Adjust the values of the globally visible symbols, and write out - local symbols. */ - sym_ptr = _bfd_generic_link_get_symbols (input_bfd); - sym_end = sym_ptr + _bfd_generic_link_get_symcount (input_bfd); - for (; sym_ptr < sym_end; sym_ptr++) - { - asymbol *sym; - struct generic_link_hash_entry *h; - boolean output; - - h = (struct generic_link_hash_entry *) NULL; - sym = *sym_ptr; - if ((sym->flags & (BSF_INDIRECT - | BSF_WARNING - | BSF_GLOBAL - | BSF_CONSTRUCTOR - | BSF_WEAK)) != 0 - || bfd_is_und_section (bfd_get_section (sym)) - || bfd_is_com_section (bfd_get_section (sym)) - || bfd_is_ind_section (bfd_get_section (sym))) - { - h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), - bfd_asymbol_name (sym), - false, false, true); - if (h != (struct generic_link_hash_entry *) NULL) - { - /* Force all references to this symbol to point to - the same area in memory. It is possible that - this routine will be called with a hash table - other than a generic hash table, so we double - check that. */ - if (info->hash->creator == input_bfd->xvec) - { - if (h->sym != (asymbol *) NULL) - *sym_ptr = sym = h->sym; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - case bfd_link_hash_weak: - break; - case bfd_link_hash_defined: - sym->value = h->root.u.def.value; - sym->section = h->root.u.def.section; - sym->flags |= BSF_GLOBAL; - break; - case bfd_link_hash_common: - sym->value = h->root.u.c.size; - sym->flags |= BSF_GLOBAL; - if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* We do not set the section of the symbol to - h->root.u.c.section. That value was saved so - that we would know where to allocate the symbol - if it was defined. In this case the type is - still bfd_link_hash_common, so we did not define - it, so we do not want to use that section. */ - break; - } - } - } - - /* This switch is straight from the old code in - write_file_locals in ldsym.c. */ - if (info->strip == strip_some - && (bfd_hash_lookup (info->keep_hash, bfd_asymbol_name (sym), - false, false) - == (struct bfd_hash_entry *) NULL)) - output = false; - else if ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0) - { - /* If this symbol is marked as occurring now, rather - than at the end, output it now. This is used for - COFF C_EXT FCN symbols. FIXME: There must be a - better way. */ - if (bfd_asymbol_bfd (sym) == input_bfd - && (sym->flags & BSF_NOT_AT_END) != 0) - output = true; - else - output = false; - } - else if (bfd_is_ind_section (sym->section)) - output = false; - else if ((sym->flags & BSF_DEBUGGING) != 0) - { - if (info->strip == strip_none) - output = true; - else - output = false; - } - else if (bfd_is_und_section (sym->section) - || bfd_is_com_section (sym->section)) - output = false; - else if ((sym->flags & BSF_LOCAL) != 0) - { - if ((sym->flags & BSF_WARNING) != 0) - output = false; - else - { - switch (info->discard) - { - default: - case discard_all: - output = false; - break; - case discard_l: - if (bfd_asymbol_name (sym)[0] == info->lprefix[0] - && (info->lprefix_len == 1 - || strncmp (bfd_asymbol_name (sym), info->lprefix, - info->lprefix_len) == 0)) - output = false; - else - output = true; - break; - case discard_none: - output = true; - break; - } - } - } - else if ((sym->flags & BSF_CONSTRUCTOR)) - { - if (info->strip != strip_all) - output = true; - else - output = false; - } - else - abort (); - - if (output) - { - if (! generic_add_output_symbol (output_bfd, psymalloc, sym)) - return false; - if (h != (struct generic_link_hash_entry *) NULL) - h->written = true; - } - } - - return true; -} - -/* Write out a global symbol, if it hasn't already been written out. - This is called for each symbol in the hash table. */ - -boolean -_bfd_generic_link_write_global_symbol (h, data) - struct generic_link_hash_entry *h; - PTR data; -{ - struct generic_write_global_symbol_info *wginfo = - (struct generic_write_global_symbol_info *) data; - asymbol *sym; - - if (h->written) - return true; - - h->written = true; - - if (wginfo->info->strip == strip_all - || (wginfo->info->strip == strip_some - && bfd_hash_lookup (wginfo->info->keep_hash, h->root.root.string, - false, false) == NULL)) - return true; - - if (h->sym != (asymbol *) NULL) - { - sym = h->sym; - BFD_ASSERT (strcmp (bfd_asymbol_name (sym), h->root.root.string) == 0); - } - else - { - sym = bfd_make_empty_symbol (wginfo->output_bfd); - if (!sym) - return false; - sym->name = h->root.root.string; - sym->flags = 0; - } - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - abort (); - case bfd_link_hash_undefined: - sym->section = bfd_und_section_ptr; - sym->value = 0; - break; - case bfd_link_hash_weak: - sym->section = bfd_und_section_ptr; - sym->value = 0; - sym->flags |= BSF_WEAK; - break; - case bfd_link_hash_defined: - sym->section = h->root.u.def.section; - sym->value = h->root.u.def.value; - break; - case bfd_link_hash_common: - sym->value = h->root.u.c.size; - if (sym->section == NULL) - sym->section = bfd_com_section_ptr; - else if (! bfd_is_com_section (sym->section)) - { - BFD_ASSERT (bfd_is_und_section (sym->section)); - sym->section = bfd_com_section_ptr; - } - /* Do not set the section; see _bfd_generic_link_output_symbols. */ - break; - case bfd_link_hash_indirect: - case bfd_link_hash_warning: - /* FIXME: What should we do here? */ - break; - } - - sym->flags |= BSF_GLOBAL; - - if (! generic_add_output_symbol (wginfo->output_bfd, wginfo->psymalloc, - sym)) - { - /* FIXME: No way to return failure. */ - abort (); - } - - return true; -} - -/* Create a relocation. */ - -boolean -_bfd_generic_reloc_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - arelent *r; - - if (! info->relocateable) - abort (); - if (sec->orelocation == (arelent **) NULL) - abort (); - - r = (arelent *) bfd_alloc (abfd, sizeof (arelent)); - if (r == (arelent *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - r->address = link_order->offset; - r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc); - if (r->howto == (const reloc_howto_type *) NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Get the symbol to use for the relocation. */ - if (link_order->type == bfd_section_reloc_link_order) - r->sym_ptr_ptr = link_order->u.reloc.p->u.section->symbol_ptr_ptr; - else - { - struct generic_link_hash_entry *h; - - h = _bfd_generic_link_hash_lookup (_bfd_generic_hash_table (info), - link_order->u.reloc.p->u.name, - false, false, true); - if (h == (struct generic_link_hash_entry *) NULL - || ! h->written) - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - return false; - bfd_set_error (bfd_error_bad_value); - return false; - } - r->sym_ptr_ptr = &h->sym; - } - - /* If this is an inplace reloc, write the addend to the object file. - Otherwise, store it in the reloc addend. */ - if (! r->howto->partial_inplace) - r->addend = link_order->u.reloc.p->addend; - else - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - boolean ok; - - size = bfd_get_reloc_size (r->howto); - buf = (bfd_byte *) bfd_zmalloc (size); - if (buf == (bfd_byte *) NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - rstat = _bfd_relocate_contents (r->howto, abfd, - link_order->u.reloc.p->addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - if (! ((*info->callbacks->reloc_overflow) - (info, - (link_order->type == bfd_section_reloc_link_order - ? bfd_section_name (abfd, link_order->u.reloc.p->u.section) - : link_order->u.reloc.p->u.name), - r->howto->name, link_order->u.reloc.p->addend, - (bfd *) NULL, (asection *) NULL, (bfd_vma) 0))) - { - free (buf); - return false; - } - break; - } - ok = bfd_set_section_contents (abfd, sec, (PTR) buf, - (file_ptr) link_order->offset, size); - free (buf); - if (! ok) - return false; - - r->addend = 0; - } - - sec->orelocation[sec->reloc_count] = r; - ++sec->reloc_count; - - return true; -} - -/* Allocate a new link_order for a section. */ - -struct bfd_link_order * -bfd_new_link_order (abfd, section) - bfd *abfd; - asection *section; -{ - struct bfd_link_order *new; - - new = ((struct bfd_link_order *) - bfd_alloc_by_size_t (abfd, sizeof (struct bfd_link_order))); - if (!new) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - new->type = bfd_undefined_link_order; - new->offset = 0; - new->size = 0; - new->next = (struct bfd_link_order *) NULL; - - if (section->link_order_tail != (struct bfd_link_order *) NULL) - section->link_order_tail->next = new; - else - section->link_order_head = new; - section->link_order_tail = new; - - return new; -} - -/* Default link order processing routine. Note that we can not handle - the reloc_link_order types here, since they depend upon the details - of how the particular backends generates relocs. */ - -boolean -_bfd_default_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - switch (link_order->type) - { - case bfd_undefined_link_order: - case bfd_section_reloc_link_order: - case bfd_symbol_reloc_link_order: - default: - abort (); - case bfd_indirect_link_order: - return default_indirect_link_order (abfd, info, sec, link_order); - case bfd_fill_link_order: - return default_fill_link_order (abfd, info, sec, link_order); - case bfd_data_link_order: - return bfd_set_section_contents (abfd, sec, - (PTR) link_order->u.data.contents, - (file_ptr) link_order->offset, - link_order->size); - } -} - -/* Default routine to handle a bfd_fill_link_order. */ - -/*ARGSUSED*/ -static boolean -default_fill_link_order (abfd, info, sec, link_order) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - struct bfd_link_order *link_order; -{ - size_t size; - char *space; - size_t i; - int fill; - boolean result; - - BFD_ASSERT ((sec->flags & SEC_HAS_CONTENTS) != 0); - - size = (size_t) link_order->size; - space = (char *) malloc (size); - if (space == NULL && size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - fill = link_order->u.fill.value; - for (i = 0; i < size; i += 2) - space[i] = fill >> 8; - for (i = 1; i < size; i += 2) - space[i] = fill; - result = bfd_set_section_contents (abfd, sec, space, - (file_ptr) link_order->offset, - link_order->size); - free (space); - return result; -} - -/* Default routine to handle a bfd_indirect_link_order. */ - -static boolean -default_indirect_link_order (output_bfd, info, output_section, link_order) - bfd *output_bfd; - struct bfd_link_info *info; - asection *output_section; - struct bfd_link_order *link_order; -{ - asection *input_section; - bfd *input_bfd; - bfd_byte *contents = NULL; - bfd_byte *new_contents; - - BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0); - - if (link_order->size == 0) - return true; - - input_section = link_order->u.indirect.section; - input_bfd = input_section->owner; - - BFD_ASSERT (input_section->output_section == output_section); - BFD_ASSERT (input_section->output_offset == link_order->offset); - BFD_ASSERT (input_section->_cooked_size == link_order->size); - - if (info->relocateable - && input_section->reloc_count > 0 - && output_section->orelocation == (arelent **) NULL) - { - /* Space has not been allocated for the output relocations. - This can happen when we are called by a specific backend - because somebody is attempting to link together different - types of object files. Handling this case correctly is - difficult, and sometimes impossible. */ - abort (); - } - - /* Get the canonical symbols. The generic linker will always have - retrieved them by this point, but we may be being called by a - specific linker when linking different types of object files - together. */ - if (! generic_link_read_symbols (input_bfd)) - return false; - - /* Get and relocate the section contents. */ - contents = (bfd_byte *) malloc (bfd_section_size (input_bfd, input_section)); - if (contents == NULL && bfd_section_size (input_bfd, input_section) != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - new_contents = (bfd_get_relocated_section_contents - (output_bfd, info, link_order, contents, info->relocateable, - _bfd_generic_link_get_symbols (input_bfd))); - if (!new_contents) - goto error_return; - - /* Output the section contents. */ - if (! bfd_set_section_contents (output_bfd, output_section, - (PTR) new_contents, - link_order->offset, link_order->size)) - goto error_return; - - if (contents != NULL) - free (contents); - return true; - - error_return: - if (contents != NULL) - free (contents); - return false; -} - -/* A little routine to count the number of relocs in a link_order - list. */ - -unsigned int -_bfd_count_link_order_relocs (link_order) - struct bfd_link_order *link_order; -{ - register unsigned int c; - register struct bfd_link_order *l; - - c = 0; - for (l = link_order; l != (struct bfd_link_order *) NULL; l = l->next) - { - if (l->type == bfd_section_reloc_link_order - || l->type == bfd_symbol_reloc_link_order) - ++c; - } - - return c; -} diff --git a/gnu/usr.bin/gdb/bfd/opncls.c b/gnu/usr.bin/gdb/bfd/opncls.c deleted file mode 100644 index 2d760a1..0000000 --- a/gnu/usr.bin/gdb/bfd/opncls.c +++ /dev/null @@ -1,548 +0,0 @@ -/* opncls.c -- open and close a BFD. - Copyright (C) 1990 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "obstack.h" - -/* fdopen is a loser -- we should use stdio exclusively. Unfortunately - if we do that we can't use fcntl. */ - - -#define obstack_chunk_alloc malloc -#define obstack_chunk_free free - -/* Return a new BFD. All BFD's are allocated through this routine. */ - -bfd * -_bfd_new_bfd () -{ - bfd *nbfd; - - nbfd = (bfd *)bfd_zmalloc (sizeof (bfd)); - if (!nbfd) - { - bfd_set_error (bfd_error_no_memory); - return 0; - } - - bfd_check_init(); - if (!obstack_begin(&nbfd->memory, 128)) - { - bfd_set_error (bfd_error_no_memory); - return 0; - } - - nbfd->arch_info = &bfd_default_arch_struct; - - nbfd->direction = no_direction; - nbfd->iostream = NULL; - nbfd->where = 0; - nbfd->sections = (asection *)NULL; - nbfd->format = bfd_unknown; - nbfd->my_archive = (bfd *)NULL; - nbfd->origin = 0; - nbfd->opened_once = false; - nbfd->output_has_begun = false; - nbfd->section_count = 0; - nbfd->usrdata = (PTR)NULL; - nbfd->cacheable = false; - nbfd->flags = NO_FLAGS; - nbfd->mtime_set = false; - - return nbfd; -} - -/* Allocate a new BFD as a member of archive OBFD. */ - -bfd * -_bfd_new_bfd_contained_in (obfd) - bfd *obfd; -{ - bfd *nbfd; - - nbfd = _bfd_new_bfd(); - nbfd->xvec = obfd->xvec; - nbfd->my_archive = obfd; - nbfd->direction = read_direction; - nbfd->target_defaulted = obfd->target_defaulted; - return nbfd; -} - -/* -SECTION - Opening and closing BFDs - -*/ - -/* -FUNCTION - bfd_openr - -SYNOPSIS - bfd *bfd_openr(CONST char *filename, CONST char *target); - -DESCRIPTION - Open the file @var{filename} (using <<fopen>>) with the target - @var{target}. Return a pointer to the created BFD. - - Calls <<bfd_find_target>>, so @var{target} is interpreted as by - that function. - - If <<NULL>> is returned then an error has occured. Possible errors - are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error. -*/ - -bfd * -bfd_openr (filename, target) - CONST char *filename; - CONST char *target; -{ - bfd *nbfd; - const bfd_target *target_vec; - - nbfd = _bfd_new_bfd(); - if (nbfd == NULL) { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - return NULL; - } - - nbfd->filename = filename; - nbfd->direction = read_direction; - - if (bfd_open_file (nbfd) == NULL) { - bfd_set_error (bfd_error_system_call); /* File didn't exist, or some such */ - bfd_release(nbfd,0); - return NULL; - } - return nbfd; -} - - -/* Don't try to `optimize' this function: - - o - We lock using stack space so that interrupting the locking - won't cause a storage leak. - o - We open the file stream last, since we don't want to have to - close it if anything goes wrong. Closing the stream means closing - the file descriptor too, even though we didn't open it. - */ -/* -FUNCTION - bfd_fdopenr - -SYNOPSIS - bfd *bfd_fdopenr(CONST char *filename, CONST char *target, int fd); - -DESCRIPTION - <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>. - It opens a BFD on a file already described by the @var{fd} - supplied. - - When the file is later <<bfd_close>>d, the file descriptor will be closed. - - If the caller desires that this file descriptor be cached by BFD - (opened as needed, closed as needed to free descriptors for - other opens), with the supplied @var{fd} used as an initial - file descriptor (but subject to closure at any time), call - bfd_set_cacheable(bfd, 1) on the returned BFD. The default is to - assume no cacheing; the file descriptor will remain open until - <<bfd_close>>, and will not be affected by BFD operations on other - files. - - Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>. -*/ - -bfd * -bfd_fdopenr (filename, target, fd) - CONST char *filename; - CONST char *target; - int fd; -{ - bfd *nbfd; - const bfd_target *target_vec; - int fdflags; - - bfd_set_error (bfd_error_system_call); - -#ifdef NO_FCNTL - fdflags = O_RDWR; /* Assume full access */ -#else - fdflags = fcntl (fd, F_GETFL, NULL); -#endif - if (fdflags == -1) return NULL; - - nbfd = _bfd_new_bfd(); - - if (nbfd == NULL) { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) { - bfd_set_error (bfd_error_invalid_target); - return NULL; - } -#if defined(VMS) || defined(__GO32__) - nbfd->iostream = (char *)fopen(filename, FOPEN_RB); -#else - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (fdflags & (O_ACCMODE)) { - case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break; - case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break; - case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break; - default: abort (); - } -#endif - if (nbfd->iostream == NULL) { - (void) obstack_free (&nbfd->memory, (PTR)0); - return NULL; - } - - /* OK, put everything where it belongs */ - - nbfd->filename = filename; - - /* As a special case we allow a FD open for read/write to - be written through, although doing so requires that we end - the previous clause with a preposition. */ - /* (O_ACCMODE) parens are to avoid Ultrix header file bug */ - switch (fdflags & (O_ACCMODE)) { - case O_RDONLY: nbfd->direction = read_direction; break; - case O_WRONLY: nbfd->direction = write_direction; break; - case O_RDWR: nbfd->direction = both_direction; break; - default: abort (); - } - - if (! bfd_cache_init (nbfd)) - return NULL; - - return nbfd; -} - -/** bfd_openw -- open for writing. - Returns a pointer to a freshly-allocated BFD on success, or NULL. - - See comment by bfd_fdopenr before you try to modify this function. */ - -/* -FUNCTION - bfd_openw - -SYNOPSIS - bfd *bfd_openw(CONST char *filename, CONST char *target); - -DESCRIPTION - Create a BFD, associated with file @var{filename}, using the - file format @var{target}, and return a pointer to it. - - Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>, - <<bfd_error_invalid_target>>. -*/ - -bfd * -bfd_openw (filename, target) - CONST char *filename; - CONST char *target; -{ - bfd *nbfd; - const bfd_target *target_vec; - - bfd_set_error (bfd_error_system_call); - - /* nbfd has to point to head of malloc'ed block so that bfd_close may - reclaim it correctly. */ - - nbfd = _bfd_new_bfd(); - if (nbfd == NULL) { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - target_vec = bfd_find_target (target, nbfd); - if (target_vec == NULL) return NULL; - - nbfd->filename = filename; - nbfd->direction = write_direction; - - if (bfd_open_file (nbfd) == NULL) { - bfd_set_error (bfd_error_system_call); /* File not writeable, etc */ - (void) obstack_free (&nbfd->memory, (PTR)0); - return NULL; - } - return nbfd; -} - -/* - -FUNCTION - bfd_close - -SYNOPSIS - boolean bfd_close(bfd *abfd); - -DESCRIPTION - - Close a BFD. If the BFD was open for writing, - then pending operations are completed and the file written out - and closed. If the created file is executable, then - <<chmod>> is called to mark it as such. - - All memory attached to the BFD's obstacks is released. - - The file descriptor associated with the BFD is closed (even - if it was passed in to BFD by <<bfd_fdopenr>>). - -RETURNS - <<true>> is returned if all is ok, otherwise <<false>>. -*/ - - -boolean -bfd_close (abfd) - bfd *abfd; -{ - boolean ret; - - if (!bfd_read_p(abfd)) - if (BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)) != true) - return false; - - if (BFD_SEND (abfd, _close_and_cleanup, (abfd)) != true) return false; - - ret = bfd_cache_close(abfd); - - /* If the file was open for writing and is now executable, - make it so */ - if (ret == true - && abfd->direction == write_direction - && abfd->flags & EXEC_P) { - struct stat buf; - stat(abfd->filename, &buf); -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 /* Execute by group. */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 /* Execute by others. */ -#endif - - chmod(abfd->filename, 0777 & (buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH)); - } - (void) obstack_free (&abfd->memory, (PTR)0); - (void) free(abfd); - return ret; -} - -/* -FUNCTION - bfd_close_all_done - -SYNOPSIS - boolean bfd_close_all_done(bfd *); - -DESCRIPTION - Close a BFD. Differs from <<bfd_close>> - since it does not complete any pending operations. This - routine would be used if the application had just used BFD for - swapping and didn't want to use any of the writing code. - - If the created file is executable, then <<chmod>> is called - to mark it as such. - - All memory attached to the BFD's obstacks is released. - -RETURNS - <<true>> is returned if all is ok, otherwise <<false>>. - -*/ - -boolean -bfd_close_all_done (abfd) - bfd *abfd; -{ - boolean ret; - - ret = bfd_cache_close(abfd); - - /* If the file was open for writing and is now executable, - make it so */ - if (ret == true - && abfd->direction == write_direction - && abfd->flags & EXEC_P) { - struct stat buf; - stat(abfd->filename, &buf); -#ifndef S_IXUSR -#define S_IXUSR 0100 /* Execute by owner. */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 /* Execute by group. */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 /* Execute by others. */ -#endif - - chmod(abfd->filename, 0x777 &(buf.st_mode | S_IXUSR | S_IXGRP | S_IXOTH)); - } - (void) obstack_free (&abfd->memory, (PTR)0); - (void) free(abfd); - return ret; -} - - -/* -FUNCTION - bfd_alloc_size - -SYNOPSIS - bfd_size_type bfd_alloc_size(bfd *abfd); - -DESCRIPTION - Return the number of bytes in the obstacks connected to @var{abfd}. - -*/ - -bfd_size_type -bfd_alloc_size (abfd) - bfd *abfd; -{ - struct _obstack_chunk *chunk = abfd->memory.chunk; - size_t size = 0; - while (chunk) { - size += chunk->limit - &(chunk->contents[0]); - chunk = chunk->prev; - } - return size; -} - - - -/* -FUNCTION - bfd_create - -SYNOPSIS - bfd *bfd_create(CONST char *filename, bfd *templ); - -DESCRIPTION - Create a new BFD in the manner of - <<bfd_openw>>, but without opening a file. The new BFD - takes the target from the target used by @var{template}. The - format is always set to <<bfd_object>>. - -*/ - -bfd * -bfd_create (filename, templ) - CONST char *filename; - bfd *templ; -{ - bfd *nbfd = _bfd_new_bfd(); - if (nbfd == (bfd *)NULL) { - bfd_set_error (bfd_error_no_memory); - return (bfd *)NULL; - } - nbfd->filename = filename; - if(templ) { - nbfd->xvec = templ->xvec; - } - nbfd->direction = no_direction; - bfd_set_format(nbfd, bfd_object); - return nbfd; -} - -/* -INTERNAL_FUNCTION - bfd_alloc_by_size_t - -SYNOPSIS - PTR bfd_alloc_by_size_t(bfd *abfd, size_t wanted); - -DESCRIPTION - Allocate a block of @var{wanted} bytes of memory in the obstack - attatched to <<abfd>> and return a pointer to it. -*/ - - -PTR -bfd_alloc_by_size_t (abfd, size) - bfd *abfd; - size_t size; -{ - return obstack_alloc(&(abfd->memory), size); -} - -void -bfd_alloc_grow (abfd, ptr, size) - bfd *abfd; - PTR ptr; - size_t size; -{ - (void) obstack_grow(&(abfd->memory), ptr, size); -} - -PTR -bfd_alloc_finish (abfd) - bfd *abfd; -{ - return obstack_finish(&(abfd->memory)); -} - -PTR -bfd_alloc (abfd, size) - bfd *abfd; - size_t size; -{ - return bfd_alloc_by_size_t(abfd, (size_t)size); -} - -PTR -bfd_zalloc (abfd, size) - bfd *abfd; - size_t size; -{ - PTR res; - res = bfd_alloc(abfd, size); - if (res) - memset(res, 0, (size_t)size); - return res; -} - -PTR -bfd_realloc (abfd, old, size) - bfd *abfd; - PTR old; - size_t size; -{ - PTR res = bfd_alloc(abfd, size); - if (res) - memcpy(res, old, (size_t)size); - return res; -} diff --git a/gnu/usr.bin/gdb/bfd/reloc.c b/gnu/usr.bin/gdb/bfd/reloc.c deleted file mode 100644 index edb8903..0000000 --- a/gnu/usr.bin/gdb/bfd/reloc.c +++ /dev/null @@ -1,1635 +0,0 @@ -/* BFD support for handling relocation entries. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - Relocations - - BFD maintains relocations in much the same way it maintains - symbols: they are left alone until required, then read in - en-mass and translated into an internal form. A common - routine <<bfd_perform_relocation>> acts upon the - canonical form to do the fixup. - - Relocations are maintained on a per section basis, - while symbols are maintained on a per BFD basis. - - All that a back end has to do to fit the BFD interface is to create - a <<struct reloc_cache_entry>> for each relocation - in a particular section, and fill in the right bits of the structures. - -@menu -@* typedef arelent:: -@* howto manager:: -@end menu - -*/ -#include "bfd.h" -#include "sysdep.h" -#include "bfdlink.h" -#include "libbfd.h" -/* -DOCDD -INODE - typedef arelent, howto manager, Relocations, Relocations - -SUBSECTION - typedef arelent - - This is the structure of a relocation entry: - -CODE_FRAGMENT -. -.typedef enum bfd_reloc_status -.{ -. {* No errors detected *} -. bfd_reloc_ok, -. -. {* The relocation was performed, but there was an overflow. *} -. bfd_reloc_overflow, -. -. {* The address to relocate was not within the section supplied. *} -. bfd_reloc_outofrange, -. -. {* Used by special functions *} -. bfd_reloc_continue, -. -. {* Unsupported relocation size requested. *} -. bfd_reloc_notsupported, -. -. {* Unused *} -. bfd_reloc_other, -. -. {* The symbol to relocate against was undefined. *} -. bfd_reloc_undefined, -. -. {* The relocation was performed, but may not be ok - presently -. generated only when linking i960 coff files with i960 b.out -. symbols. If this type is returned, the error_message argument -. to bfd_perform_relocation will be set. *} -. bfd_reloc_dangerous -. } -. bfd_reloc_status_type; -. -. -.typedef struct reloc_cache_entry -.{ -. {* A pointer into the canonical table of pointers *} -. struct symbol_cache_entry **sym_ptr_ptr; -. -. {* offset in section *} -. bfd_size_type address; -. -. {* addend for relocation value *} -. bfd_vma addend; -. -. {* Pointer to how to perform the required relocation *} -. const struct reloc_howto_struct *howto; -. -.} arelent; - -*/ - -/* -DESCRIPTION - - Here is a description of each of the fields within an <<arelent>>: - - o <<sym_ptr_ptr>> - - The symbol table pointer points to a pointer to the symbol - associated with the relocation request. It is - the pointer into the table returned by the back end's - <<get_symtab>> action. @xref{Symbols}. The symbol is referenced - through a pointer to a pointer so that tools like the linker - can fix up all the symbols of the same name by modifying only - one pointer. The relocation routine looks in the symbol and - uses the base of the section the symbol is attached to and the - value of the symbol as the initial relocation offset. If the - symbol pointer is zero, then the section provided is looked up. - - o <<address>> - - The <<address>> field gives the offset in bytes from the base of - the section data which owns the relocation record to the first - byte of relocatable information. The actual data relocated - will be relative to this point; for example, a relocation - type which modifies the bottom two bytes of a four byte word - would not touch the first byte pointed to in a big endian - world. - - o <<addend>> - - The <<addend>> is a value provided by the back end to be added (!) - to the relocation offset. Its interpretation is dependent upon - the howto. For example, on the 68k the code: - - -| char foo[]; -| main() -| { -| return foo[0x12345678]; -| } - - Could be compiled into: - -| linkw fp,#-4 -| moveb @@#12345678,d0 -| extbl d0 -| unlk fp -| rts - - - This could create a reloc pointing to <<foo>>, but leave the - offset in the data, something like: - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000006 32 _foo -| -|00000000 4e56 fffc ; linkw fp,#-4 -|00000004 1039 1234 5678 ; moveb @@#12345678,d0 -|0000000a 49c0 ; extbl d0 -|0000000c 4e5e ; unlk fp -|0000000e 4e75 ; rts - - - Using coff and an 88k, some instructions don't have enough - space in them to represent the full address range, and - pointers have to be loaded in two parts. So you'd get something like: - - -| or.u r13,r0,hi16(_foo+0x12345678) -| ld.b r2,r13,lo16(_foo+0x12345678) -| jmp r1 - - - This should create two relocs, both pointing to <<_foo>>, and with - 0x12340000 in their addend field. The data would consist of: - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000002 HVRT16 _foo+0x12340000 -|00000006 LVRT16 _foo+0x12340000 -| -|00000000 5da05678 ; or.u r13,r0,0x5678 -|00000004 1c4d5678 ; ld.b r2,r13,0x5678 -|00000008 f400c001 ; jmp r1 - - - The relocation routine digs out the value from the data, adds - it to the addend to get the original offset, and then adds the - value of <<_foo>>. Note that all 32 bits have to be kept around - somewhere, to cope with carry from bit 15 to bit 16. - - One further example is the sparc and the a.out format. The - sparc has a similar problem to the 88k, in that some - instructions don't have room for an entire offset, but on the - sparc the parts are created in odd sized lumps. The designers of - the a.out format chose to not use the data within the section - for storing part of the offset; all the offset is kept within - the reloc. Anything in the data should be ignored. - -| save %sp,-112,%sp -| sethi %hi(_foo+0x12345678),%g2 -| ldsb [%g2+%lo(_foo+0x12345678)],%i0 -| ret -| restore - - Both relocs contain a pointer to <<foo>>, and the offsets - contain junk. - - -|RELOCATION RECORDS FOR [.text]: -|offset type value -|00000004 HI22 _foo+0x12345678 -|00000008 LO10 _foo+0x12345678 -| -|00000000 9de3bf90 ; save %sp,-112,%sp -|00000004 05000000 ; sethi %hi(_foo+0),%g2 -|00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 -|0000000c 81c7e008 ; ret -|00000010 81e80000 ; restore - - - o <<howto>> - - The <<howto>> field can be imagined as a - relocation instruction. It is a pointer to a structure which - contains information on what to do with all of the other - information in the reloc record and data section. A back end - would normally have a relocation instruction set and turn - relocations into pointers to the correct structure on input - - but it would be possible to create each howto field on demand. - -*/ - -/* -SUBSUBSECTION - <<enum complain_overflow>> - - Indicates what sort of overflow checking should be done when - performing a relocation. - -CODE_FRAGMENT -. -.enum complain_overflow -.{ -. {* Do not complain on overflow. *} -. complain_overflow_dont, -. -. {* Complain if the bitfield overflows, whether it is considered -. as signed or unsigned. *} -. complain_overflow_bitfield, -. -. {* Complain if the value overflows when considered as signed -. number. *} -. complain_overflow_signed, -. -. {* Complain if the value overflows when considered as an -. unsigned number. *} -. complain_overflow_unsigned -.}; - -*/ - -/* -SUBSUBSECTION - <<reloc_howto_type>> - - The <<reloc_howto_type>> is a structure which contains all the - information that libbfd needs to know to tie up a back end's data. - -CODE_FRAGMENT -.struct symbol_cache_entry; {* Forward declaration *} -. -.typedef unsigned char bfd_byte; -.typedef struct reloc_howto_struct reloc_howto_type; -. -.struct reloc_howto_struct -.{ -. {* The type field has mainly a documetary use - the back end can -. do what it wants with it, though normally the back end's -. external idea of what a reloc number is stored -. in this field. For example, a PC relative word relocation -. in a coff environment has the type 023 - because that's -. what the outside world calls a R_PCRWORD reloc. *} -. unsigned int type; -. -. {* The value the final relocation is shifted right by. This drops -. unwanted data from the relocation. *} -. unsigned int rightshift; -. -. {* The size of the item to be relocated. This is *not* a -. power-of-two measure. To get the number of bytes operated -. on by a type of relocation, use bfd_get_reloc_size. *} -. int size; -. -. {* The number of bits in the item to be relocated. This is used -. when doing overflow checking. *} -. unsigned int bitsize; -. -. {* Notes that the relocation is relative to the location in the -. data section of the addend. The relocation function will -. subtract from the relocation value the address of the location -. being relocated. *} -. boolean pc_relative; -. -. {* The bit position of the reloc value in the destination. -. The relocated value is left shifted by this amount. *} -. unsigned int bitpos; -. -. {* What type of overflow error should be checked for when -. relocating. *} -. enum complain_overflow complain_on_overflow; -. -. {* If this field is non null, then the supplied function is -. called rather than the normal function. This allows really -. strange relocation methods to be accomodated (e.g., i960 callj -. instructions). *} -. bfd_reloc_status_type (*special_function) -. PARAMS ((bfd *abfd, -. arelent *reloc_entry, -. struct symbol_cache_entry *symbol, -. PTR data, -. asection *input_section, -. bfd *output_bfd, -. char **error_message)); -. -. {* The textual name of the relocation type. *} -. char *name; -. -. {* When performing a partial link, some formats must modify the -. relocations rather than the data - this flag signals this.*} -. boolean partial_inplace; -. -. {* The src_mask selects which parts of the read in data -. are to be used in the relocation sum. E.g., if this was an 8 bit -. bit of data which we read and relocated, this would be -. 0x000000ff. When we have relocs which have an addend, such as -. sun4 extended relocs, the value in the offset part of a -. relocating field is garbage so we never use it. In this case -. the mask would be 0x00000000. *} -. bfd_vma src_mask; -. -. {* The dst_mask selects which parts of the instruction are replaced -. into the instruction. In most cases src_mask == dst_mask, -. except in the above special case, where dst_mask would be -. 0x000000ff, and src_mask would be 0x00000000. *} -. bfd_vma dst_mask; -. -. {* When some formats create PC relative instructions, they leave -. the value of the pc of the place being relocated in the offset -. slot of the instruction, so that a PC relative relocation can -. be made just by adding in an ordinary offset (e.g., sun3 a.out). -. Some formats leave the displacement part of an instruction -. empty (e.g., m88k bcs); this flag signals the fact.*} -. boolean pcrel_offset; -. -.}; - -*/ - -/* -FUNCTION - The HOWTO Macro - -DESCRIPTION - The HOWTO define is horrible and will go away. - - -.#define HOWTO(C, R,S,B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ -. {(unsigned)C,R,S,B, P, BI, O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC} - -DESCRIPTION - And will be replaced with the totally magic way. But for the - moment, we are compatible, so do it this way. - - -.#define NEWHOWTO( FUNCTION, NAME,SIZE,REL,IN) HOWTO(0,0,SIZE,0,REL,0,complain_overflow_dont,FUNCTION, NAME,false,0,0,IN) -. -DESCRIPTION - Helper routine to turn a symbol into a relocation value. - -.#define HOWTO_PREPARE(relocation, symbol) \ -. { \ -. if (symbol != (asymbol *)NULL) { \ -. if (bfd_is_com_section (symbol->section)) { \ -. relocation = 0; \ -. } \ -. else { \ -. relocation = symbol->value; \ -. } \ -. } \ -.} - -*/ - -/* -FUNCTION - bfd_get_reloc_size - -SYNOPSIS - int bfd_get_reloc_size (const reloc_howto_type *); - -DESCRIPTION - For a reloc_howto_type that operates on a fixed number of bytes, - this returns the number of bytes operated on. - */ - -int -bfd_get_reloc_size (howto) - const reloc_howto_type *howto; -{ - switch (howto->size) - { - case 0: return 1; - case 1: return 2; - case 2: return 4; - case 3: return 0; - case 4: return 8; - case -2: return 4; - default: abort (); - } -} - -/* -TYPEDEF - arelent_chain - -DESCRIPTION - - How relocs are tied together in an <<asection>>: - -.typedef struct relent_chain { -. arelent relent; -. struct relent_chain *next; -.} arelent_chain; - -*/ - - - -/* -FUNCTION - bfd_perform_relocation - -SYNOPSIS - bfd_reloc_status_type - bfd_perform_relocation - (bfd *abfd, - arelent *reloc_entry, - PTR data, - asection *input_section, - bfd *output_bfd, - char **error_message); - -DESCRIPTION - If @var{output_bfd} is supplied to this function, the - generated image will be relocatable; the relocations are - copied to the output file after they have been changed to - reflect the new state of the world. There are two ways of - reflecting the results of partial linkage in an output file: - by modifying the output data in place, and by modifying the - relocation record. Some native formats (e.g., basic a.out and - basic coff) have no way of specifying an addend in the - relocation type, so the addend has to go in the output data. - This is no big deal since in these formats the output data - slot will always be big enough for the addend. Complex reloc - types with addends were invented to solve just this problem. - The @var{error_message} argument is set to an error message if - this return @code{bfd_reloc_dangerous}. - -*/ - - -bfd_reloc_status_type -bfd_perform_relocation (abfd, reloc_entry, data, input_section, output_bfd, - error_message) - bfd *abfd; - arelent *reloc_entry; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; -{ - bfd_vma relocation; - bfd_reloc_status_type flag = bfd_reloc_ok; - bfd_size_type addr = reloc_entry->address; - bfd_vma output_base = 0; - const reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asymbol *symbol; - - symbol = *(reloc_entry->sym_ptr_ptr); - if (bfd_is_abs_section (symbol->section) - && output_bfd != (bfd *) NULL) - { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; - } - - /* If we are not producing relocateable output, return an error if - the symbol is not defined. An undefined weak symbol is - considered to have a value of zero (SVR4 ABI, p. 4-27). */ - if (bfd_is_und_section (symbol->section) - && (symbol->flags & BSF_WEAK) == 0 - && output_bfd == (bfd *) NULL) - flag = bfd_reloc_undefined; - - /* If there is a function supplied to handle this relocation type, - call it. It'll return `bfd_reloc_continue' if further processing - can be done. */ - if (howto->special_function) - { - bfd_reloc_status_type cont; - cont = howto->special_function (abfd, reloc_entry, symbol, data, - input_section, output_bfd, - error_message); - if (cont != bfd_reloc_continue) - return cont; - } - - /* Is the address of the relocation really within the section? */ - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* Work out which section the relocation is targetted at and the - initial relocation command value. */ - - /* Get symbol value. (Common symbols are special.) */ - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; - - - reloc_target_output_section = symbol->section->output_section; - - /* Convert input-section-relative symbol value to absolute. */ - if (output_bfd && howto->partial_inplace == false) - output_base = 0; - else - output_base = reloc_target_output_section->vma; - - relocation += output_base + symbol->section->output_offset; - - /* Add in supplied addend. */ - relocation += reloc_entry->addend; - - /* Here the variable relocation holds the final address of the - symbol we are relocating against, plus any addend. */ - - if (howto->pc_relative == true) - { - /* This is a PC relative relocation. We want to set RELOCATION - to the distance between the address of the symbol and the - location. RELOCATION is already the address of the symbol. - - We start by subtracting the address of the section containing - the location. - - If pcrel_offset is set, we must further subtract the position - of the location within the section. Some targets arrange for - the addend to be the negative of the position of the location - within the section; for example, i386-aout does this. For - i386-aout, pcrel_offset is false. Some other targets do not - include the position of the location; for example, m88kbcs, - or ELF. For those targets, pcrel_offset is true. - - If we are producing relocateable output, then we must ensure - that this reloc will be correctly computed when the final - relocation is done. If pcrel_offset is false we want to wind - up with the negative of the location within the section, - which means we must adjust the existing addend by the change - in the location within the section. If pcrel_offset is true - we do not want to adjust the existing addend at all. - - FIXME: This seems logical to me, but for the case of - producing relocateable output it is not what the code - actually does. I don't want to change it, because it seems - far too likely that something will break. */ - - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true) - relocation -= reloc_entry->address; - } - - if (output_bfd != (bfd *) NULL) - { - if (howto->partial_inplace == false) - { - /* This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. */ - reloc_entry->addend = relocation; - reloc_entry->address += input_section->output_offset; - return flag; - } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol. */ - - reloc_entry->address += input_section->output_offset; - - /* WTF?? */ - if (abfd->xvec->flavour == bfd_target_coff_flavour - && strcmp (abfd->xvec->name, "aixcoff-rs6000") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-little") != 0 - && strcmp (abfd->xvec->name, "coff-Intel-big") != 0) - { -#if 1 - /* For m68k-coff, the addend was being subtracted twice during - relocation with -r. Removing the line below this comment - fixes that problem; see PR 2953. - -However, Ian wrote the following, regarding removing the line below, -which explains why it is still enabled: --djm - -If you put a patch like that into BFD you need to check all the COFF -linkers. I am fairly certain that patch will break coff-i386 (e.g., -SCO); see coff_i386_reloc in coff-i386.c where I worked around the -problem in a different way. There may very well be a reason that the -code works as it does. - -Hmmm. The first obvious point is that bfd_perform_relocation should -not have any tests that depend upon the flavour. It's seem like -entirely the wrong place for such a thing. The second obvious point -is that the current code ignores the reloc addend when producing -relocateable output for COFF. That's peculiar. In fact, I really -have no idea what the point of the line you want to remove is. - -A typical COFF reloc subtracts the old value of the symbol and adds in -the new value to the location in the object file (if it's a pc -relative reloc it adds the difference between the symbol value and the -location). When relocating we need to preserve that property. - -BFD handles this by setting the addend to the negative of the old -value of the symbol. Unfortunately it handles common symbols in a -non-standard way (it doesn't subtract the old value) but that's a -different story (we can't change it without losing backward -compatibility with old object files) (coff-i386 does subtract the old -value, to be compatible with existing coff-i386 targets, like SCO). - -So everything works fine when not producing relocateable output. When -we are producing relocateable output, logically we should do exactly -what we do when not producing relocateable output. Therefore, your -patch is correct. In fact, it should probably always just set -reloc_entry->addend to 0 for all cases, since it is, in fact, going to -add the value into the object file. This won't hurt the COFF code, -which doesn't use the addend; I'm not sure what it will do to other -formats (the thing to check for would be whether any formats both use -the addend and set partial_inplace). - -When I wanted to make coff-i386 produce relocateable output, I ran -into the problem that you are running into: I wanted to remove that -line. Rather than risk it, I made the coff-i386 relocs use a special -function; it's coff_i386_reloc in coff-i386.c. The function -specifically adds the addend field into the object file, knowing that -bfd_perform_relocation is not going to. If you remove that line, then -coff-i386.c will wind up adding the addend field in twice. It's -trivial to fix; it just needs to be done. - -The problem with removing the line is just that it may break some -working code. With BFD it's hard to be sure of anything. The right -way to deal with this is simply to build and test at least all the -supported COFF targets. It should be straightforward if time and disk -space consuming. For each target: - 1) build the linker - 2) generate some executable, and link it using -r (I would - probably use paranoia.o and link against newlib/libc.a, which - for all the supported targets would be available in - /usr/cygnus/progressive/H-host/target/lib/libc.a). - 3) make the change to reloc.c - 4) rebuild the linker - 5) repeat step 2 - 6) if the resulting object files are the same, you have at least - made it no worse - 7) if they are different you have to figure out which version is - right -*/ - relocation -= reloc_entry->addend; -#endif - reloc_entry->addend = 0; - } - else - { - reloc_entry->addend = relocation; - } - } - } - else - { - reloc_entry->addend = 0; - } - - /* FIXME: This overflow checking is incomplete, because the value - might have overflowed before we get here. For a correct check we - need to compute the value in a size larger than bitsize, but we - can't reasonably do that for a reloc the same size as a host - machine word. - FIXME: We should also do overflow checking on the result after - adding in the value contained in the object file. */ - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - - /* Get the value that will be used for the relocation, but - starting at bit position zero. */ - if (howto->rightshift > howto->bitpos) - check = relocation >> (howto->rightshift - howto->bitpos); - else - check = relocation << (howto->bitpos - howto->rightshift); - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - /* The above right shift is incorrect for a signed value. - Fix it up by forcing on the upper bits. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if ((bfd_signed_vma) check > reloc_signed_max - || (bfd_signed_vma) check < reloc_signed_min) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((bfd_vma) check > reloc_unsigned_max) - flag = bfd_reloc_overflow; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && ((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - { - /* The above right shift is incorrect for a signed - value. See if turning on the upper bits fixes the - overflow. */ - if (howto->rightshift > howto->bitpos - && (bfd_signed_vma) relocation < 0) - { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> (howto->rightshift - howto->bitpos))); - if (((bfd_vma) check & ~reloc_bits) != (-1 & ~reloc_bits)) - flag = bfd_reloc_overflow; - } - else - flag = bfd_reloc_overflow; - } - } - break; - default: - abort (); - } - } - - /* - Either we are relocating all the way, or we don't want to apply - the relocation to the reloc entry (probably because there isn't - any room in the output format to describe addends to relocs) - */ - - /* The cast to bfd_vma avoids a bug in the Alpha OSF/1 C compiler - (OSF version 1.3, compiler version 3.11). It miscompiles the - following program: - - struct str - { - unsigned int i0; - } s = { 0 }; - - int - main () - { - unsigned long x; - - x = 0x100000000; - x <<= (unsigned long) s.i0; - if (x == 0) - printf ("failed\n"); - else - printf ("succeeded (%lx)\n", x); - } - */ - - relocation >>= (bfd_vma) howto->rightshift; - - /* Shift everything up to where it's going to be used */ - - relocation <<= (bfd_vma) howto->bitpos; - - /* Wait for the day when all have the mask in them */ - - /* What we do: - i instruction to be left alone - o offset within instruction - r relocation offset to apply - S src mask - D dst mask - N ~dst mask - A part 1 - B part 2 - R result - - Do this: - i i i i i o o o o o from bfd_get<size> - and S S S S S to get the size offset we want - + r r r r r r r r r r to get the final value to place - and D D D D D to chop to right size - ----------------------- - A A A A A - And this: - ... i i i i i o o o o o from bfd_get<size> - and N N N N N get instruction - ----------------------- - ... B B B B B - - And then: - B B B B B - or A A A A A - ----------------------- - R R R R R R R R R R put into bfd_put<size> - */ - -#define DOIT(x) \ - x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - - switch (howto->size) - { - case 0: - { - char x = bfd_get_8 (abfd, (char *) data + addr); - DOIT (x); - bfd_put_8 (abfd, x, (unsigned char *) data + addr); - } - break; - - case 1: - if (relocation) - { - short x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_16 (abfd, x, (unsigned char *) data + addr); - } - break; - case 2: - if (relocation) - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); - } - break; - case -2: - { - long x = bfd_get_32 (abfd, (bfd_byte *) data + addr); - relocation = -relocation; - DOIT (x); - bfd_put_32 (abfd, x, (bfd_byte *) data + addr); - } - break; - - case 3: - /* Do nothing */ - break; - - case 4: -#ifdef BFD64 - if (relocation) - { - bfd_vma x = bfd_get_64 (abfd, (bfd_byte *) data + addr); - DOIT (x); - bfd_put_64 (abfd, x, (bfd_byte *) data + addr); - } -#else - abort (); -#endif - break; - default: - return bfd_reloc_other; - } - - return flag; -} - -/* This relocation routine is used by some of the backend linkers. - They do not construct asymbol or arelent structures, so there is no - reason for them to use bfd_perform_relocation. Also, - bfd_perform_relocation is so hacked up it is easier to write a new - function than to try to deal with it. - - This routine does a final relocation. It should not be used when - generating relocateable output. - - FIXME: This routine ignores any special_function in the HOWTO, - since the existing special_function values have been written for - bfd_perform_relocation. - - HOWTO is the reloc howto information. - INPUT_BFD is the BFD which the reloc applies to. - INPUT_SECTION is the section which the reloc applies to. - CONTENTS is the contents of the section. - ADDRESS is the address of the reloc within INPUT_SECTION. - VALUE is the value of the symbol the reloc refers to. - ADDEND is the addend of the reloc. */ - -bfd_reloc_status_type -_bfd_final_link_relocate (howto, input_bfd, input_section, contents, address, - value, addend) - const reloc_howto_type *howto; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma address; - bfd_vma value; - bfd_vma addend; -{ - bfd_vma relocation; - - /* Sanity check the address. */ - if (address > input_section->_cooked_size) - return bfd_reloc_outofrange; - - /* This function assumes that we are dealing with a basic relocation - against a symbol. We want to compute the value of the symbol to - relocate to. This is just VALUE, the value of the symbol, plus - ADDEND, any addend associated with the reloc. */ - relocation = value + addend; - - /* If the relocation is PC relative, we want to set RELOCATION to - the distance between the symbol (currently in RELOCATION) and the - location we are relocating. Some targets (e.g., i386-aout) - arrange for the contents of the section to be the negative of the - offset of the location within the section; for such targets - pcrel_offset is false. Other targets (e.g., m88kbcs or ELF) - simply leave the contents of the section as zero; for such - targets pcrel_offset is true. If pcrel_offset is false we do not - need to subtract out the offset of the location within the - section (which is just ADDRESS). */ - if (howto->pc_relative) - { - relocation -= (input_section->output_section->vma - + input_section->output_offset); - if (howto->pcrel_offset) - relocation -= address; - } - - return _bfd_relocate_contents (howto, input_bfd, relocation, - contents + address); -} - -/* Relocate a given location using a given value and howto. */ - -bfd_reloc_status_type -_bfd_relocate_contents (howto, input_bfd, relocation, location) - const reloc_howto_type *howto; - bfd *input_bfd; - bfd_vma relocation; - bfd_byte *location; -{ - int size; - bfd_vma x; - boolean overflow; - - /* If the size is negative, negate RELOCATION. This isn't very - general. */ - if (howto->size < 0) - relocation = -relocation; - - /* Get the value we are going to relocate. */ - size = bfd_get_reloc_size (howto); - switch (size) - { - default: - case 0: - abort (); - case 1: - x = bfd_get_8 (input_bfd, location); - break; - case 2: - x = bfd_get_16 (input_bfd, location); - break; - case 4: - x = bfd_get_32 (input_bfd, location); - break; - case 8: -#ifdef BFD64 - x = bfd_get_64 (input_bfd, location); -#else - abort (); -#endif - break; - } - - /* Check for overflow. FIXME: We may drop bits during the addition - which we don't check for. We must either check at every single - operation, which would be tedious, or we must do the computations - in a type larger than bfd_vma, which would be inefficient. */ - overflow = false; - if (howto->complain_on_overflow != complain_overflow_dont) - { - bfd_vma check; - bfd_signed_vma signed_check; - bfd_vma add; - bfd_signed_vma signed_add; - - if (howto->rightshift == 0) - { - check = relocation; - signed_check = (bfd_signed_vma) relocation; - } - else - { - /* Drop unwanted bits from the value we are relocating to. */ - check = relocation >> howto->rightshift; - - /* If this is a signed value, the rightshift just dropped - leading 1 bits (assuming twos complement). */ - if ((bfd_signed_vma) relocation >= 0) - signed_check = check; - else - signed_check = (check - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->rightshift))); - } - - /* Get the value from the object file. */ - add = x & howto->src_mask; - - /* Get the value from the object file with an appropriate sign. - The expression involving howto->src_mask isolates the upper - bit of src_mask. If that bit is set in the value we are - adding, it is negative, and we subtract out that number times - two. If src_mask includes the highest possible bit, then we - can not get the upper bit, but that does not matter since - signed_add needs no adjustment to become negative in that - case. */ - signed_add = add; - if ((add & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) - signed_add -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; - - /* Add the value from the object file, shifted so that it is a - straight number. */ - if (howto->bitpos == 0) - { - check += add; - signed_check += signed_add; - } - else - { - check += add >> howto->bitpos; - - /* For the signed case we use ADD, rather than SIGNED_ADD, - to avoid warnings from SVR4 cc. This is OK since we - explictly handle the sign bits. */ - if (signed_add >= 0) - signed_check += add >> howto->bitpos; - else - signed_check += ((add >> howto->bitpos) - | ((bfd_vma) - 1 - & ~((bfd_vma) - 1 >> howto->bitpos))); - } - - switch (howto->complain_on_overflow) - { - case complain_overflow_signed: - { - /* Assumes two's complement. */ - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; - bfd_signed_vma reloc_signed_min = ~reloc_signed_max; - - if (signed_check > reloc_signed_max - || signed_check < reloc_signed_min) - overflow = true; - } - break; - case complain_overflow_unsigned: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_unsigned_max = - (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (check > reloc_unsigned_max) - overflow = true; - } - break; - case complain_overflow_bitfield: - { - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - bfd_vma reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if ((check & ~reloc_bits) != 0 - && (((bfd_vma) signed_check & ~reloc_bits) - != (-1 & ~reloc_bits))) - overflow = true; - } - break; - default: - abort (); - } - } - - /* Put RELOCATION in the right bits. */ - relocation >>= (bfd_vma) howto->rightshift; - relocation <<= (bfd_vma) howto->bitpos; - - /* Add RELOCATION to the right bits of X. */ - x = ((x & ~howto->dst_mask) - | (((x & howto->src_mask) + relocation) & howto->dst_mask)); - - /* Put the relocated value back in the object file. */ - switch (size) - { - default: - case 0: - abort (); - case 1: - bfd_put_8 (input_bfd, x, location); - break; - case 2: - bfd_put_16 (input_bfd, x, location); - break; - case 4: - bfd_put_32 (input_bfd, x, location); - break; - case 8: -#ifdef BFD64 - bfd_put_64 (input_bfd, x, location); -#else - abort (); -#endif - break; - } - - return overflow ? bfd_reloc_overflow : bfd_reloc_ok; -} - -/* -DOCDD -INODE - howto manager, , typedef arelent, Relocations - -SECTION - The howto manager - - When an application wants to create a relocation, but doesn't - know what the target machine might call it, it can find out by - using this bit of code. - -*/ - -/* -TYPEDEF - bfd_reloc_code_type - -DESCRIPTION - The insides of a reloc code. The idea is that, eventually, there - will be one enumerator for every type of relocation we ever do. - Pass one of these values to <<bfd_reloc_type_lookup>>, and it'll - return a howto pointer. - - This does mean that the application must determine the correct - enumerator value; you can't get a howto pointer from a random set - of attributes. - -CODE_FRAGMENT -. -.typedef enum bfd_reloc_code_real -.{ -. {* Basic absolute relocations *} -. BFD_RELOC_64, -. BFD_RELOC_32, -. BFD_RELOC_26, -. BFD_RELOC_16, -. BFD_RELOC_14, -. BFD_RELOC_8, -. -. {* PC-relative relocations *} -. BFD_RELOC_64_PCREL, -. BFD_RELOC_32_PCREL, -. BFD_RELOC_24_PCREL, {* used by i960 *} -. BFD_RELOC_16_PCREL, -. BFD_RELOC_8_PCREL, -. -. {* Linkage-table relative *} -. BFD_RELOC_32_BASEREL, -. BFD_RELOC_16_BASEREL, -. BFD_RELOC_8_BASEREL, -. -. {* The type of reloc used to build a contructor table - at the moment -. probably a 32 bit wide abs address, but the cpu can choose. *} -. BFD_RELOC_CTOR, -. -. {* 8 bits wide, but used to form an address like 0xffnn *} -. BFD_RELOC_8_FFnn, -. -. {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit -. word displacement, e.g. for SPARC) *} -. BFD_RELOC_32_PCREL_S2, -. {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *} -. BFD_RELOC_16_PCREL_S2, -. {* this is used on the Alpha *} -. BFD_RELOC_23_PCREL_S2, -. -. {* High 22 bits of 32-bit value, placed into lower 22 bits of -. target word; simple reloc. *} -. BFD_RELOC_HI22, -. {* Low 10 bits. *} -. BFD_RELOC_LO10, -. -. {* For systems that allocate a Global Pointer register, these are -. displacements off that register. These relocation types are -. handled specially, because the value the register will have is -. decided relatively late. *} -. BFD_RELOC_GPREL16, -. BFD_RELOC_GPREL32, -. -. {* Reloc types used for i960/b.out. *} -. BFD_RELOC_I960_CALLJ, -. -. {* now for the sparc/elf codes *} -. BFD_RELOC_NONE, {* actually used *} -. BFD_RELOC_SPARC_WDISP22, -. BFD_RELOC_SPARC22, -. BFD_RELOC_SPARC13, -. BFD_RELOC_SPARC_GOT10, -. BFD_RELOC_SPARC_GOT13, -. BFD_RELOC_SPARC_GOT22, -. BFD_RELOC_SPARC_PC10, -. BFD_RELOC_SPARC_PC22, -. BFD_RELOC_SPARC_WPLT30, -. BFD_RELOC_SPARC_COPY, -. BFD_RELOC_SPARC_GLOB_DAT, -. BFD_RELOC_SPARC_JMP_SLOT, -. BFD_RELOC_SPARC_RELATIVE, -. BFD_RELOC_SPARC_UA32, -. -. {* these are a.out specific? *} -. BFD_RELOC_SPARC_BASE13, -. BFD_RELOC_SPARC_BASE22, -. -. {* some relocations we're using for sparc v9 -. -- subject to change *} -. BFD_RELOC_SPARC_10, -. BFD_RELOC_SPARC_11, -.#define BFD_RELOC_SPARC_64 BFD_RELOC_64 -. BFD_RELOC_SPARC_OLO10, -. BFD_RELOC_SPARC_HH22, -. BFD_RELOC_SPARC_HM10, -. BFD_RELOC_SPARC_LM22, -. BFD_RELOC_SPARC_PC_HH22, -. BFD_RELOC_SPARC_PC_HM10, -. BFD_RELOC_SPARC_PC_LM22, -. BFD_RELOC_SPARC_WDISP16, -. BFD_RELOC_SPARC_WDISP19, -. BFD_RELOC_SPARC_GLOB_JMP, -. BFD_RELOC_SPARC_LO7, -. -. {* Alpha ECOFF relocations. Some of these treat the symbol or "addend" -. in some special way. *} -. {* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when -. writing; when reading, it will be the absolute section symbol. The -. addend is the displacement in bytes of the "lda" instruction from -. the "ldah" instruction (which is at the address of this reloc). *} -. BFD_RELOC_ALPHA_GPDISP_HI16, -. {* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as -. with GPDISP_HI16 relocs. The addend is ignored when writing the -. relocations out, and is filled in with the file's GP value on -. reading, for convenience. *} -. BFD_RELOC_ALPHA_GPDISP_LO16, -. -. {* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; -. the assembler turns it into a LDQ instruction to load the address of -. the symbol, and then fills in a register in the real instruction. -. -. The LITERAL reloc, at the LDQ instruction, refers to the .lita -. section symbol. The addend is ignored when writing, but is filled -. in with the file's GP value on reading, for convenience, as with the -. GPDISP_LO16 reloc. -. -. The LITUSE reloc, on the instruction using the loaded address, gives -. information to the linker that it might be able to use to optimize -. away some literal section references. The symbol is ignored (read -. as the absolute section symbol), and the "addend" indicates the type -. of instruction using the register: -. 1 - "memory" fmt insn -. 2 - byte-manipulation (byte offset reg) -. 3 - jsr (target of branch) -. -. The GNU linker currently doesn't do any of this optimizing. *} -. BFD_RELOC_ALPHA_LITERAL, -. BFD_RELOC_ALPHA_LITUSE, -. -. {* The HINT relocation indicates a value that should be filled into the -. "hint" field of a jmp/jsr/ret instruction, for possible branch- -. prediction logic which may be provided on some processors. *} -. BFD_RELOC_ALPHA_HINT, -. -. {* Bits 27..2 of the relocation address shifted right 2 bits; -. simple reloc otherwise. *} -. BFD_RELOC_MIPS_JMP, -. -. {* High 16 bits of 32-bit value; simple reloc. *} -. BFD_RELOC_HI16, -. {* High 16 bits of 32-bit value but the low 16 bits will be sign -. extended and added to form the final result. If the low 16 -. bits form a negative number, we need to add one to the high value -. to compensate for the borrow when the low bits are added. *} -. BFD_RELOC_HI16_S, -. {* Low 16 bits. *} -. BFD_RELOC_LO16, -. {* Like BFD_RELOC_HI16_S, but PC relative. *} -. BFD_RELOC_PCREL_HI16_S, -. {* Like BFD_RELOC_LO16, but PC relative. *} -. BFD_RELOC_PCREL_LO16, -. -. {* relocation relative to the global pointer. *} -.#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16 -. -. {* Relocation against a MIPS literal section. *} -. BFD_RELOC_MIPS_LITERAL, -. -. {* MIPS ELF relocations. *} -. BFD_RELOC_MIPS_GOT16, -. BFD_RELOC_MIPS_CALL16, -.#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32 -. -. {* i386/elf relocations *} -. BFD_RELOC_386_GOT32, -. BFD_RELOC_386_PLT32, -. BFD_RELOC_386_COPY, -. BFD_RELOC_386_GLOB_DAT, -. BFD_RELOC_386_JUMP_SLOT, -. BFD_RELOC_386_RELATIVE, -. BFD_RELOC_386_GOTOFF, -. BFD_RELOC_386_GOTPC, -. -. {* ns32k relocations *} -. BFD_RELOC_NS32K_IMM_8, -. BFD_RELOC_NS32K_IMM_16, -. BFD_RELOC_NS32K_IMM_32, -. BFD_RELOC_NS32K_IMM_8_PCREL, -. BFD_RELOC_NS32K_IMM_16_PCREL, -. BFD_RELOC_NS32K_IMM_32_PCREL, -. BFD_RELOC_NS32K_DISP_8, -. BFD_RELOC_NS32K_DISP_16, -. BFD_RELOC_NS32K_DISP_32, -. BFD_RELOC_NS32K_DISP_8_PCREL, -. BFD_RELOC_NS32K_DISP_16_PCREL, -. BFD_RELOC_NS32K_DISP_32_PCREL, -. -. {* PowerPC/POWER (RS/6000) relocs. *} -. {* 26 bit relative branch. Low two bits must be zero. High 24 -. bits installed in bits 6 through 29 of instruction. *} -. BFD_RELOC_PPC_B26, -. {* 26 bit absolute branch, like BFD_RELOC_PPC_B26 but absolute. *} -. BFD_RELOC_PPC_BA26, -. {* 16 bit TOC relative reference. *} -. BFD_RELOC_PPC_TOC16, -. -. {* this must be the highest numeric value *} -. BFD_RELOC_UNUSED -. } bfd_reloc_code_real_type; -*/ - - -/* -FUNCTION - bfd_reloc_type_lookup - -SYNOPSIS - const struct reloc_howto_struct * - bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code); - -DESCRIPTION - Return a pointer to a howto structure which, when - invoked, will perform the relocation @var{code} on data from the - architecture noted. - -*/ - - -const struct reloc_howto_struct * -bfd_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - return BFD_SEND (abfd, reloc_type_lookup, (abfd, code)); -} - -static reloc_howto_type bfd_howto_32 = -HOWTO (0, 00, 2, 32, false, 0, complain_overflow_bitfield, 0, "VRT32", false, 0xffffffff, 0xffffffff, true); - - -/* -INTERNAL_FUNCTION - bfd_default_reloc_type_lookup - -SYNOPSIS - const struct reloc_howto_struct *bfd_default_reloc_type_lookup - (bfd *abfd, bfd_reloc_code_real_type code); - -DESCRIPTION - Provides a default relocation lookup routine for any architecture. - - -*/ - -const struct reloc_howto_struct * -bfd_default_reloc_type_lookup (abfd, code) - bfd *abfd; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_CTOR: - /* The type of reloc used in a ctor, which will be as wide as the - address - so either a 64, 32, or 16 bitter. */ - switch (bfd_get_arch_info (abfd)->bits_per_address) - { - case 64: - BFD_FAIL (); - case 32: - return &bfd_howto_32; - case 16: - BFD_FAIL (); - default: - BFD_FAIL (); - } - default: - BFD_FAIL (); - } - return (const struct reloc_howto_struct *) NULL; -} - - -/* -INTERNAL_FUNCTION - bfd_generic_relax_section - -SYNOPSIS - boolean bfd_generic_relax_section - (bfd *abfd, - asection *section, - struct bfd_link_info *, - boolean *); - -DESCRIPTION - Provides default handling for relaxing for back ends which - don't do relaxing -- i.e., does nothing. -*/ - -/*ARGSUSED*/ -boolean -bfd_generic_relax_section (abfd, section, link_info, again) - bfd *abfd; - asection *section; - struct bfd_link_info *link_info; - boolean *again; -{ - *again = false; - return true; -} - -/* -INTERNAL_FUNCTION - bfd_generic_get_relocated_section_contents - -SYNOPSIS - bfd_byte * - bfd_generic_get_relocated_section_contents (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - boolean relocateable, - asymbol **symbols); - -DESCRIPTION - Provides default handling of relocation effort for back ends - which can't be bothered to do it efficiently. - -*/ - -bfd_byte * -bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, - relocateable, symbols) - bfd *abfd; - struct bfd_link_info *link_info; - struct bfd_link_order *link_order; - bfd_byte *data; - boolean relocateable; - asymbol **symbols; -{ - /* Get enough memory to hold the stuff */ - bfd *input_bfd = link_order->u.indirect.section->owner; - asection *input_section = link_order->u.indirect.section; - - long reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); - arelent **reloc_vector = NULL; - long reloc_count; - - if (reloc_size < 0) - goto error_return; - - reloc_vector = (arelent **) malloc (reloc_size); - if (reloc_vector == NULL && reloc_size != 0) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } - - /* read in the section */ - if (!bfd_get_section_contents (input_bfd, - input_section, - (PTR) data, - 0, - input_section->_raw_size)) - goto error_return; - - /* We're not relaxing the section, so just copy the size info */ - input_section->_cooked_size = input_section->_raw_size; - input_section->reloc_done = true; - - reloc_count = bfd_canonicalize_reloc (input_bfd, - input_section, - reloc_vector, - symbols); - if (reloc_count < 0) - goto error_return; - - if (reloc_count > 0) - { - arelent **parent; - for (parent = reloc_vector; *parent != (arelent *) NULL; - parent++) - { - char *error_message = (char *) NULL; - bfd_reloc_status_type r = - bfd_perform_relocation (input_bfd, - *parent, - (PTR) data, - input_section, - relocateable ? abfd : (bfd *) NULL, - &error_message); - - if (relocateable) - { - asection *os = input_section->output_section; - - /* A partial link, so keep the relocs */ - os->orelocation[os->reloc_count] = *parent; - os->reloc_count++; - } - - if (r != bfd_reloc_ok) - { - switch (r) - { - case bfd_reloc_undefined: - if (!((*link_info->callbacks->undefined_symbol) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_dangerous: - BFD_ASSERT (error_message != (char *) NULL); - if (!((*link_info->callbacks->reloc_dangerous) - (link_info, error_message, input_bfd, input_section, - (*parent)->address))) - goto error_return; - break; - case bfd_reloc_overflow: - if (!((*link_info->callbacks->reloc_overflow) - (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), - (*parent)->howto->name, (*parent)->addend, - input_bfd, input_section, (*parent)->address))) - goto error_return; - break; - case bfd_reloc_outofrange: - default: - abort (); - break; - } - - } - } - } - if (reloc_vector != NULL) - free (reloc_vector); - return data; - -error_return: - if (reloc_vector != NULL) - free (reloc_vector); - return NULL; -} diff --git a/gnu/usr.bin/gdb/bfd/section.c b/gnu/usr.bin/gdb/bfd/section.c deleted file mode 100644 index bfee4b9..0000000 --- a/gnu/usr.bin/gdb/bfd/section.c +++ /dev/null @@ -1,969 +0,0 @@ -/* Object file "section" support for the BFD library. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - Sections - - The raw data contained within a BFD is maintained through the - section abstraction. A single BFD may have any number of - sections. It keeps hold of them by pointing to the first; - each one points to the next in the list. - - Sections are supported in BFD in <<section.c>>. - -@menu -@* Section Input:: -@* Section Output:: -@* typedef asection:: -@* section prototypes:: -@end menu - -INODE -Section Input, Section Output, Sections, Sections -SUBSECTION - Section input - - When a BFD is opened for reading, the section structures are - created and attached to the BFD. - - Each section has a name which describes the section in the - outside world---for example, <<a.out>> would contain at least - three sections, called <<.text>>, <<.data>> and <<.bss>>. - - Names need not be unique; for example a COFF file may have several - sections named <<.data>>. - - Sometimes a BFD will contain more than the ``natural'' number of - sections. A back end may attach other sections containing - constructor data, or an application may add a section (using - <<bfd_make_section>>) to the sections attached to an already open - BFD. For example, the linker creates an extra section - <<COMMON>> for each input file's BFD to hold information about - common storage. - - The raw data is not necessarily read in when - the section descriptor is created. Some targets may leave the - data in place until a <<bfd_get_section_contents>> call is - made. Other back ends may read in all the data at once. For - example, an S-record file has to be read once to determine the - size of the data. An IEEE-695 file doesn't contain raw data in - sections, but data and relocation expressions intermixed, so - the data area has to be parsed to get out the data and - relocations. - -INODE -Section Output, typedef asection, Section Input, Sections - -SUBSECTION - Section output - - To write a new object style BFD, the various sections to be - written have to be created. They are attached to the BFD in - the same way as input sections; data is written to the - sections using <<bfd_set_section_contents>>. - - Any program that creates or combines sections (e.g., the assembler - and linker) must use the <<asection>> fields <<output_section>> and - <<output_offset>> to indicate the file sections to which each - section must be written. (If the section is being created from - scratch, <<output_section>> should probably point to the section - itself and <<output_offset>> should probably be zero.) - - The data to be written comes from input sections attached - (via <<output_section>> pointers) to - the output sections. The output section structure can be - considered a filter for the input section: the output section - determines the vma of the output data and the name, but the - input section determines the offset into the output section of - the data to be written. - - E.g., to create a section "O", starting at 0x100, 0x123 long, - containing two subsections, "A" at offset 0x0 (i.e., at vma - 0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the <<asection>> - structures would look like: - -| section name "A" -| output_offset 0x00 -| size 0x20 -| output_section -----------> section name "O" -| | vma 0x100 -| section name "B" | size 0x123 -| output_offset 0x20 | -| size 0x103 | -| output_section --------| - - -SUBSECTION - Link orders - - The data within a section is stored in a @dfn{link_order}. - These are much like the fixups in <<gas>>. The link_order - abstraction allows a section to grow and shrink within itself. - - A link_order knows how big it is, and which is the next - link_order and where the raw data for it is; it also points to - a list of relocations which apply to it. - - The link_order is used by the linker to perform relaxing on - final code. The compiler creates code which is as big as - necessary to make it work without relaxing, and the user can - select whether to relax. Sometimes relaxing takes a lot of - time. The linker runs around the relocations to see if any - are attached to data which can be shrunk, if so it does it on - a link_order by link_order basis. - -*/ - - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - - -/* -DOCDD -INODE -typedef asection, section prototypes, Section Output, Sections -SUBSECTION - typedef asection - - Here is the section structure: - -CODE_FRAGMENT -. -.typedef struct sec -.{ -. {* The name of the section; the name isn't a copy, the pointer is -. the same as that passed to bfd_make_section. *} -. -. CONST char *name; -. -. {* Which section is it; 0..nth. *} -. -. int index; -. -. {* The next section in the list belonging to the BFD, or NULL. *} -. -. struct sec *next; -. -. {* The field flags contains attributes of the section. Some -. flags are read in from the object file, and some are -. synthesized from other information. *} -. -. flagword flags; -. -.#define SEC_NO_FLAGS 0x000 -. -. {* Tells the OS to allocate space for this section when loading. -. This is clear for a section containing debug information -. only. *} -.#define SEC_ALLOC 0x001 -. -. {* Tells the OS to load the section from the file when loading. -. This is clear for a .bss section. *} -.#define SEC_LOAD 0x002 -. -. {* The section contains data still to be relocated, so there is -. some relocation information too. *} -.#define SEC_RELOC 0x004 -. -.#if 0 {* Obsolete ? *} -.#define SEC_BALIGN 0x008 -.#endif -. -. {* A signal to the OS that the section contains read only -. data. *} -.#define SEC_READONLY 0x010 -. -. {* The section contains code only. *} -.#define SEC_CODE 0x020 -. -. {* The section contains data only. *} -.#define SEC_DATA 0x040 -. -. {* The section will reside in ROM. *} -.#define SEC_ROM 0x080 -. -. {* The section contains constructor information. This section -. type is used by the linker to create lists of constructors and -. destructors used by <<g++>>. When a back end sees a symbol -. which should be used in a constructor list, it creates a new -. section for the type of name (e.g., <<__CTOR_LIST__>>), attaches -. the symbol to it, and builds a relocation. To build the lists -. of constructors, all the linker has to do is catenate all the -. sections called <<__CTOR_LIST__>> and relocate the data -. contained within - exactly the operations it would peform on -. standard data. *} -.#define SEC_CONSTRUCTOR 0x100 -. -. {* The section is a constuctor, and should be placed at the -. end of the text, data, or bss section(?). *} -.#define SEC_CONSTRUCTOR_TEXT 0x1100 -.#define SEC_CONSTRUCTOR_DATA 0x2100 -.#define SEC_CONSTRUCTOR_BSS 0x3100 -. -. {* The section has contents - a data section could be -. <<SEC_ALLOC>> | <<SEC_HAS_CONTENTS>>; a debug section could be -. <<SEC_HAS_CONTENTS>> *} -.#define SEC_HAS_CONTENTS 0x200 -. -. {* An instruction to the linker to not output the section -. even if it has information which would normally be written. *} -.#define SEC_NEVER_LOAD 0x400 -. -. {* The section is a COFF shared library section. This flag is -. only for the linker. If this type of section appears in -. the input file, the linker must copy it to the output file -. without changing the vma or size. FIXME: Although this -. was originally intended to be general, it really is COFF -. specific (and the flag was renamed to indicate this). It -. might be cleaner to have some more general mechanism to -. allow the back end to control what the linker does with -. sections. *} -.#define SEC_COFF_SHARED_LIBRARY 0x800 -. -. {* The section is a common section (symbols may be defined -. multiple times, the value of a symbol is the amount of -. space it requires, and the largest symbol value is the one -. used). Most targets have exactly one of these (which we -. translate to bfd_com_section_ptr), but ECOFF has two. *} -.#define SEC_IS_COMMON 0x8000 -. -. {* The section contains only debugging information. For -. example, this is set for ELF .debug and .stab sections. -. strip tests this flag to see if a section can be -. discarded. *} -.#define SEC_DEBUGGING 0x10000 -. -. {* The contents of this section are held in memory pointed to -. by the contents field. This is checked by -. bfd_get_section_contents, and the data is retrieved from -. memory if appropriate. *} -.#define SEC_IN_MEMORY 0x20000 -. -. {* End of section flags. *} -. -. {* The virtual memory address of the section - where it will be -. at run time. The symbols are relocated against this. The -. user_set_vma flag is maintained by bfd; if it's not set, the -. backend can assign addresses (for example, in <<a.out>>, where -. the default address for <<.data>> is dependent on the specific -. target and various flags). *} -. -. bfd_vma vma; -. boolean user_set_vma; -. -. {* The load address of the section - where it would be in a -. rom image; really only used for writing section header -. information. *} -. -. bfd_vma lma; -. -. {* The size of the section in bytes, as it will be output. -. contains a value even if the section has no contents (e.g., the -. size of <<.bss>>). This will be filled in after relocation *} -. -. bfd_size_type _cooked_size; -. -. {* The original size on disk of the section, in bytes. Normally this -. value is the same as the size, but if some relaxing has -. been done, then this value will be bigger. *} -. -. bfd_size_type _raw_size; -. -. {* If this section is going to be output, then this value is the -. offset into the output section of the first byte in the input -. section. E.g., if this was going to start at the 100th byte in -. the output section, this value would be 100. *} -. -. bfd_vma output_offset; -. -. {* The output section through which to map on output. *} -. -. struct sec *output_section; -. -. {* The alignment requirement of the section, as an exponent of 2 - -. e.g., 3 aligns to 2^3 (or 8). *} -. -. unsigned int alignment_power; -. -. {* If an input section, a pointer to a vector of relocation -. records for the data in this section. *} -. -. struct reloc_cache_entry *relocation; -. -. {* If an output section, a pointer to a vector of pointers to -. relocation records for the data in this section. *} -. -. struct reloc_cache_entry **orelocation; -. -. {* The number of relocation records in one of the above *} -. -. unsigned reloc_count; -. -. {* Information below is back end specific - and not always used -. or updated. *} -. -. {* File position of section data *} -. -. file_ptr filepos; -. -. {* File position of relocation info *} -. -. file_ptr rel_filepos; -. -. {* File position of line data *} -. -. file_ptr line_filepos; -. -. {* Pointer to data for applications *} -. -. PTR userdata; -. -. {* If the SEC_IN_MEMORY flag is set, this points to the actual -. contents. *} -. unsigned char *contents; -. -. {* Attached line number information *} -. -. alent *lineno; -. -. {* Number of line number records *} -. -. unsigned int lineno_count; -. -. {* When a section is being output, this value changes as more -. linenumbers are written out *} -. -. file_ptr moving_line_filepos; -. -. {* What the section number is in the target world *} -. -. int target_index; -. -. PTR used_by_bfd; -. -. {* If this is a constructor section then here is a list of the -. relocations created to relocate items within it. *} -. -. struct relent_chain *constructor_chain; -. -. {* The BFD which owns the section. *} -. -. bfd *owner; -. -. boolean reloc_done; -. {* A symbol which points at this section only *} -. struct symbol_cache_entry *symbol; -. struct symbol_cache_entry **symbol_ptr_ptr; -. -. struct bfd_link_order *link_order_head; -. struct bfd_link_order *link_order_tail; -.} asection ; -. -. {* These sections are global, and are managed by BFD. The application -. and target back end are not permitted to change the values in -. these sections. New code should use the section_ptr macros rather -. than referring directly to the const sections. The const sections -. may eventually vanish. *} -.#define BFD_ABS_SECTION_NAME "*ABS*" -.#define BFD_UND_SECTION_NAME "*UND*" -.#define BFD_COM_SECTION_NAME "*COM*" -.#define BFD_IND_SECTION_NAME "*IND*" -. -. {* the absolute section *} -.extern const asection bfd_abs_section; -.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) -. {* Pointer to the undefined section *} -.extern const asection bfd_und_section; -.#define bfd_und_section_ptr ((asection *) &bfd_und_section) -.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) -. {* Pointer to the common section *} -.extern const asection bfd_com_section; -.#define bfd_com_section_ptr ((asection *) &bfd_com_section) -. {* Pointer to the indirect section *} -.extern const asection bfd_ind_section; -.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) -.#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) -. -.extern const struct symbol_cache_entry * const bfd_abs_symbol; -.extern const struct symbol_cache_entry * const bfd_com_symbol; -.extern const struct symbol_cache_entry * const bfd_und_symbol; -.extern const struct symbol_cache_entry * const bfd_ind_symbol; -.#define bfd_get_section_size_before_reloc(section) \ -. (section->reloc_done ? (abort(),1): (section)->_raw_size) -.#define bfd_get_section_size_after_reloc(section) \ -. ((section->reloc_done) ? (section)->_cooked_size: (abort(),1)) -*/ - -/* These symbols are global, not specific to any BFD. Therefore, anything - that tries to change them is broken, and should be repaired. */ -static const asymbol global_syms[] = -{ - /* the_bfd, name, value, attr, section [, udata] */ - {0, BFD_COM_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_com_section}, - {0, BFD_UND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_und_section}, - {0, BFD_ABS_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_abs_section}, - {0, BFD_IND_SECTION_NAME, 0, BSF_SECTION_SYM, (asection *) &bfd_ind_section}, -}; - -#define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ - const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \ - const asection SEC = \ - { NAME, 0, 0, FLAGS, 0, false, 0, 0, 0, 0, (asection *) &SEC, \ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (boolean) 0, \ - (asymbol *) &global_syms[IDX], (asymbol **) &SYM, } - -STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, - BFD_COM_SECTION_NAME, 0); -STD_SECTION (bfd_und_section, 0, bfd_und_symbol, BFD_UND_SECTION_NAME, 1); -STD_SECTION (bfd_abs_section, 0, bfd_abs_symbol, BFD_ABS_SECTION_NAME, 2); -STD_SECTION (bfd_ind_section, 0, bfd_ind_symbol, BFD_IND_SECTION_NAME, 3); -#undef STD_SECTION - -/* -DOCDD -INODE -section prototypes, , typedef asection, Sections -SUBSECTION - Section prototypes - -These are the functions exported by the section handling part of BFD. -*/ - -/* -FUNCTION - bfd_get_section_by_name - -SYNOPSIS - asection *bfd_get_section_by_name(bfd *abfd, CONST char *name); - -DESCRIPTION - Run through @var{abfd} and return the one of the - <<asection>>s whose name matches @var{name}, otherwise <<NULL>>. - @xref{Sections}, for more information. - - This should only be used in special cases; the normal way to process - all sections of a given name is to use <<bfd_map_over_sections>> and - <<strcmp>> on the name (or better yet, base it on the section flags - or something else) for each section. -*/ - -asection * -bfd_get_section_by_name (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sect; - - for (sect = abfd->sections; sect != NULL; sect = sect->next) - if (!strcmp (sect->name, name)) - return sect; - return NULL; -} - - -/* -FUNCTION - bfd_make_section_old_way - -SYNOPSIS - asection *bfd_make_section_old_way(bfd *abfd, CONST char *name); - -DESCRIPTION - Create a new empty section called @var{name} - and attach it to the end of the chain of sections for the - BFD @var{abfd}. An attempt to create a section with a name which - is already in use returns its pointer without changing the - section chain. - - It has the funny name since this is the way it used to be - before it was rewritten.... - - Possible errors are: - o <<bfd_error_invalid_operation>> - - If output has already started for this BFD. - o <<bfd_error_no_memory>> - - If obstack alloc fails. - -*/ - - -asection * -bfd_make_section_old_way (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sec = bfd_get_section_by_name (abfd, name); - if (sec == (asection *) NULL) - { - sec = bfd_make_section (abfd, name); - } - return sec; -} - -/* -FUNCTION - bfd_make_section_anyway - -SYNOPSIS - asection *bfd_make_section_anyway(bfd *abfd, CONST char *name); - -DESCRIPTION - Create a new empty section called @var{name} and attach it to the end of - the chain of sections for @var{abfd}. Create a new section even if there - is already a section with that name. - - Return <<NULL>> and set <<bfd_error>> on error; possible errors are: - o <<bfd_error_invalid_operation>> - If output has already started for @var{abfd}. - o <<bfd_error_no_memory>> - If obstack alloc fails. -*/ - -sec_ptr -bfd_make_section_anyway (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *newsect; - asection **prev = &abfd->sections; - asection *sect = abfd->sections; - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return NULL; - } - - while (sect) - { - prev = §->next; - sect = sect->next; - } - - newsect = (asection *) bfd_zalloc (abfd, sizeof (asection)); - if (newsect == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - newsect->name = name; - newsect->index = abfd->section_count++; - newsect->flags = SEC_NO_FLAGS; - - newsect->userdata = NULL; - newsect->contents = NULL; - newsect->next = (asection *) NULL; - newsect->relocation = (arelent *) NULL; - newsect->reloc_count = 0; - newsect->line_filepos = 0; - newsect->owner = abfd; - - /* Create a symbol whos only job is to point to this section. This is - useful for things like relocs which are relative to the base of a - section. */ - newsect->symbol = bfd_make_empty_symbol (abfd); - if (!newsect) - return NULL; - newsect->symbol->name = name; - newsect->symbol->value = 0; - newsect->symbol->section = newsect; - newsect->symbol->flags = BSF_SECTION_SYM; - - newsect->symbol_ptr_ptr = &newsect->symbol; - - if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) - { - free (newsect); - return NULL; - } - - *prev = newsect; - return newsect; -} - -/* -FUNCTION - bfd_make_section - -SYNOPSIS - asection *bfd_make_section(bfd *, CONST char *name); - -DESCRIPTION - Like <<bfd_make_section_anyway>>, but return <<NULL>> (without calling - bfd_set_error ()) without changing the section chain if there is already a - section named @var{name}. If there is an error, return <<NULL>> and set - <<bfd_error>>. -*/ - -asection * -bfd_make_section (abfd, name) - bfd *abfd; - CONST char *name; -{ - asection *sect = abfd->sections; - - if (strcmp (name, BFD_ABS_SECTION_NAME) == 0) - { - return bfd_abs_section_ptr; - } - if (strcmp (name, BFD_COM_SECTION_NAME) == 0) - { - return bfd_com_section_ptr; - } - if (strcmp (name, BFD_UND_SECTION_NAME) == 0) - { - return bfd_und_section_ptr; - } - - if (strcmp (name, BFD_IND_SECTION_NAME) == 0) - { - return bfd_ind_section_ptr; - } - - while (sect) - { - if (!strcmp (sect->name, name)) - return NULL; - sect = sect->next; - } - - /* The name is not already used; go ahead and make a new section. */ - return bfd_make_section_anyway (abfd, name); -} - - -/* -FUNCTION - bfd_set_section_flags - -SYNOPSIS - boolean bfd_set_section_flags(bfd *abfd, asection *sec, flagword flags); - -DESCRIPTION - Set the attributes of the section @var{sec} in the BFD - @var{abfd} to the value @var{flags}. Return <<true>> on success, - <<false>> on error. Possible error returns are: - - o <<bfd_error_invalid_operation>> - - The section cannot have one or more of the attributes - requested. For example, a .bss section in <<a.out>> may not - have the <<SEC_HAS_CONTENTS>> field set. - -*/ - -/*ARGSUSED*/ -boolean -bfd_set_section_flags (abfd, section, flags) - bfd *abfd; - sec_ptr section; - flagword flags; -{ -#if 0 - /* If you try to copy a text section from an input file (where it - has the SEC_CODE flag set) to an output file, this loses big if - the bfd_applicable_section_flags (abfd) doesn't have the SEC_CODE - set - which it doesn't, at least not for a.out. FIXME */ - - if ((flags & bfd_applicable_section_flags (abfd)) != flags) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } -#endif - - section->flags = flags; - return true; -} - - -/* -FUNCTION - bfd_map_over_sections - -SYNOPSIS - void bfd_map_over_sections(bfd *abfd, - void (*func)(bfd *abfd, - asection *sect, - PTR obj), - PTR obj); - -DESCRIPTION - Call the provided function @var{func} for each section - attached to the BFD @var{abfd}, passing @var{obj} as an - argument. The function will be called as if by - -| func(abfd, the_section, obj); - - This is the prefered method for iterating over sections; an - alternative would be to use a loop: - -| section *p; -| for (p = abfd->sections; p != NULL; p = p->next) -| func(abfd, p, ...) - - -*/ - -/*VARARGS2*/ -void -bfd_map_over_sections (abfd, operation, user_storage) - bfd *abfd; - void (*operation) PARAMS ((bfd * abfd, asection * sect, PTR obj)); - PTR user_storage; -{ - asection *sect; - int i = 0; - - for (sect = abfd->sections; sect != NULL; i++, sect = sect->next) - (*operation) (abfd, sect, user_storage); - - if (i != abfd->section_count) /* Debugging */ - abort (); -} - - -/* -FUNCTION - bfd_set_section_size - -SYNOPSIS - boolean bfd_set_section_size(bfd *abfd, asection *sec, bfd_size_type val); - -DESCRIPTION - Set @var{sec} to the size @var{val}. If the operation is - ok, then <<true>> is returned, else <<false>>. - - Possible error returns: - o <<bfd_error_invalid_operation>> - - Writing has started to the BFD, so setting the size is invalid. - -*/ - -boolean -bfd_set_section_size (abfd, ptr, val) - bfd *abfd; - sec_ptr ptr; - bfd_size_type val; -{ - /* Once you've started writing to any section you cannot create or change - the size of any others. */ - - if (abfd->output_has_begun) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - ptr->_cooked_size = val; - ptr->_raw_size = val; - - return true; -} - -/* -FUNCTION - bfd_set_section_contents - -SYNOPSIS - boolean bfd_set_section_contents - (bfd *abfd, - asection *section, - PTR data, - file_ptr offset, - bfd_size_type count); - - -DESCRIPTION - Sets the contents of the section @var{section} in BFD - @var{abfd} to the data starting in memory at @var{data}. The - data is written to the output section starting at offset - @var{offset} for @var{count} bytes. - - - - Normally <<true>> is returned, else <<false>>. Possible error - returns are: - o <<bfd_error_no_contents>> - - The output section does not have the <<SEC_HAS_CONTENTS>> - attribute, so nothing can be written to it. - o and some more too - - This routine is front end to the back end function - <<_bfd_set_section_contents>>. - - -*/ - -#define bfd_get_section_size_now(abfd,sec) \ -(sec->reloc_done \ - ? bfd_get_section_size_after_reloc (sec) \ - : bfd_get_section_size_before_reloc (sec)) - -boolean -bfd_set_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - bfd_size_type sz; - - if (!(bfd_get_section_flags (abfd, section) & SEC_HAS_CONTENTS)) - { - bfd_set_error (bfd_error_no_contents); - return (false); - } - - if (offset < 0) - { - bad_val: - bfd_set_error (bfd_error_bad_value); - return false; - } - sz = bfd_get_section_size_now (abfd, section); - if (offset > sz - || count > sz - || offset + count > sz) - goto bad_val; - - switch (abfd->direction) - { - case read_direction: - case no_direction: - bfd_set_error (bfd_error_invalid_operation); - return false; - - case write_direction: - break; - - case both_direction: - /* File is opened for update. `output_has_begun' some time ago when - the file was created. Do not recompute sections sizes or alignments - in _bfd_set_section_content. */ - abfd->output_has_begun = true; - break; - } - - if (BFD_SEND (abfd, _bfd_set_section_contents, - (abfd, section, location, offset, count))) - { - abfd->output_has_begun = true; - return true; - } - - return false; -} - -/* -FUNCTION - bfd_get_section_contents - -SYNOPSIS - boolean bfd_get_section_contents - (bfd *abfd, asection *section, PTR location, - file_ptr offset, bfd_size_type count); - -DESCRIPTION - Read data from @var{section} in BFD @var{abfd} - into memory starting at @var{location}. The data is read at an - offset of @var{offset} from the start of the input section, - and is read for @var{count} bytes. - - If the contents of a constructor with the <<SEC_CONSTRUCTOR>> - flag set are requested or if the section does not have the - <<SEC_HAS_CONTENTS>> flag set, then the @var{location} is filled - with zeroes. If no errors occur, <<true>> is returned, else - <<false>>. - - - -*/ -boolean -bfd_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - bfd_size_type sz; - - if (section->flags & SEC_CONSTRUCTOR) - { - memset (location, 0, (unsigned) count); - return true; - } - - if (offset < 0) - { - bad_val: - bfd_set_error (bfd_error_bad_value); - return false; - } - /* Even if reloc_done is true, this function reads unrelocated - contents, so we want the raw size. */ - sz = section->_raw_size; - if (offset > sz || count > sz || offset + count > sz) - goto bad_val; - - if (count == 0) - /* Don't bother. */ - return true; - - if ((section->flags & SEC_HAS_CONTENTS) == 0) - { - memset (location, 0, (unsigned) count); - return true; - } - - if ((section->flags & SEC_IN_MEMORY) != 0) - { - memcpy (location, section->contents + offset, count); - return true; - } - - return BFD_SEND (abfd, _bfd_get_section_contents, - (abfd, section, location, offset, count)); -} - -/* -FUNCTION - bfd_copy_private_section_data - -SYNOPSIS - boolean bfd_copy_private_section_data(bfd *ibfd, asection *isec, bfd *obfd, asection *osec); - -DESCRIPTION - Copy private section information from @var{isec} in the BFD - @var{ibfd} to the section @var{osec} in the BFD @var{obfd}. - Return <<true>> on success, <<false>> on error. Possible error - returns are: - - o <<bfd_error_no_memory>> - - Not enough memory exists to create private data for @var{osec}. - -.#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ -. BFD_SEND (ibfd, _bfd_copy_private_section_data, \ -. (ibfd, isection, obfd, osection)) -*/ diff --git a/gnu/usr.bin/gdb/bfd/srec.c b/gnu/usr.bin/gdb/bfd/srec.c deleted file mode 100644 index 2d82ffc..0000000 --- a/gnu/usr.bin/gdb/bfd/srec.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* BFD back-end for s-record objects. - Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SUBSECTION - S-Record handling - -DESCRIPTION - - Ordinary S-Records cannot hold anything but addresses and - data, so that's all that we implement. - - The only interesting thing is that S-Records may come out of - order and there is no header, so an initial scan is required - to discover the minimum and maximum addresses used to create - the vma and size of the only section we create. We - arbitrarily call this section ".text". - - When bfd_get_section_contents is called the file is read - again, and this time the data is placed into a bfd_alloc'd - area. - - Any number of sections may be created for output, we save them - up and output them when it's time to close the bfd. - - An s record looks like: - -EXAMPLE - S<type><length><address><data><checksum> - -DESCRIPTION - Where - o length - is the number of bytes following upto the checksum. Note that - this is not the number of chars following, since it takes two - chars to represent a byte. - o type - is one of: - 0) header record - 1) two byte address data record - 2) three byte address data record - 3) four byte address data record - 7) four byte address termination record - 8) three byte address termination record - 9) two byte address termination record - - o address - is the start address of the data following, or in the case of - a termination record, the start address of the image - o data - is the data. - o checksum - is the sum of all the raw byte data in the record, from the length - upwards, modulo 256 and subtracted from 255. - - -SUBSECTION - Symbol S-Record handling - -DESCRIPTION - Some ICE equipment understands an addition to the standard - S-Record format; symbols and their addresses can be sent - before the data. - - The format of this is: - ($$ <modulename> - (<space> <symbol> <address>)*) - $$ - - so a short symbol table could look like: - -EXAMPLE - $$ flash.x - $$ flash.c - _port6 $0 - _delay $4 - _start $14 - _etext $8036 - _edata $8036 - _end $8036 - $$ - -DESCRIPTION - We allow symbols to be anywhere in the data stream - the module names - are always ignored. - -*/ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -static boolean srec_write_record PARAMS ((bfd *, int, bfd_vma, - const unsigned char *, - const unsigned char *)); -static boolean srec_write_header PARAMS ((bfd *)); -static boolean srec_write_symbols PARAMS ((bfd *)); - -/* Macros for converting between hex and binary. */ - -static CONST char digs[] = "0123456789ABCDEF"; - -/* Table that gets filled in with numbers corresponding to hex chars. */ - -static char hex_value[256]; - -#define NOT_HEX 20 -#define NIBBLE(x) hex_value[(unsigned char)(x)] -#define HEX(buffer) ((NIBBLE((buffer)[0])<<4) + NIBBLE((buffer)[1])) -#define TOHEX(d, x, ch) \ - d[1] = digs[(x) & 0xf]; \ - d[0] = digs[((x)>>4)&0xf]; \ - ch += ((x) & 0xff); -#define ISHEX(x) (hex_value[(unsigned char)(x)] != NOT_HEX) - -/* Initialize by filling in the hex conversion array. */ - -static void -srec_init () -{ - unsigned int i; - static boolean inited = false; - - if (inited == false) - { - inited = true; - - for (i = 0; i < sizeof (hex_value); i++) - { - hex_value[i] = NOT_HEX; - } - for (i = 0; i < 10; i++) - { - hex_value[i + '0'] = i; - } - for (i = 0; i < 6; i++) - { - hex_value[i + 'a'] = i + 10; - hex_value[i + 'A'] = i + 10; - } - } -} - - -/* The maximum number of bytes on a line is FF */ -#define MAXCHUNK 0xff -/* The number of bytes we fit onto a line on output */ -#define CHUNK 21 - -/* We cannot output our srecords as we see them, we have to glue them - together, this is done in this structure : */ - -struct srec_data_list_struct -{ - unsigned char *data; - bfd_vma where; - bfd_size_type size; - struct srec_data_list_struct *next; - - -}; -typedef struct srec_data_list_struct srec_data_list_type; - - -typedef struct srec_data_struct - { - srec_data_list_type *head; - unsigned int type; - - int done_symbol_read; - int count; - asymbol *symbols; - char *strings; - int symbol_idx; - int string_size; - int string_idx; - } -tdata_type; - -static boolean srec_write_section PARAMS ((bfd *, tdata_type *, - srec_data_list_type *)); -static boolean srec_write_terminator PARAMS ((bfd *, tdata_type *)); - -/* - called once per input S-Record, used to work out vma and size of data. - */ - -static bfd_vma low, high; - -/*ARGSUSED*/ -static void -size_symbols (abfd, buf, len, val) - bfd *abfd; - char *buf; - int len; - int val; -{ - abfd->symcount++; - abfd->tdata.srec_data->string_size += len + 1; -} - -static void -fillup_symbols (abfd, buf, len, val) - bfd *abfd; - char *buf; - int len; - int val; -{ - if (!abfd->tdata.srec_data->done_symbol_read) - { - asymbol *p; - if (abfd->tdata.srec_data->symbols == 0) - { - abfd->tdata.srec_data->symbols = (asymbol *) bfd_alloc (abfd, abfd->symcount * sizeof (asymbol)); - abfd->tdata.srec_data->strings = (char *) bfd_alloc (abfd, abfd->tdata.srec_data->string_size); - if (!abfd->tdata.srec_data->symbols || !abfd->tdata.srec_data->strings) - { - bfd_set_error (bfd_error_no_memory); - abort (); /* FIXME */ - } - abfd->tdata.srec_data->symbol_idx = 0; - abfd->tdata.srec_data->string_idx = 0; - } - - p = abfd->tdata.srec_data->symbols + abfd->tdata.srec_data->symbol_idx++; - p->the_bfd = abfd; - p->name = abfd->tdata.srec_data->strings + abfd->tdata.srec_data->string_idx; - memcpy ((char *) (p->name), buf, len + 1); - abfd->tdata.srec_data->string_idx += len + 1; - p->value = val; - p->flags = BSF_EXPORT | BSF_GLOBAL; - p->section = bfd_abs_section_ptr; - p->udata = 0; - } -} -/*ARGSUSED*/ -static void -size_srec (abfd, section, address, raw, length) - bfd *abfd; - asection *section; - bfd_vma address; - bfd_byte *raw; - unsigned int length; -{ - if (address < low) - low = address; - if (address + length > high) - high = address + length - 1; -} - - -/* - called once per input S-Record, copies data from input into bfd_alloc'd area - */ - -/*ARGSUSED*/ -static void -fillup (abfd, section, address, raw, length) - bfd *abfd; - asection *section; - bfd_vma address; - bfd_byte *raw; - unsigned int length; -{ - unsigned int i; - bfd_byte *dst = - (bfd_byte *) (section->used_by_bfd) + address - section->vma; - /* length -1 because we don't read in the checksum */ - for (i = 0; i < length - 1; i++) - { - *dst = HEX (raw); - dst++; - raw += 2; - } -} - -/* Pass over an S-Record file, calling one of the above functions on each - record. */ - -static int -white (x) - char x; -{ - return (x == ' ' || x == '\t' || x == '\n' || x == '\r'); -} -static int -skipwhite (src, abfd) - char *src; - bfd *abfd; -{ - int eof = 0; - while (white (*src) && !eof) - { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - return eof; -} - -static boolean -srec_mkobject (abfd) - bfd *abfd; -{ - if (abfd->tdata.srec_data == 0) - { - tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type)); - if (!tdata) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - abfd->tdata.srec_data = tdata; - tdata->type = 1; - tdata->head = (srec_data_list_type *) NULL; - } - return true; - -} - -static void -pass_over (abfd, func, symbolfunc, section) - bfd *abfd; - void (*func) (); - void (*symbolfunc) (); - asection *section; -{ - unsigned int bytes_on_line; - boolean eof = false; - - srec_mkobject (abfd); - /* To the front of the file */ - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) - abort (); - while (eof == false) - { - char buffer[MAXCHUNK]; - char *src = buffer; - char type; - bfd_vma address = 0; - - /* Find first 'S' or $ */ - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - switch (*src) - { - default: - if (eof) - return; - break; - - case '$': - /* Inside a symbol definition - just ignore the module name */ - while (*src != '\n' && !eof) - { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - break; - - case ' ': - /* spaces - maybe just before a symbol */ - while (*src != '\n' && *src != '\r' && white (*src)) - { - eof = skipwhite (src, abfd); - - { - int val = 0; - int slen = 0; - char symbol[MAXCHUNK]; - - /* get the symbol part */ - while (!eof && !white (*src) && slen < MAXCHUNK) - { - symbol[slen++] = *src; - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - symbol[slen] = 0; - eof = skipwhite (src, abfd); - /* skip the $ for the hex value */ - if (*src == '$') - { - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - - /* Scan off the hex number */ - while (isxdigit (*src)) - { - val *= 16; - if (isdigit (*src)) - val += *src - '0'; - else if (isupper (*src)) - { - val += *src - 'A' + 10; - } - else - { - val += *src - 'a' + 10; - } - eof = (boolean) (bfd_read (src, 1, 1, abfd) != 1); - } - symbolfunc (abfd, symbol, slen, val); - } - } - break; - case 'S': - src++; - - /* Fetch the type and the length */ - if (bfd_read (src, 1, 3, abfd) != 3) - abort (); /* FIXME */ - - type = *src++; - - if (!ISHEX (src[0]) || !ISHEX (src[1])) - break; - - bytes_on_line = HEX (src); - - if (bytes_on_line > MAXCHUNK / 2) - break; - src += 2; - - if (bfd_read (src, 1, bytes_on_line * 2, abfd) != bytes_on_line * 2) - abort (); /* FIXME */ - - switch (type) - { - case '0': - case '5': - /* Prologue - ignore */ - break; - case '3': - address = HEX (src); - src += 2; - bytes_on_line--; - - case '2': - address = HEX (src) | (address << 8); - src += 2; - bytes_on_line--; - case '1': - address = HEX (src) | (address << 8); - src += 2; - address = HEX (src) | (address << 8); - src += 2; - bytes_on_line -= 2; - func (abfd, section, address, src, bytes_on_line); - break; - default: - return; - } - } - } - -} - -static const bfd_target * -object_p (abfd) - bfd *abfd; -{ - asection *section; - /* We create one section called .text for all the contents, - and allocate enough room for the entire file. */ - - section = bfd_make_section (abfd, ".text"); - section->_raw_size = 0; - section->vma = 0xffffffff; - low = 0xffffffff; - high = 0; - pass_over (abfd, size_srec, size_symbols, section); - section->_raw_size = high - low; - section->vma = low; - section->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - - if (abfd->symcount) - abfd->flags |= HAS_SYMS; - return abfd->xvec; -} - -static const bfd_target * -srec_object_p (abfd) - bfd *abfd; -{ - char b[4]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_read (b, 1, 4, abfd) != 4) - return NULL; - - if (b[0] != 'S' || !ISHEX (b[1]) || !ISHEX (b[2]) || !ISHEX (b[3])) - return (const bfd_target *) NULL; - - /* We create one section called .text for all the contents, - and allocate enough room for the entire file. */ - - return object_p (abfd); -} - - -static const bfd_target * -symbolsrec_object_p (abfd) - bfd *abfd; -{ - char b[4]; - - srec_init (); - - if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 - || bfd_read (b, 1, 4, abfd) != 4) - return NULL; - - if (b[0] != '$' || b[1] != '$') - return (const bfd_target *) NULL; - - return object_p (abfd); -} - - -static boolean -srec_get_section_contents (abfd, section, location, offset, count) - bfd *abfd; - asection *section; - PTR location; - file_ptr offset; - bfd_size_type count; -{ - if (section->used_by_bfd == (PTR) NULL) - { - section->used_by_bfd = (PTR) bfd_alloc (abfd, section->_raw_size); - if (!section->used_by_bfd) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - pass_over (abfd, fillup, fillup_symbols, section); - } - memcpy ((PTR) location, - (PTR) ((char *) (section->used_by_bfd) + offset), - count); - return true; -} - - - -boolean -srec_set_arch_mach (abfd, arch, machine) - bfd *abfd; - enum bfd_architecture arch; - unsigned long machine; -{ - return bfd_default_set_arch_mach (abfd, arch, machine); -} - - -/* we have to save up all the Srecords for a splurge before output, - also remember */ - -static boolean -srec_set_section_contents (abfd, section, location, offset, bytes_to_do) - bfd *abfd; - sec_ptr section; - PTR location; - file_ptr offset; - bfd_size_type bytes_to_do; -{ - tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *entry = (srec_data_list_type *) - bfd_alloc (abfd, sizeof (srec_data_list_type)); - - if (!entry) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - - if ((section->flags & SEC_ALLOC) - && (section->flags & SEC_LOAD)) - { - unsigned char *data = (unsigned char *) bfd_alloc (abfd, bytes_to_do); - if (!data) - { - bfd_set_error (bfd_error_no_memory); - return false; - } - memcpy ((PTR) data, location, bytes_to_do); - - if ((section->lma + offset + bytes_to_do) <= 0xffff) - { - - } - else if ((section->lma + offset + bytes_to_do) <= 0xffffff - && tdata->type < 2) - { - tdata->type = 2; - } - else - { - tdata->type = 3; - } - - entry->data = data; - entry->where = section->lma + offset; - entry->size = bytes_to_do; - entry->next = tdata->head; - tdata->head = entry; - } - return true; -} - -/* Write a record of type, of the supplied number of bytes. The - supplied bytes and length don't have a checksum. That's worked out - here -*/ -static boolean -srec_write_record (abfd, type, address, data, end) - bfd *abfd; - int type; - bfd_vma address; - const unsigned char *data; - const unsigned char *end; -{ - char buffer[MAXCHUNK]; - - unsigned int check_sum = 0; - CONST unsigned char *src = data; - char *dst = buffer; - char *length; - - - *dst++ = 'S'; - *dst++ = '0' + type; - - length = dst; - dst += 2; /* leave room for dst*/ - - switch (type) - { - case 3: - case 7: - TOHEX (dst, (address >> 24), check_sum); - dst += 2; - case 8: - case 2: - TOHEX (dst, (address >> 16), check_sum); - dst += 2; - case 9: - case 1: - case 0: - TOHEX (dst, (address >> 8), check_sum); - dst += 2; - TOHEX (dst, (address), check_sum); - dst += 2; - break; - - } - for (src = data; src < end; src++) - { - TOHEX (dst, *src, check_sum); - dst += 2; - } - - /* Fill in the length */ - TOHEX (length, (dst - length) / 2, check_sum); - check_sum &= 0xff; - check_sum = 255 - check_sum; - TOHEX (dst, check_sum, check_sum); - dst += 2; - - *dst++ = '\r'; - *dst++ = '\n'; - if (bfd_write ((PTR) buffer, 1, dst - buffer, abfd) != dst - buffer) - return false; - return true; -} - - - -static boolean -srec_write_header (abfd) - bfd *abfd; -{ - unsigned char buffer[MAXCHUNK]; - unsigned char *dst = buffer; - unsigned int i; - - /* I'll put an arbitary 40 char limit on header size */ - for (i = 0; i < 40 && abfd->filename[i]; i++) - { - *dst++ = abfd->filename[i]; - } - return srec_write_record (abfd, 0, 0, buffer, dst); -} - -static boolean -srec_write_section (abfd, tdata, list) - bfd *abfd; - tdata_type *tdata; - srec_data_list_type *list; -{ - unsigned int bytes_written = 0; - unsigned char *location = list->data; - - while (bytes_written < list->size) - { - bfd_vma address; - - unsigned int bytes_this_chunk = list->size - bytes_written; - - if (bytes_this_chunk > CHUNK) - { - bytes_this_chunk = CHUNK; - } - - address = list->where + bytes_written; - - if (! srec_write_record (abfd, - tdata->type, - address, - location, - location + bytes_this_chunk)) - return false; - - bytes_written += bytes_this_chunk; - location += bytes_this_chunk; - } - - return true; -} - -static boolean -srec_write_terminator (abfd, tdata) - bfd *abfd; - tdata_type *tdata; -{ - unsigned char buffer[2]; - - return srec_write_record (abfd, 10 - tdata->type, - abfd->start_address, buffer, buffer); -} - - - -static boolean -srec_write_symbols (abfd) - bfd *abfd; -{ - char buffer[MAXCHUNK]; - /* Dump out the symbols of a bfd */ - int i; - int count = bfd_get_symcount (abfd); - - if (count) - { - size_t len; - asymbol **table = bfd_get_outsymbols (abfd); - sprintf (buffer, "$$ %s\r\n", abfd->filename); - - len = strlen (buffer); - if (bfd_write (buffer, len, 1, abfd) != len) - return false; - - for (i = 0; i < count; i++) - { - asymbol *s = table[i]; -#if 0 - int len = strlen (s->name); - - /* If this symbol has a .[ocs] in it, it's probably a file name - and we'll output that as the module name */ - - if (len > 3 && s->name[len - 2] == '.') - { - int l; - sprintf (buffer, "$$ %s\r\n", s->name); - l = strlen (buffer); - if (bfd_write (buffer, l, 1, abfd) != l) - return false; - } - else -#endif - if (s->flags & (BSF_GLOBAL | BSF_LOCAL) - && (s->flags & BSF_DEBUGGING) == 0 - && s->name[0] != '.' - && s->name[0] != 't') - { - /* Just dump out non debug symbols */ - - int l; - char buf2[40], *p; - - sprintf_vma (buf2, - s->value + s->section->output_section->lma - + s->section->output_offset); - p = buf2; - while (p[0] == '0' && p[1] != 0) - p++; - sprintf (buffer, " %s $%s\r\n", s->name, p); - l = strlen (buffer); - if (bfd_write (buffer, l, 1, abfd) != l) - return false; - } - } - sprintf (buffer, "$$ \r\n"); - len = strlen (buffer); - if (bfd_write (buffer, len, 1, abfd) != len) - return false; - } - - return true; -} - -static boolean -internal_srec_write_object_contents (abfd, symbols) - bfd *abfd; - int symbols; -{ - tdata_type *tdata = abfd->tdata.srec_data; - srec_data_list_type *list; - - if (symbols) - { - if (! srec_write_symbols (abfd)) - return false; - } - - if (! srec_write_header (abfd)) - return false; - - /* Now wander though all the sections provided and output them */ - list = tdata->head; - - while (list != (srec_data_list_type *) NULL) - { - if (! srec_write_section (abfd, tdata, list)) - return false; - list = list->next; - } - return srec_write_terminator (abfd, tdata); -} - -static boolean -srec_write_object_contents (abfd) - bfd *abfd; -{ - return internal_srec_write_object_contents (abfd, 0); -} - -static boolean -symbolsrec_write_object_contents (abfd) - bfd *abfd; -{ - return internal_srec_write_object_contents (abfd, 1); -} - -/*ARGSUSED*/ -static int -srec_sizeof_headers (abfd, exec) - bfd *abfd; - boolean exec; -{ - return 0; -} - -static asymbol * -srec_make_empty_symbol (abfd) - bfd *abfd; -{ - asymbol *new = (asymbol *) bfd_zalloc (abfd, sizeof (asymbol)); - if (new) - new->the_bfd = abfd; - return new; -} - -static long -srec_get_symtab_upper_bound (abfd) - bfd *abfd; -{ - /* Read in all the info */ - if (! srec_get_section_contents (abfd, abfd->sections, 0, 0, 0)) - return -1; - return (bfd_get_symcount (abfd) + 1) * (sizeof (asymbol *)); -} - -static long -srec_get_symtab (abfd, alocation) - bfd *abfd; - asymbol **alocation; -{ - int lim = abfd->symcount; - int i; - for (i = 0; i < lim; i++) - { - alocation[i] = abfd->tdata.srec_data->symbols + i; - } - alocation[i] = 0; - return lim; -} - -/*ARGSUSED*/ -void -srec_get_symbol_info (ignore_abfd, symbol, ret) - bfd *ignore_abfd; - asymbol *symbol; - symbol_info *ret; -{ - bfd_symbol_info (symbol, ret); -} - -/*ARGSUSED*/ -void -srec_print_symbol (ignore_abfd, afile, symbol, how) - bfd *ignore_abfd; - PTR afile; - asymbol *symbol; - bfd_print_symbol_type how; -{ - FILE *file = (FILE *) afile; - switch (how) - { - case bfd_print_symbol_name: - fprintf (file, "%s", symbol->name); - break; - default: - bfd_print_symbol_vandf ((PTR) file, symbol); - fprintf (file, " %-5s %s", - symbol->section->name, - symbol->name); - - } -} - -#define srec_close_and_cleanup _bfd_generic_close_and_cleanup -#define srec_bfd_free_cached_info _bfd_generic_bfd_free_cached_info -#define srec_new_section_hook _bfd_generic_new_section_hook - -#define srec_bfd_is_local_label bfd_generic_is_local_label -#define srec_get_lineno _bfd_nosymbols_get_lineno -#define srec_find_nearest_line _bfd_nosymbols_find_nearest_line -#define srec_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol - -#define srec_bfd_get_relocated_section_contents \ - bfd_generic_get_relocated_section_contents -#define srec_bfd_relax_section bfd_generic_relax_section -#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create -#define srec_bfd_link_add_symbols _bfd_generic_link_add_symbols -#define srec_bfd_final_link _bfd_generic_final_link - -const bfd_target srec_vec = -{ - "srec", /* name */ - bfd_target_srec_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 1, /* minimum alignment */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - srec_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - srec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; - - - -const bfd_target symbolsrec_vec = -{ - "symbolsrec", /* name */ - bfd_target_srec_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS - | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* leading underscore */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 1, /* minimum alignment */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */ - bfd_getb64, bfd_getb_signed_64, bfd_putb64, - bfd_getb32, bfd_getb_signed_32, bfd_putb32, - bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */ - - { - _bfd_dummy_target, - symbolsrec_object_p, /* bfd_check_format */ - _bfd_dummy_target, - _bfd_dummy_target, - }, - { - bfd_false, - srec_mkobject, - _bfd_generic_mkarchive, - bfd_false, - }, - { /* bfd_write_contents */ - bfd_false, - symbolsrec_write_object_contents, - _bfd_write_archive_contents, - bfd_false, - }, - - BFD_JUMP_TABLE_GENERIC (srec), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (_bfd_nocore), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (srec), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (srec), - BFD_JUMP_TABLE_LINK (srec), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 -}; diff --git a/gnu/usr.bin/gdb/bfd/stab-syms.c b/gnu/usr.bin/gdb/bfd/stab-syms.c deleted file mode 100644 index 4cc9332..0000000 --- a/gnu/usr.bin/gdb/bfd/stab-syms.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Table of stab names for the BFD library. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" - -#define ARCH_SIZE 32 /* Value doesn't matter. */ -#include "libaout.h" -#include "aout/aout64.h" - -/* Create a table of debugging stab-codes and corresponding names. */ - -#define __define_name(CODE, STRING) {(int)CODE, STRING}, -#define __define_stab(NAME, CODE, STRING) __define_name(CODE, STRING) -CONST struct - { - short code; - char string[10]; - } -aout_stab_names[] = -{ -#include "aout/stab.def" - -/* These are not really stab symbols, but it is - convenient to have them here for the sake of nm. - For completeness, we could also add N_TEXT etc, but those - are never needed, since nm treats those specially. */ - __define_name (N_SETA, "SETA")/* Absolute set element symbol */ - __define_name (N_SETT, "SETT")/* Text set element symbol */ - __define_name (N_SETD, "SETD")/* Data set element symbol */ - __define_name (N_SETB, "SETB")/* Bss set element symbol */ - __define_name (N_SETV, "SETV")/* Pointer to set vector in data area. */ - __define_name (N_INDR, "INDR") - __define_name (N_WARNING, "WARNING") -}; -#undef __define_stab -#undef GNU_EXTRA_STABS - -CONST char * -aout_stab_name (code) - int code; -{ - register int i = sizeof (aout_stab_names) / sizeof (aout_stab_names[0]); - while (--i >= 0) - if (aout_stab_names[i].code == code) - return aout_stab_names[i].string; - return 0; -} diff --git a/gnu/usr.bin/gdb/bfd/syms.c b/gnu/usr.bin/gdb/bfd/syms.c deleted file mode 100644 index 23a70f5..0000000 --- a/gnu/usr.bin/gdb/bfd/syms.c +++ /dev/null @@ -1,557 +0,0 @@ -/* Generic symbol-table support for the BFD library. - Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* -SECTION - Symbols - - BFD tries to maintain as much symbol information as it can when - it moves information from file to file. BFD passes information - to applications though the <<asymbol>> structure. When the - application requests the symbol table, BFD reads the table in - the native form and translates parts of it into the internal - format. To maintain more than the information passed to - applications, some targets keep some information ``behind the - scenes'' in a structure only the particular back end knows - about. For example, the coff back end keeps the original - symbol table structure as well as the canonical structure when - a BFD is read in. On output, the coff back end can reconstruct - the output symbol table so that no information is lost, even - information unique to coff which BFD doesn't know or - understand. If a coff symbol table were read, but were written - through an a.out back end, all the coff specific information - would be lost. The symbol table of a BFD - is not necessarily read in until a canonicalize request is - made. Then the BFD back end fills in a table provided by the - application with pointers to the canonical information. To - output symbols, the application provides BFD with a table of - pointers to pointers to <<asymbol>>s. This allows applications - like the linker to output a symbol as it was read, since the ``behind - the scenes'' information will be still available. -@menu -@* Reading Symbols:: -@* Writing Symbols:: -@* typedef asymbol:: -@* symbol handling functions:: -@end menu - -INODE -Reading Symbols, Writing Symbols, Symbols, Symbols -SUBSECTION - Reading symbols - - There are two stages to reading a symbol table from a BFD: - allocating storage, and the actual reading process. This is an - excerpt from an application which reads the symbol table: - -| long storage_needed; -| asymbol **symbol_table; -| long number_of_symbols; -| long i; -| -| storage_needed = bfd_get_symtab_upper_bound (abfd); -| -| if (storage_needed < 0) -| FAIL -| -| if (storage_needed == 0) { -| return ; -| } -| symbol_table = (asymbol **) xmalloc (storage_needed); -| ... -| number_of_symbols = -| bfd_canonicalize_symtab (abfd, symbol_table); -| -| if (number_of_symbols < 0) -| FAIL -| -| for (i = 0; i < number_of_symbols; i++) { -| process_symbol (symbol_table[i]); -| } - - All storage for the symbols themselves is in an obstack - connected to the BFD; it is freed when the BFD is closed. - - -INODE -Writing Symbols, typedef asymbol, Reading Symbols, Symbols -SUBSECTION - Writing symbols - - Writing of a symbol table is automatic when a BFD open for - writing is closed. The application attaches a vector of - pointers to pointers to symbols to the BFD being written, and - fills in the symbol count. The close and cleanup code reads - through the table provided and performs all the necessary - operations. The BFD output code must always be provided with an - ``owned'' symbol: one which has come from another BFD, or one - which has been created using <<bfd_make_empty_symbol>>. Here is an - example showing the creation of a symbol table with only one element: - -| #include "bfd.h" -| main() -| { -| bfd *abfd; -| asymbol *ptrs[2]; -| asymbol *new; -| -| abfd = bfd_openw("foo","a.out-sunos-big"); -| bfd_set_format(abfd, bfd_object); -| new = bfd_make_empty_symbol(abfd); -| new->name = "dummy_symbol"; -| new->section = bfd_make_section_old_way(abfd, ".text"); -| new->flags = BSF_GLOBAL; -| new->value = 0x12345; -| -| ptrs[0] = new; -| ptrs[1] = (asymbol *)0; -| -| bfd_set_symtab(abfd, ptrs, 1); -| bfd_close(abfd); -| } -| -| ./makesym -| nm foo -| 00012345 A dummy_symbol - - Many formats cannot represent arbitary symbol information; for - instance, the <<a.out>> object format does not allow an - arbitary number of sections. A symbol pointing to a section - which is not one of <<.text>>, <<.data>> or <<.bss>> cannot - be described. - -*/ - - - -/* -DOCDD -INODE -typedef asymbol, symbol handling functions, Writing Symbols, Symbols - -*/ -/* -SUBSECTION - typedef asymbol - - An <<asymbol>> has the form: - -*/ - -/* -CODE_FRAGMENT - -. -.typedef struct symbol_cache_entry -.{ -. {* A pointer to the BFD which owns the symbol. This information -. is necessary so that a back end can work out what additional -. information (invisible to the application writer) is carried -. with the symbol. -. -. This field is *almost* redundant, since you can use section->owner -. instead, except that some symbols point to the global sections -. bfd_{abs,com,und}_section. This could be fixed by making -. these globals be per-bfd (or per-target-flavor). FIXME. *} -. -. struct _bfd *the_bfd; {* Use bfd_asymbol_bfd(sym) to access this field. *} -. -. {* The text of the symbol. The name is left alone, and not copied; the -. application may not alter it. *} -. CONST char *name; -. -. {* The value of the symbol. This really should be a union of a -. numeric value with a pointer, since some flags indicate that -. a pointer to another symbol is stored here. *} -. symvalue value; -. -. {* Attributes of a symbol: *} -. -.#define BSF_NO_FLAGS 0x00 -. -. {* The symbol has local scope; <<static>> in <<C>>. The value -. is the offset into the section of the data. *} -.#define BSF_LOCAL 0x01 -. -. {* The symbol has global scope; initialized data in <<C>>. The -. value is the offset into the section of the data. *} -.#define BSF_GLOBAL 0x02 -. -. {* The symbol has global scope and is exported. The value is -. the offset into the section of the data. *} -.#define BSF_EXPORT BSF_GLOBAL {* no real difference *} -. -. {* A normal C symbol would be one of: -. <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or -. <<BSF_GLOBAL>> *} -. -. {* The symbol is a debugging record. The value has an arbitary -. meaning. *} -.#define BSF_DEBUGGING 0x08 -. -. {* The symbol denotes a function entry point. Used in ELF, -. perhaps others someday. *} -.#define BSF_FUNCTION 0x10 -. -. {* Used by the linker. *} -.#define BSF_KEEP 0x20 -.#define BSF_KEEP_G 0x40 -. -. {* A weak global symbol, overridable without warnings by -. a regular global symbol of the same name. *} -.#define BSF_WEAK 0x80 -. -. {* This symbol was created to point to a section, e.g. ELF's -. STT_SECTION symbols. *} -.#define BSF_SECTION_SYM 0x100 -. -. {* The symbol used to be a common symbol, but now it is -. allocated. *} -.#define BSF_OLD_COMMON 0x200 -. -. {* The default value for common data. *} -.#define BFD_FORT_COMM_DEFAULT_VALUE 0 -. -. {* In some files the type of a symbol sometimes alters its -. location in an output file - ie in coff a <<ISFCN>> symbol -. which is also <<C_EXT>> symbol appears where it was -. declared and not at the end of a section. This bit is set -. by the target BFD part to convey this information. *} -. -.#define BSF_NOT_AT_END 0x400 -. -. {* Signal that the symbol is the label of constructor section. *} -.#define BSF_CONSTRUCTOR 0x800 -. -. {* Signal that the symbol is a warning symbol. If the symbol -. is a warning symbol, then the value field (I know this is -. tacky) will point to the asymbol which when referenced will -. cause the warning. *} -.#define BSF_WARNING 0x1000 -. -. {* Signal that the symbol is indirect. The value of the symbol -. is a pointer to an undefined asymbol which contains the -. name to use instead. *} -.#define BSF_INDIRECT 0x2000 -. -. {* BSF_FILE marks symbols that contain a file name. This is used -. for ELF STT_FILE symbols. *} -.#define BSF_FILE 0x4000 -. -. {* Symbol is from dynamic linking information. *} -.#define BSF_DYNAMIC 0x8000 -. -. flagword flags; -. -. {* A pointer to the section to which this symbol is -. relative. This will always be non NULL, there are special -. sections for undefined and absolute symbols *} -. struct sec *section; -. -. {* Back end special data. This is being phased out in favour -. of making this a union. *} -. PTR udata; -. -.} asymbol; -*/ - -#include "bfd.h" -#include "sysdep.h" - -#include "libbfd.h" -#include "aout/stab_gnu.h" - -/* -DOCDD -INODE -symbol handling functions, , typedef asymbol, Symbols -SUBSECTION - Symbol handling functions -*/ - -/* -FUNCTION - bfd_get_symtab_upper_bound - -DESCRIPTION - Return the number of bytes required to store a vector of pointers - to <<asymbols>> for all the symbols in the BFD @var{abfd}, - including a terminal NULL pointer. If there are no symbols in - the BFD, then return 0. If an error occurs, return -1. - -.#define bfd_get_symtab_upper_bound(abfd) \ -. BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) - -*/ - -/* -FUNCTION - bfd_is_local_label - -SYNOPSIS - boolean bfd_is_local_label(bfd *abfd, asymbol *sym); - -DESCRIPTION - Return true if the given symbol @var{sym} in the BFD @var{abfd} is - a compiler generated local label, else return false. -.#define bfd_is_local_label(abfd, sym) \ -. BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym)) -*/ - -/* -FUNCTION - bfd_canonicalize_symtab - -DESCRIPTION - Read the symbols from the BFD @var{abfd}, and fills in - the vector @var{location} with pointers to the symbols and - a trailing NULL. - Return the actual number of symbol pointers, not - including the NULL. - - -.#define bfd_canonicalize_symtab(abfd, location) \ -. BFD_SEND (abfd, _bfd_canonicalize_symtab,\ -. (abfd, location)) - -*/ - - -/* -FUNCTION - bfd_set_symtab - -SYNOPSIS - boolean bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int count); - -DESCRIPTION - Arrange that when the output BFD @var{abfd} is closed, - the table @var{location} of @var{count} pointers to symbols - will be written. -*/ - -boolean -bfd_set_symtab (abfd, location, symcount) - bfd *abfd; - asymbol **location; - unsigned int symcount; -{ - if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) - { - bfd_set_error (bfd_error_invalid_operation); - return false; - } - - bfd_get_outsymbols (abfd) = location; - bfd_get_symcount (abfd) = symcount; - return true; -} - -/* -FUNCTION - bfd_print_symbol_vandf - -SYNOPSIS - void bfd_print_symbol_vandf(PTR file, asymbol *symbol); - -DESCRIPTION - Print the value and flags of the @var{symbol} supplied to the - stream @var{file}. -*/ -void -bfd_print_symbol_vandf (arg, symbol) - PTR arg; - asymbol *symbol; -{ - FILE *file = (FILE *) arg; - flagword type = symbol->flags; - if (symbol->section != (asection *) NULL) - { - fprintf_vma (file, symbol->value + symbol->section->vma); - } - else - { - fprintf_vma (file, symbol->value); - } - - /* This presumes that a symbol can not be both BSF_DEBUGGING and - BSF_DYNAMIC. */ - fprintf (file, " %c%c%c%c%c%c%c", - (type & BSF_LOCAL) ? 'l' : ' ', - (type & BSF_GLOBAL) ? 'g' : ' ', - (type & BSF_WEAK) ? 'w' : ' ', - (type & BSF_CONSTRUCTOR) ? 'C' : ' ', - (type & BSF_WARNING) ? 'W' : ' ', - (type & BSF_INDIRECT) ? 'I' : ' ', - (type & BSF_DEBUGGING) ? 'd' - : (type & BSF_DYNAMIC) ? 'D' : ' '); -} - - -/* -FUNCTION - bfd_make_empty_symbol - -DESCRIPTION - Create a new <<asymbol>> structure for the BFD @var{abfd} - and return a pointer to it. - - This routine is necessary because each back end has private - information surrounding the <<asymbol>>. Building your own - <<asymbol>> and pointing to it will not create the private - information, and will cause problems later on. - -.#define bfd_make_empty_symbol(abfd) \ -. BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) -*/ - -/* -FUNCTION - bfd_make_debug_symbol - -DESCRIPTION - Create a new <<asymbol>> structure for the BFD @var{abfd}, - to be used as a debugging symbol. Further details of its use have - yet to be worked out. - -.#define bfd_make_debug_symbol(abfd,ptr,size) \ -. BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) -*/ - -struct section_to_type -{ - CONST char *section; - char type; -}; - -/* Map section names to POSIX/BSD single-character symbol types. - This table is probably incomplete. It is sorted for convenience of - adding entries. Since it is so short, a linear search is used. */ -static CONST struct section_to_type stt[] = -{ - {"*DEBUG*", 'N'}, - {".bss", 'b'}, - {".data", 'd'}, - {".sbss", 's'}, /* Small BSS (uninitialized data) */ - {".scommon", 'c'}, /* Small common */ - {".sdata", 'g'}, /* Small initialized data */ - {".text", 't'}, - {0, 0} -}; - -/* Return the single-character symbol type corresponding to - section S, or '?' for an unknown COFF section. */ - -static char -coff_section_type (s) - char *s; -{ - CONST struct section_to_type *t; - - for (t = &stt[0]; t->section; t++) - if (!strcmp (s, t->section)) - return t->type; - return '?'; -} - -#ifndef islower -#define islower(c) ((c) >= 'a' && (c) <= 'z') -#endif -#ifndef toupper -#define toupper(c) (islower(c) ? ((c) & ~0x20) : (c)) -#endif - -/* -FUNCTION - bfd_decode_symclass - -DESCRIPTION - Return a character corresponding to the symbol - class of @var{symbol}, or '?' for an unknown class. - -SYNOPSIS - int bfd_decode_symclass(asymbol *symbol); -*/ -int -bfd_decode_symclass (symbol) - asymbol *symbol; -{ - char c; - - if (bfd_is_com_section (symbol->section)) - return 'C'; - if (bfd_is_und_section (symbol->section)) - return 'U'; - if (bfd_is_ind_section (symbol->section)) - return 'I'; - if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL))) - return '?'; - - if (bfd_is_abs_section (symbol->section)) - c = 'a'; - else if (symbol->section) - c = coff_section_type (symbol->section->name); - else - return '?'; - if (symbol->flags & BSF_GLOBAL) - c = toupper (c); - return c; - - /* We don't have to handle these cases just yet, but we will soon: - N_SETV: 'v'; - N_SETA: 'l'; - N_SETT: 'x'; - N_SETD: 'z'; - N_SETB: 's'; - N_INDR: 'i'; - */ -} - -/* -FUNCTION - bfd_symbol_info - -DESCRIPTION - Fill in the basic info about symbol that nm needs. - Additional info may be added by the back-ends after - calling this function. - -SYNOPSIS - void bfd_symbol_info(asymbol *symbol, symbol_info *ret); -*/ - -void -bfd_symbol_info (symbol, ret) - asymbol *symbol; - symbol_info *ret; -{ - ret->type = bfd_decode_symclass (symbol); - if (ret->type != 'U') - ret->value = symbol->value + symbol->section->vma; - else - ret->value = 0; - ret->name = symbol->name; -} - -void -bfd_symbol_is_absolute () -{ - abort (); -} diff --git a/gnu/usr.bin/gdb/bfd/sysdep.h b/gnu/usr.bin/gdb/bfd/sysdep.h deleted file mode 100644 index 5e989eb..0000000 --- a/gnu/usr.bin/gdb/bfd/sysdep.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef hosts_i386bsd_H -/* Intel 386 running any BSD Unix */ -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> -#include <string.h> -#include <sys/file.h> -#include <machine/param.h> -#include <machine/vmparam.h> - -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#define SEEK_SET 0 -#define SEEK_CUR 1 - -#define HOST_PAGE_SIZE PAGE_SIZE -#define HOST_MACHINE_ARCH bfd_arch_i386 -#define HOST_TEXT_START_ADDR USRTEXT - -/* Jolitz suggested defining HOST_STACK_END_ADDR to - (u.u_kproc.kp_eproc.e_vm.vm_maxsaddr + MAXSSIZ), which should work on - both BSDI and 386BSD, but that is believed not to work for BSD 4.4. */ - -#if defined (__bsdi__) || defined (__FreeBSD__) -/* This seems to be the right thing for BSDI and FreeBSD. */ -#define HOST_STACK_END_ADDR USRSTACK -#else -/* This seems to be the right thing for 386BSD release 0.1. */ -#define HOST_STACK_END_ADDR (USRSTACK - MAXSSIZ) -#endif - -#define HOST_DATA_START_ADDR ((bfd_vma)u.u_kproc.kp_eproc.e_vm.vm_daddr) - -#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \ - ((core_bfd)->tdata.trad_core_data->u.u_sig) -#define u_comm u_kproc.kp_proc.p_comm - -#include "fopen-same.h" - -#define hosts_i386bsd_H -#endif diff --git a/gnu/usr.bin/gdb/bfd/targets.c b/gnu/usr.bin/gdb/bfd/targets.c deleted file mode 100644 index f6115a8..0000000 --- a/gnu/usr.bin/gdb/bfd/targets.c +++ /dev/null @@ -1,770 +0,0 @@ -/* Generic target-file-type support for the BFD library. - Copyright 1990, 91, 92, 93, 1994 Free Software Foundation, Inc. - Written by Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" - -/* -SECTION - Targets - -DESCRIPTION - Each port of BFD to a different machine requries the creation - of a target back end. All the back end provides to the root - part of BFD is a structure containing pointers to functions - which perform certain low level operations on files. BFD - translates the applications's requests through a pointer into - calls to the back end routines. - - When a file is opened with <<bfd_openr>>, its format and - target are unknown. BFD uses various mechanisms to determine - how to interpret the file. The operations performed are: - - o Create a BFD by calling the internal routine - <<_bfd_new_bfd>>, then call <<bfd_find_target>> with the - target string supplied to <<bfd_openr>> and the new BFD pointer. - - o If a null target string was provided to <<bfd_find_target>>, - look up the environment variable <<GNUTARGET>> and use - that as the target string. - - o If the target string is still <<NULL>>, or the target string is - <<default>>, then use the first item in the target vector - as the target type, and set <<target_defaulted>> in the BFD to - cause <<bfd_check_format>> to loop through all the targets. - @xref{bfd_target}. @xref{Formats}. - - o Otherwise, inspect the elements in the target vector - one by one, until a match on target name is found. When found, - use it. - - o Otherwise return the error <<bfd_error_invalid_target>> to - <<bfd_openr>>. - - o <<bfd_openr>> attempts to open the file using - <<bfd_open_file>>, and returns the BFD. - - Once the BFD has been opened and the target selected, the file - format may be determined. This is done by calling - <<bfd_check_format>> on the BFD with a suggested format. - If <<target_defaulted>> has been set, each possible target - type is tried to see if it recognizes the specified format. - <<bfd_check_format>> returns <<true>> when the caller guesses right. -@menu -@* bfd_target:: -@end menu -*/ - - -/* - -INODE - bfd_target, , Targets, Targets -DOCDD -SUBSECTION - bfd_target - -DESCRIPTION - This structure contains everything that BFD knows about a - target. It includes things like its byte order, name, and which - routines to call to do various operations. - - Every BFD points to a target structure with its <<xvec>> - member. - - The macros below are used to dispatch to functions through the - <<bfd_target>> vector. They are used in a number of macros further - down in @file{bfd.h}, and are also used when calling various - routines by hand inside the BFD implementation. The @var{arglist} - argument must be parenthesized; it contains all the arguments - to the called function. - - They make the documentation (more) unpleasant to read, so if - someone wants to fix this and not break the above, please do. - -.#define BFD_SEND(bfd, message, arglist) \ -. ((*((bfd)->xvec->message)) arglist) -. -.#ifdef DEBUG_BFD_SEND -.#undef BFD_SEND -.#define BFD_SEND(bfd, message, arglist) \ -. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ -. ((*((bfd)->xvec->message)) arglist) : \ -. (bfd_assert (__FILE__,__LINE__), NULL)) -.#endif - - For operations which index on the BFD format: - -.#define BFD_SEND_FMT(bfd, message, arglist) \ -. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) -. -.#ifdef DEBUG_BFD_SEND -.#undef BFD_SEND_FMT -.#define BFD_SEND_FMT(bfd, message, arglist) \ -. (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ -. (((bfd)->xvec->message[(int)((bfd)->format)]) arglist) : \ -. (bfd_assert (__FILE__,__LINE__), NULL)) -.#endif - - This is the structure which defines the type of BFD this is. The - <<xvec>> member of the struct <<bfd>> itself points here. Each - module that implements access to a different target under BFD, - defines one of these. - - - FIXME, these names should be rationalised with the names of - the entry points which call them. Too bad we can't have one - macro to define them both! - -.enum bfd_flavour { -. bfd_target_unknown_flavour, -. bfd_target_aout_flavour, -. bfd_target_coff_flavour, -. bfd_target_ecoff_flavour, -. bfd_target_elf_flavour, -. bfd_target_ieee_flavour, -. bfd_target_nlm_flavour, -. bfd_target_oasys_flavour, -. bfd_target_tekhex_flavour, -. bfd_target_srec_flavour, -. bfd_target_som_flavour, -. bfd_target_os9k_flavour}; -. -.{* Forward declaration. *} -.typedef struct bfd_link_info _bfd_link_info; -. -.typedef struct bfd_target -.{ - -Identifies the kind of target, e.g., SunOS4, Ultrix, etc. - -. char *name; - -The "flavour" of a back end is a general indication about the contents -of a file. - -. enum bfd_flavour flavour; - -The order of bytes within the data area of a file. - -. boolean byteorder_big_p; - -The order of bytes within the header parts of a file. - -. boolean header_byteorder_big_p; - -A mask of all the flags which an executable may have set - -from the set <<NO_FLAGS>>, <<HAS_RELOC>>, ...<<D_PAGED>>. - -. flagword object_flags; - -A mask of all the flags which a section may have set - from -the set <<SEC_NO_FLAGS>>, <<SEC_ALLOC>>, ...<<SET_NEVER_LOAD>>. - -. flagword section_flags; - -The character normally found at the front of a symbol -(if any), perhaps `_'. - -. char symbol_leading_char; - -The pad character for file names within an archive header. - -. char ar_pad_char; - -The maximum number of characters in an archive header. - -. unsigned short ar_max_namelen; - -The minimum alignment restriction for any section. - -. unsigned int align_power_min; - -Entries for byte swapping for data. These are different from the other -entry points, since they don't take a BFD asthe first argument. -Certain other handlers could do the same. - -. bfd_vma (*bfd_getx64) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_64) PARAMS ((const bfd_byte *)); -. void (*bfd_putx64) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_getx32) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_32) PARAMS ((const bfd_byte *)); -. void (*bfd_putx32) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_getx16) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_getx_signed_16) PARAMS ((const bfd_byte *)); -. void (*bfd_putx16) PARAMS ((bfd_vma, bfd_byte *)); - -Byte swapping for the headers - -. bfd_vma (*bfd_h_getx64) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_64) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx64) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_h_getx32) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_32) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx32) PARAMS ((bfd_vma, bfd_byte *)); -. bfd_vma (*bfd_h_getx16) PARAMS ((const bfd_byte *)); -. bfd_signed_vma (*bfd_h_getx_signed_16) PARAMS ((const bfd_byte *)); -. void (*bfd_h_putx16) PARAMS ((bfd_vma, bfd_byte *)); - -Format dependent routines: these are vectors of entry points -within the target vector structure, one for each format to check. - -Check the format of a file being read. Return a <<bfd_target *>> or zero. - -. const struct bfd_target *(*_bfd_check_format[bfd_type_end]) PARAMS ((bfd *)); - -Set the format of a file being written. - -. boolean (*_bfd_set_format[bfd_type_end]) PARAMS ((bfd *)); - -Write cached information into a file being written, at <<bfd_close>>. - -. boolean (*_bfd_write_contents[bfd_type_end]) PARAMS ((bfd *)); - -The general target vector. - -. -. {* Generic entry points. *} -.#define BFD_JUMP_TABLE_GENERIC(NAME)\ -.CAT(NAME,_close_and_cleanup),\ -.CAT(NAME,_bfd_free_cached_info),\ -.CAT(NAME,_new_section_hook),\ -.CAT(NAME,_get_section_contents) -. {* Called when the BFD is being closed to do any necessary cleanup. *} -. boolean (*_close_and_cleanup) PARAMS ((bfd *)); -. {* Ask the BFD to free all cached information. *} -. boolean (*_bfd_free_cached_info) PARAMS ((bfd *)); -. {* Called when a new section is created. *} -. boolean (*_new_section_hook) PARAMS ((bfd *, sec_ptr)); -. {* Read the contents of a section. *} -. boolean (*_bfd_get_section_contents) PARAMS ((bfd *, sec_ptr, PTR, -. file_ptr, bfd_size_type)); -. -. {* Entry points to copy private data. *} -.#define BFD_JUMP_TABLE_COPY(NAME)\ -.CAT(NAME,_bfd_copy_private_bfd_data),\ -.CAT(NAME,_bfd_copy_private_section_data) -. {* Called to copy BFD general private data from one object file -. to another. *} -. boolean (*_bfd_copy_private_bfd_data) PARAMS ((bfd *, bfd *)); -. {* Called to copy BFD private section data from one object file -. to another. *} -. boolean (*_bfd_copy_private_section_data) PARAMS ((bfd *, sec_ptr, -. bfd *, sec_ptr)); -. -. {* Core file entry points. *} -.#define BFD_JUMP_TABLE_CORE(NAME)\ -.CAT(NAME,_core_file_failing_command),\ -.CAT(NAME,_core_file_failing_signal),\ -.CAT(NAME,_core_file_matches_executable_p) -. char * (*_core_file_failing_command) PARAMS ((bfd *)); -. int (*_core_file_failing_signal) PARAMS ((bfd *)); -. boolean (*_core_file_matches_executable_p) PARAMS ((bfd *, bfd *)); -. -. {* Archive entry points. *} -.#define BFD_JUMP_TABLE_ARCHIVE(NAME)\ -.CAT(NAME,_slurp_armap),\ -.CAT(NAME,_slurp_extended_name_table),\ -.CAT(NAME,_truncate_arname),\ -.CAT(NAME,_write_armap),\ -.CAT(NAME,_openr_next_archived_file),\ -.CAT(NAME,_generic_stat_arch_elt) -. boolean (*_bfd_slurp_armap) PARAMS ((bfd *)); -. boolean (*_bfd_slurp_extended_name_table) PARAMS ((bfd *)); -. void (*_bfd_truncate_arname) PARAMS ((bfd *, CONST char *, char *)); -. boolean (*write_armap) PARAMS ((bfd *arch, -. unsigned int elength, -. struct orl *map, -. unsigned int orl_count, -. int stridx)); -. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev)); -. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *)); -. -. {* Entry points used for symbols. *} -.#define BFD_JUMP_TABLE_SYMBOLS(NAME)\ -.CAT(NAME,_get_symtab_upper_bound),\ -.CAT(NAME,_get_symtab),\ -.CAT(NAME,_make_empty_symbol),\ -.CAT(NAME,_print_symbol),\ -.CAT(NAME,_get_symbol_info),\ -.CAT(NAME,_bfd_is_local_label),\ -.CAT(NAME,_get_lineno),\ -.CAT(NAME,_find_nearest_line),\ -.CAT(NAME,_bfd_make_debug_symbol) -. long (*_bfd_get_symtab_upper_bound) PARAMS ((bfd *)); -. long (*_bfd_canonicalize_symtab) PARAMS ((bfd *, -. struct symbol_cache_entry **)); -. struct symbol_cache_entry * -. (*_bfd_make_empty_symbol) PARAMS ((bfd *)); -. void (*_bfd_print_symbol) PARAMS ((bfd *, PTR, -. struct symbol_cache_entry *, -. bfd_print_symbol_type)); -.#define bfd_print_symbol(b,p,s,e) BFD_SEND(b, _bfd_print_symbol, (b,p,s,e)) -. void (*_bfd_get_symbol_info) PARAMS ((bfd *, -. struct symbol_cache_entry *, -. symbol_info *)); -.#define bfd_get_symbol_info(b,p,e) BFD_SEND(b, _bfd_get_symbol_info, (b,p,e)) -. boolean (*_bfd_is_local_label) PARAMS ((bfd *, asymbol *)); -. -. alent * (*_get_lineno) PARAMS ((bfd *, struct symbol_cache_entry *)); -. boolean (*_bfd_find_nearest_line) PARAMS ((bfd *abfd, -. struct sec *section, struct symbol_cache_entry **symbols, -. bfd_vma offset, CONST char **file, CONST char **func, -. unsigned int *line)); -. {* Back-door to allow format-aware applications to create debug symbols -. while using BFD for everything else. Currently used by the assembler -. when creating COFF files. *} -. asymbol * (*_bfd_make_debug_symbol) PARAMS (( -. bfd *abfd, -. void *ptr, -. unsigned long size)); -. -. {* Routines for relocs. *} -.#define BFD_JUMP_TABLE_RELOCS(NAME)\ -.CAT(NAME,_get_reloc_upper_bound),\ -.CAT(NAME,_canonicalize_reloc),\ -.CAT(NAME,_bfd_reloc_type_lookup) -. long (*_get_reloc_upper_bound) PARAMS ((bfd *, sec_ptr)); -. long (*_bfd_canonicalize_reloc) PARAMS ((bfd *, sec_ptr, arelent **, -. struct symbol_cache_entry **)); -. {* See documentation on reloc types. *} -. CONST struct reloc_howto_struct * -. (*reloc_type_lookup) PARAMS ((bfd *abfd, -. bfd_reloc_code_real_type code)); -. -. {* Routines used when writing an object file. *} -.#define BFD_JUMP_TABLE_WRITE(NAME)\ -.CAT(NAME,_set_arch_mach),\ -.CAT(NAME,_set_section_contents) -. boolean (*_bfd_set_arch_mach) PARAMS ((bfd *, enum bfd_architecture, -. unsigned long)); -. boolean (*_bfd_set_section_contents) PARAMS ((bfd *, sec_ptr, PTR, -. file_ptr, bfd_size_type)); -. -. {* Routines used by the linker. *} -.#define BFD_JUMP_TABLE_LINK(NAME)\ -.CAT(NAME,_sizeof_headers),\ -.CAT(NAME,_bfd_get_relocated_section_contents),\ -.CAT(NAME,_bfd_relax_section),\ -.CAT(NAME,_bfd_link_hash_table_create),\ -.CAT(NAME,_bfd_link_add_symbols),\ -.CAT(NAME,_bfd_final_link) -. int (*_bfd_sizeof_headers) PARAMS ((bfd *, boolean)); -. bfd_byte * (*_bfd_get_relocated_section_contents) PARAMS ((bfd *, -. struct bfd_link_info *, struct bfd_link_order *, -. bfd_byte *data, boolean relocateable, -. struct symbol_cache_entry **)); -. -. boolean (*_bfd_relax_section) PARAMS ((bfd *, struct sec *, -. struct bfd_link_info *, boolean *again)); -. -. {* Create a hash table for the linker. Different backends store -. different information in this table. *} -. struct bfd_link_hash_table *(*_bfd_link_hash_table_create) PARAMS ((bfd *)); -. -. {* Add symbols from this object file into the hash table. *} -. boolean (*_bfd_link_add_symbols) PARAMS ((bfd *, struct bfd_link_info *)); -. -. {* Do a link based on the link_order structures attached to each -. section of the BFD. *} -. boolean (*_bfd_final_link) PARAMS ((bfd *, struct bfd_link_info *)); -. -. {* Routines to handle dynamic symbols and relocs. *} -.#define BFD_JUMP_TABLE_DYNAMIC(NAME)\ -.CAT(NAME,_get_dynamic_symtab_upper_bound),\ -.CAT(NAME,_canonicalize_dynamic_symtab),\ -.CAT(NAME,_get_dynamic_reloc_upper_bound),\ -.CAT(NAME,_canonicalize_dynamic_reloc) -. {* Get the amount of memory required to hold the dynamic symbols. *} -. long (*_bfd_get_dynamic_symtab_upper_bound) PARAMS ((bfd *)); -. {* Read in the dynamic symbols. *} -. long (*_bfd_canonicalize_dynamic_symtab) -. PARAMS ((bfd *, struct symbol_cache_entry **)); -. {* Get the amount of memory required to hold the dynamic relocs. *} -. long (*_bfd_get_dynamic_reloc_upper_bound) PARAMS ((bfd *)); -. {* Read in the dynamic relocs. *} -. long (*_bfd_canonicalize_dynamic_reloc) -. PARAMS ((bfd *, arelent **, struct symbol_cache_entry **)); -. - -Data for use by back-end routines, which isn't generic enough to belong -in this structure. - -. PTR backend_data; -.} bfd_target; - -*/ - -/* All known xvecs (even those that don't compile on all systems). - Alphabetized for easy reference. - They are listed a second time below, since - we can't intermix extern's and initializers. */ -extern const bfd_target a29kcoff_big_vec; -extern const bfd_target a_out_adobe_vec; -extern const bfd_target aout_mips_big_vec; -extern const bfd_target aout_mips_little_vec; -extern const bfd_target aout0_big_vec; -extern const bfd_target apollocoff_vec; -extern const bfd_target b_out_vec_big_host; -extern const bfd_target b_out_vec_little_host; -extern const bfd_target bfd_elf32_big_generic_vec; -extern const bfd_target bfd_elf32_bigmips_vec; -extern const bfd_target bfd_elf32_hppa_vec; -extern const bfd_target bfd_elf32_i386_vec; -extern const bfd_target bfd_elf32_i860_vec; -extern const bfd_target bfd_elf32_little_generic_vec; -extern const bfd_target bfd_elf32_littlemips_vec; -extern const bfd_target bfd_elf32_m68k_vec; -extern const bfd_target bfd_elf32_m88k_vec; -extern const bfd_target bfd_elf32_powerpc_vec; -extern const bfd_target bfd_elf32_sparc_vec; -extern const bfd_target bfd_elf64_big_generic_vec; -extern const bfd_target bfd_elf64_little_generic_vec; -extern const bfd_target bfd_elf64_sparc_vec; -extern const bfd_target demo_64_vec; -extern const bfd_target ecoff_big_vec; -extern const bfd_target ecoff_little_vec; -extern const bfd_target ecoffalpha_little_vec; -extern const bfd_target h8300coff_vec; -extern const bfd_target h8500coff_vec; -extern const bfd_target host_aout_vec; -extern const bfd_target hp300bsd_vec; -extern const bfd_target hp300hpux_vec; -extern const bfd_target som_vec; -extern const bfd_target i386aout_vec; -extern const bfd_target i386bsd_vec; -extern const bfd_target i386dynix_vec; -extern const bfd_target i386os9k_vec; -extern const bfd_target netbsd386_vec; -extern const bfd_target freebsd386_vec; -extern const bfd_target i386coff_vec; -extern const bfd_target go32coff_vec; -extern const bfd_target i386linux_vec; -extern const bfd_target i386lynx_aout_vec; -extern const bfd_target i386lynx_coff_vec; -extern const bfd_target i386mach3_vec; -extern const bfd_target icoff_big_vec; -extern const bfd_target icoff_little_vec; -extern const bfd_target ieee_vec; -extern const bfd_target m68kcoff_vec; -extern const bfd_target m68kcoffun_vec; -extern const bfd_target m68klynx_aout_vec; -extern const bfd_target m68klynx_coff_vec; -extern const bfd_target m88kbcs_vec; -extern const bfd_target m88kmach3_vec; -extern const bfd_target netbsd532_vec; -extern const bfd_target newsos3_vec; -extern const bfd_target nlm32_i386_vec; -extern const bfd_target nlm32_sparc_vec; -extern const bfd_target nlm32_alpha_vec; -extern const bfd_target nlm32_powerpc_vec; -extern const bfd_target oasys_vec; -extern const bfd_target pc532mach_vec; -extern const bfd_target rs6000coff_vec; -extern const bfd_target shcoff_vec; -extern const bfd_target sparclynx_aout_vec; -extern const bfd_target sparclynx_coff_vec; -extern const bfd_target sparccoff_vec; -extern const bfd_target sunos_big_vec; -extern const bfd_target tekhex_vec; -extern const bfd_target we32kcoff_vec; -extern const bfd_target z8kcoff_vec; - -/* srec is always included. */ -extern const bfd_target srec_vec; -extern const bfd_target symbolsrec_vec; - -/* All of the xvecs for core files. */ -extern const bfd_target aix386_core_vec; -extern const bfd_target cisco_core_vec; -extern const bfd_target hpux_core_vec; -extern const bfd_target hppabsd_core_vec; -extern const bfd_target irix_core_vec; -extern const bfd_target osf_core_vec; -extern const bfd_target sco_core_vec; -extern const bfd_target trad_core_vec; -extern const bfd_target ptrace_core_vec; - -const bfd_target * const bfd_target_vector[] = { - -#ifdef SELECT_VECS - - SELECT_VECS, - -#else /* not SELECT_VECS */ - -#ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, -#endif - /* This list is alphabetized to make it easy to compare - with other vector lists -- the decls above and - the case statement in configure.in. - Vectors that don't compile on all systems, or aren't finished, - should have an entry here with #if 0 around it, to show that - it wasn't omitted by mistake. */ - &a29kcoff_big_vec, - &a_out_adobe_vec, -#if 0 /* No one seems to use this. */ - &aout_mips_big_vec, -#endif - &aout_mips_little_vec, - &b_out_vec_big_host, - &b_out_vec_little_host, - - /* This, and other vectors, may not be used in any *.mt configuration. - But that does not mean they are unnecessary. If configured with - --enable-targets=all, objdump or gdb should be able to examine - the file even if we don't recognize the machine type. */ - &bfd_elf32_big_generic_vec, - &bfd_elf32_bigmips_vec, - &bfd_elf32_hppa_vec, - &bfd_elf32_i386_vec, - &bfd_elf32_i860_vec, - &bfd_elf32_little_generic_vec, - &bfd_elf32_littlemips_vec, - &bfd_elf32_m68k_vec, - &bfd_elf32_m88k_vec, - &bfd_elf32_sparc_vec, - &bfd_elf32_powerpc_vec, -#ifdef BFD64 /* No one seems to use this. */ - &bfd_elf64_big_generic_vec, - &bfd_elf64_little_generic_vec, -#endif -#if 0 - &bfd_elf64_sparc_vec, -#endif - /* We don't include cisco_core_vec. Although it has a magic number, - the magic number isn't at the beginning of the file, and thus - might spuriously match other kinds of files. */ -#ifdef BFD64 - &demo_64_vec, /* Only compiled if host has long-long support */ -#endif - &ecoff_big_vec, - &ecoff_little_vec, -#if 0 - &ecoffalpha_little_vec, -#endif - &h8300coff_vec, - &h8500coff_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &host_aout_vec, -#endif -#if 0 /* Clashes with sunos_big_vec magic no. */ - &hp300bsd_vec, -#endif - &hp300hpux_vec, -#if defined (HOST_HPPAHPUX) || defined (HOST_HPPABSD) || defined (HOST_HPPAOSF) - &som_vec, -#endif - &i386aout_vec, - &i386bsd_vec, - &i386coff_vec, - &go32coff_vec, -#if 0 - /* Since a.out files lack decent magic numbers, no way to recognize - which kind of a.out file it is. */ - &i386linux_vec, -#endif - &i386lynx_aout_vec, - &i386lynx_coff_vec, -#if 0 - /* No distinguishing features for Mach 3 executables. */ - &i386mach3_vec, -#endif - &i386os9k_vec, - &icoff_big_vec, - &icoff_little_vec, - &ieee_vec, - &m68kcoff_vec, - &m68kcoffun_vec, - &m68klynx_aout_vec, - &m68klynx_coff_vec, - &m88kbcs_vec, - &m88kmach3_vec, - &newsos3_vec, - &netbsd386_vec, - &netbsd532_vec, - &nlm32_i386_vec, - &nlm32_sparc_vec, -#ifdef BFD64 - &nlm32_alpha_vec, -#endif -#if 0 - /* We have no oasys tools anymore, so we can't test any of this - anymore. If you want to test the stuff yourself, go ahead... - steve@cygnus.com - Worse, since there is no magic number for archives, there - can be annoying target mis-matches. */ - &oasys_vec, -#endif - &pc532machaout_vec, - &rs6000coff_vec, - &shcoff_vec, - &sparclynx_aout_vec, - &sparclynx_coff_vec, - &sunos_big_vec, - &aout0_big_vec, -#if 0 - &tekhex_vec, -#endif - &we32kcoff_vec, - &z8kcoff_vec, - -#endif /* not SELECT_VECS */ - -/* Always support S-records, for convenience. */ - &srec_vec, - &symbolsrec_vec, - -/* Add any required traditional-core-file-handler. */ - -#ifdef AIX386_CORE - &aix386_core_vec, -#endif -#ifdef HPUX_CORE - &hpux_core_vec, -#endif -#ifdef HPPABSD_CORE - &hppabsd_core_vec, -#endif -#ifdef IRIX_CORE - &irix_core_vec, -#endif -#ifdef OSF_CORE - &osf_core_vec, -#endif -#ifdef TRAD_CORE - &trad_core_vec, -#endif - -#ifdef PTRACE_CORE - &ptrace_core_vec, -#endif - - NULL /* end of list marker */ -}; - -/* bfd_default_vector[0] contains either the address of the default vector, - if there is one, or zero if there isn't. */ - -const bfd_target * const bfd_default_vector[] = { -#ifdef DEFAULT_VECTOR - &DEFAULT_VECTOR, -#endif - NULL -}; - -/* When there is an ambiguous match, bfd_check_format_matches puts the - names of the matching targets in an array. This variable is the maximum - number of entries that the array could possibly need. */ -const size_t _bfd_target_vector_entries = sizeof(bfd_target_vector)/sizeof(*bfd_target_vector); - -/* -FUNCTION - bfd_find_target - -SYNOPSIS - const bfd_target *bfd_find_target(CONST char *target_name, bfd *abfd); - -DESCRIPTION - Return a pointer to the transfer vector for the object target - named @var{target_name}. If @var{target_name} is <<NULL>>, choose the - one in the environment variable <<GNUTARGET>>; if that is null or not - defined, then choose the first entry in the target list. - Passing in the string "default" or setting the environment - variable to "default" will cause the first entry in the target - list to be returned, and "target_defaulted" will be set in the - BFD. This causes <<bfd_check_format>> to loop over all the - targets to find the one that matches the file being read. -*/ - -const bfd_target * -bfd_find_target (target_name, abfd) - CONST char *target_name; - bfd *abfd; -{ - const bfd_target * const *target; - extern char *getenv (); - CONST char *targname = (target_name ? target_name : - (CONST char *) getenv ("GNUTARGET")); - - /* This is safe; the vector cannot be null */ - if (targname == NULL || !strcmp (targname, "default")) { - abfd->target_defaulted = true; - return abfd->xvec = bfd_target_vector[0]; - } - - abfd->target_defaulted = false; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) { - if (!strcmp (targname, (*target)->name)) - return abfd->xvec = *target; - } - - bfd_set_error (bfd_error_invalid_target); - return NULL; -} - - -/* -FUNCTION - bfd_target_list - -SYNOPSIS - const char **bfd_target_list(void); - -DESCRIPTION - Return a freshly malloced NULL-terminated - vector of the names of all the valid BFD targets. Do not - modify the names. - -*/ - -const char ** -bfd_target_list () -{ - int vec_length= 0; -#ifdef NATIVE_HPPAHPUX_COMPILER - /* The native compiler on the HP9000/700 has a bug which causes it - to loop endlessly when compiling this file. This avoids it. */ - volatile -#endif - const bfd_target * const *target; - CONST char **name_list, **name_ptr; - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - vec_length++; - - name_ptr = name_list = (CONST char **) - bfd_zmalloc ((vec_length + 1) * sizeof (char **)); - - if (name_list == NULL) { - bfd_set_error (bfd_error_no_memory); - return NULL; - } - - for (target = &bfd_target_vector[0]; *target != NULL; target++) - *(name_ptr++) = (*target)->name; - - return name_list; -} diff --git a/gnu/usr.bin/gdb/bfd/trad-core.c b/gnu/usr.bin/gdb/bfd/trad-core.c deleted file mode 100644 index c79ac3a..0000000 --- a/gnu/usr.bin/gdb/bfd/trad-core.c +++ /dev/null @@ -1,339 +0,0 @@ -/* BFD back end for traditional Unix core files (U-area and raw sections) - Copyright 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. - Written by John Gilmore of Cygnus Support. - -This file is part of BFD, the Binary File Descriptor library. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* To use this file on a particular host, configure the host with these - parameters in the config/h-HOST file: - - HDEFINES=-DTRAD_CORE - HDEPFILES=trad-core.o - - */ - -#include "bfd.h" -#include "sysdep.h" -#include "libbfd.h" -#include "libaout.h" /* BFD a.out internal data structures */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <signal.h> - -#include <sys/user.h> /* After a.out.h */ -#if 0 -/* file.h is included by std-host.h. So we better not try to include it - twice; on some systems (dpx2) it is not protected against multiple - inclusion. I have checked that all the hosts which use this file - include sys/file.h in the hosts file. */ -#include <sys/file.h> -#endif - -#include <errno.h> - - struct trad_core_struct - { - asection *data_section; - asection *stack_section; - asection *reg_section; - struct user u; - } *rawptr; - -#define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u)) -#define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section) -#define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section) -#define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section) - -/* forward declarations */ - -const bfd_target *trad_unix_core_file_p PARAMS ((bfd *abfd)); -char * trad_unix_core_file_failing_command PARAMS ((bfd *abfd)); -int trad_unix_core_file_failing_signal PARAMS ((bfd *abfd)); -boolean trad_unix_core_file_matches_executable_p - PARAMS ((bfd *core_bfd, bfd *exec_bfd)); - -/* Handle 4.2-style (and perhaps also sysV-style) core dump file. */ - -/* ARGSUSED */ -const bfd_target * -trad_unix_core_file_p (abfd) - bfd *abfd; - -{ - int val; - struct user u; - -#ifdef TRAD_CORE_USER_OFFSET - /* If defined, this macro is the file position of the user struct. */ - if (bfd_seek (abfd, TRAD_CORE_USER_OFFSET, SEEK_SET) != 0) - return 0; -#endif - - val = bfd_read ((void *)&u, 1, sizeof u, abfd); - if (val != sizeof u) - { - /* Too small to be a core file */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* Sanity check perhaps??? */ - if (u.u_dsize > 0x1000000) /* Remember, it's in pages... */ - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - if (u.u_ssize > 0x1000000) - { - bfd_set_error (bfd_error_wrong_format); - return 0; - } - - /* Check that the size claimed is no greater than the file size. */ - { - FILE *stream = bfd_cache_lookup (abfd); - struct stat statbuf; - if (stream == NULL) - return 0; - if (fstat (fileno (stream), &statbuf) < 0) - { - bfd_set_error (bfd_error_system_call); - return 0; - } - if (PAGE_SIZE * (UPAGES + u.u_dsize -#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE - - u.u_tsize -#endif - + u.u_ssize) > statbuf.st_size) - { - bfd_set_error (bfd_error_file_truncated); - return 0; - } -#ifndef TRAD_CORE_ALLOW_ANY_EXTRA_SIZE - if (PAGE_SIZE * (UPAGES + u.u_dsize + u.u_ssize) -#ifdef TRAD_CORE_EXTRA_SIZE_ALLOWED - /* Some systems write the file too big. */ - + TRAD_CORE_EXTRA_SIZE_ALLOWED -#endif - < statbuf.st_size) - { - /* The file is too big. Maybe it's not a core file - or we otherwise have bad values for u_dsize and u_ssize). */ - bfd_set_error (bfd_error_wrong_format); - return 0; - } -#endif - } - - /* OK, we believe you. You're a core file (sure, sure). */ - - /* Allocate both the upage and the struct core_data at once, so - a single free() will free them both. */ - rawptr = (struct trad_core_struct *) - bfd_zmalloc (sizeof (struct trad_core_struct)); - if (rawptr == NULL) { - bfd_set_error (bfd_error_no_memory); - return 0; - } - - abfd->tdata.trad_core_data = rawptr; - - rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */ - - /* Create the sections. This is raunchy, but bfd_close wants to free - them separately. */ - - core_stacksec(abfd) = (asection *) bfd_zmalloc (sizeof (asection)); - if (core_stacksec (abfd) == NULL) { - loser: - bfd_set_error (bfd_error_no_memory); - free ((void *)rawptr); - return 0; - } - core_datasec (abfd) = (asection *) bfd_zmalloc (sizeof (asection)); - if (core_datasec (abfd) == NULL) { - loser1: - free ((void *)core_stacksec (abfd)); - goto loser; - } - core_regsec (abfd) = (asection *) bfd_zmalloc (sizeof (asection)); - if (core_regsec (abfd) == NULL) { - free ((void *)core_datasec (abfd)); - goto loser1; - } - - core_stacksec (abfd)->name = ".stack"; - core_datasec (abfd)->name = ".data"; - core_regsec (abfd)->name = ".reg"; - - core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS; - core_regsec (abfd)->flags = SEC_HAS_CONTENTS; - - core_datasec (abfd)->_raw_size = PAGE_SIZE * u.u_dsize -#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE - - PAGE_SIZE * u.u_tsize -#endif - ; - core_stacksec (abfd)->_raw_size = PAGE_SIZE * u.u_ssize; - core_regsec (abfd)->_raw_size = PAGE_SIZE * UPAGES; /* Larger than sizeof struct u */ - - /* What a hack... we'd like to steal it from the exec file, - since the upage does not seem to provide it. FIXME. */ -#ifdef HOST_DATA_START_ADDR - core_datasec (abfd)->vma = HOST_DATA_START_ADDR; -#else - core_datasec (abfd)->vma = HOST_TEXT_START_ADDR + (PAGE_SIZE * u.u_tsize); -#endif - -#ifdef HOST_STACK_START_ADDR - core_stacksec (abfd)->vma = HOST_STACK_START_ADDR; -#else - core_stacksec (abfd)->vma = HOST_STACK_END_ADDR - (PAGE_SIZE * u.u_ssize); -#endif - - /* This is tricky. As the "register section", we give them the entire - upage and stack. u.u_ar0 points to where "register 0" is stored. - There are two tricks with this, though. One is that the rest of the - registers might be at positive or negative (or both) displacements - from *u_ar0. The other is that u_ar0 is sometimes an absolute address - in kernel memory, and on other systems it is an offset from the beginning - of the `struct user'. - - As a practical matter, we don't know where the registers actually are, - so we have to pass the whole area to GDB. We encode the value of u_ar0 - by setting the .regs section up so that its virtual memory address - 0 is at the place pointed to by u_ar0 (by setting the vma of the start - of the section to -u_ar0). GDB uses this info to locate the regs, - using minor trickery to get around the offset-or-absolute-addr problem. */ - core_regsec (abfd)->vma = 0 - (int) u.u_ar0; - - core_datasec (abfd)->filepos = PAGE_SIZE * UPAGES; - core_stacksec (abfd)->filepos = (PAGE_SIZE * UPAGES) + PAGE_SIZE * u.u_dsize -#ifdef TRAD_CORE_DSIZE_INCLUDES_TSIZE - - PAGE_SIZE * u.u_tsize -#endif - ; - core_regsec (abfd)->filepos = 0; /* Register segment is the upage */ - - /* Align to word at least */ - core_stacksec (abfd)->alignment_power = 2; - core_datasec (abfd)->alignment_power = 2; - core_regsec (abfd)->alignment_power = 2; - - abfd->sections = core_stacksec (abfd); - core_stacksec (abfd)->next = core_datasec (abfd); - core_datasec (abfd)->next = core_regsec (abfd); - abfd->section_count = 3; - - return abfd->xvec; -} - -char * -trad_unix_core_file_failing_command (abfd) - bfd *abfd; -{ -#ifndef NO_CORE_COMMAND - char *com = abfd->tdata.trad_core_data->u.u_comm; - if (*com) - return com; - else -#endif - return 0; -} - -/* ARGSUSED */ -int -trad_unix_core_file_failing_signal (ignore_abfd) - bfd *ignore_abfd; -{ -#ifdef TRAD_UNIX_CORE_FILE_FAILING_SIGNAL - return TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(ignore_abfd); -#else - return -1; /* FIXME, where is it? */ -#endif -} - -/* ARGSUSED */ -boolean -trad_unix_core_file_matches_executable_p (core_bfd, exec_bfd) - bfd *core_bfd, *exec_bfd; -{ - return true; /* FIXME, We have no way of telling at this point */ -} - -/* If somebody calls any byte-swapping routines, shoot them. */ -void -swap_abort() -{ - abort(); /* This way doesn't require any declaration for ANSI to fuck up */ -} -#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort ) -#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort ) -#define NO_SIGNED_GET \ - ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort ) - -const bfd_target trad_core_vec = - { - "trad-core", - bfd_target_unknown_flavour, - true, /* target byte order */ - true, /* target headers byte order */ - (HAS_RELOC | EXEC_P | /* object flags */ - HAS_LINENO | HAS_DEBUG | - HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED), - (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - 0, /* symbol prefix */ - ' ', /* ar_pad_char */ - 16, /* ar_max_namelen */ - 3, /* minimum alignment power */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */ - NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */ - - { /* bfd_check_format */ - _bfd_dummy_target, /* unknown format */ - _bfd_dummy_target, /* object file */ - _bfd_dummy_target, /* archive */ - trad_unix_core_file_p /* a core file */ - }, - { /* bfd_set_format */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - { /* bfd_write_contents */ - bfd_false, bfd_false, - bfd_false, bfd_false - }, - - BFD_JUMP_TABLE_GENERIC (_bfd_generic), - BFD_JUMP_TABLE_COPY (_bfd_generic), - BFD_JUMP_TABLE_CORE (trad_unix), - BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive), - BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols), - BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), - BFD_JUMP_TABLE_WRITE (_bfd_generic), - BFD_JUMP_TABLE_LINK (_bfd_nolink), - BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), - - (PTR) 0 /* backend_data */ -}; |