* config/tc-mips.c (s_is_linkonce): New function.
(mips16_mark_labels): Don't adjust mips16 symbol addresses for weak, external, and linkonce symbols. (pic_need_relax): Use s_is_linkonce.
This commit is contained in:
parent
cd9260d951
commit
5f0fe04bc5
|
@ -1,3 +1,11 @@
|
||||||
|
2006-07-04 Thiemo Seufer <ths@mips.com>
|
||||||
|
David Ung <davidu@mips.com>
|
||||||
|
|
||||||
|
* config/tc-mips.c (s_is_linkonce): New function.
|
||||||
|
(mips16_mark_labels): Don't adjust mips16 symbol addresses for
|
||||||
|
weak, external, and linkonce symbols.
|
||||||
|
(pic_need_relax): Use s_is_linkonce.
|
||||||
|
|
||||||
2006-06-24 H.J. Lu <hongjiu.lu@intel.com>
|
2006-06-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* doc/as.texinfo (Org): Remove space.
|
* doc/as.texinfo (Org): Remove space.
|
||||||
|
|
|
@ -2138,6 +2138,28 @@ mips_move_labels (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bfd_boolean
|
||||||
|
s_is_linkonce (symbolS *sym, segT from_seg)
|
||||||
|
{
|
||||||
|
bfd_boolean linkonce = FALSE;
|
||||||
|
segT symseg = S_GET_SEGMENT (sym);
|
||||||
|
|
||||||
|
if (symseg != from_seg && !S_IS_LOCAL (sym))
|
||||||
|
{
|
||||||
|
if ((bfd_get_section_flags (stdoutput, symseg) & SEC_LINK_ONCE))
|
||||||
|
linkonce = TRUE;
|
||||||
|
#ifdef OBJ_ELF
|
||||||
|
/* The GNU toolchain uses an extension for ELF: a section
|
||||||
|
beginning with the magic string .gnu.linkonce is a
|
||||||
|
linkonce section. */
|
||||||
|
if (strncmp (segment_name (symseg), ".gnu.linkonce",
|
||||||
|
sizeof ".gnu.linkonce" - 1) == 0)
|
||||||
|
linkonce = TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return linkonce;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark instruction labels in mips16 mode. This permits the linker to
|
/* Mark instruction labels in mips16 mode. This permits the linker to
|
||||||
handle them specially, such as generating jalx instructions when
|
handle them specially, such as generating jalx instructions when
|
||||||
needed. We also make them odd for the duration of the assembly, in
|
needed. We also make them odd for the duration of the assembly, in
|
||||||
|
@ -2163,7 +2185,14 @@ mips16_mark_labels (void)
|
||||||
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||||
S_SET_OTHER (label, STO_MIPS16);
|
S_SET_OTHER (label, STO_MIPS16);
|
||||||
#endif
|
#endif
|
||||||
if ((S_GET_VALUE (label) & 1) == 0)
|
if ((S_GET_VALUE (label) & 1) == 0
|
||||||
|
/* Don't adjust the address if the label is global or weak, or
|
||||||
|
in a link-once section, since we'll be emitting symbol reloc
|
||||||
|
references to it which will be patched up by the linker, and
|
||||||
|
the final value of the symbol may or may not be MIPS16. */
|
||||||
|
&& ! S_IS_WEAK (label)
|
||||||
|
&& ! S_IS_EXTERNAL (label)
|
||||||
|
&& ! s_is_linkonce (label, now_seg))
|
||||||
S_SET_VALUE (label, S_GET_VALUE (label) | 1);
|
S_SET_VALUE (label, S_GET_VALUE (label) | 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13131,15 +13160,13 @@ static bfd_boolean
|
||||||
pic_need_relax (symbolS *sym, asection *segtype)
|
pic_need_relax (symbolS *sym, asection *segtype)
|
||||||
{
|
{
|
||||||
asection *symsec;
|
asection *symsec;
|
||||||
bfd_boolean linkonce;
|
|
||||||
|
|
||||||
/* Handle the case of a symbol equated to another symbol. */
|
/* Handle the case of a symbol equated to another symbol. */
|
||||||
while (symbol_equated_reloc_p (sym))
|
while (symbol_equated_reloc_p (sym))
|
||||||
{
|
{
|
||||||
symbolS *n;
|
symbolS *n;
|
||||||
|
|
||||||
/* It's possible to get a loop here in a badly written
|
/* It's possible to get a loop here in a badly written program. */
|
||||||
program. */
|
|
||||||
n = symbol_get_value_expression (sym)->X_add_symbol;
|
n = symbol_get_value_expression (sym)->X_add_symbol;
|
||||||
if (n == sym)
|
if (n == sym)
|
||||||
break;
|
break;
|
||||||
|
@ -13148,27 +13175,11 @@ pic_need_relax (symbolS *sym, asection *segtype)
|
||||||
|
|
||||||
symsec = S_GET_SEGMENT (sym);
|
symsec = S_GET_SEGMENT (sym);
|
||||||
|
|
||||||
/* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
|
|
||||||
linkonce = FALSE;
|
|
||||||
if (symsec != segtype && ! S_IS_LOCAL (sym))
|
|
||||||
{
|
|
||||||
if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
|
|
||||||
!= 0)
|
|
||||||
linkonce = TRUE;
|
|
||||||
|
|
||||||
/* The GNU toolchain uses an extension for ELF: a section
|
|
||||||
beginning with the magic string .gnu.linkonce is a linkonce
|
|
||||||
section. */
|
|
||||||
if (strncmp (segment_name (symsec), ".gnu.linkonce",
|
|
||||||
sizeof ".gnu.linkonce" - 1) == 0)
|
|
||||||
linkonce = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This must duplicate the test in adjust_reloc_syms. */
|
/* This must duplicate the test in adjust_reloc_syms. */
|
||||||
return (symsec != &bfd_und_section
|
return (symsec != &bfd_und_section
|
||||||
&& symsec != &bfd_abs_section
|
&& symsec != &bfd_abs_section
|
||||||
&& ! bfd_is_com_section (symsec)
|
&& !bfd_is_com_section (symsec)
|
||||||
&& !linkonce
|
&& !s_is_linkonce (sym, segtype)
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
/* A global or weak symbol is treated as external. */
|
/* A global or weak symbol is treated as external. */
|
||||||
&& (OUTPUT_FLAVOR != bfd_target_elf_flavour
|
&& (OUTPUT_FLAVOR != bfd_target_elf_flavour
|
||||||
|
|
Loading…
Reference in New Issue