mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 17:18:24 +08:00
* 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:
81
bfd/libnlm.h
81
bfd/libnlm.h
@ -117,14 +117,41 @@ struct nlm_obj_tdata
|
|||||||
#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups)
|
#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups)
|
||||||
#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs)
|
#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
|
/* We store some function pointer in the backend structure. This lets
|
||||||
different NLM targets share most of the same code, while providing
|
different NLM targets share most of the same code, while providing
|
||||||
slightly different code where necessary. */
|
slightly different code where necessary. */
|
||||||
|
|
||||||
struct nlm_backend_data
|
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;
|
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
|
/* Read a relocation fixup from abfd. The reloc information is
|
||||||
machine specific. The second argument is the symbol if this is
|
machine specific. The second argument is the symbol if this is
|
||||||
an import, or NULL if this is a reloc fixup. This function
|
an import, or NULL if this is a reloc fixup. This function
|
||||||
@ -134,25 +161,69 @@ struct nlm_backend_data
|
|||||||
import symbol. */
|
import symbol. */
|
||||||
boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *,
|
boolean (*nlm_read_reloc) PARAMS ((bfd *, nlmNAME(symbol_type) *,
|
||||||
asection **, arelent *));
|
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
|
/* To make objcopy to an i386 NLM work, the i386 backend needs a
|
||||||
chance to work over the relocs. This is a bit icky. */
|
chance to work over the relocs. This is a bit icky. */
|
||||||
boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data,
|
boolean (*nlm_mangle_relocs) PARAMS ((bfd *, asection *, PTR data,
|
||||||
bfd_vma offset,
|
bfd_vma offset,
|
||||||
bfd_size_type count));
|
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) \
|
#define nlm_backend(bfd) \
|
||||||
((struct nlm_backend_data *)((bfd) -> xvec -> backend_data))
|
((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) \
|
#define nlm_architecture(bfd) \
|
||||||
(nlm_backend(bfd) ? nlm_backend(bfd) -> arch : bfd_arch_unknown)
|
(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) \
|
#define nlm_read_reloc_func(bfd) \
|
||||||
(nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_read_reloc : 0)
|
(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) \
|
#define nlm_mangle_relocs_func(bfd) \
|
||||||
(nlm_backend(bfd) ? nlm_backend(bfd) -> nlm_mangle_relocs : 0)
|
(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
|
/* 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
|
in the NLM, but bfd wants to give them names, so use the traditional
|
||||||
|
136
bfd/nlm32-i386.c
136
bfd/nlm32-i386.c
@ -22,14 +22,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#include "libbfd.h"
|
#include "libbfd.h"
|
||||||
|
|
||||||
#define ARCH_SIZE 32
|
#define ARCH_SIZE 32
|
||||||
|
|
||||||
|
#include "nlm/i386-ext.h"
|
||||||
|
#define Nlm_External_Fixed_Header Nlm32_i386_External_Fixed_Header
|
||||||
|
|
||||||
#include "libnlm.h"
|
#include "libnlm.h"
|
||||||
|
|
||||||
static boolean nlm_i386_read_reloc
|
static boolean nlm_i386_read_reloc
|
||||||
PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
|
PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
|
||||||
static boolean nlm_i386_write_reloc
|
static boolean nlm_i386_write_import
|
||||||
PARAMS ((bfd *, asection *, arelent *));
|
PARAMS ((bfd *, asection *, arelent *));
|
||||||
static boolean nlm_i386_mangle_relocs
|
static boolean nlm_i386_mangle_relocs
|
||||||
PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
|
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. */
|
/* 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. */
|
/* Write a NetWare i386 reloc. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
nlm_i386_write_reloc (abfd, sec, rel)
|
nlm_i386_write_import (abfd, sec, rel)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *sec;
|
asection *sec;
|
||||||
arelent *rel;
|
arelent *rel;
|
||||||
@ -165,7 +173,6 @@ nlm_i386_write_reloc (abfd, sec, rel)
|
|||||||
|| rel->howto->size != 2
|
|| rel->howto->size != 2
|
||||||
|| rel->howto->bitsize != 32
|
|| rel->howto->bitsize != 32
|
||||||
|| rel->howto->bitpos != 0
|
|| rel->howto->bitpos != 0
|
||||||
|| ! rel->howto->partial_inplace
|
|
||||||
|| rel->howto->src_mask != 0xffffffff
|
|| rel->howto->src_mask != 0xffffffff
|
||||||
|| rel->howto->dst_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;
|
sym = *rel->sym_ptr_ptr;
|
||||||
|
|
||||||
/* Note that no serious harm will ensue if we fail to change a
|
/* 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
|
/* Make sure this reloc is within the data we have. We only 4
|
||||||
byte relocs here, so we insist on having 4 bytes. */
|
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
|
that at this point the size of the data section is in the NLM
|
||||||
header. */
|
header. */
|
||||||
if (((bfd_get_section_flags (abfd, bfd_get_section (sym))
|
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))
|
&& ((bfd_get_section_flags (abfd, bfd_get_section (sym))
|
||||||
& SEC_ALLOC) != 0))
|
& SEC_ALLOC) != 0))
|
||||||
addend += nlm_fixed_header (abfd)->dataImageSize;
|
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->size == 2
|
||||||
&& rel->howto->bitsize == 32
|
&& rel->howto->bitsize == 32
|
||||||
&& rel->howto->bitpos == 0
|
&& rel->howto->bitpos == 0
|
||||||
&& rel->howto->partial_inplace
|
|
||||||
&& rel->howto->src_mask == 0xffffffff
|
&& rel->howto->src_mask == 0xffffffff
|
||||||
&& rel->howto->dst_mask == 0xffffffff)
|
&& rel->howto->dst_mask == 0xffffffff)
|
||||||
{
|
{
|
||||||
bfd_vma val;
|
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;
|
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->addend = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,7 +325,6 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
|
|||||||
&& rel->howto->size == 2
|
&& rel->howto->size == 2
|
||||||
&& rel->howto->bitsize == 32
|
&& rel->howto->bitsize == 32
|
||||||
&& rel->howto->bitpos == 0
|
&& rel->howto->bitpos == 0
|
||||||
&& rel->howto->partial_inplace
|
|
||||||
&& rel->howto->src_mask == 0xffffffff
|
&& rel->howto->src_mask == 0xffffffff
|
||||||
&& rel->howto->dst_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
|
/* When pcrel_offset is not set, it means that the negative
|
||||||
of the address of the memory location is stored in the
|
of the address of the memory location is stored in the
|
||||||
memory location. We must add it back in. */
|
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;
|
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;
|
rel->howto = &nlm_i386_pcrel_howto;
|
||||||
}
|
}
|
||||||
@ -339,12 +344,117 @@ nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
|
|||||||
return true;
|
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 =
|
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,
|
bfd_arch_i386,
|
||||||
|
0,
|
||||||
|
0, /* backend_object_p */
|
||||||
|
0, /* write_prefix_func */
|
||||||
nlm_i386_read_reloc,
|
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"
|
#define TARGET_LITTLE_NAME "nlm32-i386"
|
||||||
|
400
bfd/nlm32-sparc.c
Normal file
400
bfd/nlm32-sparc.c
Normal 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, §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"
|
406
bfd/nlmcode.h
406
bfd/nlmcode.h
@ -51,14 +51,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||||||
#define nlm_set_section_contents nlmNAME(set_section_contents)
|
#define nlm_set_section_contents nlmNAME(set_section_contents)
|
||||||
#define nlm_write_object_contents nlmNAME(write_object_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 */
|
/* Forward declarations of static functions */
|
||||||
|
|
||||||
static boolean add_bfd_section
|
static boolean add_bfd_section
|
||||||
PARAMS ((bfd *, char *, file_ptr, bfd_size_type, flagword));
|
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
|
static boolean nlm_swap_variable_header_in
|
||||||
PARAMS ((bfd *));
|
PARAMS ((bfd *));
|
||||||
static boolean nlm_swap_variable_header_out
|
static boolean nlm_swap_variable_header_out
|
||||||
@ -92,63 +93,73 @@ static int nlm_external_reloc_compare
|
|||||||
bfd_target *
|
bfd_target *
|
||||||
DEFUN (nlm_object_p, (abfd), bfd * abfd)
|
DEFUN (nlm_object_p, (abfd), bfd * abfd)
|
||||||
{
|
{
|
||||||
Nlm_External_Fixed_Header x_fxdhdr; /* Nlm file header, external form */
|
struct nlm_obj_tdata *preserved_tdata = nlm_tdata (abfd);
|
||||||
Nlm_Internal_Fixed_Header *i_fxdhdrp; /* Nlm file header, internal form */
|
boolean (*backend_object_p) PARAMS ((bfd *));
|
||||||
|
PTR x_fxdhdr;
|
||||||
|
Nlm_Internal_Fixed_Header *i_fxdhdrp;
|
||||||
|
const char *signature;
|
||||||
enum bfd_architecture arch;
|
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. */
|
/* Read in the fixed length portion of the NLM header in external format. */
|
||||||
|
|
||||||
if (bfd_read ((PTR) &x_fxdhdr, sizeof (x_fxdhdr), 1, abfd) !=
|
x_fxdhdr = alloca (nlm_fixed_header_size (abfd));
|
||||||
sizeof (x_fxdhdr))
|
|
||||||
|
if (bfd_read ((PTR) x_fxdhdr, nlm_fixed_header_size (abfd), 1, abfd) !=
|
||||||
|
nlm_fixed_header_size (abfd))
|
||||||
{
|
{
|
||||||
bfd_error = system_call_error;
|
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
|
/* Allocate an instance of the nlm_obj_tdata structure and hook it up to
|
||||||
the tdata pointer in the bfd.
|
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 *)
|
nlm_tdata (abfd) = (struct nlm_obj_tdata *)
|
||||||
bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
|
bfd_zalloc (abfd, sizeof (struct nlm_obj_tdata));
|
||||||
if (nlm_tdata (abfd) == NULL)
|
if (nlm_tdata (abfd) == NULL)
|
||||||
{
|
{
|
||||||
bfd_error = no_memory;
|
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).
|
/* 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
|
And a memory leak also means we lost the real tdata info we wanted
|
||||||
to save, because it was in the leaked memory. */
|
to save, because it was in the leaked memory. */
|
||||||
|
|
||||||
/* Swap in the rest of the fixed length header. */
|
/* 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)
|
if (!nlm_swap_variable_header_in (abfd)
|
||||||
|| !nlm_swap_auxiliary_headers_in (abfd)
|
|| !nlm_swap_auxiliary_headers_in (abfd)
|
||||||
|| !add_bfd_section (abfd, NLM_CODE_NAME,
|
|| !add_bfd_section (abfd, NLM_CODE_NAME,
|
||||||
@ -165,10 +176,7 @@ DEFUN (nlm_object_p, (abfd), bfd * abfd)
|
|||||||
(file_ptr) 0,
|
(file_ptr) 0,
|
||||||
i_fxdhdrp -> uninitializedDataSize,
|
i_fxdhdrp -> uninitializedDataSize,
|
||||||
SEC_ALLOC))
|
SEC_ALLOC))
|
||||||
{
|
goto got_wrong_format_error;
|
||||||
bfd_error = wrong_format;
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
|
if (nlm_fixed_header (abfd)->numberOfRelocationFixups != 0
|
||||||
|| nlm_fixed_header (abfd)->numberOfExternalReferences != 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);
|
bfd_default_set_arch_mach (abfd, arch, (unsigned long) 0);
|
||||||
|
|
||||||
return (abfd -> xvec);
|
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. */
|
/* Add a section to the bfd. */
|
||||||
@ -210,124 +224,6 @@ DEFUN (add_bfd_section, (abfd, name, offset, size, flags),
|
|||||||
return (true);
|
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
|
/* 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. */
|
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),
|
DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
|
||||||
bfd * abfd)
|
bfd * abfd)
|
||||||
{
|
{
|
||||||
unsigned char tempstr [16];
|
char tempstr [16];
|
||||||
long position;
|
long position;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -623,6 +519,10 @@ DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
|
|||||||
get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
|
get_word (abfd, (bfd_byte *) thdr.sharedPublicsOffset);
|
||||||
nlm_extended_header (abfd) -> sharedPublicsCount =
|
nlm_extended_header (abfd) -> sharedPublicsCount =
|
||||||
get_word (abfd, (bfd_byte *) thdr.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 =
|
nlm_extended_header (abfd) -> SharedInitializationOffset =
|
||||||
get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
|
get_word (abfd, (bfd_byte *) thdr.sharedInitializationOffset);
|
||||||
nlm_extended_header (abfd) -> SharedExitProcedureOffset =
|
nlm_extended_header (abfd) -> SharedExitProcedureOffset =
|
||||||
@ -661,7 +561,6 @@ DEFUN (nlm_swap_auxiliary_headers_in, (abfd),
|
|||||||
}
|
}
|
||||||
else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
|
else if (strncmp (tempstr, "CoPyRiGhT=", 10) == 0)
|
||||||
{
|
{
|
||||||
Nlm_External_Copyright_Header thdr;
|
|
||||||
if (bfd_read ((PTR) &nlm_copyright_header (abfd)->stamp,
|
if (bfd_read ((PTR) &nlm_copyright_header (abfd)->stamp,
|
||||||
sizeof (nlm_copyright_header (abfd)->stamp),
|
sizeof (nlm_copyright_header (abfd)->stamp),
|
||||||
1, abfd)
|
1, abfd)
|
||||||
@ -805,6 +704,12 @@ nlm_swap_auxiliary_headers_out (abfd)
|
|||||||
put_word (abfd,
|
put_word (abfd,
|
||||||
(bfd_vma) nlm_extended_header (abfd) -> sharedPublicsCount,
|
(bfd_vma) nlm_extended_header (abfd) -> sharedPublicsCount,
|
||||||
(bfd_byte *) thdr.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,
|
put_word (abfd,
|
||||||
(bfd_vma) nlm_extended_header (abfd) -> SharedInitializationOffset,
|
(bfd_vma) nlm_extended_header (abfd) -> SharedInitializationOffset,
|
||||||
(bfd_byte *) thdr.sharedInitializationOffset);
|
(bfd_byte *) thdr.sharedInitializationOffset);
|
||||||
@ -1026,10 +931,9 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
nlm_symbol_type *sym; /* Pointer to current bfd symbol */
|
nlm_symbol_type *sym; /* Pointer to current bfd symbol */
|
||||||
unsigned char symlength; /* Symbol length read into here */
|
unsigned char symlength; /* Symbol length read into here */
|
||||||
unsigned char symtype; /* Type of debugging symbol */
|
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 */
|
bfd_byte temp[NLM_TARGET_LONG_SIZE]; /* Symbol offsets read into here */
|
||||||
boolean (*read_reloc_func) PARAMS ((bfd *, nlm_symbol_type *, asection **,
|
boolean (*read_import_func) PARAMS ((bfd *, nlm_symbol_type *));
|
||||||
arelent *));
|
boolean (*set_public_section_func) PARAMS ((bfd *, nlm_symbol_type *));
|
||||||
|
|
||||||
if (nlm_get_symbols (abfd) != NULL)
|
if (nlm_get_symbols (abfd) != NULL)
|
||||||
return (true);
|
return (true);
|
||||||
@ -1066,6 +970,7 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
termination of the loop leaves the symcount correct for the symbols that
|
termination of the loop leaves the symcount correct for the symbols that
|
||||||
were read. */
|
were read. */
|
||||||
|
|
||||||
|
set_public_section_func = nlm_set_public_section_func (abfd);
|
||||||
symcount = i_fxdhdrp -> numberOfPublics;
|
symcount = i_fxdhdrp -> numberOfPublics;
|
||||||
while (abfd -> symcount < symcount)
|
while (abfd -> symcount < symcount)
|
||||||
{
|
{
|
||||||
@ -1083,6 +988,8 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
bfd_error = system_call_error;
|
bfd_error = system_call_error;
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
/* Cast away const. */
|
||||||
|
((char *) (sym -> symbol.name))[symlength] = '\0';
|
||||||
if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
|
if (bfd_read ((PTR) temp, sizeof (temp), 1, abfd) != sizeof (temp))
|
||||||
{
|
{
|
||||||
bfd_error = system_call_error;
|
bfd_error = system_call_error;
|
||||||
@ -1090,6 +997,15 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
}
|
}
|
||||||
sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
|
sym -> symbol.flags = BSF_GLOBAL | BSF_EXPORT;
|
||||||
sym -> symbol.value = get_word (abfd, temp);
|
sym -> symbol.value = get_word (abfd, temp);
|
||||||
|
if (set_public_section_func)
|
||||||
|
{
|
||||||
|
/* 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
|
||||||
|
{
|
||||||
if (sym -> symbol.value & NLM_HIBIT)
|
if (sym -> symbol.value & NLM_HIBIT)
|
||||||
{
|
{
|
||||||
sym -> symbol.value &= ~NLM_HIBIT;
|
sym -> symbol.value &= ~NLM_HIBIT;
|
||||||
@ -1102,6 +1018,7 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
sym -> symbol.section =
|
sym -> symbol.section =
|
||||||
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
|
bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sym -> rcnt = 0;
|
sym -> rcnt = 0;
|
||||||
abfd -> symcount++;
|
abfd -> symcount++;
|
||||||
sym++;
|
sym++;
|
||||||
@ -1137,6 +1054,8 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
bfd_error = system_call_error;
|
bfd_error = system_call_error;
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
/* Cast away const. */
|
||||||
|
((char *) (sym -> symbol.name))[symlength] = '\0';
|
||||||
sym -> symbol.flags = BSF_LOCAL;
|
sym -> symbol.flags = BSF_LOCAL;
|
||||||
sym -> symbol.value = get_word (abfd, temp);
|
sym -> symbol.value = get_word (abfd, temp);
|
||||||
if (symtype == 0)
|
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
|
/* Read in the import records. We can only do this if we know how
|
||||||
to read relocs for this target. */
|
to read relocs for this target. */
|
||||||
|
|
||||||
read_reloc_func = nlm_read_reloc_func (abfd);
|
read_import_func = nlm_read_import_func (abfd);
|
||||||
if (read_reloc_func != NULL)
|
if (read_import_func != NULL)
|
||||||
{
|
{
|
||||||
if (bfd_seek (abfd, i_fxdhdrp -> externalReferencesOffset, SEEK_SET)
|
if (bfd_seek (abfd, i_fxdhdrp -> externalReferencesOffset, SEEK_SET)
|
||||||
== -1)
|
== -1)
|
||||||
@ -1176,50 +1095,10 @@ nlm_slurp_symbol_table (abfd)
|
|||||||
symcount += i_fxdhdrp -> numberOfExternalReferences;
|
symcount += i_fxdhdrp -> numberOfExternalReferences;
|
||||||
while (abfd -> symcount < symcount)
|
while (abfd -> symcount < symcount)
|
||||||
{
|
{
|
||||||
struct nlm_relent *nlm_relocs;
|
if ((*read_import_func) (abfd, sym) == false)
|
||||||
|
|
||||||
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;
|
return false;
|
||||||
nlm_relocs -> section = section;
|
|
||||||
nlm_relocs++;
|
|
||||||
sym -> rcnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
abfd -> symcount++;
|
|
||||||
sym++;
|
sym++;
|
||||||
|
abfd->symcount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,7 +1323,7 @@ nlm_compute_section_file_positions (abfd)
|
|||||||
abfd->output_has_begun = true;
|
abfd->output_has_begun = true;
|
||||||
|
|
||||||
/* The fixed header. */
|
/* The fixed header. */
|
||||||
sofar = sizeof (Nlm_External_Fixed_Header);
|
sofar = nlm_optional_prefix_size (abfd) + nlm_fixed_header_size (abfd);
|
||||||
|
|
||||||
/* The variable header. */
|
/* The variable header. */
|
||||||
sofar += (sizeof (nlm_variable_header (abfd)->descriptionLength)
|
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
|
/* We need to sort a list of relocs associated with sections when we
|
||||||
write out the external relocs. */
|
write out the external relocs. */
|
||||||
|
|
||||||
struct reloc_and_sec
|
|
||||||
{
|
|
||||||
arelent *rel;
|
|
||||||
asection *sec;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nlm_external_reloc_compare (p1, p2)
|
nlm_external_reloc_compare (p1, p2)
|
||||||
const void *p1;
|
const void *p1;
|
||||||
@ -1694,20 +1567,23 @@ boolean
|
|||||||
nlm_write_object_contents (abfd)
|
nlm_write_object_contents (abfd)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
{
|
{
|
||||||
Nlm_External_Fixed_Header fixed_header;
|
|
||||||
asection *sec;
|
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;
|
bfd_size_type external_reloc_count, internal_reloc_count, i, c;
|
||||||
struct reloc_and_sec *external_relocs;
|
struct reloc_and_sec *external_relocs;
|
||||||
asymbol **sym_ptr_ptr;
|
asymbol **sym_ptr_ptr;
|
||||||
file_ptr last;
|
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
|
if (abfd->output_has_begun == false
|
||||||
&& nlm_compute_section_file_positions (abfd) == false)
|
&& nlm_compute_section_file_positions (abfd) == false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Write out the variable length headers. */
|
/* 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;
|
bfd_error = system_call_error;
|
||||||
return false;
|
return false;
|
||||||
@ -1738,7 +1614,7 @@ nlm_write_object_contents (abfd)
|
|||||||
/* The format of the relocation entries is dependent upon the
|
/* The format of the relocation entries is dependent upon the
|
||||||
particular target. We use an external routine to write the reloc
|
particular target. We use an external routine to write the reloc
|
||||||
out. */
|
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
|
/* Write out the internal relocation fixups. While we're looping
|
||||||
over the relocs, we also count the external relocs, which is
|
over the relocs, we also count the external relocs, which is
|
||||||
@ -1753,15 +1629,12 @@ nlm_write_object_contents (abfd)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We can only represent relocs within a code or data
|
/* 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)
|
if ((bfd_get_section_flags (abfd, sec) & (SEC_CODE | SEC_DATA)) == 0)
|
||||||
{
|
continue;
|
||||||
bfd_error = invalid_operation;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need to know how to write out relocs. */
|
/* We need to know how to write out imports */
|
||||||
if (write_reloc_func == NULL)
|
if (write_import_func == NULL)
|
||||||
{
|
{
|
||||||
bfd_error = invalid_operation;
|
bfd_error = invalid_operation;
|
||||||
return false;
|
return false;
|
||||||
@ -1780,7 +1653,7 @@ nlm_write_object_contents (abfd)
|
|||||||
if (bfd_get_section (sym) != &bfd_und_section)
|
if (bfd_get_section (sym) != &bfd_und_section)
|
||||||
{
|
{
|
||||||
++internal_reloc_count;
|
++internal_reloc_count;
|
||||||
if ((*write_reloc_func) (abfd, sec, rel) == false)
|
if ((*write_import_func) (abfd, sec, rel) == false)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1843,24 +1716,13 @@ nlm_write_object_contents (abfd)
|
|||||||
{
|
{
|
||||||
arelent *rel;
|
arelent *rel;
|
||||||
asymbol *sym;
|
asymbol *sym;
|
||||||
bfd_byte len;
|
|
||||||
bfd_size_type j, cnt;
|
bfd_size_type j, cnt;
|
||||||
bfd_byte temp[NLM_TARGET_LONG_SIZE];
|
|
||||||
|
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
rel = external_relocs[i].rel;
|
rel = external_relocs[i].rel;
|
||||||
sym = *rel->sym_ptr_ptr;
|
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;
|
cnt = 0;
|
||||||
for (j = i;
|
for (j = i;
|
||||||
(j < external_reloc_count
|
(j < external_reloc_count
|
||||||
@ -1868,30 +1730,25 @@ nlm_write_object_contents (abfd)
|
|||||||
j++)
|
j++)
|
||||||
++cnt;
|
++cnt;
|
||||||
|
|
||||||
put_word (abfd, (bfd_vma) cnt, temp);
|
if ((*nlm_write_external_func (abfd)) (abfd, cnt, sym,
|
||||||
if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
|
&external_relocs[i])
|
||||||
{
|
== false)
|
||||||
bfd_error = system_call_error;
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
i += cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (cnt-- != 0)
|
|
||||||
{
|
|
||||||
if ((*write_reloc_func) (abfd, external_relocs[i].sec,
|
|
||||||
external_relocs[i].rel) == false)
|
|
||||||
return false;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nlm_fixed_header (abfd)->numberOfExternalReferences = c;
|
nlm_fixed_header (abfd)->numberOfExternalReferences = c;
|
||||||
|
|
||||||
/* Write out the public symbols (exports). */
|
/* Write out the public symbols (exports). */
|
||||||
sym_ptr_ptr = bfd_get_outsymbols (abfd);
|
sym_ptr_ptr = bfd_get_outsymbols (abfd);
|
||||||
if (sym_ptr_ptr != (asymbol **) NULL)
|
if (sym_ptr_ptr != (asymbol **) NULL)
|
||||||
{
|
{
|
||||||
|
bfd_vma (*get_public_offset_func) PARAMS ((bfd *, asymbol *));
|
||||||
asymbol **sym_end;
|
asymbol **sym_end;
|
||||||
|
|
||||||
nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
|
nlm_fixed_header (abfd)->publicsOffset = bfd_tell (abfd);
|
||||||
|
get_public_offset_func = nlm_get_public_offset_func (abfd);
|
||||||
c = 0;
|
c = 0;
|
||||||
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
|
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
|
||||||
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
|
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
|
||||||
@ -1918,6 +1775,14 @@ nlm_write_object_contents (abfd)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get_public_offset_func)
|
||||||
|
{
|
||||||
|
/* Most backends can use the code below, but
|
||||||
|
unfortunately some use a different scheme. */
|
||||||
|
offset = (*get_public_offset_func) (abfd, sym);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
offset = bfd_asymbol_value (sym);
|
offset = bfd_asymbol_value (sym);
|
||||||
sec = sym->section;
|
sec = sym->section;
|
||||||
if (sec->flags & SEC_CODE)
|
if (sec->flags & SEC_CODE)
|
||||||
@ -1932,11 +1797,12 @@ nlm_write_object_contents (abfd)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We can't handle an exported symbol that is not in the
|
/* We can't handle an exported symbol that is not in
|
||||||
code or data segment. */
|
the code or data segment. */
|
||||||
bfd_error = invalid_operation;
|
bfd_error = invalid_operation;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
put_word (abfd, offset, temp);
|
put_word (abfd, offset, temp);
|
||||||
if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
|
if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
|
||||||
@ -1983,17 +1849,16 @@ nlm_write_object_contents (abfd)
|
|||||||
|
|
||||||
++c;
|
++c;
|
||||||
|
|
||||||
offset = bfd_asymbol_value (sym);
|
offset = sym->value;
|
||||||
sec = sym->section;
|
sec = sym->section;
|
||||||
if (sec->flags & SEC_CODE)
|
if (sec->flags & SEC_CODE)
|
||||||
{
|
|
||||||
offset -= nlm_get_text_low (abfd);
|
|
||||||
type = 1;
|
type = 1;
|
||||||
}
|
else if (sec->flags & SEC_DATA)
|
||||||
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
|
|
||||||
{
|
|
||||||
offset -= nlm_get_data_low (abfd);
|
|
||||||
type = 0;
|
type = 0;
|
||||||
|
else if (sec->flags & SEC_ALLOC)
|
||||||
|
{
|
||||||
|
type = 0;
|
||||||
|
offset += nlm_fixed_header (abfd)->dataImageSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
type = 2;
|
type = 2;
|
||||||
@ -2048,7 +1913,7 @@ nlm_write_object_contents (abfd)
|
|||||||
|
|
||||||
/* At this point everything has been written out except the fixed
|
/* At this point everything has been written out except the fixed
|
||||||
header. */
|
header. */
|
||||||
memcpy (nlm_fixed_header (abfd)->signature, NLM_SIGNATURE,
|
memcpy (nlm_fixed_header (abfd)->signature, nlm_signature (abfd),
|
||||||
NLM_SIGNATURE_SIZE);
|
NLM_SIGNATURE_SIZE);
|
||||||
nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
|
nlm_fixed_header (abfd)->version = NLM_HEADER_VERSION;
|
||||||
nlm_fixed_header (abfd)->codeStartOffset =
|
nlm_fixed_header (abfd)->codeStartOffset =
|
||||||
@ -2063,10 +1928,21 @@ nlm_write_object_contents (abfd)
|
|||||||
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
|
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
|
||||||
nlm_get_text_low (abfd);
|
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)
|
||||||
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
return false;
|
||||||
|| (bfd_write (&fixed_header, sizeof fixed_header, 1, abfd)
|
|
||||||
!= sizeof fixed_header))
|
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;
|
bfd_error = system_call_error;
|
||||||
return false;
|
return false;
|
||||||
|
Reference in New Issue
Block a user