Example #1
0
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next'

    fname = tempfile.mktemp('.cocci')
    fp = open(fname, "w")
    fp.write(COCCI)
    fp.close()

    print '\
/// use free_netdev() instead of kfree() in {{function}}\n\
///\n\
/// Freeing netdev without free_netdev() leads to net, tx leaks.\n\
/// And it may lead to dereferencing freed pointer.\n\
///\n'

    stypes = []
    sargs = '/usr/bin/spatch -I %s -timeout 60 -very_quiet -sp_file %s %s' % (
                        os.path.join(kdir, 'include'), fname, kdir)
    for line in _execute_shell(sargs):
        if line.find('|') == -1:
            continue
        a = line.split('|')
        # skip sub field
        if a[1].find('->') != -1:
            continue
        if stypes.count(a) != 0:
            continue
        stypes.append(a)
        print '@@\n\
%s *x;\n\
@@\n\
- kfree(x->%s);\n\
+ free_netdev(x->%s);\n' % (a[0], a[1].split('\n')[0], a[1].split('\n')[0])

    os.unlink(fname)
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next'

    fname = tempfile.mktemp('.cocci')
    fp = open(fname, "w")
    fp.write(COCCI)
    fp.close()

    print '\
/// use kmem_cache_free() instead of kfree()\n\
///\n\
/// memory allocated by kmem_cache_alloc() should be freed using\n\
/// kmem_cache_free(), not kfree().\n\
///\n'

    stypes = []
    for sfile in _execute_shell("find %s -type f" % kdir)[0:-1]:
        if not is_source_file(sfile):
            continue
        sargs = '/usr/bin/spatch -I %s -timeout 60 -very_quiet -sp_file %s %s' % (
                        os.path.join(kdir, 'include'), fname, sfile)
        for line in _execute_shell(sargs):
            if line.find('|') == -1:
                continue
            a = line.split('|')
            # skip sub field
            if a[1].find('->') != -1:
                continue
            if stypes.count(a[0]) != 0:
                continue
            if a[0] in ['char *', 'void *', 'u32 *', 'unsigned long *', 'struct sk_buff *', 'struct urb_priv *']:
                continue
            stypes.append(a[0])
            print '@@\n\
%sx;\n\
@@\n\
- kfree(x);\n\
+ kmem_cache_free(%s, x);\n' % (a[0], a[1].split('\n')[0])

    os.unlink(fname)
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next/'

    skip_list = ['malloc',
                 'readb',
                 'xchg',
                 'PDE_DATA',
                 'ioread32',
                 'in_be32',
                 'nv_ro16',
                 'be32_to_cpu',
                 'le32_to_cpu',
                 'min',
                 'min_t',
                 'inl',
                 'inb',
                 'container_of',
                 'ERR_CAST',
                 'ERR_PTR',
                 'list_entry',
                 'list_first_entry',
                 'key_ref_to_ptr',
                 # skip special function
                 'posix_acl_from_xattr',
                 'skb_gso_segment',
                 'd_hash_and_lookup']

    _fix_table = {"clk_get": "IS_ERR",
                  "dma_buf_attach": "IS_ERR",
                  "platform_device_register_resndata": "IS_ERR",
                  "syscon_node_to_regmap": "IS_ERR",
                  "clk_get_parent": "NULL",
                  "container_of": "NULL",
                  "devm_request_and_ioremap": "NULL",
                  "scsi_host_lookup": "NULL",
                  "ubifs_fast_find_freeable": "NULL",
                  "ubifs_fast_find_frdi_idx": "NULL",
                  "btrfs_get_acl": "IS_ERR_OR_NULL",
                  "btrfs_lookup_xattr": "IS_ERR_OR_NULL",
                  "ext2_get_acl": "IS_ERR_OR_NULL",
                  "ext3_get_acl": "IS_ERR_OR_NULL",
                  "ext4_get_acl": "IS_ERR_OR_NULL",
                  "f2fs_get_acl": "IS_ERR_OR_NULL",
                  "flow_cache_lookup": "IS_ERR_OR_NULL",
                  "gfs2_get_acl": "IS_ERR_OR_NULL",
                  "gfs2_lookupi": "IS_ERR_OR_NULL",
                  "hfsplus_get_posix_acl": "IS_ERR_OR_NULL",
                  "jffs2_get_acl": "IS_ERR_OR_NULL",
                  "jfs_get_acl": "IS_ERR_OR_NULL",
                  "nfs3_proc_getacl": "IS_ERR_OR_NULL",
                  "posix_acl_from_xattr": "IS_ERR_OR_NULL",
                  "reiserfs_get_acl": "IS_ERR_OR_NULL",
                  "xfs_get_acl": "IS_ERR_OR_NULL",}

    if not os.path.exists(DATAFILE):
        sfiles = _execute_shell("find %s -type f" % kdir)[0:-1]
        count = 0
        fp = open(DATAFILE, "w")
        for sfile in sfiles:
            if not is_source_file(sfile):
                continue
            if count > 0 and count % 100 == 0:
                print 'total: %d, current: %d' % (count, len(sfiles))
            count += 1
            sargs = '/usr/bin/spatch -I %s -timeout 20 -very_quiet -sp_file %s %s | sort -u' % (
                        os.path.join(kdir, 'include'), SCRIPTFILE, sfile)
            lines = []
            for line in _execute_shell(sargs):
                if line.find('|') == -1:
                    continue
                #if not re.search('\w+', line):
                #    continue
                #if lines.count(line) != 0:
                #    continue
                if line in skip_list:
                    continue
                lines.append("%s|%s" % (line, sfile))

            if len(lines):
                fp.write('\n'.join(lines))
                fp.write('\n')
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    # merge data
    mlines = []
    lastfile = None
    mfuncs = {}
    for line in lines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if a[1] == 'IS_ERR_OR_NULL':
            continue
        if lastfile != a[2]:
            for fun in mfuncs.keys():
                mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))
            mfuncs.clear()
            lastfile = a[2]
        if mfuncs.has_key(a[0]) and mfuncs[a[0]] != a[1]:
            #print 'fix for function: %s in file %s' %(a[0], a[2])
            mfuncs[a[0]] = 'IS_ERR_OR_NULL'
        else:
            mfuncs[a[0]] = a[1]
    if not lastfile is None:
        for fun in mfuncs.keys():
            mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))

    funcs = {}
    for line in mlines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if funcs.has_key(a[0]):
            funcs[a[0]]['cnt'] += 1
            if funcs[a[0]]['type'] != a[1]:
                if a[1] == 'IS_ERR_OR_NULL':
                    #print "WARN: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], funcs[a[0]]['type'], a[2])
                    continue 
                if a[0].find('debugfs_') == 0 and not is_config_debug_fs(a[2]):
                    continue
                print "ERROR: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], funcs[a[0]]['type'], a[2])
        else:
            if _fix_table.has_key(a[0]):
                if _fix_table[a[0]] != a[1]:
                    if a[1] == 'IS_ERR_OR_NULL':
                        #print "WARN: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], _fix_table[a[0]], a[2])
                        continue 
                    if a[0].find('debugfs_') == 0 and not is_config_debug_fs(a[2]):
                        continue
                    print "ERROR: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], _fix_table[a[0]], a[2])
                    funcs[a[0]] = {'type': _fix_table[a[0]], 'cnt': 1}
                else:
                    funcs[a[0]] = {'type': a[1], 'cnt': 1}
            else:
                funcs[a[0]] = {'type': a[1], 'cnt': 1}

    if not os.path.exists(ERRFILE):
        tmps = []
        for fn in funcs.keys():
            if funcs[fn]['type'] != 'IS_ERR':
                continue
            tmps.append("%s|%s|%s" % (fn, funcs[fn]['type'], funcs[fn]['cnt']))
     
        fp = open(ERRFILE, "w")
        fp.write("// Update: %s\n" % datetime.datetime.now())
        fp.write('\n'.join(tmps))
        fp.close()
   
    if not os.path.exists(NULLFILE):
        tmps = []
        for fn in funcs.keys():
            if funcs[fn]['type'] != 'NULL' or funcs[fn]['cnt'] < 2:
                continue
            tmps.append("%s|%s|%s" % (fn, funcs[fn]['type'], funcs[fn]['cnt']))
    
        fp = open(NULLFILE, "w")
        fp.write("// Update: %s\n" % datetime.datetime.now())
        fp.write('\n'.join(tmps))
        fp.close()

    return 0
def main(args):
    kdir = '/var/lib/dpatch/repo/2/linux-next'

    skip_list = [
        'malloc',
        'readb',
         'xchg',
         'PDE_DATA',
         'ioread32',
         'in_be32',
         'nv_ro16',
         'be32_to_cpu',
         'le32_to_cpu',
         'le64_to_cpu',
         'min',
         'min_t',
         'inl',
         'inb',
         'container_of',
         'ERR_CAST',
         'ERR_PTR',
         'list_entry',
         'list_first_entry',
         'key_ref_to_ptr',
         # skip special function
         'posix_acl_from_xattr',
         'skb_gso_segment',
         'd_hash_and_lookup',
         'rcu_dereference',
         'rcu_dereference_protected',
         'dget_parent',
         'get_acl',
         'netdev_priv',
         'ext4_bread',
         '__d_path',
         'i_size_read',
         '__skb_gso_segment',
         'dget',
         'map_extent_mft_record',
         'gfs2_lookupi',
         'fat_build_inode'
    ]

    _fix_table = {
        "clk_get": "IS_ERR",
        "dma_buf_attach": "IS_ERR",
        "platform_device_register_resndata": "IS_ERR",
        "syscon_node_to_regmap": "IS_ERR",
        "clk_get_parent": "NULL",
        "container_of": "NULL",
        "devm_request_and_ioremap": "NULL",
        "scsi_host_lookup": "NULL",
        "ubifs_fast_find_freeable": "NULL",
        "ubifs_fast_find_frdi_idx": "NULL",
        "btrfs_get_acl": "IS_ERR_OR_NULL",
        "btrfs_lookup_xattr": "IS_ERR_OR_NULL",
        "dma_buf_map_attachment": "IS_ERR",
        "ext2_get_acl": "IS_ERR_OR_NULL",
        "ext3_get_acl": "IS_ERR_OR_NULL",
        "ext4_get_acl": "IS_ERR_OR_NULL",
        "f2fs_get_acl": "IS_ERR_OR_NULL",
        "flow_cache_lookup": "IS_ERR_OR_NULL",
        "follow_page_mask": "IS_ERR_OR_NULL",
        "gfs2_get_acl": "IS_ERR_OR_NULL",
        "gfs2_lookupi": "IS_ERR_OR_NULL",
        "get_phy_device": "IS_ERR",
        "hfsplus_get_posix_acl": "IS_ERR_OR_NULL",
        "jffs2_get_acl": "IS_ERR_OR_NULL",
        "jfs_get_acl": "IS_ERR_OR_NULL",
        "nfs3_proc_getacl": "IS_ERR_OR_NULL",
        "posix_acl_from_xattr": "IS_ERR_OR_NULL",
        "reiserfs_get_acl": "IS_ERR_OR_NULL",
        "xfs_get_acl": "IS_ERR_OR_NULL",
        "pci_device_group": "IS_ERR_OR_NULL",
        "assoc_array_delete": "IS_ERR_OR_NULL",
        "d_splice_alias": "IS_ERR_OR_NULL"
    }

    if not os.path.exists(DATAFILE):
        sfiles = _execute_shell("find %s -type f" % kdir)[0:-1]
        count = 0
        fp = open(DATAFILE, "w")
        for sfile in sfiles:
            if not is_source_file(sfile):
                continue
            if sfile.find("Documentation/") == 0:
                continue
            if sfile.find("scripts/") == 0:
                continue
            if sfile.find("tools/") == 0:
                continue
            if sfile.find("firmware/") == 0:
                continue
            if count > 0 and count % 100 == 0:
                print 'current: %d, total: %d' % (count, len(sfiles))
            count += 1
            sargs = '/usr/bin/spatch -I %s -timeout 20 -very_quiet -sp_file %s %s | sort -u' % (
                        os.path.join(kdir, 'include'), SCRIPTFILE, sfile)
            lines = []
            for line in _execute_shell(sargs):
                if line.find('|') == -1:
                    continue
                #if not re.search('\w+', line):
                #    continue
                #if lines.count(line) != 0:
                #    continue
                if line in skip_list:
                    continue
                lines.append("%s|%s" % (line, sfile))

            if len(lines):
                fp.write('\n'.join(lines))
                fp.write('\n')
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    # merge data
    mlines = []
    lastfile = None
    mfuncs = {}
    for line in lines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if a[1] == 'IS_ERR_OR_NULL':
            continue
        if lastfile != a[2]:
            for fun in mfuncs.keys():
                mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))
            mfuncs.clear()
            lastfile = a[2]
        if mfuncs.has_key(a[0]) and mfuncs[a[0]] != a[1]:
            #print 'fix for function: %s in file %s' %(a[0], a[2])
            mfuncs[a[0]] = 'IS_ERR_OR_NULL'
        else:
            mfuncs[a[0]] = a[1]
    if not lastfile is None:
        for fun in mfuncs.keys():
            mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))

    mfuncs = {}
    for line in mlines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if not mfuncs.has_key(a[0]):
            mfuncs[a[0]] = {'TYPE': 'NULL', 'COUNT': 0, 'NULL': 0, 'IS_ERR': 0, 'IS_ERR_OR_NULL': 0}
        mfuncs[a[0]][a[1]] = mfuncs[a[0]][a[1]] + 1
        mfuncs[a[0]]['COUNT'] = mfuncs[a[0]]['COUNT'] + 1

        if _fix_table.has_key(a[0]):
            mfuncs[a[0]]['TYPE'] = _fix_table[a[0]]
        else:
            if mfuncs[a[0]]['NULL'] > mfuncs[a[0]]['IS_ERR']:
                if mfuncs[a[0]]['NULL'] > mfuncs[a[0]]['IS_ERR_OR_NULL']:
                    mfuncs[a[0]]['TYPE'] = 'NULL'
                else:
                    mfuncs[a[0]]['TYPE'] = 'IS_ERR_OR_NULL'
            else:
                if mfuncs[a[0]]['IS_ERR'] > mfuncs[a[0]]['IS_ERR_OR_NULL']:
                    mfuncs[a[0]]['TYPE'] = 'IS_ERR'
                else:
                    mfuncs[a[0]]['TYPE'] = 'IS_ERR_OR_NULL'

    for line in lines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if a[1] == 'IS_ERR_OR_NULL':
            continue
        if a[0].find('debugfs_') == 0: #and not is_config_debug_fs(a[2]):
            continue
        if mfuncs[a[0]]['TYPE'] != a[1] and mfuncs[a[0]]['IS_ERR'] != mfuncs[a[0]]['NULL'] and mfuncs[a[0]]['COUNT'] > 1:
            print "ERROR: %s, type: %s, real type: %s, file: %s, NULL: %d, IS_ERR:%d, IS_ERR_OR_NULL: %d" % (a[0],
                    a[1], mfuncs[a[0]]['TYPE'], a[2], mfuncs[a[0]]['NULL'], mfuncs[a[0]]['IS_ERR'], mfuncs[a[0]]['IS_ERR_OR_NULL'])

    update_err_ptr_ret_chk(mfuncs)
    update_null_ret_chk(mfuncs)

    #print json.dumps(mfuncs, indent = 4)

    '''
    # merge data
    mlines = []
    lastfile = None
    mfuncs = {}
    for line in lines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if a[1] == 'IS_ERR_OR_NULL':
            continue
        if lastfile != a[2]:
            for fun in mfuncs.keys():
                mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))
            mfuncs.clear()
            lastfile = a[2]
        if mfuncs.has_key(a[0]) and mfuncs[a[0]] != a[1]:
            #print 'fix for function: %s in file %s' %(a[0], a[2])
            mfuncs[a[0]] = 'IS_ERR_OR_NULL'
        else:
            mfuncs[a[0]] = a[1]
    if not lastfile is None:
        for fun in mfuncs.keys():
            mlines.append("%s|%s|%s" % (fun, mfuncs[fun], lastfile))

    funcs = {}
    for line in mlines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        a = line.split('|')
        if len(a) < 3:
            continue
        if a[0] in skip_list:
            continue
        if funcs.has_key(a[0]):
            funcs[a[0]]['cnt'] += 1
            if funcs[a[0]]['type'] != a[1]:
                if a[1] == 'IS_ERR_OR_NULL':
                    #print "WARN: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], funcs[a[0]]['type'], a[2])
                    continue 
                if a[0].find('debugfs_') == 0 and not is_config_debug_fs(a[2]):
                    continue
                print "ERROR: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], funcs[a[0]]['type'], a[2])
        else:
            if _fix_table.has_key(a[0]):
                if _fix_table[a[0]] != a[1]:
                    if a[1] == 'IS_ERR_OR_NULL':
                        #print "WARN: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], _fix_table[a[0]], a[2])
                        continue 
                    if a[0].find('debugfs_') == 0 and not is_config_debug_fs(a[2]):
                        continue
                    print "ERROR: %s, type: %s, real type: %s, file: %s" % (a[0], a[1], _fix_table[a[0]], a[2])
                    funcs[a[0]] = {'type': _fix_table[a[0]], 'cnt': 1}
                else:
                    funcs[a[0]] = {'type': a[1], 'cnt': 1}
            else:
                funcs[a[0]] = {'type': a[1], 'cnt': 1}

    if not os.path.exists(ERRFILE):
        tmps = []
        for fn in funcs.keys():
            if funcs[fn]['type'] != 'IS_ERR':
                continue
            tmps.append("%s|%s|%s" % (fn, funcs[fn]['type'], funcs[fn]['cnt']))
     
        fp = open(ERRFILE, "w")
        fp.write("// Update: %s\n" % datetime.datetime.now())
        fp.write('\n'.join(tmps))
        fp.close()
   
    if not os.path.exists(NULLFILE):
        tmps = []
        for fn in funcs.keys():
            if funcs[fn]['type'] != 'NULL' or funcs[fn]['cnt'] < 2:
                continue
            tmps.append("%s|%s|%s" % (fn, funcs[fn]['type'], funcs[fn]['cnt']))
    
        fp = open(NULLFILE, "w")
        fp.write("// Update: %s\n" % datetime.datetime.now())
        fp.write('\n'.join(tmps))
        fp.close()
    '''
    return 0
def main(args):

    kdir = "/var/lib/dpatch/repo/linux-next/drivers/"

    if not os.path.exists(DATAFILE):
        lines = []
        sfiles = _execute_shell("find %s -type f" % kdir)[0:-1]
        count = 0
        for sfile in sfiles:
            if not is_source_file(sfile):
                continue
            if count > 0 and count % 100 == 0:
                print "total: %d, current: %d" % (count, len(sfiles))
            count += 1
            sargs = "/usr/bin/spatch -I %s -timeout 30 -very_quiet -sp_file %s %s" % (
                os.path.join(kdir, "include"),
                SCRIPTFILE,
                sfile,
            )
            for line in _execute_shell(sargs):
                if line.find("|") == -1:
                    continue
                a = line.split("|")
                if len(a) < 2:
                    continue
                lines.append(line)
        fp = open(DATAFILE, "w")
        fp.write("\n".join(lines))
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    print "@[email protected]\n\
declarer name module_init;\n\
identifier fn_init;\n\
@@\n\
module_init(fn_init);\n\
\n\
@[email protected]\n\
declarer name module_exit;\n\
identifier fn_exit;\n\
@@\n\
module_exit(fn_exit);\n\
\n\
@[email protected]\n\
declarer name module_acpi_driver;\n\
declarer name module_comedi_pcmcia_driver;\n\
declarer name module_pci_driver;\n\
declarer name module_usb_driver;\n\
declarer name module_comedi_usb_driver;\n\
declarer name module_platform_driver;\n\
declarer name module_virtio_driver;\n\
declarer name module_amba_driver;\n\
declarer name module_gameport_driver;\n\
declarer name module_platform_driver_probe;\n\
declarer name module_comedi_driver;\n\
declarer name module_hid_driver;\n\
declarer name module_serio_driver;\n\
declarer name module_comedi_pci_driver;\n\
declarer name module_i2c_driver;\n\
declarer name module_spi_driver;\n\
identifier i_driver;\n\
@@\n\
(\n\
module_acpi_driver(i_driver);\n\
|\n\
module_comedi_pcmcia_driver(i_driver);\n\
|\n\
module_pci_driver(i_driver);\n\
|\n\
module_usb_driver(i_driver);\n\
|\n\
module_comedi_usb_driver(i_driver);\n\
|\n\
module_platform_driver(i_driver);\n\
|\n\
module_virtio_driver(i_driver);\n\
|\n\
module_amba_driver(i_driver);\n\
|\n\
module_gameport_driver(i_driver);\n\
|\n\
module_platform_driver_probe(i_driver);\n\
|\n\
module_comedi_driver(i_driver);\n\
|\n\
module_hid_driver(i_driver);\n\
|\n\
module_serio_driver(i_driver);\n\
|\n\
module_comedi_pci_driver(i_driver);\n\
|\n\
module_i2c_driver(i_driver);\n\
|\n\
module_spi_driver(i_driver);\n\
)\n\n"

    skiplist = [
        "snd_soc_card",  # special
        "dvb_usb_device_properties",
        "hotplug_slot_ops",
        "i2c_driver",
        "pci_driver",
        "usb_driver",
        "platform_driver",
        "gameport_driver",
        "scsi_host_template",
        "file_operations",
    ]
    for line in lines:
        if line.find("|") == -1:
            continue
        line = line.replace("\n", "")
        a = line.split("|")
        if skiplist.count(a[0]) != 0:
            continue
        if len(a) == 3:
            print "\
@r1__%s depends on (r1 && r2) || [email protected]\n\
identifier nm;\n\
position p;\n\
@@\n\
struct %s [email protected] = {\n\
...,\n\
  .%s = {\n\
    ...,\n\
    .%s = THIS_MODULE,\n\
    ...\n\
   },\n\
...\n\
};\n\
\n\
@r2__%s depends on (r1 && r2) || [email protected]\n\
identifier nm;\n\
position p;\n\
@@\n\
struct %s [email protected] = {\n\
...,\n\
  .%s.%s = THIS_MODULE,\n\
...\n\
};\n\
\n\
@depends on (r1 && r2) || [email protected]\n\
identifier nm;\n\
position p != {r1__%s.p, r2__%s.p};\n\
@@\n\
(\n\
struct %s [email protected] = {\n\
...,\n\
  .%s = {\n\
    ...,\n\
+   .%s = THIS_MODULE,\n\
   },\n\
...\n\
};\n\
|\n\
struct %s [email protected] = {\n\
...,\n\
+  .%s.%s = THIS_MODULE,\n\
};\n)\n\
" % (
                a[0],
                a[0],
                a[1],
                a[2],
                a[0],
                a[0],
                a[1],
                a[2],
                a[0],
                a[0],
                a[0],
                a[1],
                a[2],
                a[0],
                a[1],
                a[2],
            )
        else:
            print "\
@r__%s depends on (r1 && r2) || [email protected]\n\
identifier nm;\n\
position p;\n\
@@\n\
struct %s [email protected] = {\n\
...,\n\
  .%s = THIS_MODULE,\n\
...\n\
};\n\
\n\
@depends on (r1 && r2) || [email protected]\n\
identifier nm;\n\
position p != {r__%s.p};\n\
@@\n\
struct %s [email protected] = {\n\
...,\n\
+ .%s = THIS_MODULE,\n\
};\n" % (
                a[0],
                a[0],
                a[1],
                a[0],
                a[0],
                a[1],
            )

    return 0
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next'

    print '/// fix return value check in {{function}}\n\
///\n\
/// In case of error, the function XXXX() returns ERR_PTR()\n\
/// and never returns NULL. The NULL test in the return value check\n\
/// should be replaced with IS_ERR().\n\
///\n'

    skiplist = ['rfkill_alloc', 'clk_get', 'clk_register', 'clk_register_fixed_rate',
                'rpcauth_create', 'vb2_dma_contig_init_ctx', 'of_clk_get',
                'arm_iommu_create_mapping', 'devm_regulator_get',
                'platform_device_register_full', 'anon_inode_getfile',
                'of_clk_get_by_name', 'sock_alloc_file', 'skb_mac_gso_segment',
                'get_fb_info', 'unpack_dfa', 'select_bad_process', 'perf_init_event',
                'debugfs_rename']

    if not os.path.exists(DATAFILE):
        lines = []
        for sfile in _execute_shell("find %s -type f" % kdir)[0:-1]:
            if not is_source_file(sfile):
                continue
            sargs = '/usr/bin/spatch -I %s -timeout 60 -very_quiet -sp_file %s %s' % (
                            os.path.join(kdir, 'include'), SCRIPTFILE, sfile)
            for line in _execute_shell(sargs):
                if not re.search('\w+', line):
                    continue
                if lines.count(line) != 0:
                    continue
                if line in skiplist:
                    continue
                if line.find('debugfs_create') != -1:
                    continue
                lines.append(line)
        fp = open(DATAFILE, "w")
        fp.write('\n'.join(lines))
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    funcs = []
    for line in lines:
        line = line.replace('\n', '')
        if line.find('//') != -1:
            continue
        if line.find('|') != -1:
            line = line.split('|')[0]
        if line in skiplist:
            continue
        funcs.append(line)

    print '@@\n\
expression ret, E;\n\
@@\n\
ret = \(%s\)(...);\n\
... when != ret = E\n\
(\n\
- ret == NULL || IS_ERR(ret)\n\
+ IS_ERR(ret)\n\
|\n\
- IS_ERR(ret) || ret == NULL\n\
+ IS_ERR(ret)\n\
|\n\
- ret != NULL && !IS_ERR(ret)\n\
+ !IS_ERR(ret)\n\
|\n\
- !IS_ERR(ret) && ret != NULL\n\
+ !IS_ERR(ret)\n\
|\n\
- ret == NULL\n\
+ IS_ERR(ret)\n\
|\n\
- ret != NULL\n\
+ !IS_ERR(ret)\n\
)\n' % '\|\n'.join(funcs)

    return 0
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next'

    print '/// fix return value check in {{function}}\n\
///\n\
/// In case of error, the function XXXX() returns NULL pointer\n\
/// not ERR_PTR(). The IS_ERR() test in the return value check\n\
/// should be replaced with NULL test.\n\
///\n'

    skip_list = []

    if not os.path.exists(DATAFILE):
        lines = []
        sfiles = _execute_shell("find %s -type f" % kdir)[0:-1]
        count = 0
        for sfile in sfiles:
            if not is_source_file(sfile):
                continue
            if count > 0 and count % 100 == 0:
                print 'total: %d, current: %d' % (count, len(sfiles))
            count += 1
            sargs = '/usr/bin/spatch -I %s -timeout 60 -very_quiet -sp_file %s %s' % (
                        os.path.join(kdir, 'include'), SCRIPTFILE, sfile)
            for line in _execute_shell(sargs):
                if not re.search('\w+', line):
                    continue
                if lines.count(line) != 0:
                    continue
                if line in skip_list:
                    continue
                lines.append(line)
        fp = open(DATAFILE, "w")
        fp.write('\n'.join(lines))
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    funcs = []
    for line in lines:
        line = line.replace('\n', '')
        if line.find('//') != -1:
            continue
        if line.find('|') != -1:
            line = line.split('|')[0]
        if line in skip_list:
            continue
        funcs.append(line)

    print '@@\n\
expression ret, E;\n\
@@\n\
ret = \(%s\)(...);\n\
... when != ret = E\n\
(\n\
- IS_ERR(ret)\n\
+ !ret\n\
|\n\
- !IS_ERR(ret)\n\
+ ret\n\
)\n' % '\|\n'.join(funcs)

    return 0
def main(args):
    kdir = '/var/lib/dpatch/repo/linux-next/drivers/'

    if not os.path.exists(DATAFILE):
        lines = []
        sfiles = _execute_shell("find %s -type f" % kdir)[0:-1]
        count = 0
        for sfile in sfiles:
            if not is_source_file(sfile):
                continue
            if count > 0 and count % 100 == 0:
                print 'total: %d, current: %d' % (count, len(sfiles))
            count += 1
            sargs = '/usr/bin/spatch -I %s -timeout 30 -very_quiet -sp_file %s %s' % (
                            os.path.join(kdir, 'include'), SCRIPTFILE, sfile)
            afuncs = []
            bfuncs = []
            funcinfo = {}
            tfuncinfo = {}
            for line in _execute_shell(sargs):
                if line.find('|') == -1:
                    continue
                a = line.split('|')
                if len(a) < 3:
                    continue
                afuncs.append(a[0])
                bfuncs.append(a[1])
                if afuncs.count(a[0]) > 1:
                    funcinfo[a[0]] = None
                else:
                    funcinfo[a[0]] = a[1]
                    tfuncinfo[a[0]] = a[2]
            for func in funcinfo.keys():
                if funcinfo[func] is None:
                    continue
                if func in ['PTR_RET', 'IS_ERR']:
                    continue
                if afuncs.count(func) > 1:
                    continue
                if bfuncs.count(funcinfo[func]) > 1 and not funcinfo[func] in ['kfree']:
                    continue
                lines.append("%s|%s|%s|%s" % (func, funcinfo[func], tfuncinfo[func], sfile))
                print "%s|%s|%s|%s" % (func, funcinfo[func], tfuncinfo[func], sfile)
        fp = open(DATAFILE, "w")
        fp.write('\n'.join(lines))
        fp.close()

    fp = open(DATAFILE, "r")
    lines = fp.readlines()
    fp.close()

    print '/// add missing {{function1}} on error path in {{function}}\n\
///\n\
/// Add the missing {{function1}} before return from\n\
/// {{function}} in the error handling case.\n'

    fixlist = {
        'lpfc_sli4_rb_alloc': 'lpfc_sli4_rb_free',
        'lpfc_els_hbq_alloc': 'lpfc_els_hbq_free',
        'init_bch': 'free_bch',
        'usb_create_hcd': 'usb_create_hcd',
        'scsi_host_alloc': 'scsi_host_put'
    }
    # skip entry
    _extlist = ['vmalloc|kfree|1',
                'request_mem_region|release_resource|1',
                'device_register|put_device|2',
                'ad7606_reset|ad7606_free_gpios|2',
                'ahci_stop_engine|ahci_start_engine|2',
                'apei_exec_pre_map_gars|apei_exec_post_unmap_gars|2',
                'ast_mm_init|kfree|2',
                'ath10k_hif_power_up|ath10k_hif_power_down|2',
                'ath10k_htt_tx_alloc_msdu_id|ath10k_htt_tx_dec_pending|2',
                'ath10k_pci_wake|ath10k_pci_sleep|2',
                'ath6kl_htc_start|ath6kl_htc_stop|2',
                'ath6kl_wmi_init|ath6kl_wmi_shutdown|1',
                'bch_cache_set_alloc|bch_cache_set_unregister|1',
                'be_chk_reset_complete|beiscsi_unmap_pci_function|2',
                'bnx2fc_send_fw_fcoe_init_msg|bnx2fc_unbind_adapter_devices|2',
                'brcmf_p2p_attach|wl_deinit_priv|2',
                'chp_update_desc|kfree|2',
                'clk_prepare_enable|clk_unprepare|2',
                'CMD_SP|fc_fcp_pkt_release|1',
                'cpia2_init_camera_struct|kfree|1',
                'create_wlan|kfree|1',
                'cryp_check|kfree|2',
                'device_bind_driver|device_unregister|2',
                'device_register|device_del|2',
                'device_register|put_device|2',
                'dgrp_tty_init|kfree|2',
                'dsp_reload|kfree|2',
                'ehea_sense_port_attr|ehea_unregister_port|2',
                'es|ecard_release_resources|2',
                'exynos_drm_gem_init|kfree|1',
                'get_cpu_device|put_cluster_clk_and_freq_table|1',
                'gpio_to_irq|gpio_free|2',
                'hash_check_hw|kfree|2',
                'i1480_mac_fw_upload|i1480_print_state|2',
                'i915_gem_init_hw|i915_gem_cleanup_ringbuffer|2',
                'i915_gem_object_get_pages|i915_gem_object_unpin_pages|2',
                'init_ft1000_netdev|kfree|2',
                'intelfbhw_check_non_crt|cleanup|2',
                'inv_mpu6050_probe_trigger|iio_triggered_buffer_cleanup|2',
                'ioat_dma_setup_interrupts|ioat_disable_interrupts|2',
                'iwl_run_init_ucode|iwl_down|2',
                'ldlm_handle2lock|LDLM_LOCK_PUT|1',
                '_malloc|kfree|1',
                'mantis_pci_init|kfree|2',
                'mdesc_grab|mdesc_release|1',
                'mempool_alloc|fc_exch_hold|1',
                'nand_scan_tail|nand_release|2',
                'NCR_700_detect|scsi_host_put|1',
                'of_device_alloc|platform_device_put|1',
                'pch_gbe_hal_read_mac_addr|pch_gbe_hal_phy_hw_reset|2',
                'pci_alloc_dev|pci_stop_and_remove_bus_device|1',
                'pcibios_add_platform_entries|pci_remove_resource_files|2',
                'pci_create_sysfs_dev_files|pci_dev_put|2',
                'pci_get_domain_bus_and_slot|pci_dev_put|1',
                'pcmcia_request_io|pcmcia_disable_device|2',
                'pm_runtime_get_sync|pm_runtime_disable|2',
                'ptlrpc_queue_wait|ptlrpc_req_finished|2',
                'pwc_init_controls|kfree|2',
                'qlcnic_83xx_enable_flash_write|qlcnic_83xx_unlock_flash|2',
                'r600_parse_extended_power_table|ci_dpm_fini|2',
                'radeon_dummy_page_init|radeon_gart_fini|2',
                'register_sja1000dev|free_sja1000dev|2',
                'rsxx_creg_setup|kfree|2',
                's3c_camif_create_subdev|s3c_camif_unregister_subdev|2',
                's3c_camif_create_subdev|s3c_camif_unregister_subdev|2',
                'sas_end_device_alloc|sas_rphy_free|1',
                'sas_port_add|sas_port_mark_backlink|2',
                'sdhci_add_host|sdhci_bcm_kona_sd_reset|2',
                'setup_fritz|kfree|2',
                'skb_unshare|kfree_skb|1',
                'snd_cx18_pcm_create|kfree|2',
                'snd_ivtv_pcm_create|kfree|2',
                'st5481_setup_b|st5481_release_b|2',
                'stk1160_vb2_setup|kfree|2',
                't4_l2t_alloc_switching|cxgb4_l2t_release|1',
                't4_prep_adapter|kfree|2',
                'ubi_wl_get_peb|ubi_ro_mode|2',
                'usb_create_hcd|kfree|1',
                'usb_phy_init|usb_phy_shutdown|2',
                'vb2_queue_init|kfree|2',
                'wl1251_ps_elp_wakeup|wl1251_ps_elp_sleep|2',
                'wl1271_ps_elp_wakeup|wl1271_ps_elp_sleep|2',
                'xhci_halt|kfree|2',
                'xhci_reset|kfree|2',
                'xillybus_init_endpoint|kfree|1',
      ]
    # skip alloc or release
    skiplist = ['alloc_etherdev',
                'cdev_alloc',
                'clk_disable_unprepare',
                'clk_put',
                'csio_get_scsi_ioreq_lock',
                'destroy_workqueue',
                'drm_fb_helper_fini',
                'free',
                'free_netdev',
                'hid_add_device',
                'hid_parse',
                'i915_gem_init_hw',
                'i915_gem_object_unpin',
                'iounmap',
                'IS_ERR',
                'KMEM_CACHE',
                'lpfc_selective_reset',
                'misc_deregister',
                'pci_disable_device',
                'pcmcia_enable_device',
                'platform_device_del',
                'platform_device_unregister',
                'platform_driver_unregister',
                'platform_device_put',
                'platform_get_resource',
                's5p_mfc_reset',
                'spi_get_ctldata',
                'uart_unregister_driver',
                'ubi_dump_vid_hdr',
                'udl_gem_alloc_object',
                'vfree',
                'videobuf_alloc_vb',
                'videobuf_sg_alloc',
                'vzalloc' ]

    funcs = {}
    # prepare data
    for line in lines:
        if line.find('|') == -1:
            continue
        line = line.replace('\n', '')
        if line in _extlist:
            continue
        a = line.split('|')
        if skiplist.count(a[0]) != 0:
            continue
        if skiplist.count(a[1]) != 0:
            continue
        if len(a) < 3:
            continue
        if "%s|%s|%s" % (a[0], a[1], a[2]) in _extlist:
            continue
        if len(a[0]) < 1:
            continue
        if funcs.has_key(a[0]):
            if funcs[a[0]]['key'] != a[2]:
                #print "wrong key: %s|%s|%s|%s" % (a[0], a[1], a[2], a[3])
                continue
            if funcs[a[0]]['func'].count(a[1]) == 0:
                funcs[a[0]]['func'].append(a[1])
        else:
            if fixlist.has_key(a[0]):
                funcs[a[0]] = {'key': a[2], 'func': [fixlist[a[0]]]}
                if funcs[a[0]]['func'].count(a[1]) == 0:
                    funcs[a[0]]['func'].append(a[1])
            else:
                funcs[a[0]] = {'key': a[2], 'func': [a[1]]}

    # write script
    for _func in funcs.keys():
        _release = funcs[_func]['func'][0]
        if funcs[_func]['key'] == '1':
            continue
            print '\
@r1__%s [email protected]\n\
expression nm;\n\
expression E != {0};\n\
statement S;\n\
position p1, p2;\n\
@@\n\
 nm = %s(...);\n\
 if (nm == NULL) S\n\
  ... when != %s(nm)\n\
 [email protected] (...) {\n\
   ... when != %s(nm)' % (_func, _func, _release, _release)
            for _ref in funcs[_func]['func'][1:]:
                print '       when != %s(nm)' % _ref
            print '       when forall\n\
   [email protected] E;\n\
  }\n\
\n\
@depends on r1__%[email protected]\n\
expression r1__%s.nm, r1__%s.E;\n\
position r1__%s.p2;\n\
@@\n\
+ %s(nm);\n\
  [email protected] E;\n\
' % (_func, _func, _func, _func, _release)

        elif funcs[_func]['key'] == '2':
            print '\
@r1__%s [email protected]\n\
expression ret, nm;\n\
expression E != {0};\n\
statement S;\n\
position p1, p2;\n\
@@\n\
 ret = %s(nm);\n\
 if (\(ret < 0\|ret != 0\)) S\n\
  ... when != %s(nm)\n\
 [email protected] (...) {\n\
   ... when != %s(nm)' % (_func, _func, _release, _release)
            for _ref in funcs[_func]['func'][1:]:
                print '       when != %s(nm)' % _ref
            print '       when forall\n\
   [email protected] E;\n\
  }\n\
\n\
@depends on r1__%[email protected]\n\
expression r1__%s.nm, r1__%s.E;\n\
position r1__%s.p2;\n\
@@\n\
+ %s(nm);\n\
  [email protected] E;\n\
' % (_func, _func, _func, _func, _release)

    #print json.dumps(funcs, indent=4)
    return 0