aboutsummaryrefslogtreecommitdiff
path: root/bfd/aoutx.h
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus>1992-06-16 12:04:03 +0000
committerKen Raeburn <raeburn@cygnus>1992-06-16 12:04:03 +0000
commitce07dd7c0cc9034fd9aac351d34a99b1452c0203 (patch)
tree1178d85f82390429d19d2f3b233b3bdf72e5b32e /bfd/aoutx.h
parent41729eb4b085f5e524678a9c0b4d4a6516ad4e6a (diff)
downloadgdb-ce07dd7c0cc9034fd9aac351d34a99b1452c0203.zip
gdb-ce07dd7c0cc9034fd9aac351d34a99b1452c0203.tar.gz
gdb-ce07dd7c0cc9034fd9aac351d34a99b1452c0203.tar.bz2
[time to file a PR on cvs...]
Various changes to get linker working again for a.out: * don't set/adjust section file positions or vmas more than once * use correct page size and segment size when calculating them * deal with some variations in a.out implementations Tested on sun4 and sun4->sun3 so far, will be testing further but needed to get wider exposure&testing. See ChangeLog for details. Also: * coffcode.h (coff_write_relocs): Write out swapped reloc, not pre-swapped version. * hosts/sparc.h (abort, exit): Hide these names if compiling with gcc version 2, to avoid warnings.
Diffstat (limited to 'bfd/aoutx.h')
-rw-r--r--bfd/aoutx.h361
1 files changed, 289 insertions, 72 deletions
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index a97cd58..71b56e8 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -1,3 +1,4 @@
+#define BFD_AOUT_DEBUG
/* BFD semi-generic back-end for a.out binaries
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -108,6 +109,15 @@ DESCRIPTION
*/
+/* 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
@@ -122,7 +132,7 @@ struct external_exec;
#include "aout/stab_gnu.h"
#include "aout/ar.h"
-void (*bfd_error_trap)();
+extern void (*bfd_error_trap)();
/*
SUBSECTION
@@ -140,8 +150,10 @@ DESCRIPTION
*/
#define CTOR_TABLE_RELOC_IDX 2
+#define howto_table_ext NAME(aout,ext_howto_table)
+#define howto_table_std NAME(aout,std_howto_table)
-static reloc_howto_type howto_table_ext[] =
+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),
@@ -172,7 +184,7 @@ static reloc_howto_type howto_table_ext[] =
/* Convert standard reloc records to "arelent" format (incl byte swap). */
-static reloc_howto_type howto_table_std[] = {
+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),
@@ -185,7 +197,7 @@ HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedfac
};
-bfd_error_vector_type bfd_error_vector;
+extern bfd_error_vector_type bfd_error_vector;
/*
SUBSECTION
@@ -318,8 +330,18 @@ DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
if (execp->a_syms)
abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
- if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
- if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
+ 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;
@@ -569,13 +591,248 @@ DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
enum bfd_architecture arch AND
unsigned long machine)
{
+ bfd_arch_info_type *ainfo;
+
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 */
+
+ BFD_ASSERT (&adata(abfd) != 0);
+ ainfo = bfd_get_arch_info (abfd);
+ if (ainfo->segment_size)
+ adata(abfd).segment_size = ainfo->segment_size;
+ if (ainfo->page_size)
+ adata(abfd).page_size = ainfo->page_size;
return true; /* We're easy ... */
}
+boolean
+DEFUN (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;
+
+ obj_textsec(abfd)->filepos = pos;
+ pos += obj_textsec(abfd)->_raw_size;
+ vma += obj_textsec(abfd)->_raw_size;
+ if (!obj_datasec(abfd)->user_set_vma)
+ {
+ /* ?? Does alignment in the file image really matter? */
+ pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
+ 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)
+ {
+ pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
+ 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)
+ 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:
+ {
+ CONST struct aout_backend_data *abdp;
+ 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)
+ obj_bsssec(abfd)->vma = vma;
+ else
+ vma = obj_bsssec(abfd)->vma;
+ }
+ 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);
+ 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
+}
+
/*
FUNCTION
aout_<size>new_section_hook
@@ -634,6 +891,7 @@ boolean
{
file_ptr text_end;
bfd_size_type text_size;
+
if (abfd->output_has_begun == false)
{ /* set by bfd.c handler */
switch (abfd->direction)
@@ -642,55 +900,14 @@ boolean
case no_direction:
bfd_error = invalid_operation;
return false;
-
+
+ case write_direction:
+ if (NAME(aout,adjust_sizes_and_vmas) (abfd,
+ &text_size,
+ &text_end) == false)
+ return false;
case both_direction:
break;
-
- case write_direction:
- if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
- {
- bfd_error = invalid_operation;
- return false;
- }
- 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. */
- if (!(abfd->flags & D_PAGED))
- { /* Not demand-paged. */
- obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
- }
- else if (obj_textsec(abfd)->vma % adata(abfd).page_size
- < adata(abfd).exec_bytes_size)
- { /* Old-style demand-paged. */
- obj_textsec(abfd)->filepos = adata(abfd).page_size;
- }
- else
- { /* Sunos-style demand-paged. */
- obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
- text_size += adata(abfd).exec_bytes_size;
- }
- text_end = obj_textsec(abfd)->_raw_size + obj_textsec(abfd)->filepos;
- if (abfd->flags & (D_PAGED|WP_TEXT))
- {
- bfd_size_type text_pad =
- BFD_ALIGN(text_size, adata(abfd).page_size)
- - text_size;
- text_end += text_pad;
- obj_textsec(abfd)->_raw_size += text_pad;
- }
- obj_datasec(abfd)->filepos = text_end;
- obj_datasec(abfd)->_raw_size =
- align_power(obj_datasec(abfd)->_raw_size,
- obj_datasec(abfd)->alignment_power);
}
}
@@ -1162,13 +1379,13 @@ DEFUN(NAME(aout,get_symtab),(abfd, location),
{
unsigned int counter = 0;
aout_symbol_type *symbase;
-
+
if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
-
+
for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
*(location++) = (asymbol *)( symbase++);
*location++ =0;
- return bfd_get_symcount(abfd);
+ return bfd_get_symcount (abfd);
}
@@ -1189,9 +1406,9 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
int r_baserel, r_jmptable, r_relative;
unsigned int r_addend;
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? */
/* r_baserel, r_jmptable, r_relative??? FIXME-soon */
@@ -1203,21 +1420,21 @@ DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
/* name was clobbered by aout_write_syms to be symbol index */
-if (output_section == &bfd_com_section
- || output_section == &bfd_abs_section
- || output_section == &bfd_und_section)
- {
- /* Fill in symbol */
- r_extern = 1;
- r_index = stoi((*(g->sym_ptr_ptr))->KEEPIT);
- }
+ if (output_section == &bfd_com_section
+ || output_section == &bfd_abs_section
+ || output_section == &bfd_und_section)
+ {
+ /* 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;
- }
-
+ {
+ /* 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;