]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
COFF: function auxiliary symbols
authorJan Beulich <jbeulich@suse.com>
Fri, 2 May 2025 08:07:53 +0000 (10:07 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 2 May 2025 08:07:53 +0000 (10:07 +0200)
For one at least x86 gcc emits .def/.endef for functions, but no 2nd
pair to designate their ends (sizes). While we can't recover the sizes,
we can at least properly establish the chain of function symbols, which
of course requires to emit auxiliary symbols for every function symbol
even when there's no C_EFCN: We simply shouldn't be making their
insertion conditional upon there not being a function processing of
which is "in progress".

In fact it was wrong to assign dual purpose to {,next_}set_end:
Functions don't have "ends" set, but links to the next one. The same
symbol table entry can serve both as an end marker and be a part of the
chain of (defined) functions; this can't be expressed by a single static
variable. Use what (again) becomes last_functionP for this purpose,
along with tracking what symbol C_EFCN should apply to.

This then allows to undo exposing of the respective (supposedly static)
tracking variable, which PPC's XCOFF handling had introduced. Also
rename it back to what it was before its exposure.

For now the new testcases are XFAIL for Arm64 since there, unlike for
Arm32, mapping symbols are emitted for COFF, too.

12 files changed:
gas/config/obj-coff.c
gas/config/obj-coff.h
gas/config/tc-ppc.c
gas/testsuite/gas/coff/coff.exp
gas/testsuite/gas/coff/func1.d [new file with mode: 0644]
gas/testsuite/gas/coff/func1.s [new file with mode: 0644]
gas/testsuite/gas/coff/func2.d [new file with mode: 0644]
gas/testsuite/gas/coff/func2.s [new file with mode: 0644]
gas/testsuite/gas/coff/func3.d [new file with mode: 0644]
gas/testsuite/gas/coff/func3.s [new file with mode: 0644]
gas/testsuite/gas/coff/func4.d [new file with mode: 0644]
gas/testsuite/gas/coff/func4.s [new file with mode: 0644]

index 53e923197d3b35782d4513450f9c0db8ba390829..445f2ac764d4a6f4bdce80dadacb2ad08ee1153c 100644 (file)
@@ -1187,7 +1187,6 @@ coff_assign_symbol (symbolS *symp ATTRIBUTE_UNUSED)
 #endif
 }
 
-symbolS *coff_last_function;
 #ifndef OBJ_XCOFF
 static symbolS *coff_last_bf;
 #endif
@@ -1195,6 +1194,7 @@ static symbolS *coff_last_bf;
 void
 coff_frob_symbol (symbolS *symp, int *punt)
 {
+  static symbolS *last_functionP;
   static symbolS *last_tagP;
   static stack *block_stack;
   static symbolS *set_end;
@@ -1338,12 +1338,10 @@ coff_frob_symbol (symbolS *symp, int *punt)
                }
            }
 
-         if (coff_last_function == 0 && SF_GET_FUNCTION (symp)
-             && S_IS_DEFINED (symp))
+         if (SF_GET_FUNCTION (symp) && S_IS_DEFINED (symp))
            {
              union internal_auxent *auxp;
 
-             coff_last_function = symp;
              if (S_GET_NUMBER_AUXILIARY (symp) < 1)
                S_SET_NUMBER_AUXILIARY (symp, 1);
              auxp = SYM_AUXENT (symp);
@@ -1354,14 +1352,12 @@ coff_frob_symbol (symbolS *symp, int *punt)
          if (S_GET_STORAGE_CLASS (symp) == C_EFCN
              && S_IS_DEFINED (symp))
            {
-             if (coff_last_function == 0)
+             if (!last_functionP)
                as_fatal (_("C_EFCN symbol for %s out of scope"),
                          S_GET_NAME (symp));
-             SA_SET_SYM_FSIZE (coff_last_function,
+             SA_SET_SYM_FSIZE (last_functionP,
                                (long) (S_GET_VALUE (symp)
-                                       - S_GET_VALUE (coff_last_function)));
-             next_set_end = coff_last_function;
-             coff_last_function = 0;
+                                       - S_GET_VALUE (last_functionP)));
            }
        }
 
@@ -1415,6 +1411,13 @@ coff_frob_symbol (symbolS *symp, int *punt)
       set_end = next_set_end;
     }
 
+  if (SF_GET_FUNCTION (symp) && S_IS_DEFINED (symp) && !*punt)
+    {
+      if (last_functionP)
+       SA_SET_SYM_ENDNDX (last_functionP, symp);
+      last_functionP = symp;
+    }
+
 #ifndef OBJ_XCOFF
   if (! *punt
       && S_GET_STORAGE_CLASS (symp) == C_FCN
index 1d191ee2eee3ded846eb3fb0b38fd1615c0a6f15..51dfd56e4470c717611a02d34df0142696787640 100644 (file)
 extern int text_lineno_number;
 extern int coff_line_base;
 extern int coff_n_line_nos;
-extern symbolS *coff_last_function;
 
 #define obj_emit_lineno(WHERE, LINE, FILE_START)       abort ()
 #define obj_app_file(name)           c_dot_file_symbol (name)
index 33f3a4c840aeb8de6f31c2f26bd1a860926f528c..0de27140d6af991eec5f1b7c7e2e7bf18fc89da9 100644 (file)
@@ -6140,9 +6140,6 @@ ppc_frob_symbol (symbolS *sym)
 
   if (SF_GET_FUNCTION (sym))
     {
-      /* Make sure coff_last_function is reset. Otherwise, we won't create
-         the auxent for the next function.  */
-      coff_last_function = 0;
       ppc_last_function = sym;
       if (symbol_get_tc (sym)->u.size != (symbolS *) NULL)
        {
@@ -6170,10 +6167,6 @@ ppc_frob_symbol (symbolS *sym)
        {
          set_end = ppc_last_function;
          ppc_last_function = NULL;
-
-         /* We don't have a C_EFCN symbol, but we need to force the
-            COFF backend to believe that it has seen one.  */
-         coff_last_function = NULL;
        }
     }
 
index 0ef804490fe9c92ca664304cf045221f679817ce..b5e7d24068941591c5b5218b8a3504d12dc0b158 100644 (file)
@@ -30,3 +30,11 @@ if {    ![istarget arm*-*-*]
      && ![istarget *c54x*-*-*] } {
     run_dump_test tag
 }
+
+# Omit c4x and c54x, since .def means something different there.
+if { ![istarget *c4x*-*-*] && ![istarget *c54x*-*-*] } {
+    run_dump_test func1
+    run_dump_test func2
+    run_dump_test func3
+    run_dump_test func4
+}
diff --git a/gas/testsuite/gas/coff/func1.d b/gas/testsuite/gas/coff/func1.d
new file mode 100644 (file)
index 0000000..c0bfa83
--- /dev/null
@@ -0,0 +1,16 @@
+#xfail: aarch64-*-*
+#objdump: -t
+#name: functions w/o C_EFCN
+
+.*:     file format .*
+
+SYMBOL TABLE:
+\[  0\]\(sec -2\)\(fl 0x00\)\(ty    0\)\(scl 103\) \(nx 1\) 0x0+0000 func1.c
+File *
+\[  2\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+0000 inner
+AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 4
+\[  4\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+000. outer
+AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 6
+\[  6\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   2\) \(nx 1\) 0x0+000. test
+AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
+#pass
diff --git a/gas/testsuite/gas/coff/func1.s b/gas/testsuite/gas/coff/func1.s
new file mode 100644 (file)
index 0000000..28300e7
--- /dev/null
@@ -0,0 +1,22 @@
+       .file   "func1.c"
+       .text
+       .macro fcn, name
+       .def    \name
+       .scl    3               /* C_STAT */
+       .type   32              /* DT_FUNC */
+       .endef
+\name:
+       .endm
+
+       fcn inner
+       .nop
+
+       fcn outer
+       .nop
+       .nop
+
+       .global test
+       fcn test
+       .nop
+       .nop
+       .nop
diff --git a/gas/testsuite/gas/coff/func2.d b/gas/testsuite/gas/coff/func2.d
new file mode 100644 (file)
index 0000000..55a3a25
--- /dev/null
@@ -0,0 +1,16 @@
+#xfail: aarch64-*-*
+#objdump: -t
+#name: functions w/ C_EFCN
+
+.*:     file format .*
+
+SYMBOL TABLE:
+\[  0\]\(sec -2\)\(fl 0x00\)\(ty    0\)\(scl 103\) \(nx 1\) 0x0+0000 func2.c
+File *
+\[  2\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+0000 inner
+AUX tagndx 0 ttlsiz 0x[124] lnnos 0 next 4
+\[  4\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+000. outer
+AUX tagndx 0 ttlsiz 0x[248] lnnos 0 next 6
+\[  6\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   2\) \(nx 1\) 0x0+000. test
+AUX tagndx 0 ttlsiz 0x[36c] lnnos 0 next 0
+#pass
diff --git a/gas/testsuite/gas/coff/func2.s b/gas/testsuite/gas/coff/func2.s
new file mode 100644 (file)
index 0000000..75f2069
--- /dev/null
@@ -0,0 +1,34 @@
+       .file   "func2.c"
+
+       .macro fcn, name
+       .def    \name
+       .scl    3               /* C_STAT */
+       .type   32              /* DT_FUNC */
+       .endef
+\name:
+       .endm
+
+       .macro efcn, name
+       .def    .\name
+       .scl    255             /* C_EFCN */
+       .val    .
+       .endef
+       .endm
+
+       .text
+
+       fcn inner
+       .nop
+       efcn inner
+
+       fcn outer
+       .nop
+       .nop
+       efcn outer
+
+       .global test
+       fcn test
+       .nop
+       .nop
+       .nop
+       efcn test
diff --git a/gas/testsuite/gas/coff/func3.d b/gas/testsuite/gas/coff/func3.d
new file mode 100644 (file)
index 0000000..06b37f8
--- /dev/null
@@ -0,0 +1,16 @@
+#xfail: aarch64-*-*
+#objdump: -t
+#name: functions mixed C_EFCN
+
+.*:     file format .*
+
+SYMBOL TABLE:
+\[  0\]\(sec -2\)\(fl 0x00\)\(ty    0\)\(scl 103\) \(nx 1\) 0x0+0000 func3.c
+File *
+\[  2\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+0000 inner
+AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 4
+\[  4\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+000. outer
+AUX tagndx 0 ttlsiz 0x[248] lnnos 0 next 6
+\[  6\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   2\) \(nx 1\) 0x0+000. test
+AUX tagndx 0 ttlsiz 0x[36c] lnnos 0 next 0
+#pass
diff --git a/gas/testsuite/gas/coff/func3.s b/gas/testsuite/gas/coff/func3.s
new file mode 100644 (file)
index 0000000..5d41171
--- /dev/null
@@ -0,0 +1,33 @@
+       .file   "func3.c"
+
+       .macro fcn, name
+       .def    \name
+       .scl    3               /* C_STAT */
+       .type   32              /* DT_FUNC */
+       .endef
+\name:
+       .endm
+
+       .macro efcn, name
+       .def    .\name
+       .scl    255             /* C_EFCN */
+       .val    .
+       .endef
+       .endm
+
+       .text
+
+       fcn inner
+       .nop
+
+       fcn outer
+       .nop
+       .nop
+       efcn outer
+
+       .global test
+       fcn test
+       .nop
+       .nop
+       .nop
+       efcn test
diff --git a/gas/testsuite/gas/coff/func4.d b/gas/testsuite/gas/coff/func4.d
new file mode 100644 (file)
index 0000000..e7cd444
--- /dev/null
@@ -0,0 +1,18 @@
+#xfail: aarch64-*-*
+#objdump: -t
+#name: functions interleaved with data
+
+.*:     file format .*
+
+SYMBOL TABLE:
+\[  0\]\(sec -2\)\(fl 0x00\)\(ty    0\)\(scl 103\) \(nx 1\) 0x0+0000 func4.c
+File *
+\[  2\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+0000 inner
+AUX tagndx 0 ttlsiz 0x[124] lnnos 0 next 5
+\[  4\]\(sec  2\)\(fl 0x00\)\(ty    0\)\(scl   3\) \(nx 0\) 0x0+0000 item1
+\[  5\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   3\) \(nx 1\) 0x0+000. outer
+AUX tagndx 0 ttlsiz 0x[248] lnnos 0 next 8
+\[  7\]\(sec  2\)\(fl 0x00\)\(ty    0\)\(scl   3\) \(nx 0\) 0x0+000. item2
+\[  8\]\(sec  1\)\(fl 0x00\)\(ty   20\)\(scl   2\) \(nx 1\) 0x0+000. test
+AUX tagndx 0 ttlsiz 0x[36c] lnnos 0 next 0
+#pass
diff --git a/gas/testsuite/gas/coff/func4.s b/gas/testsuite/gas/coff/func4.s
new file mode 100644 (file)
index 0000000..e9c75f4
--- /dev/null
@@ -0,0 +1,41 @@
+       .file   "func4.c"
+
+       .macro fcn, name
+       .def    \name
+       .scl    3               /* C_STAT */
+       .type   32              /* DT_FUNC */
+       .endef
+\name:
+       .endm
+
+       .macro efcn, name
+       .def    .\name
+       .scl    255             /* C_EFCN */
+       .val    .
+       .endef
+       .endm
+
+       .text
+       fcn inner
+       .nop
+       efcn inner
+
+       .data
+item1: .long -1
+
+       .text
+       fcn outer
+       .nop
+       .nop
+       efcn outer
+
+       .data
+item2: .long -2
+
+       .text
+       .global test
+       fcn test
+       .nop
+       .nop
+       .nop
+       efcn test