#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups)
#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs)
+/* This is used when writing out the external relocs. */
+
+struct reloc_and_sec
+{
+ arelent *rel;
+ asection *sec;
+};
+
/* We store some function pointer in the backend structure. This lets
different NLM targets share most of the same code, while providing
slightly different code where necessary. */
struct nlm_backend_data
{
- /* Machine architecture. */
+ /* Signature for this backend. */
+ char signature[NLM_SIGNATURE_SIZE];
+ /* Size of the fixed header. */
+ bfd_size_type fixed_header_size;
+ /* Size of optional prefix for this backend. Some backend may
+ require this to be a function, but so far a constant is OK. This
+ is for a prefix which precedes the standard NLM fixed header. */
+ bfd_size_type optional_prefix_size;
+ /* Architecture. */
enum bfd_architecture arch;
+ /* Machine. */
+ long mach;
+ /* Some NLM formats have a prefix on the file. If this function is
+ not NULL, it will be called by nlm_object_p. It should return
+ true if this file could match this format, and it should leave
+ the BFD such that a bfd_read will pick up the fixed header. */
+ boolean (*nlm_backend_object_p) PARAMS ((bfd *));
+ /* Write out the prefix. This function may be NULL. This must
+ write out the same number of bytes as is in the field
+ optional_prefix_size. */
+ boolean (*nlm_write_prefix) PARAMS ((bfd *));
/* Read a relocation fixup from abfd. The reloc information is
machine specific. The second argument is the symbol if this is
an import, or NULL if this is a reloc fixup. This function
import symbol. */
boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *,
asection **, arelent *));
- /* Write a relocation fixup to abfd. */
- boolean (*nlm_write_reloc) PARAMS ((bfd *, asection *, arelent *));
/* To make objcopy to an i386 NLM work, the i386 backend needs a
chance to work over the relocs. This is a bit icky. */
boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data,
bfd_vma offset,
bfd_size_type count));
+ /* Read an import record from abfd. It would be nice if this
+ were in a machine-dependent format, but it doesn't seem to be. */
+ boolean (*nlm_read_import) PARAMS ((bfd *, nlmNAME(symbol_type) *));
+ /* Write an import record to abfd. */
+ boolean (*nlm_write_import) PARAMS ((bfd *, asection *, arelent *));
+ /* Set the section for a public symbol. This may be NULL, in which
+ case a default method will be used. */
+ boolean (*nlm_set_public_section) PARAMS ((bfd *, nlmNAME(symbol_type) *));
+ /* Get the offset to write out for a public symbol. This may be
+ NULL, in which case a default method will be used. */
+ bfd_vma (*nlm_get_public_offset) PARAMS ((bfd *, asymbol *));
+ /* Swap the fixed header in and out */
+ void (*nlm_swap_fhdr_in) PARAMS ((bfd *,
+ PTR,
+ Nlm_Internal_Fixed_Header *));
+ void (*nlm_swap_fhdr_out) PARAMS ((bfd *,
+ struct nlm_internal_fixed_header *,
+ PTR));
+ /* Write out an external reference. */
+ boolean (*nlm_write_external) PARAMS ((bfd *, bfd_size_type,
+ asymbol *,
+ struct reloc_and_sec *));
};
#define nlm_backend(bfd) \
((struct nlm_backend_data *)((bfd) -> xvec -> backend_data))
+#define nlm_signature(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> signature : "")
+#define nlm_fixed_header_size(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> fixed_header_size : 0)
+#define nlm_optional_prefix_size(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> optional_prefix_size : 0)
#define nlm_architecture(bfd) \
(nlm_backend(bfd) ? nlm_backend(bfd) -> arch : bfd_arch_unknown)
+#define nlm_machine(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> mach : 0)
+#define nlm_backend_object_p_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_backend_object_p : 0)
+#define nlm_write_prefix_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_write_prefix : 0)
#define nlm_read_reloc_func(bfd) \
(nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_read_reloc : 0)
-#define nlm_write_reloc_func(bfd) \
- (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_write_reloc : 0)
#define nlm_mangle_relocs_func(bfd) \
(nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_mangle_relocs : 0)
+#define nlm_read_import_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_read_import : 0)
+#define nlm_write_import_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_write_import : 0)
+#define nlm_set_public_section_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_set_public_section : 0)
+#define nlm_get_public_offset_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_get_public_offset : 0)
+#define nlm_swap_fixed_header_in_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_swap_fhdr_in : 0)
+#define nlm_swap_fixed_header_out_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_swap_fhdr_out : 0)
+#define nlm_write_external_func(bfd) \
+ (nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_write_external : 0)
/* The NLM code, data, and uninitialized sections have no names defined
in the NLM, but bfd wants to give them names, so use the traditional
#include "libbfd.h"
#define ARCH_SIZE 32
+
+#include "nlm/i386-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header
+
#include "libnlm.h"
static boolean nlm_i386_read_reloc
PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
-static boolean nlm_i386_write_reloc
+static boolean nlm_i386_write_import
PARAMS ((bfd *, asection *, arelent *));
static boolean nlm_i386_mangle_relocs
PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_i386_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static boolean nlm_i386_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
/* Adjust the reloc location by an absolute value. */
/* Write a NetWare i386 reloc. */
static boolean
-nlm_i386_write_reloc (abfd, sec, rel)
+nlm_i386_write_import (abfd, sec, rel)
bfd *abfd;
asection *sec;
arelent *rel;
|| rel->howto->size != 2
|| rel->howto->bitsize != 32
|| rel->howto->bitpos != 0
- || ! rel->howto->partial_inplace
|| rel->howto->src_mask != 0xffffffff
|| rel->howto->dst_mask != 0xffffffff)
{
sym = *rel->sym_ptr_ptr;
/* Note that no serious harm will ensue if we fail to change a
- reloc. We will wind up failing in nlm_i386_write_reloc. */
+ reloc. We will wind up failing in nlm_i386_write_import. */
/* Make sure this reloc is within the data we have. We only 4
byte relocs here, so we insist on having 4 bytes. */
that at this point the size of the data section is in the NLM
header. */
if (((bfd_get_section_flags (abfd, bfd_get_section (sym))
- & (SEC_CODE | SEC_DATA)) == 0)
+ & SEC_LOAD) == 0)
&& ((bfd_get_section_flags (abfd, bfd_get_section (sym))
& SEC_ALLOC) != 0))
addend += nlm_fixed_header (abfd)->dataImageSize;
&& rel->howto->size == 2
&& rel->howto->bitsize == 32
&& rel->howto->bitpos == 0
- && rel->howto->partial_inplace
&& rel->howto->src_mask == 0xffffffff
&& rel->howto->dst_mask == 0xffffffff)
{
bfd_vma val;
- val = bfd_get_32 (abfd, (char *) data + rel->address - offset);
+ val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
val += addend;
- bfd_put_32 (abfd, val, (char *) data + rel->address - offset);
+ bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
rel->addend = 0;
}
&& rel->howto->size == 2
&& rel->howto->bitsize == 32
&& rel->howto->bitpos == 0
- && rel->howto->partial_inplace
&& rel->howto->src_mask == 0xffffffff
&& rel->howto->dst_mask == 0xffffffff)
{
/* When pcrel_offset is not set, it means that the negative
of the address of the memory location is stored in the
memory location. We must add it back in. */
- val = bfd_get_32 (abfd, (char *) data + rel->address - offset);
+ val = bfd_get_32 (abfd, (bfd_byte *) data + rel->address - offset);
val += rel->address;
- bfd_put_32 (abfd, val, (char *) data + rel->address - offset);
+ bfd_put_32 (abfd, val, (bfd_byte *) data + rel->address - offset);
rel->howto = &nlm_i386_pcrel_howto;
}
return true;
}
+/* Read a NetWare i386 import record */
+static boolean
+nlm_i386_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ sym -> symbol.the_bfd = abfd;
+ sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
+ if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
+ != symlength)
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = &bfd_und_section;
+ if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ rcount = bfd_h_get_32 (abfd, temp);
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_i386_read_reloc (abfd, sym, §ion,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return true;
+}
+
+/* Write out an external reference. */
+
+static boolean
+nlm_i386_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (nlm_i386_write_import (abfd, relocs[i].sec,
+ relocs[i].rel) == false)
+ return false;
+ }
+
+ return true;
+}
+
+#include "nlmswap.h"
+
static const struct nlm_backend_data nlm32_i386_backend =
{
+ "NetWare Loadable Module\032",
+ sizeof (Nlm32_i386_External_Fixed_Header),
+ 0, /* optional_prefix_size */
bfd_arch_i386,
+ 0,
+ 0, /* backend_object_p */
+ 0, /* write_prefix_func */
nlm_i386_read_reloc,
- nlm_i386_write_reloc,
- nlm_i386_mangle_relocs
+ nlm_i386_mangle_relocs,
+ nlm_i386_read_import,
+ nlm_i386_write_import,
+ 0, /* set_public_section */
+ 0, /* get_public_offset */
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_i386_write_external,
};
#define TARGET_LITTLE_NAME "nlm32-i386"
--- /dev/null
+/* Support for 32-bit SPARC NLM (NetWare Loadable Module)
+ Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+
+#define ARCH_SIZE 32
+
+#include "nlm/sparc32-ext.h"
+#define Nlm_External_Fixed_Header Nlm32_sparc_External_Fixed_Header
+
+#include "libnlm.h"
+
+static boolean nlm_sparc_read_reloc
+ PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
+static boolean nlm_sparc_write_reloc
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_sparc_mangle_relocs
+ PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
+static boolean nlm_sparc_read_import
+ PARAMS ((bfd *, nlmNAME(symbol_type) *));
+static boolean nlm_sparc_write_import
+ PARAMS ((bfd *, asection *, arelent *));
+static boolean nlm_sparc_write_external
+ PARAMS ((bfd *, bfd_size_type, asymbol *, struct reloc_and_sec *));
+
+enum reloc_type
+ {
+ R_SPARC_NONE = 0,
+ R_SPARC_8, R_SPARC_16, R_SPARC_32,
+ R_SPARC_DISP8, R_SPARC_DISP16, R_SPARC_DISP32,
+ R_SPARC_WDISP30, R_SPARC_WDISP22,
+ R_SPARC_HI22, R_SPARC_22,
+ R_SPARC_13, R_SPARC_LO10,
+ R_SPARC_GOT10, R_SPARC_GOT13, R_SPARC_GOT22,
+ R_SPARC_PC10, R_SPARC_PC22,
+ R_SPARC_WPLT30,
+ R_SPARC_COPY,
+ R_SPARC_GLOB_DAT, R_SPARC_JMP_SLOT,
+ R_SPARC_RELATIVE,
+ R_SPARC_UA32,
+ R_SPARC_max
+ };
+
+#if 0
+static CONST char *CONST reloc_type_names[] =
+{
+ "R_SPARC_NONE",
+ "R_SPARC_8", "R_SPARC_16", "R_SPARC_32",
+ "R_SPARC_DISP8", "R_SPARC_DISP16", "R_SPARC_DISP32",
+ "R_SPARC_WDISP30", "R_SPARC_WDISP22",
+ "R_SPARC_HI22", "R_SPARC_22",
+ "R_SPARC_13", "R_SPARC_LO10",
+ "R_SPARC_GOT10", "R_SPARC_GOT13", "R_SPARC_GOT22",
+ "R_SPARC_PC10", "R_SPARC_PC22",
+ "R_SPARC_WPLT30",
+ "R_SPARC_COPY",
+ "R_SPARC_GLOB_DAT", "R_SPARC_JMP_SLOT",
+ "R_SPARC_RELATIVE",
+ "R_SPARC_UA32",
+};
+#endif
+
+static reloc_howto_type nlm32_sparc_howto_table[] =
+{
+ HOWTO(R_SPARC_NONE, 0,0, 0,false,0,complain_overflow_dont, 0,"R_SPARC_NONE", false,0,0x00000000,true),
+ HOWTO(R_SPARC_8, 0,0, 8,false,0,complain_overflow_bitfield,0,"R_SPARC_8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_16, 0,1,16,false,0,complain_overflow_bitfield,0,"R_SPARC_16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_32, 0,2,32,false,0,complain_overflow_bitfield,0,"R_SPARC_32", false,0,0xffffffff,true),
+ HOWTO(R_SPARC_DISP8, 0,0, 8,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP8", false,0,0x000000ff,true),
+ HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP16", false,0,0x0000ffff,true),
+ HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,complain_overflow_signed, 0,"R_SPARC_DISP32", false,0,0x00ffffff,true),
+ HOWTO(R_SPARC_WDISP30, 2,2,30,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP30", false,0,0x3fffffff,true),
+ HOWTO(R_SPARC_WDISP22, 2,2,22,true, 0,complain_overflow_signed, 0,"R_SPARC_WDISP22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_HI22, 10,2,22,false,0,complain_overflow_dont, 0,"R_SPARC_HI22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_LO10, 0,2,10,false,0,complain_overflow_dont, 0,"R_SPARC_LO10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_GOT13, 0,2,13,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT13", false,0,0x00001fff,true),
+ HOWTO(R_SPARC_GOT22, 10,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_GOT22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_PC10, 0,2,10,false,0,complain_overflow_bitfield,0,"R_SPARC_PC10", false,0,0x000003ff,true),
+ HOWTO(R_SPARC_PC22, 0,2,22,false,0,complain_overflow_bitfield,0,"R_SPARC_PC22", false,0,0x003fffff,true),
+ HOWTO(R_SPARC_WPLT30, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_WPLT30", false,0,0x00000000,true),
+ HOWTO(R_SPARC_COPY, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_COPY", false,0,0x00000000,true),
+ HOWTO(R_SPARC_GLOB_DAT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_GLOB_DAT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_JMP_SLOT,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_JMP_SLOT",false,0,0x00000000,true),
+ HOWTO(R_SPARC_RELATIVE,0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_RELATIVE",false,0,0x00000000,true),
+ HOWTO(R_SPARC_UA32, 0,0,00,false,0,complain_overflow_dont, 0,"R_SPARC_UA32", false,0,0x00000000,true),
+};
+
+/* Read a NetWare sparc reloc. */
+
+struct nlm32_sparc_reloc_ext {
+ unsigned char offset[4];
+ unsigned char addend[4];
+ unsigned char type[1];
+ unsigned char pad1[3];
+};
+
+static boolean
+nlm_sparc_read_reloc (abfd, sym, secp, rel)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+ asection **secp;
+ arelent *rel;
+{
+ bfd_byte temp[4];
+ bfd_vma val, addend;
+ const char *name;
+ int index;
+ unsigned int type;
+ struct nlm32_sparc_reloc_ext tmp_reloc;
+
+ if (bfd_read (&tmp_reloc, 12, 1, abfd) != 12) {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ *secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+
+ val = bfd_get_32 (abfd, tmp_reloc.offset);
+ addend = bfd_get_32 (abfd, tmp_reloc.addend);
+ type = bfd_get_8 (abfd, tmp_reloc.type);
+
+ rel->address = val;
+ rel->addend = addend;
+ rel->howto = NULL;
+
+ for (index = 0;
+ index < sizeof(nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
+ index++)
+ if (nlm32_sparc_howto_table[index].type == type) {
+ rel->howto = &nlm32_sparc_howto_table[index];
+ break;
+ }
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: address = %08lx, addend = %08lx, type = %d, howto = %08lx\n",
+ __FILE__, rel->address, rel->addend, type, rel->howto);
+#endif
+ return true;
+
+}
+
+/* Write a NetWare sparc reloc. */
+
+static boolean
+nlm_sparc_write_reloc (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ bfd_vma val;
+ struct nlm32_sparc_reloc_ext tmp_reloc = {0};
+ int index;
+ int type = -1;
+ reloc_howto_type *tmp;
+
+
+ for (index = 0;
+ index < sizeof (nlm32_sparc_howto_table) / sizeof(reloc_howto_type);
+ index++) {
+ tmp = &nlm32_sparc_howto_table[index];
+
+ if (tmp->rightshift == rel->howto->rightshift
+ && tmp->size == rel->howto->size
+ && tmp->bitsize == rel->howto->bitsize
+ && tmp->pc_relative == rel->howto->pc_relative
+ && tmp->bitpos == rel->howto->bitpos
+ && tmp->src_mask == rel->howto->src_mask
+ && tmp->dst_mask == rel->howto->dst_mask) {
+ type = tmp->type;
+ break;
+ }
+ }
+ if (type == -1)
+ abort();
+
+ /*
+ * Netware wants a list of relocs for each address.
+ * Format is:
+ * long offset
+ * long addend
+ * char type
+ * That should be it.
+ */
+
+ /* The value we write out is the offset into the appropriate
+ segment. This offset is the section vma, adjusted by the vma of
+ the lowest section in that segment, plus the address of the
+ relocation. */
+ val = bfd_get_section_vma (abfd, sec) + rel->address;
+
+#ifdef DEBUG
+ fprintf (stderr, "%s: val = %08lx, addend = %08lx, type = %d\n",
+ __FILE__, val, rel->addend, rel->howto->type);
+#endif
+ bfd_put_32 (abfd, val, tmp_reloc.offset);
+ bfd_put_32 (abfd, rel->addend, tmp_reloc.addend);
+ bfd_put_8 (abfd, (short)(rel->howto->type), tmp_reloc.type);
+
+ if (bfd_write (&tmp_reloc, 12, 1, abfd) != 12)
+ {
+ abort();
+ }
+
+ return true;
+}
+
+/* Mangle relocs for SPARC NetWare. We can just use the standard
+ SPARC relocs. */
+
+static boolean
+nlm_sparc_mangle_relocs (abfd, sec, data, offset, count)
+ bfd *abfd;
+ asection *sec;
+ PTR data;
+ bfd_vma offset;
+ bfd_size_type count;
+{
+ return true;
+}
+
+/* Read a NetWare sparc import record */
+static boolean
+nlm_sparc_read_import (abfd, sym)
+ bfd *abfd;
+ nlmNAME(symbol_type) *sym;
+{
+ struct nlm_relent *nlm_relocs; /* relocation records for symbol */
+ bfd_size_type rcount; /* number of relocs */
+ bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* temporary 32-bit value */
+ unsigned char symlength; /* length of symbol name */
+
+ /*
+ * First, read in the number of relocation
+ * entries for this symbol
+ */
+ if (bfd_read ((PTR) temp, 4, 1, abfd)
+ != 4)
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+
+ rcount = bfd_get_32 (abfd, temp);
+
+ /*
+ * Next, read in the length of the symbol
+ */
+
+ if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
+ != sizeof (symlength))
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ sym -> symbol.the_bfd = abfd;
+ sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
+
+ /*
+ * Then read in the symbol
+ */
+
+ if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
+ != symlength)
+ {
+ bfd_error = system_call_error;
+ return (false);
+ }
+ sym -> symbol.flags = 0;
+ sym -> symbol.value = 0;
+ sym -> symbol.section = &bfd_und_section;
+
+ /*
+ * Next, start reading in the relocs.
+ */
+
+ nlm_relocs = ((struct nlm_relent *)
+ bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
+ sym -> relocs = nlm_relocs;
+ sym -> rcnt = 0;
+ while (sym -> rcnt < rcount)
+ {
+ asection *section;
+
+ if (nlm_sparc_read_reloc (abfd, sym, §ion,
+ &nlm_relocs -> reloc)
+ == false)
+ return false;
+ nlm_relocs -> section = section;
+ nlm_relocs++;
+ sym -> rcnt++;
+ }
+ return true;
+}
+
+static boolean
+nlm_sparc_write_import (abfd, sec, rel)
+ bfd *abfd;
+ asection *sec;
+ arelent *rel;
+{
+ char temp[4];
+
+ bfd_put_32 (abfd, (*rel->sym_ptr_ptr)->value, temp);
+ bfd_write ((PTR)temp, 4, 1, abfd);
+ bfd_put_32 (abfd, 1, temp);
+ bfd_write ((PTR)temp, 4, 1, abfd);
+ if (nlm_sparc_write_reloc (abfd, sec, rel) == false)
+ return false;
+ return true;
+}
+
+/* Write out an external reference. */
+
+static boolean
+nlm_sparc_write_external (abfd, count, sym, relocs)
+ bfd *abfd;
+ bfd_size_type count;
+ asymbol *sym;
+ struct reloc_and_sec *relocs;
+{
+ int i;
+ bfd_byte len;
+ unsigned char temp[NLM_TARGET_LONG_SIZE];
+
+ bfd_put_32 (abfd, count, temp);
+ if (bfd_write (temp, sizeof(temp), 1, abfd) != sizeof (temp))
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ len = strlen (sym->name);
+ if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd) != sizeof(bfd_byte))
+ || bfd_write (sym->name, len, 1, abfd) != len)
+ {
+ bfd_error = system_call_error;
+ return false;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ if (nlm_sparc_write_reloc (abfd, relocs[i].sec,
+ relocs[i].rel) == false)
+ return false;
+ }
+
+ return true;
+}
+
+#undef nlm_swap_fixed_header_in
+#undef nlm_swap_fixed_header_out
+
+#include "nlmswap.h"
+
+static const struct nlm_backend_data nlm32_sparc_backend =
+{
+ "NetWare SPARC Module \032",
+ sizeof (Nlm32_sparc_External_Fixed_Header),
+ 0, /* optional_prefix_size */
+ bfd_arch_sparc,
+ 0,
+ 0, /* backend_object_p */
+ 0, /* write_prefix_func */
+ nlm_sparc_read_reloc,
+ nlm_sparc_mangle_relocs,
+ nlm_sparc_read_import,
+ nlm_sparc_write_import,
+ 0, /* set_public_section */
+ 0, /* get_public_offset */
+ nlm_swap_fixed_header_in,
+ nlm_swap_fixed_header_out,
+ nlm_sparc_write_external,
+};
+
+#define TARGET_BIG_NAME "nlm32-sparc"
+#define TARGET_BIG_SYM nlmNAME(sparc_vec)
+#define TARGET_BACKEND_DATA &nlm32_sparc_backend
+
+#include "nlm-target.h"
#define nlm_set_section_contents nlmNAME(set_section_contents)
#define nlm_write_object_contents nlmNAME(write_object_contents)
+#define nlm_swap_fixed_header_in(abfd,src,dst) \
+ (nlm_swap_fixed_header_in_func(abfd))(abfd,src,dst)
+#define nlm_swap_fixed_header_out(abfd,src,dst) \
+ (nlm_swap_fixed_header_out_func(abfd))(abfd,src,dst)
+
/* Forward declarations of static functions */
static boolean add_bfd_section
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
-static void nlm_swap_fixed_header_in
- PARAMS ((bfd *, Nlm_External_Fixed_Header *, Nlm_Internal_Fixed_Header *));
-static void nlm_swap_fixed_header_out
- PARAMS ((bfd *, Nlm_Internal_Fixed_Header *, Nlm_External_Fixed_Header *));
static boolean nlm_swap_variable_header_in
PARAMS ((bfd *));
static boolean nlm_swap_variable_header_out
bfd_target *
DEFUN (nlm_object_p, (abfd), bfd * abfd)
{
- Nlm_External_Fixed_Header x_fxdhdr; /* Nlm file header, external form */
- Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
+ struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
+ boolean (*backend_object_p) PARAMS ((bfd *));
+ PTR x_fxdhdr;
+ Nlm_Internal_Fixed_Header *i_fxdhdrp;
+ const char *signature;
enum bfd_architecture arch;
+ /* Some NLM formats have a prefix before the standard NLM fixed
+ header. */
+ backend_object_p = nlm_backend_object_p_func (abfd);
+ if (backend_object_p)
+ {
+ if (! (*backend_object_p) (abfd))
+ goto got_wrong_format_error;
+ }
+
/* Read in the fixed length portion of the NLM header in external format. */
- if (bfd_read ((PTR) &x_fxdhdr, sizeof (x_fxdhdr), 1, abfd) !=
- sizeof (x_fxdhdr))
+ x_fxdhdr = alloca (nlm_fixed_header_size (abfd));
+
+ if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
+ nlm_fixed_header_size (abfd))
{
bfd_error = system_call_error;
- return (NULL);
+ goto got_no_match;
}
- /* Check to see if we have an NLM file by matching the NLM signature. */
+ /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
+ the tdata pointer in the bfd. */
- if (strncmp (x_fxdhdr.signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE) != 0)
+ nlm_tdata (abfd) = (struct nlm_obj_tdata *)
+ bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
+ if (nlm_tdata (abfd) == NULL)
{
- bfd_error = wrong_format;
- return (NULL);
+ bfd_error = no_memory;
+ goto got_no_match;
}
+ i_fxdhdrp = nlm_fixed_header (abfd);
+ nlm_swap_fixed_header_in (abfd, x_fxdhdr, i_fxdhdrp);
+
+ /* Check to see if we have an NLM file for this backend by matching
+ the NLM signature. */
+
+ signature = nlm_signature (abfd);
+ if (signature != NULL
+ && *signature != '\0'
+ && strncmp ((char *) i_fxdhdrp->signature, signature,
+ NLM_SIGNATURE_SIZE) != 0)
+ goto got_wrong_format_error;
+
/* There's no supported way to discover the endianess of an NLM, so test for
a sane version number after doing byte swapping appropriate for this
XVEC. (Hack alert!) */
- if (get_word (abfd, (bfd_byte *) x_fxdhdr.version) > 0xFFFF)
- {
- bfd_error = wrong_format;
- return (NULL);
- }
+ if (i_fxdhdrp->version > 0xFFFF)
+ goto got_wrong_format_error;
/* There's no supported way to check for 32 bit versus 64 bit addresses,
so ignore this distinction for now. (FIXME) */
- /* Allocate an instance of the nlm_obj_tdata structure and hook it up to
- the tdata pointer in the bfd.
- FIXME: If we later decide this isn't the right format and the bfd
- already had valid tdata, we've just blown away the tdata we wanted
- to save for the right format. */
-
- nlm_tdata (abfd) = (struct nlm_obj_tdata *)
- bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
- if (nlm_tdata (abfd) == NULL)
- {
- bfd_error = no_memory;
- return (NULL);
- }
-
/* FIXME: Any return(NULL) exits below here will leak memory (tdata).
And a memory leak also means we lost the real tdata info we wanted
to save, because it was in the leaked memory. */
/* Swap in the rest of the fixed length header. */
- i_fxdhdrp = nlm_fixed_header (abfd);
- nlm_swap_fixed_header_in (abfd, &x_fxdhdr, i_fxdhdrp);
-
if (!nlm_swap_variable_header_in (abfd)
|| !nlm_swap_auxiliary_headers_in (abfd)
|| !add_bfd_section (abfd, NLM_CODE_NAME,
(file_ptr) 0,
i_fxdhdrp -> uninitializedDataSize,
SEC_ALLOC))
- {
- bfd_error = wrong_format;
- return (NULL);
- }
+ goto got_wrong_format_error;
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 0)
bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
return (abfd -> xvec);
+
+ got_wrong_format_error:
+ bfd_error = wrong_format;
+ got_no_match:
+ nlm_tdata (abfd) = preserved_tdata;
+ return (NULL);
}
/* Add a section to the bfd. */
return (true);
}
-/* Translate an NLM fixed length file header in external format into an NLM
- file header in internal format. */
-
-static void
-DEFUN (nlm_swap_fixed_header_in, (abfd, src, dst),
- bfd * abfd AND
- Nlm_External_Fixed_Header * src AND
- Nlm_Internal_Fixed_Header * dst)
-{
- memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
- memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
- dst -> version =
- get_word (abfd, (bfd_byte *) src -> version);
- dst -> codeImageOffset =
- get_word (abfd, (bfd_byte *) src -> codeImageOffset);
- dst -> codeImageSize =
- get_word (abfd, (bfd_byte *) src -> codeImageSize);
- dst -> dataImageOffset =
- get_word (abfd, (bfd_byte *) src -> dataImageOffset);
- dst -> dataImageSize =
- get_word (abfd, (bfd_byte *) src -> dataImageSize);
- dst -> uninitializedDataSize =
- get_word (abfd, (bfd_byte *) src -> uninitializedDataSize);
- dst -> customDataOffset =
- get_word (abfd, (bfd_byte *) src -> customDataOffset);
- dst -> customDataSize =
- get_word (abfd, (bfd_byte *) src -> customDataSize);
- dst -> moduleDependencyOffset =
- get_word (abfd, (bfd_byte *) src -> moduleDependencyOffset);
- dst -> numberOfModuleDependencies =
- get_word (abfd, (bfd_byte *) src -> numberOfModuleDependencies);
- dst -> relocationFixupOffset =
- get_word (abfd, (bfd_byte *) src -> relocationFixupOffset);
- dst -> numberOfRelocationFixups =
- get_word (abfd, (bfd_byte *) src -> numberOfRelocationFixups);
- dst -> externalReferencesOffset =
- get_word (abfd, (bfd_byte *) src -> externalReferencesOffset);
- dst -> numberOfExternalReferences =
- get_word (abfd, (bfd_byte *) src -> numberOfExternalReferences);
- dst -> publicsOffset =
- get_word (abfd, (bfd_byte *) src -> publicsOffset);
- dst -> numberOfPublics =
- get_word (abfd, (bfd_byte *) src -> numberOfPublics);
- dst -> debugInfoOffset =
- get_word (abfd, (bfd_byte *) src -> debugInfoOffset);
- dst -> numberOfDebugRecords =
- get_word (abfd, (bfd_byte *) src -> numberOfDebugRecords);
- dst -> codeStartOffset =
- get_word (abfd, (bfd_byte *) src -> codeStartOffset);
- dst -> exitProcedureOffset =
- get_word (abfd, (bfd_byte *) src -> exitProcedureOffset);
- dst -> checkUnloadProcedureOffset =
- get_word (abfd, (bfd_byte *) src -> checkUnloadProcedureOffset);
- dst -> moduleType =
- get_word (abfd, (bfd_byte *) src -> moduleType);
- dst -> flags =
- get_word (abfd, (bfd_byte *) src -> flags);
-}
-
-/* Translate an NLM fixed length file header in internal format into
- an NLM file header in external format. */
-
-static void
-DEFUN (nlm_swap_fixed_header_out, (abfd, src, dst),
- bfd * abfd AND
- Nlm_Internal_Fixed_Header * src AND
- Nlm_External_Fixed_Header * dst)
-{
- memcpy (dst -> signature, src -> signature, NLM_SIGNATURE_SIZE);
- memcpy (dst -> moduleName, src -> moduleName, NLM_MODULE_NAME_SIZE);
- put_word (abfd, (bfd_vma) src -> version,
- (bfd_byte *) dst -> version);
- put_word (abfd, (bfd_vma) src -> codeImageOffset,
- (bfd_byte *) dst -> codeImageOffset);
- put_word (abfd, (bfd_vma) src -> codeImageSize,
- (bfd_byte *) dst -> codeImageSize);
- put_word (abfd, (bfd_vma) src -> dataImageOffset,
- (bfd_byte *) dst -> dataImageOffset);
- put_word (abfd, (bfd_vma) src -> dataImageSize,
- (bfd_byte *) dst -> dataImageSize);
- put_word (abfd, (bfd_vma) src -> uninitializedDataSize,
- (bfd_byte *) dst -> uninitializedDataSize);
- put_word (abfd, (bfd_vma) src -> customDataOffset,
- (bfd_byte *) dst -> customDataOffset);
- put_word (abfd, (bfd_vma) src -> customDataSize,
- (bfd_byte *) dst -> customDataSize);
- put_word (abfd, (bfd_vma) src -> moduleDependencyOffset,
- (bfd_byte *) dst -> moduleDependencyOffset);
- put_word (abfd, (bfd_vma) src -> numberOfModuleDependencies,
- (bfd_byte *) dst -> numberOfModuleDependencies);
- put_word (abfd, (bfd_vma) src -> relocationFixupOffset,
- (bfd_byte *) dst -> relocationFixupOffset);
- put_word (abfd, (bfd_vma) src -> numberOfRelocationFixups,
- (bfd_byte *) dst -> numberOfRelocationFixups);
- put_word (abfd, (bfd_vma) src -> externalReferencesOffset,
- (bfd_byte *) dst -> externalReferencesOffset);
- put_word (abfd, (bfd_vma) src -> numberOfExternalReferences,
- (bfd_byte *) dst -> numberOfExternalReferences);
- put_word (abfd, (bfd_vma) src -> publicsOffset,
- (bfd_byte *) dst -> publicsOffset);
- put_word (abfd, (bfd_vma) src -> numberOfPublics,
- (bfd_byte *) dst -> numberOfPublics);
- put_word (abfd, (bfd_vma) src -> debugInfoOffset,
- (bfd_byte *) dst -> debugInfoOffset);
- put_word (abfd, (bfd_vma) src -> numberOfDebugRecords,
- (bfd_byte *) dst -> numberOfDebugRecords);
- put_word (abfd, (bfd_vma) src -> codeStartOffset,
- (bfd_byte *) dst -> codeStartOffset);
- put_word (abfd, (bfd_vma) src -> exitProcedureOffset,
- (bfd_byte *) dst -> exitProcedureOffset);
- put_word (abfd, (bfd_vma) src -> checkUnloadProcedureOffset,
- (bfd_byte *) dst -> checkUnloadProcedureOffset);
- put_word (abfd, (bfd_vma) src -> moduleType,
- (bfd_byte *) dst -> moduleType);
- put_word (abfd, (bfd_vma) src -> flags,
- (bfd_byte *) dst -> flags);
-}
-
/* Read and swap in the variable length header. All the fields must
exist in the NLM, and must exist in the order they are read here. */
DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
bfd * abfd)
{
- unsigned char tempstr [16];
+ char tempstr [16];
long position;
for (;;)
get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
nlm_extended_header (abfd) -> sharedPublicsCount =
get_word (abfd, (bfd_byte *) thdr.sharedPublicsCount);
+ nlm_extended_header (abfd) -> sharedDebugRecordOffset =
+ get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordOffset);
+ nlm_extended_header (abfd) -> sharedDebugRecordCount =
+ get_word (abfd, (bfd_byte *) thdr.sharedDebugRecordCount);
nlm_extended_header (abfd) -> SharedInitializationOffset =
get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
nlm_extended_header (abfd) -> SharedExitProcedureOffset =
}
else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
{
- Nlm_External_Copyright_Header thdr;
if (bfd_read ((PTR) &nlm_copyright_header (abfd)->stamp,
sizeof (nlm_copyright_header (abfd)->stamp),
1, abfd)
put_word (abfd,
(bfd_vma) nlm_extended_header (abfd) -> sharedPublicsCount,
(bfd_byte *) thdr.sharedPublicsCount);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd) -> sharedDebugRecordOffset,
+ (bfd_byte *) thdr.sharedDebugRecordOffset);
+ put_word (abfd,
+ (bfd_vma) nlm_extended_header (abfd) -> sharedDebugRecordCount,
+ (bfd_byte *) thdr.sharedDebugRecordCount);
put_word (abfd,
(bfd_vma) nlm_extended_header (abfd) -> SharedInitializationOffset,
(bfd_byte *) thdr.sharedInitializationOffset);
nlm_symbol_type *sym; /* Pointer to current bfd symbol */
unsigned char symlength; /* Symbol length read into here */
unsigned char symtype; /* Type of debugging symbol */
- bfd_size_type rcount; /* Number of relocs */
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
- boolean (*read_reloc_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
- arelent *));
+ boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
+ boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
if (nlm_get_symbols (abfd) != NULL)
return (true);
termination of the loop leaves the symcount correct for the symbols that
were read. */
+ set_public_section_func = nlm_set_public_section_func (abfd);
symcount = i_fxdhdrp -> numberOfPublics;
while (abfd -> symcount < symcount)
{
bfd_error = system_call_error;
return (false);
}
+ /* Cast away const. */
+ ((char *) (sym -> symbol.name))[symlength] = '\0';
if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
{
bfd_error = system_call_error;
}
sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
sym -> symbol.value = get_word (abfd, temp);
- if (sym -> symbol.value & NLM_HIBIT)
+ if (set_public_section_func)
{
- sym -> symbol.value &= ~NLM_HIBIT;
- sym -> symbol.flags |= BSF_FUNCTION;
- sym -> symbol.section =
- bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ /* Most backends can use the code below, but unfortunately
+ some use a different scheme. */
+ if ((*set_public_section_func) (abfd, sym) == false)
+ return false;
}
else
{
- sym -> symbol.section =
- bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ if (sym -> symbol.value & NLM_HIBIT)
+ {
+ sym -> symbol.value &= ~NLM_HIBIT;
+ sym -> symbol.flags |= BSF_FUNCTION;
+ sym -> symbol.section =
+ bfd_get_section_by_name (abfd, NLM_CODE_NAME);
+ }
+ else
+ {
+ sym -> symbol.section =
+ bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
+ }
}
sym -> rcnt = 0;
abfd -> symcount++;
bfd_error = system_call_error;
return (false);
}
+ /* Cast away const. */
+ ((char *) (sym -> symbol.name))[symlength] = '\0';
sym -> symbol.flags = BSF_LOCAL;
sym -> symbol.value = get_word (abfd, temp);
if (symtype == 0)
/* Read in the import records. We can only do this if we know how
to read relocs for this target. */
- read_reloc_func = nlm_read_reloc_func (abfd);
- if (read_reloc_func != NULL)
+ read_import_func = nlm_read_import_func (abfd);
+ if (read_import_func != NULL)
{
if (bfd_seek (abfd, i_fxdhdrp -> externalReferencesOffset, SEEK_SET)
== -1)
symcount += i_fxdhdrp -> numberOfExternalReferences;
while (abfd -> symcount < symcount)
{
- struct nlm_relent *nlm_relocs;
-
- if (bfd_read ((PTR) &symlength, sizeof (symlength), 1, abfd)
- != sizeof (symlength))
- {
- bfd_error = system_call_error;
- return (false);
- }
- sym -> symbol.the_bfd = abfd;
- sym -> symbol.name = bfd_alloc (abfd, symlength + 1);
- if (bfd_read ((PTR) sym -> symbol.name, symlength, 1, abfd)
- != symlength)
- {
- bfd_error = system_call_error;
- return (false);
- }
- sym -> symbol.flags = 0;
- sym -> symbol.value = 0;
- sym -> symbol.section = &bfd_und_section;
- if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
- {
- bfd_error = system_call_error;
- return (false);
- }
- rcount = get_word (abfd, temp);
- nlm_relocs = ((struct nlm_relent *)
- bfd_alloc (abfd, rcount * sizeof (struct nlm_relent)));
- sym -> relocs = nlm_relocs;
- sym -> rcnt = 0;
- while (sym -> rcnt < rcount)
- {
- asection *section;
-
- if ((*read_reloc_func) (abfd, sym, §ion,
- &nlm_relocs -> reloc)
- == false)
- return false;
- nlm_relocs -> section = section;
- nlm_relocs++;
- sym -> rcnt++;
- }
-
- abfd -> symcount++;
+ if ((*read_import_func) (abfd, sym) == false)
+ return false;
sym++;
+ abfd->symcount++;
}
}
abfd->output_has_begun = true;
/* The fixed header. */
- sofar = sizeof (Nlm_External_Fixed_Header);
+ sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
/* The variable header. */
sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
/* We need to sort a list of relocs associated with sections when we
write out the external relocs. */
-struct reloc_and_sec
-{
- arelent *rel;
- asection *sec;
-};
-
static int
nlm_external_reloc_compare (p1, p2)
const void *p1;
nlm_write_object_contents (abfd)
bfd *abfd;
{
- Nlm_External_Fixed_Header fixed_header;
asection *sec;
- boolean (*write_reloc_func) PARAMS ((bfd *, asection *, arelent *));
+ boolean (*write_import_func) PARAMS ((bfd *, asection *, arelent *));
bfd_size_type external_reloc_count, internal_reloc_count, i, c;
struct reloc_and_sec *external_relocs;
asymbol **sym_ptr_ptr;
file_ptr last;
+ boolean (*write_prefix_func) PARAMS ((bfd *));
+ unsigned char *fixed_header = alloca (nlm_fixed_header_size (abfd));
if (abfd->output_has_begun == false
&& nlm_compute_section_file_positions (abfd) == false)
return false;
/* Write out the variable length headers. */
- if (bfd_seek (abfd, sizeof (Nlm_External_Fixed_Header), SEEK_SET) != 0)
+ if (bfd_seek (abfd,
+ nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd),
+ SEEK_SET) != 0)
{
bfd_error = system_call_error;
return false;
/* The format of the relocation entries is dependent upon the
particular target. We use an external routine to write the reloc
out. */
- write_reloc_func = nlm_write_reloc_func (abfd);
+ write_import_func = nlm_write_import_func (abfd);
/* Write out the internal relocation fixups. While we're looping
over the relocs, we also count the external relocs, which is
continue;
/* We can only represent relocs within a code or data
- section. */
+ section. We ignore them for a debugging section. */
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
- {
- bfd_error = invalid_operation;
- return false;
- }
+ continue;
- /* We need to know how to write out relocs. */
- if (write_reloc_func == NULL)
+ /* We need to know how to write out imports */
+ if (write_import_func == NULL)
{
bfd_error = invalid_operation;
return false;
if (bfd_get_section (sym) != &bfd_und_section)
{
++internal_reloc_count;
- if ((*write_reloc_func) (abfd, sec, rel) == false)
+ if ((*write_import_func) (abfd, sec, rel) == false)
return false;
}
else
{
arelent *rel;
asymbol *sym;
- bfd_byte len;
bfd_size_type j, cnt;
- bfd_byte temp[NLM_TARGET_LONG_SIZE];
++c;
rel = external_relocs[i].rel;
sym = *rel->sym_ptr_ptr;
- len = strlen (sym->name);
- if ((bfd_write (&len, sizeof (bfd_byte), 1, abfd)
- != sizeof (bfd_byte))
- || bfd_write (sym->name, len, 1, abfd) != len)
- {
- bfd_error = system_call_error;
- return false;
- }
-
cnt = 0;
for (j = i;
(j < external_reloc_count
j++)
++cnt;
- put_word (abfd, (bfd_vma) cnt, temp);
- if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
- {
- bfd_error = system_call_error;
- return false;
- }
+ if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
+ &external_relocs[i])
+ == false)
+ return false;
- while (cnt-- != 0)
- {
- if ((*write_reloc_func) (abfd, external_relocs[i].sec,
- external_relocs[i].rel) == false)
- return false;
- ++i;
- }
+ i += cnt;
}
+
nlm_fixed_header (abfd)->numberOfExternalReferences = c;
/* Write out the public symbols (exports). */
sym_ptr_ptr = bfd_get_outsymbols (abfd);
if (sym_ptr_ptr != (asymbol **) NULL)
{
+ bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
asymbol **sym_end;
nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
+ get_public_offset_func = nlm_get_public_offset_func (abfd);
c = 0;
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
return false;
}
- offset = bfd_asymbol_value (sym);
- sec = sym->section;
- if (sec->flags & SEC_CODE)
- {
- offset -= nlm_get_text_low (abfd);
- offset |= NLM_HIBIT;
- }
- else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+ if (get_public_offset_func)
{
- /* SEC_ALLOC is for the .bss section. */
- offset -= nlm_get_data_low (abfd);
+ /* Most backends can use the code below, but
+ unfortunately some use a different scheme. */
+ offset = (*get_public_offset_func) (abfd, sym);
}
else
{
- /* We can't handle an exported symbol that is not in the
- code or data segment. */
- bfd_error = invalid_operation;
- return false;
+ offset = bfd_asymbol_value (sym);
+ sec = sym->section;
+ if (sec->flags & SEC_CODE)
+ {
+ offset -= nlm_get_text_low (abfd);
+ offset |= NLM_HIBIT;
+ }
+ else if (sec->flags & (SEC_DATA | SEC_ALLOC))
+ {
+ /* SEC_ALLOC is for the .bss section. */
+ offset -= nlm_get_data_low (abfd);
+ }
+ else
+ {
+ /* We can't handle an exported symbol that is not in
+ the code or data segment. */
+ bfd_error = invalid_operation;
+ return false;
+ }
}
put_word (abfd, offset, temp);
++c;
- offset = bfd_asymbol_value (sym);
+ offset = sym->value;
sec = sym->section;
if (sec->flags & SEC_CODE)
+ type = 1;
+ else if (sec->flags & SEC_DATA)
+ type = 0;
+ else if (sec->flags & SEC_ALLOC)
{
- offset -= nlm_get_text_low (abfd);
- type = 1;
- }
- else if (sec->flags & (SEC_DATA | SEC_ALLOC))
- {
- offset -= nlm_get_data_low (abfd);
type = 0;
+ offset += nlm_fixed_header (abfd)->dataImageSize;
}
else
type = 2;
/* At this point everything has been written out except the fixed
header. */
- memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
+ memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
NLM_SIGNATURE_SIZE);
nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
nlm_fixed_header (abfd)->codeStartOffset =
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
nlm_get_text_low (abfd);
- nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), &fixed_header);
- if (bfd_seek (abfd, 0, SEEK_SET) != 0
- || (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
- != sizeof fixed_header))
+ if (bfd_seek (abfd, 0, SEEK_SET) != 0)
+ return false;
+
+ write_prefix_func = nlm_write_prefix_func (abfd);
+ if (write_prefix_func)
+ {
+ if ((*write_prefix_func) (abfd) == false)
+ return false;
+ }
+
+ BFD_ASSERT (bfd_tell (abfd) == nlm_optional_prefix_size (abfd));
+
+ nlm_swap_fixed_header_out (abfd, nlm_fixed_header (abfd), fixed_header);
+ if (bfd_write (fixed_header, nlm_fixed_header_size (abfd), 1, abfd)
+ != nlm_fixed_header_size (abfd))
{
bfd_error = system_call_error;
return false;