Ошибка: не удалось вставить модуль. Неизвестный символ в модуле

Я пытаюсь портировать RR0D Rasta Ring0 Debugger с 32-битного Linux на 64-битный Linux. Я преобразовал 32-битную встроенную сборку gcc в 64-битную, используя vim regex, как указано в моем вопросе: Как преобразовать 32-битную встроенную сборку gcc в Linux в 64-битный код?

Я использую GCC с -m64 флаг. Целевая среда - Linux x86-64, версия ядра 3.5.5.

Makefile является следующим:

EXTRA_CFLAGS +=  -O2 -Wall -DLINUX_26 -m64

OBJ          := module_nux.o breakpoint.o buffering.o command.o disasmbak.o idt.o 
OBJ          += keyboard.o page.o video.o utils.o import_symb.o core_rr0d.o pci.o
MODULE       := rr0d.o 

obj-m        := $(MODULE)
rr0d-objs    := $(OBJ)

default:
    make -C /lib/modules/`uname -r`/build/ SUBDIRS=`pwd` modules

clean:
    rm -f  *.o .*.o.cmd .*.ko.cmd *.mod.c  *~ 
    rm -rf .tmp_versions

mrproper:
    make clean
    rm -f *.ko

make дает много предупреждений, таких как warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] а также warning: cast from pointer to integer of different size [-Wpointer-to-int-cast], но это, вероятно, не имеет отношения к теме.

Последние строки вывода make вероятно, важные из них:

/home/user/code/rr0d/0.3/core_rr0d.c: In function ‘cleanup_rr0d’:
/home/user/code/rr0d/0.3/core_rr0d.c:1938:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  CC [M]  /home/user/code/rr0d/0.3/pci.o
  LD [M]  /home/user/code/rr0d/0.3/rr0d.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "RING_HOOO_SEGMENT" [/home/user/code/rr0d/0.3/rr0d.ko] undefined!
  CC      /home/user/code/rr0d/0.3/rr0d.mod.o
  LD [M]  /home/user/code/rr0d/0.3/rr0d.ko
make[1]: Leaving directory `/home/user/code/kernel/linux-3.5.5'

Так, RING_HOOO_SEGMENT не определено

Когда я пытаюсь insmod модуль с insmod ./rr0d.ko как root я получаю:

Error: could not insert module ./rr0d.ko: Unknown symbol in module

Проверка с dmesg | tail -n 1 дает следующий вывод:

[15975.412346] rr0d: Unknown symbol RING_HOOO_SEGMENT (err 0)

Итак, неизвестный символ окончательно RING_HOOO_SEGMENT,

RING_HOOO_SEGMENT константа, созданная с #define в vars.h, что входит в несколько .c файлы с #include "vars.h",

Самое важное #ifdef блок из vars.h с #define RING_HOOO_SEGMENT это один:

#ifdef LINUX_26

#define fake_naked

#if defined(__GNUC__)
// the line below is the important one.
#define RING_HOOO_SEGMENT "$0x7b"
//#define       RING_HOOO_SEGMENT "$0x60"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x7b
#endif

#else /* LINUX_24 */

#define fake_naked _asm_("\t" \
                     "add $0x08, %esp\n\t" \
                     "popl %ebp\n" \
);

#if defined(__GNUC__)
#define RING_HOOO_SEGMENT "$0x18"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x18
#endif

#define RING_HOOO_SEGMENT_VALUE 0x18

#endif /* LINUX_26 */

Очевидно, если #define RING_HOOO_SEGMENT "$0x7b"#if defined(__GNUC__) внутри #ifdef LINUX_26), код не будет компилироваться, поэтому ясно, что RING_HOOO_SEGMENT определяется

Grepping для RING_HOOO_SEGMENT дает следующие совпадения:

$ grep 'RING_HOOO_SEGMENT' *.c *.o *.ko

core_rr0d.c:    "movq RING_HOOO_SEGMENT, %rax\n\t"\
core_rr0d.c:  __asm{    movq RING_HOOO_SEGMENT, %rax}\
Binary file rr0d.ko matches

И то и другое core_rr0d.c ряды встроены в сборку. core_rr0d.c содержит #include "vars.h" так что должно быть хорошо.

Также бинарный модуль rr0d.ko совпадает, поэтому он содержит строку RING_HOOO_SEGMENT (в некоторой форме), даже если insmod ./rr0d.ko не удается с Error: could not insert module ./rr0d.ko: Unknown symbol in module,

Любые идеи, что может быть причиной этой проблемы и как поступить, чтобы иметь возможность insmod модуль?

1 ответ

Решение
core_rr0d.c:    "movq RING_HOOO_SEGMENT, %rax\n\t"\

Здесь RING_HOOO_SEGMENT находится в строке (вероятно, является частью встроенного блока ассемблера). Таким образом, препроцессор не заменит RING_HOOO_SEGMENTи он передается как-есть ассемблеру, где определение RING_HOOO_SEGMENT не доступен.

К счастью, RING_HOOO_SEGMENT сам по себе определяется как строка "$0x7b", поэтому мы можем использовать конкатенацию строк во время компиляции:

"movq " RING_HOOO_SEGMENT ", %rax\n\t"\

Препроцессор заменит RING_HOOO_SEGMENT за "$0x7b"затем GCC объединит эти строки перед передачей ассемблеру.

Другие вопросы по тегам