/* BFD back-end for PDP-11 a.out binaries.
- Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2020 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#define ARCH_SIZE 16
#undef TARGET_IS_BIG_ENDIAN_P
-#define TARGET_PAGE_SIZE 1024
+#define TARGET_PAGE_SIZE 8192
#define SEGMENT__SIZE TARGET_PAGE_SIZE
#define DEFAULT_ARCH bfd_arch_pdp11
-#define DEFAULT_MID M_PDP11
+#define DEFAULT_MID M_PDP11
/* Do not "beautify" the CONCAT* macro args. Traditional C will not
remove whitespace added here, and thus will fail to concatenate
#define N_HEADER_IN_TEXT(x) 0
/* There is no flags field. */
-#define N_FLAGS(exec) 0
+#define N_FLAGS(execp) 0
-#define N_SET_FLAGS(exec, flags) do { } while (0)
+#define N_SET_FLAGS(execp, flags) do { } while (0)
#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
&& N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC)
#include "sysdep.h"
+#include <limits.h>
#include "bfd.h"
#define external_exec pdp11_external_exec
bfd_byte e_entry[2]; /* Start address. */
bfd_byte e_unused[2]; /* Not used. */
bfd_byte e_flag[2]; /* Relocation info stripped. */
- bfd_byte e_relocatable; /* Ugly hack. */
+ bfd_byte e_relocatable; /* Ugly hack. */
};
#define EXEC_BYTES_SIZE (8 * 2)
#define EXTERNAL_NLIST_SIZE 8
#define N_TXTOFF(x) (EXEC_BYTES_SIZE)
-#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
-#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
-#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
-#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
-#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
+#define N_DATOFF(x) (N_TXTOFF(x) + (x)->a_text)
+#define N_TRELOFF(x) (N_DATOFF(x) + (x)->a_data)
+#define N_DRELOFF(x) (N_TRELOFF(x) + (x)->a_trsize)
+#define N_SYMOFF(x) (N_DRELOFF(x) + (x)->a_drsize)
+#define N_STROFF(x) (N_SYMOFF(x) + (x)->a_syms)
#define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
reloc_howto_type howto_table_pdp11[] =
{
- /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
+ /* type rs size bsz pcrel bitpos ovrf sf name part_inpl readmask setmask pcdone */
HOWTO( 0, 0, 1, 16, FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
HOWTO( 1, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
};
#define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
-static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, bfd_boolean *);
-static bfd_boolean aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
-static bfd_boolean aout_link_add_symbols (bfd *, struct bfd_link_info *);
-static bfd_boolean aout_link_write_symbols (struct aout_final_link_info *, bfd *);
+static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, const char *, bfd_boolean *);
+static bfd_boolean aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean aout_link_add_symbols (bfd *, struct bfd_link_info *);
+static bfd_boolean aout_link_write_symbols (struct aout_final_link_info *, bfd *);
reloc_howto_type *
pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp)
{
struct external_exec exec_bytes;
- bfd_size_type text_size;
- file_ptr text_end;
if (adata(abfd).magic == undecided_magic)
- NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
+ NAME (aout, adjust_sizes_and_vmas) (abfd);
execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
execp->a_entry = bfd_get_start_address (abfd);
if (bfd_get_outsymbols (abfd) != NULL
&& bfd_get_symcount (abfd) != 0)
{
- if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)
+ if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (execp)), SEEK_SET) != 0)
return FALSE;
if (! NAME (aout, write_syms) (abfd))
if (obj_textsec (abfd)->reloc_count > 0
|| obj_datasec (abfd)->reloc_count > 0)
{
- if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0
+ if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (execp)), SEEK_SET) != 0
|| !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
- || bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0
- || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
+ || bfd_seek (abfd, (file_ptr) (N_DRELOFF (execp)), SEEK_SET) != 0
+ || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
return FALSE;
}
will normally have been done by set_section_contents, but only if
there actually are some section contents. */
if (! abfd->output_has_begun)
- {
- bfd_size_type text_size;
- file_ptr text_end;
-
- NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
- }
+ NAME (aout, adjust_sizes_and_vmas) (abfd);
obj_reloc_entry_size (abfd) = RELOC_SIZE;
{
struct aout_data_struct *rawptr, *oldrawptr;
const bfd_target *result;
- bfd_size_type amt = sizeof (struct aout_data_struct);
+ size_t amt = sizeof (struct aout_data_struct);
rawptr = bfd_zalloc (abfd, amt);
if (rawptr == NULL)
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. */
+ /* Copy the contents of the old tdata struct. */
if (oldrawptr != NULL)
*abfd->tdata.aout_data = *oldrawptr;
/* 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))
+ if (N_DYNAMIC (execp))
abfd->flags |= DYNAMIC;
- if (N_MAGIC (*execp) == ZMAGIC)
+ if (N_MAGIC (execp) == ZMAGIC)
{
abfd->flags |= D_PAGED | WP_TEXT;
adata (abfd).magic = z_magic;
}
- else if (N_MAGIC (*execp) == NMAGIC)
+ else if (N_MAGIC (execp) == NMAGIC)
{
abfd->flags |= WP_TEXT;
adata (abfd).magic = n_magic;
}
- else if (N_MAGIC (*execp) == OMAGIC)
+ else if (N_MAGIC (execp) == OMAGIC)
adata (abfd).magic = o_magic;
else
{
abort ();
}
- bfd_get_start_address (abfd) = execp->a_entry;
+ abfd->start_address = execp->a_entry;
obj_aout_symbols (abfd) = NULL;
- bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
+ abfd->symcount = execp->a_syms / sizeof (struct external_nlist);
/* The default relocation entry size is that of traditional V7 Unix. */
obj_reloc_entry_size (abfd) = RELOC_SIZE;
in by the callback: */
struct exec *execp = exec_hdr (abfd);
- obj_textsec (abfd)->size = N_TXTSIZE(*execp);
+ obj_textsec (abfd)->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);
+ 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);
+ 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);
+ 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);
+ obj_str_filepos (abfd) = N_STROFF (execp);
+ obj_sym_filepos (abfd) = N_SYMOFF (execp);
/* Determine the architecture and machine type of the object file. */
abfd->obj_arch = bfd_arch_obscure;
struct stat stat_buf;
/* 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. */
+ 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. */
if (abfd->iostream != NULL
&& (abfd->flags & BFD_IN_MEMORY) == 0
&& (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
NAME (aout, mkobject) (bfd *abfd)
{
struct aout_data_struct *rawptr;
- bfd_size_type amt = sizeof (struct aout_data_struct);
+ size_t amt = sizeof (struct aout_data_struct);
bfd_set_error (bfd_error_system_call);
arch_flags = M_SPARCLET;
break;
- case bfd_arch_m68k:
- switch (machine)
- {
- case 0: arch_flags = M_68010; break;
- case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = FALSE; break;
- case bfd_mach_m68010: arch_flags = M_68010; break;
- case bfd_mach_m68020: arch_flags = M_68020; break;
- default: arch_flags = M_UNKNOWN; break;
- }
- break;
-
case bfd_arch_i386:
if (machine == 0
|| machine == bfd_mach_i386_i386
case 0:
case 2000:
case bfd_mach_mips3000:
- arch_flags = M_MIPS1;
+ arch_flags = M_MIPS1;
break;
case bfd_mach_mips4000: /* MIPS3 */
case bfd_mach_mips4400:
case bfd_mach_mips8000: /* MIPS4 */
case bfd_mach_mips6000: /* Real MIPS2: */
- arch_flags = M_MIPS2;
+ arch_flags = M_MIPS2;
break;
default:
arch_flags = M_UNKNOWN;
case bfd_arch_ns32k:
switch (machine)
{
- case 0: arch_flags = M_NS32532; break;
+ 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;
file_ptr pos = adata (abfd).exec_bytes_size;
bfd_vma vma = 0;
int pad = 0;
+ asection *text = obj_textsec (abfd);
+ asection *data = obj_datasec (abfd);
+ asection *bss = obj_bsssec (abfd);
/* Text. */
- obj_textsec (abfd)->filepos = pos;
- if (! obj_textsec (abfd)->user_set_vma)
- obj_textsec (abfd)->vma = vma;
+ text->filepos = pos;
+ if (!text->user_set_vma)
+ text->vma = vma;
else
- vma = obj_textsec (abfd)->vma;
+ vma = text->vma;
- pos += obj_textsec (abfd)->size;
- vma += obj_textsec (abfd)->size;
+ pos += execp->a_text;
+ vma += execp->a_text;
/* Data. */
- if (!obj_datasec (abfd)->user_set_vma)
+ if (!data->user_set_vma)
{
- obj_textsec (abfd)->size += pad;
pos += pad;
vma += pad;
- obj_datasec (abfd)->vma = vma;
+ data->vma = vma;
}
else
- vma = obj_datasec (abfd)->vma;
- obj_datasec (abfd)->filepos = pos;
- pos += obj_datasec (abfd)->size;
- vma += obj_datasec (abfd)->size;
+ vma = data->vma;
+ execp->a_text += pad;
+
+ data->filepos = pos;
+ pos += data->size;
+ vma += data->size;
/* BSS. */
- if (! obj_bsssec (abfd)->user_set_vma)
+ if (!bss->user_set_vma)
{
- obj_datasec (abfd)->size += pad;
pos += pad;
vma += pad;
- obj_bsssec (abfd)->vma = vma;
+ bss->vma = vma;
}
else
{
/* The VMA of the .bss section is set by the VMA of the
- .data section plus the size of the .data section. We may
- need to add padding bytes to make this true. */
- pad = obj_bsssec (abfd)->vma - vma;
- if (pad > 0)
- {
- obj_datasec (abfd)->size += pad;
- pos += pad;
- }
+ .data section plus the size of the .data section. We may
+ need to add padding bytes to make this true. */
+ pad = bss->vma - vma;
+ if (pad < 0)
+ pad = 0;
+ pos += pad;
}
- obj_bsssec (abfd)->filepos = pos;
+ execp->a_data = data->size + pad;
+ bss->filepos = pos;
+ execp->a_bss = bss->size;
- /* Fix up the exec header. */
- execp->a_text = obj_textsec (abfd)->size;
- execp->a_data = obj_datasec (abfd)->size;
- execp->a_bss = obj_bsssec (abfd)->size;
- N_SET_MAGIC (*execp, OMAGIC);
+ N_SET_MAGIC (execp, OMAGIC);
}
static void
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. */
+ /* TRUE if text includes exec header. */
+ bfd_boolean ztih;
+ asection *text = obj_textsec (abfd);
+ asection *data = obj_datasec (abfd);
+ asection *bss = obj_bsssec (abfd);
abdp = aout_backend_info (abfd);
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)
+ text->filepos = (ztih
+ ? adata (abfd).exec_bytes_size
+ : adata (abfd).zmagic_disk_block_size);
+ if (!text->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));
+ text->vma = ((abfd->flags & HAS_RELOC)
+ ? 0
+ : (ztih
+ ? abdp->default_text_vma + adata (abfd).exec_bytes_size
+ : abdp->default_text_vma));
text_pad = 0;
}
else
{
/* The .text section is being loaded at an unusual address. We
- may need to pad it such that the .data section starts at a page
- boundary. */
+ may need to pad it such that the .data section starts at a page
+ boundary. */
if (ztih)
- text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
+ text_pad = ((text->filepos - text->vma)
& (adata (abfd).page_size - 1));
else
- text_pad = ((- obj_textsec (abfd)->vma)
+ text_pad = (-text->vma
& (adata (abfd).page_size - 1));
}
/* Find start of data. */
if (ztih)
{
- text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
+ text_end = text->filepos + execp->a_text;
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)->size;
+ text_end = execp->a_text;
text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
- text_end += obj_textsec (abfd)->filepos;
+ text_end += text->filepos;
}
-
- obj_textsec (abfd)->size += text_pad;
- text_end += text_pad;
+ execp->a_text += text_pad;
/* Data. */
- if (!obj_datasec(abfd)->user_set_vma)
+ if (!data->user_set_vma)
{
bfd_vma vma;
- vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->size;
- obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
+ vma = text->vma + execp->a_text;
+ data->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)->size);
- obj_textsec(abfd)->size += text_pad;
+ text_pad = data->vma - (text->vma + execp->a_text);
+ /* Only pad the text section if the data
+ section is going to be placed after it. */
+ if (text_pad > 0)
+ execp->a_text += text_pad;
}
- obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
- + obj_textsec (abfd)->size);
+ data->filepos = text->filepos + execp->a_text;
/* Fix up exec header while we're at it. */
- execp->a_text = obj_textsec(abfd)->size;
if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
- execp->a_text += adata(abfd).exec_bytes_size;
- N_SET_MAGIC (*execp, ZMAGIC);
+ execp->a_text += adata (abfd).exec_bytes_size;
+ N_SET_MAGIC (execp, ZMAGIC);
/* Spec says data section should be rounded up to page boundary. */
- obj_datasec(abfd)->size
- = align_power (obj_datasec(abfd)->size,
- obj_bsssec(abfd)->alignment_power);
- execp->a_data = BFD_ALIGN (obj_datasec(abfd)->size,
- adata(abfd).page_size);
- data_pad = execp->a_data - obj_datasec(abfd)->size;
+ execp->a_data = align_power (data->size, bss->alignment_power);
+ execp->a_data = BFD_ALIGN (execp->a_data, adata (abfd).page_size);
+ data_pad = execp->a_data - data->size;
/* BSS. */
- if (!obj_bsssec(abfd)->user_set_vma)
- obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
- + obj_datasec(abfd)->size);
+ if (!bss->user_set_vma)
+ bss->vma = data->vma + execp->a_data;
/* 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
(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)->size)
- execp->a_bss = (data_pad > obj_bsssec(abfd)->size) ? 0 :
- obj_bsssec(abfd)->size - data_pad;
+ if (align_power (bss->vma, bss->alignment_power) == data->vma + execp->a_data)
+ execp->a_bss = data_pad > bss->size ? 0 : bss->size - data_pad;
else
- execp->a_bss = obj_bsssec(abfd)->size;
+ execp->a_bss = bss->size;
}
static void
adjust_n_magic (bfd *abfd, struct internal_exec *execp)
{
- file_ptr pos = adata(abfd).exec_bytes_size;
+ file_ptr pos = adata (abfd).exec_bytes_size;
bfd_vma vma = 0;
int pad;
+ asection *text = obj_textsec (abfd);
+ asection *data = obj_datasec (abfd);
+ asection *bss = obj_bsssec (abfd);
/* Text. */
- obj_textsec(abfd)->filepos = pos;
- if (!obj_textsec(abfd)->user_set_vma)
- obj_textsec(abfd)->vma = vma;
+ text->filepos = pos;
+ if (!text->user_set_vma)
+ text->vma = vma;
else
- vma = obj_textsec(abfd)->vma;
- pos += obj_textsec(abfd)->size;
- vma += obj_textsec(abfd)->size;
+ vma = text->vma;
+ pos += execp->a_text;
+ vma += execp->a_text;
/* 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;
+ data->filepos = pos;
+ if (!data->user_set_vma)
+ data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
+ vma = data->vma;
/* Since BSS follows data immediately, see if it needs alignment. */
- vma += obj_datasec(abfd)->size;
- pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
- obj_datasec(abfd)->size += pad;
- pos += obj_datasec(abfd)->size;
+ vma += data->size;
+ pad = align_power (vma, bss->alignment_power) - vma;
+ execp->a_data = data->size + pad;
+ pos += execp->a_data;
/* BSS. */
- if (!obj_bsssec(abfd)->user_set_vma)
- obj_bsssec(abfd)->vma = vma;
+ if (!bss->user_set_vma)
+ bss->vma = vma;
else
- vma = obj_bsssec(abfd)->vma;
+ vma = bss->vma;
/* Fix up exec header. */
- execp->a_text = obj_textsec(abfd)->size;
- execp->a_data = obj_datasec(abfd)->size;
- execp->a_bss = obj_bsssec(abfd)->size;
- N_SET_MAGIC (*execp, NMAGIC);
+ execp->a_bss = bss->size;
+ N_SET_MAGIC (execp, NMAGIC);
}
bfd_boolean
-NAME (aout, adjust_sizes_and_vmas) (bfd *abfd,
- bfd_size_type *text_size,
- file_ptr * text_end ATTRIBUTE_UNUSED)
+NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
{
struct internal_exec *execp = exec_hdr (abfd);
if (! NAME (aout, make_sections) (abfd))
return FALSE;
- if (adata(abfd).magic != undecided_magic)
+ if (adata (abfd).magic != undecided_magic)
return TRUE;
- obj_textsec(abfd)->size =
- align_power(obj_textsec(abfd)->size,
- obj_textsec(abfd)->alignment_power);
+ execp->a_text = align_power (obj_textsec (abfd)->size,
+ obj_textsec (abfd)->alignment_power);
- *text_size = obj_textsec (abfd)->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
(TARGET_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. */
+ 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
minute. */
if (abfd->flags & WP_TEXT)
- adata(abfd).magic = n_magic;
+ adata (abfd).magic = n_magic;
else
- adata(abfd).magic = o_magic;
+ 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 ();
- }
+ 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)->size,
- obj_textsec(abfd)->alignment_power,
- obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
- obj_datasec(abfd)->alignment_power,
- obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size,
- obj_bsssec(abfd)->alignment_power);
+ obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
+ obj_textsec (abfd)->alignment_power,
+ obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
+ obj_datasec (abfd)->alignment_power,
+ obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size,
+ obj_bsssec (abfd)->alignment_power);
#endif
#endif
- switch (adata(abfd).magic)
+ switch (adata (abfd).magic)
{
case o_magic:
adjust_o_magic (abfd, execp);
#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)->size,
- obj_textsec(abfd)->filepos,
- obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
- obj_datasec(abfd)->filepos,
- obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size);
+ obj_textsec (abfd)->vma, execp->a_text,
+ obj_textsec (abfd)->filepos,
+ obj_datasec (abfd)->vma, execp->a_data,
+ obj_datasec (abfd)->filepos,
+ obj_bsssec (abfd)->vma, execp->a_bss);
#endif
return TRUE;
file_ptr offset,
bfd_size_type count)
{
- file_ptr text_end;
- bfd_size_type text_size;
-
if (! abfd->output_has_begun)
{
- if (! NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end))
+ if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
return FALSE;
}
if (section != obj_textsec (abfd)
&& section != obj_datasec (abfd))
{
- (*_bfd_error_handler)
- ("%s: can not represent section `%s' in a.out object file format",
- bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: can not represent section `%pA' in a.out object file format"),
+ abfd, section);
bfd_set_error (bfd_error_nonrepresentable_section);
return FALSE;
}
count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
+ /* PR 17512: file: 011f5a08. */
+ if (count == 0)
+ {
+ obj_aout_external_syms (abfd) = NULL;
+ obj_aout_external_sym_count (abfd) = count;
+ return TRUE;
+ }
+
#ifdef USE_MMAP
if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
exec_hdr (abfd)->a_syms,
/* We allocate using malloc to make the values easy to free
later on. If we put them on the objalloc it might not be
possible to free them. */
- syms = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
+ if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
+ return FALSE;
+ syms = (struct external_nlist *)
+ _bfd_malloc_and_read (abfd, count * EXTERNAL_NLIST_SIZE,
+ count * EXTERNAL_NLIST_SIZE);
if (syms == NULL && count != 0)
return FALSE;
-
- if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
- || (bfd_bread (syms, exec_hdr (abfd)->a_syms, abfd)
- != exec_hdr (abfd)->a_syms))
- {
- free (syms);
- return FALSE;
- }
#endif
obj_aout_external_syms (abfd) = syms;
to another. */
sym_pointer->e_type[0] &= ~N_TYPE;
- sec = bfd_get_section (cache_ptr);
+ sec = bfd_asymbol_section (cache_ptr);
off = 0;
if (sec == NULL)
{
/* This case occurs, e.g., for the *DEBUG* section of a COFF
file. */
- (*_bfd_error_handler)
- ("%B: can not represent section for symbol `%s' in a.out object file format",
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: can not represent section for symbol `%s' in a.out object file format"),
abfd, cache_ptr->name != NULL ? cache_ptr->name : "*unknown*");
bfd_set_error (bfd_error_nonrepresentable_section);
return FALSE;
sym_pointer->e_type[0] = N_UNDF | N_EXT;
else
{
- (*_bfd_error_handler)
- ("%B: can not represent section `%A' in a.out object file format",
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: can not represent section `%pA' in a.out object file format"),
abfd, sec);
bfd_set_error (bfd_error_nonrepresentable_section);
return FALSE;
asymbol *
NAME (aout, make_empty_symbol) (bfd *abfd)
{
- bfd_size_type amt = sizeof (aout_symbol_type);
+ size_t amt = sizeof (aout_symbol_type);
aout_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
if (!new_symbol_type)
return FALSE;
}
- bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
+ abfd->symcount = obj_aout_external_sym_count (abfd);
obj_aout_symbols (abfd) = cached;
bfd_boolean copy)
{
bfd_boolean hash;
- bfd_size_type index;
+ bfd_size_type str_index;
/* An index of 0 always means the empty string. */
if (str == 0 || *str == '\0')
if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
hash = FALSE;
- index = _bfd_stringtab_add (tab, str, hash, copy);
+ str_index = _bfd_stringtab_add (tab, str, hash, copy);
- if (index != (bfd_size_type) -1)
+ if (str_index != (bfd_size_type) -1)
/* Add BYTES_IN_LONG to the return value to account for the
space taken up by the string table size. */
- index += BYTES_IN_LONG;
+ str_index += BYTES_IN_LONG;
- return index;
+ return str_index;
}
/* Write out a strtab. ABFD is already at the right location in the
return TRUE;
-error_return:
+ error_return:
_bfd_stringtab_free (strtab);
return FALSE;
}
to give the true offset from the section */
-#define MOVE_ADDRESS(ad) \
- if (r_extern) \
+#define MOVE_ADDRESS(ad) \
+ if (r_extern) \
{ \
/* Undefined symbol. */ \
cache_ptr->sym_ptr_ptr = symbols + r_index; \
} \
else \
{ \
- /* Defined, section relative. replace symbol with pointer to \
+ /* Defined, section relative. replace symbol with pointer to \
symbol which points to section. */ \
switch (r_index) \
{ \
}
static void
-pdp11_aout_swap_reloc_in (bfd * abfd,
- bfd_byte * bytes,
- arelent * cache_ptr,
- bfd_size_type offset,
- asymbol ** symbols,
- bfd_size_type symcount)
+pdp11_aout_swap_reloc_in (bfd * abfd,
+ bfd_byte * bytes,
+ arelent * cache_ptr,
+ bfd_size_type offset,
+ asymbol ** symbols,
+ bfd_size_type symcount)
{
struct aoutdata *su = &(abfd->tdata.aout_data->a);
unsigned int r_index;
if (r_extern && r_index > symcount)
{
/* We could arrange to return an error, but it might be useful
- to see the file even if it is bad. */
+ to see the file even if it is bad. */
r_extern = 0;
r_index = N_ABS;
}
if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
return FALSE;
-
- each_size = obj_reloc_entry_size (abfd);
-
- relocs = bfd_malloc (reloc_size);
+ relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size);
if (relocs == NULL && reloc_size != 0)
return FALSE;
- if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
- {
- free (relocs);
- return FALSE;
- }
-
+ each_size = obj_reloc_entry_size (abfd);
count = reloc_size / each_size;
/* Count the number of NON-ZERO relocs, this is the count we want. */
long
NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
{
+ bfd_size_type count;
+
if (bfd_get_format (abfd) != bfd_object)
{
bfd_set_error (bfd_error_invalid_operation);
}
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));
-
- /* TODO: why are there two if statements for obj_bsssec()? */
-
- if (asect == obj_bsssec (abfd))
- return sizeof (arelent *);
-
- if (asect == obj_bsssec (abfd))
- return 0;
+ count = asect->reloc_count;
+ else if (asect == obj_datasec (abfd))
+ count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
+ else if (asect == obj_textsec (abfd))
+ count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
+ else if (asect == obj_bsssec (abfd))
+ count = 0;
+ else
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return -1;
+ }
- bfd_set_error (bfd_error_invalid_operation);
- return -1;
+ if (count >= LONG_MAX / sizeof (arelent *))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return -1;
+ }
+ return (count + 1) * sizeof (arelent *);
}
\f
bfd_boolean
NAME (aout, find_nearest_line) (bfd *abfd,
- asection *section,
asymbol **symbols,
+ asection *section,
bfd_vma offset,
const char **filename_ptr,
const char **functionname_ptr,
- unsigned int *line_ptr)
+ unsigned int *line_ptr,
+ unsigned int *discriminator_ptr)
{
/* Run down the file looking for the filename, function and linenumber. */
asymbol **p;
*filename_ptr = abfd->filename;
*functionname_ptr = 0;
*line_ptr = 0;
+ if (discriminator_ptr)
+ *discriminator_ptr = 0;
if (symbols != NULL)
{
NAME (aout, link_hash_table_create) (bfd *abfd)
{
struct aout_link_hash_table *ret;
- bfd_size_type amt = sizeof (struct aout_link_hash_table);
+ size_t amt = sizeof (struct aout_link_hash_table);
- ret = bfd_alloc (abfd, amt);
+ ret = bfd_malloc (amt);
if (ret == NULL)
return NULL;
if (! NAME (aout, link_hash_table_init) (ret, abfd,
static bfd_boolean
aout_link_check_ar_symbols (bfd *abfd,
struct bfd_link_info *info,
- bfd_boolean *pneeded)
+ bfd_boolean *pneeded,
+ bfd **subsbfd)
{
struct external_nlist *p;
struct external_nlist *pend;
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;
+ int a;
and this object file from the archive includes
- int a = 5;
+ 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
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;
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
+ continue;
*pneeded = TRUE;
return TRUE;
}
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))
+ if (!(*info->callbacks
+ ->add_archive_element) (info, abfd, name, subsbfd))
return FALSE;
*pneeded = TRUE;
return TRUE;
static bfd_boolean
aout_link_check_archive_element (bfd *abfd,
struct bfd_link_info *info,
+ struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED,
bfd_boolean *pneeded)
{
- if (! aout_get_external_symbols (abfd))
+ bfd *oldbfd;
+ bfd_boolean needed;
+
+ if (!aout_get_external_symbols (abfd))
return FALSE;
- if (! aout_link_check_ar_symbols (abfd, info, pneeded))
+ oldbfd = abfd;
+ if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
return FALSE;
- if (*pneeded)
+ needed = *pneeded;
+ if (needed)
{
- if (! aout_link_add_symbols (abfd, info))
+ /* Potentially, the add_archive_element hook may have set a
+ substitute BFD for us. */
+ if (abfd != oldbfd)
+ {
+ if (!info->keep_memory
+ && !aout_link_free_symbols (oldbfd))
+ return FALSE;
+ if (!aout_get_external_symbols (abfd))
+ return FALSE;
+ }
+ if (!aout_link_add_symbols (abfd, info))
return FALSE;
}
- if (! info->keep_memory || ! *pneeded)
+ if (!info->keep_memory || !needed)
{
- if (! aout_link_free_symbols (abfd))
+ if (!aout_link_free_symbols (abfd))
return FALSE;
}
switch (type)
{
default:
- abort ();
+ /* Anything else should be a debugging symbol. */
+ BFD_ASSERT ((type & N_STAB) != 0);
+ continue;
case N_UNDF:
case N_ABS:
break;
case N_TEXT | N_EXT:
section = obj_textsec (abfd);
- value -= bfd_get_section_vma (abfd, section);
+ value -= bfd_section_vma (section);
break;
case N_DATA | 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);
+ value -= bfd_section_vma (section);
break;
case N_BSS | N_EXT:
section = obj_bsssec (abfd);
- value -= bfd_get_section_vma (abfd, section);
+ value -= bfd_section_vma (section);
break;
}
}
static bfd_boolean
-aout_link_write_other_symbol (struct aout_link_hash_entry *h, void * data)
+aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
{
- struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
+ struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
+ struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
bfd *output_bfd;
int type;
bfd_vma val;
struct external_nlist outsym;
bfd_size_type indx;
- bfd_size_type amt;
+ size_t amt;
if (h->root.type == bfd_link_hash_warning)
{
return TRUE;
}
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->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)))
+ (output_bfd, flaginfo->info, h)))
{
/* FIXME: No way to handle errors. */
abort ();
/* An indx of -2 means the symbol must be written. */
if (h->indx != -2
- && (finfo->info->strip == strip_all
- || (finfo->info->strip == strip_some
- && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
+ && (flaginfo->info->strip == strip_all
+ || (flaginfo->info->strip == strip_some
+ && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
FALSE, FALSE) == NULL)))
return TRUE;
return TRUE;
case bfd_link_hash_new:
/* This can happen for set symbols when sets are not being
- built. */
+ built. */
return TRUE;
case bfd_link_hash_undefined:
type = N_UNDF | N_EXT;
case bfd_link_hash_undefweak:
type = N_WEAKU;
val = 0;
+ /* Fall through. */
case bfd_link_hash_indirect:
case bfd_link_hash_warning:
/* FIXME: Ignore these for now. The circumstances under which
}
H_PUT_8 (output_bfd, type, outsym.e_type);
- indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
+ indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
FALSE);
if (indx == (bfd_size_type) -1)
/* FIXME: No way to handle errors. */
PUT_WORD (output_bfd, val, outsym.e_value);
amt = EXTERNAL_NLIST_SIZE;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
|| bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
/* FIXME: No way to handle errors. */
abort ();
- finfo->symoff += amt;
+ flaginfo->symoff += amt;
h->indx = obj_aout_external_sym_count (output_bfd);
++obj_aout_external_sym_count (output_bfd);
/* Handle a link order which is supposed to generate a reloc. */
static bfd_boolean
-aout_link_reloc_link_order (struct aout_final_link_info *finfo,
+aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
asection *o,
struct bfd_link_order *p)
{
r_index = N_ABS | N_EXT;
else
{
- BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
+ BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
r_index = pr->u.section->target_index;
}
}
BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
r_extern = 1;
h = ((struct aout_link_hash_entry *)
- bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
+ bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
pr->u.name, FALSE, FALSE, TRUE));
if (h != NULL
&& h->indx >= 0)
symbol. */
h->indx = -2;
h->written = FALSE;
- if (! aout_link_write_other_symbol (h, (void *) finfo))
+ if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
return FALSE;
r_index = h->indx;
}
else
{
- if (! ((*finfo->info->callbacks->unattached_reloc)
- (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
- return FALSE;
+ (*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0);
r_index = 0;
}
}
- howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
+ howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
if (howto == 0)
{
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;
+ if (o == obj_textsec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->treloff;
+ else if (o == obj_datasec (flaginfo->output_bfd))
+ reloff_ptr = &flaginfo->dreloff;
else
abort ();
#ifdef MY_put_reloc
- MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
+ MY_put_reloc(flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
&srel);
#else
{
r_relative = (howto->type & 32) != 0;
r_length = howto->size;
- PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
- if (bfd_header_big_endian (finfo->output_bfd))
+ PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
+ if (bfd_header_big_endian (flaginfo->output_bfd))
{
srel.r_index[0] = r_index >> 16;
srel.r_index[1] = r_index >> 8;
size = bfd_get_reloc_size (howto);
buf = bfd_zmalloc (size);
- if (buf == NULL)
+ if (buf == NULL && size != 0)
return FALSE;
- r = MY_relocate_contents (howto, finfo->output_bfd,
+ r = MY_relocate_contents (howto, flaginfo->output_bfd,
pr->addend, buf);
switch (r)
{
case bfd_reloc_outofrange:
abort ();
case bfd_reloc_overflow:
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, NULL,
- (p->type == bfd_section_reloc_link_order
- ? bfd_section_name (finfo->output_bfd,
- pr->u.section)
- : pr->u.name),
- howto->name, pr->addend, NULL,
- (asection *) NULL, (bfd_vma) 0)))
- {
- free (buf);
- return FALSE;
- }
+ (*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, NULL,
+ (p->type == bfd_section_reloc_link_order
+ ? bfd_section_name (pr->u.section)
+ : pr->u.name),
+ howto->name, pr->addend, NULL,
+ (asection *) NULL, (bfd_vma) 0);
break;
}
- ok = bfd_set_section_contents (finfo->output_bfd, o,
+ ok = bfd_set_section_contents (flaginfo->output_bfd, o,
(void *) buf,
(file_ptr) p->offset,
size);
return FALSE;
}
- rel_size = obj_reloc_entry_size (finfo->output_bfd);
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
- || bfd_bwrite (rel_ptr, rel_size, finfo->output_bfd) != rel_size)
+ rel_size = obj_reloc_entry_size (flaginfo->output_bfd);
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
+ || bfd_bwrite (rel_ptr, rel_size, flaginfo->output_bfd) != rel_size)
return FALSE;
*reloff_ptr += rel_size;
/* 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
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
return TRUE;
}
}
static bfd_boolean
-pdp11_aout_link_input_section (struct aout_final_link_info *finfo,
+pdp11_aout_link_input_section (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
bfd_byte *relocs,
char *strings;
struct aout_link_hash_entry **sym_hashes;
int *symbol_map;
- bfd_size_type reloc_count;
bfd_byte *rel;
bfd_byte *rel_end;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->output_bfd;
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
BFD_ASSERT (input_bfd->xvec->header_byteorder
== output_bfd->xvec->header_byteorder);
- relocatable = finfo->info->relocatable;
+ relocatable = bfd_link_relocatable (flaginfo->info);
syms = obj_aout_external_syms (input_bfd);
strings = obj_aout_external_strings (input_bfd);
sym_hashes = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
- reloc_count = rel_size / RELOC_SIZE;
rel = relocs;
rel_end = rel + rel_size;
for (; rel < rel_end; rel += RELOC_SIZE)
if (h != NULL)
{
/* We decided to strip this symbol, but it
- turns out that we can't. Note that we
- lose the other and desc information here.
- I don't think that will ever matter for a
- global symbol. */
+ turns out that we can't. Note that we
+ lose the other and desc information here.
+ I don't think that will ever matter for a
+ global symbol. */
if (h->indx < 0)
{
h->indx = -2;
h->written = FALSE;
- if (! aout_link_write_other_symbol (h,
- (void *) finfo))
+ if (!aout_link_write_other_symbol (&h->root.root,
+ flaginfo))
return FALSE;
}
r_index = h->indx;
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;
+ (*flaginfo->info->callbacks->unattached_reloc)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr);
r_index = 0;
}
}
bfd_boolean skip;
if (! ((*check_dynamic_reloc)
- (finfo->info, input_bfd, input_section, h,
+ (flaginfo->info, input_bfd, input_section, h,
(void *) rel, contents, &skip, &relocation)))
return FALSE;
if (skip)
}
/* Now warn if a global symbol is undefined. We could not
- do this earlier, because check_dynamic_reloc might want
- to skip this reloc. */
- if (hundef && ! finfo->info->shared)
+ do this earlier, because check_dynamic_reloc might want
+ to skip this reloc. */
+ if (hundef && ! bfd_link_pic (flaginfo->info))
{
const char *name;
name = h->root.root.string;
else
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, TRUE)))
- return FALSE;
+ (*flaginfo->info->callbacks->undefined_symbol)
+ (flaginfo->info, name, input_bfd, input_section,
+ r_addr, TRUE);
}
r = MY_final_link_relocate (howto,
asection *s;
s = aout_reloc_type_to_section (input_bfd, r_type);
- name = bfd_section_name (input_bfd, s);
+ name = bfd_section_name (s);
}
- if (! ((*finfo->info->callbacks->reloc_overflow)
- (finfo->info, (h ? &h->root : NULL), name,
- howto->name, (bfd_vma) 0, input_bfd,
- input_section, r_addr)))
- return FALSE;
+ (*flaginfo->info->callbacks->reloc_overflow)
+ (flaginfo->info, (h ? &h->root : NULL), name, howto->name,
+ (bfd_vma) 0, input_bfd, input_section, r_addr);
}
break;
}
/* Link an a.out section into the output file. */
static bfd_boolean
-aout_link_input_section (struct aout_final_link_info *finfo,
+aout_link_input_section (struct aout_final_link_info *flaginfo,
bfd *input_bfd,
asection *input_section,
file_ptr *reloff_ptr,
/* Get the section contents. */
input_size = input_section->size;
if (! bfd_get_section_contents (input_bfd, input_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) 0, input_size))
return FALSE;
relocs = aout_section_data (input_section)->relocs;
else
{
- relocs = finfo->relocs;
+ relocs = flaginfo->relocs;
if (rel_size > 0)
{
if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
}
/* Relocate the section contents. */
- if (! pdp11_aout_link_input_section (finfo, input_bfd, input_section,
+ if (! pdp11_aout_link_input_section (flaginfo, input_bfd, input_section,
(bfd_byte *) relocs,
- rel_size, finfo->contents))
+ rel_size, flaginfo->contents))
return FALSE;
/* Write out the section contents. */
- if (! bfd_set_section_contents (finfo->output_bfd,
+ if (! bfd_set_section_contents (flaginfo->output_bfd,
input_section->output_section,
- (void *) finfo->contents,
+ (void *) flaginfo->contents,
(file_ptr) input_section->output_offset,
input_size))
return FALSE;
/* If we are producing relocatable output, the relocs were
modified, and we now write them out. */
- if (finfo->info->relocatable && rel_size > 0)
+ if (bfd_link_relocatable (flaginfo->info) && rel_size > 0)
{
- if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
+ if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
return FALSE;
- if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
+ if (bfd_bwrite (relocs, rel_size, flaginfo->output_bfd) != rel_size)
return FALSE;
*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
+ BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
+ && (reloff_ptr != &flaginfo->treloff
|| (*reloff_ptr
- <= obj_datasec (finfo->output_bfd)->rel_filepos)));
+ <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
}
return TRUE;
/* Link an a.out input BFD into the output file. */
static bfd_boolean
-aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
- bfd_size_type sym_count;
-
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));
+ (flaginfo->info, input_bfd));
/* Get the symbols. We probably have them already, unless
- finfo->info->keep_memory is FALSE. */
+ flaginfo->info->keep_memory is FALSE. */
if (! aout_get_external_symbols (input_bfd))
return FALSE;
- sym_count = obj_aout_external_sym_count (input_bfd);
-
/* Write out the symbols and get a map of the new indices. The map
- is placed into finfo->symbol_map. */
- if (! aout_link_write_symbols (finfo, input_bfd))
+ is placed into flaginfo->symbol_map. */
+ if (! aout_link_write_symbols (flaginfo, input_bfd))
return FALSE;
/* Relocate and write out the sections. These functions use the
link, which will normally be the case. */
if (obj_textsec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_textsec (input_bfd),
- &finfo->treloff,
+ &flaginfo->treloff,
exec_hdr (input_bfd)->a_trsize))
return FALSE;
}
if (obj_datasec (input_bfd)->linker_mark)
{
- if (! aout_link_input_section (finfo, input_bfd,
+ if (! aout_link_input_section (flaginfo, input_bfd,
obj_datasec (input_bfd),
- &finfo->dreloff,
+ &flaginfo->dreloff,
exec_hdr (input_bfd)->a_drsize))
return FALSE;
}
/* 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 (! flaginfo->info->keep_memory)
{
if (! aout_link_free_symbols (input_bfd))
return FALSE;
/* 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
+ 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. */
bfd_size_type max_contents_size;
bfd_size_type max_relocs_size;
bfd_size_type max_sym_count;
- bfd_size_type text_size;
- file_ptr text_end;
struct bfd_link_order *p;
asection *o;
bfd_boolean have_link_order_relocs;
- if (info->shared)
+ if (bfd_link_pic (info))
abfd->flags |= DYNAMIC;
aout_info.info = info;
max_contents_size = 0;
max_relocs_size = 0;
max_sym_count = 0;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
size_t sz;
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
{
and call get_reloc_upper_bound and canonicalize_reloc to
work out the number of relocs needed, and then multiply
by the reloc size. */
- (*_bfd_error_handler)
- ("%s: relocatable link from %s to %s not supported",
- bfd_get_filename (abfd),
- sub->xvec->name, abfd->xvec->name);
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%pB: relocatable link from %s to %s not supported"),
+ abfd, sub->xvec->name, abfd->xvec->name);
bfd_set_error (bfd_error_invalid_operation);
goto error_return;
}
}
}
- if (info->relocatable)
+ if (bfd_link_relocatable (info))
{
if (obj_textsec (abfd) != NULL)
trsize += (_bfd_count_link_order_relocs (obj_textsec (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))
+ if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
goto error_return;
/* The relocation and symbol file positions differ among a.out
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. */
+ can compute the relocation file positions. */
(*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
&aout_info.symoff);
obj_textsec (abfd)->rel_filepos = aout_info.treloff;
h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
FALSE, FALSE, FALSE);
if (h != NULL)
- aout_link_write_other_symbol (h, &aout_info);
+ aout_link_write_other_symbol (&h->root.root, &aout_info);
}
/* The most time efficient way to do the link would be to read all
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 != NULL; sub = sub->link_next)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
sub->output_has_begun = FALSE;
/* Mark all sections which are to be included in the link. This
}
/* Write out any symbols that we have not already written out. */
- aout_link_hash_traverse (aout_hash_table (info),
- aout_link_write_other_symbol,
- (void *) &aout_info);
+ bfd_hash_traverse (&info->hash->table,
+ aout_link_write_other_symbol,
+ &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
else if (obj_textsec (abfd)->reloc_count == 0
&& obj_datasec (abfd)->reloc_count == 0)
{
- bfd_byte b;
-
- b = 0;
- if (bfd_seek (abfd,
- (file_ptr) (obj_datasec (abfd)->filepos
- + exec_hdr (abfd)->a_data
- - 1),
- SEEK_SET) != 0
- || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
- goto error_return;
+ /* The layout of a typical a.out file is header, text, data,
+ relocs, symbols, string table. When there are no relocs,
+ symbols or string table, the last thing in the file is data
+ and a_data may be rounded up. However we may have a smaller
+ sized .data section and thus not written final padding. The
+ same thing can happen with text if there is no data. Write
+ final padding here to extend the file. */
+ file_ptr pos = 0;
+
+ if (exec_hdr (abfd)->a_data > obj_datasec (abfd)->size)
+ pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data;
+ else if (obj_datasec (abfd)->size == 0
+ && exec_hdr (abfd)->a_text > obj_textsec (abfd)->size)
+ pos = obj_textsec (abfd)->filepos + exec_hdr (abfd)->a_text;
+ if (pos != 0)
+ {
+ bfd_byte b = 0;
+
+ if (bfd_seek (abfd, pos - 1, SEEK_SET) != 0
+ || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
+ goto error_return;
+ }
}
return TRUE;
symbol indices into a symbol_map. */
static bfd_boolean
-aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
+aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
{
bfd *output_bfd;
bfd_size_type sym_count;
bfd_boolean pass;
bfd_boolean skip_next;
- output_bfd = finfo->output_bfd;
+ output_bfd = flaginfo->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;
- outsym = finfo->output_syms;
+ strip = flaginfo->info->strip;
+ discard = flaginfo->info->discard;
+ outsym = flaginfo->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,
+ || bfd_hash_lookup (flaginfo->info->keep_hash, input_bfd->filename,
FALSE, FALSE) != NULL)
&& discard != discard_all)
{
H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
input_bfd->filename, FALSE);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
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)
+ (bfd_section_vma (obj_textsec (input_bfd)->output_section)
+ obj_textsec (input_bfd)->output_offset),
outsym->e_value);
++obj_aout_external_sym_count (output_bfd);
sym = obj_aout_external_syms (input_bfd);
sym_end = sym + sym_count;
sym_hash = obj_aout_sym_hashes (input_bfd);
- symbol_map = finfo->symbol_map;
+ symbol_map = flaginfo->symbol_map;
memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
{
bfd_boolean copy;
/* We set *symbol_map to 0 above for all symbols. If it has
- already been set to -1 for this symbol, it means that we are
- discarding it because it appears in a duplicate header file.
- See the N_BINCL code below. */
+ already been set to -1 for this symbol, it means that we are
+ discarding it because it appears in a duplicate header file.
+ See the N_BINCL code below. */
if (*symbol_map == -1)
continue;
/* Initialize *symbol_map to -1, which means that the symbol was
- not copied into the output file. We will change it later if
- we do copy the symbol over. */
+ not copied into the output file. We will change it later if
+ we do copy the symbol over. */
*symbol_map = -1;
type = H_GET_8 (input_bfd, sym->e_type);
h = *sym_hash;
/* Use the name from the hash table, in case the symbol was
- wrapped. */
+ wrapped. */
if (h != NULL)
name = h->root.root.string;
skip = TRUE;
break;
case strip_some:
- if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
+ if (bfd_hash_lookup (flaginfo->info->keep_hash, name, FALSE, FALSE)
== NULL)
skip = TRUE;
break;
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)
+ + bfd_section_vma (output_section)
+ input_section->output_offset);
/* Get the correct type based on the section. If
}
/* If we have already included a header file with the
- same value, then replace this one with an N_EXCL
- symbol. */
- copy = ! finfo->info->keep_memory;
- incl_entry = aout_link_includes_lookup (&finfo->includes,
+ same value, then replace this one with an N_EXCL
+ symbol. */
+ copy = ! flaginfo->info->keep_memory;
+ incl_entry = aout_link_includes_lookup (&flaginfo->includes,
name, TRUE, copy);
if (incl_entry == NULL)
return FALSE;
if (t == NULL)
{
/* This is the first time we have seen this header
- file with this set of stabs strings. */
- t = bfd_hash_allocate (&finfo->includes.root,
+ file with this set of stabs strings. */
+ t = bfd_hash_allocate (&flaginfo->includes.root,
sizeof *t);
if (t == NULL)
return FALSE;
int *incl_map;
/* This is a duplicate header file. We must change
- it to be an N_EXCL entry, and mark all the
- included symbols to prevent outputting them. */
+ it to be an N_EXCL entry, and mark all the
+ included symbols to prevent outputting them. */
type = N_EXCL;
nest = 0;
write out. */
H_PUT_8 (output_bfd, type, outsym->e_type);
copy = FALSE;
- if (! finfo->info->keep_memory)
+ if (! flaginfo->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.
else
copy = TRUE;
}
- strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
+ strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
name, copy);
if (strtab_index == (bfd_size_type) -1)
return FALSE;
}
/* Write out the output symbols we have just constructed. */
- if (outsym > finfo->output_syms)
+ if (outsym > flaginfo->output_syms)
{
bfd_size_type size;
- if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
+ if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
return FALSE;
- size = outsym - finfo->output_syms;
+ size = outsym - flaginfo->output_syms;
size *= EXTERNAL_NLIST_SIZE;
- if (bfd_bwrite ((void *) finfo->output_syms, size, output_bfd) != size)
+ if (bfd_bwrite ((void *) flaginfo->output_syms, size, output_bfd) != size)
return FALSE;
- finfo->symoff += size;
+ flaginfo->symoff += size;
}
return TRUE;
MY_symbol_leading_char,
AR_PAD_CHAR, /* AR_pad_char. */
15, /* AR_max_namelen. */
+ 0, /* match priority. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getp32, bfd_getp_signed_32, bfd_putp32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
bfd_getl64, bfd_getl_signed_64, bfd_putl64,
bfd_getp32, bfd_getp_signed_32, bfd_putp32,
bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers. */
- {_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),
+ { /* bfd_check_format. */
+ _bfd_dummy_target,
+ MY_object_p,
+ bfd_generic_archive_p,
+ MY_core_file_p
+ },
+ { /* bfd_set_format. */
+ _bfd_bool_bfd_false_error,
+ MY_mkobject,
+ _bfd_generic_mkarchive,
+ _bfd_bool_bfd_false_error
+ },
+ { /* bfd_write_contents. */
+ _bfd_bool_bfd_false_error,
+ MY_write_object_contents,
+ _bfd_write_archive_contents,
+ _bfd_bool_bfd_false_error
+ },
+
+ 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),
/* Alternative_target. */
NULL,