* sunos.c (sunos_add_one_symbol): Don't change

bfd_link_hash_common to bfd_link_hash_new, since it may be on the
	undef list.
	(bfd_sunos_record_link_assignment): Don't put __DYNAMIC in the
	dynamic symbols when creating a shared library.
	(sunos_scan_ext_relocs): Handle relocs correctly when creating a
	shared library.
	(sunos_scan_dynamic_symbol): Don't mark the __DYNAMIC symbol as
	written even if it is not defined in a regular object.
	(sunos_write_dynamic_symbol): Use plt_offset for the address of
	the jump table reloc.  Add an assertion.  Use RELOC_JMP_SLOT
	rather than the constant 22.
	(sunos_check_dynamic_reloc): Handle creating a shared library.
	(sunos_finish_dynamic_link): Set the first entry in the GOT to
	zero when creating a shared library.
	* aoutx.h (NAME(aout,final_link)): If there is a symbol __DYNAMIC,
	write it out at the start of the symbol table.
This commit is contained in:
Ian Lance Taylor 1995-09-28 16:30:54 +00:00
parent 11b072f46c
commit 9db5923077
2 changed files with 224 additions and 85 deletions

View File

@ -1,5 +1,23 @@
Thu Sep 28 11:19:53 1995 Ian Lance Taylor <ian@cygnus.com> Thu Sep 28 11:19:53 1995 Ian Lance Taylor <ian@cygnus.com>
* sunos.c (sunos_add_one_symbol): Don't change
bfd_link_hash_common to bfd_link_hash_new, since it may be on the
undef list.
(bfd_sunos_record_link_assignment): Don't put __DYNAMIC in the
dynamic symbols when creating a shared library.
(sunos_scan_ext_relocs): Handle relocs correctly when creating a
shared library.
(sunos_scan_dynamic_symbol): Don't mark the __DYNAMIC symbol as
written even if it is not defined in a regular object.
(sunos_write_dynamic_symbol): Use plt_offset for the address of
the jump table reloc. Add an assertion. Use RELOC_JMP_SLOT
rather than the constant 22.
(sunos_check_dynamic_reloc): Handle creating a shared library.
(sunos_finish_dynamic_link): Set the first entry in the GOT to
zero when creating a shared library.
* aoutx.h (NAME(aout,final_link)): If there is a symbol __DYNAMIC,
write it out at the start of the symbol table.
* Makefile.in (BFD32_BACKENDS): Add coff-arm.o. * Makefile.in (BFD32_BACKENDS): Add coff-arm.o.
Thu Sep 28 00:58:05 1995 Doug Evans <dje@deneb.cygnus.com> Thu Sep 28 00:58:05 1995 Doug Evans <dje@deneb.cygnus.com>

View File

@ -1008,18 +1008,25 @@ sunos_add_one_symbol (info, abfd, name, flags, section, value, string,
reference. */ reference. */
section = bfd_und_section_ptr; section = bfd_und_section_ptr;
} }
else if ((h->root.root.type == bfd_link_hash_defined else if (h->root.root.type == bfd_link_hash_defined
&& h->root.root.u.def.section->owner != NULL && h->root.root.u.def.section->owner != NULL
&& (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
|| (h->root.root.type == bfd_link_hash_common
&& ((h->root.root.u.c.p->section->owner->flags & DYNAMIC)
!= 0)))
{ {
/* The existing definition is from a dynamic object. We /* The existing definition is from a dynamic object. We
want to override it with the definition we just found. want to override it with the definition we just found.
Clobber the existing definition. */ Clobber the existing definition. */
h->root.root.type = bfd_link_hash_new; h->root.root.type = bfd_link_hash_new;
} }
else if (h->root.root.type == bfd_link_hash_common
&& (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0)
{
/* The existing definition is from a dynamic object. We
want to override it with the definition we just found.
Clobber the existing definition. We can't set it to new,
because it is on the undefined list. */
h->root.root.type = bfd_link_hash_undefined;
h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner;
}
} }
/* Do the usual procedure for adding a symbol. */ /* Do the usual procedure for adding a symbol. */
@ -1081,12 +1088,17 @@ bfd_sunos_record_link_assignment (output_bfd, info, name)
if (h == NULL) if (h == NULL)
return true; return true;
h->flags |= SUNOS_DEF_REGULAR; /* In a shared library, the __DYNAMIC symbol does not appear in the
dynamic symbol table. */
if (h->dynindx == -1) if (! info->shared || strcmp (name, "__DYNAMIC") != 0)
{ {
++sunos_hash_table (info)->dynsymcount; h->flags |= SUNOS_DEF_REGULAR;
h->dynindx = -2;
if (h->dynindx == -1)
{
++sunos_hash_table (info)->dynsymcount;
h->dynindx = -2;
}
} }
return true; return true;
@ -1675,7 +1687,36 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
defined in dynamic objects but not in regular objects. We defined in dynamic objects but not in regular objects. We
only need to consider relocs against external symbols. */ only need to consider relocs against external symbols. */
if (! r_extern) if (! r_extern)
continue; {
/* But, if we are creating a shared library, we need to
generate an absolute reloc. */
if (info->shared)
{
if (sec == obj_textsec (abfd))
{
(*_bfd_error_handler)
("%s: may not have .text section relocs in shared library",
bfd_get_filename (abfd));
bfd_set_error (bfd_error_nonrepresentable_section);
return false;
}
if (dynobj == NULL)
{
if (! sunos_create_dynamic_sections (abfd, info, true))
return false;
dynobj = sunos_hash_table (info)->dynobj;
splt = bfd_get_section_by_name (dynobj, ".plt");
sgot = bfd_get_section_by_name (dynobj, ".got");
srel = bfd_get_section_by_name (dynobj, ".dynrel");
BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
}
srel->_raw_size += RELOC_EXT_SIZE;
}
continue;
}
/* 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
@ -1688,6 +1729,7 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
continue; continue;
if (r_type != RELOC_JMP_TBL if (r_type != RELOC_JMP_TBL
&& ! info->shared
&& ((h->flags & SUNOS_DEF_DYNAMIC) == 0 && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
|| (h->flags & SUNOS_DEF_REGULAR) != 0)) || (h->flags & SUNOS_DEF_REGULAR) != 0))
continue; continue;
@ -1709,6 +1751,7 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
BFD_ASSERT (r_type == RELOC_JMP_TBL BFD_ASSERT (r_type == RELOC_JMP_TBL
|| (h->flags & SUNOS_REF_REGULAR) != 0); || (h->flags & SUNOS_REF_REGULAR) != 0);
BFD_ASSERT (r_type == RELOC_JMP_TBL BFD_ASSERT (r_type == RELOC_JMP_TBL
|| info->shared
|| h->plt_offset != 0 || h->plt_offset != 0
|| ((h->root.root.type == bfd_link_hash_defined || ((h->root.root.type == bfd_link_hash_defined
|| h->root.root.type == bfd_link_hash_defweak) || h->root.root.type == bfd_link_hash_defweak)
@ -1719,24 +1762,28 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
/* This reloc is against a symbol defined only by a dynamic /* This reloc is against a symbol defined only by a dynamic
object, or it is a jump table reloc from PIC compiled code. */ object, or it is a jump table reloc from PIC compiled code. */
if (h->root.root.type == bfd_link_hash_undefined) if (r_type != RELOC_JMP_TBL
&& h->root.root.type == bfd_link_hash_undefined)
{ {
/* Presumably this symbol was marked as being undefined by /* Presumably this symbol was marked as being undefined by
an earlier reloc. */ an earlier reloc. */
srel->_raw_size += RELOC_EXT_SIZE; srel->_raw_size += RELOC_EXT_SIZE;
} }
else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0) else if (r_type != RELOC_JMP_TBL
&& (h->root.root.u.def.section->flags & SEC_CODE) == 0)
{ {
bfd *sub; bfd *sub;
/* This reloc is not in the .text section. It must be /* This reloc is not in the .text section. It must be
copied into the dynamic relocs. We mark the symbol as copied into the dynamic relocs. We mark the symbol as
being undefined. */ being undefined. */
BFD_ASSERT (r_type != RELOC_JMP_TBL);
srel->_raw_size += RELOC_EXT_SIZE; srel->_raw_size += RELOC_EXT_SIZE;
sub = h->root.root.u.def.section->owner; if ((h->flags & SUNOS_DEF_REGULAR) == 0)
h->root.root.type = bfd_link_hash_undefined; {
h->root.root.u.undef.abfd = sub; sub = h->root.root.u.def.section->owner;
h->root.root.type = bfd_link_hash_undefined;
h->root.root.u.undef.abfd = sub;
}
} }
else else
{ {
@ -1753,6 +1800,8 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
if ((h->flags & SUNOS_DEF_REGULAR) == 0) if ((h->flags & SUNOS_DEF_REGULAR) == 0)
{ {
if (h->root.root.type == bfd_link_hash_undefined)
h->root.root.type = bfd_link_hash_defined;
h->root.root.u.def.section = splt; h->root.root.u.def.section = splt;
h->root.root.u.def.value = splt->_raw_size; h->root.root.u.def.value = splt->_raw_size;
} }
@ -1765,6 +1814,11 @@ sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
srel->_raw_size += RELOC_EXT_SIZE; srel->_raw_size += RELOC_EXT_SIZE;
} }
/* If we are creating a shared library, we need to copy over
any reloc other than a jump table reloc. */
if (info->shared && r_type != RELOC_JMP_TBL)
srel->_raw_size += RELOC_EXT_SIZE;
} }
} }
@ -1786,7 +1840,8 @@ sunos_scan_dynamic_symbol (h, data)
not defined in a regular object file. For some reason symbols not defined in a regular object file. For some reason symbols
which are referenced by a regular object and defined by a dynamic which are referenced by a regular object and defined by a dynamic
object do not seem to show up in the regular symbol table. */ object do not seem to show up in the regular symbol table. */
if ((h->flags & SUNOS_DEF_REGULAR) == 0) if ((h->flags & SUNOS_DEF_REGULAR) == 0
&& strcmp (h->root.root.root.string, "__DYNAMIC") != 0)
h->root.written = true; h->root.written = true;
/* If this symbol is defined by a dynamic object and referenced by a /* If this symbol is defined by a dynamic object and referenced by a
@ -2021,9 +2076,9 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
s = bfd_get_section_by_name (dynobj, ".dynrel"); s = bfd_get_section_by_name (dynobj, ".dynrel");
r_address = (h->root.root.u.def.section->output_section->vma r_address = (splt->output_section->vma
+ h->root.root.u.def.section->output_offset + splt->output_offset
+ h->root.root.u.def.value); + h->plt_offset);
switch (bfd_get_arch (output_bfd)) switch (bfd_get_arch (output_bfd))
{ {
@ -2073,6 +2128,8 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
result of a JMP_TBL reloc from PIC compiled code. */ result of a JMP_TBL reloc from PIC compiled code. */
if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0) if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
{ {
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
< s->_raw_size);
p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd); p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd);
if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE) if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE)
{ {
@ -2108,16 +2165,18 @@ sunos_write_dynamic_symbol (output_bfd, info, harg)
erel->r_index[0] = h->dynindx >> 16; erel->r_index[0] = h->dynindx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = h->dynindx >> 8;
erel->r_index[2] = h->dynindx; erel->r_index[2] = h->dynindx;
erel->r_type[0] = (RELOC_EXT_BITS_EXTERN_BIG erel->r_type[0] =
| (22 << RELOC_EXT_BITS_TYPE_SH_BIG)); (RELOC_EXT_BITS_EXTERN_BIG
| (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG));
} }
else else
{ {
erel->r_index[2] = h->dynindx >> 16; erel->r_index[2] = h->dynindx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = h->dynindx >> 8;
erel->r_index[0] = h->dynindx; erel->r_index[0] = h->dynindx;
erel->r_type[0] = (RELOC_EXT_BITS_EXTERN_LITTLE erel->r_type[0] =
| (22 << RELOC_EXT_BITS_TYPE_SH_LITTLE)); (RELOC_EXT_BITS_EXTERN_LITTLE
| (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE));
} }
PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend); PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend);
} }
@ -2150,8 +2209,10 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg; struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
bfd *dynobj; bfd *dynobj;
boolean baserel; boolean baserel;
boolean jmptbl;
asection *s; asection *s;
bfd_byte *p; bfd_byte *p;
long indx;
*skip = false; *skip = false;
@ -2174,9 +2235,15 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
srel = (struct reloc_std_external *) reloc; srel = (struct reloc_std_external *) reloc;
if (input_bfd->xvec->header_byteorder_big_p) if (input_bfd->xvec->header_byteorder_big_p)
baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG)); {
baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
}
else else
baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE)); {
baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
}
} }
else else
{ {
@ -2193,6 +2260,7 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
baserel = (r_type == RELOC_BASE10 baserel = (r_type == RELOC_BASE10
|| r_type == RELOC_BASE13 || r_type == RELOC_BASE13
|| r_type == RELOC_BASE22); || r_type == RELOC_BASE22);
jmptbl = r_type == RELOC_JMP_TBL;
} }
if (baserel) if (baserel)
@ -2247,21 +2315,35 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
already initialized the GOT entry. */ already initialized the GOT entry. */
if ((*got_offsetp & 1) == 0) if ((*got_offsetp & 1) == 0)
{ {
PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp); if (h == NULL
|| (! info->shared
&& ((h->flags & SUNOS_DEF_DYNAMIC) == 0
|| (h->flags & SUNOS_DEF_REGULAR) != 0)))
PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp);
else
PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp);
if (h != NULL if (info->shared
&& (h->flags & SUNOS_DEF_DYNAMIC) != 0 || (h != NULL
&& (h->flags & SUNOS_DEF_REGULAR) == 0) && (h->flags & SUNOS_DEF_DYNAMIC) != 0
&& (h->flags & SUNOS_DEF_REGULAR) == 0))
{ {
/* We need to create a GLOB_DAT reloc to tell the /* We need to create a GLOB_DAT or 32 reloc to tell the
dynamic linker to fill in this entry in the table. */ dynamic linker to fill in this entry in the table. */
s = bfd_get_section_by_name (dynobj, ".dynrel"); s = bfd_get_section_by_name (dynobj, ".dynrel");
BFD_ASSERT (s != NULL); BFD_ASSERT (s != NULL);
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
< s->_raw_size);
p = (s->contents p = (s->contents
+ s->reloc_count * obj_reloc_entry_size (dynobj)); + s->reloc_count * obj_reloc_entry_size (dynobj));
if (h != NULL)
indx = h->dynindx;
else
indx = 0;
if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
{ {
struct reloc_std_external *srel; struct reloc_std_external *srel;
@ -2274,25 +2356,31 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
srel->r_address); srel->r_address);
if (dynobj->xvec->header_byteorder_big_p) if (dynobj->xvec->header_byteorder_big_p)
{ {
srel->r_index[0] = h->dynindx >> 16; srel->r_index[0] = indx >> 16;
srel->r_index[1] = h->dynindx >> 8; srel->r_index[1] = indx >> 8;
srel->r_index[2] = h->dynindx; srel->r_index[2] = indx;
srel->r_type[0] = if (h == NULL)
(RELOC_STD_BITS_EXTERN_BIG srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG;
| RELOC_STD_BITS_BASEREL_BIG else
| RELOC_STD_BITS_RELATIVE_BIG srel->r_type[0] =
| (2 << RELOC_STD_BITS_LENGTH_SH_BIG)); (RELOC_STD_BITS_EXTERN_BIG
| RELOC_STD_BITS_BASEREL_BIG
| RELOC_STD_BITS_RELATIVE_BIG
| (2 << RELOC_STD_BITS_LENGTH_SH_BIG));
} }
else else
{ {
srel->r_index[2] = h->dynindx >> 16; srel->r_index[2] = indx >> 16;
srel->r_index[1] = h->dynindx >> 8; srel->r_index[1] = indx >> 8;
srel->r_index[0] = h->dynindx; srel->r_index[0] = indx;
srel->r_type[0] = if (h == NULL)
(RELOC_STD_BITS_EXTERN_LITTLE srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE;
| RELOC_STD_BITS_BASEREL_LITTLE else
| RELOC_STD_BITS_RELATIVE_LITTLE srel->r_type[0] =
| (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE)); (RELOC_STD_BITS_EXTERN_LITTLE
| RELOC_STD_BITS_BASEREL_LITTLE
| RELOC_STD_BITS_RELATIVE_LITTLE
| (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE));
} }
} }
else else
@ -2307,21 +2395,30 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
erel->r_address); erel->r_address);
if (dynobj->xvec->header_byteorder_big_p) if (dynobj->xvec->header_byteorder_big_p)
{ {
erel->r_index[0] = h->dynindx >> 16; erel->r_index[0] = indx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = indx >> 8;
erel->r_index[2] = h->dynindx; erel->r_index[2] = indx;
erel->r_type[0] = if (h == NULL)
(RELOC_EXT_BITS_EXTERN_BIG erel->r_type[0] =
| (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG)); RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG;
else
erel->r_type[0] =
(RELOC_EXT_BITS_EXTERN_BIG
| (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG));
} }
else else
{ {
erel->r_index[2] = h->dynindx >> 16; erel->r_index[2] = indx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = indx >> 8;
erel->r_index[0] = h->dynindx; erel->r_index[0] = indx;
erel->r_type[0] = if (h == NULL)
(RELOC_EXT_BITS_EXTERN_LITTLE erel->r_type[0] =
| (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_LITTLE)); RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE;
else
erel->r_type[0] =
(RELOC_EXT_BITS_EXTERN_LITTLE
| (RELOC_GLOB_DAT
<< RELOC_EXT_BITS_TYPE_SH_LITTLE));
} }
PUT_WORD (dynobj, 0, erel->r_addend); PUT_WORD (dynobj, 0, erel->r_addend);
} }
@ -2338,25 +2435,45 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
return true; return true;
} }
if (! sunos_hash_table (info)->dynamic_sections_needed if (! sunos_hash_table (info)->dynamic_sections_needed)
|| h == NULL
|| h->dynindx == -1
|| h->root.root.type != bfd_link_hash_undefined
|| (h->flags & SUNOS_DEF_REGULAR) != 0
|| (h->flags & SUNOS_DEF_DYNAMIC) == 0
|| (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
return true; return true;
if (! info->shared)
{
if (h == NULL
|| h->dynindx == -1
|| h->root.root.type != bfd_link_hash_undefined
|| (h->flags & SUNOS_DEF_REGULAR) != 0
|| (h->flags & SUNOS_DEF_DYNAMIC) == 0
|| (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
return true;
}
else
{
if (h != NULL
&& (h->dynindx == -1
|| jmptbl
|| strcmp (h->root.root.root.string,
"__GLOBAL_OFFSET_TABLE_") == 0))
return true;
BFD_ASSERT (input_section != obj_textsec (input_bfd));
}
/* It looks like this is a reloc we are supposed to copy. */ /* It looks like this is a reloc we are supposed to copy. */
s = bfd_get_section_by_name (dynobj, ".dynrel"); s = bfd_get_section_by_name (dynobj, ".dynrel");
BFD_ASSERT (s != NULL); BFD_ASSERT (s != NULL);
BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size);
p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj); p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj);
/* Copy the reloc over. */ /* Copy the reloc over. */
memcpy (p, reloc, obj_reloc_entry_size (dynobj)); memcpy (p, reloc, obj_reloc_entry_size (dynobj));
if (h != NULL)
indx = h->dynindx;
else
indx = 0;
/* Adjust the address and symbol index. */ /* Adjust the address and symbol index. */
if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE) if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
{ {
@ -2370,15 +2487,15 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
srel->r_address); srel->r_address);
if (dynobj->xvec->header_byteorder_big_p) if (dynobj->xvec->header_byteorder_big_p)
{ {
srel->r_index[0] = h->dynindx >> 16; srel->r_index[0] = indx >> 16;
srel->r_index[1] = h->dynindx >> 8; srel->r_index[1] = indx >> 8;
srel->r_index[2] = h->dynindx; srel->r_index[2] = indx;
} }
else else
{ {
srel->r_index[2] = h->dynindx >> 16; srel->r_index[2] = indx >> 16;
srel->r_index[1] = h->dynindx >> 8; srel->r_index[1] = indx >> 8;
srel->r_index[0] = h->dynindx; srel->r_index[0] = indx;
} }
} }
else else
@ -2393,21 +2510,22 @@ sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
erel->r_address); erel->r_address);
if (dynobj->xvec->header_byteorder_big_p) if (dynobj->xvec->header_byteorder_big_p)
{ {
erel->r_index[0] = h->dynindx >> 16; erel->r_index[0] = indx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = indx >> 8;
erel->r_index[2] = h->dynindx; erel->r_index[2] = indx;
} }
else else
{ {
erel->r_index[2] = h->dynindx >> 16; erel->r_index[2] = indx >> 16;
erel->r_index[1] = h->dynindx >> 8; erel->r_index[1] = indx >> 8;
erel->r_index[0] = h->dynindx; erel->r_index[0] = indx;
} }
} }
++s->reloc_count; ++s->reloc_count;
*skip = true; if (h != NULL)
*skip = true;
return true; return true;
} }
@ -2459,12 +2577,15 @@ sunos_finish_dynamic_link (abfd, info)
} }
} }
/* The first entry in the .got section is the address of the dynamic /* The first entry in the .got section is the address of the
information. */ dynamic information, unless this is a shared library. */
s = bfd_get_section_by_name (dynobj, ".got"); s = bfd_get_section_by_name (dynobj, ".got");
BFD_ASSERT (s != NULL); BFD_ASSERT (s != NULL);
PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset, if (info->shared)
s->contents); PUT_WORD (dynobj, 0, s->contents);
else
PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset,
s->contents);
for (o = dynobj->sections; o != NULL; o = o->next) for (o = dynobj->sections; o != NULL; o = o->next)
{ {