LCOV - code coverage report
Current view: top level - strace - mtd.c (source / functions) Hit Total Coverage
Test: strace-4.18.0.129.97bbb Code Coverage Lines: 111 148 75.0 %
Date: 2017-07-31 03:46:08 Functions: 13 14 92.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 54 82 65.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2012 Mike Frysinger <vapier@gentoo.org>
       3                 :            :  * Copyright (c) 2012-2017 The strace developers.
       4                 :            :  *
       5                 :            :  * Redistribution and use in source and binary forms, with or without
       6                 :            :  * modification, are permitted provided that the following conditions
       7                 :            :  * are met:
       8                 :            :  * 1. Redistributions of source code must retain the above copyright
       9                 :            :  *    notice, this list of conditions and the following disclaimer.
      10                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer in the
      12                 :            :  *    documentation and/or other materials provided with the distribution.
      13                 :            :  * 3. The name of the author may not be used to endorse or promote products
      14                 :            :  *    derived from this software without specific prior written permission.
      15                 :            :  *
      16                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      20                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26                 :            :  */
      27                 :            : 
      28                 :            : #include "defs.h"
      29                 :            : 
      30                 :            : #include DEF_MPERS_TYPE(struct_mtd_oob_buf)
      31                 :            : 
      32                 :            : #include <linux/ioctl.h>
      33                 :            : 
      34                 :            : /* The mtd api changes quickly, so we have to keep a local copy */
      35                 :            : #include <linux/version.h>
      36                 :            : #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
      37                 :            : # include "mtd-abi.h"
      38                 :            : #else
      39                 :            : # include <mtd/mtd-abi.h>
      40                 :            : #endif
      41                 :            : 
      42                 :            : typedef struct mtd_oob_buf struct_mtd_oob_buf;
      43                 :            : 
      44                 :            : #include MPERS_DEFS
      45                 :            : 
      46                 :            : #include "xlat/mtd_mode_options.h"
      47                 :            : #include "xlat/mtd_file_mode_options.h"
      48                 :            : #include "xlat/mtd_type_options.h"
      49                 :            : #include "xlat/mtd_flags_options.h"
      50                 :            : #include "xlat/mtd_otp_options.h"
      51                 :            : #include "xlat/mtd_nandecc_options.h"
      52                 :            : 
      53                 :            : static void
      54                 :         16 : decode_erase_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
      55                 :            : {
      56                 :            :         struct erase_info_user einfo;
      57                 :            : 
      58                 :         16 :         tprints(", ");
      59         [ +  + ]:         16 :         if (umove_or_printaddr(tcp, addr, &einfo))
      60                 :          8 :                 return;
      61                 :            : 
      62                 :          8 :         tprintf("{start=%#x, length=%#x}", einfo.start, einfo.length);
      63                 :            : }
      64                 :            : 
      65                 :            : static void
      66                 :          4 : decode_erase_info_user64(struct tcb *const tcp, const kernel_ulong_t addr)
      67                 :            : {
      68                 :            :         struct erase_info_user64 einfo64;
      69                 :            : 
      70                 :          4 :         tprints(", ");
      71         [ +  + ]:          4 :         if (umove_or_printaddr(tcp, addr, &einfo64))
      72                 :          2 :                 return;
      73                 :            : 
      74                 :          2 :         tprintf("{start=%#" PRIx64 ", length=%#" PRIx64 "}",
      75                 :          2 :                 (uint64_t) einfo64.start, (uint64_t) einfo64.length);
      76                 :            : }
      77                 :            : 
      78                 :            : static void
      79                 :          8 : decode_mtd_oob_buf(struct tcb *const tcp, const kernel_ulong_t addr)
      80                 :            : {
      81                 :            :         struct_mtd_oob_buf mbuf;
      82                 :            : 
      83                 :          8 :         tprints(", ");
      84         [ +  + ]:          8 :         if (umove_or_printaddr(tcp, addr, &mbuf))
      85                 :          4 :                 return;
      86                 :            : 
      87                 :          4 :         tprintf("{start=%#x, length=%#x, ptr=", mbuf.start, mbuf.length);
      88                 :          4 :         printaddr(ptr_to_kulong(mbuf.ptr));
      89                 :          4 :         tprints("}");
      90                 :            : }
      91                 :            : 
      92                 :            : static void
      93                 :          8 : decode_mtd_oob_buf64(struct tcb *const tcp, const kernel_ulong_t addr)
      94                 :            : {
      95                 :            :         struct mtd_oob_buf64 mbuf64;
      96                 :            : 
      97                 :          8 :         tprints(", ");
      98         [ +  + ]:          8 :         if (umove_or_printaddr(tcp, addr, &mbuf64))
      99                 :          4 :                 return;
     100                 :            : 
     101                 :          4 :         tprintf("{start=%#" PRIx64 ", length=%#x, usr_ptr=%#" PRIx64 "}",
     102                 :          4 :                 (uint64_t) mbuf64.start, mbuf64.length,
     103                 :          4 :                 (uint64_t) mbuf64.usr_ptr);
     104                 :            : }
     105                 :            : 
     106                 :            : static void
     107                 :          6 : decode_otp_info(struct tcb *const tcp, const kernel_ulong_t addr)
     108                 :            : {
     109                 :            :         struct otp_info oinfo;
     110                 :            : 
     111                 :          6 :         tprints(", ");
     112         [ +  + ]:          6 :         if (umove_or_printaddr(tcp, addr, &oinfo))
     113                 :          4 :                 return;
     114                 :            : 
     115                 :          2 :         tprintf("{start=%#x, length=%#x, locked=%u}",
     116                 :            :                 oinfo.start, oinfo.length, oinfo.locked);
     117                 :            : }
     118                 :            : 
     119                 :            : static void
     120                 :          6 : decode_otp_select(struct tcb *const tcp, const kernel_ulong_t addr)
     121                 :            : {
     122                 :            :         unsigned int i;
     123                 :            : 
     124                 :          6 :         tprints(", ");
     125         [ +  + ]:          6 :         if (umove_or_printaddr(tcp, addr, &i))
     126                 :          2 :                 return;
     127                 :            : 
     128                 :          4 :         tprints("[");
     129                 :          4 :         printxval(mtd_otp_options, i, "MTD_OTP_???");
     130                 :          4 :         tprints("]");
     131                 :            : }
     132                 :            : 
     133                 :            : static void
     134                 :          4 : decode_mtd_write_req(struct tcb *const tcp, const kernel_ulong_t addr)
     135                 :            : {
     136                 :            :         struct mtd_write_req mreq;
     137                 :            : 
     138                 :          4 :         tprints(", ");
     139         [ +  + ]:          4 :         if (umove_or_printaddr(tcp, addr, &mreq))
     140                 :          2 :                 return;
     141                 :            : 
     142                 :          2 :         tprintf("{start=%#" PRIx64 ", len=%#" PRIx64
     143                 :            :                 ", ooblen=%#" PRIx64 ", usr_data=%#" PRIx64
     144                 :            :                 ", usr_oob=%#" PRIx64 ", mode=",
     145                 :          2 :                 (uint64_t) mreq.start, (uint64_t) mreq.len,
     146                 :          2 :                 (uint64_t) mreq.ooblen, (uint64_t) mreq.usr_data,
     147                 :          2 :                 (uint64_t) mreq.usr_oob);
     148                 :          2 :         printxval(mtd_mode_options, mreq.mode, "MTD_OPS_???");
     149                 :          2 :         tprints("}");
     150                 :            : }
     151                 :            : 
     152                 :            : static void
     153                 :          2 : decode_mtd_info_user(struct tcb *const tcp, const kernel_ulong_t addr)
     154                 :            : {
     155                 :            :         struct mtd_info_user minfo;
     156                 :            : 
     157                 :          2 :         tprints(", ");
     158         [ -  + ]:          2 :         if (umove_or_printaddr(tcp, addr, &minfo))
     159                 :          2 :                 return;
     160                 :            : 
     161                 :          0 :         tprints("{type=");
     162                 :          0 :         printxval(mtd_type_options, minfo.type, "MTD_???");
     163                 :          0 :         tprints(", flags=");
     164                 :          0 :         printflags(mtd_flags_options, minfo.flags, "MTD_???");
     165                 :          0 :         tprintf(", size=%#x, erasesize=%#x, writesize=%#x, oobsize=%#x"
     166                 :            :                 ", padding=%#" PRIx64 "}",
     167                 :            :                 minfo.size, minfo.erasesize, minfo.writesize, minfo.oobsize,
     168                 :          0 :                 (uint64_t) minfo.padding);
     169                 :            : }
     170                 :            : 
     171                 :            : static void
     172                 :          2 : decode_nand_oobinfo(struct tcb *const tcp, const kernel_ulong_t addr)
     173                 :            : {
     174                 :            :         struct nand_oobinfo ninfo;
     175                 :            :         unsigned int i, j;
     176                 :            : 
     177                 :          2 :         tprints(", ");
     178         [ -  + ]:          2 :         if (umove_or_printaddr(tcp, addr, &ninfo))
     179                 :          2 :                 return;
     180                 :            : 
     181                 :          0 :         tprints("{useecc=");
     182                 :          0 :         printxval(mtd_nandecc_options, ninfo.useecc, "MTD_NANDECC_???");
     183                 :          0 :         tprintf(", eccbytes=%#x", ninfo.eccbytes);
     184                 :            : 
     185                 :          0 :         tprints(", oobfree={");
     186         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ninfo.oobfree); ++i) {
     187         [ #  # ]:          0 :                 if (i)
     188                 :          0 :                         tprints("}, ");
     189                 :          0 :                 tprints("{");
     190         [ #  # ]:          0 :                 for (j = 0; j < ARRAY_SIZE(ninfo.oobfree[0]); ++j) {
     191         [ #  # ]:          0 :                         if (j)
     192                 :          0 :                                 tprints(", ");
     193                 :          0 :                         tprintf("%#x", ninfo.oobfree[i][j]);
     194                 :            :                 }
     195                 :            :         }
     196                 :            : 
     197                 :          0 :         tprints("}}, eccpos={");
     198         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(ninfo.eccpos); ++i) {
     199         [ #  # ]:          0 :                 if (i)
     200                 :          0 :                         tprints(", ");
     201                 :          0 :                 tprintf("%#x", ninfo.eccpos[i]);
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         tprints("}");
     205                 :            : }
     206                 :            : 
     207                 :            : static void
     208                 :          2 : decode_nand_ecclayout_user(struct tcb *const tcp, const kernel_ulong_t addr)
     209                 :            : {
     210                 :            :         struct nand_ecclayout_user nlay;
     211                 :            :         unsigned int i;
     212                 :            : 
     213                 :          2 :         tprints(", ");
     214         [ -  + ]:          2 :         if (umove_or_printaddr(tcp, addr, &nlay))
     215                 :          2 :                 return;
     216                 :            : 
     217                 :          0 :         tprintf("{eccbytes=%#x, eccpos={", nlay.eccbytes);
     218         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(nlay.eccpos); ++i) {
     219         [ #  # ]:          0 :                 if (i)
     220                 :          0 :                         tprints(", ");
     221                 :          0 :                 tprintf("%#x", nlay.eccpos[i]);
     222                 :            :         }
     223                 :          0 :         tprintf("}, oobavail=%#x, oobfree={", nlay.oobavail);
     224         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(nlay.oobfree); ++i) {
     225         [ #  # ]:          0 :                 if (i)
     226                 :          0 :                         tprints(", ");
     227                 :          0 :                 tprintf("{offset=%#x, length=%#x}",
     228                 :            :                         nlay.oobfree[i].offset, nlay.oobfree[i].length);
     229                 :            :         }
     230                 :          0 :         tprints("}");
     231                 :            : }
     232                 :            : 
     233                 :            : static void
     234                 :          2 : decode_mtd_ecc_stats(struct tcb *const tcp, const kernel_ulong_t addr)
     235                 :            : {
     236                 :            :         struct mtd_ecc_stats es;
     237                 :            : 
     238                 :          2 :         tprints(", ");
     239         [ -  + ]:          2 :         if (umove_or_printaddr(tcp, addr, &es))
     240                 :          2 :                 return;
     241                 :            : 
     242                 :          0 :         tprintf("{corrected=%#x, failed=%#x, badblocks=%#x, bbtblocks=%#x}",
     243                 :            :                 es.corrected, es.failed, es.badblocks, es.bbtblocks);
     244                 :            : }
     245                 :            : 
     246                 :         94 : MPERS_PRINTER_DECL(int, mtd_ioctl, struct tcb *const tcp,
     247                 :            :                    const unsigned int code, const kernel_ulong_t arg)
     248                 :            : {
     249   [ +  +  +  +  :         94 :         switch (code) {
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     250                 :            :         case MEMERASE:
     251                 :            :         case MEMLOCK:
     252                 :            :         case MEMUNLOCK:
     253                 :            :         case MEMISLOCKED:
     254                 :         16 :                 decode_erase_info_user(tcp, arg);
     255                 :         16 :                 break;
     256                 :            : 
     257                 :            :         case MEMERASE64:
     258                 :          4 :                 decode_erase_info_user64(tcp, arg);
     259                 :          4 :                 break;
     260                 :            : 
     261                 :            :         case MEMWRITEOOB:
     262                 :            :         case MEMREADOOB:
     263                 :          8 :                 decode_mtd_oob_buf(tcp, arg);
     264                 :          8 :                 break;
     265                 :            : 
     266                 :            :         case MEMWRITEOOB64:
     267                 :            :         case MEMREADOOB64:
     268                 :          8 :                 decode_mtd_oob_buf64(tcp, arg);
     269                 :          8 :                 break;
     270                 :            : 
     271                 :            :         case MEMWRITE:
     272                 :          4 :                 decode_mtd_write_req(tcp, arg);
     273                 :          4 :                 break;
     274                 :            : 
     275                 :            :         case OTPGETREGIONINFO:
     276         [ +  + ]:          4 :                 if (entering(tcp))
     277                 :            :                         return 0;
     278                 :            :                 /* fall through */
     279                 :            :         case OTPLOCK:
     280                 :          6 :                 decode_otp_info(tcp, arg);
     281                 :          6 :                 break;
     282                 :            : 
     283                 :            :         case OTPSELECT:
     284                 :          6 :                 decode_otp_select(tcp, arg);
     285                 :          6 :                 break;
     286                 :            : 
     287                 :            :         case MTDFILEMODE:
     288                 :          2 :                 tprints(", ");
     289                 :            :                 printxval64(mtd_file_mode_options, arg, "MTD_FILE_MODE_???");
     290                 :            :                 break;
     291                 :            : 
     292                 :            :         case MEMGETBADBLOCK:
     293                 :            :         case MEMSETBADBLOCK:
     294                 :          8 :                 tprints(", ");
     295                 :          8 :                 printnum_int64(tcp, arg, "%" PRIu64);
     296                 :          8 :                 break;
     297                 :            : 
     298                 :            :         case MEMGETINFO:
     299         [ +  + ]:          4 :                 if (entering(tcp))
     300                 :            :                         return 0;
     301                 :          2 :                 decode_mtd_info_user(tcp, arg);
     302                 :          2 :                 break;
     303                 :            : 
     304                 :            :         case MEMGETOOBSEL:
     305         [ +  + ]:          4 :                 if (entering(tcp))
     306                 :            :                         return 0;
     307                 :          2 :                 decode_nand_oobinfo(tcp, arg);
     308                 :          2 :                 break;
     309                 :            : 
     310                 :            :         case ECCGETLAYOUT:
     311         [ +  + ]:          4 :                 if (entering(tcp))
     312                 :            :                         return 0;
     313                 :          2 :                 decode_nand_ecclayout_user(tcp, arg);
     314                 :          2 :                 break;
     315                 :            : 
     316                 :            :         case ECCGETSTATS:
     317         [ +  + ]:          4 :                 if (entering(tcp))
     318                 :            :                         return 0;
     319                 :          2 :                 decode_mtd_ecc_stats(tcp, arg);
     320                 :          2 :                 break;
     321                 :            : 
     322                 :            :         case OTPGETREGIONCOUNT:
     323         [ +  + ]:          4 :                 if (entering(tcp))
     324                 :            :                         return 0;
     325                 :          2 :                 tprints(", ");
     326                 :          2 :                 printnum_int(tcp, arg, "%u");
     327                 :          2 :                 break;
     328                 :            : 
     329                 :            :         case MEMGETREGIONCOUNT:
     330         [ +  + ]:          4 :                 if (entering(tcp))
     331                 :            :                         return 0;
     332                 :          2 :                 tprints(", ");
     333                 :          2 :                 printnum_int(tcp, arg, "%d");
     334                 :          2 :                 break;
     335                 :            : 
     336                 :            :         case MEMGETREGIONINFO:
     337         [ +  + ]:          4 :                 if (entering(tcp)) {
     338                 :            :                         struct region_info_user rinfo;
     339                 :            : 
     340                 :          2 :                         tprints(", ");
     341         [ +  - ]:          2 :                         if (umove_or_printaddr(tcp, arg, &rinfo))
     342                 :            :                                 break;
     343                 :          2 :                         tprintf("{regionindex=%#x", rinfo.regionindex);
     344                 :          2 :                         return 0;
     345                 :            :                 } else {
     346                 :            :                         struct region_info_user rinfo;
     347                 :            : 
     348 [ -  + ][ #  # ]:          2 :                         if (!syserror(tcp) && !umove(tcp, arg, &rinfo))
     349                 :          0 :                                 tprintf(", offset=%#x"
     350                 :            :                                         ", erasesize=%#x"
     351                 :            :                                         ", numblocks=%#x}",
     352                 :            :                                         rinfo.offset,
     353                 :            :                                         rinfo.erasesize,
     354                 :            :                                         rinfo.numblocks);
     355                 :          2 :                         tprints("}");
     356                 :            :                         break;
     357                 :            :                 }
     358                 :            : 
     359                 :            :         default:
     360                 :            :                 return RVAL_DECODED;
     361                 :            :         }
     362                 :            : 
     363                 :            :         return RVAL_DECODED | 1;
     364                 :            : }

Generated by: LCOV version 1.11