mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
get symndx right for TOC relative relocs
This commit is contained in:
@ -242,9 +242,15 @@ struct xcoff_link_hash_entry
|
|||||||
section which holds it. */
|
section which holds it. */
|
||||||
asection *toc_section;
|
asection *toc_section;
|
||||||
|
|
||||||
/* If we have created a TOC entry, this is the offset in
|
union
|
||||||
toc_section. */
|
{
|
||||||
bfd_vma toc_offset;
|
/* If we have created a TOC entry (the XCOFF_SET_TOC flag is
|
||||||
|
set), this is the offset in toc_section. */
|
||||||
|
bfd_vma toc_offset;
|
||||||
|
/* If the TOC entry comes from an input file, this is set to the
|
||||||
|
symbo lindex of the C_HIDEXT XMC_TC symbol. */
|
||||||
|
long toc_indx;
|
||||||
|
} u;
|
||||||
|
|
||||||
/* If this symbol is a function entry point which is called, this
|
/* If this symbol is a function entry point which is called, this
|
||||||
field holds a pointer to the function descriptor. */
|
field holds a pointer to the function descriptor. */
|
||||||
@ -505,7 +511,7 @@ xcoff_link_hash_newfunc (entry, table, string)
|
|||||||
/* Set local fields. */
|
/* Set local fields. */
|
||||||
ret->indx = -1;
|
ret->indx = -1;
|
||||||
ret->toc_section = NULL;
|
ret->toc_section = NULL;
|
||||||
ret->toc_offset = 0;
|
ret->u.toc_indx = -1;
|
||||||
ret->descriptor = NULL;
|
ret->descriptor = NULL;
|
||||||
ret->ldsym = NULL;
|
ret->ldsym = NULL;
|
||||||
ret->ldindx = -1;
|
ret->ldindx = -1;
|
||||||
@ -1385,10 +1391,7 @@ xcoff_link_add_symbols (abfd, info)
|
|||||||
|
|
||||||
/* If this is a TOC section for a symbol, record it. */
|
/* If this is a TOC section for a symbol, record it. */
|
||||||
if (set_toc != NULL)
|
if (set_toc != NULL)
|
||||||
{
|
set_toc->toc_section = csect;
|
||||||
set_toc->toc_section = csect;
|
|
||||||
set_toc->toc_offset = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2562,7 +2565,7 @@ xcoff_build_ldsyms (h, p)
|
|||||||
if (hds->toc_section == NULL)
|
if (hds->toc_section == NULL)
|
||||||
{
|
{
|
||||||
hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
|
hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section;
|
||||||
hds->toc_offset = hds->toc_section->_raw_size;
|
hds->u.toc_offset = hds->toc_section->_raw_size;
|
||||||
hds->toc_section->_raw_size += 4;
|
hds->toc_section->_raw_size += 4;
|
||||||
++xcoff_hash_table (ldinfo->info)->ldrel_count;
|
++xcoff_hash_table (ldinfo->info)->ldrel_count;
|
||||||
++hds->toc_section->reloc_count;
|
++hds->toc_section->reloc_count;
|
||||||
@ -3658,6 +3661,18 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
|||||||
h->indx = output_index;
|
h->indx = output_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If this is a symbol in the TOC which we may have merged
|
||||||
|
(class XMC_TC), remember the symbol index of the TOC
|
||||||
|
symbol. */
|
||||||
|
if (isym.n_sclass == C_HIDEXT
|
||||||
|
&& aux.x_csect.x_smclas == XMC_TC
|
||||||
|
&& *sym_hash != NULL)
|
||||||
|
{
|
||||||
|
BFD_ASSERT (((*sym_hash)->flags & XCOFF_SET_TOC) == 0);
|
||||||
|
BFD_ASSERT ((*sym_hash)->toc_section != NULL);
|
||||||
|
(*sym_hash)->u.toc_indx = output_index;
|
||||||
|
}
|
||||||
|
|
||||||
output_index += add;
|
output_index += add;
|
||||||
outsym += add * osymesz;
|
outsym += add * osymesz;
|
||||||
}
|
}
|
||||||
@ -4044,7 +4059,34 @@ xcoff_link_input_bfd (finfo, input_bfd)
|
|||||||
if (r_symndx != -1)
|
if (r_symndx != -1)
|
||||||
{
|
{
|
||||||
h = obj_xcoff_sym_hashes (input_bfd)[r_symndx];
|
h = obj_xcoff_sym_hashes (input_bfd)[r_symndx];
|
||||||
if (h != NULL)
|
if (h != NULL
|
||||||
|
&& (irel->r_type == R_TOC
|
||||||
|
|| irel->r_type == R_GL
|
||||||
|
|| irel->r_type == R_TCL
|
||||||
|
|| irel->r_type == R_TRL
|
||||||
|
|| irel->r_type == R_TRLA))
|
||||||
|
{
|
||||||
|
/* This is a TOC relative reloc with a symbol
|
||||||
|
attached. The symbol should be the one which
|
||||||
|
this reloc is for. We want to make this
|
||||||
|
reloc against the TOC address of the symbol,
|
||||||
|
not the symbol itself. */
|
||||||
|
BFD_ASSERT (h->toc_section != NULL);
|
||||||
|
BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
|
||||||
|
if (h->u.toc_indx == -1)
|
||||||
|
{
|
||||||
|
/* We could handle this case if we had to,
|
||||||
|
but I don't think it can arise. */
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
("%s: unattached TOC reloc against `%s'",
|
||||||
|
bfd_get_filename (input_bfd),
|
||||||
|
h->root.root.string);
|
||||||
|
bfd_set_error (bfd_error_bad_value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
irel->r_symndx = h->u.toc_indx;
|
||||||
|
}
|
||||||
|
else if (h != NULL)
|
||||||
{
|
{
|
||||||
/* This is a global symbol. */
|
/* This is a global symbol. */
|
||||||
if (h->indx >= 0)
|
if (h->indx >= 0)
|
||||||
@ -4344,8 +4386,9 @@ xcoff_write_global_symbol (h, p)
|
|||||||
specific TOC element. */
|
specific TOC element. */
|
||||||
tocoff = (h->descriptor->toc_section->output_section->vma
|
tocoff = (h->descriptor->toc_section->output_section->vma
|
||||||
+ h->descriptor->toc_section->output_offset
|
+ h->descriptor->toc_section->output_offset
|
||||||
+ h->descriptor->toc_offset
|
|
||||||
- xcoff_data (output_bfd)->toc);
|
- xcoff_data (output_bfd)->toc);
|
||||||
|
if ((h->descriptor->flags & XCOFF_SET_TOC) != 0)
|
||||||
|
tocoff += h->descriptor->u.toc_offset;
|
||||||
bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | tocoff, p);
|
bfd_put_32 (output_bfd, XCOFF_GLINK_FIRST | tocoff, p);
|
||||||
for (i = 0, p += 4;
|
for (i = 0, p += 4;
|
||||||
i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0];
|
i < sizeof xcoff_glink_code / sizeof xcoff_glink_code[0];
|
||||||
@ -4369,7 +4412,7 @@ xcoff_write_global_symbol (h, p)
|
|||||||
irel = finfo->section_info[oindx].relocs + osec->reloc_count;
|
irel = finfo->section_info[oindx].relocs + osec->reloc_count;
|
||||||
irel->r_vaddr = (osec->vma
|
irel->r_vaddr = (osec->vma
|
||||||
+ tocsec->output_offset
|
+ tocsec->output_offset
|
||||||
+ h->toc_offset);
|
+ h->u.toc_offset);
|
||||||
if (h->indx >= 0)
|
if (h->indx >= 0)
|
||||||
irel->r_symndx = h->indx;
|
irel->r_symndx = h->indx;
|
||||||
else
|
else
|
||||||
@ -4838,9 +4881,11 @@ _bfd_ppc_xcoff_relocate_section (output_bfd, info, input_bfd,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
val = (h->toc_section->output_section->vma
|
{
|
||||||
+ h->toc_section->output_offset
|
BFD_ASSERT ((h->flags & XCOFF_SET_TOC) == 0);
|
||||||
+ h->toc_offset);
|
val = (h->toc_section->output_section->vma
|
||||||
|
+ h->toc_section->output_offset);
|
||||||
|
}
|
||||||
val = ((val - xcoff_data (output_bfd)->toc)
|
val = ((val - xcoff_data (output_bfd)->toc)
|
||||||
- (sym->n_value - xcoff_data (input_bfd)->toc));
|
- (sym->n_value - xcoff_data (input_bfd)->toc));
|
||||||
addend = 0;
|
addend = 0;
|
||||||
|
Reference in New Issue
Block a user