mips specific patches
Package: binutils
Version: 2.10.1.0.2-1
Severity: normal
tags: patch
for debian-mips support please add the mips patches
binutils-2.10-mips-call_reloc.patch.gz
binutils-2.10-mips-extsym_debug.gz
binutils-2.10.1-mips-merge.patch.gz
binutils-2.10.1-mips-sym_is_global.patch.gz
from ftp.ds2.pg.gda.pl/pub/macro/SRPMS/binutils-2.10.1.src.rpm. I
applied them to the current version and they are working.
I hope I succeed in building glibc-2.2 with that now.
Christoph
*** binutils-2.10.1.0.2/bfd/elf32-mips.c~ Fri Jan 5 00:05:20 2001
--- binutils-2.10.1.0.2/bfd/elf32-mips.c Thu Jan 4 23:48:07 2001
***************
*** 79,84 ****
--- 79,90 ----
section) against this symbol. */
unsigned int min_dyn_reloc_index;
+ /* We must not create a stub for a symbol that has relocations
+ related to taking the function's address, i.e. any but
+ R_MIPS_CALL*16 ones -- see "MIPS ABI Supplement, 3rd Edition",
+ p. 4-20. */
+ boolean no_fn_stub;
+
/* If there is a stub that 32 bit functions should use to call this
16 bit function, this points to the section containing the stub. */
asection *fn_stub;
***************
*** 2275,2281 ****
bfd *abfd ATTRIBUTE_UNUSED;
asymbol *sym;
{
! return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
}
/* Set the right machine number for a MIPS ELF file. This is used for
--- 2281,2292 ----
bfd *abfd ATTRIBUTE_UNUSED;
asymbol *sym;
{
! if (SGI_COMPAT (abfd))
! return (sym->flags & BSF_SECTION_SYM) == 0 ? true : false;
! else
! return ((sym->flags & (BSF_GLOBAL | BSF_WEAK)) != 0
! || bfd_is_und_section (bfd_get_section (sym))
! || bfd_is_com_section (bfd_get_section (sym))) ? true : false;
}
/* Set the right machine number for a MIPS ELF file. This is used for
***************
*** 2475,2480 ****
--- 2486,2493 ----
flagword old_flags;
flagword new_flags;
boolean ok;
+ boolean null_input_bfd = true;
+ asection *sec;
/* Check if we have the same endianess */
if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
***************
*** 2514,2519 ****
--- 2527,2553 ----
if (new_flags == old_flags)
return true;
+ /* Check to see if the input BFD actually contains any sections.
+ If not, its flags may not have been initialised either, but it cannot
+ actually cause any incompatibility. */
+ for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+ {
+ /* Ignore synthetic sections and empty .text, .data and .bss sections
+ which are automatically generated by gas. */
+ if (strcmp (sec->name, ".reginfo")
+ && strcmp (sec->name, ".mdebug")
+ && ((!strcmp (sec->name, ".text")
+ || !strcmp (sec->name, ".data")
+ || !strcmp (sec->name, ".bss"))
+ && sec->_raw_size != 0))
+ {
+ null_input_bfd = false;
+ break;
+ }
+ }
+ if (null_input_bfd)
+ return true;
+
ok = true;
if ((new_flags & EF_MIPS_PIC) != (old_flags & EF_MIPS_PIC))
***************
*** 3891,3896 ****
--- 3925,3931 ----
ret->esym.ifd = -2;
ret->possibly_dynamic_relocs = 0;
ret->min_dyn_reloc_index = 0;
+ ret->no_fn_stub = false;
ret->fn_stub = NULL;
ret->need_fn_stub = false;
ret->call_stub = NULL;
***************
*** 4267,4290 ****
}
else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
! /* Set type and value for a symbol with a function stub. */
! h->esym.asym.st = stProc;
! sec = h->root.root.u.def.section;
! if (sec == NULL)
! h->esym.asym.value = 0;
! else
{
! output_section = sec->output_section;
! if (output_section != NULL)
! h->esym.asym.value = (h->root.plt.offset
! + sec->output_offset
! + output_section->vma);
! else
! h->esym.asym.value = 0;
}
#if 0 /* FIXME? */
h->esym.ifd = 0;
#endif
}
if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
--- 4302,4337 ----
}
else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
! struct mips_elf_link_hash_entry *hd = h;
! boolean no_fn_stub = h->no_fn_stub;
!
! while (hd->root.root.type == bfd_link_hash_indirect)
{
! hd = (struct mips_elf_link_hash_entry *)h->root.root.u.i.link;
! no_fn_stub = no_fn_stub || hd->no_fn_stub;
}
+
+ if (!no_fn_stub)
+ {
+ /* Set type and value for a symbol with a function stub. */
+ h->esym.asym.st = stProc;
+ sec = hd->root.root.u.def.section;
+ if (sec == NULL)
+ h->esym.asym.value = 0;
+ else
+ {
+ output_section = sec->output_section;
+ if (output_section != NULL)
+ h->esym.asym.value = (hd->root.plt.offset
+ + sec->output_offset
+ + output_section->vma);
+ else
+ h->esym.asym.value = 0;
+ }
#if 0 /* FIXME? */
h->esym.ifd = 0;
#endif
+ }
}
if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
***************
*** 5774,5788 ****
/* The relocation we're building is section-relative.
Therefore, the original addend must be adjusted by the
section offset. */
! *addendp += symbol - sec->output_section->vma;
/* Now, the relocation is just against the section. */
symbol = sec->output_section->vma;
}
! /* If the relocation is against a local symbol was previously an absolute
! relocation, we must adjust it by the value we give it in the dynamic
! symbol table. */
! if (local_p && r_type != R_MIPS_REL32)
*addendp += symbol;
/* The relocation is always an REL32 relocation because we don't
--- 5821,5836 ----
/* The relocation we're building is section-relative.
Therefore, the original addend must be adjusted by the
section offset. */
! *addendp += section_offset;
/* Now, the relocation is just against the section. */
symbol = sec->output_section->vma;
}
! /* If the relocation was previously an absolute relocation and
! this symbol will not be referred to by the relocation, we must
! adjust it by the value we give it in the dynamic symbol table.
! Otherwise leave the job up to the dynamic linker. */
! if (!indx && r_type != R_MIPS_REL32)
*addendp += symbol;
/* The relocation is always an REL32 relocation because we don't
***************
*** 6157,6163 ****
symbol + addend, sgot->contents + g);
}
}
! else if (r_type == R_MIPS_GOT16)
/* There's no need to create a local GOT entry here; the
calculation for a local GOT16 entry does not involve G. */
break;
--- 6205,6211 ----
symbol + addend, sgot->contents + g);
}
}
! else if (r_type == R_MIPS_GOT16 || r_type == R_MIPS_CALL16)
/* There's no need to create a local GOT entry here; the
calculation for a local GOT16 entry does not involve G. */
break;
***************
*** 6325,6330 ****
--- 6373,6379 ----
break;
case R_MIPS_GOT16:
+ case R_MIPS_CALL16:
if (local_p)
{
boolean forced;
***************
*** 6347,6353 ****
/* Fall through. */
- case R_MIPS_CALL16:
case R_MIPS_GOT_DISP:
value = g;
overflowed_p = mips_elf_overflow_p (value, 16);
--- 6396,6401 ----
***************
*** 7662,7671 ****
/* We may need a local GOT entry for this relocation. We
don't count R_MIPS_GOT_PAGE because we can estimate the
maximum number of pages needed by looking at the size of
! the segment. Similar comments apply to R_MIPS_GOT16. We
! don't count R_MIPS_GOT_HI16, or R_MIPS_CALL_HI16 because
! these are always followed by an R_MIPS_GOT_LO16 or
! R_MIPS_CALL_LO16.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
--- 7710,7719 ----
/* We may need a local GOT entry for this relocation. We
don't count R_MIPS_GOT_PAGE because we can estimate the
maximum number of pages needed by looking at the size of
! the segment. Similar comments apply to R_MIPS_GOT16 and
! R_MIPS_CALL16. We don't count R_MIPS_GOT_HI16, or
! R_MIPS_CALL_HI16 because these are always followed by an
! R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
***************
*** 7797,7802 ****
--- 7845,7869 ----
break;
}
+ /* We must not create a stub for a symbol that has relocations
+ related to taking the function's address. */
+ switch (r_type)
+ {
+ default:
+ if (h != NULL)
+ {
+ struct mips_elf_link_hash_entry *mh;
+
+ mh = (struct mips_elf_link_hash_entry *) h;
+ mh->no_fn_stub = true;
+ }
+ break;
+ case R_MIPS_CALL16:
+ case R_MIPS_CALL_HI16:
+ case R_MIPS_CALL_LO16:
+ break;
+ }
+
/* If this reloc is not a 16 bit call, and it has a global
symbol, then we will need the fn_stub if there is one.
References from a stub section do not count. */
***************
*** 7932,7937 ****
--- 7999,8006 ----
|| (indmips->min_dyn_reloc_index != 0
&& indmips->min_dyn_reloc_index < dirmips->min_dyn_reloc_index))
dirmips->min_dyn_reloc_index = indmips->min_dyn_reloc_index;
+ if (indmips->no_fn_stub)
+ dirmips->no_fn_stub = true;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
***************
*** 7972,7979 ****
mips_elf_allocate_dynamic_relocations (dynobj,
hmips->possibly_dynamic_relocs);
! /* For a function, create a stub, if needed. */
! if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
if (! elf_hash_table (info)->dynamic_sections_created)
return true;
--- 8041,8049 ----
mips_elf_allocate_dynamic_relocations (dynobj,
hmips->possibly_dynamic_relocs);
! /* For a function create a stub, if allowed. */
! if (! hmips->no_fn_stub
! && (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{
if (! elf_hash_table (info)->dynamic_sections_created)
return true;
*** binutils-2.10.1.0.2/gas/config/tc-mips.c~ Fri Jan 5 00:12:16 2001
--- binutils-2.10.1.0.2/gas/config/tc-mips.c Thu Jan 4 23:55:15 2001
***************
*** 4278,4288 ****
--- 4278,4292 ----
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
{
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT16;
+
/* If this is a reference to an external symbol, and there
is no constant, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
For a local symbol, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
+ or if tempreg is PIC_CALL_REG
+ lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
nop
addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
***************
*** 4307,4315 ****
expr1.X_add_number = offset_expr.X_add_number;
offset_expr.X_add_number = 0;
frag_grow (32);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
! "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
if (expr1.X_add_number == 0)
{
int off;
--- 4311,4321 ----
expr1.X_add_number = offset_expr.X_add_number;
offset_expr.X_add_number = 0;
frag_grow (32);
+ if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL16;
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
! "t,o(b)", tempreg, lw_reloc_type, GP);
if (expr1.X_add_number == 0)
{
int off;
***************
*** 4415,4426 ****
--- 4421,4438 ----
else if (mips_pic == SVR4_PIC)
{
int gpdel;
+ int lui_reloc_type = (int) BFD_RELOC_MIPS_GOT_HI16;
+ int lw_reloc_type = (int) BFD_RELOC_MIPS_GOT_LO16;
/* This is the large GOT case. If this is a reference to an
external symbol, and there is no constant, we want
lui $tempreg,<sym> (BFD_RELOC_MIPS_GOT_HI16)
addu $tempreg,$tempreg,$gp
lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)
+ or if tempreg is PIC_CALL_REG
+ lui $tempreg,<sym> (BFD_RELOC_MIPS_CALL_HI16)
+ addu $tempreg,$tempreg,$gp
+ lw $tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_CALL_LO16)
For a local symbol, we want
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
nop
***************
*** 4459,4466 ****
gpdel = 4;
else
gpdel = 0;
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
! tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
|| ! ISA_HAS_64BIT_REGS (mips_opts.isa))
--- 4471,4483 ----
gpdel = 4;
else
gpdel = 0;
+ if (expr1.X_add_number == 0 && tempreg == PIC_CALL_REG)
+ {
+ lui_reloc_type = (int) BFD_RELOC_MIPS_CALL_HI16;
+ lw_reloc_type = (int) BFD_RELOC_MIPS_CALL_LO16;
+ }
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
! tempreg, lui_reloc_type);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
|| ! ISA_HAS_64BIT_REGS (mips_opts.isa))
***************
*** 4468,4475 ****
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
! "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
! tempreg);
if (expr1.X_add_number == 0)
{
int off;
--- 4485,4491 ----
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
! "t,o(b)", tempreg, lw_reloc_type, tempreg);
if (expr1.X_add_number == 0)
{
int off;
-- System Information
Debian Release: 2.2
Kernel Version: Linux pongo 2.4.0-test9 #1 Thu Oct 26 21:35:48 CEST 2000 mips un
known
Versions of the packages gdb depends on:
ii libc6 2.1.95-1.1 GNU C Library: Shared libraries and Timezone
Reply to: