kakts-log

programming について調べたことを整理していきます

Cでインラインアセンブラコードをgccでコンパイルする際に "relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object;" というエラーが出た時の対処法

概要

GCCインラインアセンブラを利用して Cで書かれたコード内でアセンブリ言語のプログラムを埋め込み、コンパイルした場合に下記のエラーがでました gcc実行時に、内部でldコマンドが実行された時のエラーのようです。

$ gcc -fno-pic -fomit-frame-pointer inline.c -o inline
/usr/bin/ld: /tmp/ccEEoJFV.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
make: *** [Makefile:3: cmp-inline] Error 1

前提

user@079882db3e52:~/src/inline$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

元のコード inline.c

#include <stdio.h>

int main(void) {
    int i = 123;
    asm("addl $456,%0" : "=r" (i) : "0" (i));
    printf("i = %d\n", i);
    return 0;
}

対処法

このエラーは -fno-picをつけてコンパイルした時に発生しており、下記の2つでの方法で対応できました

-fno-picを外す

gcc -fomit-frame-pointer inline.c -o inline
user@079882db3e52:~/src/inline$ ./inline
i = 579

これによりエラーが出ずに実行ファイルを生成できます

-no-pieをつける

gcc -no-pie -fno-pic -fomit-frame-pointer inline.c -o inline
user@079882db3e52:~/src/inline$ ./inline
i = 579

-no-pieをつけてもエラーが解消しました
参考: keens.github.io