Distinguish a weak defined symbol from a regular defined symbol.

* linker.c (enum link_action): Add DEFW.
	(link_action): Add bfd_link_hash_defweak column.
	(_bfd_generic_link_add_one_symbol): Add DEFW case.  Handle
	bfd_link_hash_defweak in a few other cases.
	* Many files (bfd_link_hash_undefweak): Renamed from
	bfd_link_hash_weak.
	* aoutx.h (aout_link_write_symbols): Handle bfd_link_hash_defweak.
	(aout_link_write_other_symbol): Likewise.
	(aout_link_input_section_std): Likewise.
	(aout_link_input_section_ext): Likewise.
	* bout.c (get_value): Likewise.
	* coff-a29k.c (coff_a29k_relocate_section): Likewise.
	* coff-alpha.c (alpha_convert_external_reloc): Likewise.
	(alpha_relocate_section): Likewise.
	* coff-mips.c (mips_relocate_section): Likewise.
	(mips_relax_section): Likewise.
	(bfd_mips_ecoff_create_embedded_relocs): Likewise.
	* cofflink.c (coff_write_global_sym): Likewise.
	(_bfd_coff_generic_relocate_section): Likewise.
	* ecoff.c (ecoff_link_add_externals): Likewise.
	(ecoff_link_write_external): LIkewise.
	* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
	(elf32_hppa_size_stubs): Likewise.
	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
	(elf_i386_relocate_section): Likewise.
	(elf_i386_finish_dynamic_symbol): Likewise.
	* elf32-mips.c (mips_elf_output_extsym): Likewise.
	(mips_elf_relocate_section): Likewise.
	* elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
	(elf32_sparc_relocate_section): Likewise.
	* elfcode.h (elf_link_add_object_symbols): Likewise.
	(elf_adjust_dynamic_symbol): Likewise.
	(elf_bfd_final_link): Likewise.
	(elf_link_output_extsym): Likewise.
	* i386linux.c (linux_add_one_symbol): Likewise.
	(linux_tally_symbols): Likewise.
	(linux_finish_dynamic_link): Likewise.
	* linker.c (_bfd_generic_link_output_symbols): Likewise.
	(set_symbol_from_hash): Likewise.
	* reloc16.c (bfd_coff_reloc16_get_value): Likewise.
	(bfd_perform_slip): Likewise.
	* sunos.c (sunos_add_one_symbol): Likewise.
	(sunos_scan_std_relocs): Likewise.
	(sunos_scan_ext_relocs): Likewise.
	(sunos_scan_dynamic_symbol): Likewise.
	(sunos_write_dynamic_symbol): Likewise.
This commit is contained in:
Ian Lance Taylor 1995-02-06 20:01:08 +00:00
parent ebc4ca90f9
commit 6c97aedf26
9 changed files with 423 additions and 177 deletions

View File

@ -1,3 +1,53 @@
Mon Feb 6 14:25:24 1995 Ian Lance Taylor <ian@cygnus.com>
Distinguish a weak defined symbol from a regular defined symbol.
* linker.c (enum link_action): Add DEFW.
(link_action): Add bfd_link_hash_defweak column.
(_bfd_generic_link_add_one_symbol): Add DEFW case. Handle
bfd_link_hash_defweak in a few other cases.
* Many files (bfd_link_hash_undefweak): Renamed from
bfd_link_hash_weak.
* aoutx.h (aout_link_write_symbols): Handle bfd_link_hash_defweak.
(aout_link_write_other_symbol): Likewise.
(aout_link_input_section_std): Likewise.
(aout_link_input_section_ext): Likewise.
* bout.c (get_value): Likewise.
* coff-a29k.c (coff_a29k_relocate_section): Likewise.
* coff-alpha.c (alpha_convert_external_reloc): Likewise.
(alpha_relocate_section): Likewise.
* coff-mips.c (mips_relocate_section): Likewise.
(mips_relax_section): Likewise.
(bfd_mips_ecoff_create_embedded_relocs): Likewise.
* cofflink.c (coff_write_global_sym): Likewise.
(_bfd_coff_generic_relocate_section): Likewise.
* ecoff.c (ecoff_link_add_externals): Likewise.
(ecoff_link_write_external): LIkewise.
* elf32-hppa.c (elf32_hppa_relocate_section): Likewise.
(elf32_hppa_size_stubs): Likewise.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Likewise.
(elf_i386_relocate_section): Likewise.
(elf_i386_finish_dynamic_symbol): Likewise.
* elf32-mips.c (mips_elf_output_extsym): Likewise.
(mips_elf_relocate_section): Likewise.
* elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
(elf32_sparc_relocate_section): Likewise.
* elfcode.h (elf_link_add_object_symbols): Likewise.
(elf_adjust_dynamic_symbol): Likewise.
(elf_bfd_final_link): Likewise.
(elf_link_output_extsym): Likewise.
* i386linux.c (linux_add_one_symbol): Likewise.
(linux_tally_symbols): Likewise.
(linux_finish_dynamic_link): Likewise.
* linker.c (_bfd_generic_link_output_symbols): Likewise.
(set_symbol_from_hash): Likewise.
* reloc16.c (bfd_coff_reloc16_get_value): Likewise.
(bfd_perform_slip): Likewise.
* sunos.c (sunos_add_one_symbol): Likewise.
(sunos_scan_std_relocs): Likewise.
(sunos_scan_ext_relocs): Likewise.
(sunos_scan_dynamic_symbol): Likewise.
(sunos_write_dynamic_symbol): Likewise.
Mon Feb 6 03:20:17 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
Changes from Bryan Ford, baford@schirf.cs.utah.edu:

View File

@ -562,35 +562,33 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
result = (*callback_to_real_object_p)(abfd);
#ifdef STAT_FOR_EXEC
/* The original heuristic doesn't work in some important cases. The
* a.out file has no information about the text start address. For
* files (like kernels) linked to non-standard addresses (ld -Ttext
* nnn) the entry point may not be between the default text start
* (obj_textsec(abfd)->vma) and (obj_textsec(abfd)->vma) + text size
* This is not just a mach issue. Many kernels are loaded at non
* standard addresses.
*/
{
struct stat stat_buf;
if (abfd->iostream
&& (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
&& ((stat_buf.st_mode & 0111) != 0))
abfd->flags |= EXEC_P;
}
#else /* ! defined (STAT_FOR_EXEC) */
/* Now that the segment addresses have been worked out, take a better
guess at whether the file is executable. If the entry point
is within the text segment, assume it is. (This makes files
executable even if their entry point address is 0, as long as
their text starts at zero.)
At some point we should probably break down and stat the file and
declare it executable if (one of) its 'x' bits are on... */
their text starts at zero.). */
if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
(execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
abfd->flags |= EXEC_P;
#endif /* ! defined (STAT_FOR_EXEC) */
#ifdef STAT_FOR_EXEC
else
{
struct stat stat_buf;
/* The original heuristic doesn't work in some important cases.
The a.out file has no information about the text start
address. For files (like kernels) linked to non-standard
addresses (ld -Ttext nnn) the entry point may not be between
the default text start (obj_textsec(abfd)->vma) and
(obj_textsec(abfd)->vma) + text size. This is not just a mach
issue. Many kernels are loaded at non standard addresses. */
if (abfd->iostream
&& (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
&& ((stat_buf.st_mode & 0111) != 0))
abfd->flags |= EXEC_P;
}
#endif /* STAT_FOR_EXEC */
if (result)
{
#if 0 /* These should be set correctly anyways. */
@ -3789,6 +3787,7 @@ aout_link_write_symbols (finfo, input_bfd)
else if (((type & N_TYPE) == N_INDR
&& (hresolve == (struct aout_link_hash_entry *) NULL
|| (hresolve->root.type != bfd_link_hash_defined
&& hresolve->root.type != bfd_link_hash_defweak
&& hresolve->root.type != bfd_link_hash_common)))
|| type == N_WARNING)
{
@ -3841,13 +3840,14 @@ aout_link_write_symbols (finfo, input_bfd)
break;
}
}
else if (hresolve->root.type == bfd_link_hash_defined)
else if (hresolve->root.type == bfd_link_hash_defined
|| hresolve->root.type == bfd_link_hash_defweak)
{
asection *input_section;
asection *output_section;
/* This case means a common symbol which was turned
into a defined symbol. */
/* This case usually means a common symbol which was
turned into a defined symbol. */
input_section = hresolve->root.u.def.section;
output_section = input_section->output_section;
BFD_ASSERT (bfd_is_abs_section (output_section)
@ -3868,17 +3868,25 @@ aout_link_write_symbols (finfo, input_bfd)
type &=~ N_TYPE;
if (output_section == obj_textsec (output_bfd))
type |= N_TEXT;
type |= (hresolve->root.type == bfd_link_hash_defined
? N_TEXT
: N_WEAKT);
else if (output_section == obj_datasec (output_bfd))
type |= N_DATA;
type |= (hresolve->root.type == bfd_link_hash_defined
? N_DATA
: N_WEAKD);
else if (output_section == obj_bsssec (output_bfd))
type |= N_BSS;
type |= (hresolve->root.type == bfd_link_hash_defined
? N_BSS
: N_WEAKB);
else
type |= N_ABS;
type |= (hresolve->root.type == bfd_link_hash_defined
? N_ABS
: N_WEAKA);
}
else if (hresolve->root.type == bfd_link_hash_common)
val = hresolve->root.u.c.size;
else if (hresolve->root.type == bfd_link_hash_weak)
else if (hresolve->root.type == bfd_link_hash_undefweak)
{
val = 0;
type = N_WEAKU;
@ -4030,6 +4038,7 @@ aout_link_write_other_symbol (h, data)
val = 0;
break;
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
{
asection *sec;
@ -4037,13 +4046,14 @@ aout_link_write_other_symbol (h, data)
BFD_ASSERT (bfd_is_abs_section (sec)
|| sec->owner == output_bfd);
if (sec == obj_textsec (output_bfd))
type = N_TEXT | N_EXT;
type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
else if (sec == obj_datasec (output_bfd))
type = N_DATA | N_EXT;
type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
else if (sec == obj_bsssec (output_bfd))
type = N_BSS | N_EXT;
type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
else
type = N_ABS | N_EXT;
type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
type |= N_EXT;
val = (h->root.u.def.value
+ sec->vma
+ h->root.u.def.section->output_offset);
@ -4053,7 +4063,7 @@ aout_link_write_other_symbol (h, data)
type = N_UNDF | N_EXT;
val = h->root.u.c.size;
break;
case bfd_link_hash_weak:
case bfd_link_hash_undefweak:
type = N_WEAKU;
val = 0;
case bfd_link_hash_indirect:
@ -4305,7 +4315,8 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
is what the native linker does. */
h = sym_hashes[r_index];
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
asection *output_section;
@ -4443,14 +4454,15 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
}
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
relocation = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_weak)
&& h->root.type == bfd_link_hash_undefweak)
relocation = 0;
else
{
@ -4606,7 +4618,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
is what the native linker does. */
h = sym_hashes[r_index];
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
asection *output_section;
@ -4761,14 +4774,15 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
}
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_defined)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak))
{
relocation = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else if (h != (struct aout_link_hash_entry *) NULL
&& h->root.type == bfd_link_hash_weak)
&& h->root.type == bfd_link_hash_undefweak)
relocation = 0;
else
{

View File

@ -385,7 +385,8 @@ coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
if (h->root.type == bfd_link_hash_defined)
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
sec = h->root.u.def.section;
val = (h->root.u.def.value

View File

@ -1,5 +1,5 @@
/* Generic ECOFF (Extended-COFF) routines.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
@ -1358,7 +1358,7 @@ ecoff_type_to_string (abfd, fdr, indx)
} qualifiers[7];
unsigned int basic_type;
int i;
static char buffer1[1024];
char buffer1[1024];
static char buffer2[1024];
char *p1 = buffer1;
char *p2 = buffer2;
@ -2027,6 +2027,8 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
FDR *fdr_hold;
boolean stabs;
offset += section->vma;
/* If we're not in the .text section, we don't have any line
numbers. */
if (strcmp (section->name, _TEXT) != 0
@ -2091,14 +2093,14 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
list of procedure descriptors (PDR). PDR's also have an
address, which is relative to the FDR address, and are also
stored in increasing memory order. */
if (offset < fdr_ptr->adr)
return false;
offset -= fdr_ptr->adr;
external_pdr_size = debug_swap->external_pdr_size;
pdr_ptr = ((char *) debug_info->external_pdr
+ fdr_ptr->ipdFirst * external_pdr_size);
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
if (offset < pdr.adr)
return false;
/* The address of the first PDR is an offset which applies to
the addresses of all the PDR's. */
@ -2109,7 +2111,7 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
pdr_ptr += external_pdr_size)
{
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
if (offset < pdr.adr)
if (offset < pdr.adr - first_off)
break;
}
@ -3860,6 +3862,9 @@ ecoff_link_add_archive_symbols (abfd, info)
if (! bfd_has_map (abfd))
{
/* An empty archive is a special case. */
if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL)
return true;
bfd_set_error (bfd_error_no_symbols);
return false;
}
@ -4360,7 +4365,8 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext)
if (h->abfd == (bfd *) NULL
|| (! bfd_is_und_section (section)
&& (! bfd_is_com_section (section)
|| h->root.type != bfd_link_hash_defined)))
|| (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak))))
{
h->abfd = abfd;
h->esym = esym;
@ -4732,7 +4738,8 @@ ecoff_link_write_external (h, data)
h->esym.asym.value = 0;
h->esym.asym.st = stGlobal;
if (h->root.type != bfd_link_hash_defined)
if (h->root.type != bfd_link_hash_defined
&& h->root.type != bfd_link_hash_defweak)
h->esym.asym.sc = scAbs;
else
{
@ -4787,12 +4794,13 @@ ecoff_link_write_external (h, data)
case bfd_link_hash_new:
abort ();
case bfd_link_hash_undefined:
case bfd_link_hash_weak:
case bfd_link_hash_undefweak:
if (h->esym.asym.sc != scUndefined
&& h->esym.asym.sc != scSUndefined)
h->esym.asym.sc = scUndefined;
break;
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
if (h->esym.asym.sc == scUndefined
|| h->esym.asym.sc == scSUndefined)
h->esym.asym.sc = scAbs;
@ -4979,7 +4987,7 @@ ecoff_reloc_link_order (output_bfd, info, output_section, link_order)
rel.address = link_order->offset;
rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
if (rel.howto == (const reloc_howto_type *) NULL)
if (rel.howto == 0)
{
bfd_set_error (bfd_error_bad_value);
return false;

View File

@ -163,7 +163,10 @@ static file_ptr assign_file_position_for_section
static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean));
static int elf_sort_hdrs PARAMS ((const PTR, const PTR));
static void assign_file_positions_for_relocs PARAMS ((bfd *));
static bfd_size_type get_program_header_size PARAMS ((bfd *));
static bfd_size_type get_program_header_size PARAMS ((bfd *,
Elf_Internal_Shdr **,
unsigned int,
bfd_vma));
static file_ptr map_program_segments
PARAMS ((bfd *, file_ptr, Elf_Internal_Shdr *, Elf_Internal_Shdr **,
bfd_size_type));
@ -1719,20 +1722,121 @@ assign_file_position_for_section (i_shdrp, offset, align)
return offset;
}
/* Get the size of the program header. This is called by the linker
before any of the section VMA's are set, so it can't calculate the
correct value for a strange memory layout. */
/* Get the size of the program header.
SORTED_HDRS, if non-NULL, is an array of COUNT pointers to headers sorted
by VMA. Non-allocated sections (!SHF_ALLOC) must appear last. All
section VMAs and sizes are known so we can compute the correct value.
(??? This may not be perfectly true. What cases do we miss?)
If SORTED_HDRS is NULL we assume there are two segments: text and data
(exclusive of .interp and .dynamic).
If this is called by the linker before any of the section VMA's are set, it
can't calculate the correct value for a strange memory layout. This only
happens when SIZEOF_HEADERS is used in a linker script. In this case,
SORTED_HDRS is NULL and we assume the normal scenario of one text and one
data segment (exclusive of .interp and .dynamic).
??? User written scripts must either not use SIZEOF_HEADERS, or assume there
will be two segments. */
static bfd_size_type
get_program_header_size (abfd)
get_program_header_size (abfd, sorted_hdrs, count, maxpagesize)
bfd *abfd;
Elf_Internal_Shdr **sorted_hdrs;
unsigned int count;
bfd_vma maxpagesize;
{
size_t segs;
asection *s;
/* Assume we will need exactly two PT_LOAD segments: one for text
and one for data. */
segs = 2;
/* We can't return a different result each time we're called. */
if (elf_tdata (abfd)->program_header_size != 0)
return elf_tdata (abfd)->program_header_size;
if (sorted_hdrs != NULL)
{
unsigned int i;
unsigned int last_type;
Elf_Internal_Shdr **hdrpp;
/* What we think the current segment's offset is. */
bfd_vma p_offset;
/* What we think the current segment's address is. */
bfd_vma p_vaddr;
/* How big we think the current segment is. */
bfd_vma p_memsz;
/* What we think the current file offset is. */
bfd_vma file_offset;
bfd_vma next_offset;
/* Scan the headers and compute the number of segments required. This
code is intentionally similar to the code in map_program_segments.
The `sh_offset' field isn't valid at this point, so we keep our own
running total in `file_offset'.
This works because section VMAs are already known. */
segs = 1;
/* Make sure the first section goes in the first segment. */
file_offset = p_offset = sorted_hdrs[0]->sh_addr % maxpagesize;
p_vaddr = sorted_hdrs[0]->sh_addr;
p_memsz = 0;
last_type = SHT_PROGBITS;
for (i = 0, hdrpp = sorted_hdrs; i < count; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
hdr = *hdrpp;
/* Ignore any section which will not be part of the process
image. */
if ((hdr->sh_flags & SHF_ALLOC) == 0)
continue;
/* Keep track of where this and the next sections go.
The section VMA must equal the file position modulo
the page size. */
file_offset += (hdr->sh_addr - file_offset) % maxpagesize;
next_offset = file_offset;
if (hdr->sh_type != SHT_NOBITS)
next_offset = file_offset + hdr->sh_size;
/* If this section fits in the segment we are constructing, add
it in. */
if ((file_offset - (p_offset + p_memsz)
== hdr->sh_addr - (p_vaddr + p_memsz))
&& (last_type != SHT_NOBITS || hdr->sh_type == SHT_NOBITS))
{
bfd_size_type adjust;
adjust = hdr->sh_addr - (p_vaddr + p_memsz);
p_memsz += hdr->sh_size + adjust;
file_offset = next_offset;
last_type = hdr->sh_type;
continue;
}
/* The section won't fit, start a new segment. */
++segs;
/* Initialize the segment. */
p_vaddr = hdr->sh_addr;
p_memsz = hdr->sh_size;
p_offset = file_offset;
file_offset = next_offset;
last_type = hdr->sh_type;
}
}
else
{
/* Assume we will need exactly two PT_LOAD segments: one for text
and one for data. */
segs = 2;
}
s = bfd_get_section_by_name (abfd, ".interp");
if (s != NULL && (s->flags & SEC_LOAD) != 0)
@ -1750,7 +1854,8 @@ get_program_header_size (abfd)
++segs;
}
return segs * sizeof (Elf_External_Phdr);
elf_tdata (abfd)->program_header_size = segs * sizeof (Elf_External_Phdr);
return elf_tdata (abfd)->program_header_size;
}
/* Create the program header. OFF is the file offset where the
@ -1877,14 +1982,15 @@ map_program_segments (abfd, off, first, sorted_hdrs, phdr_size)
continue;
}
/* If we have a segment, move to the next one. */
/* The section won't fit, start a new segment. If we're already in one,
move to the next one. */
if (phdr->p_type != PT_NULL)
{
++phdr;
++phdr_count;
}
/* Start a new segment. */
/* Initialize the segment. */
phdr->p_type = PT_LOAD;
phdr->p_offset = hdr->sh_offset;
phdr->p_vaddr = hdr->sh_addr;
@ -2050,16 +2156,7 @@ assign_file_positions_except_relocs (abfd, dosyms)
Elf_Internal_Shdr *first;
file_ptr phdr_map;
/* We are creating an executable. We must create a program
header. We can't actually create the program header until we
have set the file positions for the sections, but we can
figure out how big it is going to be. */
off = align_file_position (off);
phdr_size = get_program_header_size (abfd);
if (phdr_size == (file_ptr) -1)
return false;
phdr_off = off;
off += phdr_size;
/* We are creating an executable. */
maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
if (maxpagesize == 0)
@ -2081,6 +2178,19 @@ assign_file_positions_except_relocs (abfd, dosyms)
qsort (sorted_hdrs, i_ehdrp->e_shnum - 1, sizeof (Elf_Internal_Shdr *),
elf_sort_hdrs);
/* We can't actually create the program header until we have set the
file positions for the sections, and we can't do that until we know
how big the header is going to be. */
off = align_file_position (off);
phdr_size = get_program_header_size (abfd,
sorted_hdrs, i_ehdrp->e_shnum - 1,
maxpagesize);
if (phdr_size == (file_ptr) -1)
return false;
/* Compute the file offsets of each section. */
phdr_off = off;
off += phdr_size;
first = NULL;
for (i = 1, hdrpp = sorted_hdrs; i < i_ehdrp->e_shnum; i++, hdrpp++)
{
@ -2116,6 +2226,7 @@ assign_file_positions_except_relocs (abfd, dosyms)
off = assign_file_position_for_section (hdr, off, false);
}
/* Create the program header. */
phdr_map = map_program_segments (abfd, phdr_off, first, sorted_hdrs,
phdr_size);
if (phdr_map == (file_ptr) -1)
@ -3209,7 +3320,8 @@ elf_sizeof_headers (abfd, reloc)
ret = sizeof (Elf_External_Ehdr);
if (! reloc)
ret += get_program_header_size (abfd);
ret += get_program_header_size (abfd, (Elf_Internal_Shdr **) NULL, 0,
(bfd_vma) 0);
return ret;
}
@ -4297,7 +4409,8 @@ elf_link_add_object_symbols (abfd, info)
clobbering sec to be bfd_und_section_ptr. */
if (dynamic && definition)
{
if (h->root.type == bfd_link_hash_defined)
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
sec = bfd_und_section_ptr;
}
@ -4309,7 +4422,8 @@ elf_link_add_object_symbols (abfd, info)
object in the link. */
if (! dynamic
&& definition
&& h->root.type == bfd_link_hash_defined
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
&& (bfd_get_flavour (h->root.u.def.section->owner)
== bfd_target_elf_flavour)
@ -4332,7 +4446,7 @@ elf_link_add_object_symbols (abfd, info)
&& ! bfd_is_und_section (sec)
&& (h->root.type == bfd_link_hash_new
|| h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_weak))
|| h->root.type == bfd_link_hash_undefweak))
h->elf_link_hash_flags |= ELF_LINK_HASH_DEFINED_WEAK;
}
@ -4454,7 +4568,8 @@ elf_link_add_object_symbols (abfd, info)
weaks = hlook->weakdef;
hlook->weakdef = NULL;
BFD_ASSERT (hlook->root.type == bfd_link_hash_defined);
BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
|| hlook->root.type == bfd_link_hash_defweak);
slook = hlook->root.u.def.section;
vlook = hlook->root.u.def.value;
@ -4466,7 +4581,8 @@ elf_link_add_object_symbols (abfd, info)
h = *hpp;
if (h != hlook
&& h->root.type == bfd_link_hash_defined
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section == slook
&& h->root.u.def.value == vlook)
{
@ -5136,9 +5252,11 @@ elf_adjust_dynamic_symbol (h, data)
{
struct elf_link_hash_entry *weakdef;
BFD_ASSERT (h->root.type == bfd_link_hash_defined);
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak);
weakdef = h->weakdef;
BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined);
BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
|| weakdef->root.type == bfd_link_hash_defweak);
BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC);
if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
{
@ -5703,7 +5821,8 @@ elf_bfd_final_link (abfd, info)
h = elf_link_hash_lookup (elf_hash_table (info), name,
false, false, true);
BFD_ASSERT (h != NULL);
if (h->root.type == bfd_link_hash_defined)
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
dyn.d_un.d_val = h->root.u.def.value;
o = h->root.u.def.section;
@ -5980,7 +6099,8 @@ elf_link_output_extsym (h, data)
sym.st_value = 0;
sym.st_size = h->size;
sym.st_other = 0;
if (h->root.type == bfd_link_hash_weak
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_defweak
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEFINED_WEAK) != 0)
sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
else
@ -5998,12 +6118,13 @@ elf_link_output_extsym (h, data)
sym.st_shndx = SHN_UNDEF;
break;
case bfd_link_hash_weak:
case bfd_link_hash_undefweak:
input_sec = bfd_und_section_ptr;
sym.st_shndx = SHN_UNDEF;
break;
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
{
input_sec = h->root.u.def.section;
if (input_sec->output_section != NULL)

View File

@ -342,7 +342,8 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
if (! info->relocateable
&& linux_hash_table (info)->dynobj == NULL
&& strcmp (name, SHARABLE_CONFLICTS) == 0
&& (flags & BSF_CONSTRUCTOR) != 0)
&& (flags & BSF_CONSTRUCTOR) != 0
&& abfd->xvec == info->hash->creator)
{
if (! linux_link_create_dynamic_sections (abfd, info))
return false;
@ -351,12 +352,13 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
}
if (bfd_is_abs_section (section)
&& (IS_GOT_SYM (name) || IS_PLT_SYM (name)))
&& abfd->xvec == info->hash->creator)
{
h = linux_link_hash_lookup (linux_hash_table (info), name, false,
false, false);
if (h != NULL
&& h->root.root.type == bfd_link_hash_defined)
&& (h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak))
{
struct fixup *f;
@ -445,7 +447,8 @@ linux_tally_symbols (h, data)
fixup anyway, since there are cases where these symbols come
from different shared libraries */
if (h1 != NULL
&& ((h1->root.root.type == bfd_link_hash_defined
&& (((h1->root.root.type == bfd_link_hash_defined
|| h1->root.root.type == bfd_link_hash_defweak)
&& ! bfd_is_abs_section (h1->root.root.u.def.section))
|| h2->root.root.type == bfd_link_hash_indirect))
{
@ -458,9 +461,11 @@ linux_tally_symbols (h, data)
f1 != NULL;
f1 = f1->next)
{
if (f1->h != h
if ((f1->h != h && f1->h != h1)
|| (! f1->builtin && ! f1->jump))
continue;
if (f1->h == h1)
exists = true;
if (! exists
&& bfd_is_abs_section (h->root.root.u.def.section))
{
@ -593,7 +598,8 @@ linux_finish_dynamic_link (output_bfd, info)
if (f->builtin)
continue;
if (f->h->root.root.type != bfd_link_hash_defined)
if (f->h->root.root.type != bfd_link_hash_defined
&& f->h->root.root.type != bfd_link_hash_defweak)
{
/* FIXME! */
fprintf (stderr,
@ -643,7 +649,8 @@ linux_finish_dynamic_link (output_bfd, info)
if (! f->builtin)
continue;
if (f->h->root.root.type != bfd_link_hash_defined)
if (f->h->root.root.type != bfd_link_hash_defined
&& f->h->root.root.type != bfd_link_hash_defweak)
{
/* FIXME! */
fprintf (stderr,
@ -687,7 +694,9 @@ linux_finish_dynamic_link (output_bfd, info)
"__BUILTIN_FIXUPS__",
false, false, false);
if (h != NULL && h->root.root.type == bfd_link_hash_defined)
if (h != NULL
&& (h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak))
{
is = h->root.root.u.def.section;
section_offset = is->output_section->vma + is->output_offset;

View File

@ -308,12 +308,13 @@ struct elf_backend_data
referenced by a regular object. This is called after all the
input files have been seen, but before the SIZE_DYNAMIC_SECTIONS
function has been called. The hash table entry should be
bfd_link_hash_defined, and it should be defined in a section from
a dynamic object. Dynamic object sections are not included in
the final link, and this function is responsible for changing the
value to something which the rest of the link can deal with.
This will normally involve adding an entry to the .plt or .got or
some such section, and setting the symbol to point to that. */
bfd_link_hash_defined ore bfd_link_hash_defweak, and it should be
defined in a section from a dynamic object. Dynamic object
sections are not included in the final link, and this function is
responsible for changing the value to something which the rest of
the link can deal with. This will normally involve adding an
entry to the .plt or .got or some such section, and setting the
symbol to point to that. */
boolean (*elf_backend_adjust_dynamic_symbol)
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));

View File

@ -1,5 +1,5 @@
/* linker.c -- BFD linker routines
Copyright (C) 1993, 1994 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
This file is part of BFD, the Binary File Descriptor library.
@ -380,10 +380,7 @@ SUBSUBSECTION
written out when considering the symbols of each input file,
but it is still necessary to traverse the hash table since the
linker script may have defined some symbols that are not in
any of the input files. The <<written>> field in the
<<bfd_link_hash_entry>> structure may be used to determine
which entries in the hash table have not already been written
out.
any of the input files.
The <<strip>> field of the <<bfd_link_info>> structure
controls which symbols are written out. The possible values
@ -1065,9 +1062,9 @@ generic_link_check_archive_element (abfd, info, pneeded, collect)
/* We are only interested if we know something about this
symbol, and it is undefined or common. An undefined weak
symbol (type bfd_link_hash_weak) is not considered to be a
reference when pulling files out of an archive. See the SVR4
ABI, p. 4-27. */
symbol (type bfd_link_hash_undefweak) is not considered to be
a reference when pulling files out of an archive. See the
SVR4 ABI, p. 4-27. */
h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
false, true);
if (h == (struct bfd_link_hash_entry *) NULL
@ -1287,6 +1284,7 @@ enum link_action
UND, /* Mark symbol undefined. */
WEAK, /* Mark symbol weak undefined. */
DEF, /* Mark symbol defined. */
DEFW, /* Mark symbol weak defined. */
COM, /* Mark symbol common. */
REF, /* Mark defined symbol referenced. */
CREF, /* Possibly warn about common reference to defined symbol. */
@ -1309,17 +1307,17 @@ enum link_action
/* The state table itself. The first index is a link_row and the
second index is a bfd_link_hash_type. */
static const enum link_action link_action[8][7] =
static const enum link_action link_action[8][8] =
{
/* current\prev new undef weak def com indr warn */
/* UNDEF_ROW */ {UND, NOACT, NOACT, REF, NOACT, REFC, WARNC },
/* UNDEFW_ROW */ {WEAK, WEAK, NOACT, REF, NOACT, REFC, WARNC },
/* DEF_ROW */ {DEF, DEF, DEF, MDEF, CDEF, MDEF, CYCLE },
/* DEFW_ROW */ {DEF, DEF, DEF, NOACT, NOACT, NOACT, CYCLE },
/* COMMON_ROW */ {COM, COM, COM, CREF, BIG, CREF, WARNC },
/* INDR_ROW */ {IND, IND, IND, MDEF, CIND, MIND, CYCLE },
/* WARN_ROW */ {MWARN, WARN, WARN, CWARN, WARN, CWARN, CYCLE },
/* SET_ROW */ {SET, SET, SET, SET, SET, CYCLE, CYCLE }
/* current\prev new undef undefw def defw com indr warn */
/* UNDEF_ROW */ {UND, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC },
/* UNDEFW_ROW */ {WEAK, WEAK, NOACT, REF, REF, NOACT, REFC, WARNC },
/* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE },
/* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE },
/* COMMON_ROW */ {COM, COM, COM, CREF, CREF, BIG, CREF, WARNC },
/* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE },
/* WARN_ROW */ {MWARN, WARN, WARN, CWARN, CWARN, WARN, CWARN, CYCLE },
/* SET_ROW */ {SET, SET, SET, SET, SET, SET, CYCLE, CYCLE }
};
/* Most of the entries in the LINK_ACTION table are straightforward,
@ -1453,7 +1451,7 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
case WEAK:
/* Make a new weak undefined symbol. */
h->type = bfd_link_hash_weak;
h->type = bfd_link_hash_undefweak;
h->u.undef.abfd = abfd;
break;
@ -1468,50 +1466,69 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
return false;
/* Fall through. */
case DEF:
/* Define a symbol. */
h->type = bfd_link_hash_defined;
h->u.def.section = section;
h->u.def.value = value;
case DEFW:
{
enum bfd_link_order_type oldtype;
/* If we have been asked to, we act like collect2 and
identify all functions that might be global constructors
and destructors and pass them up in a callback. We only
do this for certain object file types, since many object
file types can handle this automatically. */
if (collect && name[0] == '_')
{
const char *s;
/* Define a symbol. */
oldtype = h->type;
if (action == DEFW)
h->type = bfd_link_hash_defweak;
else
h->type = bfd_link_hash_defined;
h->u.def.section = section;
h->u.def.value = value;
/* A constructor or destructor name starts like this:
_+GLOBAL_[_.$][ID][_.$]
where the first [_.$] and the second are the same
character (we accept any character there, in case a
new object file format comes along with even worse
naming restrictions). */
/* If we have been asked to, we act like collect2 and
identify all functions that might be global
constructors and destructors and pass them up in a
callback. We only do this for certain object file
types, since many object file types can handle this
automatically. */
if (collect && name[0] == '_')
{
const char *s;
/* A constructor or destructor name starts like this:
_+GLOBAL_[_.$][ID][_.$] where the first [_.$] and
the second are the same character (we accept any
character there, in case a new object file format
comes along with even worse naming restrictions). */
#define CONS_PREFIX "GLOBAL_"
#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1)
s = name + 1;
while (*s == '_')
++s;
if (s[0] == 'G'
&& strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0)
{
char c;
s = name + 1;
while (*s == '_')
++s;
if (s[0] == 'G'
&& strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0)
{
char c;
c = s[CONS_PREFIX_LEN + 1];
if ((c == 'I' || c == 'D')
&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
{
if (! ((*info->callbacks->constructor)
(info,
c == 'I' ? true : false,
name, abfd, section, value)))
return false;
}
}
}
c = s[CONS_PREFIX_LEN + 1];
if ((c == 'I' || c == 'D')
&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
{
/* If this is a definition of a symbol which
was previously weakly defined, we are in
trouble. We have already added a
constructor entry for the weak defined
symbol, and now we are trying to add one
for the new symbol. Fortunately, this case
should never arise in practice. */
if (oldtype == bfd_link_hash_defweak)
abort ();
if (! ((*info->callbacks->constructor)
(info,
c == 'I' ? true : false,
name, abfd, section, value)))
return false;
}
}
}
}
break;
@ -1602,7 +1619,8 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
was already defined. FIXME: It would nice if we could
report the BFD which defined an indirect symbol, but we
don't have anywhere to store the information. */
if (h->type == bfd_link_hash_defined)
if (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
obfd = h->u.def.section->owner;
else
obfd = NULL;
@ -1631,10 +1649,6 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
msec = h->u.def.section;
mval = h->u.def.value;
break;
case bfd_link_hash_common:
msec = bfd_com_section_ptr;
mval = h->u.c.size;
break;
case bfd_link_hash_indirect:
msec = bfd_ind_section_ptr;
mval = 0;
@ -1738,10 +1752,10 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
case CWARN:
/* Warn if this symbol has been referenced already,
otherwise either add a warning or cycle. A symbol has
been referenced if the next field is not NULL, or it is
the tail of the undefined symbol list. The REF case
above helps to ensure this. */
otherwise add a warning. A symbol has been referenced if
the next field is not NULL, or it is the tail of the
undefined symbol list. The REF case above helps to
ensure this. */
if (h->next != NULL || info->hash->undefs_tail == h)
{
if (! (*info->callbacks->warning) (info, string))
@ -2037,12 +2051,19 @@ _bfd_generic_link_output_symbols (output_bfd, input_bfd, info, psymalloc)
case bfd_link_hash_new:
abort ();
case bfd_link_hash_undefined:
case bfd_link_hash_weak:
break;
case bfd_link_hash_undefweak:
sym->flags |= BSF_WEAK;
break;
case bfd_link_hash_defined:
sym->flags |= BSF_GLOBAL;
sym->value = h->root.u.def.value;
sym->section = h->root.u.def.section;
break;
case bfd_link_hash_defweak:
sym->flags |= BSF_WEAK;
sym->value = h->root.u.def.value;
sym->section = h->root.u.def.section;
sym->flags |= BSF_GLOBAL;
break;
case bfd_link_hash_common:
sym->value = h->root.u.c.size;
@ -2160,7 +2181,7 @@ set_symbol_from_hash (sym, h)
sym->section = bfd_und_section_ptr;
sym->value = 0;
break;
case bfd_link_hash_weak:
case bfd_link_hash_undefweak:
sym->section = bfd_und_section_ptr;
sym->value = 0;
sym->flags |= BSF_WEAK;
@ -2169,6 +2190,11 @@ set_symbol_from_hash (sym, h)
sym->section = h->u.def.section;
sym->value = h->u.def.value;
break;
case bfd_link_hash_defweak:
sym->flags |= BSF_WEAK;
sym->section = h->u.def.section;
sym->value = h->u.def.value;
break;
case bfd_link_hash_common:
sym->value = h->u.c.size;
if (sym->section == NULL)
@ -2263,7 +2289,7 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order)
r->address = link_order->offset;
r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
if (r->howto == (const reloc_howto_type *) NULL)
if (r->howto == 0)
{
bfd_set_error (bfd_error_bad_value);
return false;

View File

@ -1,5 +1,5 @@
/* BFD backend for SunOS binaries.
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@ -859,7 +859,8 @@ sunos_add_one_symbol (info, abfd, name, flags, section, value, string,
if (! bfd_is_und_section (section)
&& h->root.root.type != bfd_link_hash_new
&& h->root.root.type != bfd_link_hash_undefined)
&& h->root.root.type != bfd_link_hash_undefined
&& h->root.root.type != bfd_link_hash_defweak)
{
/* We are defining the symbol, and it is already defined. This
is a potential multiple definition error. */
@ -1297,9 +1298,10 @@ sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)
/* At this point common symbols have already been allocated, so
we don't have to worry about them. We need to consider that
we may have already seen this symbol and marked it undefined;
if the symbols is really undefined, then SUNOS_DEF_DYNAMIC
if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
will be zero. */
if (h->root.root.type != bfd_link_hash_defined
&& h->root.root.type != bfd_link_hash_defweak
&& h->root.root.type != bfd_link_hash_undefined)
continue;
@ -1308,7 +1310,8 @@ sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)
continue;
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
BFD_ASSERT (h->root.root.type == bfd_link_hash_defined
BFD_ASSERT ((h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak)
? (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0
: (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0);
@ -1444,6 +1447,7 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
if the symbols is really undefined, then SUNOS_DEF_DYNAMIC
will be zero. */
if (h->root.root.type != bfd_link_hash_defined
&& h->root.root.type != bfd_link_hash_defweak
&& h->root.root.type != bfd_link_hash_undefined)
continue;
@ -1452,7 +1456,8 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
continue;
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
BFD_ASSERT (h->root.root.type == bfd_link_hash_defined
BFD_ASSERT ((h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak)
? (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0
: (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0);
@ -1527,7 +1532,8 @@ sunos_scan_dynamic_symbol (h, data)
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0
&& (h->flags & SUNOS_REF_REGULAR) != 0)
{
if (h->root.root.type == bfd_link_hash_defined
if ((h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak)
&& ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
&& h->root.root.u.def.section->output_section == NULL)
{
@ -1665,6 +1671,7 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
val = 0;
break;
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
{
asection *sec;
asection *output_section;
@ -1682,13 +1689,22 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
else
{
if (output_section == obj_textsec (output_bfd))
type = N_TEXT | N_EXT;
type = (h->root.root.type == bfd_link_hash_defined
? N_TEXT
: N_WEAKT);
else if (output_section == obj_datasec (output_bfd))
type = N_DATA | N_EXT;
type = (h->root.root.type == bfd_link_hash_defined
? N_DATA
: N_WEAKD);
else if (output_section == obj_bsssec (output_bfd))
type = N_BSS | N_EXT;
type = (h->root.root.type == bfd_link_hash_defined
? N_BSS
: N_WEAKB);
else
type = N_ABS | N_EXT;
type = (h->root.root.type == bfd_link_hash_defined
? N_ABS
: N_WEAKA);
type |= N_EXT;
val = (h->root.root.u.def.value
+ output_section->vma
+ sec->output_offset);
@ -1699,7 +1715,7 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
type = N_UNDF | N_EXT;
val = h->root.root.u.c.size;
break;
case bfd_link_hash_weak:
case bfd_link_hash_undefweak:
type = N_WEAKU;
val = 0;
break;