mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 01:42:21 +08:00
* elf32-m68hc11.c (m68hc11_elf_relax_delete_bytes): Also adjust
symbols that mark the end of the section. (m68hc11_elf_relax_section): Use R_M68HC11_PCREL_8 relocs when converting to a relative branch so that the offset is computed after the relaxation; also relocate a jsr into a bsr if possible but don't relax them if they are to a far symbol as we need to call the trampoline code. (elf_m68hc11_howto_table): Set pcrel_offset to true.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2003-04-04 Stephane Carrez <stcarrez@nerim.fr>
|
||||||
|
|
||||||
|
* elf32-m68hc11.c (m68hc11_elf_relax_delete_bytes): Also adjust
|
||||||
|
symbols that mark the end of the section.
|
||||||
|
(m68hc11_elf_relax_section): Use R_M68HC11_PCREL_8 relocs when
|
||||||
|
converting to a relative branch so that the offset is computed after
|
||||||
|
the relaxation; also relocate a jsr into a bsr if possible but don't
|
||||||
|
relax them if they are to a far symbol as we need to call the
|
||||||
|
trampoline code.
|
||||||
|
(elf_m68hc11_howto_table): Set pcrel_offset to true.
|
||||||
|
|
||||||
2003-04-04 Svein E. Seldal <Svein.Seldal@solidas.com>
|
2003-04-04 Svein E. Seldal <Svein.Seldal@solidas.com>
|
||||||
|
|
||||||
* archures.c: Namespace cleanup. Rename bfd_mach_c3x to
|
* archures.c: Namespace cleanup. Rename bfd_mach_c3x to
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Motorola 68HC11-specific support for 32-bit ELF
|
/* Motorola 68HC11-specific support for 32-bit ELF
|
||||||
Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
Contributed by Stephane Carrez (stcarrez@nerim.fr)
|
Contributed by Stephane Carrez (stcarrez@nerim.fr)
|
||||||
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
(Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
FALSE, /* partial_inplace */
|
FALSE, /* partial_inplace */
|
||||||
0x00ff, /* src_mask */
|
0x00ff, /* src_mask */
|
||||||
0x00ff, /* dst_mask */
|
0x00ff, /* dst_mask */
|
||||||
FALSE), /* pcrel_offset */
|
TRUE), /* pcrel_offset */
|
||||||
|
|
||||||
/* A 16 bit absolute relocation */
|
/* A 16 bit absolute relocation */
|
||||||
HOWTO (R_M68HC11_16, /* type */
|
HOWTO (R_M68HC11_16, /* type */
|
||||||
@ -204,7 +204,7 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
FALSE, /* partial_inplace */
|
FALSE, /* partial_inplace */
|
||||||
0xffff, /* src_mask */
|
0xffff, /* src_mask */
|
||||||
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
||||||
FALSE), /* pcrel_offset */
|
TRUE), /* pcrel_offset */
|
||||||
|
|
||||||
/* GNU extension to record C++ vtable hierarchy */
|
/* GNU extension to record C++ vtable hierarchy */
|
||||||
HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
|
HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
|
||||||
@ -247,8 +247,8 @@ static reloc_howto_type elf_m68hc11_howto_table[] = {
|
|||||||
bfd_elf_generic_reloc, /* special_function */
|
bfd_elf_generic_reloc, /* special_function */
|
||||||
"R_M68HC11_24", /* name */
|
"R_M68HC11_24", /* name */
|
||||||
FALSE, /* partial_inplace */
|
FALSE, /* partial_inplace */
|
||||||
0xffff, /* src_mask */
|
0xffffff, /* src_mask */
|
||||||
0xffff, /* dst_mask */
|
0xffffff, /* dst_mask */
|
||||||
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
||||||
|
|
||||||
/* A 16-bit low relocation */
|
/* A 16-bit low relocation */
|
||||||
@ -445,6 +445,9 @@ elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 68HC11 Linker Relaxation. */
|
||||||
|
|
||||||
struct m68hc11_direct_relax
|
struct m68hc11_direct_relax
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -694,6 +697,7 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
bfd_vma value;
|
bfd_vma value;
|
||||||
Elf_Internal_Sym *isym;
|
Elf_Internal_Sym *isym;
|
||||||
asection *sym_sec;
|
asection *sym_sec;
|
||||||
|
int is_far = 0;
|
||||||
|
|
||||||
/* If this isn't something that can be relaxed, then ignore
|
/* If this isn't something that can be relaxed, then ignore
|
||||||
this reloc. */
|
this reloc. */
|
||||||
@ -747,7 +751,7 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
prev_insn_group = 0;
|
prev_insn_group = 0;
|
||||||
|
|
||||||
/* Do nothing if this reloc is the last byte in the section. */
|
/* Do nothing if this reloc is the last byte in the section. */
|
||||||
if (irel->r_offset == sec->_cooked_size)
|
if (irel->r_offset + 2 >= sec->_cooked_size)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* See if the next instruction is an unconditional pc-relative
|
/* See if the next instruction is an unconditional pc-relative
|
||||||
@ -793,6 +797,7 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
{
|
{
|
||||||
/* A local symbol. */
|
/* A local symbol. */
|
||||||
isym = isymbuf + ELF32_R_SYM (irel->r_info);
|
isym = isymbuf + ELF32_R_SYM (irel->r_info);
|
||||||
|
is_far = isym->st_other & STO_M68HC12_FAR;
|
||||||
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||||||
symval = (isym->st_value
|
symval = (isym->st_value
|
||||||
+ sym_sec->output_section->vma
|
+ sym_sec->output_section->vma
|
||||||
@ -818,6 +823,7 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_far = h->other & STO_M68HC12_FAR;
|
||||||
isym = 0;
|
isym = 0;
|
||||||
sym_sec = h->root.u.def.section;
|
sym_sec = h->root.u.def.section;
|
||||||
symval = (h->root.u.def.value
|
symval = (h->root.u.def.value
|
||||||
@ -891,23 +897,25 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
{
|
{
|
||||||
code = 0x20;
|
code = 0x20;
|
||||||
bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
|
bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
|
||||||
bfd_put_8 (abfd, offset,
|
bfd_put_8 (abfd, 0xff,
|
||||||
contents + prev_insn_branch->r_offset + 1);
|
contents + prev_insn_branch->r_offset + 1);
|
||||||
|
irel->r_offset = prev_insn_branch->r_offset + 1;
|
||||||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
||||||
R_M68HC11_NONE);
|
R_M68HC11_PCREL_8);
|
||||||
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
||||||
irel->r_offset, 1);
|
irel->r_offset + 1, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code ^= 0x1;
|
code ^= 0x1;
|
||||||
bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
|
bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
|
||||||
bfd_put_8 (abfd, offset,
|
bfd_put_8 (abfd, 0xff,
|
||||||
contents + prev_insn_branch->r_offset + 1);
|
contents + prev_insn_branch->r_offset + 1);
|
||||||
|
irel->r_offset = prev_insn_branch->r_offset + 1;
|
||||||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
||||||
R_M68HC11_NONE);
|
R_M68HC11_PCREL_8);
|
||||||
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
||||||
irel->r_offset - 1, 3);
|
irel->r_offset + 1, 3);
|
||||||
}
|
}
|
||||||
prev_insn_branch = 0;
|
prev_insn_branch = 0;
|
||||||
*again = TRUE;
|
*again = TRUE;
|
||||||
@ -991,14 +999,14 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
/* That will change things, so, we should relax again. */
|
/* That will change things, so, we should relax again. */
|
||||||
*again = TRUE;
|
*again = TRUE;
|
||||||
}
|
}
|
||||||
else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16)
|
else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
|
||||||
{
|
{
|
||||||
unsigned char code;
|
unsigned char code;
|
||||||
bfd_vma offset;
|
bfd_vma offset;
|
||||||
|
|
||||||
prev_insn_branch = 0;
|
prev_insn_branch = 0;
|
||||||
code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
|
code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
|
||||||
if (code == 0x7e)
|
if (code == 0x7e || code == 0xbd)
|
||||||
{
|
{
|
||||||
offset = value - (irel->r_offset
|
offset = value - (irel->r_offset
|
||||||
+ sec->output_section->vma
|
+ sec->output_section->vma
|
||||||
@ -1021,13 +1029,13 @@ m68hc11_elf_relax_section (abfd, sec, link_info, again)
|
|||||||
free_extsyms = NULL;
|
free_extsyms = NULL;
|
||||||
|
|
||||||
/* Shrink the branch. */
|
/* Shrink the branch. */
|
||||||
code = 0x20;
|
code = (code == 0x7e) ? 0x20 : 0x8d;
|
||||||
bfd_put_8 (abfd, code,
|
bfd_put_8 (abfd, code,
|
||||||
contents + irel->r_offset - 1);
|
contents + irel->r_offset - 1);
|
||||||
bfd_put_8 (abfd, offset,
|
bfd_put_8 (abfd, 0xff,
|
||||||
contents + irel->r_offset);
|
contents + irel->r_offset);
|
||||||
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
|
||||||
R_M68HC11_NONE);
|
R_M68HC11_PCREL_8);
|
||||||
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
m68hc11_elf_relax_delete_bytes (abfd, sec,
|
||||||
irel->r_offset + 1, 1);
|
irel->r_offset + 1, 1);
|
||||||
/* That will change things, so, we should relax again. */
|
/* That will change things, so, we should relax again. */
|
||||||
@ -1220,7 +1228,7 @@ m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
|
|||||||
{
|
{
|
||||||
if (isym->st_shndx == sec_shndx
|
if (isym->st_shndx == sec_shndx
|
||||||
&& isym->st_value > addr
|
&& isym->st_value > addr
|
||||||
&& isym->st_value < toaddr)
|
&& isym->st_value <= toaddr)
|
||||||
isym->st_value -= count;
|
isym->st_value -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1236,7 +1244,7 @@ m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
|
|||||||
|| sym_hash->root.type == bfd_link_hash_defweak)
|
|| sym_hash->root.type == bfd_link_hash_defweak)
|
||||||
&& sym_hash->root.u.def.section == sec
|
&& sym_hash->root.u.def.section == sec
|
||||||
&& sym_hash->root.u.def.value > addr
|
&& sym_hash->root.u.def.value > addr
|
||||||
&& sym_hash->root.u.def.value < toaddr)
|
&& sym_hash->root.u.def.value <= toaddr)
|
||||||
{
|
{
|
||||||
sym_hash->root.u.def.value -= count;
|
sym_hash->root.u.def.value -= count;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user