+Mon Jan 11 18:32:22 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * targets.c (bfd_target): Added relocateable argument to
+ _bfd_get_relocated_section_contents. Added _bfd_seclet_link
+ target vector for linker use.
+ * bfd.c (bfd_seclet_link): New macro.
+ * bfd-in.h (JUMP_TABLE): Added _bfd_seclet_link.
+ * seclet.c (rel, seclet_dump_seclet): Added relocateable argument
+ and boolean return value. Made static.
+ (bfd_generic_seclet_link): Renamed from seclet_dump. Added
+ relocateable argument.
+ * reloc.c (bfd_generic_get_relocated_section_contents): Added
+ relocateable argument (if relocateable, saves relocs).
+ * bout.c (b_out_get_relocated_section_contents),
+ reloc16.c (bfd_coff_reloc16_get_relocated_section_contents): Added
+ relocateable argument (if relocateable, just calls
+ bfd_generic_get_relocated_section_contents).
+ * libcoff-in.h (bfd_coff_reloc16_get_value): Added relocateable
+ argument to prototype.
+ * All targets: Set new _bfd_seclet_link vector to
+ bfd_generic_seclet_link.
+
Sat Jan 9 21:29:32 1993 Stu Grossman (grossman at cygnus.com)
* coffgen.c: #include seclet.h.
#define bfd_get_section(x) ((x)->section)
#define bfd_get_output_section(x) ((x)->section->output_section)
#define bfd_set_section(x,y) ((x)->section) = (y)
-#define bfd_asymbol_base(x) ((x)->section?((x)->section->vma):0)
+#define bfd_asymbol_base(x) ((x)->section->vma)
#define bfd_asymbol_value(x) (bfd_asymbol_base(x) + x->value)
#define bfd_asymbol_name(x) ((x)->name)
+/*Perhaps future: #define bfd_asymbol_bfd(x) ((x)->section->owner)*/
+#define bfd_asymbol_bfd(x) ((x)->the_bfd)
+#define bfd_asymbol_flavour(x) (bfd_asymbol_bfd(x)->xvec->flavour)
/* This is a type pun with struct ranlib on purpose! */
typedef struct carsym {
CAT(NAME,_bfd_debug_info_end),\
CAT(NAME,_bfd_debug_info_accumulate),\
CAT(NAME,_bfd_get_relocated_section_contents),\
-CAT(NAME,_bfd_relax_section)
-
-#define COFF_SWAP_TABLE \
- coff_swap_aux_in, coff_swap_sym_in, coff_swap_lineno_in, \
- coff_swap_aux_out, coff_swap_sym_out, \
- coff_swap_lineno_out, coff_swap_reloc_out, \
- coff_swap_filehdr_out, coff_swap_aouthdr_out, \
- coff_swap_scnhdr_out
+CAT(NAME,_bfd_relax_section),\
+CAT(NAME,_bfd_seclet_link)
+#define COFF_SWAP_TABLE (PTR) &bfd_coff_std_swap_table
\f
/* User program access to BFD facilities */
/* BFD back-end for Intel 960 b.out binaries.
- Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#define PCREL13_MASK 0x1fff
/* Magic to turn callx into calljx */
static bfd_reloc_status_type
-DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section),
+DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section, seclet),
bfd *abfd AND
arelent *reloc_entry AND
PTR src AND
PTR dst AND
-
- asection *input_section)
+ asection *input_section AND
+ bfd_seclet_type *seclet)
{
int word = bfd_get_32(abfd, src);
asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
aout_symbol_type *symbol = aout_symbol(symbol_in);
+ if (symbol_in->section == &bfd_und_section)
+ {
+ bfd_error_vector.undefined_symbol(reloc_entry, seclet);
+ }
+
if (IS_CALLNAME(symbol->other))
{
/* Magic to turn call into callj */
static bfd_reloc_status_type
-DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, input_section),
+DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx,
+ input_section, seclet),
bfd *abfd AND
arelent *reloc_entry AND
PTR data AND
unsigned int srcidx AND
unsigned int dstidx AND
- asection *input_section )
+ asection *input_section AND
+ bfd_seclet_type *seclet)
{
int word = bfd_get_32(abfd, (bfd_byte *) data + srcidx);
asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
aout_symbol_type *symbol = aout_symbol(symbol_in);
+ if (symbol_in->section == &bfd_und_section)
+ {
+ bfd_error_vector.undefined_symbol(reloc_entry, seclet);
+ }
+
if (IS_OTHER(symbol->other))
{
/* Call to a system procedure - replace code with system
arelent *g = *generic;
unsigned char *raw = (unsigned char *)natptr;
asymbol *sym = *(g->sym_ptr_ptr);
-
+
asection *output_section = sym->section->output_section;
+
bfd_h_put_32(abfd, g->address, raw);
/* Find a type in the output format which matches the input howto -
* at the moment we assume input format == output format FIXME!!
*/
+ r_idx = 0;
/* FIXME: Need callj stuff here, and to check the howto entries to
be sure they are real for this architecture. */
if (g->howto== &howto_reloc_callj)
{
raw[7] = len_2 + incode_mask;
}
+ else if (g->howto >= howto_align_table
+ && g->howto <= (howto_align_table
+ + sizeof (howto_align_table) / sizeof (howto_align_table[0])
+ - 1))
+ {
+ /* symnum == -2; extern_mask not set, pcrel_mask set */
+ r_idx = -2;
+ r_extern = 0;
+ raw[7] = (pcrel_mask
+ | ((g->howto - howto_align_table) << 1));
+ }
else {
raw[7] = len_2;
}
- if (output_section == &bfd_com_section
- || output_section == &bfd_abs_section
- || output_section == &bfd_und_section)
+
+ if (r_idx != 0)
+ /* already mucked with r_extern, r_idx */;
+ else if (output_section == &bfd_com_section
+ || output_section == &bfd_abs_section
+ || output_section == &bfd_und_section)
{
if (bfd_abs_section.symbol == sym)
#endif
static bfd_byte *
-DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
+DEFUN(b_out_get_relocated_section_contents,(in_abfd,
+ seclet,
+ data,
+ relocateable),
bfd *in_abfd AND
bfd_seclet_type *seclet AND
- bfd_byte *data)
-
+ bfd_byte *data AND
+ boolean relocateable)
{
/* Get enough memory to hold the stuff */
bfd *input_bfd = seclet->u.indirect.section->owner;
input_section);
arelent **reloc_vector = (arelent **)alloca(reloc_size);
+ /* If producing relocateable output, don't bother to relax. */
+ if (relocateable)
+ return bfd_generic_get_relocated_section_contents (in_abfd, seclet,
+ data, relocateable);
+
/* read in the section */
bfd_get_section_contents(input_bfd,
input_section,
switch (reloc->howto->type)
{
case ABS32CODE:
- calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, input_section);
+ calljx_callback(in_abfd, reloc, src_address + data, dst_address+data,
+ input_section, seclet);
src_address+=4;
dst_address+=4;
break;
dst_address+=4;
break;
case CALLJ:
- callj_callback(in_abfd, reloc ,data,src_address,dst_address,input_section);
+ callj_callback(in_abfd, reloc ,data,src_address,dst_address,
+ input_section, seclet);
src_address+=4;
dst_address+=4;
break;
case ABS32CODE_SHRUNK:
/* This used to be a callx, but we've found out that a
callj will reach, so do the right thing */
- callj_callback(in_abfd, reloc,data,src_address+4, dst_address,input_section);
+ callj_callback(in_abfd, reloc,data,src_address+4, dst_address,
+ input_section, seclet);
dst_address+=4;
src_address+=8;
{
long int word = bfd_get_32(in_abfd, data+src_address);
asymbol *symbol = *(reloc->sym_ptr_ptr);
+ if (symbol->section == &bfd_und_section)
+ {
+ bfd_error_vector.undefined_symbol(reloc, seclet);
+ }
word = (word & ~BAL_MASK) |
(((word & BAL_MASK) +
symbol->section->output_offset +
{
long int word = bfd_get_32(in_abfd, data+src_address);
asymbol *symbol = *(reloc->sym_ptr_ptr);
+ if (symbol->section == &bfd_und_section)
+ {
+ bfd_error_vector.undefined_symbol(reloc, seclet);
+ }
word = (word & ~PCREL13_MASK) |
(((word & PCREL13_MASK) +
symbol->section->output_offset +
#define aout_32_bfd_get_relocated_section_contents b_out_get_relocated_section_contents
#define aout_32_bfd_relax_section b_out_relax_section
+#define aout_32_bfd_seclet_link bfd_generic_seclet_link
bfd_target b_out_vec_big_host =
{
_bfd_write_archive_contents, bfd_false},
JUMP_TABLE(aout_32),
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
b_out_reloc_type_lookup,
};
{bfd_false, b_out_write_object_contents, /* bfd_write_contents */
_bfd_write_archive_contents, bfd_false},
JUMP_TABLE(aout_32),
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
b_out_reloc_type_lookup,
};
(void (*) PARAMS ((bfd *, struct sec *))) bfd_void
#define ecoff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define ecoff_bfd_relax_section bfd_generic_relax_section
+#define ecoff_bfd_seclet_link bfd_generic_seclet_link
bfd_target ecoff_little_vec =
{
(void (*) PARAMS ((bfd *, struct sec *))) bfd_void
#define coff_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define coff_bfd_relax_section bfd_generic_relax_section
+#define coff_bfd_seclet_link bfd_generic_seclet_link
#define hppa_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define hppa_bfd_relax_section bfd_generic_relax_section
+#define hppa_bfd_seclet_link bfd_generic_seclet_link
bfd_target hppa_vec =
{
asection *,
asymbol **));
extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
- PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *));
+ PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable));
extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
struct bfd_seclet *));
asection *,
asymbol **));
extern bfd_byte *bfd_coff_reloc16_get_relocated_section_contents
- PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *));
+ PARAMS ((bfd *, struct bfd_seclet *, bfd_byte *, boolean relocateable));
extern bfd_vma bfd_coff_reloc16_get_value PARAMS ((arelent *,
struct bfd_seclet *));
(bfd *, struct sec *))) bfd_void
#define sco_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define sco_bfd_relax_section bfd_generic_relax_section
+#define sco_bfd_seclet_link \
+ ((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
+
/* If somebody calls any byte-swapping routines, shoot them. */
void
swap_abort()
#include "libbfd.h"
#include "seclet.h"
#include "coff/internal.h"
+
+/* Create a new seclet and attach it to a section. */
+
bfd_seclet_type *
DEFUN(bfd_new_seclet,(abfd, section),
bfd *abfd AND
return n;
}
+/* Given an indirect seclet which points to an input section, relocate
+ the contents of the seclet and put the data in its final
+ destination. */
-
-
-#define MAX_ERRORS_IN_A_ROW 10
-extern bfd_error_vector_type bfd_error_vector;
-
-
-void
-DEFUN(rel,(abfd, seclet, output_section, data),
+static boolean
+DEFUN(rel,(abfd, seclet, output_section, data, relocateable),
bfd *abfd AND
bfd_seclet_type *seclet AND
asection *output_section AND
- PTR data)
+ PTR data AND
+ boolean relocateable)
{
if (output_section->flags & SEC_HAS_CONTENTS
&& (output_section->flags & SEC_LOAD)
&& seclet->size)
{
- data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data);
+ data = (PTR) bfd_get_relocated_section_contents(abfd, seclet, data,
+ relocateable);
if(bfd_set_section_contents(abfd,
output_section,
data,
abort();
}
}
+ return true;
}
-void
-DEFUN(seclet_dump_seclet,(abfd, seclet, section, data),
+/* Put the contents of a seclet in its final destination. */
+
+static boolean
+DEFUN(seclet_dump_seclet,(abfd, seclet, section, data, relocateable),
bfd *abfd AND
bfd_seclet_type *seclet AND
asection *section AND
- PTR data)
+ PTR data AND
+ boolean relocateable)
{
switch (seclet->type)
- {
- case bfd_indirect_seclet:
- /* The contents of this section come from another one somewhere
- else */
- rel(abfd, seclet, section, data);
- break;
- case bfd_fill_seclet:
- /* Fill in the section with us */
- {
- char *d = bfd_xmalloc(seclet->size);
- unsigned int i;
- for (i =0; i < seclet->size; i+=2) {
- d[i] = seclet->u.fill.value >> 8;
- }
- for (i = 1; i < seclet->size; i+=2) {
- d[i] = seclet->u.fill.value ;
- }
- bfd_set_section_contents(abfd, section, d, seclet->offset, seclet->size);
-
- }
- break;
- default:
- abort();
- }
+ {
+ case bfd_indirect_seclet:
+ /* The contents of this section come from another one somewhere
+ else */
+ return rel(abfd, seclet, section, data, relocateable);
+
+ case bfd_fill_seclet:
+ /* Fill in the section with us */
+ {
+ char *d = bfd_xmalloc(seclet->size);
+ unsigned int i;
+ for (i =0; i < seclet->size; i+=2) {
+ d[i] = seclet->u.fill.value >> 8;
+ }
+ for (i = 1; i < seclet->size; i+=2) {
+ d[i] = seclet->u.fill.value ;
+ }
+ return bfd_set_section_contents(abfd, section, d, seclet->offset,
+ seclet->size);
+ }
+
+ default:
+ abort();
+ }
+
+ return true;
}
-void
-DEFUN(seclet_dump,(abfd, data),
+/*
+INTERNAL_FUNCTION
+ bfd_generic_seclet_link
+
+SYNOPSIS
+ boolean bfd_generic_seclet_link
+ (bfd *abfd,
+ PTR data,
+ boolean relocateable);
+
+DESCRIPTION
+
+ The generic seclet linking routine. The caller should have
+ set up seclets for all the output sections. The DATA argument
+ should point to a memory area large enough to hold the largest
+ section. This function looks through the seclets and moves
+ the contents into the output sections. If RELOCATEABLE is
+ true, the orelocation fields of the output sections must
+ already be initialized.
+
+*/
+
+boolean
+DEFUN(bfd_generic_seclet_link,(abfd, data, relocateable),
bfd *abfd AND
- PTR data)
+ PTR data AND
+ boolean relocateable)
{
- /* Write all the seclets on the bfd out, relocate etc according to the
- rules */
-
asection *o = abfd->sections;
while (o != (asection *)NULL)
{
bfd_seclet_type *p = o->seclets_head;
while (p != (bfd_seclet_type *)NULL)
{
- seclet_dump_seclet(abfd, p, o, data);
+ if (seclet_dump_seclet(abfd, p, o, data, relocateable) == false)
+ return false;
p = p ->next;
}
o = o->next;
}
+
+ return true;
}