aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-sh.c
diff options
context:
space:
mode:
authorJoern Rennecke <joern.rennecke@embecosm.com>1999-06-03 18:54:32 +0000
committerJoern Rennecke <joern.rennecke@embecosm.com>1999-06-03 18:54:32 +0000
commit084aa3aa9f448323ca9af578ae1d405f82717410 (patch)
tree1af7ef95e0d972f2d57f450e995cb5abcd5ebfd3 /bfd/elf32-sh.c
parent875f7f6940b2e802454dac25028ad90abf254562 (diff)
downloadgdb-084aa3aa9f448323ca9af578ae1d405f82717410.zip
gdb-084aa3aa9f448323ca9af578ae1d405f82717410.tar.gz
gdb-084aa3aa9f448323ca9af578ae1d405f82717410.tar.bz2
* elf32-sh.c (sh_elf_relax_delete_bytes): Handle R_SH_SWITCH32
in other text sections.
Diffstat (limited to 'bfd/elf32-sh.c')
-rw-r--r--bfd/elf32-sh.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index aa9bc00..b3670d0 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -1307,6 +1307,56 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
{
Elf_Internal_Sym sym;
+ /* Dwarf line numbers use R_SH_SWITCH32 relocs. */
+ if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_SWITCH32)
+ {
+ bfd_vma start, stop;
+ bfd_signed_vma voff;
+
+ if (ocontents == NULL)
+ {
+ if (elf_section_data (o)->this_hdr.contents != NULL)
+ ocontents = elf_section_data (o)->this_hdr.contents;
+ else
+ {
+ /* We always cache the section contents.
+ Perhaps, if info->keep_memory is false, we
+ should free them, if we are permitted to,
+ when we leave sh_coff_relax_section. */
+ ocontents = (bfd_byte *) bfd_malloc (o->_raw_size);
+ if (ocontents == NULL)
+ return false;
+ if (! bfd_get_section_contents (abfd, o, ocontents,
+ (file_ptr) 0,
+ o->_raw_size))
+ return false;
+ elf_section_data (o)->this_hdr.contents = ocontents;
+ }
+ }
+
+ stop = irelscan->r_offset;
+ start
+ = (bfd_vma) ((bfd_signed_vma) stop - (long) irelscan->r_addend);
+
+ /* STOP is in a different section, so it won't change. */
+ if (start > addr && start < toaddr)
+ irelscan->r_addend += count;
+
+ voff = bfd_get_signed_32 (abfd, ocontents + irelscan->r_offset);
+ stop = (bfd_vma) ((bfd_signed_vma) start + voff);
+
+ if (start > addr
+ && start < toaddr
+ && (stop <= addr || stop >= toaddr))
+ bfd_put_signed_32 (abfd, voff + count,
+ ocontents + irelscan->r_offset);
+ else if (stop > addr
+ && stop < toaddr
+ && (start <= addr || start >= toaddr))
+ bfd_put_signed_32 (abfd, voff - count,
+ ocontents + irelscan->r_offset);
+ }
+
if (ELF32_R_TYPE (irelscan->r_info) != (int) R_SH_DIR32)
continue;