Перейти к содержанию

Задачи в пользовательском пространстве

Исходники по этой теме

На прмиере предыдущего задания readelf -h build/asm_example:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x10c0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13984 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30

Entry point address: 0x10c0, это start nm build/asm_example:

...
0000000000001060 T main
                 U __printf_chk@GLIBC_2.3.4
0000000000001120 t register_tm_clones
00000000000010c0 T _start
...

При objdump -d build/asm_example видно, что из _start вычисляется адрес целевого main относительно текущей инструкции регистра и вызывается уже сам main:

...
0000000000001060 <main>:
    1060:       f3 0f 1e fa             endbr64
...

00000000000010c0 <_start>:
...
    10d8:       48 8d 3d 81 ff ff ff    lea    -0x7f(%rip),%rdi        # 1060 <main>
    10df:       ff 15 f3 2e 00 00       call   *0x2ef3(%rip)        # 3fd8 <__libc_start_main@GLIBC_2.34>
...

Статические и динамические библиотеки

Статическая библиотека — это архив (ar) объектных файлов.

Создать статическую библиотеку из объектных файлов и использовать в сборке приложения:

ar rc libfoo_static.a libfoo_static_a.o libfoo_static_b.o
gcc app.o -lfoo_static  -o app

Посмотреть тип библиотеки при помощи утилиты file, просмотреть входящие библиотеки ar -t

$ file libfoo_static.a
libfoo_static.a: current ar archive
$ ar -t libfoo_static.a
libfoo_static_a.o
libfoo_static_b.o

Динамическая библиотека - хранятся отдельно (загружается по запросу или после запуска) и имеет расширение *.so.

Создание разделяемой библиотеки и сборка программы с ней:

gcc -Wall -fPIC -c foo_a.c
gcc -Wall -fPIC -c foo_b.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0   foo_a.o foo_a.b
mv libctest.so.1.0 /opt/lib # перенос в область всех библиотек
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
gcc -Wall -L/opt/lib app.o -lctest -o app

Пример

make clean && make all
./build/userspace_example
my pid: 951085, message from 951084: message from parent
my pid: 951084, message from 951084: message from child

Выполнение задания

Разработать API для работы с логами dbgwrite, dbginit, dbgwrite dbgclose. API должно позволять записывать отладочные сообщения в циклический буфер в разделяемой памятьи (SHM).

Вероятно, имелось ввиду dbgread.

Статический анализ:

cppcheck --enable=all --suppress=missingIncludeSystem .

missingIncludeSystem - отключает проверку зависимых файлов Сборка приложения: make all формирует следующие файлы:

  • libdbg.so - динамическая библиотека, содержащая функции инициализации, чтения и записи в разделенную память dbg_log_shm.

    build/libdbg.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked

  • writer - бинарный файл "писателя" логов.
  • reader - бинарный файл "читателя" логов.

При инициализации писателя создается dbg_log_shm с правами 0666. Подробнее про shm_open.

Запись в кольцевой буфер осуществляется побайтовым заполнением через указатель на область с отраженными данными shm_ptr.

Чтение осуществляется сначала ожиданием сигнала в семафоре через sem_trywait. Если в семафоре появился сигнал - выполняется побайтовое чтение из shm_ptr пока не появится байт \n.

Проверка вызова библиотеки:

ldd build/writer
linux-vdso.so.1 (0x00007ffe7e500000)
libdbg.so => .../build/libdbg.so (0x00007fe1af0d6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe1aeea5000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe1af0e2000)

Также через readelf

readelf -d build/writer

Dynamic section at offset 0x2d78 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libdbg.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...