[s390x] Backport arch12 support and other s390x fixes (RH BZ 1420304).

This commit is contained in:
Jan Kratochvil 2017-08-19 22:40:32 +02:00
parent 99b34dc784
commit 4f1de05c3f
38 changed files with 4770 additions and 374 deletions

View File

@ -0,0 +1,62 @@
commit d7ab4911f8aa3e1cd06ece40f74d0b4a532d6a10
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 8 19:10:42 2017 +0200
S/390: Fix ifunc missing runtime reloc
This fixes a problem with a missing R_390_64 reloc against .data for a
function pointer to an ifunc function.
No regressions on s390x.
Pushed to mainline.
bfd/ChangeLog:
2017-05-08 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf-s390-common.c: Don't check non_got_ref flag.
* elf32-s390.c (elf_s390_relocate_section): Likewise.
* elf64-s390.c (elf_s390_relocate_section): Likewise.
--- a/bfd/elf-s390-common.c
+++ b/bfd/elf-s390-common.c
@@ -161,9 +161,7 @@ keep:
h->type = STT_FUNC;
}
- /* We need dynamic relocation for STT_GNU_IFUNC symbol only when
- there is a non-GOT reference in a shared object. */
- if (!bfd_link_pic (info) || !h->non_got_ref)
+ if (!bfd_link_pic (info))
*head = NULL;
/* Finally, allocate space. */
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -2774,7 +2774,7 @@ elf_s390_relocate_section (bfd *output_bfd,
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
{
- if (!bfd_link_pic (info) || !h->non_got_ref)
+ if (!bfd_link_pic (info))
{
/* For a non-shared object STT_GNU_IFUNC symbol must
go through PLT. */
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -2737,10 +2737,11 @@ elf_s390_relocate_section (bfd *output_bfd,
&& s390_is_ifunc_symbol_p (h)
&& h->def_regular)
{
- if (!bfd_link_pic (info) || !h->non_got_ref)
+ if (!bfd_link_pic (info))
{
- /* For a non-shared object STT_GNU_IFUNC symbol must
- go through PLT. */
+ /* For a non-shared object the symbol will not
+ change. Hence we can write the address of the
+ target IPLT slot now. */
relocation = (htab->elf.iplt->output_section->vma
+ htab->elf.iplt->output_offset
+ h ->plt.offset);

View File

@ -0,0 +1,43 @@
commit a0a110b0dd5077373c4102d1502130eb159c366b
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Wed May 17 12:39:39 2017 +0200
S/390: Fix arch level of pckmo instruction.
Fix wrong architecture level of PCKMO instruction.
Committed to mainline.
opcodes/ChangeLog:
2017-05-17 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-opc.txt: PCKMO change arch level to z196.
gas/ChangeLog:
2017-05-17 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* testsuite/gas/s390/zarch-z10.d: Remove pckmo.
* testsuite/gas/s390/zarch-z10.s: Remove pckmo.
* testsuite/gas/s390/zarch-z196.d: Add pckmo.
* testsuite/gas/s390/zarch-z196.s: Add pckmo.
--- a/opcodes/s390-opc.txt
+++ b/opcodes/s390-opc.txt
@@ -976,7 +976,6 @@ b286 qsi S_RD "query sampling information" z10 zarch
b2e0 scctr RRE_RR "set cpu counter" z10 zarch
b2e1 spctr RRE_RR "set peripheral counter" z10 zarch
b280 lpp S_RD "load program parameter" z10 zarch
-b928 pckmo RRE_00 "perform cryptographic key management operation" z10 zarch
# The new instructions of the IBM zEnterprise z196
b9c8 ahhhr RRF_R0RR2 "add high high" z196 zarch
@@ -1116,6 +1115,7 @@ b92a kmf RRE_RR "cipher message with CFB" z196 zarch
b92b kmo RRE_RR "cipher message with OFB" z196 zarch
b92c pcc RRE_00 "perform cryptographic computation" z196 zarch
b92d kmctr RRF_R0RR "cipher message with counter" z196 zarch
+b928 pckmo RRE_00 "perform cryptographic key management operation" z196 zarch
# The new instructions of the IBM zEnterprise EC12
b2ec etnd RRE_R0 "extract transaction nesting depth" zEC12 zarch htm

View File

@ -0,0 +1,52 @@
commit bfcfbe611b4d7e650236f8b8ba7d0706cfe6a0b7
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 29 12:33:15 2017 +0200
S/390: Remove optional operand flag.
The per operand optional flag hasn't been used for quite some time.
Cleanup some remains.
include/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* opcode/s390.h: Remove S390_OPERAND_OPTIONAL.
gas/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/tc-s390.c (md_gather_operands): Remove code dealing with
S390_OPERAND_OPTIONAL.
--- a/include/opcode/s390.h
+++ b/include/opcode/s390.h
@@ -156,21 +156,17 @@ extern const struct s390_operand s390_operands[];
/* This operand is a length. */
#define S390_OPERAND_LENGTH 0x200
-/* This operand is optional. Only a single operand at the end of
- the instruction may be optional. */
-#define S390_OPERAND_OPTIONAL 0x400
-
/* The operand needs to be a valid GP or FP register pair. */
-#define S390_OPERAND_REG_PAIR 0x800
+#define S390_OPERAND_REG_PAIR 0x400
/* This operand names a vector register. The disassembler uses this
to print register names with a leading 'v'. */
-#define S390_OPERAND_VR 0x1000
+#define S390_OPERAND_VR 0x800
-#define S390_OPERAND_CP16 0x2000
+#define S390_OPERAND_CP16 0x1000
-#define S390_OPERAND_OR1 0x4000
-#define S390_OPERAND_OR2 0x8000
-#define S390_OPERAND_OR8 0x10000
+#define S390_OPERAND_OR1 0x2000
+#define S390_OPERAND_OR2 0x4000
+#define S390_OPERAND_OR8 0x8000
#endif /* S390_H */

View File

@ -0,0 +1,97 @@
commit a09f2586017aeed82fa07c8bfea6c75859295bd9
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 29 12:34:56 2017 +0200
S/390: Improve error checking for optional operands
So far we only had an instruction flag which made an arbitrary number
of operands optional. This limits error checking capabilities for
instructions marked that way. With this patch the optparm flag only
allows a single optional parameter and another one is added (optparm2)
allowing 2 optional arguments. Hopefully we won't need more than that
in the future. So far there will be only a single use of optparm2.
gas/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/tc-s390.c (md_gather_operands): Support new optparm2
instruction flag.
include/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* opcode/s390.h: Add new instruction flags optparm2.
opcodes/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-dis.c (s390_print_insn_with_opcode): Support new optparm2
instruction flag.
* s390-mkopc.c (main): Recognize the new instruction flag when
parsing instruction list.
--- a/include/opcode/s390.h
+++ b/include/opcode/s390.h
@@ -48,10 +48,11 @@ enum s390_opcode_cpu_val
/* Instruction specific flags. */
#define S390_INSTR_FLAG_OPTPARM 0x1
+#define S390_INSTR_FLAG_OPTPARM2 0x2
-#define S390_INSTR_FLAG_HTM 0x2
-#define S390_INSTR_FLAG_VX 0x4
-#define S390_INSTR_FLAG_FACILITY_MASK 0x6
+#define S390_INSTR_FLAG_HTM 0x4
+#define S390_INSTR_FLAG_VX 0x8
+#define S390_INSTR_FLAG_FACILITY_MASK 0xc
/* The opcode table is an array of struct s390_opcode. */
--- a/opcodes/s390-dis.c
+++ b/opcodes/s390-dis.c
@@ -206,11 +206,20 @@ s390_print_insn_with_opcode (bfd_vma memaddr,
/* For instructions with a last optional operand don't print it
if zero. */
- if ((opcode->flags & S390_INSTR_FLAG_OPTPARM)
+ if ((opcode->flags & (S390_INSTR_FLAG_OPTPARM | S390_INSTR_FLAG_OPTPARM2))
&& val.u == 0
&& opindex[1] == 0)
break;
+ if ((opcode->flags & S390_INSTR_FLAG_OPTPARM2)
+ && val.u == 0 && opindex[1] != 0 && opindex[2] == 0)
+ {
+ union operand_value next_op_val =
+ s390_extract_operand (buffer, s390_operands + opindex[1]);
+ if (next_op_val.u == 0)
+ break;
+ }
+
if (flags & S390_OPERAND_GPR)
info->fprintf_func (info->stream, "%c%%r%u", separator, val.u);
else if (flags & S390_OPERAND_FPR)
--- a/opcodes/s390-mkopc.c
+++ b/opcodes/s390-mkopc.c
@@ -411,12 +411,16 @@ main (void)
&& (str[7] == 0 || str[7] == ',')) {
flag_bits |= S390_INSTR_FLAG_OPTPARM;
str += 7;
+ } else if (strncmp (str, "optparm2", 8) == 0
+ && (str[8] == 0 || str[8] == ',')) {
+ flag_bits |= S390_INSTR_FLAG_OPTPARM2;
+ str += 8;
} else if (strncmp (str, "htm", 3) == 0
- && (str[3] == 0 || str[3] == ',')) {
+ && (str[3] == 0 || str[3] == ',')) {
flag_bits |= S390_INSTR_FLAG_HTM;
str += 3;
} else if (strncmp (str, "vx", 2) == 0
- && (str[2] == 0 || str[2] == ',')) {
+ && (str[2] == 0 || str[2] == ',')) {
flag_bits |= S390_INSTR_FLAG_VX;
str += 2;
} else {

View File

@ -0,0 +1,58 @@
commit ffc61c5de1a5a89e3e37fb9376725c32a839c34d
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 29 12:36:57 2017 +0200
S/390: Add ipte/idte variants with optional operands
This patch adds missing variants of ipte and idte instructions added with later CPU
generations.
ipte got an optional operand with z196 and another one with zEC12.
idte got an optional operand with zEC12
opcodes/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-opc.c: Add new idte/ipte variants.
* s390-opc.txt: Likewise.
gas/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* testsuite/gas/s390/zarch-z196.d: Add new idte/ipte variants.
* testsuite/gas/s390/zarch-z196.s: Likewise.
* testsuite/gas/s390/zarch-zEC12.d: Likewise.
* testsuite/gas/s390/zarch-zEC12.s: Likewise.
--- a/opcodes/s390-opc.c
+++ b/opcodes/s390-opc.c
@@ -355,7 +355,7 @@ const struct s390_operand s390_operands[] =
#define INSTR_RRF_FEUFEFE 4, { FE_24,FE_16,FE_28,U4_20,0,0 } /* e.g. qaxtr */
#define INSTR_RRF_FUFF2 4, { F_24,F_28,F_16,U4_20,0,0 } /* e.g. adtra */
#define INSTR_RRF_FEUFEFE2 4, { FE_24,FE_28,FE_16,U4_20,0,0 } /* e.g. axtra */
-#define INSTR_RRF_RURR 4, { R_24,R_28,R_16,U4_20,0,0 } /* e.g. .insn */
+#define INSTR_RRF_RURR 4, { R_24,R_28,R_16,U4_20,0,0 } /* e.g. ipte */
#define INSTR_RRF_RURR2 4, { R_24,R_16,R_28,U4_20,0,0 } /* e.g. lptea */
#define INSTR_RRF_R0RR 4, { R_24,R_16,R_28,0,0,0 } /* e.g. idte */
#define INSTR_RRF_R0RR2 4, { R_24,R_28,R_16,0,0,0 } /* e.g. ark */
--- a/opcodes/s390-opc.txt
+++ b/opcodes/s390-opc.txt
@@ -1116,6 +1116,7 @@ b92b kmo RRE_RR "cipher message with OFB" z196 zarch
b92c pcc RRE_00 "perform cryptographic computation" z196 zarch
b92d kmctr RRF_R0RR "cipher message with counter" z196 zarch
b928 pckmo RRE_00 "perform cryptographic key management operation" z196 zarch
+b221 ipte RRF_R0RR2 "invalidate page table entry" z196 zarch optparm
# The new instructions of the IBM zEnterprise EC12
b2ec etnd RRE_R0 "extract transaction nesting depth" zEC12 zarch htm
@@ -1143,6 +1144,8 @@ ed00000000aa cdzt RSL_LRDFU "convert from zoned long" zEC12 zarch
ed00000000ab cxzt RSL_LRDFEU "convert from zoned extended" zEC12 zarch
ed00000000a8 czdt RSL_LRDFU "convert to zoned long" zEC12 zarch
ed00000000a9 czxt RSL_LRDFEU "convert to zoned extended" zEC12 zarch
+b98e idte RRF_RURR2 "invalidate dat table entry" zEC12 zarch optparm
+b221 ipte RRF_RURR "invalidate page table entry" zEC12 zarch optparm2
# The new instructions of IBM z13

View File

@ -0,0 +1,31 @@
commit 67aa8be4cb43cd94bc322fed8bdba48b3c8719c4
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 29 12:38:11 2017 +0200
S/390: Add missing operand to tb instruction
gas/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* testsuite/gas/s390/esa-g5.d: Add missing operand to tb
instruction.
* testsuite/gas/s390/esa-g5.s: Likewise.
opcodes/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-opc.txt: Add missing operand to tb instruction.
--- a/opcodes/s390-opc.txt
+++ b/opcodes/s390-opc.txt
@@ -228,7 +228,7 @@ b246 stura RRE_RR "store using real address" g5 esa,zarch
2f swr RR_FF "subtract unnormalized (long)" g5 esa,zarch
37 sxr RR_FEFE "subtract normalized (ext.)" g5 esa,zarch
b24c tar RRE_AR "test access" g5 esa,zarch
-b22c tb RRE_0R "test block" g5 esa,zarch
+b22c tb RRE_RR "test block" g5 esa,zarch
91 tm SI_URD "test under mask" g5 esa,zarch
b236 tpi S_RD "test pending interruption" g5 esa,zarch
e501 tprot SSE_RDRD "test protection" g5 esa,zarch

View File

@ -0,0 +1,53 @@
commit ca87ae741fe9c8aad9db1afbf109dc070d0168cf
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon May 29 12:38:42 2017 +0200
S/390: Fix instruction types of csdtr and csxtr
opcodes/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-opc.c: Add new instruction types RRF_0URF and RRF_0UREFE.
* s390-opc.txt: Fix instruction typs of csdtr and csxtr.
gas/ChangeLog:
2017-05-30 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* testsuite/gas/s390/zarch-z9-ec.d: Adjust csdtr and csxtr.
* testsuite/gas/s390/zarch-z9-ec.s: Likewise.
--- a/opcodes/s390-opc.c
+++ b/opcodes/s390-opc.c
@@ -374,6 +374,8 @@ const struct s390_operand s390_operands[] =
#define INSTR_RRF_U0RER 4, { RE_24,R_28,U4_16,0,0,0 } /* e.g. trte */
#define INSTR_RRF_U0RERE 4, { RE_24,RE_28,U4_16,0,0,0 } /* e.g. cu24 */
#define INSTR_RRF_00RR 4, { R_24,R_28,0,0,0,0 } /* e.g. clrtne */
+#define INSTR_RRF_0URF 4, { R_24,F_28,U4_20,0,0,0 } /* e.g. csdtr */
+#define INSTR_RRF_0UREFE 4, { RE_24,FE_28,U4_20,0,0,0 } /* e.g. csxtr */
#define INSTR_RRF_UUFR 4, { F_24,U4_16,R_28,U4_20,0,0 } /* e.g. cdgtra */
#define INSTR_RRF_UUFER 4, { FE_24,U4_16,R_28,U4_20,0,0 } /* e.g. cxfbra */
#define INSTR_RRF_UURF 4, { R_24,U4_16,F_28,U4_20,0,0 } /* e.g. cgdtra */
@@ -590,6 +592,8 @@ const struct s390_operand s390_operands[] =
#define MASK_RRF_U0RER { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 }
#define MASK_RRF_U0RERE { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 }
#define MASK_RRF_00RR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 }
+#define MASK_RRF_0URF { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 }
+#define MASK_RRF_0UREFE { 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00 }
#define MASK_RRF_UUFR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
#define MASK_RRF_UUFER { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
#define MASK_RRF_UURF { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
--- a/opcodes/s390-opc.txt
+++ b/opcodes/s390-opc.txt
@@ -817,8 +817,8 @@ b3f2 cdutr RRE_FR "convert from unsigned bcd to long dfp" z9-ec zarch
b3fa cxutr RRE_FER "convert from unsigned bcd to extended dfp" z9-ec zarch
b3e1 cgdtr RRF_U0RF "convert from long dfp to fixed" z9-ec zarch
b3e9 cgxtr RRF_U0RFE "convert from extended dfp to fixed" z9-ec zarch
-b3e3 csdtr RRE_RF "convert from long dfp to signed bcd" z9-ec zarch
-b3eb csxtr RRE_RFE "convert from extended dfp to signed bcd" z9-ec zarch
+b3e3 csdtr RRF_0URF "convert from long dfp to signed bcd" z9-ec zarch
+b3eb csxtr RRF_0UREFE "convert from extended dfp to signed bcd" z9-ec zarch
b3e2 cudtr RRE_RF "convert from long dfp to unsigned bcd" z9-ec zarch
b3ea cuxtr RRE_RFE "convert from extended dfp to unsigned bcd" z9-ec zarch
b3d1 ddtr RRR_F0FF "divide long dfp" z9-ec zarch

View File

@ -0,0 +1,76 @@
commit 19fb31c0060f646a9f84be1a84ed1bea04e7ed57
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Thu Jun 1 13:46:15 2017 +0200
S/390: idte/ipte fixes
Later CPU generations added optional operands to the ipte/idte
instructions. I've added these with:
https://sourceware.org/ml/binutils/2017-05/msg00316.html ... but
supported the optional operands only with the specific hardware
levels. However, it is more useful to have the optional operands
already in the first versions. Of course they need to be zero there.
Regression-tested with on s390 and s390x. Committed to mainline.
Bye,
-Andreas-
opcodes/ChangeLog:
2017-06-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-opc.txt: Support the optional parameters with the first
versions of ipte/idte.
gas/ChangeLog:
2017-06-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* testsuite/gas/s390/esa-g5.d: Add ipte tests.
* testsuite/gas/s390/esa-g5.s: Likewise.
* testsuite/gas/s390/zarch-z196.d: Remove ipte tests.
* testsuite/gas/s390/zarch-z196.s: Likewise.
* testsuite/gas/s390/zarch-z990.d: Add idte tests.
* testsuite/gas/s390/zarch-z990.s: Likewise.
* testsuite/gas/s390/zarch-zEC12.d: Remove ipte/idte tests.
* testsuite/gas/s390/zarch-zEC12.s: Likewise.
--- a/opcodes/s390-opc.txt
+++ b/opcodes/s390-opc.txt
@@ -79,7 +79,7 @@ b224 iac RRE_R0 "insert address space control" g5 esa,zarch
bf icm RS_RURD "insert characters under mask" g5 esa,zarch
b20b ipk S_00 "insert PSW key" g5 esa,zarch
b222 ipm RRE_R0 "insert program mask" g5 esa,zarch
-b221 ipte RRE_RR "invalidate page table entry" g5 esa,zarch
+b221 ipte RRF_RURR "invalidate page table entry" g5 esa,zarch optparm2
b229 iske RRE_RR "insert storage key extended" g5 esa,zarch
b223 ivsk RRE_RR "insert virtual storage key" g5 esa,zarch
58 l RX_RRRD "load" g5 esa,zarch
@@ -700,7 +700,7 @@ eb000000008f clclu RSY_RRRD "compare logical long unicode with long offset" z990
eb0000000096 lmh RSY_RRRD "load multiple high" z990 zarch
# new z990 instructions
b98a cspg RRE_RR "compare and swap and purge" z990 zarch
-b98e idte RRF_R0RR "invalidate dat table entry" z990 zarch
+b98e idte RRF_RURR2 "invalidate dat table entry" z990 zarch optparm
b33e madr RRF_F0FF "multiply and add long hfp" z990 esa,zarch
ed000000003e mad RXF_FRRDF "multiply and add long hfp" z990 esa,zarch
b32e maer RRF_F0FF "multiply and add short hfp" z990 esa,zarch
@@ -1116,7 +1116,6 @@ b92b kmo RRE_RR "cipher message with OFB" z196 zarch
b92c pcc RRE_00 "perform cryptographic computation" z196 zarch
b92d kmctr RRF_R0RR "cipher message with counter" z196 zarch
b928 pckmo RRE_00 "perform cryptographic key management operation" z196 zarch
-b221 ipte RRF_R0RR2 "invalidate page table entry" z196 zarch optparm
# The new instructions of the IBM zEnterprise EC12
b2ec etnd RRE_R0 "extract transaction nesting depth" zEC12 zarch htm
@@ -1144,8 +1143,6 @@ ed00000000aa cdzt RSL_LRDFU "convert from zoned long" zEC12 zarch
ed00000000ab cxzt RSL_LRDFEU "convert from zoned extended" zEC12 zarch
ed00000000a8 czdt RSL_LRDFU "convert to zoned long" zEC12 zarch
ed00000000a9 czxt RSL_LRDFEU "convert to zoned extended" zEC12 zarch
-b98e idte RRF_RURR2 "invalidate dat table entry" zEC12 zarch optparm
-b221 ipte RRF_RURR "invalidate page table entry" zEC12 zarch optparm2
# The new instructions of IBM z13

View File

@ -0,0 +1,123 @@
commit 3704e3589d3d187fbf76e688388b1a92fd627c8d
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Fri Jun 9 11:19:01 2017 +0200
S/390: Return with an error for broken tls rewrites
bfd/ChangeLog:
2017-06-12 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf32-s390.c (elf_s390_relocate_section): Return false in case
the rewriting fails.
* elf64-s390.c (elf_s390_relocate_section): Likewise.
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -3231,7 +3231,6 @@ elf_s390_relocate_section (bfd *output_bfd,
unsigned int insn, ry;
insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
- ry = 0;
if ((insn & 0xff00f000) == 0x58000000)
/* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0 */
ry = (insn & 0x000f0000);
@@ -3245,7 +3244,10 @@ elf_s390_relocate_section (bfd *output_bfd,
/* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0 */
ry = (insn & 0x0000f000) << 4;
else
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
insn = 0x18000700 | (insn & 0x00f00000) | ry;
bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
}
@@ -3258,7 +3260,10 @@ elf_s390_relocate_section (bfd *output_bfd,
if ((insn & 0xff000fff) != 0x4d000000 &&
(insn & 0xffff0000) != 0xc0e50000 &&
(insn & 0xff000000) != 0x0d000000)
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
{
if ((insn & 0xff000000) == 0x0d000000)
@@ -3287,7 +3292,10 @@ elf_s390_relocate_section (bfd *output_bfd,
/* If basr is used in the pic case to invoke
_tls_get_offset, something went wrong before. */
if ((insn & 0xff000000) == 0x0d000000)
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
if ((insn & 0xff000000) == 0x4d000000)
{
@@ -3317,7 +3325,10 @@ elf_s390_relocate_section (bfd *output_bfd,
if ((insn & 0xff000fff) != 0x4d000000 &&
(insn & 0xffff0000) != 0xc0e50000 &&
(insn & 0xff000000) != 0x0d000000)
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
if ((insn & 0xff000000) == 0x0d000000)
{
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -3197,8 +3197,10 @@ elf_s390_relocate_section (bfd *output_bfd,
insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
if (insn1 != 0x0004)
- invalid_tls_insn (input_bfd, input_section, rel);
- ry = 0;
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
if ((insn0 & 0xff00f000) == 0xe3000000)
/* lg %rx,0(%ry,0) -> sllg %rx,%ry,0 */
ry = (insn0 & 0x000f0000);
@@ -3212,7 +3214,10 @@ elf_s390_relocate_section (bfd *output_bfd,
/* lg %rx,0(%r12,%ry) -> sllg %rx,%ry,0 */
ry = (insn0 & 0x0000f000) << 4;
else
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
insn0 = 0xeb000000 | (insn0 & 0x00f00000) | ry;
insn1 = 0x000d;
bfd_put_32 (output_bfd, insn0, contents + rel->r_offset);
@@ -3226,7 +3231,10 @@ elf_s390_relocate_section (bfd *output_bfd,
insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
if ((insn0 & 0xffff0000) != 0xc0e50000)
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
{
/* GD->LE transition.
@@ -3253,7 +3261,10 @@ elf_s390_relocate_section (bfd *output_bfd,
insn0 = bfd_get_32 (input_bfd, contents + rel->r_offset);
insn1 = bfd_get_16 (input_bfd, contents + rel->r_offset + 4);
if ((insn0 & 0xffff0000) != 0xc0e50000)
- invalid_tls_insn (input_bfd, input_section, rel);
+ {
+ invalid_tls_insn (input_bfd, input_section, rel);
+ return FALSE;
+ }
/* LD->LE transition.
brasl %r14,__tls_get_addr@plt -> brcl 0,. */
insn0 = 0xc0040000;

View File

@ -0,0 +1,270 @@
commit 0567c9861e113a573cc905002a59cb1bc3d78450
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:25 2017 +0200
Add test for modifiable DWARF locations
This adds a test for read/write access to variables with various types of
DWARF locations. It uses register- and memory locations and composite
locations with register- and memory pieces.
Since the new test calls gdb_test_no_output with commands that contain
braces, it is necessary for string_to_regexp to quote braces as well.
This was not done before.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/var-access.c: New file.
* gdb.dwarf2/var-access.exp: New test.
* lib/gdb-utils.exp (string_to_regexp): Quote braces as well.
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,3 +1,9 @@
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * gdb.dwarf2/var-access.c: New file.
+ * gdb.dwarf2/var-access.exp: New test.
+ * lib/gdb-utils.exp (string_to_regexp): Quote braces as well.
+
2017-06-12 Tom Tromey <tom@tromey.com>
* gdb.dwarf2/formdata16.exp: Add tests.
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/var-access.c
@@ -0,0 +1,25 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+char buf[] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+int
+main (void)
+{
+ asm volatile ("main_label: .globl main_label");
+ return 0;
+}
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -0,0 +1,197 @@
+# Copyright 2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test reading/writing variables with non-trivial DWARF locations. In
+# particular the test uses register- and memory locations as well as
+# composite locations with register- and memory pieces.
+
+load_lib dwarf.exp
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if {![dwarf2_support]} {
+ return 0
+}
+
+# Choose suitable integer registers for the test.
+
+set dwarf_regnum {0 1}
+
+if { [istarget "aarch64*-*-*"] } {
+ set regname {x0 x1}
+} elseif { [istarget "arm*-*-*"]
+ || [istarget "s390*-*-*" ]
+ || [istarget "powerpc*-*-*"]
+ || [istarget "rs6000*-*-aix*"] } {
+ set regname {r0 r1}
+} elseif { [istarget "i?86-*-*"] } {
+ set regname {eax edx}
+} elseif { [istarget "x86_64-*-*"] } {
+ set regname {rax rdx}
+} else {
+ verbose "Skipping tests for accessing DWARF-described variables."
+ return
+}
+
+standard_testfile .c ${gdb_test_file_name}-dw.S
+
+# Make some DWARF for the test.
+
+set asm_file [standard_output_file $srcfile2]
+Dwarf::assemble $asm_file {
+ global srcdir subdir srcfile
+ global dwarf_regnum regname
+
+ set buf_var [gdb_target_symbol buf]
+
+ cu {} {
+ DW_TAG_compile_unit {
+ {DW_AT_name var-pieces-dw.c}
+ {DW_AT_comp_dir /tmp}
+ } {
+ declare_labels char_type_label
+ declare_labels int_type_label short_type_label
+ declare_labels array_a8_label struct_s_label
+
+ # char
+ char_type_label: base_type {
+ {name "char"}
+ {encoding @DW_ATE_unsigned_char}
+ {byte_size 1 DW_FORM_sdata}
+ }
+
+ # int
+ int_type_label: base_type {
+ {name "int"}
+ {encoding @DW_ATE_signed}
+ {byte_size 4 DW_FORM_sdata}
+ }
+
+ # char [8]
+ array_a8_label: array_type {
+ {type :$char_type_label}
+ } {
+ subrange_type {
+ {type :$int_type_label}
+ {upper_bound 7 DW_FORM_udata}
+ }
+ }
+
+ # struct s { char a, b, c, d; };
+ struct_s_label: structure_type {
+ {name "s"}
+ {byte_size 4 DW_FORM_sdata}
+ } {
+ member {
+ {name "a"}
+ {type :$char_type_label}
+ {data_member_location 0 DW_FORM_udata}
+ }
+ member {
+ {name "b"}
+ {type :$char_type_label}
+ {data_member_location 1 DW_FORM_udata}
+ }
+ member {
+ {name "c"}
+ {type :$char_type_label}
+ {data_member_location 2 DW_FORM_udata}
+ }
+ member {
+ {name "d"}
+ {type :$char_type_label}
+ {data_member_location 3 DW_FORM_udata}
+ }
+ }
+
+ DW_TAG_subprogram {
+ {MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
+ {DW_AT_external 1 flag}
+ } {
+ # Simple memory location.
+ DW_TAG_variable {
+ {name "a"}
+ {type :$array_a8_label}
+ {location {
+ addr $buf_var
+ } SPECIAL_expr}
+ }
+ # Memory pieces: two bytes from &buf[2], and two bytes
+ # from &buf[0].
+ DW_TAG_variable {
+ {name "s1"}
+ {type :$struct_s_label}
+ {location {
+ addr $buf_var
+ plus_uconst 2
+ piece 2
+ addr $buf_var
+ piece 2
+ } SPECIAL_expr}
+ }
+ # Register- and memory pieces: one byte each from r0,
+ # &buf[4], r1, and &buf[5].
+ DW_TAG_variable {
+ {name "s2"}
+ {type :$struct_s_label}
+ {location {
+ regx [lindex $dwarf_regnum 0]
+ piece 1
+ addr "$buf_var + 4"
+ piece 1
+ regx [lindex $dwarf_regnum 1]
+ piece 1
+ addr "$buf_var + 5"
+ piece 1
+ } SPECIAL_expr}
+ }
+ }
+ }
+ }
+}
+
+if { [prepare_for_testing ${testfile}.exp ${testfile} \
+ [list $srcfile $asm_file] {nodebug}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+# Byte-aligned memory pieces.
+gdb_test "print/d s1" " = \\{a = 2, b = 3, c = 0, d = 1\\}" \
+ "s1 == re-ordered buf"
+gdb_test_no_output "set var s1.a = 63"
+gdb_test "print/d s1" " = \\{a = 63, b = 3, c = 0, d = 1\\}" \
+ "verify s1.a"
+gdb_test "print/d a" " = \\{0, 1, 63, 3, 4, 5, 6, 7\\}" \
+ "verify s1.a through a"
+
+# Byte-aligned register- and memory pieces.
+gdb_test_no_output "set var \$[lindex $regname 0] = 81" \
+ "init reg for s2.a"
+gdb_test_no_output "set var \$[lindex $regname 1] = 28" \
+ "init reg for s2.c"
+gdb_test "print/d s2" " = \\{a = 81, b = 4, c = 28, d = 5\\}" \
+ "initialized s2 from mem and regs"
+gdb_test_no_output "set var s2.c += s2.a + s2.b - s2.d"
+gdb_test "print/d s2" " = \\{a = 81, b = 4, c = 108, d = 5\\}" \
+ "verify s2.c"
+gdb_test "print/d \$[lindex $regname 1]" " = 108" \
+ "verify s2.c through reg"
+gdb_test_no_output "set var s2 = {191, 73, 231, 123}" \
+ "re-initialize s2"
+gdb_test "print/d s2" " = \\{a = 191, b = 73, c = 231, d = 123\\}" \
+ "verify re-initialized s2"
--- a/gdb/testsuite/lib/gdb-utils.exp
+++ b/gdb/testsuite/lib/gdb-utils.exp
@@ -34,6 +34,6 @@ proc gdb_init_commands {} {
proc string_to_regexp {str} {
set result $str
- regsub -all {[]*+.|()^$\[\\]} $str {\\&} result
+ regsub -all {[]*+.|(){}^$\[\\]} $str {\\&} result
return $result
}

View File

@ -0,0 +1,106 @@
commit d5d1163eff2415a01895f1cff8bbee32b3f0ab66
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:26 2017 +0200
write_pieced_value: Fix size capping logic
A field f in a structure composed of DWARF pieces may be located in
multiple pieces, where the first and last of those may contain bits from
other fields as well. So when writing to f, the beginning of the first
and the end of the last of those pieces may have to be skipped. But the
logic in write_pieced_value for handling one of those pieces is flawed
when the first and last piece are the same, i.e., f is contained in a
single piece:
< - - - - - - - - - piece_size - - - - - - - - - ->
+-------------------------------------------------+
| skipped_bits | f_bits | / / / / / / / / / / |
+-------------------------------------------------+
The current logic determines the size of the sub-piece to operate on by
limiting the piece size to the bit size of f and then subtracting the
skipped bits:
min (piece_size, f_bits) - skipped_bits
Instead of:
min (piece_size - skipped_bits, f_bits)
So the resulting sub-piece size is corrupted, leading to wrong handling of
this piece in write_pieced_value.
Note that the same bug was already found in read_pieced_value and fixed
there (but not in write_pieced_value), see PR 15391.
This patch swaps the calculations, bringing them into the same (correct)
order as in read_pieced_value.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): Fix order of calculations for
size capping.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/var-pieces.exp: Add test case for modifying a
variable at nonzero offset.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,3 +1,8 @@
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * dwarf2loc.c (write_pieced_value): Fix order of calculations for
+ size capping.
+
2017-06-13 Yao Qi <yao.qi@linaro.org>
* mips-linux-nat.c: Move include features/mips*-linux.c to
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1964,8 +1964,6 @@ write_pieced_value (struct value *to, struct value *from)
bits_to_skip -= this_size_bits;
continue;
}
- if (this_size_bits > type_len - offset)
- this_size_bits = type_len - offset;
if (bits_to_skip > 0)
{
dest_offset_bits = bits_to_skip;
@@ -1978,6 +1976,8 @@ write_pieced_value (struct value *to, struct value *from)
dest_offset_bits = 0;
source_offset_bits = offset;
}
+ if (this_size_bits > type_len - offset)
+ this_size_bits = type_len - offset;
this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * gdb.dwarf2/var-pieces.exp: Add test case for modifying a
+ variable at nonzero offset.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* gdb.dwarf2/var-access.c: New file.
* gdb.dwarf2/var-access.exp: New test.
* lib/gdb-utils.exp (string_to_regexp): Quote braces as well.
--- a/gdb/testsuite/gdb.dwarf2/var-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -178,6 +178,11 @@ gdb_test "print/d s1" " = \\{a = 63, b = 3, c = 0, d = 1\\}" \
"verify s1.a"
gdb_test "print/d a" " = \\{0, 1, 63, 3, 4, 5, 6, 7\\}" \
"verify s1.a through a"
+gdb_test_no_output "set var s1.b = 42"
+gdb_test "print/d s1" " = \\{a = 63, b = 42, c = 0, d = 1\\}" \
+ "verify s1.b"
+gdb_test "print/d a" " = \\{0, 1, 63, 42, 4, 5, 6, 7\\}" \
+ "verify s1.b through a"
# Byte-aligned register- and memory pieces.
gdb_test_no_output "set var \$[lindex $regname 0] = 81" \

View File

@ -0,0 +1,189 @@
commit e93523245b704bc126705620969b4736b00350c5
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:26 2017 +0200
PR gdb/21226: Take DWARF stack value pieces from LSB end
When taking a DW_OP_piece or DW_OP_bit_piece from a DW_OP_stack_value, the
existing logic always takes the piece from the lowest-addressed end, which
is wrong on big-endian targets. The DWARF standard states that the
"DW_OP_bit_piece operation describes a sequence of bits using the least
significant bits of that value", and this also matches the current logic
in GCC. For instance, the GCC guality test case pr54970.c fails on s390x
because of this.
This fix adjusts the piece accordingly on big-endian targets. It is
assumed that:
* DW_OP_piece shall take the piece from the LSB end as well;
* pieces reaching outside the stack value bits are considered undefined,
and a zero value can be used instead.
gdb/ChangeLog:
PR gdb/21226
* dwarf2loc.c (read_pieced_value): Anchor stack value pieces at
the LSB end, independent of endianness.
gdb/testsuite/ChangeLog:
PR gdb/21226
* gdb.dwarf2/nonvar-access.exp: Add checks for verifying that
stack value pieces are taken from the LSB end.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ PR gdb/21226
+ * dwarf2loc.c (read_pieced_value): Anchor stack value pieces at
+ the LSB end, independent of endianness.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): Fix order of calculations for
size capping.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1858,6 +1858,10 @@ read_pieced_value (struct value *v)
if (unavail)
mark_value_bits_unavailable (v, offset, this_size_bits);
}
+
+ copy_bitwise (contents, dest_offset_bits,
+ intermediate_buffer, source_offset_bits % 8,
+ this_size_bits, bits_big_endian);
}
break;
@@ -1866,26 +1870,30 @@ read_pieced_value (struct value *v)
p->v.mem.in_stack_memory,
p->v.mem.addr + source_offset,
buffer.data (), this_size);
+ copy_bitwise (contents, dest_offset_bits,
+ intermediate_buffer, source_offset_bits % 8,
+ this_size_bits, bits_big_endian);
break;
case DWARF_VALUE_STACK:
{
- size_t n = this_size;
+ struct objfile *objfile = dwarf2_per_cu_objfile (c->per_cu);
+ struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
+ ULONGEST stack_value_size_bits
+ = 8 * TYPE_LENGTH (value_type (p->v.value));
- if (n > c->addr_size - source_offset)
- n = (c->addr_size >= source_offset
- ? c->addr_size - source_offset
- : 0);
- if (n == 0)
- {
- /* Nothing. */
- }
- else
- {
- const gdb_byte *val_bytes = value_contents_all (p->v.value);
+ /* Use zeroes if piece reaches beyond stack value. */
+ if (p->size > stack_value_size_bits)
+ break;
- intermediate_buffer = val_bytes + source_offset;
- }
+ /* Piece is anchored at least significant bit end. */
+ if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
+ source_offset_bits += stack_value_size_bits - p->size;
+
+ copy_bitwise (contents, dest_offset_bits,
+ value_contents_all (p->v.value),
+ source_offset_bits,
+ this_size_bits, bits_big_endian);
}
break;
@@ -1899,6 +1907,10 @@ read_pieced_value (struct value *v)
: 0);
if (n != 0)
intermediate_buffer = p->v.literal.data + source_offset;
+
+ copy_bitwise (contents, dest_offset_bits,
+ intermediate_buffer, source_offset_bits % 8,
+ this_size_bits, bits_big_endian);
}
break;
@@ -1915,12 +1927,6 @@ read_pieced_value (struct value *v)
internal_error (__FILE__, __LINE__, _("invalid location type"));
}
- if (p->location != DWARF_VALUE_OPTIMIZED_OUT
- && p->location != DWARF_VALUE_IMPLICIT_POINTER)
- copy_bitwise (contents, dest_offset_bits,
- intermediate_buffer, source_offset_bits % 8,
- this_size_bits, bits_big_endian);
-
offset += this_size_bits;
}
}
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ PR gdb/21226
+ * gdb.dwarf2/nonvar-access.exp: Add checks for verifying that
+ stack value pieces are taken from the LSB end.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* gdb.dwarf2/var-pieces.exp: Add test case for modifying a
variable at nonzero offset.
--- a/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/nonvar-access.exp
@@ -128,14 +128,26 @@ Dwarf::assemble $asm_file {
{name def_t}
{type :$struct_t_label}
{location {
- const1u 0
+ const2s -184
stack_value
bit_piece 9 0
- const1s -1
+ const4u 1752286
stack_value
bit_piece 23 0
} SPECIAL_expr}
}
+ # Composite location with some empty pieces.
+ DW_TAG_variable {
+ {name part_def_a}
+ {type :$array_a9_label}
+ {location {
+ piece 3
+ const4u 0xf1927314
+ stack_value
+ piece 4
+ piece 2
+ } SPECIAL_expr}
+ }
# Implicit location: immediate value.
DW_TAG_variable {
{name def_implicit_s}
@@ -221,9 +233,12 @@ gdb_test "print/x *implicit_b_ptr" " = $val"
# Byte-aligned fields, pieced together from DWARF stack values.
gdb_test "print def_s" " = \\{a = 0, b = -1\\}"
+switch $endian { big {set val 0x92} little {set val 0x73} }
+gdb_test "print/x part_def_a\[4\]" " = $val"
+gdb_test "print/x part_def_a\[8\]" " = <optimized out>"
# Non-byte-aligned fields, pieced together from DWARF stack values.
-gdb_test "print def_t" " = \\{a = 0, b = -1\\}"
+gdb_test "print def_t" " = \\{a = -184, b = 1752286\\}"
# Simple variable without location.
gdb_test "print undef_int" " = <optimized out>"

View File

@ -0,0 +1,72 @@
commit 805acca042afed8e8431c92ab031167b03475676
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:26 2017 +0200
gdb/testsuite: Add "get_endianness" convenience proc
The test suite contains multiple instances of determining the target's
endianness with GDB's "show endian" command. This patch replaces these by
an invocation of a new convenience proc 'get_endianness'.
gdb/testsuite/ChangeLog:
* lib/gdb.exp (get_endianness): New proc.
* gdb.arch/aarch64-fp.exp: Use it.
* gdb.arch/altivec-regs.exp: Likewise.
* gdb.arch/e500-regs.exp: Likewise.
* gdb.arch/vsx-regs.exp: Likewise.
* gdb.base/dump.exp: Likewise.
* gdb.base/funcargs.exp: Likewise.
* gdb.base/gnu_vector.exp: Likewise.
* gdb.dwarf2/formdata16.exp: Likewise.
* gdb.dwarf2/implptrpiece.exp: Likewise.
* gdb.dwarf2/nonvar-access.exp: Likewise.
* gdb.python/py-inferior.exp: Likewise.
* gdb.trace/unavailable-dwarf-piece.exp: Likewise.
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,5 +1,21 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * lib/gdb.exp (get_endianness): New proc.
+ * gdb.arch/aarch64-fp.exp: Use it.
+ * gdb.arch/altivec-regs.exp: Likewise.
+ * gdb.arch/e500-regs.exp: Likewise.
+ * gdb.arch/vsx-regs.exp: Likewise.
+ * gdb.base/dump.exp: Likewise.
+ * gdb.base/funcargs.exp: Likewise.
+ * gdb.base/gnu_vector.exp: Likewise.
+ * gdb.dwarf2/formdata16.exp: Likewise.
+ * gdb.dwarf2/implptrpiece.exp: Likewise.
+ * gdb.dwarf2/nonvar-access.exp: Likewise.
+ * gdb.python/py-inferior.exp: Likewise.
+ * gdb.trace/unavailable-dwarf-piece.exp: Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
PR gdb/21226
* gdb.dwarf2/nonvar-access.exp: Add checks for verifying that
stack value pieces are taken from the LSB end.
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -5671,6 +5671,19 @@ proc set_remotetimeout { timeout } {
}
}
+# Get the target's current endianness and return it.
+proc get_endianness { } {
+ global gdb_prompt
+
+ gdb_test_multiple "show endian" "determine endianness" {
+ -re ".* (little|big) endian.*\r\n$gdb_prompt $" {
+ # Pass silently.
+ return $expect_out(1,string)
+ }
+ }
+ return "little"
+}
+
# ROOT and FULL are file names. Returns the relative path from ROOT
# to FULL. Note that FULL must be in a subdirectory of ROOT.
# For example, given ROOT = /usr/bin and FULL = /usr/bin/ls, this

View File

@ -0,0 +1,70 @@
commit af547a9614969e1d1ea6fcec6b59cd77a606380f
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:27 2017 +0200
read/write_pieced_value: Respect value parent's offset
In the case of targeting a bit-field, read_pieced_value and
write_pieced_value calculate the number of bits preceding the bit-field
without considering the relative offset of the value's parent. This is
relevant for a structure variable like this:
struct s {
uint64_t foo;
struct {
uint32_t bar;
uint32_t bf : 10; /* <-- target bit-field */
} baz;
} s;
In this scenario, if 'val' is a GDB value representing s.baz.bf,
val->parent represents the whole s.baz structure, and the following holds:
- value_offset (val) == sizeof s.baz.bar == 4
- value_offset (val->parent) == sizeof s.foo == 8
The current logic would only use value_offset(val), resulting in the wrong
offset into the target value. This is fixed.
gdb/ChangeLog:
* dwarf2loc.c (read_pieced_value): Respect parent value's offset
when targeting a bit-field.
(write_pieced_value): Likewise.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (read_pieced_value): Respect parent value's offset
+ when targeting a bit-field.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (struct piece_closure) <addr_size>: Remove field.
(allocate_piece_closure): Drop addr_size parameter.
(dwarf2_evaluate_loc_desc_full): Adjust call to
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1776,7 +1776,8 @@ read_pieced_value (struct value *v)
bits_to_skip = 8 * value_offset (v);
if (value_bitsize (v))
{
- bits_to_skip += value_bitpos (v);
+ bits_to_skip += (8 * value_offset (value_parent (v))
+ + value_bitpos (v));
type_len = value_bitsize (v);
}
else
@@ -1946,7 +1947,8 @@ write_pieced_value (struct value *to, struct value *from)
bits_to_skip = 8 * value_offset (to);
if (value_bitsize (to))
{
- bits_to_skip += value_bitpos (to);
+ bits_to_skip += (8 * value_offset (value_parent (to))
+ + value_bitpos (to));
type_len = value_bitsize (to);
}
else

View File

@ -0,0 +1,40 @@
commit cdaac320fd62bff75562aaa3e466494dc72dd175
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:27 2017 +0200
write_pieced_value: Fix copy/paste error in size calculation
In write_pieced_value, the number of bytes containing a portion of the
bit-field in a given piece is calculated with the wrong starting offset;
thus the result may be off by one. This bug was probably introduced when
copying this logic from read_pieced_value. Fix it.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): Fix copy/paste error in the
calculation of this_size.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (write_pieced_value): Fix copy/paste error in the
+ calculation of this_size.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (read_pieced_value): Respect parent value's offset
when targeting a bit-field.
(write_pieced_value): Likewise.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1983,7 +1983,7 @@ write_pieced_value (struct value *to, struct value *from)
if (this_size_bits > type_len - offset)
this_size_bits = type_len - offset;
- this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
+ this_size = (this_size_bits + dest_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
dest_offset = dest_offset_bits / 8;
if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0)

View File

@ -0,0 +1,42 @@
commit f1cc987420d9d2489eb453bd1c87139666cbe7fd
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:27 2017 +0200
write_pieced_value: Include transfer size in byte-wise check
In write_pieced_value, when checking whether the data can be transferred
byte-wise, the current logic verifies the source- and destination offsets
to be byte-aligned, but not the transfer size. This is fixed.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): Include transfer size in
byte-wise check.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (write_pieced_value): Include transfer size in
+ byte-wise check.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): Fix copy/paste error in the
calculation of this_size.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1986,7 +1986,10 @@ write_pieced_value (struct value *to, struct value *from)
this_size = (this_size_bits + dest_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
dest_offset = dest_offset_bits / 8;
- if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0)
+
+ /* Check whether the data can be transferred byte-wise. */
+ if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0
+ && this_size_bits % 8 == 0)
{
source_buffer = contents + source_offset;
need_bitwise = 0;

View File

@ -0,0 +1,42 @@
commit 07c9ca3bd8e6f83bcec49c922b52422c538f60f7
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:28 2017 +0200
write_pieced_value: Fix buffer offset for memory pieces
In write_pieced_value, when transferring the data to target memory via a
buffer, the bit offset within the target value is not reduced to its
sub-byte fraction before using it as a bit offset into the buffer. This
is fixed.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): In DWARF_VALUE_MEMORY,
truncate full bytes from dest_offset_bits before using it as an
offset into the buffer.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (write_pieced_value): In DWARF_VALUE_MEMORY,
+ truncate full bytes from dest_offset_bits before using it as an
+ offset into the buffer.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): Include transfer size in
byte-wise check.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2058,7 +2058,7 @@ write_pieced_value (struct value *to, struct value *from)
read_memory (p->v.mem.addr + dest_offset, buffer.data (), 1);
read_memory (p->v.mem.addr + dest_offset + this_size - 1,
&buffer[this_size - 1], 1);
- copy_bitwise (buffer.data (), dest_offset_bits,
+ copy_bitwise (buffer.data (), dest_offset_bits % 8,
contents, source_offset_bits,
this_size_bits,
bits_big_endian);

View File

@ -0,0 +1,166 @@
commit 359b19bb24d048750aa5367ad56a33267300d1a8
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:28 2017 +0200
write_pieced_value: Transfer least significant bits into bit-field
On big-endian targets, when targeting a bit-field, write_pieced_value
currently transfers the source value's *most* significant bits to the
target value, instead of its least significant bits. This is fixed.
In particular the fix adjusts the initial value of 'offset', which can now
potentially be nonzero. Thus the variable 'type_len' is renamed to
'max_offset', to avoid confusion. And for consistency, the affected logic
that was mirrored in read_pieced_value is changed there in the same way.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): When writing to a bit-field,
transfer the source value's least significant bits, instead of its
lowest-addressed ones. Rename type_len to max_offset.
(read_pieced_value): Mirror above changes to write_pieced_value as
applicable.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,13 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (write_pieced_value): When writing to a bit-field,
+ transfer the source value's least significant bits, instead of its
+ lowest-addressed ones. Rename type_len to max_offset.
+ (read_pieced_value): Mirror above changes to write_pieced_value as
+ applicable.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): In DWARF_VALUE_MEMORY,
truncate full bytes from dest_offset_bits before using it as an
offset into the buffer.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1756,12 +1756,11 @@ static void
read_pieced_value (struct value *v)
{
int i;
- long offset = 0;
+ LONGEST offset = 0, max_offset;
ULONGEST bits_to_skip;
gdb_byte *contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (v);
- size_t type_len;
size_t buffer_size = 0;
std::vector<gdb_byte> buffer;
int bits_big_endian
@@ -1778,12 +1777,12 @@ read_pieced_value (struct value *v)
{
bits_to_skip += (8 * value_offset (value_parent (v))
+ value_bitpos (v));
- type_len = value_bitsize (v);
+ max_offset = value_bitsize (v);
}
else
- type_len = 8 * TYPE_LENGTH (value_type (v));
+ max_offset = 8 * TYPE_LENGTH (value_type (v));
- for (i = 0; i < c->n_pieces && offset < type_len; i++)
+ for (i = 0; i < c->n_pieces && offset < max_offset; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size, this_size_bits;
@@ -1798,20 +1797,13 @@ read_pieced_value (struct value *v)
bits_to_skip -= this_size_bits;
continue;
}
- if (bits_to_skip > 0)
- {
- dest_offset_bits = 0;
- source_offset_bits = bits_to_skip;
- this_size_bits -= bits_to_skip;
- bits_to_skip = 0;
- }
- else
- {
- dest_offset_bits = offset;
- source_offset_bits = 0;
- }
- if (this_size_bits > type_len - offset)
- this_size_bits = type_len - offset;
+ source_offset_bits = bits_to_skip;
+ this_size_bits -= bits_to_skip;
+ bits_to_skip = 0;
+ dest_offset_bits = offset;
+
+ if (this_size_bits > max_offset - offset)
+ this_size_bits = max_offset - offset;
this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
@@ -1932,12 +1924,11 @@ static void
write_pieced_value (struct value *to, struct value *from)
{
int i;
- long offset = 0;
ULONGEST bits_to_skip;
+ LONGEST offset = 0, max_offset;
const gdb_byte *contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (to);
- size_t type_len;
size_t buffer_size = 0;
std::vector<gdb_byte> buffer;
int bits_big_endian
@@ -1949,12 +1940,20 @@ write_pieced_value (struct value *to, struct value *from)
{
bits_to_skip += (8 * value_offset (value_parent (to))
+ value_bitpos (to));
- type_len = value_bitsize (to);
- }
+ /* Use the least significant bits of FROM. */
+ if (gdbarch_byte_order (get_type_arch (value_type (from)))
+ == BFD_ENDIAN_BIG)
+ {
+ max_offset = 8 * TYPE_LENGTH (value_type (from));
+ offset = max_offset - value_bitsize (to);
+ }
+ else
+ max_offset = value_bitsize (to);
+ }
else
- type_len = 8 * TYPE_LENGTH (value_type (to));
+ max_offset = 8 * TYPE_LENGTH (value_type (to));
- for (i = 0; i < c->n_pieces && offset < type_len; i++)
+ for (i = 0; i < c->n_pieces && offset < max_offset; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size_bits, this_size;
@@ -1968,20 +1967,13 @@ write_pieced_value (struct value *to, struct value *from)
bits_to_skip -= this_size_bits;
continue;
}
- if (bits_to_skip > 0)
- {
- dest_offset_bits = bits_to_skip;
- source_offset_bits = 0;
- this_size_bits -= bits_to_skip;
- bits_to_skip = 0;
- }
- else
- {
- dest_offset_bits = 0;
- source_offset_bits = offset;
- }
- if (this_size_bits > type_len - offset)
- this_size_bits = type_len - offset;
+ dest_offset_bits = bits_to_skip;
+ this_size_bits -= bits_to_skip;
+ bits_to_skip = 0;
+ source_offset_bits = offset;
+
+ if (this_size_bits > max_offset - offset)
+ this_size_bits = max_offset - offset;
this_size = (this_size_bits + dest_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;

View File

@ -0,0 +1,142 @@
commit 3bf310110722b03d9ff9c4f34f5920a9be2878d0
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:29 2017 +0200
Add DWARF piece test cases for bit-field access
This verifies some of the previous fixes to the logic in
write_pieced_value when accessing bit-fields.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/var-access.exp: Add tests for accessing bit-fields
located in one or more DWARF pieces.
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * gdb.dwarf2/var-access.exp: Add tests for accessing bit-fields
+ located in one or more DWARF pieces.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* lib/gdb.exp (get_endianness): New proc.
* gdb.arch/aarch64-fp.exp: Use it.
* gdb.arch/altivec-regs.exp: Likewise.
--- a/gdb/testsuite/gdb.dwarf2/var-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -62,7 +62,8 @@ Dwarf::assemble $asm_file {
} {
declare_labels char_type_label
declare_labels int_type_label short_type_label
- declare_labels array_a8_label struct_s_label
+ declare_labels array_a8_label struct_s_label struct_t_label
+ declare_labels struct_st_label
# char
char_type_label: base_type {
@@ -115,6 +116,51 @@ Dwarf::assemble $asm_file {
}
}
+ # struct t { int u, x:9, y:13, z:10; };
+ struct_t_label: structure_type {
+ {name "t"}
+ {byte_size 8 DW_FORM_sdata}
+ } {
+ member {
+ {name "u"}
+ {type :$int_type_label}
+ }
+ member {
+ {name "x"}
+ {type :$int_type_label}
+ {data_member_location 4 DW_FORM_udata}
+ {bit_size 9 DW_FORM_udata}
+ }
+ member {
+ {name "y"}
+ {type :$int_type_label}
+ {data_bit_offset 41 DW_FORM_udata}
+ {bit_size 13 DW_FORM_udata}
+ }
+ member {
+ {name "z"}
+ {type :$int_type_label}
+ {data_bit_offset 54 DW_FORM_udata}
+ {bit_size 10 DW_FORM_udata}
+ }
+ }
+
+ # struct st { struct s s; struct t t; };
+ struct_st_label: structure_type {
+ {name "st"}
+ {byte_size 12 DW_FORM_udata}
+ } {
+ member {
+ {name "s"}
+ {type :$struct_s_label}
+ }
+ member {
+ {name "t"}
+ {type :$struct_t_label}
+ {data_member_location 4 DW_FORM_udata}
+ }
+ }
+
DW_TAG_subprogram {
{MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
{DW_AT_external 1 flag}
@@ -156,6 +202,19 @@ Dwarf::assemble $asm_file {
piece 1
} SPECIAL_expr}
}
+ # Memory pieces for bitfield access: 8 bytes optimized
+ # out, 3 bytes from &buf[3], and 1 byte from &buf[1].
+ DW_TAG_variable {
+ {name "st1"}
+ {type :$struct_st_label}
+ {location {
+ piece 8
+ addr "$buf_var + 3"
+ piece 3
+ addr "$buf_var + 1"
+ piece 1
+ } SPECIAL_expr}
+ }
}
}
}
@@ -170,6 +229,9 @@ if ![runto_main] {
return -1
}
+# Determine byte order.
+set endian [get_endianness]
+
# Byte-aligned memory pieces.
gdb_test "print/d s1" " = \\{a = 2, b = 3, c = 0, d = 1\\}" \
"s1 == re-ordered buf"
@@ -200,3 +262,20 @@ gdb_test_no_output "set var s2 = {191, 73, 231, 123}" \
"re-initialize s2"
gdb_test "print/d s2" " = \\{a = 191, b = 73, c = 231, d = 123\\}" \
"verify re-initialized s2"
+
+# Unaligned bitfield access through byte-aligned pieces.
+gdb_test_no_output "set var a = { 0 }"
+gdb_test_no_output "set var st1.t.x = -7"
+gdb_test_no_output "set var st1.t.z = 340"
+gdb_test_no_output "set var st1.t.y = 1234"
+gdb_test "print st1.t" " = \\{u = <optimized out>, x = -7, y = 1234, z = 340\\}" \
+ "verify st1.t"
+switch $endian {
+ little {set val "0x55, 0x0, 0xf9, 0xa5, 0x9"}
+ big {set val "0x54, 0x0, 0xfc, 0x93, 0x49"}
+}
+# | -- | z:2-9 | -- | x:0-7 | x:8 y:0-6 | y:7-12 z:0-1 | -- | -- |
+# \_______________________________________________/
+# val
+gdb_test "print/x a" " = \\{0x0, ${val}, 0x0, 0x0\\}" \
+ "verify st1 through a"

View File

@ -0,0 +1,74 @@
commit 840989c113433c069f54872d7e051e1572202326
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:30 2017 +0200
read/write_pieced_value: Drop 'buffer_size' variable
When the variable 'buffer_size' in read_pieced_value and
write_pieced_value was introduced, it was needed for tracking the buffer's
allocated size. Now that the buffer's data type has been changed to a
std::vector, the variable is no longer necessary; so remove it.
gdb/ChangeLog:
* dwarf2loc.c (read_pieced_value): Remove buffer_size variable.
(write_pieced_value): Likewise.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (read_pieced_value): Remove buffer_size variable.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): When writing to a bit-field,
transfer the source value's least significant bits, instead of its
lowest-addressed ones. Rename type_len to max_offset.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1761,7 +1761,6 @@ read_pieced_value (struct value *v)
gdb_byte *contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (v);
- size_t buffer_size = 0;
std::vector<gdb_byte> buffer;
int bits_big_endian
= gdbarch_bits_big_endian (get_type_arch (value_type (v)));
@@ -1806,12 +1805,8 @@ read_pieced_value (struct value *v)
this_size_bits = max_offset - offset;
this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
+ buffer.reserve (this_size);
source_offset = source_offset_bits / 8;
- if (buffer_size < this_size)
- {
- buffer_size = this_size;
- buffer.reserve (buffer_size);
- }
intermediate_buffer = buffer.data ();
/* Copy from the source to DEST_BUFFER. */
@@ -1929,7 +1924,6 @@ write_pieced_value (struct value *to, struct value *from)
const gdb_byte *contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (to);
- size_t buffer_size = 0;
std::vector<gdb_byte> buffer;
int bits_big_endian
= gdbarch_bits_big_endian (get_type_arch (value_type (to)));
@@ -1988,11 +1982,7 @@ write_pieced_value (struct value *to, struct value *from)
}
else
{
- if (buffer_size < this_size)
- {
- buffer_size = this_size;
- buffer.reserve (buffer_size);
- }
+ buffer.reserve (this_size);
source_buffer = buffer.data ();
need_bitwise = 1;
}

View File

@ -0,0 +1,227 @@
commit 03c8af18d1a8f359fd023696848bda488119da60
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:30 2017 +0200
Fix handling of DWARF register pieces on big-endian targets
For big-endian targets the logic in read/write_pieced_value tries to take
a register piece from the LSB end. This requires offsets and sizes to be
adjusted accordingly, and that's where the current implementation has some
issues:
* The formulas for recalculating the bit- and byte-offsets into the
register are wrong. They just happen to yield correct results if
everything is byte-aligned and the piece's last byte belongs to the
given value.
* After recalculating the bit offset into the register, the number of
bytes to be copied from the register is not recalculated. Of course
this does not matter if everything (particularly the piece size) is
byte-aligned.
These issues are fixed. The size calculation is performed with a new
helper function bits_to_bytes().
gdb/ChangeLog:
* dwarf2loc.c (bits_to_bytes): New function.
(read_pieced_value): Fix offset calculations for register pieces
on big-endian targets.
(write_pieced_value): Likewise.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/var-access.exp: Add test for non-byte-aligned
register pieces.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,12 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (bits_to_bytes): New function.
+ (read_pieced_value): Fix offset calculations for register pieces
+ on big-endian targets.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (read_pieced_value): Remove buffer_size variable.
(write_pieced_value): Likewise.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1752,6 +1752,15 @@ copy_bitwise_tests (void)
#endif /* GDB_SELF_TEST */
+/* Return the number of bytes overlapping a contiguous chunk of N_BITS
+ bits whose first bit is located at bit offset START. */
+
+static size_t
+bits_to_bytes (ULONGEST start, ULONGEST n_bits)
+{
+ return (start % 8 + n_bits + 7) / 8;
+}
+
static void
read_pieced_value (struct value *v)
{
@@ -1804,7 +1813,7 @@ read_pieced_value (struct value *v)
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
- this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
+ this_size = bits_to_bytes (source_offset_bits, this_size_bits);
buffer.reserve (this_size);
source_offset = source_offset_bits / 8;
intermediate_buffer = buffer.data ();
@@ -1817,20 +1826,20 @@ read_pieced_value (struct value *v)
struct frame_info *frame = frame_find_by_id (c->frame_id);
struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
+ ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
int optim, unavail;
- LONGEST reg_offset = source_offset;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && this_size < register_size (arch, gdb_regnum))
+ && p->size < reg_bits)
{
/* Big-endian, and we want less than full size. */
- reg_offset = register_size (arch, gdb_regnum) - this_size;
- /* We want the lower-order THIS_SIZE_BITS of the bytes
- we extract from the register. */
- source_offset_bits += 8 * this_size - this_size_bits;
+ source_offset_bits += reg_bits - p->size;
}
+ this_size = bits_to_bytes (source_offset_bits, this_size_bits);
+ buffer.reserve (this_size);
- if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ if (!get_frame_register_bytes (frame, gdb_regnum,
+ source_offset_bits / 8,
this_size, buffer.data (),
&optim, &unavail))
{
@@ -1844,7 +1853,7 @@ read_pieced_value (struct value *v)
}
copy_bitwise (contents, dest_offset_bits,
- intermediate_buffer, source_offset_bits % 8,
+ buffer.data (), source_offset_bits % 8,
this_size_bits, bits_big_endian);
}
break;
@@ -1969,7 +1978,7 @@ write_pieced_value (struct value *to, struct value *from)
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
- this_size = (this_size_bits + dest_offset_bits % 8 + 7) / 8;
+ this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
source_offset = source_offset_bits / 8;
dest_offset = dest_offset_bits / 8;
@@ -1994,20 +2003,25 @@ write_pieced_value (struct value *to, struct value *from)
struct frame_info *frame = frame_find_by_id (c->frame_id);
struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
- int reg_offset = dest_offset;
+ ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && this_size <= register_size (arch, gdb_regnum))
+ && p->size <= reg_bits)
{
/* Big-endian, and we want less than full size. */
- reg_offset = register_size (arch, gdb_regnum) - this_size;
+ dest_offset_bits += reg_bits - p->size;
}
+ this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
+ buffer.reserve (this_size);
- if (need_bitwise)
+ if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0)
{
+ /* Data is copied non-byte-aligned into the register.
+ Need some bits from original register value. */
int optim, unavail;
- if (!get_frame_register_bytes (frame, gdb_regnum, reg_offset,
+ if (!get_frame_register_bytes (frame, gdb_regnum,
+ dest_offset_bits / 8,
this_size, buffer.data (),
&optim, &unavail))
{
@@ -2022,14 +2036,14 @@ write_pieced_value (struct value *to, struct value *from)
"bitfield; containing word "
"is unavailable"));
}
- copy_bitwise (buffer.data (), dest_offset_bits,
- contents, source_offset_bits,
- this_size_bits,
- bits_big_endian);
}
- put_frame_register_bytes (frame, gdb_regnum, reg_offset,
- this_size, source_buffer);
+ copy_bitwise (buffer.data (), dest_offset_bits % 8,
+ contents, source_offset_bits,
+ this_size_bits, bits_big_endian);
+ put_frame_register_bytes (frame, gdb_regnum,
+ dest_offset_bits / 8,
+ this_size, buffer.data ());
}
break;
case DWARF_VALUE_MEMORY:
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,5 +1,10 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * gdb.dwarf2/var-access.exp: Add test for non-byte-aligned
+ register pieces.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* gdb.dwarf2/var-access.exp: Add tests for accessing bit-fields
located in one or more DWARF pieces.
--- a/gdb/testsuite/gdb.dwarf2/var-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -215,6 +215,19 @@ Dwarf::assemble $asm_file {
piece 1
} SPECIAL_expr}
}
+ # Register pieces for bitfield access: 4 bytes optimized
+ # out, 3 bytes from r0, and 1 byte from r1.
+ DW_TAG_variable {
+ {name "t2"}
+ {type :$struct_t_label}
+ {location {
+ piece 4
+ regx [lindex $dwarf_regnum 0]
+ piece 3
+ regx [lindex $dwarf_regnum 1]
+ piece 1
+ } SPECIAL_expr}
+ }
}
}
}
@@ -279,3 +292,15 @@ switch $endian {
# val
gdb_test "print/x a" " = \\{0x0, ${val}, 0x0, 0x0\\}" \
"verify st1 through a"
+
+switch $endian { big {set val 0x7ffc} little {set val 0x3ffe00} }
+gdb_test_no_output "set var \$[lindex $regname 0] = $val" \
+ "init t2, first piece"
+gdb_test_no_output "set var \$[lindex $regname 1] = 0" \
+ "init t2, second piece"
+gdb_test "print/d t2" " = \\{u = <optimized out>, x = 0, y = -1, z = 0\\}" \
+ "initialized t2 from regs"
+gdb_test_no_output "set var t2.y = 2641"
+gdb_test_no_output "set var t2.z = -400"
+gdb_test_no_output "set var t2.x = 200"
+gdb_test "print t2.x + t2.y + t2.z" " = 2441"

View File

@ -0,0 +1,220 @@
commit 242d31ab7c3901e02bd68c1824d1d3610e02562b
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:30 2017 +0200
read/write_pieced_value: Improve logic for buffer allocation
So far the main loop in read_pieced_value and write_pieced_value is
structured like this:
(1) Prepare a buffer and some variables we may need;
(2) depending on the DWARF piece type to be handled, use the buffer and
the prepared variables, ignore them, or even recalculate them.
This approach reduces readability and may also lead to unnecessary copying
of data. This patch moves the preparations to the places where sufficient
information is available and removes some of the variables involved.
gdb/ChangeLog:
* dwarf2loc.c (read_pieced_value): Move the buffer allocation and
some other preparations to the places where sufficient information
is available.
(write_pieced_value): Likewise.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,12 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (read_pieced_value): Move the buffer allocation and
+ some other preparations to the places where sufficient information
+ is available.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (bits_to_bytes): New function.
(read_pieced_value): Fix offset calculations for register pieces
on big-endian targets.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1794,8 +1794,7 @@ read_pieced_value (struct value *v)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size, this_size_bits;
- long dest_offset_bits, source_offset_bits, source_offset;
- const gdb_byte *intermediate_buffer;
+ long dest_offset_bits, source_offset_bits;
/* Compute size, source, and destination offsets for copying, in
bits. */
@@ -1813,11 +1812,6 @@ read_pieced_value (struct value *v)
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
- this_size = bits_to_bytes (source_offset_bits, this_size_bits);
- buffer.reserve (this_size);
- source_offset = source_offset_bits / 8;
- intermediate_buffer = buffer.data ();
-
/* Copy from the source to DEST_BUFFER. */
switch (p->location)
{
@@ -1843,13 +1837,11 @@ read_pieced_value (struct value *v)
this_size, buffer.data (),
&optim, &unavail))
{
- /* Just so garbage doesn't ever shine through. */
- memset (buffer.data (), 0, this_size);
-
if (optim)
mark_value_bits_optimized_out (v, offset, this_size_bits);
if (unavail)
mark_value_bits_unavailable (v, offset, this_size_bits);
+ break;
}
copy_bitwise (contents, dest_offset_bits,
@@ -1859,12 +1851,15 @@ read_pieced_value (struct value *v)
break;
case DWARF_VALUE_MEMORY:
+ this_size = bits_to_bytes (source_offset_bits, this_size_bits);
+ buffer.reserve (this_size);
+
read_value_memory (v, offset,
p->v.mem.in_stack_memory,
- p->v.mem.addr + source_offset,
+ p->v.mem.addr + source_offset_bits / 8,
buffer.data (), this_size);
copy_bitwise (contents, dest_offset_bits,
- intermediate_buffer, source_offset_bits % 8,
+ buffer.data (), source_offset_bits % 8,
this_size_bits, bits_big_endian);
break;
@@ -1892,18 +1887,18 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_LITERAL:
{
- size_t n = this_size;
+ ULONGEST literal_size_bits = 8 * p->v.literal.length;
+ size_t n = this_size_bits;
- if (n > p->v.literal.length - source_offset)
- n = (p->v.literal.length >= source_offset
- ? p->v.literal.length - source_offset
- : 0);
- if (n != 0)
- intermediate_buffer = p->v.literal.data + source_offset;
+ /* Cut off at the end of the implicit value. */
+ if (source_offset_bits >= literal_size_bits)
+ break;
+ if (n > literal_size_bits - source_offset_bits)
+ n = literal_size_bits - source_offset_bits;
copy_bitwise (contents, dest_offset_bits,
- intermediate_buffer, source_offset_bits % 8,
- this_size_bits, bits_big_endian);
+ p->v.literal.data, source_offset_bits,
+ n, bits_big_endian);
}
break;
@@ -1960,9 +1955,7 @@ write_pieced_value (struct value *to, struct value *from)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size_bits, this_size;
- long dest_offset_bits, source_offset_bits, dest_offset, source_offset;
- int need_bitwise;
- const gdb_byte *source_buffer;
+ long dest_offset_bits, source_offset_bits;
this_size_bits = p->size;
if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
@@ -1978,24 +1971,6 @@ write_pieced_value (struct value *to, struct value *from)
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
- this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
- source_offset = source_offset_bits / 8;
- dest_offset = dest_offset_bits / 8;
-
- /* Check whether the data can be transferred byte-wise. */
- if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0
- && this_size_bits % 8 == 0)
- {
- source_buffer = contents + source_offset;
- need_bitwise = 0;
- }
- else
- {
- buffer.reserve (this_size);
- source_buffer = buffer.data ();
- need_bitwise = 1;
- }
-
switch (p->location)
{
case DWARF_VALUE_REGISTER:
@@ -2047,21 +2022,44 @@ write_pieced_value (struct value *to, struct value *from)
}
break;
case DWARF_VALUE_MEMORY:
- if (need_bitwise)
- {
- /* Only the first and last bytes can possibly have any
- bits reused. */
- read_memory (p->v.mem.addr + dest_offset, buffer.data (), 1);
- read_memory (p->v.mem.addr + dest_offset + this_size - 1,
- &buffer[this_size - 1], 1);
- copy_bitwise (buffer.data (), dest_offset_bits % 8,
- contents, source_offset_bits,
- this_size_bits,
- bits_big_endian);
- }
+ {
+ CORE_ADDR start_addr = p->v.mem.addr + dest_offset_bits / 8;
+
+ if (dest_offset_bits % 8 == 0 && this_size_bits % 8 == 0
+ && source_offset_bits % 8 == 0)
+ {
+ /* Everything is byte-aligned; no buffer needed. */
+ write_memory (start_addr,
+ contents + source_offset_bits / 8,
+ this_size_bits / 8);
+ break;
+ }
+
+ this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
+ buffer.reserve (this_size);
- write_memory (p->v.mem.addr + dest_offset,
- source_buffer, this_size);
+ if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0)
+ {
+ if (this_size <= 8)
+ {
+ /* Perform a single read for small sizes. */
+ read_memory (start_addr, buffer.data (), this_size);
+ }
+ else
+ {
+ /* Only the first and last bytes can possibly have any
+ bits reused. */
+ read_memory (start_addr, buffer.data (), 1);
+ read_memory (start_addr + this_size - 1,
+ &buffer[this_size - 1], 1);
+ }
+ }
+
+ copy_bitwise (buffer.data (), dest_offset_bits % 8,
+ contents, source_offset_bits,
+ this_size_bits, bits_big_endian);
+ write_memory (start_addr, buffer.data (), this_size);
+ }
break;
default:
mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to)));

View File

@ -0,0 +1,167 @@
commit 65d84b76164dc8ec1a1f0f0e0fd41667065ffd4e
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:31 2017 +0200
Respect piece offset for DW_OP_bit_piece
So far GDB ignores the piece offset of all kinds of DWARF bit
pieces (DW_OP_bit_piece) and treats such pieces as if the offset was zero.
This is fixed, and an appropriate test is added.
gdb/ChangeLog:
* dwarf2loc.c (read_pieced_value): Respect the piece offset, as
given by DW_OP_bit_piece.
(write_pieced_value): Likewise.
Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.dwarf2/var-access.exp: Add test for composite location with
nonzero piece offsets.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (read_pieced_value): Respect the piece offset, as
+ given by DW_OP_bit_piece.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (read_pieced_value): Move the buffer allocation and
some other preparations to the places where sufficient information
is available.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1824,11 +1824,14 @@ read_pieced_value (struct value *v)
int optim, unavail;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && p->size < reg_bits)
+ && p->offset + p->size < reg_bits)
{
/* Big-endian, and we want less than full size. */
- source_offset_bits += reg_bits - p->size;
+ source_offset_bits += reg_bits - (p->offset + p->size);
}
+ else
+ source_offset_bits += p->offset;
+
this_size = bits_to_bytes (source_offset_bits, this_size_bits);
buffer.reserve (this_size);
@@ -1851,6 +1854,7 @@ read_pieced_value (struct value *v)
break;
case DWARF_VALUE_MEMORY:
+ source_offset_bits += p->offset;
this_size = bits_to_bytes (source_offset_bits, this_size_bits);
buffer.reserve (this_size);
@@ -1871,12 +1875,15 @@ read_pieced_value (struct value *v)
= 8 * TYPE_LENGTH (value_type (p->v.value));
/* Use zeroes if piece reaches beyond stack value. */
- if (p->size > stack_value_size_bits)
+ if (p->offset + p->size > stack_value_size_bits)
break;
/* Piece is anchored at least significant bit end. */
if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
- source_offset_bits += stack_value_size_bits - p->size;
+ source_offset_bits += (stack_value_size_bits
+ - p->offset - p->size);
+ else
+ source_offset_bits += p->offset;
copy_bitwise (contents, dest_offset_bits,
value_contents_all (p->v.value),
@@ -1891,6 +1898,7 @@ read_pieced_value (struct value *v)
size_t n = this_size_bits;
/* Cut off at the end of the implicit value. */
+ source_offset_bits += p->offset;
if (source_offset_bits >= literal_size_bits)
break;
if (n > literal_size_bits - source_offset_bits)
@@ -1981,11 +1989,14 @@ write_pieced_value (struct value *to, struct value *from)
ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && p->size <= reg_bits)
+ && p->offset + p->size < reg_bits)
{
/* Big-endian, and we want less than full size. */
- dest_offset_bits += reg_bits - p->size;
+ dest_offset_bits += reg_bits - (p->offset + p->size);
}
+ else
+ dest_offset_bits += p->offset;
+
this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
buffer.reserve (this_size);
@@ -2023,6 +2034,8 @@ write_pieced_value (struct value *to, struct value *from)
break;
case DWARF_VALUE_MEMORY:
{
+ dest_offset_bits += p->offset;
+
CORE_ADDR start_addr = p->v.mem.addr + dest_offset_bits / 8;
if (dest_offset_bits % 8 == 0 && this_size_bits % 8 == 0
--- a/gdb/testsuite/gdb.dwarf2/var-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -228,6 +228,24 @@ Dwarf::assemble $asm_file {
piece 1
} SPECIAL_expr}
}
+ # One piece per bitfield, using piece offsets: 32 bits of
+ # an implicit value, 9 bits of a stack value, 13 bits of
+ # r0, and 10 bits of buf.
+ DW_TAG_variable {
+ {name "t3"}
+ {type :$struct_t_label}
+ {location {
+ implicit_value 0x12 0x34 0x56 0x78 0x9a
+ bit_piece 32 4
+ const2s -280
+ stack_value
+ bit_piece 9 2
+ regx [lindex $dwarf_regnum 0]
+ bit_piece 13 14
+ addr $buf_var
+ bit_piece 10 42
+ } SPECIAL_expr}
+ }
}
}
}
@@ -304,3 +322,24 @@ gdb_test_no_output "set var t2.y = 2641"
gdb_test_no_output "set var t2.z = -400"
gdb_test_no_output "set var t2.x = 200"
gdb_test "print t2.x + t2.y + t2.z" " = 2441"
+
+# Bitfield access through pieces with nonzero piece offsets.
+gdb_test_no_output "set var \$[lindex $regname 0] = 0xa8000" \
+ "init reg for t3.y"
+gdb_test_no_output "set var *(char \[2\] *) (a + 5) = { 70, 82 }" \
+ "init mem for t3.z"
+switch $endian {
+ little {set val "u = -1484430527, x = -70, y = 42, z = 145"}
+ big {set val "u = 591751049, x = -70, y = 42, z = 101"}
+}
+gdb_test "print t3" " = \\{$val\\}" \
+ "initialized t3 from reg and mem"
+gdb_test_no_output "set var t3.y = -1" \
+ "overwrite t3.y"
+gdb_test "print/x \$[lindex $regname 0]" " = 0x7ffc000" \
+ "verify t3.y through reg"
+gdb_test_no_output "set var t3.z = -614" \
+ "overwrite t3.z"
+switch $endian {big {set val "0x59, 0xa2"} little {set val "0x6a, 0x56"}}
+gdb_test "print/x *(char \[2\] *) (a + 5)" " = \\{$val\\}" \
+ "verify t3.z through mem"

View File

@ -0,0 +1,290 @@
commit f236533e3c6a2693bea879b2a4d24d1229864ac9
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:31 2017 +0200
read/write_pieced_value: Remove unnecessary variable copies
In read_pieced_value's main loop, the variables `dest_offset_bits' and
`source_offset_bits' are basically just copies of `offset' and
`bits_to_skip', respectively. In write_pieced_value the copies are
reversed. This is not very helpful when trying to keep the logic between
these functions in sync. Since the copies are unnecessary, this patch
just removes them.
gdb/ChangeLog:
* dwarf2loc.c (read_pieced_value): Remove unnecessary variables
dest_offset_bits and source_offset_bits.
(write_pieced_value): Likewise.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (read_pieced_value): Remove unnecessary variables
+ dest_offset_bits and source_offset_bits.
+ (write_pieced_value): Likewise.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (read_pieced_value): Respect the piece offset, as
given by DW_OP_bit_piece.
(write_pieced_value): Likewise.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1790,25 +1790,16 @@ read_pieced_value (struct value *v)
else
max_offset = 8 * TYPE_LENGTH (value_type (v));
- for (i = 0; i < c->n_pieces && offset < max_offset; i++)
+ /* Advance to the first non-skipped piece. */
+ for (i = 0; i < c->n_pieces && bits_to_skip >= c->pieces[i].size; i++)
+ bits_to_skip -= c->pieces[i].size;
+
+ for (; i < c->n_pieces && offset < max_offset; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size, this_size_bits;
- long dest_offset_bits, source_offset_bits;
-
- /* Compute size, source, and destination offsets for copying, in
- bits. */
- this_size_bits = p->size;
- if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
- {
- bits_to_skip -= this_size_bits;
- continue;
- }
- source_offset_bits = bits_to_skip;
- this_size_bits -= bits_to_skip;
- bits_to_skip = 0;
- dest_offset_bits = offset;
+ this_size_bits = p->size - bits_to_skip;
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
@@ -1827,16 +1818,16 @@ read_pieced_value (struct value *v)
&& p->offset + p->size < reg_bits)
{
/* Big-endian, and we want less than full size. */
- source_offset_bits += reg_bits - (p->offset + p->size);
+ bits_to_skip += reg_bits - (p->offset + p->size);
}
else
- source_offset_bits += p->offset;
+ bits_to_skip += p->offset;
- this_size = bits_to_bytes (source_offset_bits, this_size_bits);
+ this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.reserve (this_size);
if (!get_frame_register_bytes (frame, gdb_regnum,
- source_offset_bits / 8,
+ bits_to_skip / 8,
this_size, buffer.data (),
&optim, &unavail))
{
@@ -1846,24 +1837,23 @@ read_pieced_value (struct value *v)
mark_value_bits_unavailable (v, offset, this_size_bits);
break;
}
-
- copy_bitwise (contents, dest_offset_bits,
- buffer.data (), source_offset_bits % 8,
+ copy_bitwise (contents, offset,
+ buffer.data (), bits_to_skip % 8,
this_size_bits, bits_big_endian);
}
break;
case DWARF_VALUE_MEMORY:
- source_offset_bits += p->offset;
- this_size = bits_to_bytes (source_offset_bits, this_size_bits);
+ bits_to_skip += p->offset;
+ this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.reserve (this_size);
read_value_memory (v, offset,
p->v.mem.in_stack_memory,
- p->v.mem.addr + source_offset_bits / 8,
+ p->v.mem.addr + bits_to_skip / 8,
buffer.data (), this_size);
- copy_bitwise (contents, dest_offset_bits,
- buffer.data (), source_offset_bits % 8,
+ copy_bitwise (contents, offset,
+ buffer.data (), bits_to_skip % 8,
this_size_bits, bits_big_endian);
break;
@@ -1880,14 +1870,13 @@ read_pieced_value (struct value *v)
/* Piece is anchored at least significant bit end. */
if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
- source_offset_bits += (stack_value_size_bits
- - p->offset - p->size);
+ bits_to_skip += stack_value_size_bits - p->offset - p->size;
else
- source_offset_bits += p->offset;
+ bits_to_skip += p->offset;
- copy_bitwise (contents, dest_offset_bits,
+ copy_bitwise (contents, offset,
value_contents_all (p->v.value),
- source_offset_bits,
+ bits_to_skip,
this_size_bits, bits_big_endian);
}
break;
@@ -1898,14 +1887,14 @@ read_pieced_value (struct value *v)
size_t n = this_size_bits;
/* Cut off at the end of the implicit value. */
- source_offset_bits += p->offset;
- if (source_offset_bits >= literal_size_bits)
+ bits_to_skip += p->offset;
+ if (bits_to_skip >= literal_size_bits)
break;
- if (n > literal_size_bits - source_offset_bits)
- n = literal_size_bits - source_offset_bits;
+ if (n > literal_size_bits - bits_to_skip)
+ n = literal_size_bits - bits_to_skip;
- copy_bitwise (contents, dest_offset_bits,
- p->v.literal.data, source_offset_bits,
+ copy_bitwise (contents, offset,
+ p->v.literal.data, bits_to_skip,
n, bits_big_endian);
}
break;
@@ -1924,6 +1913,7 @@ read_pieced_value (struct value *v)
}
offset += this_size_bits;
+ bits_to_skip = 0;
}
}
@@ -1959,23 +1949,16 @@ write_pieced_value (struct value *to, struct value *from)
else
max_offset = 8 * TYPE_LENGTH (value_type (to));
- for (i = 0; i < c->n_pieces && offset < max_offset; i++)
+ /* Advance to the first non-skipped piece. */
+ for (i = 0; i < c->n_pieces && bits_to_skip >= c->pieces[i].size; i++)
+ bits_to_skip -= c->pieces[i].size;
+
+ for (; i < c->n_pieces && offset < max_offset; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
size_t this_size_bits, this_size;
- long dest_offset_bits, source_offset_bits;
-
- this_size_bits = p->size;
- if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
- {
- bits_to_skip -= this_size_bits;
- continue;
- }
- dest_offset_bits = bits_to_skip;
- this_size_bits -= bits_to_skip;
- bits_to_skip = 0;
- source_offset_bits = offset;
+ this_size_bits = p->size - bits_to_skip;
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
@@ -1992,22 +1975,22 @@ write_pieced_value (struct value *to, struct value *from)
&& p->offset + p->size < reg_bits)
{
/* Big-endian, and we want less than full size. */
- dest_offset_bits += reg_bits - (p->offset + p->size);
+ bits_to_skip += reg_bits - (p->offset + p->size);
}
else
- dest_offset_bits += p->offset;
+ bits_to_skip += p->offset;
- this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
+ this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.reserve (this_size);
- if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0)
+ if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
{
/* Data is copied non-byte-aligned into the register.
Need some bits from original register value. */
int optim, unavail;
if (!get_frame_register_bytes (frame, gdb_regnum,
- dest_offset_bits / 8,
+ bits_to_skip / 8,
this_size, buffer.data (),
&optim, &unavail))
{
@@ -2024,34 +2007,34 @@ write_pieced_value (struct value *to, struct value *from)
}
}
- copy_bitwise (buffer.data (), dest_offset_bits % 8,
- contents, source_offset_bits,
+ copy_bitwise (buffer.data (), bits_to_skip % 8,
+ contents, offset,
this_size_bits, bits_big_endian);
put_frame_register_bytes (frame, gdb_regnum,
- dest_offset_bits / 8,
+ bits_to_skip / 8,
this_size, buffer.data ());
}
break;
case DWARF_VALUE_MEMORY:
{
- dest_offset_bits += p->offset;
+ bits_to_skip += p->offset;
- CORE_ADDR start_addr = p->v.mem.addr + dest_offset_bits / 8;
+ CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
- if (dest_offset_bits % 8 == 0 && this_size_bits % 8 == 0
- && source_offset_bits % 8 == 0)
+ if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
+ && offset % 8 == 0)
{
/* Everything is byte-aligned; no buffer needed. */
write_memory (start_addr,
- contents + source_offset_bits / 8,
+ contents + offset / 8,
this_size_bits / 8);
break;
}
- this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
+ this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.reserve (this_size);
- if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0)
+ if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
{
if (this_size <= 8)
{
@@ -2068,8 +2051,8 @@ write_pieced_value (struct value *to, struct value *from)
}
}
- copy_bitwise (buffer.data (), dest_offset_bits % 8,
- contents, source_offset_bits,
+ copy_bitwise (buffer.data (), bits_to_skip % 8,
+ contents, offset,
this_size_bits, bits_big_endian);
write_memory (start_addr, buffer.data (), this_size);
}
@@ -2079,6 +2062,7 @@ write_pieced_value (struct value *to, struct value *from)
break;
}
offset += this_size_bits;
+ bits_to_skip = 0;
}
}

View File

@ -0,0 +1,76 @@
commit 23f945bf8cebf348154aff43782de2e1977e9230
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:31 2017 +0200
Fix bit-/byte-offset mismatch in parameter to read_value_memory
The function read_value_memory accepts a parameter embedded_offset and
expects it to represent the byte offset into the given value. However,
the only invocation with a possibly non-zero embedded_offset happens in
read_pieced_value, where a bit offset is passed instead.
Adjust the implementation of read_value_memory to meet the caller's
expectation. This implicitly fixes the invocation in read_pieced_value.
gdb/ChangeLog:
* valops.c (read_value_memory): Change embedded_offset to
represent a bit offset instead of a byte offset.
* value.h (read_value_memory): Adjust comment.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * valops.c (read_value_memory): Change embedded_offset to
+ represent a bit offset instead of a byte offset.
+ * value.h (read_value_memory): Adjust comment.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (read_pieced_value): Remove unnecessary variables
dest_offset_bits and source_offset_bits.
(write_pieced_value): Likewise.
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -958,7 +958,7 @@ value_at_lazy (struct type *type, CORE_ADDR addr)
}
void
-read_value_memory (struct value *val, LONGEST embedded_offset,
+read_value_memory (struct value *val, LONGEST bit_offset,
int stack, CORE_ADDR memaddr,
gdb_byte *buffer, size_t length)
{
@@ -984,8 +984,9 @@ read_value_memory (struct value *val, LONGEST embedded_offset,
if (status == TARGET_XFER_OK)
/* nothing */;
else if (status == TARGET_XFER_UNAVAILABLE)
- mark_value_bytes_unavailable (val, embedded_offset + xfered_total,
- xfered_partial);
+ mark_value_bits_unavailable (val, (xfered_total * HOST_CHAR_BIT
+ + bit_offset),
+ xfered_partial * HOST_CHAR_BIT);
else if (status == TARGET_XFER_EOF)
memory_error (TARGET_XFER_E_IO, memaddr + xfered_total);
else
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -581,12 +581,11 @@ extern int value_contents_eq (const struct value *val1, LONGEST offset1,
/* Read LENGTH addressable memory units starting at MEMADDR into BUFFER,
which is (or will be copied to) VAL's contents buffer offset by
- EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).
- Marks value contents ranges as unavailable if the corresponding
- memory is likewise unavailable. STACK indicates whether the memory
- is known to be stack memory. */
+ BIT_OFFSET bits. Marks value contents ranges as unavailable if
+ the corresponding memory is likewise unavailable. STACK indicates
+ whether the memory is known to be stack memory. */
-extern void read_value_memory (struct value *val, LONGEST embedded_offset,
+extern void read_value_memory (struct value *val, LONGEST bit_offset,
int stack, CORE_ADDR memaddr,
gdb_byte *buffer, size_t length);

View File

@ -0,0 +1,56 @@
commit f65e204425b5b46a5927d9501c42f25d98a866ce
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:32 2017 +0200
write_pieced_value: Notify memory_changed observers
So far write_pieced_value uses write_memory when writing memory pieces to
the target. However, this is a case where GDB potentially overwrites a
watchpoint value. In such a case write_memory_with_notification should be
used instead, so that memory_changed observers get notified.
gdb/ChangeLog:
* dwarf2loc.c (write_pieced_value): When writing the data for a
memory piece, use write_memory_with_notification instead of
write_memory.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (write_pieced_value): When writing the data for a
+ memory piece, use write_memory_with_notification instead of
+ write_memory.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* valops.c (read_value_memory): Change embedded_offset to
represent a bit offset instead of a byte offset.
* value.h (read_value_memory): Adjust comment.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2025,9 +2025,9 @@ write_pieced_value (struct value *to, struct value *from)
&& offset % 8 == 0)
{
/* Everything is byte-aligned; no buffer needed. */
- write_memory (start_addr,
- contents + offset / 8,
- this_size_bits / 8);
+ write_memory_with_notification (start_addr,
+ contents + offset / 8,
+ this_size_bits / 8);
break;
}
@@ -2054,7 +2054,8 @@ write_pieced_value (struct value *to, struct value *from)
copy_bitwise (buffer.data (), bits_to_skip % 8,
contents, offset,
this_size_bits, bits_big_endian);
- write_memory (start_addr, buffer.data (), this_size);
+ write_memory_with_notification (start_addr, buffer.data (),
+ this_size);
}
break;
default:

View File

@ -0,0 +1,481 @@
commit 55acdf2242372ae52abb25c80db8e75df5578b23
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Tue Jun 13 15:20:32 2017 +0200
read/write_pieced_value: Merge into one function
Since read_pieced_value and write_pieced_value share significant logic,
this patch merges them into a single function rw_pieced_value.
gdb/ChangeLog:
* dwarf2loc.c (rw_pieced_value): New. Merge logic from...
(read_pieced_value, write_pieced_value): ...here. Reduce to
wrappers that just call rw_pieced_value.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,5 +1,11 @@
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+ * dwarf2loc.c (rw_pieced_value): New. Merge logic from...
+ (read_pieced_value, write_pieced_value): ...here. Reduce to
+ wrappers that just call rw_pieced_value.
+
+2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
* dwarf2loc.c (write_pieced_value): When writing the data for a
memory piece, use write_memory_with_notification instead of
write_memory.
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1761,31 +1761,55 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits)
return (start % 8 + n_bits + 7) / 8;
}
+/* Read or write a pieced value V. If FROM != NULL, operate in "write
+ mode": copy FROM into the pieces comprising V. If FROM == NULL,
+ operate in "read mode": fetch the contents of the (lazy) value V by
+ composing it from its pieces. */
+
static void
-read_pieced_value (struct value *v)
+rw_pieced_value (struct value *v, struct value *from)
{
int i;
LONGEST offset = 0, max_offset;
ULONGEST bits_to_skip;
- gdb_byte *contents;
+ gdb_byte *v_contents;
+ const gdb_byte *from_contents;
struct piece_closure *c
= (struct piece_closure *) value_computed_closure (v);
std::vector<gdb_byte> buffer;
int bits_big_endian
= gdbarch_bits_big_endian (get_type_arch (value_type (v)));
- if (value_type (v) != value_enclosing_type (v))
- internal_error (__FILE__, __LINE__,
- _("Should not be able to create a lazy value with "
- "an enclosing type"));
+ if (from != NULL)
+ {
+ from_contents = value_contents (from);
+ v_contents = NULL;
+ }
+ else
+ {
+ if (value_type (v) != value_enclosing_type (v))
+ internal_error (__FILE__, __LINE__,
+ _("Should not be able to create a lazy value with "
+ "an enclosing type"));
+ v_contents = value_contents_raw (v);
+ from_contents = NULL;
+ }
- contents = value_contents_raw (v);
bits_to_skip = 8 * value_offset (v);
if (value_bitsize (v))
{
bits_to_skip += (8 * value_offset (value_parent (v))
+ value_bitpos (v));
- max_offset = value_bitsize (v);
+ if (from != NULL
+ && (gdbarch_byte_order (get_type_arch (value_type (from)))
+ == BFD_ENDIAN_BIG))
+ {
+ /* Use the least significant bits of FROM. */
+ max_offset = 8 * TYPE_LENGTH (value_type (from));
+ offset = max_offset - value_bitsize (v);
+ }
+ else
+ max_offset = value_bitsize (v);
}
else
max_offset = 8 * TYPE_LENGTH (value_type (v));
@@ -1797,13 +1821,12 @@ read_pieced_value (struct value *v)
for (; i < c->n_pieces && offset < max_offset; i++)
{
struct dwarf_expr_piece *p = &c->pieces[i];
- size_t this_size, this_size_bits;
+ size_t this_size_bits, this_size;
this_size_bits = p->size - bits_to_skip;
if (this_size_bits > max_offset - offset)
this_size_bits = max_offset - offset;
- /* Copy from the source to DEST_BUFFER. */
switch (p->location)
{
case DWARF_VALUE_REGISTER:
@@ -1826,39 +1849,137 @@ read_pieced_value (struct value *v)
this_size = bits_to_bytes (bits_to_skip, this_size_bits);
buffer.reserve (this_size);
- if (!get_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- this_size, buffer.data (),
- &optim, &unavail))
+ if (from == NULL)
{
- if (optim)
- mark_value_bits_optimized_out (v, offset, this_size_bits);
- if (unavail)
- mark_value_bits_unavailable (v, offset, this_size_bits);
- break;
+ /* Read mode. */
+ if (!get_frame_register_bytes (frame, gdb_regnum,
+ bits_to_skip / 8,
+ this_size, buffer.data (),
+ &optim, &unavail))
+ {
+ if (optim)
+ mark_value_bits_optimized_out (v, offset,
+ this_size_bits);
+ if (unavail)
+ mark_value_bits_unavailable (v, offset,
+ this_size_bits);
+ break;
+ }
+
+ copy_bitwise (v_contents, offset,
+ buffer.data (), bits_to_skip % 8,
+ this_size_bits, bits_big_endian);
+ }
+ else
+ {
+ /* Write mode. */
+ if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
+ {
+ /* Data is copied non-byte-aligned into the register.
+ Need some bits from original register value. */
+ get_frame_register_bytes (frame, gdb_regnum,
+ bits_to_skip / 8,
+ this_size, buffer.data (),
+ &optim, &unavail);
+ if (optim)
+ throw_error (OPTIMIZED_OUT_ERROR,
+ _("Can't do read-modify-write to "
+ "update bitfield; containing word "
+ "has been optimized out"));
+ if (unavail)
+ throw_error (NOT_AVAILABLE_ERROR,
+ _("Can't do read-modify-write to "
+ "update bitfield; containing word "
+ "is unavailable"));
+ }
+
+ copy_bitwise (buffer.data (), bits_to_skip % 8,
+ from_contents, offset,
+ this_size_bits, bits_big_endian);
+ put_frame_register_bytes (frame, gdb_regnum,
+ bits_to_skip / 8,
+ this_size, buffer.data ());
}
- copy_bitwise (contents, offset,
- buffer.data (), bits_to_skip % 8,
- this_size_bits, bits_big_endian);
}
break;
case DWARF_VALUE_MEMORY:
- bits_to_skip += p->offset;
- this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.reserve (this_size);
-
- read_value_memory (v, offset,
- p->v.mem.in_stack_memory,
- p->v.mem.addr + bits_to_skip / 8,
- buffer.data (), this_size);
- copy_bitwise (contents, offset,
- buffer.data (), bits_to_skip % 8,
- this_size_bits, bits_big_endian);
+ {
+ bits_to_skip += p->offset;
+
+ CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
+
+ if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
+ && offset % 8 == 0)
+ {
+ /* Everything is byte-aligned; no buffer needed. */
+ if (from != NULL)
+ write_memory_with_notification (start_addr,
+ (from_contents
+ + offset / 8),
+ this_size_bits / 8);
+ else
+ read_value_memory (v, offset,
+ p->v.mem.in_stack_memory,
+ p->v.mem.addr + bits_to_skip / 8,
+ v_contents + offset / 8,
+ this_size_bits / 8);
+ break;
+ }
+
+ this_size = bits_to_bytes (bits_to_skip, this_size_bits);
+ buffer.reserve (this_size);
+
+ if (from == NULL)
+ {
+ /* Read mode. */
+ read_value_memory (v, offset,
+ p->v.mem.in_stack_memory,
+ p->v.mem.addr + bits_to_skip / 8,
+ buffer.data (), this_size);
+ copy_bitwise (v_contents, offset,
+ buffer.data (), bits_to_skip % 8,
+ this_size_bits, bits_big_endian);
+ }
+ else
+ {
+ /* Write mode. */
+ if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
+ {
+ if (this_size <= 8)
+ {
+ /* Perform a single read for small sizes. */
+ read_memory (start_addr, buffer.data (),
+ this_size);
+ }
+ else
+ {
+ /* Only the first and last bytes can possibly have
+ any bits reused. */
+ read_memory (start_addr, buffer.data (), 1);
+ read_memory (start_addr + this_size - 1,
+ &buffer[this_size - 1], 1);
+ }
+ }
+
+ copy_bitwise (buffer.data (), bits_to_skip % 8,
+ from_contents, offset,
+ this_size_bits, bits_big_endian);
+ write_memory_with_notification (start_addr,
+ buffer.data (),
+ this_size);
+ }
+ }
break;
case DWARF_VALUE_STACK:
{
+ if (from != NULL)
+ {
+ mark_value_bits_optimized_out (v, offset, this_size_bits);
+ break;
+ }
+
struct objfile *objfile = dwarf2_per_cu_objfile (c->per_cu);
struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
ULONGEST stack_value_size_bits
@@ -1874,7 +1995,7 @@ read_pieced_value (struct value *v)
else
bits_to_skip += p->offset;
- copy_bitwise (contents, offset,
+ copy_bitwise (v_contents, offset,
value_contents_all (p->v.value),
bits_to_skip,
this_size_bits, bits_big_endian);
@@ -1883,6 +2004,12 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_LITERAL:
{
+ if (from != NULL)
+ {
+ mark_value_bits_optimized_out (v, offset, this_size_bits);
+ break;
+ }
+
ULONGEST literal_size_bits = 8 * p->v.literal.length;
size_t n = this_size_bits;
@@ -1893,15 +2020,21 @@ read_pieced_value (struct value *v)
if (n > literal_size_bits - bits_to_skip)
n = literal_size_bits - bits_to_skip;
- copy_bitwise (contents, offset,
+ copy_bitwise (v_contents, offset,
p->v.literal.data, bits_to_skip,
n, bits_big_endian);
}
break;
- /* These bits show up as zeros -- but do not cause the value
- to be considered optimized-out. */
case DWARF_VALUE_IMPLICIT_POINTER:
+ if (from != NULL)
+ {
+ mark_value_bits_optimized_out (v, offset, this_size_bits);
+ break;
+ }
+
+ /* These bits show up as zeros -- but do not cause the value to
+ be considered optimized-out. */
break;
case DWARF_VALUE_OPTIMIZED_OUT:
@@ -1917,154 +2050,17 @@ read_pieced_value (struct value *v)
}
}
+
static void
-write_pieced_value (struct value *to, struct value *from)
+read_pieced_value (struct value *v)
{
- int i;
- ULONGEST bits_to_skip;
- LONGEST offset = 0, max_offset;
- const gdb_byte *contents;
- struct piece_closure *c
- = (struct piece_closure *) value_computed_closure (to);
- std::vector<gdb_byte> buffer;
- int bits_big_endian
- = gdbarch_bits_big_endian (get_type_arch (value_type (to)));
-
- contents = value_contents (from);
- bits_to_skip = 8 * value_offset (to);
- if (value_bitsize (to))
- {
- bits_to_skip += (8 * value_offset (value_parent (to))
- + value_bitpos (to));
- /* Use the least significant bits of FROM. */
- if (gdbarch_byte_order (get_type_arch (value_type (from)))
- == BFD_ENDIAN_BIG)
- {
- max_offset = 8 * TYPE_LENGTH (value_type (from));
- offset = max_offset - value_bitsize (to);
- }
- else
- max_offset = value_bitsize (to);
- }
- else
- max_offset = 8 * TYPE_LENGTH (value_type (to));
-
- /* Advance to the first non-skipped piece. */
- for (i = 0; i < c->n_pieces && bits_to_skip >= c->pieces[i].size; i++)
- bits_to_skip -= c->pieces[i].size;
-
- for (; i < c->n_pieces && offset < max_offset; i++)
- {
- struct dwarf_expr_piece *p = &c->pieces[i];
- size_t this_size_bits, this_size;
-
- this_size_bits = p->size - bits_to_skip;
- if (this_size_bits > max_offset - offset)
- this_size_bits = max_offset - offset;
-
- switch (p->location)
- {
- case DWARF_VALUE_REGISTER:
- {
- struct frame_info *frame = frame_find_by_id (c->frame_id);
- struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, p->v.regno);
- ULONGEST reg_bits = 8 * register_size (arch, gdb_regnum);
-
- if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
- && p->offset + p->size < reg_bits)
- {
- /* Big-endian, and we want less than full size. */
- bits_to_skip += reg_bits - (p->offset + p->size);
- }
- else
- bits_to_skip += p->offset;
-
- this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.reserve (this_size);
-
- if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
- {
- /* Data is copied non-byte-aligned into the register.
- Need some bits from original register value. */
- int optim, unavail;
-
- if (!get_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- this_size, buffer.data (),
- &optim, &unavail))
- {
- if (optim)
- throw_error (OPTIMIZED_OUT_ERROR,
- _("Can't do read-modify-write to "
- "update bitfield; containing word "
- "has been optimized out"));
- if (unavail)
- throw_error (NOT_AVAILABLE_ERROR,
- _("Can't do read-modify-write to update "
- "bitfield; containing word "
- "is unavailable"));
- }
- }
-
- copy_bitwise (buffer.data (), bits_to_skip % 8,
- contents, offset,
- this_size_bits, bits_big_endian);
- put_frame_register_bytes (frame, gdb_regnum,
- bits_to_skip / 8,
- this_size, buffer.data ());
- }
- break;
- case DWARF_VALUE_MEMORY:
- {
- bits_to_skip += p->offset;
-
- CORE_ADDR start_addr = p->v.mem.addr + bits_to_skip / 8;
-
- if (bits_to_skip % 8 == 0 && this_size_bits % 8 == 0
- && offset % 8 == 0)
- {
- /* Everything is byte-aligned; no buffer needed. */
- write_memory_with_notification (start_addr,
- contents + offset / 8,
- this_size_bits / 8);
- break;
- }
-
- this_size = bits_to_bytes (bits_to_skip, this_size_bits);
- buffer.reserve (this_size);
-
- if (bits_to_skip % 8 != 0 || this_size_bits % 8 != 0)
- {
- if (this_size <= 8)
- {
- /* Perform a single read for small sizes. */
- read_memory (start_addr, buffer.data (), this_size);
- }
- else
- {
- /* Only the first and last bytes can possibly have any
- bits reused. */
- read_memory (start_addr, buffer.data (), 1);
- read_memory (start_addr + this_size - 1,
- &buffer[this_size - 1], 1);
- }
- }
+ rw_pieced_value (v, NULL);
+}
- copy_bitwise (buffer.data (), bits_to_skip % 8,
- contents, offset,
- this_size_bits, bits_big_endian);
- write_memory_with_notification (start_addr, buffer.data (),
- this_size);
- }
- break;
- default:
- mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to)));
- break;
- }
- offset += this_size_bits;
- bits_to_skip = 0;
- }
+static void
+write_pieced_value (struct value *to, struct value *from)
+{
+ rw_pieced_value (to, from);
}
/* An implementation of an lval_funcs method to see whether a value is

View File

@ -0,0 +1,60 @@
commit 5524b5250e319f41933605420e9526fb74cfb9ae
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Wed Jun 14 14:24:03 2017 +0200
Fix register selection in var-access.exp
The new test var-access.exp causes FAILs on i686. This is because the
test chooses the wrong name for DWARF register number 1: It uses
"edx" (which corresponds to DWARF register number 2), but should have used
"ecx" instead.
Also, the current logic in var-access.exp does not correctly distinguish
between a 64-bit and a 32-bit program on an x86-64 target. It uses the
64-bit register names for both.
These problems are fixed. In order to address the latter, the convenience
macros is_*_target are exploited where appropriate.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/var-access.exp: Use register name ecx instead of edx
on 32-bit x86 targets. Exploit is_*_target macros where
appropriate.
### a/gdb/testsuite/ChangeLog
### b/gdb/testsuite/ChangeLog
## -1,3 +1,9 @@
+2017-06-14 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * gdb.dwarf2/var-access.exp: Use register name ecx instead of edx
+ on 32-bit x86 targets. Exploit is_*_target macros where
+ appropriate.
+
2017-06-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.dwarf2/var-access.exp: Add test for non-byte-aligned
--- a/gdb/testsuite/gdb.dwarf2/var-access.exp
+++ b/gdb/testsuite/gdb.dwarf2/var-access.exp
@@ -28,16 +28,16 @@ if {![dwarf2_support]} {
set dwarf_regnum {0 1}
-if { [istarget "aarch64*-*-*"] } {
+if { [is_aarch64_target] } {
set regname {x0 x1}
-} elseif { [istarget "arm*-*-*"]
+} elseif { [is_aarch32_target]
|| [istarget "s390*-*-*" ]
|| [istarget "powerpc*-*-*"]
|| [istarget "rs6000*-*-aix*"] } {
set regname {r0 r1}
-} elseif { [istarget "i?86-*-*"] } {
- set regname {eax edx}
-} elseif { [istarget "x86_64-*-*"] } {
+} elseif { [is_x86_like_target] } {
+ set regname {eax ecx}
+} elseif { [is_amd64_regs_target] } {
set regname {rax rdx}
} else {
verbose "Skipping tests for accessing DWARF-described variables."

View File

@ -0,0 +1,197 @@
commit b4cbbe8f7294070cc93a71ace78f134965ddad82
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Thu Jun 8 17:24:50 2017 +0200
S/390: Add support for pgste marker
This patch adds a new S/390 specific segment type: PT_S390_PGSTE. For
binaries marked with that segment the kernel will allocate 4k page
tables. The only user so far will be qemu.
ld/ChangeLog:
2017-06-23 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* Makefile.in: Add s390.em as build dependency.
* emulparams/elf64_s390.sh (EXTRA_EM_FILE): Add s390.em.
* emultempl/s390.em: New file.
* gen-doc.texi: Add documentation for --s390-pgste option.
* ld.texinfo: Likewise.
include/ChangeLog:
2017-06-23 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf/s390.h (PT_S390_PGSTE): Define macro.
binutils/ChangeLog:
2017-06-23 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* readelf.c (get_s390_segment_type): Add support for the new
segment type PT_S390_PGSTE.
(get_segment_type): Call get_s390_segment_type.
elfcpp/ChangeLog:
2017-06-23 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elfcpp.h (enum PT): Add PT_S390_PGSTE to enum.
bfd/ChangeLog:
2017-06-23 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf-s390.h: New file.
* elf64-s390.c (struct elf_s390_link_hash_table): Add params
field.
(elf_s390_additional_program_headers): New function.
(elf_s390_modify_segment_map): New function.
(bfd_elf_s390_set_options): New function.
(elf_backend_additional_program_headers)
(elf_backend_modify_segment_map): Add macro definitions.
--- /dev/null
+++ b/bfd/elf-s390.h
@@ -0,0 +1,29 @@
+/* S/390-specific support for ELF.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+ This file is part of BFD, the Binary File Descriptor library.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Used to pass info between ld and bfd. */
+struct s390_elf_params
+{
+ /* Tell the kernel to allocate 4k page tables. */
+ int pgste;
+};
+
+bfd_boolean bfd_elf_s390_set_options (struct bfd_link_info *info,
+ struct s390_elf_params *params);
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -25,6 +25,7 @@
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/s390.h"
+#include "elf-s390.h"
#include <stdarg.h>
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
@@ -660,6 +661,9 @@ struct elf_s390_link_hash_table
/* Small local sym cache. */
struct sym_cache sym_cache;
+
+ /* Options passed from the linker. */
+ struct s390_elf_params *params;
};
/* Get the s390 ELF linker hash table from a link_info structure. */
@@ -3966,6 +3970,70 @@ elf64_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
return elf_s390_merge_obj_attributes (ibfd, info);
}
+/* We may add a PT_S390_PGSTE program header. */
+
+static int
+elf_s390_additional_program_headers (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ htab = elf_s390_hash_table (info);
+ return htab->params->pgste;
+}
+
+
+/* Add the PT_S390_PGSTE program header. */
+
+static bfd_boolean
+elf_s390_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info)
+{
+ struct elf_s390_link_hash_table *htab;
+ struct elf_segment_map *m, *pm = NULL;
+
+ htab = elf_s390_hash_table (info);
+ if (!htab->params->pgste)
+ return TRUE;
+
+ /* If there is already a PT_S390_PGSTE header, avoid adding
+ another. */
+ m = elf_seg_map (abfd);
+ while (m && m->p_type != PT_S390_PGSTE)
+ {
+ pm = m;
+ m = m->next;
+ }
+
+ if (m)
+ return TRUE;
+
+ m = (struct elf_segment_map *)
+ bfd_zalloc (abfd, sizeof (struct elf_segment_map));
+ if (m == NULL)
+ return FALSE;
+ m->p_type = PT_S390_PGSTE;
+ m->count = 0;
+ m->next = NULL;
+ if (pm)
+ pm->next = m;
+
+ return TRUE;
+}
+
+bfd_boolean
+bfd_elf_s390_set_options (struct bfd_link_info *info,
+ struct s390_elf_params *params)
+{
+ struct elf_s390_link_hash_table *htab;
+
+ htab = elf_s390_hash_table (info);
+ htab->params = params;
+
+ return TRUE;
+}
+
+
/* Why was the hash table entry size definition changed from
ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
this is the only reason for the s390_elf64_size_info structure. */
@@ -4046,6 +4114,8 @@ const struct elf_size_info s390_elf64_size_info =
#define elf_backend_plt_sym_val elf_s390_plt_sym_val
#define elf_backend_add_symbol_hook elf_s390_add_symbol_hook
#define elf_backend_sort_relocs_p elf_s390_elf_sort_relocs_p
+#define elf_backend_additional_program_headers elf_s390_additional_program_headers
+#define elf_backend_modify_segment_map elf_s390_modify_segment_map
#define bfd_elf64_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
--- a/include/elf/s390.h
+++ b/include/elf/s390.h
@@ -37,6 +37,9 @@
#define EF_S390_HIGH_GPRS 0x00000001
+/* Request 4k page table size. */
+#define PT_S390_PGSTE (PT_LOPROC + 0)
+
/* Relocation types. */
START_RELOC_NUMBERS (elf_s390_reloc_type)

View File

@ -0,0 +1,85 @@
commit 93ec5e23766a9f75aa4950748cf73964028a8d1b
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Mon Jun 26 11:01:58 2017 +0200
S/390: Fix testsuite segfault added with recent pgste patch.
The recent pgste patch caused several testcases to fail with a
segfault. Fixed with this patch by adding NULL pointer checks.
regression-tested on s390x.
bfd/ChangeLog:
2017-06-26 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf64-s390.c (elf_s390_additional_program_headers): Add NULL
pointer checks.
(elf_s390_modify_segment_map): Likewise.
(bfd_elf_s390_set_options): Lisewise.
### a/bfd/ChangeLog
### b/bfd/ChangeLog
## -1,3 +1,10 @@
+2017-06-26 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * elf64-s390.c (elf_s390_additional_program_headers): Add NULL
+ pointer checks.
+ (elf_s390_modify_segment_map): Likewise.
+ (bfd_elf_s390_set_options): Lisewise.
+
2017-06-26 Alan Modra <amodra@gmail.com>
* elflink.c (_bfd_elf_link_create_dynstrtab): Don't make dynobj
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -3978,22 +3978,29 @@ elf_s390_additional_program_headers (bfd *abfd ATTRIBUTE_UNUSED,
{
struct elf_s390_link_hash_table *htab;
- htab = elf_s390_hash_table (info);
- return htab->params->pgste;
+ if (info)
+ {
+ htab = elf_s390_hash_table (info);
+ if (htab)
+ return htab->params->pgste;
+ }
+ return 0;
}
/* Add the PT_S390_PGSTE program header. */
static bfd_boolean
-elf_s390_modify_segment_map (bfd *abfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info)
+elf_s390_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
{
struct elf_s390_link_hash_table *htab;
struct elf_segment_map *m, *pm = NULL;
+ if (!abfd || !info)
+ return TRUE;
+
htab = elf_s390_hash_table (info);
- if (!htab->params->pgste)
+ if (!htab || !htab->params->pgste)
return TRUE;
/* If there is already a PT_S390_PGSTE header, avoid adding
@@ -4027,8 +4034,12 @@ bfd_elf_s390_set_options (struct bfd_link_info *info,
{
struct elf_s390_link_hash_table *htab;
- htab = elf_s390_hash_table (info);
- htab->params = params;
+ if (info)
+ {
+ htab = elf_s390_hash_table (info);
+ if (htab)
+ htab->params = params;
+ }
return TRUE;
}

View File

@ -0,0 +1,169 @@
commit 88ab90e860a46a1123fcfd13bfe51cd360e9c3f7
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Thu Jun 29 10:30:09 2017 +0200
S390: Support guarded-storage core note sections
Newer Linux kernel versions offer two new register sets in support of the
z/Architecture's guarded storage facility: NT_S390_GS_CB, the
"guarded-storage registers", and NT_S390_GS_BC, the "guarded-storage
broadcast control block". This patch adds support for the respective core
notes sections to binutils.
bfd/ChangeLog:
* elf-bfd.h (elfcore_write_s390_gs_cb): Add prototype.
(elfcore_write_s390_gs_bc): Likewise.
* elf.c (elfcore_grok_s390_gs_cb): New function.
(elfcore_grok_s390_gs_bc): New function.
(elfcore_grok_note): Call them.
(elfcore_write_s390_gs_cb): New function.
(elfcore_write_s390_gs_bc): New function.
(elfcore_write_register_note): Call them.
binutils/ChangeLog:
* readelf.c (get_note_type): Add NT_S390_GS_CB and NT_S390_GS_BC.
include/ChangeLog:
* elf/common.h (NT_S390_GS_CB): New macro.
(NT_S390_GS_BC): Likewise.
### a/bfd/ChangeLog
### b/bfd/ChangeLog
## -1,3 +1,14 @@
+2017-06-29 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * elf-bfd.h (elfcore_write_s390_gs_cb): Add prototype.
+ (elfcore_write_s390_gs_bc): Likewise.
+ * elf.c (elfcore_grok_s390_gs_cb): New function.
+ (elfcore_grok_s390_gs_bc): New function.
+ (elfcore_grok_note): Call them.
+ (elfcore_write_s390_gs_cb): New function.
+ (elfcore_write_s390_gs_bc): New function.
+ (elfcore_write_register_note): Call them.
+
2017-06-28 H.J. Lu <hongjiu.lu@intel.com>
* libbfd.c (_bfd_generic_get_section_contents): Don't call
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2533,6 +2533,10 @@ extern char *elfcore_write_s390_vxrs_low
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_s390_vxrs_high
(bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_gs_cb
+ (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_gs_bc
+ (bfd *, char *, int *, const void *, int);
extern char *elfcore_write_arm_vfp
(bfd *, char *, int *, const void *, int);
extern char *elfcore_write_aarch_tls
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9191,6 +9191,18 @@ elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note)
}
static bfd_boolean
+elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-cb", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-bc", note);
+}
+
+static bfd_boolean
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
{
return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
@@ -9668,6 +9680,20 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
else
return TRUE;
+ case NT_S390_GS_CB:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_gs_bc (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_GS_BC:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_gs_cb (abfd, note);
+ else
+ return TRUE;
+
case NT_ARM_VFP:
if (note->namesz == 6
&& strcmp (note->namedata, "LINUX") == 0)
@@ -10728,6 +10754,32 @@ elfcore_write_s390_vxrs_high (bfd *abfd,
}
char *
+elfcore_write_s390_gs_cb (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_gs_cb,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_GS_CB,
+ s390_gs_cb, size);
+}
+
+char *
+elfcore_write_s390_gs_bc (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_gs_bc,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_GS_BC,
+ s390_gs_bc, size);
+}
+
+char *
elfcore_write_arm_vfp (bfd *abfd,
char *buf,
int *bufsiz,
@@ -10815,6 +10867,10 @@ elfcore_write_register_note (bfd *abfd,
return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-s390-vxrs-high") == 0)
return elfcore_write_s390_vxrs_high (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-gs-cb") == 0)
+ return elfcore_write_s390_gs_cb (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-gs-bc") == 0)
+ return elfcore_write_s390_gs_bc (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-arm-vfp") == 0)
return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-aarch-tls") == 0)
### a/include/ChangeLog
### b/include/ChangeLog
## -1,3 +1,8 @@
+2017-06-29 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * elf/common.h (NT_S390_GS_CB): New macro.
+ (NT_S390_GS_BC): Likewise.
+
2017-06-28 Tamar Christina <tamar.christina@arm.com>
* opcode/aarch64.h: (AARCH64_FEATURE_DOTPROD): New.
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -598,6 +598,10 @@
/* note name must be "LINUX". */
#define NT_S390_VXRS_HIGH 0x30a /* S390 vector registers 16-31 */
/* note name must be "LINUX". */
+#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers */
+ /* note name must be "LINUX". */
+#define NT_S390_GS_BC 0x30c /* s390 guarded storage broadcast control block */
+ /* note name must be "LINUX". */
#define NT_ARM_VFP 0x400 /* ARM VFP registers */
/* The following definitions should really use NT_AARCH_..., but defined
this way for compatibility with Linux. */

View File

@ -0,0 +1,380 @@
commit 55efceabc6149e96134c10676adb2b1e79e0ae13
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date: Thu Jul 13 20:17:03 2017 +0200
S390: Add record/replay support for arch12 instructions
Support record/replay of the z/Architecture instructions that were
introduced with arch12.
gdb/ChangeLog:
* s390-linux-tdep.c (s390_process_record): Add support for
instructions new in arch12.
### a/gdb/ChangeLog
### b/gdb/ChangeLog
## -1,3 +1,8 @@
+2017-07-13 Andreas Arnez <arnez@linux.vnet.ibm.com>
+
+ * s390-linux-tdep.c (s390_process_record): Add support for
+ instructions new in arch12.
+
2017-07-11 John Baldwin <jhb@FreeBSD.org>
* amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers): Use
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -4992,6 +4992,8 @@ ex:
case 0xb9e9: /* SGRK - subtract */
case 0xb9ea: /* ALGRK - add logical */
case 0xb9eb: /* SLGRK - subtract logical */
+ case 0xb9ed: /* MSGRKC - multiply single 64x64 -> 64 */
+ case 0xb9fd: /* MSRKC - multiply single 32x32 -> 32 */
/* 64-bit gpr destination + flags */
if (s390_record_gpr_g (gdbarch, regcache, inib[6]))
return -1;
@@ -5019,7 +5021,7 @@ ex:
case 0xb914: /* LGFR - load */
case 0xb916: /* LLGFR - load logical */
case 0xb917: /* LLGTR - load logical thirty one bits */
- case 0xb91c: /* MSGFR - load */
+ case 0xb91c: /* MSGFR - multiply single 64<32 */
case 0xb946: /* BCTGR - branch on count */
case 0xb984: /* LLGCR - load logical character */
case 0xb985: /* LLGHR - load logical halfword */
@@ -5038,6 +5040,7 @@ ex:
case 0xb91d: /* DSGFR - divide single */
case 0xb986: /* MLGR - multiply logical */
case 0xb987: /* DLGR - divide logical */
+ case 0xb9ec: /* MGRK - multiply 64x64 -> 128 */
/* 64-bit gpr pair destination */
if (s390_record_gpr_g (gdbarch, regcache, inib[6]))
return -1;
@@ -5106,8 +5109,8 @@ ex:
/* 0xb922-0xb924 undefined */
/* 0xb925 privileged */
/* 0xb928 privileged */
- /* 0xb929 undefined */
+ case 0xb929: /* KMA - cipher message with authentication */
case 0xb92a: /* KMF - cipher message with cipher feedback [partial] */
case 0xb92b: /* KMO - cipher message with output feedback [partial] */
case 0xb92f: /* KMC - cipher message with chaining [partial] */
@@ -5170,6 +5173,15 @@ ex:
if (record_full_arch_list_add_reg (regcache, S390_R0_REGNUM + (inib[7] | 1)))
return -1;
}
+ if (tmp != 0 && insn[0] == 0xb929)
+ {
+ if (record_full_arch_list_add_reg (regcache,
+ S390_R0_REGNUM + inib[4]))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache,
+ S390_R0_REGNUM + (inib[4] | 1)))
+ return -1;
+ }
if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
return -1;
break;
@@ -5571,10 +5583,11 @@ ex:
/* 0xb9e3 undefined */
/* 0xb9e5 undefined */
- /* 0xb9ec-0xb9f1 undefined */
+ /* 0xb9ee-0xb9f1 undefined */
/* 0xb9f3 undefined */
/* 0xb9f5 undefined */
- /* 0xb9fc-0xb9ff undefined */
+ /* 0xb9fc undefined */
+ /* 0xb9fe -0xb9ff undefined */
default:
goto UNKNOWN_OP;
@@ -5962,6 +5975,7 @@ ex:
break;
case 0xe3:
+ case 0xe6:
case 0xe7:
case 0xeb:
case 0xed:
@@ -6006,6 +6020,7 @@ ex:
case 0xe31c: /* MSGF - multiply single */
case 0xe32a: /* LZRG - load and zero rightmost byte */
case 0xe33a: /* LLZRGF - load logical and zero rightmost byte */
+ case 0xe33c: /* MGH - multiply halfword 64x16mem -> 64 */
case 0xe346: /* BCTG - branch on count */
case 0xe377: /* LGB - load byte */
case 0xe390: /* LLGC - load logical character */
@@ -6036,6 +6051,7 @@ ex:
case 0xe30d: /* DSG - divide single */
case 0xe31d: /* DSGF - divide single */
+ case 0xe384: /* MG - multiply 64x64mem -> 128 */
case 0xe386: /* MLG - multiply logical */
case 0xe387: /* DLG - divide logical */
case 0xe38f: /* LPQ - load pair from quadword */
@@ -6057,6 +6073,9 @@ ex:
/* 0xe310-0xe311 undefined */
case 0xe312: /* LT - load and test */
+ case 0xe338: /* AGH - add halfword to 64 bit value */
+ case 0xe339: /* SGH - subtract halfword from 64 bit value */
+ case 0xe353: /* MSC - multiply single 32x32mem -> 32 */
case 0xe354: /* NY - and */
case 0xe356: /* OY - or */
case 0xe357: /* XY - xor */
@@ -6066,13 +6085,14 @@ ex:
case 0xe35f: /* SLY - subtract logical */
case 0xe37a: /* AHY - add halfword */
case 0xe37b: /* SHY - subtract halfword */
+ case 0xe383: /* MSGC - multiply single 64x64mem -> 64 */
case 0xe398: /* ALC - add logical with carry */
case 0xe399: /* SLB - subtract logical with borrow */
case 0xe727: /* LCBB - load count to block bounduary */
case 0xeb81: /* ICMY - insert characters under mask */
case 0xebdc: /* SRAK - shift left single */
case 0xebdd: /* SLAK - shift left single */
- /* 32-bit gpr destination + flags */
+ /* 32/64-bit gpr destination + flags */
if (record_full_arch_list_add_reg (regcache, S390_R0_REGNUM + inib[2]))
return -1;
if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
@@ -6160,7 +6180,7 @@ ex:
case 0xe336: /* PFD - prefetch data */
break;
- /* 0xe337-0xe339 undefined */
+ /* 0xe337 undefined */
/* 0xe33c-0xe33d undefined */
case 0xe33e: /* STRV - store reversed */
@@ -6183,8 +6203,12 @@ ex:
break;
/* 0xe340-0xe345 undefined */
- /* 0xe347-0xe34f undefined */
- /* 0xe352-0xe353 undefined */
+
+ case 0xe347: /* BIC - branch indirect on condition */
+ break;
+
+ /* 0xe348-0xe34f undefined */
+ /* 0xe352 undefined */
case 0xe35c: /* MFY - multiply */
case 0xe396: /* ML - multiply logical */
@@ -6216,11 +6240,12 @@ ex:
break;
/* 0xe37d-0xe37f undefined */
- /* 0xe383-0xe384 undefined */
case 0xe385: /* LGAT - load and trap */
case 0xe39c: /* LLGTAT - load logical thirty one bits and trap */
case 0xe39d: /* LLGFAT - load logical and trap */
+ case 0xe650: /* VCVB - vector convert to binary 32 bit*/
+ case 0xe652: /* VCVBG - vector convert to binary 64 bit*/
case 0xe721: /* VLGV - vector load gr from vr element */
/* 64-bit gpr destination + fpc for possible DXC write */
if (s390_record_gpr_g (gdbarch, regcache, inib[2]))
@@ -6271,6 +6296,10 @@ ex:
/* 0xe3ce undefined */
/* 0xe3d0-0xe3ff undefined */
+ case 0xe634: /* VPKZ - vector pack zoned */
+ case 0xe635: /* VLRL - vector load rightmost with immed. length */
+ case 0xe637: /* VLRLR - vector load rightmost with length */
+ case 0xe649: /* VLIP - vector load immediate decimal */
case 0xe700: /* VLEB - vector load element */
case 0xe701: /* VLEH - vector load element */
case 0xe702: /* VLEG - vector load element */
@@ -6311,7 +6340,10 @@ ex:
case 0xe769: /* VNC - vector and with complement */
case 0xe76a: /* VO - vector or */
case 0xe76b: /* VNO - vector nor */
+ case 0xe76c: /* VNX - vector not exclusive or */
case 0xe76d: /* VX - vector xor */
+ case 0xe76e: /* VNN - vector nand */
+ case 0xe76f: /* VOC - vector or with complement */
case 0xe770: /* VESLV - vector element shift left */
case 0xe772: /* VERIM - vector element rotate and insert under mask */
case 0xe773: /* VERLLV - vector element rotate left logical */
@@ -6325,11 +6357,14 @@ ex:
case 0xe77e: /* VSRA - vector shift right arithmetic */
case 0xe77f: /* VSRAB - vector shift right arithmetic by byte */
case 0xe784: /* VPDI - vector permute doubleword immediate */
+ case 0xe785: /* VBPERM - vector bit permute */
case 0xe78c: /* VPERM - vector permute */
case 0xe78d: /* VSEL - vector select */
case 0xe78e: /* VFMS - vector fp multiply and subtract */
case 0xe78f: /* VFMA - vector fp multiply and add */
case 0xe794: /* VPK - vector pack */
+ case 0xe79e: /* VFNMS - vector fp negative multiply and subtract */
+ case 0xe79f: /* VFNMA - vector fp negative multiply and add */
case 0xe7a1: /* VMLH - vector multiply logical high */
case 0xe7a2: /* VML - vector multiply low */
case 0xe7a3: /* VMH - vector multiply high */
@@ -6345,6 +6380,7 @@ ex:
case 0xe7ae: /* VMAE - vector multiply and add even */
case 0xe7af: /* VMAO - vector multiply and add odd */
case 0xe7b4: /* VGFM - vector Galois field multiply sum */
+ case 0xe7b8: /* VMSL - vector multiply sum logical */
case 0xe7b9: /* VACCC - vector add with carry compute carry */
case 0xe7bb: /* VAC - vector add with carry */
case 0xe7bc: /* VGFMA - vector Galois field multiply sum and accumulate */
@@ -6354,8 +6390,8 @@ ex:
case 0xe7c1: /* VCDLG - vector convert from logical 64-bit */
case 0xe7c2: /* VCGD - vector convert to fixed 64-bit */
case 0xe7c3: /* VCDG - vector convert from fixed 64-bit */
- case 0xe7c4: /* VLDE - vector fp load lengthened */
- case 0xe7c5: /* VLED - vector fp load rounded */
+ case 0xe7c4: /* VLDE/VFLL - vector fp load lengthened */
+ case 0xe7c5: /* VLED/VFLR - vector fp load rounded */
case 0xe7c7: /* VFI - vector load fp integer */
case 0xe7cc: /* VFPSO - vector fp perform sign operation */
case 0xe7ce: /* VFSQ - vector fp square root */
@@ -6369,6 +6405,8 @@ ex:
case 0xe7e3: /* VFA - vector fp add */
case 0xe7e5: /* VFD - vector fp divide */
case 0xe7e7: /* VFM - vector fp multiply */
+ case 0xe7ee: /* VFMIN - vector fp minimum */
+ case 0xe7ef: /* VFMAX - vector fp maximum */
case 0xe7f0: /* VAVGL - vector average logical */
case 0xe7f1: /* VACC - vector add and compute carry */
case 0xe7f2: /* VAVG - vector average */
@@ -6386,6 +6424,14 @@ ex:
return -1;
break;
+ case 0xe63d: /* VSTRL - vector store rightmost with immed. length */
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0);
+ if (record_full_arch_list_add_mem (oaddr, inib[3] + 1))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM))
+ return -1;
+ break;
+
case 0xe708: /* VSTEB - vector store element */
oaddr = s390_record_calc_disp (gdbarch, regcache, inib[3], insn[1], 0);
if (record_full_arch_list_add_mem (oaddr, 1))
@@ -6480,13 +6526,22 @@ ex:
return -1;
break;
+ case 0xe63c: /* VUPKZ - vector unpack zoned */
+ oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0);
+ if (record_full_arch_list_add_mem (oaddr, (ibyte[1] + 1) & 31))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
+ return -1;
+ break;
+
+ case 0xe63f: /* VSTRLR - vector store rightmost with length */
case 0xe73f: /* VSTL - vector store with length */
oaddr = s390_record_calc_disp (gdbarch, regcache, 0, insn[1], 0);
regcache_raw_read_unsigned (regcache, S390_R0_REGNUM + inib[3], &tmp);
tmp &= 0xffffffffu;
- if (tmp > 16)
- tmp = 16;
- if (record_full_arch_list_add_mem (oaddr, tmp))
+ if (tmp > 15)
+ tmp = 15;
+ if (record_full_arch_list_add_mem (oaddr, tmp + 1))
return -1;
if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM))
return -1;
@@ -6494,6 +6549,17 @@ ex:
/* 0xe747-0xe749 undefined */
+ case 0xe658: /* VCVD - vector convert to decimal 32 bit */
+ case 0xe659: /* VSRP - vector shift and round decimal */
+ case 0xe65a: /* VCVDG - vector convert to decimal 64 bit*/
+ case 0xe65b: /* VPSOP - vector perform sign operation decimal */
+ case 0xe671: /* VAP - vector add decimal */
+ case 0xe673: /* VSP - vector subtract decimal */
+ case 0xe678: /* VMP - vector multiply decimal */
+ case 0xe679: /* VMSP - vector multiply decimal */
+ case 0xe67a: /* VDP - vector divide decimal */
+ case 0xe67b: /* VRP - vector remainder decimal */
+ case 0xe67e: /* VSDP - vector shift and divide decimal */
case 0xe74a: /* VFTCI - vector fp test data class immediate */
case 0xe75c: /* VISTR - vector isolate string */
case 0xe780: /* VFEE - vector find element equal */
@@ -6504,7 +6570,7 @@ ex:
case 0xe797: /* VPKS - vector pack saturate */
case 0xe7e8: /* VFCE - vector fp compare equal */
case 0xe7ea: /* VFCHE - vector fp compare high or equal */
- case 0xe7eb: /* VFCE - vector fp compare high */
+ case 0xe7eb: /* VFCH - vector fp compare high */
case 0xe7f8: /* VCEQ - vector compare equal */
case 0xe7f9: /* VCHL - vector compare high logical */
case 0xe7fb: /* VCH - vector compare high */
@@ -6517,6 +6583,14 @@ ex:
return -1;
break;
+ case 0xe65f: /* VTP - vector test decimal */
+ /* flags + FPC */
+ if (record_full_arch_list_add_reg (regcache, S390_PSWM_REGNUM))
+ return -1;
+ if (record_full_arch_list_add_reg (regcache, S390_FPC_REGNUM))
+ return -1;
+ break;
+
/* 0xe74b-0xe74c undefined */
/* 0xe74e-0xe74f undefined */
/* 0xe751 undefined */
@@ -6524,26 +6598,26 @@ ex:
/* 0xe757-0xe75b undefined */
/* 0xe75d-0xe75e undefined */
/* 0xe763 undefined */
- /* 0xe76c undefined */
- /* 0xe76e-0xe76f undefined */
/* 0xe771 undefined */
/* 0xe776 undefined */
/* 0xe779 undefined */
/* 0xe77b undefined */
/* 0xe783 undefined */
- /* 0xe785-0xe789 undefined */
+ /* 0xe786-0xe789 undefined */
/* 0xe78b undefined */
/* 0xe790-0xe793 undefined */
/* 0xe796 undefined */
- /* 0xe798-0xe7a0 undefined */
- /* 0xe7a8 undefined */
+ /* 0xe798-0xe79d undefined */
+ /* 0xe7a0 undefined */
+ /* 0xe7a8 undefined */
/* 0xe7b0-0xe7b3 undefined */
- /* 0xe7b5-0xe7b8 undefined */
+ /* 0xe7b5-0xe7b7 undefined */
/* 0xe7ba undefined */
/* 0xe7be undefined */
/* 0xe7c6 undefined */
/* 0xe7c8-0xe7c9 undefined */
+ case 0xe677: /* VCP - vector compare decimal */
case 0xe7ca: /* WFK - vector fp compare and signal scalar */
case 0xe7cb: /* WFC - vector fp compare scalar */
case 0xe7d8: /* VTM - vector test under mask */
@@ -6568,7 +6642,7 @@ ex:
/* 0xe7e4 undefined */
/* 0xe7e6 undefined */
/* 0xe7e9 undefined */
- /* 0xe7ec-0xe7ef undefined */
+ /* 0xe7ec-0xe7ed undefined */
/* 0xe7f4 undefined */
/* 0xe7f6 undefined */
/* 0xe7fa undefined */
@@ -7048,8 +7122,6 @@ ex:
}
break;
- /* 0xe6 undefined */
-
case 0xec:
/* RIE/RIS/RRS-format instruction */
switch (ibyte[0] << 8 | ibyte[5])

View File

@ -0,0 +1,49 @@
commit 47826cdbec2548cd1d25acf4cfaf908ae88f3325
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Fri Jul 21 10:54:06 2017 +0200
S/390: Support z14 as CPU name.
With IBM z14 officially announced I can add z14 as CPU name.
No regressions with that patch on s390x.
gas/ChangeLog:
2017-07-21 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/tc-s390.c (s390_parse_cpu): Add z14 as alternate CPU
name.
* doc/as.texinfo: Add z14 to CPU string list.
* doc/c-s390.texi: Likewise.
opcodes/ChangeLog:
2017-07-21 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* s390-mkopc.c (main): Enable z14 as CPU string in the opcode
table.
### a/opcodes/ChangeLog
### b/opcodes/ChangeLog
## -1,3 +1,8 @@
+2017-07-21 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * s390-mkopc.c (main): Enable z14 as CPU string in the opcode
+ table.
+
2017-07-20 Nick Clifton <nickc@redhat.com>
* po/de.po: Updated German translation.
--- a/opcodes/s390-mkopc.c
+++ b/opcodes/s390-mkopc.c
@@ -374,7 +374,8 @@ main (void)
else if (strcmp (cpu_string, "z13") == 0
|| strcmp (cpu_string, "arch11") == 0)
min_cpu = S390_OPCODE_Z13;
- else if (strcmp (cpu_string, "arch12") == 0)
+ else if (strcmp (cpu_string, "z14") == 0
+ || strcmp (cpu_string, "arch12") == 0)
min_cpu = S390_OPCODE_ARCH12;
else {
fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string);

View File

@ -0,0 +1,53 @@
commit 79c12faeea57e61364b6a7a3e411b096edce989c
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Fri Jul 28 17:59:25 2017 +0200
S/390: Fix segfault when linking -shared -nostartfiles
Regression-tested on s390x.
bfd/ChangeLog:
2017-07-28 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf32-s390.c (elf_s390_finish_dynamic_sections): Add NULL
pointer check for htab->elf.irelplt.
* elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise.
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -3941,7 +3941,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
break;
case DT_PLTRELSZ:
- dyn.d_un.d_val = htab->elf.srelplt->size + htab->elf.irelplt->size;
+ dyn.d_un.d_val = htab->elf.srelplt->size;
+ if (htab->elf.irelplt)
+ dyn.d_un.d_val += htab->elf.irelplt->size;
break;
}
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -3745,7 +3745,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
break;
case DT_PLTRELSZ:
- dyn.d_un.d_val = htab->elf.srelplt->size + htab->elf.irelplt->size;
+ dyn.d_un.d_val = htab->elf.srelplt->size;
+ if (htab->elf.irelplt)
+ dyn.d_un.d_val += htab->elf.irelplt->size;
break;
case DT_RELASZ:
@@ -3756,7 +3758,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
linker script arranges for .rela.plt to follow all
other relocation sections, we don't have to worry
about changing the DT_RELA entry. */
- dyn.d_un.d_val -= htab->elf.srelplt->size + htab->elf.irelplt->size;
+ dyn.d_un.d_val -= htab->elf.srelplt->size;
+ if (htab->elf.irelplt)
+ dyn.d_un.d_val -= htab->elf.irelplt->size;
break;
}

View File

@ -0,0 +1,67 @@
commit 1ef692ea23714876cc30b1a3ab3ef33a1369f17a
Author: Andreas Krebbel <krebbel@linux.vnet.ibm.com>
Date: Tue Aug 1 15:13:40 2017 +0200
S/390: Fix claimfile failures
This fixes a segfault when trying to access the local_plt field in the
s390 specific elf data althoug the underlaying object is a generic elf
object.
This fixes the following testsuite failures:
< FAIL: plugin claimfile replace symbol with source
< FAIL: plugin claimfile resolve symbol with source
< FAIL: plugin claimfile replace file with source
< FAIL: plugin set symbol visibility with source
< FAIL: plugin ignore lib with source
< FAIL: plugin claimfile replace lib with source
< FAIL: plugin 2 with source lib
< FAIL: load plugin 2 with source
< FAIL: plugin 3 with source lib
< FAIL: load plugin 3 with source
bfd/ChangeLog:
2017-08-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* elf32-s390.c (elf_s390_finish_dynamic_sections): Skip if it
isn't the S/390 specific elf data.
* elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise.
### a/bfd/ChangeLog
### b/bfd/ChangeLog
## -1,3 +1,9 @@
+2017-08-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * elf32-s390.c (elf_s390_finish_dynamic_sections): Skip if it
+ isn't the S/390 specific elf data.
+ * elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise.
+
2017-07-31 Kuan-Lin Chen <rufus@andestech.com>
* elfxx-riscv.c (riscv_elf_add_sub_reloc): New function.
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -4001,6 +4001,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
symtab_hdr = &elf_symtab_hdr (ibfd);
+ if (!is_s390_elf (ibfd))
+ continue;
+
local_plt = elf_s390_local_plt (ibfd);
if (local_plt != NULL)
for (i = 0; i < symtab_hdr->sh_info; i++)
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -3814,6 +3814,9 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
symtab_hdr = &elf_symtab_hdr (ibfd);
+ if (!is_s390_elf (ibfd))
+ continue;
+
local_plt = elf_s390_local_plt (ibfd);
if (local_plt != NULL)
for (i = 0; i < symtab_hdr->sh_info; i++)

File diff suppressed because it is too large Load Diff

View File

@ -52,11 +52,11 @@ Content-Type: text/x-patch
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=bitpos-ensure-size_t.patch
Index: gdb-7.10.90.20160211/gdb/alpha-tdep.c
Index: gdb-8.0/gdb/alpha-tdep.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/alpha-tdep.c 2016-02-11 20:56:59.224850729 +0100
+++ gdb-7.10.90.20160211/gdb/alpha-tdep.c 2016-02-11 20:57:05.385891225 +0100
@@ -413,6 +413,13 @@
--- gdb-8.0.orig/gdb/alpha-tdep.c 2017-08-19 20:07:45.469330496 +0200
+++ gdb-8.0/gdb/alpha-tdep.c 2017-08-19 20:07:50.670379152 +0200
@@ -414,6 +414,13 @@
accumulate_size = 0;
else
accumulate_size -= sizeof(arg_reg_buffer);
@ -70,11 +70,11 @@ Index: gdb-7.10.90.20160211/gdb/alpha-tdep.c
sp -= accumulate_size;
/* Keep sp aligned to a multiple of 16 as the ABI requires. */
Index: gdb-7.10.90.20160211/gdb/cp-valprint.c
Index: gdb-8.0/gdb/cp-valprint.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/cp-valprint.c 2016-02-11 20:56:59.224850729 +0100
+++ gdb-7.10.90.20160211/gdb/cp-valprint.c 2016-02-11 20:57:05.385891225 +0100
@@ -536,6 +536,8 @@
--- gdb-8.0.orig/gdb/cp-valprint.c 2017-08-19 20:07:45.470330505 +0200
+++ gdb-8.0/gdb/cp-valprint.c 2017-08-19 20:07:50.670379152 +0200
@@ -537,6 +537,8 @@
gdb_byte *buf;
struct cleanup *back_to;
@ -83,32 +83,11 @@ Index: gdb-7.10.90.20160211/gdb/cp-valprint.c
buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass));
back_to = make_cleanup (xfree, buf);
Index: gdb-7.10.90.20160211/gdb/dwarf2loc.c
Index: gdb-8.0/gdb/findcmd.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/dwarf2loc.c 2016-02-11 20:56:59.225850736 +0100
+++ gdb-7.10.90.20160211/gdb/dwarf2loc.c 2016-02-11 20:57:05.386891231 +0100
@@ -1744,6 +1744,8 @@
this_size = (this_size_bits + source_offset_bits % 8 + 7) / 8;
source_offset = source_offset_bits / 8;
+ ulongest_fits_host_or_error (this_size);
+
if (buffer_size < this_size)
{
buffer_size = this_size;
@@ -1926,6 +1928,7 @@
}
else
{
+ ulongest_fits_host_or_error (this_size);
if (buffer_size < this_size)
{
buffer_size = this_size;
Index: gdb-7.10.90.20160211/gdb/findcmd.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/findcmd.c 2016-02-11 20:56:59.226850742 +0100
+++ gdb-7.10.90.20160211/gdb/findcmd.c 2016-02-11 20:57:05.387891238 +0100
@@ -184,6 +184,7 @@
--- gdb-8.0.orig/gdb/findcmd.c 2017-08-19 20:07:45.472330524 +0200
+++ gdb-8.0/gdb/findcmd.c 2017-08-19 20:07:50.672379171 +0200
@@ -186,6 +186,7 @@
size_t current_offset = pattern_buf_end - pattern_buf;
pattern_buf_size = pattern_buf_size_need * 2;
@ -116,11 +95,11 @@ Index: gdb-7.10.90.20160211/gdb/findcmd.c
pattern_buf = (gdb_byte *) xrealloc (pattern_buf, pattern_buf_size);
pattern_buf_end = pattern_buf + current_offset;
}
Index: gdb-7.10.90.20160211/gdb/p-valprint.c
Index: gdb-8.0/gdb/p-valprint.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/p-valprint.c 2016-02-11 20:56:59.226850742 +0100
+++ gdb-7.10.90.20160211/gdb/p-valprint.c 2016-02-11 20:57:05.387891238 +0100
@@ -769,6 +769,7 @@
--- gdb-8.0.orig/gdb/p-valprint.c 2017-08-19 20:07:45.472330524 +0200
+++ gdb-8.0/gdb/p-valprint.c 2017-08-19 20:07:50.673379180 +0200
@@ -772,6 +772,7 @@
gdb_byte *buf;
struct cleanup *back_to;
@ -128,11 +107,11 @@ Index: gdb-7.10.90.20160211/gdb/p-valprint.c
buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass));
back_to = make_cleanup (xfree, buf);
Index: gdb-7.10.90.20160211/gdb/utils.c
Index: gdb-8.0/gdb/utils.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/utils.c 2016-02-11 20:56:59.227850749 +0100
+++ gdb-7.10.90.20160211/gdb/utils.c 2016-02-11 20:57:05.388891244 +0100
@@ -2837,6 +2837,18 @@
--- gdb-8.0.orig/gdb/utils.c 2017-08-19 20:07:45.473330533 +0200
+++ gdb-8.0/gdb/utils.c 2017-08-19 20:07:50.673379180 +0200
@@ -2776,6 +2776,18 @@
return addr;
}
@ -151,11 +130,11 @@ Index: gdb-7.10.90.20160211/gdb/utils.c
char *
gdb_realpath (const char *filename)
{
Index: gdb-7.10.90.20160211/gdb/valops.c
Index: gdb-8.0/gdb/valops.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/valops.c 2016-02-11 20:56:59.228850755 +0100
+++ gdb-7.10.90.20160211/gdb/valops.c 2016-02-11 20:57:05.389891251 +0100
@@ -2057,6 +2057,7 @@
--- gdb-8.0.orig/gdb/valops.c 2017-08-19 20:07:45.474330542 +0200
+++ gdb-8.0/gdb/valops.c 2017-08-19 20:07:50.674379190 +0200
@@ -2100,6 +2100,7 @@
struct cleanup *back_to;
CORE_ADDR address;
@ -163,11 +142,11 @@ Index: gdb-7.10.90.20160211/gdb/valops.c
tmp = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass));
back_to = make_cleanup (xfree, tmp);
address = value_address (*arg1p);
Index: gdb-7.10.90.20160211/gdb/value.c
Index: gdb-8.0/gdb/value.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/value.c 2016-02-11 20:56:59.229850762 +0100
+++ gdb-7.10.90.20160211/gdb/value.c 2016-02-11 20:58:35.095480877 +0100
@@ -935,6 +935,7 @@
--- gdb-8.0.orig/gdb/value.c 2017-08-19 20:07:45.476330561 +0200
+++ gdb-8.0/gdb/value.c 2017-08-19 20:07:50.675379199 +0200
@@ -936,6 +936,7 @@
description correctly. */
check_typedef (type);
@ -175,7 +154,7 @@ Index: gdb-7.10.90.20160211/gdb/value.c
val = XCNEW (struct value);
val->contents = NULL;
val->next = all_values;
@@ -1034,6 +1035,8 @@
@@ -1033,6 +1034,8 @@
static void
allocate_value_contents (struct value *val)
{
@ -184,7 +163,7 @@ Index: gdb-7.10.90.20160211/gdb/value.c
if (!val->contents)
{
check_type_length_before_alloc (val->enclosing_type);
@@ -3090,6 +3093,7 @@
@@ -3093,6 +3096,7 @@
if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val)))
{
check_type_length_before_alloc (new_encl_type);
@ -192,10 +171,10 @@ Index: gdb-7.10.90.20160211/gdb/value.c
val->contents
= (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
}
Index: gdb-7.10.90.20160211/gdb/vax-tdep.c
Index: gdb-8.0/gdb/vax-tdep.c
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/vax-tdep.c 2016-02-11 20:56:59.229850762 +0100
+++ gdb-7.10.90.20160211/gdb/vax-tdep.c 2016-02-11 20:57:05.391891264 +0100
--- gdb-8.0.orig/gdb/vax-tdep.c 2017-08-19 20:07:45.476330561 +0200
+++ gdb-8.0/gdb/vax-tdep.c 2017-08-19 20:07:50.675379199 +0200
@@ -219,6 +219,7 @@
ULONGEST addr;
@ -204,11 +183,11 @@ Index: gdb-7.10.90.20160211/gdb/vax-tdep.c
read_memory (addr, readbuf, len);
}
Index: gdb-7.10.90.20160211/gdb/defs.h
Index: gdb-8.0/gdb/defs.h
===================================================================
--- gdb-7.10.90.20160211.orig/gdb/defs.h 2016-02-11 20:56:59.229850762 +0100
+++ gdb-7.10.90.20160211/gdb/defs.h 2016-02-11 20:57:05.391891264 +0100
@@ -690,4 +690,6 @@
--- gdb-8.0.orig/gdb/defs.h 2017-08-19 20:07:45.476330561 +0200
+++ gdb-8.0/gdb/defs.h 2017-08-19 20:07:50.676379208 +0200
@@ -750,4 +750,6 @@
#include "utils.h"

View File

@ -26,7 +26,7 @@ Version: 8.0
# The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 22%{?dist}
Release: 23%{?dist}
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
Group: Development/Debuggers
@ -689,6 +689,43 @@ Patch1155: gdb-rhbz1398387-tab-crash-test.patch
#=push+jan
Patch1171: v1.6.1-implicit-fallthrough.patch
# [s390x] Backport arch12 support and other s390x fixes (RH BZ 1420304).
Patch1210: gdb-rhbz1420304-s390x-01of35.patch
Patch1211: gdb-rhbz1420304-s390x-02of35.patch
Patch1212: gdb-rhbz1420304-s390x-03of35.patch
Patch1213: gdb-rhbz1420304-s390x-04of35.patch
Patch1214: gdb-rhbz1420304-s390x-05of35.patch
Patch1215: gdb-rhbz1420304-s390x-06of35.patch
Patch1216: gdb-rhbz1420304-s390x-07of35.patch
Patch1217: gdb-rhbz1420304-s390x-08of35.patch
Patch1218: gdb-rhbz1420304-s390x-09of35.patch
Patch1219: gdb-rhbz1420304-s390x-10of35.patch
Patch1220: gdb-rhbz1420304-s390x-11of35.patch
Patch1221: gdb-rhbz1420304-s390x-12of35.patch
Patch1222: gdb-rhbz1420304-s390x-13of35.patch
Patch1223: gdb-rhbz1420304-s390x-14of35.patch
Patch1224: gdb-rhbz1420304-s390x-15of35.patch
Patch1225: gdb-rhbz1420304-s390x-16of35.patch
Patch1226: gdb-rhbz1420304-s390x-17of35.patch
Patch1227: gdb-rhbz1420304-s390x-18of35.patch
Patch1228: gdb-rhbz1420304-s390x-19of35.patch
Patch1229: gdb-rhbz1420304-s390x-20of35.patch
Patch1230: gdb-rhbz1420304-s390x-21of35.patch
Patch1231: gdb-rhbz1420304-s390x-22of35.patch
Patch1232: gdb-rhbz1420304-s390x-23of35.patch
Patch1233: gdb-rhbz1420304-s390x-24of35.patch
Patch1234: gdb-rhbz1420304-s390x-25of35.patch
Patch1235: gdb-rhbz1420304-s390x-26of35.patch
Patch1236: gdb-rhbz1420304-s390x-27of35.patch
Patch1237: gdb-rhbz1420304-s390x-28of35.patch
Patch1238: gdb-rhbz1420304-s390x-29of35.patch
Patch1239: gdb-rhbz1420304-s390x-30of35.patch
Patch1240: gdb-rhbz1420304-s390x-31of35.patch
Patch1241: gdb-rhbz1420304-s390x-32of35.patch
Patch1242: gdb-rhbz1420304-s390x-33of35.patch
Patch1243: gdb-rhbz1420304-s390x-34of35.patch
Patch1244: gdb-rhbz1420304-s390x-35of35.patch
%if 0%{!?rhel:1} || 0%{?rhel} > 6
# RL_STATE_FEDORA_GDB would not be found for:
# Patch642: gdb-readline62-ask-more-rh.patch
@ -1012,6 +1049,41 @@ find -name "*.info*"|xargs rm -f
%patch690 -p1
%patch698 -p1
%patch703 -p1
%patch1210 -p1
%patch1211 -p1
%patch1212 -p1
%patch1213 -p1
%patch1214 -p1
%patch1215 -p1
%patch1216 -p1
%patch1217 -p1
%patch1218 -p1
%patch1219 -p1
%patch1220 -p1
%patch1221 -p1
%patch1222 -p1
%patch1223 -p1
%patch1224 -p1
%patch1225 -p1
%patch1226 -p1
%patch1227 -p1
%patch1228 -p1
%patch1229 -p1
%patch1230 -p1
%patch1231 -p1
%patch1232 -p1
%patch1233 -p1
%patch1234 -p1
%patch1235 -p1
%patch1236 -p1
%patch1237 -p1
%patch1238 -p1
%patch1239 -p1
%patch1240 -p1
%patch1241 -p1
%patch1242 -p1
%patch1243 -p1
%patch1244 -p1
%patch811 -p1
%patch812 -p1
%patch813 -p1
@ -1643,6 +1715,9 @@ then
fi
%changelog
* Sat Aug 19 2017 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0-23.fc26
- [s390x] Backport arch12 support and other s390x fixes (RH BZ 1420304).
* Fri Aug 18 2017 Jan Kratochvil <jan.kratochvil@redhat.com> - 8.0-22.fc26
- Backport a fix for clang && -gsplit-dwarf debuggees (RH BZ 1482892).