From: Fangrui Song <mask...@gcc.gnu.org> -fno-pic -mfdpic generated code is like regular -fno-pic, not suitable for FDPIC (absolute addressing for symbol references and no function descriptor). The sh port simply upgrades -fno-pic to -fpie by setting flag_pic. Let's follow suit.
Link: https://inbox.sourceware.org/gcc-patches/20150913165303.gc17...@brightrain.aerifal.cx/ gcc/ChangeLog: * config/arm/arm.cc (arm_option_override): Set flag_pic if TARGET_FDPIC. gcc/testsuite/ChangeLog: * gcc.target/arm/fdpic-pie.c: New test. --- gcc/config/arm/arm.cc | 6 +++++ gcc/testsuite/gcc.target/arm/fdpic-pie.c | 30 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 gcc/testsuite/gcc.target/arm/fdpic-pie.c diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc index 1cd69268ee9..f2fd3cce48c 100644 --- a/gcc/config/arm/arm.cc +++ b/gcc/config/arm/arm.cc @@ -3682,6 +3682,12 @@ arm_option_override (void) arm_pic_register = FDPIC_REGNUM; if (TARGET_THUMB1) sorry ("FDPIC mode is not supported in Thumb-1 mode"); + + /* FDPIC code is a special form of PIC, and the vast majority of code + generation constraints that apply to PIC also apply to FDPIC, so we + set flag_pic to avoid the need to check TARGET_FDPIC everywhere + flag_pic is checked. */ + flag_pic = 2; } if (arm_pic_register_string != NULL) diff --git a/gcc/testsuite/gcc.target/arm/fdpic-pie.c b/gcc/testsuite/gcc.target/arm/fdpic-pie.c new file mode 100644 index 00000000000..909db8bce74 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/fdpic-pie.c @@ -0,0 +1,30 @@ +// { dg-do compile } +// { dg-options "-O2 -fno-pic -mfdpic" } +// { dg-skip-if "-mpure-code and -fPIC incompatible" { *-*-* } { "-mpure-code" } } + +__attribute__((visibility("hidden"))) void hidden_fun(void); +void fun(void); +__attribute__((visibility("hidden"))) extern int hidden_var; +extern int var; +__attribute__((visibility("hidden"))) const int ro_hidden_var = 42; + +// { dg-final { scan-assembler "hidden_fun\\(GOTOFFFUNCDESC\\)" } } +void *addr_hidden_fun(void) { return hidden_fun; } + +// { dg-final { scan-assembler "fun\\(GOTFUNCDESC\\)" } } +void *addr_fun(void) { return fun; } + +// { dg-final { scan-assembler "hidden_var\\(GOT\\)" } } +void *addr_hidden_var(void) { return &hidden_var; } + +// { dg-final { scan-assembler "var\\(GOT\\)" } } +void *addr_var(void) { return &var; } + +// { dg-final { scan-assembler ".LANCHOR0\\(GOT\\)" } } +const int *addr_ro_hidden_var(void) { return &ro_hidden_var; } + +// { dg-final { scan-assembler "hidden_var\\(GOT\\)" } } +int read_hidden_var(void) { return hidden_var; } + +// { dg-final { scan-assembler "var\\(GOT\\)" } } +int read_var(void) { return var; } -- 2.44.0.rc1.240.g4c46232300-goog