📄 aoutx.h
字号:
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); /* 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; if (result) { abfd->sections = obj_textsec (abfd); obj_textsec (abfd)->next = obj_datasec (abfd); obj_datasec (abfd)->next = obj_bsssec (abfd); } else { free (rawptr); abfd->tdata.aout_data = oldrawptr; } return result;}/*FUNCTION aout_<size>_mkobjectDESCRIPTION This routine initializes a BFD for use with a.out files.EXAMPLE boolean aout_<size>_mkobject, (bfd *);*/booleanDEFUN(NAME(aout,mkobject),(abfd), bfd *abfd){ struct aout_data_struct *rawptr; bfd_error = system_call_error; /* Use an intermediate variable for clarity */ rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct )); if (rawptr == NULL) { bfd_error = no_memory; return false; } abfd->tdata.aout_data = rawptr; exec_hdr (abfd) = &(rawptr->e); /* For simplicity's sake we just make all the sections right here. */ obj_textsec (abfd) = (asection *)NULL; obj_datasec (abfd) = (asection *)NULL; obj_bsssec (abfd) = (asection *)NULL; bfd_make_section (abfd, ".text"); bfd_make_section (abfd, ".data"); bfd_make_section (abfd, ".bss"); bfd_make_section (abfd, BFD_ABS_SECTION_NAME); bfd_make_section (abfd, BFD_UND_SECTION_NAME); bfd_make_section (abfd, BFD_COM_SECTION_NAME); return true;}/*FUNCTION aout_<size>_machine_typeDESCRIPTION Keep track of machine architecture and machine type for a.out's. Return the machine_type for a particular arch&machine, or M_UNKNOWN if that exact arch&machine can't be represented in a.out format. If the architecture is understood, machine type 0 (default) should always be understood. EXAMPLE enum machine_type aout_<size>_machine_type (enum bfd_architecture arch, unsigned long machine));*/enum machine_typeDEFUN(NAME(aout,machine_type),(arch, machine), enum bfd_architecture arch AND unsigned long machine){ enum machine_type arch_flags; arch_flags = M_UNKNOWN; 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; 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; default: arch_flags = M_UNKNOWN; break; } return arch_flags;}/*FUNCTION aout_<size>_set_arch_machDESCRIPTION Sets the architecture and the machine of the BFD to those values supplied. Verifies that the format can support the architecture required.EXAMPLE boolean aout_<size>_set_arch_mach, (bfd *, enum bfd_architecture, unsigned long machine));*/booleanDEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine), bfd *abfd AND enum bfd_architecture arch AND unsigned long machine){ bfd_default_set_arch_mach(abfd, arch, machine); if (arch != bfd_arch_unknown && NAME(aout,machine_type) (arch, machine) == M_UNKNOWN) return false; /* We can't represent this type */ /* Determine the size of a relocation entry */ switch (arch) { case bfd_arch_sparc: case bfd_arch_a29k: 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);}booleanDEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end), bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end){ struct internal_exec *execp = exec_hdr (abfd); if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) { bfd_error = invalid_operation; 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 (adata(abfd).magic == undecided_magic) { if (abfd->flags & D_PAGED) /* whether or not WP_TEXT is set */ 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: { file_ptr pos = adata (abfd).exec_bytes_size; bfd_vma vma = 0; int pad = 0; obj_textsec(abfd)->filepos = pos; pos += obj_textsec(abfd)->_raw_size; vma += obj_textsec(abfd)->_raw_size; 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; 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; 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); } break; case z_magic: { bfd_size_type data_pad, text_pad; file_ptr text_end; CONST struct aout_backend_data *abdp; int ztih; bfd_vma data_vma; abdp = aout_backend_info (abfd); ztih = abdp && abdp->text_includes_header; obj_textsec(abfd)->filepos = (ztih ? adata(abfd).exec_bytes_size : adata(abfd).page_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. */ text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size; text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end; obj_textsec(abfd)->_raw_size += text_pad; text_end += text_pad; 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); } data_vma = obj_datasec(abfd)->vma; 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; N_SET_MAGIC (*execp, ZMAGIC); /* Spec says data section should be rounded up to page boundary. */ /* If extra space in page is left after 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. */ 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; /* This code is almost surely botched. It'll only get tested for the case where the application does explicitly set the VMA of the BSS section. */ if (obj_bsssec(abfd)->user_set_vma && (obj_bsssec(abfd)->vma > BFD_ALIGN (obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size, adata(abfd).page_size))) { /* Can't play with squeezing into data pages; fix this code. */ abort (); } if (!obj_bsssec(abfd)->user_set_vma) obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size); if (data_pad > obj_bsssec(abfd)->_raw_size) execp->a_bss = 0; else execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad; } break; case n_magic: { file_ptr pos = adata(abfd).exec_bytes_size; bfd_vma vma = 0; int pad; 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; 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; if (!obj_bsssec(abfd)->user_set_vma)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -