Home | History | Annotate | Line # | Download | only in gdbserver
      1 /* GNU/Linux S/390 specific low level interface, for the in-process
      2    agent library for GDB.
      3 
      4    Copyright (C) 2016-2024 Free Software Foundation, Inc.
      5 
      6    This file is part of GDB.
      7 
      8    This program is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3 of the License, or
     11    (at your option) any later version.
     12 
     13    This program is distributed in the hope that it will be useful,
     14    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16    GNU General Public License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20 
     21 #include <sys/mman.h>
     22 #include "tracepoint.h"
     23 #include "linux-s390-tdesc.h"
     24 #include <elf.h>
     25 #ifdef HAVE_GETAUXVAL
     26 #include <sys/auxv.h>
     27 #endif
     28 
     29 #define FT_FPR(x) (0x000 + (x) * 0x10)
     30 #define FT_VR(x) (0x000 + (x) * 0x10)
     31 #define FT_VR_L(x) (0x008 + (x) * 0x10)
     32 #define FT_GPR(x) (0x200 + (x) * 8)
     33 #define FT_GPR_U(x) (0x200 + (x) * 8)
     34 #define FT_GPR_L(x) (0x204 + (x) * 8)
     35 #define FT_GPR(x) (0x200 + (x) * 8)
     36 #define FT_ACR(x) (0x280 + (x) * 4)
     37 #define FT_PSWM 0x2c0
     38 #define FT_PSWM_U 0x2c0
     39 #define FT_PSWA 0x2c8
     40 #define FT_PSWA_L 0x2cc
     41 #define FT_FPC 0x2d0
     42 
     43 /* Mappings between registers collected by the jump pad and GDB's register
     44    array layout used by regcache.
     45 
     46    See linux-s390-low.c (s390_install_fast_tracepoint_jump_pad) for more
     47    details.  */
     48 
     49 #ifndef __s390x__
     50 
     51 /* Used for s390-linux32, s390-linux32v1, s390-linux32v2.  */
     52 
     53 static const int s390_linux32_ft_collect_regmap[] = {
     54   /* 32-bit PSWA and PSWM.  */
     55   FT_PSWM_U, FT_PSWA_L,
     56   /* 32-bit GPRs (mapped to lower halves of 64-bit slots).  */
     57   FT_GPR_L (0), FT_GPR_L (1), FT_GPR_L (2), FT_GPR_L (3),
     58   FT_GPR_L (4), FT_GPR_L (5), FT_GPR_L (6), FT_GPR_L (7),
     59   FT_GPR_L (8), FT_GPR_L (9), FT_GPR_L (10), FT_GPR_L (11),
     60   FT_GPR_L (12), FT_GPR_L (13), FT_GPR_L (14), FT_GPR_L (15),
     61   /* ACRs */
     62   FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
     63   FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
     64   FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
     65   FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
     66   /* FPRs (mapped to upper halves of 128-bit VR slots).  */
     67   FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
     68   FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
     69   FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
     70   FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
     71   /* orig_r2, last_break, system_call */
     72   -1, -1, -1,
     73 };
     74 
     75 /* Used for s390-linux64, s390-linux64v1, s390-linux64v2, s390-vx-linux64.  */
     76 
     77 static const int s390_linux64_ft_collect_regmap[] = {
     78   /* 32-bit PSWA and PSWM.  */
     79   FT_PSWM_U, FT_PSWA_L,
     80   /* 32-bit halves of 64-bit GPRs.  */
     81   FT_GPR_U (0), FT_GPR_L (0),
     82   FT_GPR_U (1), FT_GPR_L (1),
     83   FT_GPR_U (2), FT_GPR_L (2),
     84   FT_GPR_U (3), FT_GPR_L (3),
     85   FT_GPR_U (4), FT_GPR_L (4),
     86   FT_GPR_U (5), FT_GPR_L (5),
     87   FT_GPR_U (6), FT_GPR_L (6),
     88   FT_GPR_U (7), FT_GPR_L (7),
     89   FT_GPR_U (8), FT_GPR_L (8),
     90   FT_GPR_U (9), FT_GPR_L (9),
     91   FT_GPR_U (10), FT_GPR_L (10),
     92   FT_GPR_U (11), FT_GPR_L (11),
     93   FT_GPR_U (12), FT_GPR_L (12),
     94   FT_GPR_U (13), FT_GPR_L (13),
     95   FT_GPR_U (14), FT_GPR_L (14),
     96   FT_GPR_U (15), FT_GPR_L (15),
     97   /* ACRs */
     98   FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
     99   FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
    100   FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
    101   FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
    102   /* FPRs (mapped to upper halves of 128-bit VR slots).  */
    103   FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
    104   FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
    105   FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
    106   FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
    107   /* orig_r2, last_break, system_call */
    108   -1, -1, -1,
    109   /* Lower halves of 128-bit VRs. */
    110   FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
    111   FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
    112   FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
    113   FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
    114   /* And the next 16 VRs.  */
    115   FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
    116   FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
    117   FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
    118   FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
    119 };
    120 
    121 /* Used for s390-te-linux64, s390-tevx-linux64, and s390-gs-linux64.  */
    122 
    123 static const int s390_te_linux64_ft_collect_regmap[] = {
    124   /* 32-bit PSWA and PSWM.  */
    125   FT_PSWM_U, FT_PSWA_L,
    126   /* 32-bit halves of 64-bit GPRs.  */
    127   FT_GPR_U (0), FT_GPR_L (0),
    128   FT_GPR_U (1), FT_GPR_L (1),
    129   FT_GPR_U (2), FT_GPR_L (2),
    130   FT_GPR_U (3), FT_GPR_L (3),
    131   FT_GPR_U (4), FT_GPR_L (4),
    132   FT_GPR_U (5), FT_GPR_L (5),
    133   FT_GPR_U (6), FT_GPR_L (6),
    134   FT_GPR_U (7), FT_GPR_L (7),
    135   FT_GPR_U (8), FT_GPR_L (8),
    136   FT_GPR_U (9), FT_GPR_L (9),
    137   FT_GPR_U (10), FT_GPR_L (10),
    138   FT_GPR_U (11), FT_GPR_L (11),
    139   FT_GPR_U (12), FT_GPR_L (12),
    140   FT_GPR_U (13), FT_GPR_L (13),
    141   FT_GPR_U (14), FT_GPR_L (14),
    142   FT_GPR_U (15), FT_GPR_L (15),
    143   /* ACRs */
    144   FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
    145   FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
    146   FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
    147   FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
    148   /* FPRs (mapped to upper halves of 128-bit VR slots).  */
    149   FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
    150   FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
    151   FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
    152   FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
    153   /* orig_r2, last_break, system_call */
    154   -1, -1, -1,
    155   /* TDB */
    156   -1, -1, -1, -1,
    157   -1, -1, -1, -1,
    158   -1, -1, -1, -1,
    159   -1, -1, -1, -1,
    160   -1, -1, -1, -1,
    161   /* Lower halves of 128-bit VRs. */
    162   FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
    163   FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
    164   FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
    165   FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
    166   /* And the next 16 VRs.  */
    167   FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
    168   FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
    169   FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
    170   FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
    171 };
    172 
    173 #else /* __s390x__ */
    174 
    175 /* Used for s390x-linux64, s390x-linux64v1, s390x-linux64v2, s390x-vx-linux64.  */
    176 
    177 static const int s390x_ft_collect_regmap[] = {
    178   /* 64-bit PSWA and PSWM.  */
    179   FT_PSWM, FT_PSWA,
    180   /* 64-bit GPRs.  */
    181   FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3),
    182   FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7),
    183   FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11),
    184   FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15),
    185   /* ACRs */
    186   FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
    187   FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
    188   FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
    189   FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
    190   /* FPRs (mapped to upper halves of 128-bit VR slots).  */
    191   FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
    192   FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
    193   FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
    194   FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
    195   /* orig_r2, last_break, system_call */
    196   -1, -1, -1,
    197   /* Lower halves of 128-bit VRs. */
    198   FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
    199   FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
    200   FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
    201   FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
    202   /* And the next 16 VRs.  */
    203   FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
    204   FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
    205   FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
    206   FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
    207 };
    208 
    209 /* Used for s390x-te-linux64, s390x-tevx-linux64, and
    210    s390x-gs-linux64.  */
    211 
    212 static const int s390x_te_ft_collect_regmap[] = {
    213   /* 64-bit PSWA and PSWM.  */
    214   FT_PSWM, FT_PSWA,
    215   /* 64-bit GPRs.  */
    216   FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3),
    217   FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7),
    218   FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11),
    219   FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15),
    220   /* ACRs */
    221   FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3),
    222   FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7),
    223   FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11),
    224   FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15),
    225   /* FPRs (mapped to upper halves of 128-bit VR slots).  */
    226   FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3),
    227   FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7),
    228   FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11),
    229   FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15),
    230   /* orig_r2, last_break, system_call */
    231   -1, -1, -1,
    232   /* TDB */
    233   -1, -1, -1, -1,
    234   -1, -1, -1, -1,
    235   -1, -1, -1, -1,
    236   -1, -1, -1, -1,
    237   -1, -1, -1, -1,
    238   /* Lower halves of 128-bit VRs. */
    239   FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3),
    240   FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7),
    241   FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11),
    242   FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15),
    243   /* And the next 16 VRs.  */
    244   FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19),
    245   FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23),
    246   FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27),
    247   FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31),
    248 };
    249 
    250 #endif
    251 
    252 /* Initialized by get_ipa_tdesc according to the tdesc in use.  */
    253 
    254 static const int *s390_regmap;
    255 static int s390_regnum;
    256 
    257 /* Fill in REGCACHE with registers saved by the jump pad in BUF.  */
    258 
    259 void
    260 supply_fast_tracepoint_registers (struct regcache *regcache,
    261 				  const unsigned char *buf)
    262 {
    263   int i;
    264   for (i = 0; i < s390_regnum; i++)
    265     if (s390_regmap[i] != -1)
    266       supply_register (regcache, i, ((char *) buf) + s390_regmap[i]);
    267 }
    268 
    269 ULONGEST
    270 get_raw_reg (const unsigned char *raw_regs, int regnum)
    271 {
    272   int offset;
    273   if (regnum >= s390_regnum)
    274     return 0;
    275   offset = s390_regmap[regnum];
    276   if (offset == -1)
    277     return 0;
    278 
    279   /* The regnums are variable, better to figure out size by FT offset.  */
    280 
    281   /* 64-bit ones.  */
    282   if (offset < FT_VR(16)
    283 #ifdef __s390x__
    284       || (offset >= FT_GPR(0) && offset < FT_ACR(0))
    285       || offset == FT_PSWM
    286       || offset == FT_PSWA
    287 #endif
    288      )
    289     return *(uint64_t *) (raw_regs + offset);
    290 
    291   if (offset >= FT_ACR(0 && offset < FT_PSWM)
    292       || offset == FT_FPC
    293 #ifndef __s390x__
    294       || (offset >= FT_GPR(0) && offset < FT_ACR(0))
    295       || offset == FT_PSWM_U
    296       || offset == FT_PSWA_L
    297 #endif
    298      )
    299     return *(uint32_t *) (raw_regs + offset);
    300 
    301   /* This leaves 128-bit VX.  No way to return them.  */
    302   return 0;
    303 }
    304 
    305 /* Return target_desc to use for IPA, given the tdesc index passed by
    306    gdbserver.  For s390, it also sets s390_regmap and s390_regnum.  */
    307 
    308 const struct target_desc *
    309 get_ipa_tdesc (int idx)
    310 {
    311 #define SET_REGMAP(regmap, skip_last) \
    312 	do { \
    313 	  s390_regmap = regmap; \
    314 	  s390_regnum = (sizeof regmap / sizeof regmap[0]) - skip_last; \
    315 	} while(0)
    316   switch (idx)
    317     {
    318 #ifdef __s390x__
    319     case S390_TDESC_64:
    320       /* Subtract number of VX regs.  */
    321       SET_REGMAP(s390x_ft_collect_regmap, 32);
    322       return tdesc_s390x_linux64;
    323     case S390_TDESC_64V1:
    324       SET_REGMAP(s390x_ft_collect_regmap, 32);
    325       return tdesc_s390x_linux64v1;
    326     case S390_TDESC_64V2:
    327       SET_REGMAP(s390x_ft_collect_regmap, 32);
    328       return tdesc_s390x_linux64v2;
    329     case S390_TDESC_TE:
    330       SET_REGMAP(s390x_te_ft_collect_regmap, 32);
    331       return tdesc_s390x_te_linux64;
    332     case S390_TDESC_VX:
    333       SET_REGMAP(s390x_ft_collect_regmap, 0);
    334       return tdesc_s390x_vx_linux64;
    335     case S390_TDESC_TEVX:
    336       SET_REGMAP(s390x_te_ft_collect_regmap, 0);
    337       return tdesc_s390x_tevx_linux64;
    338     case S390_TDESC_GS:
    339       SET_REGMAP(s390x_te_ft_collect_regmap, 0);
    340       return tdesc_s390x_gs_linux64;
    341 #else
    342     case S390_TDESC_32:
    343       SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
    344       return tdesc_s390_linux32;
    345     case S390_TDESC_32V1:
    346       SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
    347       return tdesc_s390_linux32v1;
    348     case S390_TDESC_32V2:
    349       SET_REGMAP(s390_linux32_ft_collect_regmap, 0);
    350       return tdesc_s390_linux32v2;
    351     case S390_TDESC_64:
    352       SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
    353       return tdesc_s390_linux64;
    354     case S390_TDESC_64V1:
    355       SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
    356       return tdesc_s390_linux64v1;
    357     case S390_TDESC_64V2:
    358       SET_REGMAP(s390_linux64_ft_collect_regmap, 32);
    359       return tdesc_s390_linux64v2;
    360     case S390_TDESC_TE:
    361       SET_REGMAP(s390_te_linux64_ft_collect_regmap, 32);
    362       return tdesc_s390_te_linux64;
    363     case S390_TDESC_VX:
    364       SET_REGMAP(s390_linux64_ft_collect_regmap, 0);
    365       return tdesc_s390_vx_linux64;
    366     case S390_TDESC_TEVX:
    367       SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0);
    368       return tdesc_s390_tevx_linux64;
    369     case S390_TDESC_GS:
    370       SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0);
    371       return tdesc_s390_gs_linux64;
    372 #endif
    373     default:
    374       internal_error ("unknown ipa tdesc index: %d", idx);
    375 #ifdef __s390x__
    376       return tdesc_s390x_linux64;
    377 #else
    378       return tdesc_s390_linux32;
    379 #endif
    380     }
    381 }
    382 
    383 /* Allocate buffer for the jump pads.  On 31-bit, JG reaches everywhere,
    384    so just allocate normally.  On 64-bit, we have +/-4GiB of reach, and
    385    the executable is usually mapped at 0x80000000 - aim for somewhere
    386    below it.  */
    387 
    388 void *
    389 alloc_jump_pad_buffer (size_t size)
    390 {
    391 #ifdef __s390x__
    392   uintptr_t addr;
    393   uintptr_t exec_base = getauxval (AT_PHDR);
    394   int pagesize;
    395   void *res;
    396 
    397   if (exec_base == 0)
    398     exec_base = 0x80000000;
    399 
    400   pagesize = sysconf (_SC_PAGE_SIZE);
    401   if (pagesize == -1)
    402     perror_with_name ("sysconf");
    403 
    404   addr = exec_base - size;
    405 
    406   /* size should already be page-aligned, but this can't hurt.  */
    407   addr &= ~(pagesize - 1);
    408 
    409   /* Search for a free area.  If we hit 0, we're out of luck.  */
    410   for (; addr; addr -= pagesize)
    411     {
    412       /* No MAP_FIXED - we don't want to zap someone's mapping.  */
    413       res = mmap ((void *) addr, size,
    414 		  PROT_READ | PROT_WRITE | PROT_EXEC,
    415 		  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    416 
    417       /* If we got what we wanted, return.  */
    418       if ((uintptr_t) res == addr)
    419 	return res;
    420 
    421       /* If we got a mapping, but at a wrong address, undo it.  */
    422       if (res != MAP_FAILED)
    423 	munmap (res, size);
    424     }
    425 
    426   return NULL;
    427 #else
    428   void *res = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
    429 		    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    430 
    431   if (res == MAP_FAILED)
    432     return NULL;
    433 
    434   return res;
    435 #endif
    436 }
    437 
    438 void
    439 initialize_low_tracepoint (void)
    440 {
    441 #ifdef __s390x__
    442   init_registers_s390x_linux64 ();
    443   init_registers_s390x_linux64v1 ();
    444   init_registers_s390x_linux64v2 ();
    445   init_registers_s390x_te_linux64 ();
    446   init_registers_s390x_vx_linux64 ();
    447   init_registers_s390x_tevx_linux64 ();
    448   init_registers_s390x_gs_linux64 ();
    449 #else
    450   init_registers_s390_linux32 ();
    451   init_registers_s390_linux32v1 ();
    452   init_registers_s390_linux32v2 ();
    453   init_registers_s390_linux64 ();
    454   init_registers_s390_linux64v1 ();
    455   init_registers_s390_linux64v2 ();
    456   init_registers_s390_te_linux64 ();
    457   init_registers_s390_vx_linux64 ();
    458   init_registers_s390_tevx_linux64 ();
    459   init_registers_s390_gs_linux64 ();
    460 #endif
    461 }
    462