mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-07-03 19:36:46 +08:00
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:
@ -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>
|
Mon Feb 6 03:20:17 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
|
||||||
|
|
||||||
Changes from Bryan Ford, baford@schirf.cs.utah.edu:
|
Changes from Bryan Ford, baford@schirf.cs.utah.edu:
|
||||||
|
96
bfd/aoutx.h
96
bfd/aoutx.h
@ -562,35 +562,33 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
|
|||||||
|
|
||||||
result = (*callback_to_real_object_p)(abfd);
|
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
|
/* Now that the segment addresses have been worked out, take a better
|
||||||
guess at whether the file is executable. If the entry point
|
guess at whether the file is executable. If the entry point
|
||||||
is within the text segment, assume it is. (This makes files
|
is within the text segment, assume it is. (This makes files
|
||||||
executable even if their entry point address is 0, as long as
|
executable even if their entry point address is 0, as long as
|
||||||
their text starts at zero.)
|
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... */
|
|
||||||
if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
|
if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
|
||||||
(execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
|
(execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
|
||||||
abfd->flags |= EXEC_P;
|
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 (result)
|
||||||
{
|
{
|
||||||
#if 0 /* These should be set correctly anyways. */
|
#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
|
else if (((type & N_TYPE) == N_INDR
|
||||||
&& (hresolve == (struct aout_link_hash_entry *) NULL
|
&& (hresolve == (struct aout_link_hash_entry *) NULL
|
||||||
|| (hresolve->root.type != bfd_link_hash_defined
|
|| (hresolve->root.type != bfd_link_hash_defined
|
||||||
|
&& hresolve->root.type != bfd_link_hash_defweak
|
||||||
&& hresolve->root.type != bfd_link_hash_common)))
|
&& hresolve->root.type != bfd_link_hash_common)))
|
||||||
|| type == N_WARNING)
|
|| type == N_WARNING)
|
||||||
{
|
{
|
||||||
@ -3841,13 +3840,14 @@ aout_link_write_symbols (finfo, input_bfd)
|
|||||||
break;
|
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 *input_section;
|
||||||
asection *output_section;
|
asection *output_section;
|
||||||
|
|
||||||
/* This case means a common symbol which was turned
|
/* This case usually means a common symbol which was
|
||||||
into a defined symbol. */
|
turned into a defined symbol. */
|
||||||
input_section = hresolve->root.u.def.section;
|
input_section = hresolve->root.u.def.section;
|
||||||
output_section = input_section->output_section;
|
output_section = input_section->output_section;
|
||||||
BFD_ASSERT (bfd_is_abs_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;
|
type &=~ N_TYPE;
|
||||||
|
|
||||||
if (output_section == obj_textsec (output_bfd))
|
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))
|
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))
|
else if (output_section == obj_bsssec (output_bfd))
|
||||||
type |= N_BSS;
|
type |= (hresolve->root.type == bfd_link_hash_defined
|
||||||
|
? N_BSS
|
||||||
|
: N_WEAKB);
|
||||||
else
|
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)
|
else if (hresolve->root.type == bfd_link_hash_common)
|
||||||
val = hresolve->root.u.c.size;
|
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;
|
val = 0;
|
||||||
type = N_WEAKU;
|
type = N_WEAKU;
|
||||||
@ -4030,6 +4038,7 @@ aout_link_write_other_symbol (h, data)
|
|||||||
val = 0;
|
val = 0;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_defined:
|
case bfd_link_hash_defined:
|
||||||
|
case bfd_link_hash_defweak:
|
||||||
{
|
{
|
||||||
asection *sec;
|
asection *sec;
|
||||||
|
|
||||||
@ -4037,13 +4046,14 @@ aout_link_write_other_symbol (h, data)
|
|||||||
BFD_ASSERT (bfd_is_abs_section (sec)
|
BFD_ASSERT (bfd_is_abs_section (sec)
|
||||||
|| sec->owner == output_bfd);
|
|| sec->owner == output_bfd);
|
||||||
if (sec == obj_textsec (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))
|
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))
|
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
|
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
|
val = (h->root.u.def.value
|
||||||
+ sec->vma
|
+ sec->vma
|
||||||
+ h->root.u.def.section->output_offset);
|
+ h->root.u.def.section->output_offset);
|
||||||
@ -4053,7 +4063,7 @@ aout_link_write_other_symbol (h, data)
|
|||||||
type = N_UNDF | N_EXT;
|
type = N_UNDF | N_EXT;
|
||||||
val = h->root.u.c.size;
|
val = h->root.u.c.size;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_weak:
|
case bfd_link_hash_undefweak:
|
||||||
type = N_WEAKU;
|
type = N_WEAKU;
|
||||||
val = 0;
|
val = 0;
|
||||||
case bfd_link_hash_indirect:
|
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. */
|
is what the native linker does. */
|
||||||
h = sym_hashes[r_index];
|
h = sym_hashes[r_index];
|
||||||
if (h != (struct aout_link_hash_entry *) NULL
|
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;
|
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
|
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
|
relocation = (h->root.u.def.value
|
||||||
+ h->root.u.def.section->output_section->vma
|
+ h->root.u.def.section->output_section->vma
|
||||||
+ h->root.u.def.section->output_offset);
|
+ h->root.u.def.section->output_offset);
|
||||||
}
|
}
|
||||||
else if (h != (struct aout_link_hash_entry *) NULL
|
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;
|
relocation = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4606,7 +4618,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
|||||||
is what the native linker does. */
|
is what the native linker does. */
|
||||||
h = sym_hashes[r_index];
|
h = sym_hashes[r_index];
|
||||||
if (h != (struct aout_link_hash_entry *) NULL
|
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;
|
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
|
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
|
relocation = (h->root.u.def.value
|
||||||
+ h->root.u.def.section->output_section->vma
|
+ h->root.u.def.section->output_section->vma
|
||||||
+ h->root.u.def.section->output_offset);
|
+ h->root.u.def.section->output_offset);
|
||||||
}
|
}
|
||||||
else if (h != (struct aout_link_hash_entry *) NULL
|
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;
|
relocation = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -385,7 +385,8 @@ coff_a29k_relocate_section (output_bfd, info, input_bfd, input_section,
|
|||||||
}
|
}
|
||||||
else
|
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;
|
sec = h->root.u.def.section;
|
||||||
val = (h->root.u.def.value
|
val = (h->root.u.def.value
|
||||||
|
26
bfd/ecoff.c
26
bfd/ecoff.c
@ -1,5 +1,5 @@
|
|||||||
/* Generic ECOFF (Extended-COFF) routines.
|
/* 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.
|
Original version by Per Bothner.
|
||||||
Full support added by Ian Lance Taylor, ian@cygnus.com.
|
Full support added by Ian Lance Taylor, ian@cygnus.com.
|
||||||
|
|
||||||
@ -1358,7 +1358,7 @@ ecoff_type_to_string (abfd, fdr, indx)
|
|||||||
} qualifiers[7];
|
} qualifiers[7];
|
||||||
unsigned int basic_type;
|
unsigned int basic_type;
|
||||||
int i;
|
int i;
|
||||||
static char buffer1[1024];
|
char buffer1[1024];
|
||||||
static char buffer2[1024];
|
static char buffer2[1024];
|
||||||
char *p1 = buffer1;
|
char *p1 = buffer1;
|
||||||
char *p2 = buffer2;
|
char *p2 = buffer2;
|
||||||
@ -2027,6 +2027,8 @@ _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
|
|||||||
FDR *fdr_hold;
|
FDR *fdr_hold;
|
||||||
boolean stabs;
|
boolean stabs;
|
||||||
|
|
||||||
|
offset += section->vma;
|
||||||
|
|
||||||
/* If we're not in the .text section, we don't have any line
|
/* If we're not in the .text section, we don't have any line
|
||||||
numbers. */
|
numbers. */
|
||||||
if (strcmp (section->name, _TEXT) != 0
|
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
|
list of procedure descriptors (PDR). PDR's also have an
|
||||||
address, which is relative to the FDR address, and are also
|
address, which is relative to the FDR address, and are also
|
||||||
stored in increasing memory order. */
|
stored in increasing memory order. */
|
||||||
|
if (offset < fdr_ptr->adr)
|
||||||
|
return false;
|
||||||
offset -= fdr_ptr->adr;
|
offset -= fdr_ptr->adr;
|
||||||
external_pdr_size = debug_swap->external_pdr_size;
|
external_pdr_size = debug_swap->external_pdr_size;
|
||||||
pdr_ptr = ((char *) debug_info->external_pdr
|
pdr_ptr = ((char *) debug_info->external_pdr
|
||||||
+ fdr_ptr->ipdFirst * external_pdr_size);
|
+ fdr_ptr->ipdFirst * external_pdr_size);
|
||||||
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
|
pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
|
||||||
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
|
(*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 address of the first PDR is an offset which applies to
|
||||||
the addresses of all the PDR's. */
|
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)
|
pdr_ptr += external_pdr_size)
|
||||||
{
|
{
|
||||||
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
|
(*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
|
||||||
if (offset < pdr.adr)
|
if (offset < pdr.adr - first_off)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3860,6 +3862,9 @@ ecoff_link_add_archive_symbols (abfd, info)
|
|||||||
|
|
||||||
if (! bfd_has_map (abfd))
|
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);
|
bfd_set_error (bfd_error_no_symbols);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4360,7 +4365,8 @@ ecoff_link_add_externals (abfd, info, external_ext, ssext)
|
|||||||
if (h->abfd == (bfd *) NULL
|
if (h->abfd == (bfd *) NULL
|
||||||
|| (! bfd_is_und_section (section)
|
|| (! bfd_is_und_section (section)
|
||||||
&& (! bfd_is_com_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->abfd = abfd;
|
||||||
h->esym = esym;
|
h->esym = esym;
|
||||||
@ -4732,7 +4738,8 @@ ecoff_link_write_external (h, data)
|
|||||||
h->esym.asym.value = 0;
|
h->esym.asym.value = 0;
|
||||||
h->esym.asym.st = stGlobal;
|
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;
|
h->esym.asym.sc = scAbs;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4787,12 +4794,13 @@ ecoff_link_write_external (h, data)
|
|||||||
case bfd_link_hash_new:
|
case bfd_link_hash_new:
|
||||||
abort ();
|
abort ();
|
||||||
case bfd_link_hash_undefined:
|
case bfd_link_hash_undefined:
|
||||||
case bfd_link_hash_weak:
|
case bfd_link_hash_undefweak:
|
||||||
if (h->esym.asym.sc != scUndefined
|
if (h->esym.asym.sc != scUndefined
|
||||||
&& h->esym.asym.sc != scSUndefined)
|
&& h->esym.asym.sc != scSUndefined)
|
||||||
h->esym.asym.sc = scUndefined;
|
h->esym.asym.sc = scUndefined;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_defined:
|
case bfd_link_hash_defined:
|
||||||
|
case bfd_link_hash_defweak:
|
||||||
if (h->esym.asym.sc == scUndefined
|
if (h->esym.asym.sc == scUndefined
|
||||||
|| h->esym.asym.sc == scSUndefined)
|
|| h->esym.asym.sc == scSUndefined)
|
||||||
h->esym.asym.sc = scAbs;
|
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.address = link_order->offset;
|
||||||
|
|
||||||
rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
|
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);
|
bfd_set_error (bfd_error_bad_value);
|
||||||
return false;
|
return false;
|
||||||
|
185
bfd/elfcode.h
185
bfd/elfcode.h
@ -163,7 +163,10 @@ static file_ptr assign_file_position_for_section
|
|||||||
static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean));
|
static boolean assign_file_positions_except_relocs PARAMS ((bfd *, boolean));
|
||||||
static int elf_sort_hdrs PARAMS ((const PTR, const PTR));
|
static int elf_sort_hdrs PARAMS ((const PTR, const PTR));
|
||||||
static void assign_file_positions_for_relocs PARAMS ((bfd *));
|
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
|
static file_ptr map_program_segments
|
||||||
PARAMS ((bfd *, file_ptr, Elf_Internal_Shdr *, Elf_Internal_Shdr **,
|
PARAMS ((bfd *, file_ptr, Elf_Internal_Shdr *, Elf_Internal_Shdr **,
|
||||||
bfd_size_type));
|
bfd_size_type));
|
||||||
@ -1719,20 +1722,121 @@ assign_file_position_for_section (i_shdrp, offset, align)
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the size of the program header. This is called by the linker
|
/* Get the size of the program header.
|
||||||
before any of the section VMA's are set, so it can't calculate the
|
|
||||||
correct value for a strange memory layout. */
|
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
|
static bfd_size_type
|
||||||
get_program_header_size (abfd)
|
get_program_header_size (abfd, sorted_hdrs, count, maxpagesize)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
|
Elf_Internal_Shdr **sorted_hdrs;
|
||||||
|
unsigned int count;
|
||||||
|
bfd_vma maxpagesize;
|
||||||
{
|
{
|
||||||
size_t segs;
|
size_t segs;
|
||||||
asection *s;
|
asection *s;
|
||||||
|
|
||||||
/* Assume we will need exactly two PT_LOAD segments: one for text
|
/* We can't return a different result each time we're called. */
|
||||||
and one for data. */
|
if (elf_tdata (abfd)->program_header_size != 0)
|
||||||
segs = 2;
|
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");
|
s = bfd_get_section_by_name (abfd, ".interp");
|
||||||
if (s != NULL && (s->flags & SEC_LOAD) != 0)
|
if (s != NULL && (s->flags & SEC_LOAD) != 0)
|
||||||
@ -1750,7 +1854,8 @@ get_program_header_size (abfd)
|
|||||||
++segs;
|
++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
|
/* 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;
|
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)
|
if (phdr->p_type != PT_NULL)
|
||||||
{
|
{
|
||||||
++phdr;
|
++phdr;
|
||||||
++phdr_count;
|
++phdr_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start a new segment. */
|
/* Initialize the segment. */
|
||||||
phdr->p_type = PT_LOAD;
|
phdr->p_type = PT_LOAD;
|
||||||
phdr->p_offset = hdr->sh_offset;
|
phdr->p_offset = hdr->sh_offset;
|
||||||
phdr->p_vaddr = hdr->sh_addr;
|
phdr->p_vaddr = hdr->sh_addr;
|
||||||
@ -2050,16 +2156,7 @@ assign_file_positions_except_relocs (abfd, dosyms)
|
|||||||
Elf_Internal_Shdr *first;
|
Elf_Internal_Shdr *first;
|
||||||
file_ptr phdr_map;
|
file_ptr phdr_map;
|
||||||
|
|
||||||
/* We are creating an executable. We must create a program
|
/* We are creating an executable. */
|
||||||
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;
|
|
||||||
|
|
||||||
maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
|
maxpagesize = get_elf_backend_data (abfd)->maxpagesize;
|
||||||
if (maxpagesize == 0)
|
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 *),
|
qsort (sorted_hdrs, i_ehdrp->e_shnum - 1, sizeof (Elf_Internal_Shdr *),
|
||||||
elf_sort_hdrs);
|
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;
|
first = NULL;
|
||||||
for (i = 1, hdrpp = sorted_hdrs; i < i_ehdrp->e_shnum; i++, hdrpp++)
|
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);
|
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_map = map_program_segments (abfd, phdr_off, first, sorted_hdrs,
|
||||||
phdr_size);
|
phdr_size);
|
||||||
if (phdr_map == (file_ptr) -1)
|
if (phdr_map == (file_ptr) -1)
|
||||||
@ -3209,7 +3320,8 @@ elf_sizeof_headers (abfd, reloc)
|
|||||||
|
|
||||||
ret = sizeof (Elf_External_Ehdr);
|
ret = sizeof (Elf_External_Ehdr);
|
||||||
if (! reloc)
|
if (! reloc)
|
||||||
ret += get_program_header_size (abfd);
|
ret += get_program_header_size (abfd, (Elf_Internal_Shdr **) NULL, 0,
|
||||||
|
(bfd_vma) 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4297,7 +4409,8 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
clobbering sec to be bfd_und_section_ptr. */
|
clobbering sec to be bfd_und_section_ptr. */
|
||||||
if (dynamic && definition)
|
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;
|
sec = bfd_und_section_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4309,7 +4422,8 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
object in the link. */
|
object in the link. */
|
||||||
if (! dynamic
|
if (! dynamic
|
||||||
&& definition
|
&& 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
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
|
||||||
&& (bfd_get_flavour (h->root.u.def.section->owner)
|
&& (bfd_get_flavour (h->root.u.def.section->owner)
|
||||||
== bfd_target_elf_flavour)
|
== bfd_target_elf_flavour)
|
||||||
@ -4332,7 +4446,7 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
&& ! bfd_is_und_section (sec)
|
&& ! bfd_is_und_section (sec)
|
||||||
&& (h->root.type == bfd_link_hash_new
|
&& (h->root.type == bfd_link_hash_new
|
||||||
|| h->root.type == bfd_link_hash_undefined
|
|| 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;
|
h->elf_link_hash_flags |= ELF_LINK_HASH_DEFINED_WEAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4454,7 +4568,8 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
weaks = hlook->weakdef;
|
weaks = hlook->weakdef;
|
||||||
hlook->weakdef = NULL;
|
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;
|
slook = hlook->root.u.def.section;
|
||||||
vlook = hlook->root.u.def.value;
|
vlook = hlook->root.u.def.value;
|
||||||
|
|
||||||
@ -4466,7 +4581,8 @@ elf_link_add_object_symbols (abfd, info)
|
|||||||
|
|
||||||
h = *hpp;
|
h = *hpp;
|
||||||
if (h != hlook
|
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.section == slook
|
||||||
&& h->root.u.def.value == vlook)
|
&& h->root.u.def.value == vlook)
|
||||||
{
|
{
|
||||||
@ -5136,9 +5252,11 @@ elf_adjust_dynamic_symbol (h, data)
|
|||||||
{
|
{
|
||||||
struct elf_link_hash_entry *weakdef;
|
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;
|
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);
|
BFD_ASSERT (weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC);
|
||||||
if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
|
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,
|
h = elf_link_hash_lookup (elf_hash_table (info), name,
|
||||||
false, false, true);
|
false, false, true);
|
||||||
BFD_ASSERT (h != NULL);
|
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;
|
dyn.d_un.d_val = h->root.u.def.value;
|
||||||
o = h->root.u.def.section;
|
o = h->root.u.def.section;
|
||||||
@ -5980,7 +6099,8 @@ elf_link_output_extsym (h, data)
|
|||||||
sym.st_value = 0;
|
sym.st_value = 0;
|
||||||
sym.st_size = h->size;
|
sym.st_size = h->size;
|
||||||
sym.st_other = 0;
|
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)
|
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEFINED_WEAK) != 0)
|
||||||
sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
|
sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
|
||||||
else
|
else
|
||||||
@ -5998,12 +6118,13 @@ elf_link_output_extsym (h, data)
|
|||||||
sym.st_shndx = SHN_UNDEF;
|
sym.st_shndx = SHN_UNDEF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bfd_link_hash_weak:
|
case bfd_link_hash_undefweak:
|
||||||
input_sec = bfd_und_section_ptr;
|
input_sec = bfd_und_section_ptr;
|
||||||
sym.st_shndx = SHN_UNDEF;
|
sym.st_shndx = SHN_UNDEF;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bfd_link_hash_defined:
|
case bfd_link_hash_defined:
|
||||||
|
case bfd_link_hash_defweak:
|
||||||
{
|
{
|
||||||
input_sec = h->root.u.def.section;
|
input_sec = h->root.u.def.section;
|
||||||
if (input_sec->output_section != NULL)
|
if (input_sec->output_section != NULL)
|
||||||
|
@ -342,7 +342,8 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
|
|||||||
if (! info->relocateable
|
if (! info->relocateable
|
||||||
&& linux_hash_table (info)->dynobj == NULL
|
&& linux_hash_table (info)->dynobj == NULL
|
||||||
&& strcmp (name, SHARABLE_CONFLICTS) == 0
|
&& 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))
|
if (! linux_link_create_dynamic_sections (abfd, info))
|
||||||
return false;
|
return false;
|
||||||
@ -351,12 +352,13 @@ linux_add_one_symbol (info, abfd, name, flags, section, value, string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bfd_is_abs_section (section)
|
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,
|
h = linux_link_hash_lookup (linux_hash_table (info), name, false,
|
||||||
false, false);
|
false, false);
|
||||||
if (h != NULL
|
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;
|
struct fixup *f;
|
||||||
|
|
||||||
@ -445,7 +447,8 @@ linux_tally_symbols (h, data)
|
|||||||
fixup anyway, since there are cases where these symbols come
|
fixup anyway, since there are cases where these symbols come
|
||||||
from different shared libraries */
|
from different shared libraries */
|
||||||
if (h1 != NULL
|
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))
|
&& ! bfd_is_abs_section (h1->root.root.u.def.section))
|
||||||
|| h2->root.root.type == bfd_link_hash_indirect))
|
|| h2->root.root.type == bfd_link_hash_indirect))
|
||||||
{
|
{
|
||||||
@ -458,9 +461,11 @@ linux_tally_symbols (h, data)
|
|||||||
f1 != NULL;
|
f1 != NULL;
|
||||||
f1 = f1->next)
|
f1 = f1->next)
|
||||||
{
|
{
|
||||||
if (f1->h != h
|
if ((f1->h != h && f1->h != h1)
|
||||||
|| (! f1->builtin && ! f1->jump))
|
|| (! f1->builtin && ! f1->jump))
|
||||||
continue;
|
continue;
|
||||||
|
if (f1->h == h1)
|
||||||
|
exists = true;
|
||||||
if (! exists
|
if (! exists
|
||||||
&& bfd_is_abs_section (h->root.root.u.def.section))
|
&& bfd_is_abs_section (h->root.root.u.def.section))
|
||||||
{
|
{
|
||||||
@ -593,7 +598,8 @@ linux_finish_dynamic_link (output_bfd, info)
|
|||||||
if (f->builtin)
|
if (f->builtin)
|
||||||
continue;
|
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! */
|
/* FIXME! */
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@ -643,7 +649,8 @@ linux_finish_dynamic_link (output_bfd, info)
|
|||||||
if (! f->builtin)
|
if (! f->builtin)
|
||||||
continue;
|
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! */
|
/* FIXME! */
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@ -687,7 +694,9 @@ linux_finish_dynamic_link (output_bfd, info)
|
|||||||
"__BUILTIN_FIXUPS__",
|
"__BUILTIN_FIXUPS__",
|
||||||
false, false, false);
|
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;
|
is = h->root.root.u.def.section;
|
||||||
section_offset = is->output_section->vma + is->output_offset;
|
section_offset = is->output_section->vma + is->output_offset;
|
||||||
|
13
bfd/libelf.h
13
bfd/libelf.h
@ -308,12 +308,13 @@ struct elf_backend_data
|
|||||||
referenced by a regular object. This is called after all the
|
referenced by a regular object. This is called after all the
|
||||||
input files have been seen, but before the SIZE_DYNAMIC_SECTIONS
|
input files have been seen, but before the SIZE_DYNAMIC_SECTIONS
|
||||||
function has been called. The hash table entry should be
|
function has been called. The hash table entry should be
|
||||||
bfd_link_hash_defined, and it should be defined in a section from
|
bfd_link_hash_defined ore bfd_link_hash_defweak, and it should be
|
||||||
a dynamic object. Dynamic object sections are not included in
|
defined in a section from a dynamic object. Dynamic object
|
||||||
the final link, and this function is responsible for changing the
|
sections are not included in the final link, and this function is
|
||||||
value to something which the rest of the link can deal with.
|
responsible for changing the value to something which the rest of
|
||||||
This will normally involve adding an entry to the .plt or .got or
|
the link can deal with. This will normally involve adding an
|
||||||
some such section, and setting the symbol to point to that. */
|
entry to the .plt or .got or some such section, and setting the
|
||||||
|
symbol to point to that. */
|
||||||
boolean (*elf_backend_adjust_dynamic_symbol)
|
boolean (*elf_backend_adjust_dynamic_symbol)
|
||||||
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
|
PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
|
||||||
|
|
||||||
|
164
bfd/linker.c
164
bfd/linker.c
@ -1,5 +1,5 @@
|
|||||||
/* linker.c -- BFD linker routines
|
/* 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
|
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
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,
|
written out when considering the symbols of each input file,
|
||||||
but it is still necessary to traverse the hash table since the
|
but it is still necessary to traverse the hash table since the
|
||||||
linker script may have defined some symbols that are not in
|
linker script may have defined some symbols that are not in
|
||||||
any of the input files. The <<written>> field in the
|
any of the input files.
|
||||||
<<bfd_link_hash_entry>> structure may be used to determine
|
|
||||||
which entries in the hash table have not already been written
|
|
||||||
out.
|
|
||||||
|
|
||||||
The <<strip>> field of the <<bfd_link_info>> structure
|
The <<strip>> field of the <<bfd_link_info>> structure
|
||||||
controls which symbols are written out. The possible values
|
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
|
/* We are only interested if we know something about this
|
||||||
symbol, and it is undefined or common. An undefined weak
|
symbol, and it is undefined or common. An undefined weak
|
||||||
symbol (type bfd_link_hash_weak) is not considered to be a
|
symbol (type bfd_link_hash_undefweak) is not considered to be
|
||||||
reference when pulling files out of an archive. See the SVR4
|
a reference when pulling files out of an archive. See the
|
||||||
ABI, p. 4-27. */
|
SVR4 ABI, p. 4-27. */
|
||||||
h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
|
h = bfd_link_hash_lookup (info->hash, bfd_asymbol_name (p), false,
|
||||||
false, true);
|
false, true);
|
||||||
if (h == (struct bfd_link_hash_entry *) NULL
|
if (h == (struct bfd_link_hash_entry *) NULL
|
||||||
@ -1287,6 +1284,7 @@ enum link_action
|
|||||||
UND, /* Mark symbol undefined. */
|
UND, /* Mark symbol undefined. */
|
||||||
WEAK, /* Mark symbol weak undefined. */
|
WEAK, /* Mark symbol weak undefined. */
|
||||||
DEF, /* Mark symbol defined. */
|
DEF, /* Mark symbol defined. */
|
||||||
|
DEFW, /* Mark symbol weak defined. */
|
||||||
COM, /* Mark symbol common. */
|
COM, /* Mark symbol common. */
|
||||||
REF, /* Mark defined symbol referenced. */
|
REF, /* Mark defined symbol referenced. */
|
||||||
CREF, /* Possibly warn about common reference to defined symbol. */
|
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
|
/* The state table itself. The first index is a link_row and the
|
||||||
second index is a bfd_link_hash_type. */
|
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 */
|
/* current\prev new undef undefw def defw com indr warn */
|
||||||
/* UNDEF_ROW */ {UND, NOACT, NOACT, REF, NOACT, REFC, WARNC },
|
/* UNDEF_ROW */ {UND, NOACT, NOACT, REF, REF, NOACT, REFC, WARNC },
|
||||||
/* UNDEFW_ROW */ {WEAK, WEAK, NOACT, REF, NOACT, REFC, WARNC },
|
/* UNDEFW_ROW */ {WEAK, WEAK, NOACT, REF, REF, NOACT, REFC, WARNC },
|
||||||
/* DEF_ROW */ {DEF, DEF, DEF, MDEF, CDEF, MDEF, CYCLE },
|
/* DEF_ROW */ {DEF, DEF, DEF, MDEF, DEF, CDEF, MDEF, CYCLE },
|
||||||
/* DEFW_ROW */ {DEF, DEF, DEF, NOACT, NOACT, NOACT, CYCLE },
|
/* DEFW_ROW */ {DEFW, DEFW, DEFW, NOACT, NOACT, NOACT, NOACT, CYCLE },
|
||||||
/* COMMON_ROW */ {COM, COM, COM, CREF, BIG, CREF, WARNC },
|
/* COMMON_ROW */ {COM, COM, COM, CREF, CREF, BIG, CREF, WARNC },
|
||||||
/* INDR_ROW */ {IND, IND, IND, MDEF, CIND, MIND, CYCLE },
|
/* INDR_ROW */ {IND, IND, IND, MDEF, IND, CIND, MIND, CYCLE },
|
||||||
/* WARN_ROW */ {MWARN, WARN, WARN, CWARN, WARN, CWARN, CYCLE },
|
/* WARN_ROW */ {MWARN, WARN, WARN, CWARN, CWARN, WARN, CWARN, CYCLE },
|
||||||
/* SET_ROW */ {SET, SET, SET, SET, SET, CYCLE, CYCLE }
|
/* SET_ROW */ {SET, SET, SET, SET, SET, SET, CYCLE, CYCLE }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Most of the entries in the LINK_ACTION table are straightforward,
|
/* 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:
|
case WEAK:
|
||||||
/* Make a new weak undefined symbol. */
|
/* Make a new weak undefined symbol. */
|
||||||
h->type = bfd_link_hash_weak;
|
h->type = bfd_link_hash_undefweak;
|
||||||
h->u.undef.abfd = abfd;
|
h->u.undef.abfd = abfd;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1468,50 +1466,69 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
|
|||||||
return false;
|
return false;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case DEF:
|
case DEF:
|
||||||
/* Define a symbol. */
|
case DEFW:
|
||||||
h->type = bfd_link_hash_defined;
|
{
|
||||||
h->u.def.section = section;
|
enum bfd_link_order_type oldtype;
|
||||||
h->u.def.value = value;
|
|
||||||
|
|
||||||
/* If we have been asked to, we act like collect2 and
|
/* Define a symbol. */
|
||||||
identify all functions that might be global constructors
|
oldtype = h->type;
|
||||||
and destructors and pass them up in a callback. We only
|
if (action == DEFW)
|
||||||
do this for certain object file types, since many object
|
h->type = bfd_link_hash_defweak;
|
||||||
file types can handle this automatically. */
|
else
|
||||||
if (collect && name[0] == '_')
|
h->type = bfd_link_hash_defined;
|
||||||
{
|
h->u.def.section = section;
|
||||||
const char *s;
|
h->u.def.value = value;
|
||||||
|
|
||||||
/* A constructor or destructor name starts like this:
|
/* If we have been asked to, we act like collect2 and
|
||||||
_+GLOBAL_[_.$][ID][_.$]
|
identify all functions that might be global
|
||||||
where the first [_.$] and the second are the same
|
constructors and destructors and pass them up in a
|
||||||
character (we accept any character there, in case a
|
callback. We only do this for certain object file
|
||||||
new object file format comes along with even worse
|
types, since many object file types can handle this
|
||||||
naming restrictions). */
|
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 "GLOBAL_"
|
||||||
#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1)
|
#define CONS_PREFIX_LEN (sizeof CONS_PREFIX - 1)
|
||||||
|
|
||||||
s = name + 1;
|
s = name + 1;
|
||||||
while (*s == '_')
|
while (*s == '_')
|
||||||
++s;
|
++s;
|
||||||
if (s[0] == 'G'
|
if (s[0] == 'G'
|
||||||
&& strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0)
|
&& strncmp (s, CONS_PREFIX, CONS_PREFIX_LEN - 1) == 0)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
c = s[CONS_PREFIX_LEN + 1];
|
c = s[CONS_PREFIX_LEN + 1];
|
||||||
if ((c == 'I' || c == 'D')
|
if ((c == 'I' || c == 'D')
|
||||||
&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
|
&& s[CONS_PREFIX_LEN] == s[CONS_PREFIX_LEN + 2])
|
||||||
{
|
{
|
||||||
if (! ((*info->callbacks->constructor)
|
/* If this is a definition of a symbol which
|
||||||
(info,
|
was previously weakly defined, we are in
|
||||||
c == 'I' ? true : false,
|
trouble. We have already added a
|
||||||
name, abfd, section, value)))
|
constructor entry for the weak defined
|
||||||
return false;
|
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;
|
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
|
was already defined. FIXME: It would nice if we could
|
||||||
report the BFD which defined an indirect symbol, but we
|
report the BFD which defined an indirect symbol, but we
|
||||||
don't have anywhere to store the information. */
|
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;
|
obfd = h->u.def.section->owner;
|
||||||
else
|
else
|
||||||
obfd = NULL;
|
obfd = NULL;
|
||||||
@ -1631,10 +1649,6 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
|
|||||||
msec = h->u.def.section;
|
msec = h->u.def.section;
|
||||||
mval = h->u.def.value;
|
mval = h->u.def.value;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_common:
|
|
||||||
msec = bfd_com_section_ptr;
|
|
||||||
mval = h->u.c.size;
|
|
||||||
break;
|
|
||||||
case bfd_link_hash_indirect:
|
case bfd_link_hash_indirect:
|
||||||
msec = bfd_ind_section_ptr;
|
msec = bfd_ind_section_ptr;
|
||||||
mval = 0;
|
mval = 0;
|
||||||
@ -1738,10 +1752,10 @@ _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value,
|
|||||||
|
|
||||||
case CWARN:
|
case CWARN:
|
||||||
/* Warn if this symbol has been referenced already,
|
/* Warn if this symbol has been referenced already,
|
||||||
otherwise either add a warning or cycle. A symbol has
|
otherwise add a warning. A symbol has been referenced if
|
||||||
been referenced if the next field is not NULL, or it is
|
the next field is not NULL, or it is the tail of the
|
||||||
the tail of the undefined symbol list. The REF case
|
undefined symbol list. The REF case above helps to
|
||||||
above helps to ensure this. */
|
ensure this. */
|
||||||
if (h->next != NULL || info->hash->undefs_tail == h)
|
if (h->next != NULL || info->hash->undefs_tail == h)
|
||||||
{
|
{
|
||||||
if (! (*info->callbacks->warning) (info, string))
|
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:
|
case bfd_link_hash_new:
|
||||||
abort ();
|
abort ();
|
||||||
case bfd_link_hash_undefined:
|
case bfd_link_hash_undefined:
|
||||||
case bfd_link_hash_weak:
|
break;
|
||||||
|
case bfd_link_hash_undefweak:
|
||||||
|
sym->flags |= BSF_WEAK;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_defined:
|
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->value = h->root.u.def.value;
|
||||||
sym->section = h->root.u.def.section;
|
sym->section = h->root.u.def.section;
|
||||||
sym->flags |= BSF_GLOBAL;
|
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_common:
|
case bfd_link_hash_common:
|
||||||
sym->value = h->root.u.c.size;
|
sym->value = h->root.u.c.size;
|
||||||
@ -2160,7 +2181,7 @@ set_symbol_from_hash (sym, h)
|
|||||||
sym->section = bfd_und_section_ptr;
|
sym->section = bfd_und_section_ptr;
|
||||||
sym->value = 0;
|
sym->value = 0;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_weak:
|
case bfd_link_hash_undefweak:
|
||||||
sym->section = bfd_und_section_ptr;
|
sym->section = bfd_und_section_ptr;
|
||||||
sym->value = 0;
|
sym->value = 0;
|
||||||
sym->flags |= BSF_WEAK;
|
sym->flags |= BSF_WEAK;
|
||||||
@ -2169,6 +2190,11 @@ set_symbol_from_hash (sym, h)
|
|||||||
sym->section = h->u.def.section;
|
sym->section = h->u.def.section;
|
||||||
sym->value = h->u.def.value;
|
sym->value = h->u.def.value;
|
||||||
break;
|
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:
|
case bfd_link_hash_common:
|
||||||
sym->value = h->u.c.size;
|
sym->value = h->u.c.size;
|
||||||
if (sym->section == NULL)
|
if (sym->section == NULL)
|
||||||
@ -2263,7 +2289,7 @@ _bfd_generic_reloc_link_order (abfd, info, sec, link_order)
|
|||||||
|
|
||||||
r->address = link_order->offset;
|
r->address = link_order->offset;
|
||||||
r->howto = bfd_reloc_type_lookup (abfd, link_order->u.reloc.p->reloc);
|
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);
|
bfd_set_error (bfd_error_bad_value);
|
||||||
return false;
|
return false;
|
||||||
|
38
bfd/sunos.c
38
bfd/sunos.c
@ -1,5 +1,5 @@
|
|||||||
/* BFD backend for SunOS binaries.
|
/* 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.
|
Written by Cygnus Support.
|
||||||
|
|
||||||
This file is part of BFD, the Binary File Descriptor library.
|
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)
|
if (! bfd_is_und_section (section)
|
||||||
&& h->root.root.type != bfd_link_hash_new
|
&& 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
|
/* We are defining the symbol, and it is already defined. This
|
||||||
is a potential multiple definition error. */
|
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
|
/* At this point common symbols have already been allocated, so
|
||||||
we don't have to worry about them. We need to consider that
|
we don't have to worry about them. We need to consider that
|
||||||
we may have already seen this symbol and marked it undefined;
|
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. */
|
will be zero. */
|
||||||
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.type != bfd_link_hash_undefined)
|
&& h->root.root.type != bfd_link_hash_undefined)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1308,7 +1310,8 @@ sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
|
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.def.section->owner->flags & DYNAMIC) != 0
|
||||||
: (h->root.root.u.undef.abfd->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
|
if the symbols is really undefined, then SUNOS_DEF_DYNAMIC
|
||||||
will be zero. */
|
will be zero. */
|
||||||
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.type != bfd_link_hash_undefined)
|
&& h->root.root.type != bfd_link_hash_undefined)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1452,7 +1456,8 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
|
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.def.section->owner->flags & DYNAMIC) != 0
|
||||||
: (h->root.root.u.undef.abfd->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_DEF_DYNAMIC) != 0
|
||||||
&& (h->flags & SUNOS_REF_REGULAR) != 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->owner->flags & DYNAMIC) != 0)
|
||||||
&& h->root.root.u.def.section->output_section == NULL)
|
&& h->root.root.u.def.section->output_section == NULL)
|
||||||
{
|
{
|
||||||
@ -1665,6 +1671,7 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
|
|||||||
val = 0;
|
val = 0;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_defined:
|
case bfd_link_hash_defined:
|
||||||
|
case bfd_link_hash_defweak:
|
||||||
{
|
{
|
||||||
asection *sec;
|
asection *sec;
|
||||||
asection *output_section;
|
asection *output_section;
|
||||||
@ -1682,13 +1689,22 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (output_section == obj_textsec (output_bfd))
|
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))
|
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))
|
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
|
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
|
val = (h->root.root.u.def.value
|
||||||
+ output_section->vma
|
+ output_section->vma
|
||||||
+ sec->output_offset);
|
+ sec->output_offset);
|
||||||
@ -1699,7 +1715,7 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
|
|||||||
type = N_UNDF | N_EXT;
|
type = N_UNDF | N_EXT;
|
||||||
val = h->root.root.u.c.size;
|
val = h->root.root.u.c.size;
|
||||||
break;
|
break;
|
||||||
case bfd_link_hash_weak:
|
case bfd_link_hash_undefweak:
|
||||||
type = N_WEAKU;
|
type = N_WEAKU;
|
||||||
val = 0;
|
val = 0;
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user