Fix VTOY_LINUX_REMOUNT option does not work with latest linux kernel version. (#2661 #2674)

pull/1785/merge
longpanda 4 months ago
parent 4527e1db79
commit c7693d4ecd

@ -53,6 +53,9 @@ typedef struct ko_param
unsigned long sym_put_size; unsigned long sym_put_size;
unsigned long kv_major; unsigned long kv_major;
unsigned long ibt; unsigned long ibt;
unsigned long kv_minor;
unsigned long blkdev_get_addr;
unsigned long blkdev_put_addr;
unsigned long padding[1]; unsigned long padding[1];
}ko_param; }ko_param;
@ -150,10 +153,11 @@ static volatile ko_param g_ko_param =
#define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args) #define vdebug(fmt, args...) if(kprintf) kprintf(KERN_ERR fmt, ##args)
static unsigned int g_claim_ptr = 0;
static unsigned char *g_get_patch[MAX_PATCH] = { NULL }; static unsigned char *g_get_patch[MAX_PATCH] = { NULL };
static unsigned char *g_put_patch[MAX_PATCH] = { NULL }; static unsigned char *g_put_patch[MAX_PATCH] = { NULL };
static void notrace dmpatch_restore_code(unsigned char *opCode) static void notrace dmpatch_restore_code(int bytes, unsigned char *opCode, unsigned int code)
{ {
unsigned long align; unsigned long align;
@ -161,7 +165,14 @@ static void notrace dmpatch_restore_code(unsigned char *opCode)
{ {
align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize; align = (unsigned long)opCode / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1); set_mem_rw(align, 1);
*opCode = 0x80; if (bytes == 1)
{
*opCode = (unsigned char)code;
}
else
{
*(unsigned int *)opCode = code;
}
set_mem_ro(align, 1); set_mem_ro(align, 1);
} }
} }
@ -235,6 +246,121 @@ static int notrace dmpatch_replace_code
return 0; return 0;
} }
static unsigned long dmpatch_find_call_offset(unsigned long addr, unsigned long size, unsigned long func)
{
unsigned long i = 0;
unsigned long dest;
unsigned char *opCode = NULL;
unsigned char aucOffset[8] = { 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF };
opCode = (unsigned char *)addr;
for (i = 0; i + 4 < size; i++)
{
if (opCode[i] == 0xE8)
{
aucOffset[0] = opCode[i + 1];
aucOffset[1] = opCode[i + 2];
aucOffset[2] = opCode[i + 3];
aucOffset[3] = opCode[i + 4];
dest = addr + i + 5 + *(unsigned long *)aucOffset;
if (dest == func)
{
return i;
}
}
}
return 0;
}
static unsigned int dmpatch_patch_claim_ptr(void)
{
unsigned long i = 0;
unsigned long t = 0;
unsigned long offset1;
unsigned long offset2;
unsigned long align;
unsigned char *opCode = NULL;
vdebug("Get addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
vdebug("Put addr: 0x%lx %lu 0x%lx\n", g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
opCode = (unsigned char *)g_ko_param.sym_get_addr;
for (i = 0; i < 4; i++)
{
vdebug("%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
opCode[i + 0], opCode[i + 1], opCode[i + 2], opCode[i + 3],
opCode[i + 4], opCode[i + 5], opCode[i + 6], opCode[i + 7],
opCode[i + 8], opCode[i + 9], opCode[i + 10], opCode[i + 11],
opCode[i + 12], opCode[i + 13], opCode[i + 14], opCode[i + 15]);
}
offset1 = dmpatch_find_call_offset(g_ko_param.sym_get_addr, g_ko_param.sym_get_size, g_ko_param.blkdev_get_addr);
offset2 = dmpatch_find_call_offset(g_ko_param.sym_put_addr, g_ko_param.sym_put_size, g_ko_param.blkdev_put_addr);
if (offset1 == 0 || offset2 == 0)
{
vdebug("call blkdev_get or blkdev_put Not found, %lu %lu\n", offset1, offset2);
return 1;
}
vdebug("call addr1:0x%lx call addr2:0x%lx\n",
g_ko_param.sym_get_addr + offset1,
g_ko_param.sym_put_addr + offset2);
opCode = (unsigned char *)g_ko_param.sym_get_addr;
for (i = offset1 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
{
/* rdx */
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc2)
{
g_claim_ptr = *(unsigned int *)(opCode + i + 3);
g_get_patch[0] = opCode + i + 3;
vdebug("claim_ptr(%08X) found at get addr 0x%lx\n", g_claim_ptr, g_ko_param.sym_get_addr + i + 3);
break;
}
}
if (g_claim_ptr == 0)
{
vdebug("Claim_ptr not found in get\n");
return 1;
}
opCode = (unsigned char *)g_ko_param.sym_put_addr;
for (i = offset2 - 1, t = 0; (i > 0) && (t < 24); i--, t++)
{
/* rsi */
if (opCode[i] == 0x48 && opCode[i + 1] == 0xc7 && opCode[i + 2] == 0xc6)
{
if (*(unsigned int *)(opCode + i + 3) == g_claim_ptr)
{
vdebug("claim_ptr found at put addr 0x%lx\n", g_ko_param.sym_put_addr + i + 3);
g_put_patch[0] = opCode + i + 3;
break;
}
}
}
if (g_put_patch[0] == 0)
{
vdebug("Claim_ptr not found in put\n");
return 1;
}
align = (unsigned long)g_get_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
*(unsigned int *)(g_get_patch[0]) = 0;
set_mem_ro(align, 1);
align = (unsigned long)g_put_patch[0] / g_ko_param.pgsize * g_ko_param.pgsize;
set_mem_rw(align, 1);
*(unsigned int *)(g_put_patch[0]) = 0;
set_mem_ro(align, 1);
return 0;
}
#ifdef VTOY_IBT #ifdef VTOY_IBT
static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr) static __always_inline unsigned long long dmpatch_rdmsr(unsigned int msr)
{ {
@ -297,7 +423,8 @@ static int notrace dmpatch_init(void)
kprintf = (printk_pf)(g_ko_param.printk_addr); kprintf = (printk_pf)(g_ko_param.printk_addr);
vdebug("dmpatch_init start pagesize=%lu ...\n", g_ko_param.pgsize); vdebug("dmpatch_init start pagesize=%lu kernel=%lu.%lu ...\n",
g_ko_param.pgsize, g_ko_param.kv_major, g_ko_param.kv_minor);
if (g_ko_param.struct_size != sizeof(ko_param)) if (g_ko_param.struct_size != sizeof(ko_param))
{ {
@ -316,20 +443,27 @@ static int notrace dmpatch_init(void)
reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr; reg_kprobe = (kprobe_reg_pf)g_ko_param.reg_kprobe_addr;
unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr; unreg_kprobe = (kprobe_unreg_pf)g_ko_param.unreg_kprobe_addr;
r = dmpatch_replace_code(1, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device", g_get_patch); if (g_ko_param.kv_major > 6 || (g_ko_param.kv_major == 6 && g_ko_param.kv_minor >= 5))
if (r && g_ko_param.kv_major >= 5)
{ {
vdebug("new2 patch dm_get_table_device...\n"); vdebug("new interface patch dm_get_table_device...\n");
r = dmpatch_replace_code(2, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch); r = dmpatch_patch_claim_ptr();
} }
else
if (r && g_ko_param.kv_major >= 5)
{ {
vdebug("new3 patch dm_get_table_device...\n"); r = dmpatch_replace_code(1, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 2, "dm_get_table_device", g_get_patch);
r = dmpatch_replace_code(3, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch); if (r && g_ko_param.kv_major >= 5)
{
vdebug("new2 patch dm_get_table_device...\n");
r = dmpatch_replace_code(2, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
}
if (r && g_ko_param.kv_major >= 5)
{
vdebug("new3 patch dm_get_table_device...\n");
r = dmpatch_replace_code(3, g_ko_param.sym_get_addr, g_ko_param.sym_get_size, 1, "dm_get_table_device", g_get_patch);
}
} }
if (r) if (r)
{ {
rc = -EINVAL; rc = -EINVAL;
@ -337,7 +471,14 @@ static int notrace dmpatch_init(void)
} }
vdebug("patch dm_get_table_device success\n"); vdebug("patch dm_get_table_device success\n");
r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch); if (g_ko_param.kv_major >= 6 && g_ko_param.kv_minor >= 5)
{
r = 0;
}
else
{
r = dmpatch_replace_code(1, g_ko_param.sym_put_addr, g_ko_param.sym_put_size, 1, "dm_put_table_device", g_put_patch);
}
if (r) if (r)
{ {
rc = -EINVAL; rc = -EINVAL;
@ -369,10 +510,18 @@ static void notrace dmpatch_exit(void)
msr = dmpatch_ibt_save(); msr = dmpatch_ibt_save();
} }
for (i = 0; i < MAX_PATCH; i++) if (g_claim_ptr)
{ {
dmpatch_restore_code(g_get_patch[i]); dmpatch_restore_code(4, g_get_patch[0], g_claim_ptr);
dmpatch_restore_code(g_put_patch[i]); dmpatch_restore_code(4, g_put_patch[0], g_claim_ptr);
}
else
{
for (i = 0; i < MAX_PATCH; i++)
{
dmpatch_restore_code(1, g_get_patch[i], 0x80);
dmpatch_restore_code(1, g_put_patch[i], 0x80);
}
} }
vdebug("dmpatch_exit success\n"); vdebug("dmpatch_exit success\n");

@ -344,6 +344,15 @@ ventoy_dm_patch() {
get_addr=$(echo $vtLine | $AWK '{print $1}') get_addr=$(echo $vtLine | $AWK '{print $1}')
get_size=$(echo $vtLine | $AWK '{print $2}') get_size=$(echo $vtLine | $AWK '{print $2}')
vtLine=$($VTOY_PATH/tool/vtoyksym blkdev_get_by_dev $VTOY_PATH/kallsyms)
vtlog "get blkdev_get_by_dev address $vtLine"
blkdev_get_addr=$(echo $vtLine | $AWK '{print $1}')
vtLine=$($VTOY_PATH/tool/vtoyksym blkdev_put $VTOY_PATH/kallsyms)
vtlog "get blkdev_put address $vtLine"
blkdev_put_addr=$(echo $vtLine | $AWK '{print $1}')
if $GREP -m1 -q 'close_table_device.isra' $VTOY_PATH/kallsyms; then if $GREP -m1 -q 'close_table_device.isra' $VTOY_PATH/kallsyms; then
vtLine=$($VTOY_PATH/tool/vtoyksym close_table_device.isra $VTOY_PATH/kallsyms) vtLine=$($VTOY_PATH/tool/vtoyksym close_table_device.isra $VTOY_PATH/kallsyms)
vtlog "get close_table_device.isra address $vtLine" vtlog "get close_table_device.isra address $vtLine"
@ -383,6 +392,7 @@ ventoy_dm_patch() {
vtlog get_addr=$get_addr get_size=$get_size vtlog get_addr=$get_addr get_size=$get_size
vtlog put_addr=$put_addr put_size=$put_size vtlog put_addr=$put_addr put_size=$put_size
vtlog blkdev_get_addr=$blkdev_get_addr blkdev_put_addr=$blkdev_put_addr
vtlog kprobe_reg_addr=$kprobe_reg_addr kprobe_unreg_addr=$kprobe_unreg_addr vtlog kprobe_reg_addr=$kprobe_reg_addr kprobe_unreg_addr=$kprobe_unreg_addr
vtlog ro_addr=$ro_addr rw_addr=$rw_addr printk_addr=$printk_addr vtlog ro_addr=$ro_addr rw_addr=$rw_addr printk_addr=$printk_addr
@ -397,6 +407,8 @@ ventoy_dm_patch() {
vtKv=$($BUSYBOX_PATH/uname -r) vtKv=$($BUSYBOX_PATH/uname -r)
vtKVMajor=$(echo $vtKv | $AWK -F. '{print $1}')
vtKVMinor=$(echo $vtKv | $AWK -F. '{print $2}')
if [ ! -d /lib/modules/$vtKv ]; then if [ ! -d /lib/modules/$vtKv ]; then
vtlog "No modules directory found" vtlog "No modules directory found"
@ -437,13 +449,18 @@ ventoy_dm_patch() {
#step1: modify vermagic/mod crc/relocation #step1: modify vermagic/mod crc/relocation
vtlog "$VTOY_PATH/tool/vtoykmod -u $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug" vtlog "$VTOY_PATH/tool/vtoykmod -u $vtKVMajor $vtKVMinor $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug"
$VTOY_PATH/tool/vtoykmod -u $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug >>$VTLOG 2>&1 $VTOY_PATH/tool/vtoykmod -u $vtKVMajor $vtKVMinor $VTOY_PATH/tool/$vtKoName $VTOY_PATH/$vtModName $vtDebug >>$VTLOG 2>&1
#step2: fill parameters #step2: fill parameters
vtPgsize=$($VTOY_PATH/tool/vtoyksym -p) vtPgsize=$($VTOY_PATH/tool/vtoyksym -p)
vtlog "$VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtIBT $vtDebug"
$VTOY_PATH/tool/vtoykmod -f $VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKv $vtIBT $vtDebug >>$VTLOG 2>&1 vtPrams="$VTOY_PATH/tool/$vtKoName $vtPgsize 0x$printk_addr 0x$ro_addr 0x$rw_addr $get_addr $get_size $put_addr $put_size 0x$kprobe_reg_addr 0x$kprobe_unreg_addr $vtKVMajor $vtIBT $vtKVMinor $blkdev_get_addr $blkdev_put_addr $vtDebug"
vtlog "$VTOY_PATH/tool/vtoykmod -f $vtPrams"
$VTOY_PATH/tool/vtoykmod -f $vtPrams >>$VTLOG 2>&1
vtlog "insmod $VTOY_PATH/tool/$vtKoName" vtlog "insmod $VTOY_PATH/tool/$vtKoName"
$BUSYBOX_PATH/insmod $VTOY_PATH/tool/$vtKoName >>$VTLOG 2>&1 $BUSYBOX_PATH/insmod $VTOY_PATH/tool/$vtKoName >>$VTLOG 2>&1

@ -188,6 +188,9 @@ typedef struct ko_param
unsigned long sym_put_size; unsigned long sym_put_size;
unsigned long kv_major; unsigned long kv_major;
unsigned long ibt; unsigned long ibt;
unsigned long kv_minor;
unsigned long blkdev_get_addr;
unsigned long blkdev_put_addr;
unsigned long padding[1]; unsigned long padding[1];
}ko_param; }ko_param;
@ -243,7 +246,7 @@ static int vtoykmod_read_file(char *name, char **buf)
return size; return size;
} }
static int vtoykmod_find_section64(char *buf, char *section, int *offset, int *len) static int vtoykmod_find_section64(char *buf, char *section, int *offset, int *len, Elf64_Shdr **shdr)
{ {
uint16_t i; uint16_t i;
int cmplen; int cmplen;
@ -265,6 +268,10 @@ static int vtoykmod_find_section64(char *buf, char *section, int *offset, int *l
{ {
*offset = (int)(sec[i].sh_offset); *offset = (int)(sec[i].sh_offset);
*len = (int)(sec[i].sh_size); *len = (int)(sec[i].sh_size);
if (shdr)
{
*shdr = sec + i;
}
return 0; return 0;
} }
} }
@ -272,7 +279,7 @@ static int vtoykmod_find_section64(char *buf, char *section, int *offset, int *l
return 1; return 1;
} }
static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *len) static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *len, Elf32_Shdr **shdr)
{ {
uint16_t i; uint16_t i;
int cmplen; int cmplen;
@ -294,6 +301,10 @@ static int vtoykmod_find_section32(char *buf, char *section, int *offset, int *l
{ {
*offset = (int)(sec[i].sh_offset); *offset = (int)(sec[i].sh_offset);
*len = (int)(sec[i].sh_size); *len = (int)(sec[i].sh_size);
if (shdr)
{
*shdr = sec + i;
}
return 0; return 0;
} }
} }
@ -411,7 +422,7 @@ static int vtoykmod_update_vermagic(char *oldbuf, int oldsize, char *newbuf, int
return 0; return 0;
} }
int vtoykmod_update(char *oldko, char *newko) int vtoykmod_update(int kvMajor, int kvMinor, char *oldko, char *newko)
{ {
int rc = 0; int rc = 0;
int modver = 0; int modver = 0;
@ -419,6 +430,7 @@ int vtoykmod_update(char *oldko, char *newko)
int newoff, newlen; int newoff, newlen;
int oldsize, newsize; int oldsize, newsize;
char *newbuf, *oldbuf; char *newbuf, *oldbuf;
Elf64_Shdr *sec = NULL;
oldsize = vtoykmod_read_file(oldko, &oldbuf); oldsize = vtoykmod_read_file(oldko, &oldbuf);
newsize = vtoykmod_read_file(newko, &newbuf); newsize = vtoykmod_read_file(newko, &newbuf);
@ -435,13 +447,13 @@ int vtoykmod_update(char *oldko, char *newko)
{ {
if (oldbuf[EI_CLASS] == ELFCLASS64) if (oldbuf[EI_CLASS] == ELFCLASS64)
{ {
rc = vtoykmod_find_section64(oldbuf, "__versions", &oldoff, &oldlen); rc = vtoykmod_find_section64(oldbuf, "__versions", &oldoff, &oldlen, NULL);
rc += vtoykmod_find_section64(newbuf, "__versions", &newoff, &newlen); rc += vtoykmod_find_section64(newbuf, "__versions", &newoff, &newlen, NULL);
} }
else else
{ {
rc = vtoykmod_find_section32(oldbuf, "__versions", &oldoff, &oldlen); rc = vtoykmod_find_section32(oldbuf, "__versions", &oldoff, &oldlen, NULL);
rc += vtoykmod_find_section32(newbuf, "__versions", &newoff, &newlen); rc += vtoykmod_find_section32(newbuf, "__versions", &newoff, &newlen, NULL);
} }
if (rc == 0) if (rc == 0)
@ -459,8 +471,8 @@ int vtoykmod_update(char *oldko, char *newko)
{ {
Elf64_Rela *oldRela, *newRela; Elf64_Rela *oldRela, *newRela;
rc = vtoykmod_find_section64(oldbuf, ".rela.gnu.linkonce.this_module", &oldoff, &oldlen); rc = vtoykmod_find_section64(oldbuf, ".rela.gnu.linkonce.this_module", &oldoff, &oldlen, NULL);
rc += vtoykmod_find_section64(newbuf, ".rela.gnu.linkonce.this_module", &newoff, &newlen); rc += vtoykmod_find_section64(newbuf, ".rela.gnu.linkonce.this_module", &newoff, &newlen, NULL);
if (rc == 0) if (rc == 0)
{ {
oldRela = (Elf64_Rela *)(oldbuf + oldoff); oldRela = (Elf64_Rela *)(oldbuf + oldoff);
@ -478,13 +490,31 @@ int vtoykmod_update(char *oldko, char *newko)
{ {
debug("section .rela.gnu.linkonce.this_module not found\n"); debug("section .rela.gnu.linkonce.this_module not found\n");
} }
if (kvMajor > 6 || (kvMajor == 6 && kvMinor >= 3))
{
rc = vtoykmod_find_section64(oldbuf, ".gnu.linkonce.this_module", &oldoff, &oldlen, &sec);
rc += vtoykmod_find_section64(newbuf, ".gnu.linkonce.this_module", &newoff, &newlen, NULL);
if (rc == 0)
{
debug("section .gnu.linkonce.this_module change oldlen:0x%x to newlen:0x%x\n", oldlen, newlen);
if (sec)
{
sec->sh_size = newlen;
}
}
else
{
debug("section .gnu.linkonce.this_module not found\n");
}
}
} }
else else
{ {
Elf32_Rel *oldRel, *newRel; Elf32_Rel *oldRel, *newRel;
rc = vtoykmod_find_section32(oldbuf, ".rel.gnu.linkonce.this_module", &oldoff, &oldlen); rc = vtoykmod_find_section32(oldbuf, ".rel.gnu.linkonce.this_module", &oldoff, &oldlen, NULL);
rc += vtoykmod_find_section32(newbuf, ".rel.gnu.linkonce.this_module", &newoff, &newlen); rc += vtoykmod_find_section32(newbuf, ".rel.gnu.linkonce.this_module", &newoff, &newlen, NULL);
if (rc == 0) if (rc == 0)
{ {
oldRel = (Elf32_Rel *)(oldbuf + oldoff); oldRel = (Elf32_Rel *)(oldbuf + oldoff);
@ -542,8 +572,11 @@ int vtoykmod_fill_param(char **argv)
param->sym_put_size = strtoul(argv[8], NULL, 10); param->sym_put_size = strtoul(argv[8], NULL, 10);
param->reg_kprobe_addr = strtoul(argv[9], NULL, 16); param->reg_kprobe_addr = strtoul(argv[9], NULL, 16);
param->unreg_kprobe_addr = strtoul(argv[10], NULL, 16); param->unreg_kprobe_addr = strtoul(argv[10], NULL, 16);
param->kv_major = (unsigned long)(argv[11][0] - '0'); param->kv_major = strtoul(argv[11], NULL, 10);
param->ibt = strtoul(argv[12], NULL, 16);; param->ibt = strtoul(argv[12], NULL, 16);;
param->kv_minor = strtoul(argv[13], NULL, 10);
param->blkdev_get_addr = strtoul(argv[14], NULL, 16);
param->blkdev_put_addr = strtoul(argv[15], NULL, 16);
debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]); debug("pgsize=%lu (%s)\n", param->pgsize, argv[1]);
debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]); debug("printk_addr=0x%lx (%s)\n", param->printk_addr, argv[2]);
@ -557,6 +590,9 @@ int vtoykmod_fill_param(char **argv)
debug("unreg_kprobe_addr=0x%lx (%s)\n", param->unreg_kprobe_addr, argv[10]); debug("unreg_kprobe_addr=0x%lx (%s)\n", param->unreg_kprobe_addr, argv[10]);
debug("kv_major=%lu (%s)\n", param->kv_major, argv[11]); debug("kv_major=%lu (%s)\n", param->kv_major, argv[11]);
debug("ibt=0x%lx (%s)\n", param->ibt, argv[12]); debug("ibt=0x%lx (%s)\n", param->ibt, argv[12]);
debug("kv_minor=%lu (%s)\n", param->kv_minor, argv[13]);
debug("blkdev_get_addr=0x%lx (%s)\n", param->blkdev_get_addr, argv[14]);
debug("blkdev_put_addr=0x%lx (%s)\n", param->blkdev_put_addr, argv[15]);
break; break;
} }
@ -596,6 +632,8 @@ static int vtoykmod_check_ibt(void)
int vtoykmod_main(int argc, char **argv) int vtoykmod_main(int argc, char **argv)
{ {
int i; int i;
int kvMajor = 0;
int kvMinor = 0;
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
@ -612,7 +650,9 @@ int vtoykmod_main(int argc, char **argv)
} }
else if (argv[1][0] == '-' && argv[1][1] == 'u') else if (argv[1][0] == '-' && argv[1][1] == 'u')
{ {
return vtoykmod_update(argv[2], argv[3]); kvMajor = (int)strtol(argv[2], NULL, 10);
kvMinor = (int)strtol(argv[3], NULL, 10);
return vtoykmod_update(kvMajor, kvMinor, argv[4], argv[5]);
} }
else if (argv[1][0] == '-' && argv[1][1] == 'I') else if (argv[1][0] == '-' && argv[1][1] == 'I')
{ {

@ -21,6 +21,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -30,10 +31,12 @@ static int verbose = 0;
int vtoyksym_main(int argc, char **argv) int vtoyksym_main(int argc, char **argv)
{ {
int i; int i;
int len = 0;
unsigned long long addr1 = 0; unsigned long long addr1 = 0;
unsigned long long addr2 = 0; unsigned long long addr2 = 0;
char sym[256]; char sym[256];
char line[1024]; char line[1024];
char *start = NULL;
const char *name = NULL; const char *name = NULL;
FILE *fp; FILE *fp;
@ -68,9 +71,11 @@ int vtoyksym_main(int argc, char **argv)
snprintf(sym, sizeof(sym), " %s", argv[1]); snprintf(sym, sizeof(sym), " %s", argv[1]);
debug("lookup for <%s>\n", sym); debug("lookup for <%s>\n", sym);
len = (int)strlen(sym);
while (fgets(line, sizeof(line), fp)) while (fgets(line, sizeof(line), fp))
{ {
if (strstr(line, sym)) start = strstr(line, sym);
if (start && (start > line) && isspace(*(start + len)))
{ {
addr1 = strtoull(line, NULL, 16); addr1 = strtoull(line, NULL, 16);
if (!fgets(line, sizeof(line), fp)) if (!fgets(line, sizeof(line), fp))

Binary file not shown.

Binary file not shown.
Loading…
Cancel
Save