(root)/
strace-6.5/
src/
ubi.c
       1  /*
       2   * Copyright (c) 2012 Mike Frysinger <vapier@gentoo.org>
       3   * Copyright (c) 2012-2021 The strace developers.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   */
       7  
       8  #include "defs.h"
       9  
      10  #include <linux/ioctl.h>
      11  #include <mtd/ubi-user.h>
      12  
      13  #include "xlat/ubi_volume_types.h"
      14  #include "xlat/ubi_volume_flags.h"
      15  #include "xlat/ubi_volume_props.h"
      16  #include "xlat/ubi_data_types.h"
      17  
      18  static int
      19  decode_UBI_IOCMKVOL(struct tcb *const tcp, const kernel_ulong_t arg)
      20  {
      21  	struct ubi_mkvol_req mkvol;
      22  
      23  	if (entering(tcp)) {
      24  		tprint_arg_next();
      25  		if (umove_or_printaddr(tcp, arg, &mkvol))
      26  			return RVAL_IOCTL_DECODED;
      27  
      28  		tprint_struct_begin();
      29  		PRINT_FIELD_D(mkvol, vol_id);
      30  		tprint_struct_next();
      31  		PRINT_FIELD_D(mkvol, alignment);
      32  		tprint_struct_next();
      33  		PRINT_FIELD_D(mkvol, bytes);
      34  		tprint_struct_next();
      35  		PRINT_FIELD_XVAL(mkvol, vol_type,
      36  				 ubi_volume_types, "UBI_???_VOLUME");
      37  		tprint_struct_next();
      38  		PRINT_FIELD_FLAGS(mkvol, flags,
      39  				  ubi_volume_flags, "UBI_VOL_???");
      40  		tprint_struct_next();
      41  		PRINT_FIELD_D(mkvol, name_len);
      42  		tprint_struct_next();
      43  		PRINT_FIELD_CSTRING_SZ(mkvol, name,
      44  				       1 + CLAMP(mkvol.name_len, 0,
      45  						 (int) sizeof(mkvol.name) - 1));
      46  		tprint_struct_end();
      47  		return 0;
      48  	}
      49  
      50  	if (!syserror(tcp)) {
      51  		tprint_value_changed();
      52  		printnum_int(tcp, arg, "%d");
      53  	}
      54  
      55  	return RVAL_IOCTL_DECODED;
      56  }
      57  
      58  static int
      59  decode_UBI_IOCRSVOL(struct tcb *const tcp, const kernel_ulong_t arg)
      60  {
      61  	struct ubi_rsvol_req rsvol;
      62  
      63  	tprint_arg_next();
      64  	if (!umove_or_printaddr(tcp, arg, &rsvol)) {
      65  		tprint_struct_begin();
      66  		PRINT_FIELD_D(rsvol, bytes);
      67  		tprint_struct_next();
      68  		PRINT_FIELD_D(rsvol, vol_id);
      69  		tprint_struct_end();
      70  	}
      71  
      72  	return RVAL_IOCTL_DECODED;
      73  }
      74  
      75  static bool
      76  print_ubi_rnvol_req_ent_array_member(struct tcb *tcp, void *elem_buf,
      77  				     size_t elem_size, void *data)
      78  {
      79  	typeof(&((struct ubi_rnvol_req *) NULL)->ents[0]) p = elem_buf;
      80  
      81  	tprint_struct_begin();
      82  	PRINT_FIELD_D(*p, vol_id);
      83  	tprint_struct_next();
      84  	PRINT_FIELD_D(*p, name_len);
      85  	tprint_struct_next();
      86  	PRINT_FIELD_CSTRING_SZ(*p, name,
      87  			       1 + CLAMP(p->name_len, 0,
      88  				         (int) sizeof(p->name) - 1));
      89  	tprint_struct_end();
      90  
      91  	return true;
      92  }
      93  
      94  static int
      95  decode_UBI_IOCRNVOL(struct tcb *const tcp, const kernel_ulong_t arg)
      96  {
      97  	struct ubi_rnvol_req rnvol;
      98  
      99  	tprint_arg_next();
     100  	if (!umove_or_printaddr(tcp, arg, &rnvol)) {
     101  		tprint_struct_begin();
     102  		PRINT_FIELD_D(rnvol, count);
     103  		tprint_struct_next();
     104  		PRINT_FIELD_ARRAY_UPTO(rnvol, ents, rnvol.count, tcp,
     105  				       print_ubi_rnvol_req_ent_array_member);
     106  		tprint_struct_end();
     107  	}
     108  
     109  	return RVAL_IOCTL_DECODED;
     110  }
     111  
     112  static int
     113  decode_UBI_IOCEBCH(struct tcb *const tcp, const kernel_ulong_t arg)
     114  {
     115  	struct ubi_leb_change_req leb;
     116  
     117  	tprint_arg_next();
     118  	if (!umove_or_printaddr(tcp, arg, &leb)) {
     119  		tprint_struct_begin();
     120  		PRINT_FIELD_D(leb, lnum);
     121  		tprint_struct_next();
     122  		PRINT_FIELD_D(leb, bytes);
     123  		tprint_struct_next();
     124  		PRINT_FIELD_XVAL(leb, dtype, ubi_data_types, "UBI_???");
     125  		tprint_struct_end();
     126  	}
     127  
     128  	return RVAL_IOCTL_DECODED;
     129  }
     130  
     131  static int
     132  decode_UBI_IOCATT(struct tcb *const tcp, const kernel_ulong_t arg)
     133  {
     134  	if (entering(tcp)) {
     135  		struct ubi_attach_req attach;
     136  
     137  		tprint_arg_next();
     138  		if (umove_or_printaddr(tcp, arg, &attach))
     139  			return RVAL_IOCTL_DECODED;
     140  
     141  		tprint_struct_begin();
     142  		PRINT_FIELD_D(attach, ubi_num);
     143  		tprint_struct_next();
     144  		PRINT_FIELD_D(attach, mtd_num);
     145  		tprint_struct_next();
     146  		PRINT_FIELD_D(attach, vid_hdr_offset);
     147  		tprint_struct_next();
     148  		PRINT_FIELD_D(attach, max_beb_per1024);
     149  		tprint_struct_end();
     150  		return 0;
     151  	}
     152  
     153  	if (!syserror(tcp)) {
     154  		tprint_value_changed();
     155  		printnum_int(tcp, arg, "%d");
     156  	}
     157  
     158  	return RVAL_IOCTL_DECODED;
     159  }
     160  
     161  static int
     162  decode_UBI_IOCEBMAP(struct tcb *const tcp, const kernel_ulong_t arg)
     163  {
     164  	struct ubi_map_req map;
     165  
     166  	tprint_arg_next();
     167  	if (!umove_or_printaddr(tcp, arg, &map)) {
     168  		tprint_struct_begin();
     169  		PRINT_FIELD_D(map, lnum);
     170  		tprint_struct_next();
     171  		PRINT_FIELD_XVAL(map, dtype, ubi_data_types, "UBI_???");
     172  		tprint_struct_end();
     173  	}
     174  
     175  	return RVAL_IOCTL_DECODED;
     176  }
     177  
     178  static int
     179  decode_UBI_IOCSETVOLPROP(struct tcb *const tcp, const kernel_ulong_t arg)
     180  {
     181  	struct ubi_set_vol_prop_req prop;
     182  
     183  	tprint_arg_next();
     184  	if (!umove_or_printaddr(tcp, arg, &prop)) {
     185  		tprint_struct_begin();
     186  		PRINT_FIELD_XVAL(prop, property,
     187  				 ubi_volume_props, "UBI_VOL_PROP_???");
     188  		tprint_struct_next();
     189  		PRINT_FIELD_X(prop, value);
     190  		tprint_struct_end();
     191  	}
     192  
     193  	return RVAL_IOCTL_DECODED;
     194  }
     195  
     196  int
     197  ubi_ioctl(struct tcb *const tcp, const unsigned int code,
     198  	  const kernel_ulong_t arg)
     199  {
     200  	switch (code) {
     201  #define case_UBI(name)  case UBI_ ## name: return decode_UBI_ ## name(tcp, arg)
     202  	case_UBI(IOCATT);
     203  	case_UBI(IOCEBCH);
     204  	case_UBI(IOCEBMAP);
     205  	case_UBI(IOCMKVOL);
     206  	case_UBI(IOCRNVOL);
     207  	case_UBI(IOCRSVOL);
     208  	case_UBI(IOCSETVOLPROP);
     209  #undef case_UBI
     210  
     211  	case UBI_IOCVOLUP:
     212  		tprint_arg_next();
     213  		printnum_int64(tcp, arg, "%" PRIi64);
     214  		break;
     215  
     216  	case UBI_IOCDET:
     217  	case UBI_IOCEBER:
     218  	case UBI_IOCEBISMAP:
     219  	case UBI_IOCEBUNMAP:
     220  	case UBI_IOCRMVOL:
     221  	case UBI_IOCRPEB:
     222  	case UBI_IOCSPEB:
     223  		tprint_arg_next();
     224  		printnum_int(tcp, arg, "%d");
     225  		break;
     226  
     227  	case UBI_IOCVOLCRBLK:
     228  	case UBI_IOCVOLRMBLK:
     229  		/* no arguments */
     230  		break;
     231  
     232  	default:
     233  		return RVAL_DECODED;
     234  	}
     235  
     236  	return RVAL_IOCTL_DECODED;
     237  }