* libnlm.h (struct nlm_backend_data): New fields

optional_prefix_size, nlm_backend_object_p, nlm_write_prefix,
	nlm_set_public_section, nlm_get_public_offset.  Removed unused
	nlm_write_reloc field.  Changed nlm_write_import to remove
	unnecessary symbol argument.  Renamed nlm_write_externals to
	nlm_write_external, and changed cound argument from bfd_vma to
	bfd_size_type.
	(nlm_optional_prefix_size, nlm_backend_object_p_func,
	nlm_write_prefix_func, nlm_set_public_section_func,
	nlm_get_public_offset_func): New accessor macros.
	(nlm_write_reloc_func): Removed.
	(nlm_write_external_func): Adjusted for field renaming.
	* nlm32-i386.c (nlm_i386_write_import): Renamed from
	nlm_i386_write_reloc.  Removed old nlm_i386_write_import which
	just called old nlm_i386_write_reloc.
	(nlm_i386_write_external): Renamed from nlm_i386_write_externals.
	Declared.  Changed second argument from bfd_vma to bfd_size_type.
	(nlm32_i386_backend): Adjusted for changes to fields and names.
	* nlm32-sparc.c (nlm_sparc_mangle_relocs): Removed unused,
	ifdeffed out code.
	(nlm_sparc_write_import): Removed second argument.
	(nlm_sparc_write_external): Renamed from
	nlm_sparc_write_externals.  Changed second argument from bfd_vma
	to bfd_size_type.
	(nlm32_sparc_backend): Adjusted for changes to fields and names.
	* nlmcode.h: Removed some unused code.
	(nlm_object_p): Don't destroy tdata pointer.  Call
	backend_object_p function if it exists.
	(nlm_slurp_symbol_table): Removed unused variable rcount.  Call
	set_public_section_func if it exists instead of checking
	NLM_HIBIT.
	(nlm_compute_section_file_positions): Account for
	optional_prefix_size.
	(nlm_write_object_contents): Account for optional_prefix_size.
	Removed useless variable write_reloc_func.  Changed declaration
	and call of write_import_func.  Call write_prefix_func if it
	exists.  Removed unused variables len and temp.  Call
	get_public_offset_func if it exists rather than setting NLM_HIBIT.
This commit is contained in:
Ian Lance Taylor 1993-12-02 02:22:35 +00:00
parent f7912fb476
commit cdbfad1cd7
4 changed files with 761 additions and 304 deletions

View File

@ -117,14 +117,41 @@ struct nlm_obj_tdata
#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
@ -134,25 +161,69 @@ struct nlm_backend_data
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

View File

@ -22,14 +22,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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. */
@ -146,7 +154,7 @@ nlm_i386_read_reloc (abfd, sym, secp, rel)
/* 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;
@ -165,7 +173,6 @@ nlm_i386_write_reloc (abfd, sec, 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)
{
@ -264,7 +271,7 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
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. */
@ -283,7 +290,7 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
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;
@ -294,15 +301,14 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
&& 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;
}
@ -319,7 +325,6 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
&& 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)
{
@ -328,9 +333,9 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
/* 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;
}
@ -339,12 +344,117 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
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, &section,
&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"

400
bfd/nlm32-sparc.c Normal file
View File

@ -0,0 +1,400 @@
/* 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, &section,
&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"

View File

@ -51,14 +51,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#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
@ -92,63 +93,73 @@ static int nlm_external_reloc_compare
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. */
if (strncmp (x_fxdhdr.signature, NLM_SIGNATURE, NLM_SIGNATURE_SIZE) != 0)
{
bfd_error = wrong_format;
return (NULL);
}
/* 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);
}
/* 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. */
the tdata pointer in the bfd. */
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);
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 (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) */
/* 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,
@ -165,10 +176,7 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd)
(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)
@ -183,6 +191,12 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd)
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. */
@ -210,124 +224,6 @@ DEFUN (add_bfd_section, (abfd, name, offset, size, flags),
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. */
@ -537,7 +433,7 @@ static boolean
DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
bfd * abfd)
{
unsigned char tempstr [16];
char tempstr [16];
long position;
for (;;)
@ -623,6 +519,10 @@ DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
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 =
@ -661,7 +561,6 @@ DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
}
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)
@ -805,6 +704,12 @@ nlm_swap_auxiliary_headers_out (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);
@ -1026,10 +931,9 @@ nlm_slurp_symbol_table (abfd)
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);
@ -1066,6 +970,7 @@ nlm_slurp_symbol_table (abfd)
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)
{
@ -1083,6 +988,8 @@ nlm_slurp_symbol_table (abfd)
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;
@ -1090,17 +997,27 @@ nlm_slurp_symbol_table (abfd)
}
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++;
@ -1137,6 +1054,8 @@ nlm_slurp_symbol_table (abfd)
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)
@ -1163,8 +1082,8 @@ nlm_slurp_symbol_table (abfd)
/* 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)
@ -1176,50 +1095,10 @@ nlm_slurp_symbol_table (abfd)
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, &section,
&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++;
}
}
@ -1444,7 +1323,7 @@ nlm_compute_section_file_positions (abfd)
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)
@ -1644,12 +1523,6 @@ nlm_set_section_contents (abfd, section, location, offset, count)
/* 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;
@ -1694,20 +1567,23 @@ boolean
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;
@ -1738,7 +1614,7 @@ nlm_write_object_contents (abfd)
/* 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
@ -1753,15 +1629,12 @@ nlm_write_object_contents (abfd)
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;
@ -1780,7 +1653,7 @@ nlm_write_object_contents (abfd)
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
@ -1843,24 +1716,13 @@ nlm_write_object_contents (abfd)
{
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
@ -1868,30 +1730,25 @@ nlm_write_object_contents (abfd)
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++)
@ -1918,24 +1775,33 @@ nlm_write_object_contents (abfd)
return false;
}
offset = bfd_asymbol_value (sym);
sec = sym->section;
if (sec->flags & SEC_CODE)
if (get_public_offset_func)
{
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);
/* 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);
@ -1983,17 +1849,16 @@ nlm_write_object_contents (abfd)
++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;
@ -2048,7 +1913,7 @@ nlm_write_object_contents (abfd)
/* 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 =
@ -2063,10 +1928,21 @@ nlm_write_object_contents (abfd)
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;