0

I am trying to compile shared file from nasm I am using these commands:

nasm -f elf64 -o asm/asm.o asm/asm.asm
ld -shared -o asm/asm.so asm/asm.o -I/lib64/ld-linux-x86-64.so.2

after second one i got an error:

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

I cant use nasm -fPIC instead -f elf64 because it's invalid command. What should I do if I need .bss section maybe I can compile it in different way?

Here is my assembly code:

DEFAULT                 rel    
%include                "asm/python.inc"
GLOBAL                  PyInit_asm:function

SECTION         .rodata    
l_dubois_name           db "dubois", 0
l_module_name           db "asm", 0

SECTION         .bss
digitSpace resb 100
digitSpacePos resb 8


SECTION                 .data
l_asm_methods:              
ISTRUC PyMethodDef
  at PyMethodDef.ml_name    , dq l_dubois_name
  at PyMethodDef.ml_meth    , dq asm_dubois
  at PyMethodDef.ml_flags   , dq METH_NOARGS
  at PyMethodDef.ml_doc     , dq l_sayit_doc
IEND
NullMethodDef

l_asm_module:                ;; struct PyModuleDef *
ISTRUC PyModuleDef
  at PyModuleDef.m_base     , PyModuleDef_HEAD_INIT
  at PyModuleDef.m_name     , dq l_module_name
  at PyModuleDef.m_doc      , dq NULL
  at PyModuleDef.m_size     , dq -1
  at PyModuleDef.m_methods  , dq l_asm_methods
  at PyModuleDef.m_slots    , dq NULL
  at PyModuleDef.m_traverse , dq NULL
  at PyModuleDef.m_clear    , dq 0
  at PyModuleDef.m_free     , dq NULL
IEND

SECTION                 .text    
asm_dubois: 
    push rbp
    mov rbp, rsp
    mov rax, [rbp+62]
    mov rsp, rbp
    pop rbp
    call  _printRAX
    mov rax, 60
    mov rdi, 0
    syscall
        ret

_printRAX:
    mov rcx, digitSpace
    mov rbx, 10
    mov [rcx], rbx
    inc rcx
    mov [digitSpacePos], rcx

_printRAXLoop:
    mov rdx, 0
    mov rbx, 10
    div rbx
    push rax
    add rdx, 48
    mov rcx, [digitSpacePos]
    mov [rcx], dl
    inc rcx
    mov [digitSpacePos], rcx
    pop rax
    cmp rax, 0
    jne _printRAXLoop

_printRAXLoop2:
    mov rcx, [digitSpacePos]
    mov rax, 1
    mov rdi, 1
    mov rsi, rcx
    mov rdx, 1
    syscall
    mov rcx, [digitSpacePos]
    dec rcx
    mov [digitSpacePos], rcx
    cmp rcx, digitSpace
    jge _printRAXLoop2
    ret

Some random text for stackOverflow to accept mine code

  • 3
    The problem will be in your assembly code. You will need to modify the assembly code to be position independent. If you show us your assembly code then we may be able to help you make the code position independent. – Michael Petch Dec 24 '19 at 15:45
  • I updated post with code from one assembly file – Maciej Król Dec 24 '19 at 16:10
  • I'm used to seeing `..gotoff` sprinkled liberally in position independent code when using NASM. – jww Dec 24 '19 at 17:25

1 Answers1

3

The recompile with -fPIC error message is assuming that the asm / object file was created by a compiler. With hand-written asm you are the compiler and have to write position-independent code. (Or at least code that inefficiently uses 64-bit absolute addresses like your mov rcx, digitSpace; runtime fixups are supported for those relocations on GNU/Linux.)


Use lea r8, [digitSpace] (or any convenient reg, preferably outside the loop) and compare against that.

cmp rcx, digitSpace uses a static address as a 32-bit immediate sign-extended to 64-bit. This will require a R_X86_64_32S relocation: 64-bit address encoded as a 32-bit signed value. (Same as you'd get for [digitSpace + rdx] for example, that's another thing you can't do in PIC/PIE code)

Only mov allows a 64-bit immediate (which NASM uses by default when you write mov r64, symbol). Of course it would be better to use a RIP-relative LEA like lea rcx, [digitSpace]. You used default rel so that will be RIP-relative).

Almost exact duplicate of Assembler Error: Mach-O 64 bit does not support absolute 32 bit addresses (MacOS never allows using symbol addresses as 32-bit immediates so it's an assemble-time error, vs. on Linux only an error when you try to link into an ELF shared object instead of a non-PIE executable.)

Also related:

Peter Cordes
  • 245,674
  • 35
  • 423
  • 606
  • "that's another thing you can't do in PIC/PIE code; see )" -- You seem to have a link missing here. – ecm Dec 24 '19 at 21:03
  • 2
    @ecm: thanks, I think I was going to link [32-bit absolute addresses no longer allowed in x86-64 Linux?](//stackoverflow.com/q/43367427) there, but on 2nd look I'll just put that link in the list at the bottom instead of inline in that paragraph. – Peter Cordes Dec 24 '19 at 21:20