📄 aoutx.h
字号:
/* BFD semi-generic back-end for a.out binaries. 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//*SECTION a.out backendsDESCRIPTION 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 @code{aoutx.h} and other files which derive functions from the base. One derivation file is @code{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 @code{sunos.c} for sun3 and sun4, @code{newsos3.c} for the Sony NEWS, and @code{demo64.c} for a demonstration of a 64 bit a.out format. The base file @code{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 @code{aout32.c} and @code{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 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 sunos.c| #define ARCH 32| #define TARGET_NAME "a.out-sunos-big"| #define VECNAME sunos_big_vec| #include "aoutf1.h" requires all the names from aout32.c, and produces the jump vector| sunos_big_vec The 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 <<../include/sys/h-XXX.h>> (for your host). These values, plus the structures and macros defined in <<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 <<host-aout.c>., specify: | TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec| TDEPFILES= host-aout.o trad-core.o in the <<config/mt-XXX>> file, and modify configure.in to use the <<mt-XXX>> 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 "bfd.h"#include <sysdep.h>#include <ansidecl.h>struct external_exec;#include "libaout.h"#include "libbfd.h"#include "aout/aout64.h"#include "aout/stab_gnu.h"#include "aout/ar.h"extern void (*bfd_error_trap)();/*SUBSECTION relocationsDESCRIPTION The file @code{aoutx.h} caters for both the @emph{standard} and @emph{extended} forms of a.out relocation records. The standard records are characterised by containing 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. */#define CTOR_TABLE_RELOC_IDX 2#define howto_table_ext NAME(aout,ext_howto_table)#define howto_table_std NAME(aout,std_howto_table)reloc_howto_type howto_table_ext[] = { HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false), HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false), HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false), HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false), HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false), HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false), HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false), HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false), HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false), HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false), HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false), HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false), HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false), HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false), HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false), HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false), HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false), HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false), HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false), HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false), HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false), HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false), HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false), HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,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 abs ovrf sf name part_inpl readmask setmask pcdone */HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),};CONST struct reloc_howto_struct *DEFUN(NAME(aout,reloc_type_lookup),(abfd,code), bfd *abfd AND 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; } 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); } 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); } return 0;}extern bfd_error_vector_type bfd_error_vector;/*SUBSECTION Internal Entry PointsDESCRIPTION @code{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_<size>_swap_exec_header_inDESCRIPTION Swaps the information in an executable header taken from a raw byte stream memory image, into the internal exec_header structure.EXAMPLE void aout_<size>_swap_exec_header_in, (bfd *abfd, struct external_exec *raw_bytes, struct internal_exec *execp);*/ voidDEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp), bfd *abfd AND struct external_exec *raw_bytes AND 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 (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);}/*FUNCTION aout_<size>_swap_exec_header_outDESCRIPTION Swaps the information in an internal exec header structure into the supplied buffer ready for writing to disk.EXAMPLE void aout_<size>_swap_exec_header_out (bfd *abfd, struct internal_exec *execp, struct external_exec *raw_bytes);*/voidDEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes), bfd *abfd AND struct internal_exec *execp AND 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);}/*FUNCTION aout_<size>_some_aout_object_pDESCRIPTION Some A.OUT variant thinks that the file whose format we're checking is an a.out file. Do some more checking, and set up for access if it really is. Call back to the calling environments "finish up" function just before returning, to handle any last-minute setup. EXAMPLE bfd_target *aout_<size>_some_aout_object_p (bfd *abfd, bfd_target *(*callback_to_real_object_p)());*/ bfd_target *DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p), bfd *abfd AND struct internal_exec *execp AND bfd_target *(*callback_to_real_object_p) ()){ struct aout_data_struct *rawptr, *oldrawptr; bfd_target *result; rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, sizeof (struct aout_data_struct )); if (rawptr == NULL) { bfd_error = no_memory; return 0; } oldrawptr = abfd->tdata.aout_data; abfd->tdata.aout_data = rawptr; 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_MAGIC (*execp) == ZMAGIC) { abfd->flags |= D_PAGED|WP_TEXT; adata(abfd).magic = z_magic; } else if (N_MAGIC (*execp) == NMAGIC) { abfd->flags |= WP_TEXT; adata(abfd).magic = n_magic; } else adata(abfd).magic = o_magic; 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; /* create the sections. This is raunchy, but bfd_close wants to reclaim them */ obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text"); obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data"); obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");#if 0 (void)bfd_make_section (abfd, ".text"); (void)bfd_make_section (abfd, ".data"); (void)bfd_make_section (abfd, ".bss");#endif 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 addersses 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -