Почему G CC не может скомпилировать сборку, созданную CLANG? - PullRequest
0 голосов
/ 17 июня 2020

Итак, я заметил, что CLANG производит сборку, которая не может быть скомпилирована с G CC. Например, для простого "Hello world!" в программе C, CLANG производит следующую сборку:

    .text
    .file   "hello.c"
    .globl  main                    # -- Begin function main
    .p2align    4, 0x90
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movabsq $.L.str, %rdi
    movb    $0, %al
    callq   printf
    xorl    %ecx, %ecx
    movl    %eax, -4(%rbp)          # 4-byte Spill
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    .cfi_def_cfa %rsp, 8
    retq
.Lfunc_end0:
    .size   main, .Lfunc_end0-main
    .cfi_endproc
                                        # -- End function
    .type   .L.str,@object          # @.str
    .section    .rodata.str1.1,"aMS",@progbits,1
.L.str:
    .asciz  "Hello world!\n"
    .size   .L.str, 14

    .ident  "clang version 10.0.0 "
    .section    ".note.GNU-stack","",@progbits
    .addrsig
    .addrsig_sym printf

Но когда я пытаюсь скомпилировать эту сборку с помощью gcc hello.s, я получаю:

hello.s: Assembler messages:
hello.s:37: Error: unknown pseudo-op: `.addrsig'
hello.s:38: Error: unknown pseudo-op: `.addrsig_sym'

Но оба G CC и CLANG используют один и тот же ассемблер, GNU Assembler. Итак, что здесь происходит на самом деле?

1 Ответ

1 голос
/ 22 июля 2020

Для чего это нужно? Я предполагаю, что MacOS из movabsq $.L.str, %rdi - таргетинга Linux компилятор будет использовать mov $.L.str, %edi для кода позиции- зависимого (не-P IE) (в противном случае LEA, относящегося к RIP) , и Windows имеет другое соглашение о вызовах. На самом деле довольно удивительно, что clang не использует LEA, относящийся к RIP; он будет меньше, чем movabs.

Предположительно, что директива .addrsig является clang-specifici c для метаданных MachO64, которые GAS не знает, как создать . Вероятно, это также версия Clang от Apple, а не mainline clang.

Но и G CC, и CLANG используют один и тот же ассемблер, GNU Assembler.

Нет, они используют тот же синтаксис asm , но в clang встроен ассемблер. Как указывает @ Mar c Glisse, вы можете использовать clang -no-integrated-as, чтобы отключить это, которое передаст это в GAS и, предположительно, выйдет из строя.

...