* libnlm.h (nlm_backend_data): Added nlm_mangle_relocs.

(nlm_mangle_relocs_func): New macro.
	* nlm32-i386.c (nlm_i386_write_reloc): Rewrote correctly.
	(nlm_i386_mangle_relocs): New function.
	* nlmcode.h (nlm_compute_section_file_positions): Move all common
	symbols into the .bss section.
	(nlm_set_section_contents): Call the mangle_relocs function.
	(nlm_write_object_contents): Treat a reloc against any defined
	symbol as an internal reloc.  Fix bug in external reloc counting.
	Get the offset and debugging type right for .bss symbols.  Only
	output debugging symbols for defined symbols.
This commit is contained in:
Ian Lance Taylor 1993-08-04 20:25:53 +00:00
parent cdbcb08c10
commit 7389debf1c
4 changed files with 565 additions and 52 deletions

View File

@ -1,5 +1,17 @@
Wed Aug 4 08:33:55 1993 Ian Lance Taylor (ian@cygnus.com)
* libnlm.h (nlm_backend_data): Added nlm_mangle_relocs.
(nlm_mangle_relocs_func): New macro.
* nlm32-i386.c (nlm_i386_write_reloc): Rewrote correctly.
(nlm_i386_mangle_relocs): New function.
* nlmcode.h (nlm_compute_section_file_positions): Move all common
symbols into the .bss section.
(nlm_set_section_contents): Call the mangle_relocs function.
(nlm_write_object_contents): Treat a reloc against any defined
symbol as an internal reloc. Fix bug in external reloc counting.
Get the offset and debugging type right for .bss symbols. Only
output debugging symbols for defined symbols.
* coff-h8500.c (rtype2howto): Do an fprintf to stderr rather than
using printf.
* coff-z8k.c (rtype2howto): Likewise.

View File

@ -21,52 +21,63 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _LIBNLM_H_
#define _LIBNLM_H_ 1
#ifdef ARCH_SIZE
# define NLM_ARCH_SIZE ARCH_SIZE
#endif
#include "nlm/common.h"
#include "nlm/internal.h"
#include "nlm/external.h"
/* If size isn't specified as 64 or 32, NAME macro should fail. */
#ifndef NAME
# if ARCH_SIZE==64
# define NAME(x,y) CAT4(x,64,_,y)
# endif
# if ARCH_SIZE==32
# define NAME(x,y) CAT4(x,32,_,y)
# endif
#endif
/* A reloc for an imported NLM symbol. Normal relocs are associated
with sections, and include a symbol. These relocs are associated
with (undefined) symbols, and include a section. */
#define NlmNAME(X) NAME(Nlm,X)
#define nlmNAME(X) NAME(nlm,X)
struct nlm_relent
{
/* Section of reloc. */
asection *section;
/* Reloc info (sym_ptr_ptr field set only when canonicalized). */
arelent reloc;
};
/* Information we keep for an NLM symbol. */
typedef struct
{
/* BFD symbol. */
asymbol symbol;
} nlm32_symbol_type;
/* Number of reloc entries for imported symbol. */
bfd_size_type rcnt;
/* Array of reloc information for imported symbol. */
struct nlm_relent *relocs;
} nlmNAME(symbol_type);
typedef struct
{
asymbol symbol;
} nlm64_symbol_type;
extern boolean nlm_mkobject PARAMS ((bfd *));
extern boolean nlm_set_arch_mach PARAMS ((bfd *, enum bfd_architecture,
unsigned long));
#define bfd_nlm32_mkobject bfd_nlm_mkobject
#define bfd_nlm64_mkobject bfd_nlm_mkobject
#define nlm_mkobject bfd_nlm_mkobject
extern boolean bfd_nlm_mkobject PARAMS ((bfd *));
extern void bfd_nlm32_get_symbol_info
PARAMS ((bfd *, asymbol *, symbol_info *));
extern unsigned int bfd_nlm32_get_symtab_upper_bound PARAMS ((bfd *));
extern unsigned int bfd_nlm64_get_symtab_upper_bound PARAMS ((bfd *));
extern unsigned int bfd_nlm32_get_symtab PARAMS ((bfd *, asymbol **));
extern unsigned int bfd_nlm64_get_symtab PARAMS ((bfd *, asymbol **));
extern asymbol *bfd_nlm32_make_empty_symbol PARAMS ((bfd *));
extern asymbol *bfd_nlm64_make_empty_symbol PARAMS ((bfd *));
extern bfd_target *bfd_nlm32_object_p PARAMS ((bfd *));
extern bfd_target *bfd_nlm64_object_p PARAMS ((bfd *));
extern boolean bfd_nlm32_set_arch_mach
PARAMS ((bfd *, enum bfd_architecture, unsigned long));
extern boolean bfd_nlm64_set_arch_mach
PARAMS ((bfd *, enum bfd_architecture, unsigned long));
extern void nlmNAME(get_symbol_info)
PARAMS ((bfd *, asymbol *, symbol_info *));
extern unsigned int nlmNAME(get_symtab_upper_bound)
PARAMS ((bfd *));
extern unsigned int nlmNAME(get_symtab)
PARAMS ((bfd *, asymbol **));
extern asymbol *nlmNAME(make_empty_symbol)
PARAMS ((bfd *));
extern void nlmNAME(print_symbol)
PARAMS ((bfd *, PTR, asymbol *, bfd_print_symbol_type));
extern unsigned int nlmNAME(get_reloc_upper_bound)
PARAMS ((bfd *, asection *));
extern unsigned int nlmNAME(canonicalize_reloc)
PARAMS ((bfd *, asection *, arelent **, asymbol **));
extern bfd_target *nlmNAME(object_p)
PARAMS ((bfd *));
extern boolean nlmNAME(set_arch_mach)
PARAMS ((bfd *, enum bfd_architecture, unsigned long));
extern boolean nlmNAME(set_section_contents)
PARAMS ((bfd *, asection *, PTR, file_ptr, bfd_size_type));
extern boolean nlmNAME(write_object_contents)
PARAMS ((bfd *));
/* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. */
@ -80,6 +91,14 @@ struct nlm_obj_tdata
Nlm_Internal_Copyright_Header nlm_copyright_hdr[1];
Nlm_Internal_Extended_Header nlm_extended_hdr[1];
Nlm_Internal_Custom_Header nlm_custom_hdr[1];
/* BFD NLM symbols. */
nlmNAME(symbol_type) *nlm_symbols;
/* Lowest text and data VMA values. */
bfd_vma nlm_text_low;
bfd_vma nlm_data_low;
/* Caches for data read from object file. */
arelent * nlm_reloc_fixups;
asection ** nlm_reloc_fixup_secs;
};
#define nlm_tdata(bfd) ((bfd) -> tdata.nlm_obj_data)
@ -89,6 +108,51 @@ struct nlm_obj_tdata
#define nlm_copyright_header(bfd) (nlm_tdata(bfd) -> nlm_copyright_hdr)
#define nlm_extended_header(bfd) (nlm_tdata(bfd) -> nlm_extended_hdr)
#define nlm_custom_header(bfd) (nlm_tdata(bfd) -> nlm_custom_hdr)
#define nlm_get_symbols(bfd) (nlm_tdata(bfd) -> nlm_symbols)
#define nlm_set_symbols(bfd, p) (nlm_tdata(bfd) -> nlm_symbols = (p))
#define nlm_set_text_low(bfd, i) (nlm_tdata(bfd) -> nlm_text_low = (i))
#define nlm_get_text_low(bfd) (nlm_tdata(bfd) -> nlm_text_low)
#define nlm_set_data_low(bfd, i) (nlm_tdata(bfd) -> nlm_data_low = (i))
#define nlm_get_data_low(bfd) (nlm_tdata(bfd) -> nlm_data_low)
#define nlm_relocation_fixups(bfd) (nlm_tdata(bfd) -> nlm_reloc_fixups)
#define nlm_relocation_fixup_secs(bfd) (nlm_tdata(bfd)->nlm_reloc_fixup_secs)
/* 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. */
enum bfd_architecture arch;
/* 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
should set the third argument to the section which the reloc
belongs in, and the fourth argument to the reloc itself; it does
not need to fill in the sym_ptr_ptr field for a reloc against an
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));
};
#define nlm_backend(bfd) \
((struct nlm_backend_data *)((bfd) -> xvec -> backend_data))
#define nlm_architecture(bfd) \
(nlm_backend(bfd) ? nlm_backend(bfd) -> arch : bfd_arch_unknown)
#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)
/* 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

354
bfd/nlm32-i386.c Normal file
View File

@ -0,0 +1,354 @@
/* Support for 32-bit i386 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 "libnlm.h"
static boolean nlm_i386_read_reloc
PARAMS ((bfd *, nlmNAME(symbol_type) *, asection **, arelent *));
static boolean nlm_i386_write_reloc
PARAMS ((bfd *, asection *, arelent *));
static boolean nlm_i386_mangle_relocs
PARAMS ((bfd *, asection *, PTR, bfd_vma, bfd_size_type));
/* Adjust the reloc location by an absolute value. */
static reloc_howto_type nlm_i386_abs_howto =
HOWTO (0, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_bitfield, /* complain_on_overflow */
0, /* special_function */
"32", /* name */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
false); /* pcrel_offset */
/* Adjust the reloc location by a PC relative displacement. */
static reloc_howto_type nlm_i386_pcrel_howto =
HOWTO (1, /* type */
0, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
0, /* special_function */
"DISP32", /* name */
true, /* partial_inplace */
0xffffffff, /* src_mask */
0xffffffff, /* dst_mask */
true); /* pcrel_offset */
/* Read a NetWare i386 reloc. */
static boolean
nlm_i386_read_reloc (abfd, sym, secp, rel)
bfd *abfd;
nlmNAME(symbol_type) *sym;
asection **secp;
arelent *rel;
{
bfd_byte temp[4];
bfd_vma val;
const char *name;
if (bfd_read (temp, sizeof (temp), 1, abfd) != sizeof (temp))
{
bfd_error = system_call_error;
return false;
}
val = bfd_get_32 (abfd, temp);
/* The value is an offset into either the code or data segment.
This is the location which needs to be adjusted.
If this is a relocation fixup rather than an imported symbol (the
sym argument is NULL) then the high bit is 0 if the location
needs to be adjusted by the address of the data segment, or 1 if
the location needs to be adjusted by the address of the code
segment. If this is an imported symbol, then the high bit is 0
if the location is 0 if the location should be adjusted by the
offset to the symbol, or 1 if the location should adjusted by the
absolute value of the symbol.
The second most significant bit is 0 if the value is an offset
into the data segment, or 1 if the value is an offset into the
code segment.
All this translates fairly easily into a BFD reloc. */
if (sym == NULL)
{
if ((val & NLM_HIBIT) == 0)
name = NLM_INITIALIZED_DATA_NAME;
else
{
name = NLM_CODE_NAME;
val &=~ NLM_HIBIT;
}
rel->sym_ptr_ptr = bfd_get_section_by_name (abfd, name)->symbol_ptr_ptr;
rel->howto = &nlm_i386_abs_howto;
}
else
{
/* In this case we do not need to set the sym_ptr_ptr field. */
rel->sym_ptr_ptr = NULL;
if ((val & NLM_HIBIT) == 0)
rel->howto = &nlm_i386_pcrel_howto;
else
{
rel->howto = &nlm_i386_abs_howto;
val &=~ NLM_HIBIT;
}
}
if ((val & (NLM_HIBIT >> 1)) == 0)
*secp = bfd_get_section_by_name (abfd, NLM_INITIALIZED_DATA_NAME);
else
{
*secp = bfd_get_section_by_name (abfd, NLM_CODE_NAME);
val &=~ (NLM_HIBIT >> 1);
}
rel->address = val;
rel->addend = 0;
return true;
}
/* Write a NetWare i386 reloc. */
static boolean
nlm_i386_write_reloc (abfd, sec, rel)
bfd *abfd;
asection *sec;
arelent *rel;
{
asymbol *sym;
bfd_vma val;
bfd_byte temp[4];
/* NetWare only supports two kinds of relocs. We should check
special_function here, as well, but at the moment coff-i386
relocs uses a special_function which does not affect what we do
here. */
if (rel->addend != 0
|| rel->howto == NULL
|| rel->howto->rightshift != 0
|| rel->howto->size != 2
|| rel->howto->bitsize != 32
|| rel->howto->bitpos != 0
|| ! rel->howto->partial_inplace
|| rel->howto->src_mask != 0xffffffff
|| rel->howto->dst_mask != 0xffffffff)
{
bfd_error = invalid_operation;
return false;
}
sym = *rel->sym_ptr_ptr;
/* 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;
/* The second most significant bit is 0 if the value is an offset
into the data segment, or 1 if the value is an offset into the
code segment. */
if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
{
val -= nlm_get_text_low (abfd);
val |= NLM_HIBIT >> 1;
}
else
val -= nlm_get_data_low (abfd);
if (bfd_get_section (sym) != &bfd_und_section)
{
/* NetWare only supports absolute internal relocs. */
if (rel->howto->pc_relative)
{
bfd_error = invalid_operation;
return false;
}
/* The high bit is 1 if the reloc is against the code section, 0
if against the data section. */
if (bfd_get_section_flags (abfd, bfd_get_section (sym)) & SEC_CODE)
val |= NLM_HIBIT;
}
else
{
/* The high bit is 1 if this is an absolute reloc, 0 if it is PC
relative. */
if (! rel->howto->pc_relative)
val |= NLM_HIBIT;
else
{
/* PC relative relocs on NetWare must be pcrel_offset. */
if (! rel->howto->pcrel_offset)
{
bfd_error = invalid_operation;
return false;
}
}
}
bfd_put_32 (abfd, val, temp);
if (bfd_write (temp, sizeof (temp), 1, abfd) != sizeof (temp))
{
bfd_error = system_call_error;
return false;
}
return true;
}
/* I want to be able to use objcopy to turn a i386 a.out or COFF file
into a NetWare i386 module. That means that the relocs from the
source file have to be mapped into relocs that apply to the target
file. This function is called by nlm_set_section_contents to give
it a chance to rework the relocs.
This is actually a fairly general concept. However, this is not a
general implementation. */
static boolean
nlm_i386_mangle_relocs (abfd, sec, data, offset, count)
bfd *abfd;
asection *sec;
PTR data;
bfd_vma offset;
bfd_size_type count;
{
arelent **rel_ptr_ptr, **rel_end;
rel_ptr_ptr = sec->orelocation;
rel_end = rel_ptr_ptr + sec->reloc_count;
for (; rel_ptr_ptr < rel_end; rel_ptr_ptr++)
{
arelent *rel;
asymbol *sym;
bfd_vma addend;
rel = *rel_ptr_ptr;
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. */
/* Make sure this reloc is within the data we have. We only 4
byte relocs here, so we insist on having 4 bytes. */
if (rel->address < offset
|| rel->address + 4 > offset + count)
continue;
/* NetWare doesn't support reloc addends, so we get rid of them
here by simply adding them into the object data. We handle
the symbol value, if any, the same way. */
addend = rel->addend + sym->value;
/* The value of a symbol is the offset into the section. If the
symbol is in the .bss segment, we need to include the size of
the data segment in the offset as well. Fortunately, we know
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)
&& ((bfd_get_section_flags (abfd, bfd_get_section (sym))
& SEC_ALLOC) != 0))
addend += nlm_fixed_header (abfd)->dataImageSize;
if (addend != 0
&& rel->howto != NULL
&& rel->howto->rightshift == 0
&& rel->howto->size == 2
&& rel->howto->bitsize == 32
&& rel->howto->bitpos == 0
&& rel->howto->partial_inplace
&& rel->howto->src_mask == 0xffffffff
&& rel->howto->dst_mask == 0xffffffff)
{
bfd_vma val;
val = bfd_get_32 (abfd, (char *) data + rel->address - offset);
val += addend;
bfd_put_32 (abfd, val, (char *) data + rel->address - offset);
rel->addend = 0;
}
/* NetWare uses a reloc with pcrel_offset set. We adjust
pc_relative relocs accordingly. We are going to change the
howto field, so we can only do this if the current one is
compatible. We should check special_function here, but at
the moment coff-i386 uses a special_function which does not
affect what we are doing here. */
if (rel->howto != NULL
&& rel->howto->pc_relative
&& ! rel->howto->pcrel_offset
&& rel->howto->rightshift == 0
&& rel->howto->size == 2
&& rel->howto->bitsize == 32
&& rel->howto->bitpos == 0
&& rel->howto->partial_inplace
&& rel->howto->src_mask == 0xffffffff
&& rel->howto->dst_mask == 0xffffffff)
{
bfd_vma val;
/* 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 += rel->address;
bfd_put_32 (abfd, val, (char *) data + rel->address - offset);
rel->howto = &nlm_i386_pcrel_howto;
}
}
return true;
}
static const struct nlm_backend_data nlm32_i386_backend =
{
bfd_arch_i386,
nlm_i386_read_reloc,
nlm_i386_write_reloc,
nlm_i386_mangle_relocs
};
#define TARGET_LITTLE_NAME "nlm32-i386"
#define TARGET_LITTLE_SYM nlmNAME(i386_vec)
#define TARGET_BACKEND_DATA &nlm32_i386_backend
#include "nlm-target.h"

View File

@ -1337,7 +1337,14 @@ nlm_canonicalize_reloc (abfd, sec, relptr, symbols)
no way to check this.
This routine also sets the Size and Offset fields in the fixed
header. */
header.
It also looks over the symbols and moves any common symbols into
the .bss section; NLM has no way to represent a common symbol.
This approach means that either the symbols must already have been
set at this point, or there must be no common symbols. We need to
move the symbols at this point so that mangle_relocs can see the
final values. */
static boolean
nlm_compute_section_file_positions (abfd)
@ -1349,6 +1356,7 @@ nlm_compute_section_file_positions (abfd)
bfd_vma text_low, data_low;
int text_align, data_align, other_align;
file_ptr text_ptr, data_ptr, other_ptr;
asymbol **sym_ptr_ptr;
if (abfd->output_has_begun == true)
return true;
@ -1469,6 +1477,53 @@ nlm_compute_section_file_positions (abfd)
nlm_fixed_header (abfd)->relocationFixupOffset = other_ptr;
/* Move all common symbols into the .bss section. */
sym_ptr_ptr = bfd_get_outsymbols (abfd);
if (sym_ptr_ptr != NULL)
{
asymbol **sym_end;
asection *bss_sec;
bfd_vma add;
/* Make sure we have a section to hold uninitialized data. */
bss_sec = bfd_get_section_by_name (abfd, NLM_UNINITIALIZED_DATA_NAME);
if (bss_sec == NULL)
{
if (! add_bfd_section (abfd, NLM_UNINITIALIZED_DATA_NAME,
(file_ptr) 0, (bfd_size_type) 0,
SEC_ALLOC))
return false;
bss_sec = bfd_get_section_by_name (abfd,
NLM_UNINITIALIZED_DATA_NAME);
bss_sec->vma = data_low + data;
}
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
add = 0;
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
{
asymbol *sym;
bfd_vma size;
sym = *sym_ptr_ptr;
if (! bfd_is_com_section (bfd_get_section (sym)))
continue;
/* Put the common symbol in the .bss section, and increase
the size of the .bss section by the size of the common
symbol (which is the old value of the symbol). */
sym->section = bss_sec;
size = sym->value;
sym->value = bss_sec->_raw_size + add;
add += size;
add = BFD_ALIGN (add, 1 << bss_sec->alignment_power);
}
nlm_fixed_header (abfd)->uninitializedDataSize += add;
bss_sec->_raw_size += add;
}
return true;
}
@ -1492,6 +1547,25 @@ nlm_set_section_contents (abfd, section, location, offset, count)
if (count == 0)
return true;
/* i386 NetWare has a very restricted set of relocs. In order for
objcopy to work, the NLM i386 backend needs a chance to rework
the section contents so that its set of relocs will work. If all
the relocs are already acceptable, this will not do anything. */
if (section->reloc_count != 0)
{
boolean (*mangle_relocs_func) PARAMS ((bfd *, asection *, PTR data,
bfd_vma offset,
bfd_size_type count));
mangle_relocs_func = nlm_mangle_relocs_func (abfd);
if (mangle_relocs_func != NULL)
{
if (! (*mangle_relocs_func) (abfd, section, location,
(bfd_vma) offset, count))
return false;
}
}
if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) != 0
|| bfd_write (location, 1, count, abfd) != count)
{
@ -1637,7 +1711,7 @@ nlm_write_object_contents (abfd)
rel = *rel_ptr_ptr;
sym = *rel->sym_ptr_ptr;
if ((sym->flags & BSF_SECTION_SYM) != 0)
if (bfd_get_section (sym) != &bfd_und_section)
{
++internal_reloc_count;
if ((*write_reloc_func) (abfd, sec, rel) == false)
@ -1680,7 +1754,7 @@ nlm_write_object_contents (abfd)
rel = *rel_ptr_ptr;
sym = *rel->sym_ptr_ptr;
if ((sym->flags & BSF_SECTION_SYM) != 0)
if (bfd_get_section (sym) != &bfd_und_section)
continue;
external_relocs[i].rel = rel;
@ -1704,7 +1778,7 @@ nlm_write_object_contents (abfd)
arelent *rel;
asymbol *sym;
bfd_byte len;
bfd_size_type cnt;
bfd_size_type j, cnt;
bfd_byte temp[NLM_TARGET_LONG_SIZE];
++c;
@ -1722,8 +1796,10 @@ nlm_write_object_contents (abfd)
}
cnt = 0;
while (i < external_reloc_count
&& *external_relocs[i].rel->sym_ptr_ptr == sym)
for (j = i;
(j < external_reloc_count
&& *external_relocs[j].rel->sym_ptr_ptr == sym);
j++)
++cnt;
put_word (abfd, (bfd_vma) cnt, temp);
@ -1762,7 +1838,8 @@ nlm_write_object_contents (abfd)
sym = *sym_ptr_ptr;
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0)
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) == 0
|| bfd_get_section (sym) == &bfd_und_section)
continue;
++c;
@ -1783,8 +1860,9 @@ nlm_write_object_contents (abfd)
offset -= nlm_get_text_low (abfd);
offset |= NLM_HIBIT;
}
else if (sec->flags & SEC_DATA)
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
{
/* SEC_ALLOC is for the .bss section. */
offset -= nlm_get_data_low (abfd);
}
else
@ -1806,6 +1884,7 @@ nlm_write_object_contents (abfd)
nlm_fixed_header (abfd)->debugInfoOffset = bfd_tell (abfd);
c = 0;
sym_ptr_ptr = bfd_get_outsymbols (abfd);
sym_end = sym_ptr_ptr + bfd_get_symcount (abfd);
for (; sym_ptr_ptr < sym_end; sym_ptr_ptr++)
{
@ -1817,6 +1896,14 @@ nlm_write_object_contents (abfd)
sym = *sym_ptr_ptr;
/* The NLM notion of a debugging symbol is actually what BFD
calls a local or global symbol. What BFD calls a
debugging symbol NLM does not understand at all. */
if ((sym->flags & (BSF_LOCAL | BSF_GLOBAL | BSF_EXPORT)) == 0
|| (sym->flags & BSF_DEBUGGING) != 0
|| bfd_get_section (sym) == &bfd_und_section)
continue;
++c;
offset = bfd_asymbol_value (sym);
@ -1826,15 +1913,15 @@ nlm_write_object_contents (abfd)
offset -= nlm_get_text_low (abfd);
type = 1;
}
else if (sec->flags & SEC_DATA)
else if (sec->flags & (SEC_DATA | SEC_ALLOC))
{
offset -= nlm_get_data_low (abfd);
type = 0;
}
else
type = 3;
type = 2;
/* The type is 0 for data, 1 for code, 3 for absolute. */
/* The type is 0 for data, 1 for code, 2 for absolute. */
if (bfd_write (&type, sizeof (bfd_byte), 1, abfd)
!= sizeof (bfd_byte))
{
@ -1905,12 +1992,8 @@ nlm_write_object_contents (abfd)
/* We have no convenient way for the caller to pass in the exit
procedure or the check unload procedure, so the caller must set
the values in the header to the values of the symbols. */
if (nlm_fixed_header (abfd)->exitProcedureOffset == 0)
{
bfd_error = invalid_operation;
return false;
}
nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
if (nlm_fixed_header (abfd)->exitProcedureOffset != 0)
nlm_fixed_header (abfd)->exitProcedureOffset -= nlm_get_text_low (abfd);
if (nlm_fixed_header (abfd)->checkUnloadProcedureOffset != 0)
nlm_fixed_header (abfd)->checkUnloadProcedureOffset -=
nlm_get_text_low (abfd);