Search code examples
macosassembly64-bitx86-64gnu-assembler

Mac OS: ld: in section __DATA,__data reloc 0: length < 2 and X86_64_RELOC_UNSIGNED not supported


I searched online for a while and haven't seen any similar question.

So i am writing a small compiler to compile a language to x64 code.

But when I try to do clang generated-code.s, I get:

ld: in section __DATA,__data reloc 0: length < 2 and X86_64_RELOC_UNSIGNED not supported file '/var/folders/3g/ydlqd7bx3819pfrr9n52zjv80000gn/T/hello_world-795c7e.o' for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

I don't really understand the meaning of this error message. Does it mean i have undefined symbol? Can anyone please explain to me?

Here is the code my compiler generated:

.data

    .globl  Main_protoObj
    .globl  Int_protoObj
    .globl  String_protoObj
    .globl  Main_init
    .globl  Int_init
    .globl  String_init
    .globl  Bool_init
    .globl  Main_main

class_objTab:
    .word    Object_protoObj
    .word    Object_init
    .word    IO_protoObj
    .word    IO_init
    .word    String_protoObj
    .word    String_init
    .word    Int_protoObj
    .word    Int_init
    .word    Bool_protoObj
    .word    Bool_init
    .word    Main_protoObj
    .word    Main_init

Object_protoObj:
    .word    0
    .word    1
    .word    Object_dispatch_table

IO_protoObj:
    .word    1
    .word    3
    .word    IO_dispatch_table

String_protoObj:
    .word    2
    .word    3
    .word    String_dispatch_table
    .word    0
    .asciz   ""
    .align   8

Int_protoObj:
    .word    3
    .word    2
    .word    Int_dispatch_table
    .word    0

Bool_protoObj:
    .word    4
    .word    2
    .word    Bool_dispatch_table
    .word    0

Main_protoObj:
    .word    5
    .word    1
    .word    Main_dispatch_table

String_dispatch_table:
    .word    Object_abort
    .word    Object_copy
    .word    String_length
    .word    String_concat
    .word    String_substr

Main_dispatch_table:
    .word    Object_abort
    .word    Object_copy
    .word    IO_out_string
    .word    IO_out_int
    .word    IO_in_string
    .word    IO_in_int
    .word    Main_main

Bool_dispatch_table:
    .word    Object_abort
    .word    Object_copy

Object_dispatch_table:
    .word    Object_abort
    .word    Object_copy

IO_dispatch_table:
    .word    Object_abort
    .word    Object_copy
    .word    IO_out_string
    .word    IO_out_int
    .word    IO_in_string
    .word    IO_in_int

Int_dispatch_table:
    .word    Object_abort
    .word    Object_copy

int_const0:
    .word    3
    .word    4
    .word    Int_dispatch_table
    .word    22

string_const0:
    .word    2
    .word    6
    .word    String_dispatch_table
    .word    int_const0
    .asciz    "Hello, World.\n \n\n"
    .align    8


.text


Object_init:
    pushq %rbp
    movq %rsp, %rbp
    leave
    ret

IO_init:
    pushq %rbp
    movq %rsp, %rbp
    movq %rdi, %rdi
    callq Object_init
    leave
    ret


String_init:
    pushq %rbp
    movq %rsp, %rbp
    movq %rdi, %rdi
    callq Object_init
    movq '', 32(%rbp)
    movq $0, 24(%rbp)
    leave
    ret


Int_init:
    pushq %rbp
    movq %rsp, %rbp
    movq %rdi, %rdi
    callq Object_init
    movq $0, 24(%rbp)
    leave
    ret


Bool_init:
    pushq %rbp
    movq %rsp, %rbp
    movq %rdi, %rdi
    callq Object_init
    movq $0, 24(%rbp)
    leave
    ret



Main_main:
    pushq %rbp
    movq %rsp, %rbp
    subq $8, %rsp
    movq %rdi, -8(%rbp)
    movq -8(%rbp), %rdi
    leaq string_const0(%rip), %rax
    movq %rax, %rsi
    movq 16(%rdi), %r10
    movq 16(%r10), %r10
    callq* %r10
    leave
    ret

Main_init:
    pushq %rbp
    movq %rsp, %rbp
    movq %rdi, %rdi
    callq IO_init
    leave
    ret

Solution

  • The error:

    ld: in section __DATA,__data reloc 0: length < 2 and X86_64_RELOC_UNSIGNED not supported

    looks like a rather obscure way of saying that your object has allocated space to store offsets into data items that likely can't hold the offset generated at link time.

    A quick look at your code shows you use .word and a label for a value. An example .word Object_protoObj where Object_protoObj offset is a label. The directive .word allows values between 0x0000 and 0xffff (16-bits). The linker error is probably suggesting that the offsets of the labels it is generating can't fit into 16-bit words.

    Maybe you should be using .quad (allowing 64-bit values) or .int (32-bit values)? I don't know how you'll accessing these offsets in the tables so you'll have to choose .quad or .int based on your usage requirements.