mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-09 02:37:38 +00:00
Apply several patches from Maciej W. Rozycki
This commit is contained in:
parent
ecd0338944
commit
9117d2197e
@ -1,3 +1,36 @@
|
||||
2001-02-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
|
||||
|
||||
* elf32-mips.c (mips_elf_create_dynamic_relocation): Undo patch
|
||||
from 2000-10-13. Do not add the symbol's value for R_MIPS_REL32
|
||||
relocations against dynsym symbols.
|
||||
|
||||
* elf32-mips.c (elf_mips_howto_table): Fix the comment on
|
||||
the R_MIPS_26 relocation.
|
||||
(mips_elf_calculate_relocation): Use (p + 4) instead of p for
|
||||
the R_MIPS_26 relocation.
|
||||
(mips_elf_perform_relocation): Fix the comment on the R_MIPS16_26
|
||||
relocation.
|
||||
* elf64-mips.c (mips_elf64_howto_table_rel): Fix the comment on
|
||||
the R_MIPS_26 relocation.
|
||||
(mips_elf64_howto_table_rela): Likewise.
|
||||
|
||||
* elf32-mips.c (struct mips_elf_link_hash_entry): Added no_fn_stub
|
||||
member to mark symbols that have non-CALL relocations against
|
||||
them.
|
||||
(mips_elf_link_hash_newfunc): Initialize no_fn_stub.
|
||||
(mips_elf_calculate_relocation): Handle R_MIPS_CALL16 like
|
||||
R_MIPS_GOT16.
|
||||
(_bfd_mips_elf_check_relocs): Set no_fn_stub for a symbol if a
|
||||
non-CALL relocation against it is encountered.
|
||||
(_bfd_mips_elf_copy_indirect_symbol): Merge no_fn_stub as well.
|
||||
(_bfd_mips_elf_adjust_dynamic_symbol): Only create a stub if
|
||||
no_fn_stub is not set.
|
||||
|
||||
* elf32-mips.c (mips_elf_output_extsym): Get the output section
|
||||
information from the real symbol for indirect ones.
|
||||
Check no_fn_stub to find out if a symbol has a function stub
|
||||
indeed.
|
||||
|
||||
2001-02-11 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||
|
||||
* Makefile.am (stamp-lib): ranlib the libbfd.a in the build directory.
|
||||
|
113
bfd/elf32-mips.c
113
bfd/elf32-mips.c
@ -80,6 +80,12 @@ struct mips_elf_link_hash_entry
|
||||
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;
|
||||
@ -193,7 +199,7 @@ static bfd_vma mips_elf_got16_entry
|
||||
static boolean mips_elf_create_dynamic_relocation
|
||||
PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Rela *,
|
||||
struct mips_elf_link_hash_entry *, asection *,
|
||||
bfd_vma, bfd_vma *, asection *, boolean local_p));
|
||||
bfd_vma, bfd_vma *, asection *));
|
||||
static void mips_elf_allocate_dynamic_relocations
|
||||
PARAMS ((bfd *, unsigned int));
|
||||
static boolean mips_elf_stub_section_p
|
||||
@ -531,7 +537,7 @@ static reloc_howto_type elf_mips_howto_table[] =
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
/* This needs complex overflow
|
||||
detection, because the upper four
|
||||
bits must match the PC. */
|
||||
bits must match the PC + 4. */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_MIPS_26", /* name */
|
||||
true, /* partial_inplace */
|
||||
@ -3955,6 +3961,7 @@ mips_elf_link_hash_newfunc (entry, table, string)
|
||||
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;
|
||||
@ -4330,24 +4337,36 @@ mips_elf_output_extsym (h, data)
|
||||
}
|
||||
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
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
h->esym.ifd = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap,
|
||||
@ -5748,7 +5767,7 @@ mips_elf_next_relocation (r_type, relocation, relend)
|
||||
|
||||
static boolean
|
||||
mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
|
||||
symbol, addendp, input_section, local_p)
|
||||
symbol, addendp, input_section)
|
||||
bfd *output_bfd;
|
||||
struct bfd_link_info *info;
|
||||
const Elf_Internal_Rela *rel;
|
||||
@ -5757,7 +5776,6 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
|
||||
bfd_vma symbol;
|
||||
bfd_vma *addendp;
|
||||
asection *input_section;
|
||||
boolean local_p;
|
||||
{
|
||||
Elf_Internal_Rel outrel;
|
||||
boolean skip;
|
||||
@ -5842,15 +5860,16 @@ mips_elf_create_dynamic_relocation (output_bfd, info, rel, h, sec,
|
||||
/* 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;
|
||||
*addendp += section_offset;
|
||||
/* 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)
|
||||
/* 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
|
||||
@ -6225,7 +6244,7 @@ mips_elf_calculate_relocation (abfd,
|
||||
symbol + addend, sgot->contents + g);
|
||||
}
|
||||
}
|
||||
else if (r_type == R_MIPS_GOT16)
|
||||
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;
|
||||
@ -6288,7 +6307,7 @@ mips_elf_calculate_relocation (abfd,
|
||||
sec,
|
||||
symbol,
|
||||
&value,
|
||||
input_section, local_p))
|
||||
input_section))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@ -6320,14 +6339,14 @@ mips_elf_calculate_relocation (abfd,
|
||||
break;
|
||||
|
||||
case R_MIPS16_26:
|
||||
/* The calculation for R_MIPS_26 is just the same as for an
|
||||
/* The calculation for R_MIPS16_26 is just the same as for an
|
||||
R_MIPS_26. It's only the storage of the relocated field into
|
||||
the output file that's different. That's handled in
|
||||
mips_elf_perform_relocation. So, we just fall through to the
|
||||
R_MIPS_26 case here. */
|
||||
case R_MIPS_26:
|
||||
if (local_p)
|
||||
value = (((addend << 2) | (p & 0xf0000000)) + symbol) >> 2;
|
||||
value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2;
|
||||
else
|
||||
value = (mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2;
|
||||
value &= howto->dst_mask;
|
||||
@ -6393,6 +6412,7 @@ mips_elf_calculate_relocation (abfd,
|
||||
break;
|
||||
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_CALL16:
|
||||
if (local_p)
|
||||
{
|
||||
boolean forced;
|
||||
@ -6415,7 +6435,6 @@ mips_elf_calculate_relocation (abfd,
|
||||
|
||||
/* Fall through. */
|
||||
|
||||
case R_MIPS_CALL16:
|
||||
case R_MIPS_GOT_DISP:
|
||||
value = g;
|
||||
overflowed_p = mips_elf_overflow_p (value, 16);
|
||||
@ -6620,9 +6639,9 @@ mips_elf_perform_relocation (info, howto, relocation, value,
|
||||
((sub1 << 16) | sub2)).
|
||||
|
||||
When producing a relocateable object file, the calculation is
|
||||
(((A < 2) | (P & 0xf0000000) + S) >> 2)
|
||||
(((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
|
||||
When producing a fully linked file, the calculation is
|
||||
let R = (((A < 2) | (P & 0xf0000000) + S) >> 2)
|
||||
let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
|
||||
((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff) */
|
||||
|
||||
if (!info->relocateable)
|
||||
@ -7728,10 +7747,10 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
|
||||
/* 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.
|
||||
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
|
||||
@ -7863,6 +7882,25 @@ _bfd_mips_elf_check_relocs (abfd, info, sec, relocs)
|
||||
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. */
|
||||
@ -7998,6 +8036,8 @@ _bfd_mips_elf_copy_indirect_symbol (dir, ind)
|
||||
|| (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
|
||||
@ -8038,8 +8078,9 @@ _bfd_mips_elf_adjust_dynamic_symbol (info, h)
|
||||
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)
|
||||
/* 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;
|
||||
|
@ -1,3 +1,12 @@
|
||||
2001-02-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
|
||||
|
||||
* config/tc-mips.c (macro): For M_LA_AB emit a
|
||||
BFD_RELOC_MIPS_CALL16 relocation or a
|
||||
BFD_RELOC_MIPS_CALL_HI16/BFD_RELOC_MIPS_CALL_LO16 pair instead of
|
||||
BFD_RELOC_MIPS_GOT16 and
|
||||
BFD_RELOC_MIPS_GOT_HI16/BFD_RELOC_MIPS_GOT_LO16, respectively for
|
||||
loading the jump register when generating SVR4_PIC code.
|
||||
|
||||
2001-02-10 Chris Demetriou <cgd@broadcom.com>
|
||||
|
||||
* configure.in: Make 'mipself' and 'mipsecoff' emulations
|
||||
|
@ -3936,7 +3936,7 @@ macro (ip)
|
||||
if (mips_trap)
|
||||
macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);
|
||||
else
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3957,7 +3957,7 @@ macro (ip)
|
||||
macro_build ((char *) NULL, &icnt, NULL,
|
||||
dbl ? "ddiv" : "div",
|
||||
"z,s,t", sreg, treg);
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
|
||||
}
|
||||
expr1.X_add_number = -1;
|
||||
macro_build ((char *) NULL, &icnt, &expr1,
|
||||
@ -3996,7 +3996,7 @@ macro (ip)
|
||||
that later insns are available for delay slot filling. */
|
||||
--mips_opts.noreorder;
|
||||
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
|
||||
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
|
||||
}
|
||||
macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);
|
||||
break;
|
||||
@ -4213,9 +4213,13 @@ macro (ip)
|
||||
}
|
||||
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)
|
||||
or if tempreg is PIC_CALL_REG
|
||||
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_CALL16)
|
||||
For a local symbol, we want
|
||||
lw $tempreg,<sym>($gp) (BFD_RELOC_MIPS_GOT16)
|
||||
nop
|
||||
@ -4242,9 +4246,11 @@ macro (ip)
|
||||
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, (int) BFD_RELOC_MIPS_GOT16, GP);
|
||||
"t,o(b)", tempreg, lw_reloc_type, GP);
|
||||
if (expr1.X_add_number == 0)
|
||||
{
|
||||
int off;
|
||||
@ -4350,12 +4356,18 @@ macro (ip)
|
||||
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
|
||||
@ -4394,8 +4406,13 @@ macro (ip)
|
||||
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, (int) BFD_RELOC_MIPS_GOT_HI16);
|
||||
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))
|
||||
@ -4403,8 +4420,7 @@ macro (ip)
|
||||
"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);
|
||||
"t,o(b)", tempreg, lw_reloc_type, tempreg);
|
||||
if (expr1.X_add_number == 0)
|
||||
{
|
||||
int off;
|
||||
|
@ -1,3 +1,10 @@
|
||||
2001-02-11 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
|
||||
|
||||
* mips-dis.c (print_insn_arg): Use top four bits of the address of
|
||||
the following instruction not of the jump itself for the jump
|
||||
target.
|
||||
(print_mips16_insn_arg): Likewise.
|
||||
|
||||
2001-02-11 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||
|
||||
* Makefile.am (stamp-lib): ranlib the libopcodes.a in the build
|
||||
|
@ -137,7 +137,7 @@ print_insn_arg (d, l, pc, info)
|
||||
|
||||
case 'a':
|
||||
(*info->print_address_func)
|
||||
(((pc & ~ (bfd_vma) 0x0fffffff)
|
||||
((((pc + 4) & ~ (bfd_vma) 0x0fffffff)
|
||||
| (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
|
||||
info);
|
||||
break;
|
||||
@ -1038,9 +1038,9 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
|
||||
if (! use_extend)
|
||||
extend = 0;
|
||||
l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
|
||||
(*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
|
||||
(*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
|
||||
info->insn_type = dis_jsr;
|
||||
info->target = (memaddr & 0xf0000000) | l;
|
||||
info->target = ((memaddr + 4) & 0xf0000000) | l;
|
||||
info->branch_delay_insns = 1;
|
||||
break;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user