diff mbox series

arm: Force flag_pic for FDPIC

Message ID 20240304081305.420124-1-maskray@google.com
State New
Headers show
Series arm: Force flag_pic for FDPIC | expand

Commit Message

Fangrui Song March 4, 2024, 8:13 a.m. UTC
From: Fangrui Song <maskray@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.GC17773@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 mbox series

Patch

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; }