Можно ли создать общий объект, используя только as и ld? - PullRequest
0 голосов
/ 14 апреля 2019

Мне не удалось найти информацию, подходящую для создания общих объектов в сборке с использованием as и ld.

Я хочу создать общую библиотеку, содержащую некоторые функции с переменными (раздел .data).Но ld не примет опцию -shared, когда в моем коде есть сегмент .data.(перемещение R_X86_64_32S к '.data' не может быть использовано при создании общего объекта; перекомпилируйте с -fPIC).Конечно, должна быть возможность использовать локальные переменные в общем объектном коде, но я не могу найти информацию о том, как это сделать, без компиляции C-кода с опцией -fPIC.

my_lib.s:

.globl print_info

.data
    output:
        .ascii "The processor vendor ID is 'xxxxxxxxxxxx'\n"

.bss

.text
    print_info:
        xor %eax, %eax
        cpuid
        movq $output, %rdi
        movl %ebx, 28(%rdi)
        movl %edx, 32(%rdi)
        movl %ecx, 36(%rdi)
        movl $1, %eax
        movl $1, %edi
        movq $output, %rsi
        movl $42, %edx
        ret
caller.s:

.globl _start

.data

.bss

.text
    _start:
        # some code to load shared library
        # with open() and mmap() syscalls

        subq $8, %rsp         # align stack
        call print_info
        addq $8, %rsp

        # some code here

        movl $60, %eax        # exit program
        xor %edi, %edi
        syscall
as my_lib.s -omy_lib.o
as caller.s -ocaller.o

не выдает ошибок.Однако

ld -shared my_lib.o

представляет:

ld: my_lib.o: relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: nonrepresentable section on output

Вся информация по теме, которую мне удалось найти, использует C-код и gcc для компиляции и компоновки.Кто-нибудь может показать, как это сделать, не кодируя на C и не используя gcc?

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Как отметил выше yugr, разделяемый объект должен быть написан с независимым от позиции кодом. Используя libdl.so для динамической загрузки функции из lib [системные вызовы open () и mmap () должны появиться позже], я получил все это работающее с:

lib.s: 

.globl print_info

.data
    output:
        .ascii "The processor vendor ID is 'xxxxxxxxxxxx'\n"

.bss

.text
    print_info:
        xor %eax, %eax
        cpuid
        leaq output(%rip), %rdi
        movl %ebx, 28(%rdi)
        movl %edx, 32(%rdi)
        movl %ecx, 36(%rdi)
        movl $1, %eax
        movl $1, %edi
        leaq output(%rip), %rsi
        movl $42, %edx
        syscall
        ret
assemble and link with:

as -olib.o lib.s
ld -shared -olib.so lib.o
rm lib.o
caller.s:

.globl _start

.data
    so_name:
        .asciz "./lib.so"
    func_name:
        .asciz "print_info"

.bss
    .lcomm handle, 8
    .lcomm func, 8

.text
    _start:
        movq $so_name, %rdi
        movl $1, %esi        # RTLD_LAZY == 1
        call dlopen

        movq %rax, handle
        movq %rax, %rdi
        movq $func_name, %rsi
        call dlsym

        movq %rax, func      # Not really necessary here, as func is used
                             # immediately and just this once
        call *%rax

        movq handle, %rdi
        call dlclose

        movl $60, %eax
        xorl %edi, %edi
        syscall
assemble and link with:

as -ocaller.o caller.s
ld -dynamic-linker /usr/lib64/ld-linux-x86-64.so.2 -ocaller caller.o -ldl
rm caller.o

Теперь вы можете запустить вызывающую программу с помощью:

./caller

Похоже, что стек правильно выровнен при использовании _start в качестве записи (в отличие от использования main, что, по-видимому, вызывает начальное смещение при нажатии% rbp перед вызовом main = вашей программы), поэтому нет необходимости настраивать с помощью

subq $8, %rsp

до звонка и

addq $8, %rsp

после. По крайней мере, так кажется, но я могу ошибаться в этом вопросе.

0 голосов
/ 14 апреля 2019

Ваша сборка не зависит от позиции.В частности это:

movq $output, %rdi

должно стать

movq $output(%rip), %rdi

В качестве общего рецепта, я предлагаю скомпилировать эквивалентный код в C (с -fPIC), а затем изучить сгенерированный asm длянеобходимые синтаксисы.

...