From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31447 invoked by alias); 30 Jul 2013 13:41:15 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 31427 invoked by uid 9364); 30 Jul 2013 13:41:15 -0000 Date: Tue, 30 Jul 2013 13:41:00 -0000 Message-ID: <20130730134114.31364.qmail@sourceware.org> From: gary@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] gbenson/rtld-probes: Double free Tom found X-Git-Refname: refs/heads/gbenson/rtld-probes X-Git-Reftype: branch X-Git-Oldrev: 8a3197058b8349dbc69dbd65d5492404f61b4fa4 X-Git-Newrev: 8f564f23edf41a8a00e0bc253fa3493e548dd52d X-SW-Source: 2013-q3/txt/msg00010.txt.bz2 List-Id: The branch, gbenson/rtld-probes has been updated via 8f564f23edf41a8a00e0bc253fa3493e548dd52d (commit) via 6cca719788dee5fa02c986fa66876648a527d5df (commit) via 039a3399c570982a7631549f94f15307ebc15d69 (commit) via b45ac1c71b81513599dbb4e479e862854e2e7708 (commit) via 04bd610ae9bbed5fedbc5fb873cc6069611e72c2 (commit) via 7ee7e095e018447b78c30ba29381b1d971d96dee (commit) via 30b768f283051261a0fdd837ae83fc0c6fd8e70e (commit) via 7176aecf86e5d9b7991c71656f3b52cec82bf417 (commit) via 2ed2c6a394277aa2de2f557d34b7d20b36518592 (commit) via 9f5e30f7cf73a3256fbb9a265c897aa3f2c91439 (commit) via 59f2be5e4349279d67dfb81a9674b3ed6bd53437 (commit) via 9836361131fc4d63d93d1265e4fc57a07f525760 (commit) via 31852533eb8fd3a0f37df8bef9a3086940642289 (commit) via a518bc5be2c62c92575e1493ad5bfabd160966f3 (commit) via 4dc07c16e9adada7a989b729a2a5123614d4f367 (commit) via 484a566f8762dcf2fb7943538fea6bbdf601adf8 (commit) via 1f2a93c952e0b415748eb4ab4bd5e09fbdae9bf9 (commit) via ffd52cc35a35577116a01459e65711d2c07ccd1c (commit) via 7051386e48c0e80cdd2ccb8cc5c0a8e84e831020 (commit) via c9820d96249a52508af0e55488acda0ede4cb41a (commit) via 1dafc5fd9caefc8306e4e45083b0ba8c20b42d43 (commit) via 88fb6edc3722f678d8f7aa5ae65daf9ec6dc12b3 (commit) via 6a120c2f9c46edc6f93932c3738bd0d3afb8db02 (commit) via 882b6307d545a0f42682428d30cddb7bc3e084f6 (commit) via 28447e14cde86eb09a4a0ee246d154eb080971c4 (commit) via 994b49f18871aaa48729f83671578c1a36a7fbaf (commit) via 23badfd01793d55645ca6dff0d92fa7a04c7f11a (commit) via 030cae2ec201337c7360afa4284501dd432f0e4a (commit) via f966e8edbc82ba636cdee4badf1c50bef7c0599e (commit) via 9eebe822db35048e297f13759ed533baf58571a8 (commit) via def372ee599734e7249184208ebb5f6ff797a107 (commit) via 7d74338ce734fb147fab4a2cd2074e256b07b5b4 (commit) via dae3e1d42e9a72735e8068c14049a41aa6a00d92 (commit) via a6b18e13c836e9b583ccd460337b9320f314dc7f (commit) via 12c8a94d097d33b80f2b393658670a6f95a46ec7 (commit) from 8a3197058b8349dbc69dbd65d5492404f61b4fa4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 8f564f23edf41a8a00e0bc253fa3493e548dd52d Author: Gary Benson Date: Tue Jul 23 11:20:06 2013 +0100 Double free Tom found commit 6cca719788dee5fa02c986fa66876648a527d5df Author: Gary Benson Date: Tue Jul 23 11:16:09 2013 +0100 Use XDUP (Tom's suggestion) commit 039a3399c570982a7631549f94f15307ebc15d69 Author: Gary Benson Date: Tue Jul 23 11:13:00 2013 +0100 Another implicit pointer if commit b45ac1c71b81513599dbb4e479e862854e2e7708 Author: Gary Benson Date: Tue Jul 23 11:08:50 2013 +0100 Sergio's nit & reordering, and rewrite/elaborate comments commit 04bd610ae9bbed5fedbc5fb873cc6069611e72c2 Merge: 7ee7e09 7176aec Author: Gary Benson Date: Mon Jul 8 13:02:17 2013 +0100 Merge remote branch 'gdb/master' into gbenson/rtld-probes commit 7ee7e095e018447b78c30ba29381b1d971d96dee Author: Gary Benson Date: Mon Jul 8 12:58:19 2013 +0100 Possibly lazy? commit 30b768f283051261a0fdd837ae83fc0c6fd8e70e Author: Gary Benson Date: Mon Jul 8 12:53:57 2013 +0100 Why did I not do these earlier? ----------------------------------------------------------------------- Summary of changes: LIST | 8 +- bfd/ChangeLog | 16 ++ bfd/bfd-in2.h | 12 + bfd/coffcode.h | 2 +- bfd/elf32-s390.c | 75 +++++++- bfd/elf64-s390.c | 77 +++++++- bfd/libbfd.h | 4 + bfd/version.h | 2 +- gdb/ChangeLog | 48 ++++ gdb/breakpoint.c | 16 +- gdb/breakpoint.h | 3 +- gdb/findvar.c | 8 +- gdb/frame-unwind.c | 6 +- gdb/main.c | 76 ++++--- gdb/rs6000-tdep.c | 4 +- gdb/solib-osf.c | 20 ++- gdb/solib-som.c | 2 +- gdb/solib-spu.c | 2 + gdb/solib-sunos.c | 2 +- gdb/solib-svr4.c | 35 ++-- gdb/testsuite/ChangeLog | 44 ++++ gdb/testsuite/boards/gdbserver-base.exp | 50 +++++ gdb/testsuite/boards/local-remote-host.exp | 9 - gdb/testsuite/boards/native-extended-gdbserver.exp | 35 +--- gdb/testsuite/boards/native-gdbserver.exp | 37 +--- gdb/testsuite/boards/native-stdio-gdbserver.exp | 37 +--- gdb/testsuite/gdb.base/dump.exp | 13 +- gdb/testsuite/gdb.base/gnu-ifunc-lib.c | 2 +- gdb/testsuite/gdb.mi/gdb2549.exp | 10 +- gdb/testsuite/gdb.python/py-explore.exp | 2 +- gdb/testsuite/gdb.threads/wp-replication.exp | 8 + gdb/top.c | 6 + gdb/value.c | 9 +- include/elf/ChangeLog | 5 + include/elf/s390.h | 4 + include/opcode/ChangeLog | 44 ++++ include/opcode/mips.h | 154 +++----------- opcodes/ChangeLog | 64 ++++++ opcodes/micromips-opc.c | 92 +------- opcodes/mips-dis.c | 232 ++++++++------------ opcodes/mips-opc.c | 149 +++---------- opcodes/mips16-opc.c | 4 +- opcodes/s390-opc.c | 19 +- opcodes/s390-opc.txt | 2 +- 44 files changed, 766 insertions(+), 683 deletions(-) create mode 100644 gdb/testsuite/boards/gdbserver-base.exp First 500 lines of diff: diff --git a/LIST b/LIST index 0c16200..33d58b5 100644 --- a/LIST +++ b/LIST @@ -79,15 +79,17 @@ gdb/solib-som.c:som_free_so (struct so_list *so) gdb/solib-som.c: som_so_ops.free_so = som_free_so; # Never called directly - # XXX + # xfree(so) added gdb/solib-spu.c:spu_free_so (struct so_list *so) gdb/solib-spu.c: spu_so_ops.free_so = spu_free_so; - # XXX + # Never called directly + # xfree(so) added gdb/solib-sunos.c:sunos_free_so (struct so_list *so) gdb/solib-sunos.c: sunos_so_ops.free_so = sunos_free_so; - # XXX + # Never called directly + # xfree(so) added gdb/solib-svr4.c: svr4_free_so (so->lm_info->copy); gdb/solib-svr4.c:svr4_free_so (struct so_list *so) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 450d19c..9b048ac 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2013-07-05 Tristan Gingold + + * coffcode.h (coff_write_object_contents): Use ".ovrflo" name for + overflow sections. + +2013-07-05 Andreas Krebbel + + * elf32-s390.c: Add new relocation definitions R_390_PC12DBL, + R_390_PLT12DBL, R_390_PC24DBL, and R_390_PLT24DBL. + (elf_s390_reloc_type_lookup, elf_s390_check_relocs) + (elf_s390_gc_sweep_hook, elf_s390_relocate_section): Support new + relocations. + * elf64-s390.c: See elf32-s390.c + * bfd-in2.h: Add new relocs to enum bfd_reloc_code_real. + * libbfd.h: Add new reloc strings. + 2013-07-03 Marcus Shawcroft * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Reorder case diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 9cbd820..1712f12 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4332,12 +4332,24 @@ in .byte hlo8(symbol) */ /* 16 bit GOT offset. */ BFD_RELOC_390_GOT16, +/* PC relative 12 bit shifted by 1. */ + BFD_RELOC_390_PC12DBL, + +/* 12 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT12DBL, + /* PC relative 16 bit shifted by 1. */ BFD_RELOC_390_PC16DBL, /* 16 bit PC rel. PLT shifted by 1. */ BFD_RELOC_390_PLT16DBL, +/* PC relative 24 bit shifted by 1. */ + BFD_RELOC_390_PC24DBL, + +/* 24 bit PC rel. PLT shifted by 1. */ + BFD_RELOC_390_PLT24DBL, + /* PC relative 32 bit shifted by 1. */ BFD_RELOC_390_PC32DBL, diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 2a1a172..a198e1c 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -3953,7 +3953,7 @@ coff_write_object_contents (bfd * abfd) bfd_size_type amt; internal_f.f_nscns++; - strncpy (&(scnhdr.s_name[0]), current->name, 8); + memcpy (scnhdr.s_name, ".ovrflo", 8); scnhdr.s_paddr = current->reloc_count; scnhdr.s_vaddr = current->lineno_count; scnhdr.s_size = 0; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 52d4abc..6467b03 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -40,7 +40,7 @@ static reloc_howto_type elf_howto_table[] = { HOWTO (R_390_NONE, /* type */ 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ @@ -161,6 +161,14 @@ static reloc_howto_type elf_howto_table[] = s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE), HOWTO(R_390_IRELATIVE, 0, 2, 32, TRUE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, 0xffffffff, FALSE), + HOWTO(R_390_PC12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PC12DBL", FALSE, 0,0x00000fff, TRUE), + HOWTO(R_390_PLT12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE), + HOWTO(R_390_PC24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PC24DBL", FALSE, 0,0x00ffffff, TRUE), + HOWTO(R_390_PLT24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE), }; /* GNU extension to record C++ vtable hierarchy. */ @@ -211,10 +219,18 @@ elf_s390_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &elf_howto_table[(int) R_390_GOT16]; case BFD_RELOC_16_PCREL: return &elf_howto_table[(int) R_390_PC16]; + case BFD_RELOC_390_PC12DBL: + return &elf_howto_table[(int) R_390_PC12DBL]; + case BFD_RELOC_390_PLT12DBL: + return &elf_howto_table[(int) R_390_PLT12DBL]; case BFD_RELOC_390_PC16DBL: return &elf_howto_table[(int) R_390_PC16DBL]; case BFD_RELOC_390_PLT16DBL: return &elf_howto_table[(int) R_390_PLT16DBL]; + case BFD_RELOC_390_PC24DBL: + return &elf_howto_table[(int) R_390_PC24DBL]; + case BFD_RELOC_390_PLT24DBL: + return &elf_howto_table[(int) R_390_PLT24DBL]; case BFD_RELOC_390_PC32DBL: return &elf_howto_table[(int) R_390_PC32DBL]; case BFD_RELOC_390_PLT32DBL: @@ -1107,7 +1123,9 @@ elf_s390_check_relocs (bfd *abfd, are done. */ break; + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32DBL: case R_390_PLT32: case R_390_PLTOFF16: @@ -1242,7 +1260,9 @@ elf_s390_check_relocs (bfd *abfd, case R_390_16: case R_390_32: case R_390_PC16: + case R_390_PC12DBL: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32DBL: case R_390_PC32: if (h != NULL) @@ -1287,7 +1307,9 @@ elf_s390_check_relocs (bfd *abfd, if ((info->shared && (sec->flags & SEC_ALLOC) != 0 && ((ELF32_R_TYPE (rel->r_info) != R_390_PC16 + && ELF32_R_TYPE (rel->r_info) != R_390_PC12DBL && ELF32_R_TYPE (rel->r_info) != R_390_PC16DBL + && ELF32_R_TYPE (rel->r_info) != R_390_PC24DBL && ELF32_R_TYPE (rel->r_info) != R_390_PC32DBL && ELF32_R_TYPE (rel->r_info) != R_390_PC32) || (h != NULL @@ -1364,7 +1386,9 @@ elf_s390_check_relocs (bfd *abfd, p->count += 1; if (ELF32_R_TYPE (rel->r_info) == R_390_PC16 + || ELF32_R_TYPE (rel->r_info) == R_390_PC12DBL || ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL + || ELF32_R_TYPE (rel->r_info) == R_390_PC24DBL || ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL || ELF32_R_TYPE (rel->r_info) == R_390_PC32) p->pc_count += 1; @@ -1531,14 +1555,18 @@ elf_s390_gc_sweep_hook (bfd *abfd, case R_390_20: case R_390_32: case R_390_PC16: + case R_390_PC12DBL: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32DBL: case R_390_PC32: if (info->shared) break; /* Fall through. */ + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32DBL: case R_390_PLT32: case R_390_PLTOFF16: @@ -2508,6 +2536,36 @@ elf_s390_relocate_section (bfd *output_bfd, base_got->contents + off); h->got.offset |= 1; } + + if ((h->def_regular + && info->shared + && SYMBOL_REFERENCES_LOCAL (info, h)) + /* lrl rx,sym@GOTENT -> larl rx, sym */ + && ((r_type == R_390_GOTENT + && (bfd_get_16 (input_bfd, + contents + rel->r_offset - 2) + & 0xff0f) == 0xc40d) + /* ly rx, sym@GOT(r12) -> larl rx, sym */ + || (r_type == R_390_GOT20 + && (bfd_get_32 (input_bfd, + contents + rel->r_offset - 2) + & 0xff00f000) == 0xe300c000 + && bfd_get_8 (input_bfd, + contents + rel->r_offset + 3) == 0x58))) + { + unsigned short new_insn = + (0xc000 | (bfd_get_8 (input_bfd, + contents + rel->r_offset - 1) & 0xf0)); + bfd_put_16 (output_bfd, new_insn, + contents + rel->r_offset - 2); + r_type = R_390_PC32DBL; + rel->r_addend = 2; + howto = elf_howto_table + r_type; + relocation = h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset; + goto do_relocation; + } } else unresolved_reloc = FALSE; @@ -2588,7 +2646,9 @@ elf_s390_relocate_section (bfd *output_bfd, unresolved_reloc = FALSE; break; + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32DBL: case R_390_PLT32: /* Relocation is to the entry for this symbol in the @@ -2651,7 +2711,9 @@ elf_s390_relocate_section (bfd *output_bfd, case R_390_16: case R_390_32: case R_390_PC16: + case R_390_PC12DBL: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32DBL: case R_390_PC32: if (h != NULL @@ -2723,7 +2785,9 @@ elf_s390_relocate_section (bfd *output_bfd, || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) && ((r_type != R_390_PC16 + && r_type != R_390_PC12DBL && r_type != R_390_PC16DBL + && r_type != R_390_PC24DBL && r_type != R_390_PC32DBL && r_type != R_390_PC32) || !SYMBOL_CALLS_LOCAL (info, h))) @@ -2764,7 +2828,9 @@ elf_s390_relocate_section (bfd *output_bfd, else if (h != NULL && h->dynindx != -1 && (r_type == R_390_PC16 + || r_type == R_390_PC12DBL || r_type == R_390_PC16DBL + || r_type == R_390_PC24DBL || r_type == R_390_PC32DBL || r_type == R_390_PC32 || !info->shared @@ -3242,6 +3308,13 @@ elf_s390_relocate_section (bfd *output_bfd, do_relocation: + /* When applying a 24 bit reloc we need to start one byte + earlier. Otherwise the 32 bit get/put bfd operations might + access a byte after the actual section. */ + if (r_type == R_390_PC24DBL + || r_type == R_390_PLT24DBL) + rel->r_offset--; + if (r_type == R_390_20 || r_type == R_390_GOT20 || r_type == R_390_GOTPLT20 diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index f2c396f..75413e0 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -43,7 +43,7 @@ static reloc_howto_type elf_howto_table[] = { HOWTO (R_390_NONE, /* type */ 0, /* rightshift */ - 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */ 0, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ @@ -171,7 +171,14 @@ static reloc_howto_type elf_howto_table[] = s390_elf_ldisp_reloc, "R_390_TLS_GOTIE20", FALSE, 0,0x0fffff00, FALSE), HOWTO(R_390_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_IRELATIVE", FALSE, 0, MINUS_ONE, FALSE), - + HOWTO(R_390_PC12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PC12DBL", FALSE, 0,0x00000fff, TRUE), + HOWTO(R_390_PLT12DBL, 1, 1, 12, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PLT12DBL", FALSE, 0,0x00000fff, TRUE), + HOWTO(R_390_PC24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PC24DBL", FALSE, 0,0x00ffffff, TRUE), + HOWTO(R_390_PLT24DBL, 1, 2, 24, TRUE, 0, complain_overflow_bitfield, + bfd_elf_generic_reloc, "R_390_PLT24DBL", FALSE, 0,0x00ffffff, TRUE), }; /* GNU extension to record C++ vtable hierarchy. */ @@ -222,10 +229,18 @@ elf_s390_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, return &elf_howto_table[(int) R_390_GOT16]; case BFD_RELOC_16_PCREL: return &elf_howto_table[(int) R_390_PC16]; + case BFD_RELOC_390_PC12DBL: + return &elf_howto_table[(int) R_390_PC12DBL]; + case BFD_RELOC_390_PLT12DBL: + return &elf_howto_table[(int) R_390_PLT12DBL]; case BFD_RELOC_390_PC16DBL: return &elf_howto_table[(int) R_390_PC16DBL]; case BFD_RELOC_390_PLT16DBL: return &elf_howto_table[(int) R_390_PLT16DBL]; + case BFD_RELOC_390_PC24DBL: + return &elf_howto_table[(int) R_390_PC24DBL]; + case BFD_RELOC_390_PLT24DBL: + return &elf_howto_table[(int) R_390_PLT24DBL]; case BFD_RELOC_390_PC32DBL: return &elf_howto_table[(int) R_390_PC32DBL]; case BFD_RELOC_390_PLT32DBL: @@ -1037,7 +1052,9 @@ elf_s390_check_relocs (bfd *abfd, are done. */ break; + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32: case R_390_PLT32DBL: case R_390_PLT64: @@ -1176,8 +1193,10 @@ elf_s390_check_relocs (bfd *abfd, case R_390_16: case R_390_32: case R_390_64: + case R_390_PC12DBL: case R_390_PC16: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32: case R_390_PC32DBL: case R_390_PC64: @@ -1223,7 +1242,9 @@ elf_s390_check_relocs (bfd *abfd, if ((info->shared && (sec->flags & SEC_ALLOC) != 0 && ((ELF64_R_TYPE (rel->r_info) != R_390_PC16 + && ELF64_R_TYPE (rel->r_info) != R_390_PC12DBL && ELF64_R_TYPE (rel->r_info) != R_390_PC16DBL + && ELF64_R_TYPE (rel->r_info) != R_390_PC24DBL && ELF64_R_TYPE (rel->r_info) != R_390_PC32 && ELF64_R_TYPE (rel->r_info) != R_390_PC32DBL && ELF64_R_TYPE (rel->r_info) != R_390_PC64) @@ -1300,6 +1321,8 @@ elf_s390_check_relocs (bfd *abfd, p->count += 1; if (ELF64_R_TYPE (rel->r_info) == R_390_PC16 + || ELF64_R_TYPE (rel->r_info) == R_390_PC12DBL + || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL || ELF64_R_TYPE (rel->r_info) == R_390_PC32 || ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL @@ -1471,7 +1494,9 @@ elf_s390_gc_sweep_hook (bfd *abfd, case R_390_32: case R_390_64: case R_390_PC16: + case R_390_PC12DBL: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32: case R_390_PC32DBL: case R_390_PC64: @@ -1479,7 +1504,9 @@ elf_s390_gc_sweep_hook (bfd *abfd, break; /* Fall through */ + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32: case R_390_PLT32DBL: case R_390_PLT64: @@ -2469,6 +2496,37 @@ elf_s390_relocate_section (bfd *output_bfd, base_got->contents + off); h->got.offset |= 1; } + + if ((h->def_regular + && info->shared + && SYMBOL_REFERENCES_LOCAL (info, h)) + /* lgrl rx,sym@GOTENT -> larl rx, sym */ + && ((r_type == R_390_GOTENT + && (bfd_get_16 (input_bfd, + contents + rel->r_offset - 2) + & 0xff0f) == 0xc408) + /* lg rx, sym@GOT(r12) -> larl rx, sym */ + || (r_type == R_390_GOT20 + && (bfd_get_32 (input_bfd, + contents + rel->r_offset - 2) + & 0xff00f000) == 0xe300c000 + && bfd_get_8 (input_bfd, + contents + rel->r_offset + 3) == 0x04))) + + { + unsigned short new_insn = + (0xc000 | (bfd_get_8 (input_bfd, + contents + rel->r_offset - 1) & 0xf0)); + bfd_put_16 (output_bfd, new_insn, + contents + rel->r_offset - 2); + r_type = R_390_PC32DBL; + rel->r_addend = 2; + howto = elf_howto_table + r_type; + relocation = h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset; + goto do_relocation; + } } else unresolved_reloc = FALSE; @@ -2550,7 +2608,9 @@ elf_s390_relocate_section (bfd *output_bfd, unresolved_reloc = FALSE; break; + case R_390_PLT12DBL: case R_390_PLT16DBL: + case R_390_PLT24DBL: case R_390_PLT32: case R_390_PLT32DBL: case R_390_PLT64: @@ -2615,7 +2675,9 @@ elf_s390_relocate_section (bfd *output_bfd, case R_390_32: case R_390_64: case R_390_PC16: + case R_390_PC12DBL: case R_390_PC16DBL: + case R_390_PC24DBL: case R_390_PC32: case R_390_PC32DBL: case R_390_PC64: @@ -2689,7 +2751,9 @@ elf_s390_relocate_section (bfd *output_bfd, || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) && ((r_type != R_390_PC16 + && r_type != R_390_PC12DBL && r_type != R_390_PC16DBL + && r_type != R_390_PC24DBL && r_type != R_390_PC32 && r_type != R_390_PC32DBL && r_type != R_390_PC64) @@ -2731,7 +2795,9 @@ elf_s390_relocate_section (bfd *output_bfd, else if (h != NULL && h->dynindx != -1 && (r_type == R_390_PC16 + || r_type == R_390_PC12DBL || r_type == R_390_PC16DBL + || r_type == R_390_PC24DBL || r_type == R_390_PC32 || r_type == R_390_PC32DBL || r_type == R_390_PC64 @@ -3168,6 +3234,13 @@ elf_s390_relocate_section (bfd *output_bfd, do_relocation: + /* When applying a 24 bit reloc we need to start one byte + earlier. Otherwise the 32 bit get/put bfd operations might + access a byte after the actual section. */ + if (r_type == R_390_PC24DBL + || r_type == R_390_PLT24DBL) + rel->r_offset--; + if (r_type == R_390_20 || r_type == R_390_GOT20 || r_type == R_390_GOTPLT20 diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 274b49d..1381803 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2008,8 +2008,12 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_390_RELATIVE", "BFD_RELOC_390_GOTPC", "BFD_RELOC_390_GOT16", + "BFD_RELOC_390_PC12DBL", + "BFD_RELOC_390_PLT12DBL", "BFD_RELOC_390_PC16DBL", "BFD_RELOC_390_PLT16DBL", hooks/post-receive -- Repository for Project Archer.