From: Jan Beulich Date: Fri, 2 May 2025 08:07:53 +0000 (+0200) Subject: COFF: function auxiliary symbols X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea9c4d157496d68a489f1d9e3a623d1dd9788192;p=thirdparty%2Fbinutils-gdb.git COFF: function auxiliary symbols 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. --- diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 53e923197d3..445f2ac764d 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -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 diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 1d191ee2eee..51dfd56e447 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -242,7 +242,6 @@ 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) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 33f3a4c840a..0de27140d6a 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -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; } } diff --git a/gas/testsuite/gas/coff/coff.exp b/gas/testsuite/gas/coff/coff.exp index 0ef804490fe..b5e7d240689 100644 --- a/gas/testsuite/gas/coff/coff.exp +++ b/gas/testsuite/gas/coff/coff.exp @@ -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 index 00000000000..c0bfa831d66 --- /dev/null +++ b/gas/testsuite/gas/coff/func1.d @@ -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 index 00000000000..28300e709df --- /dev/null +++ b/gas/testsuite/gas/coff/func1.s @@ -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 index 00000000000..55a3a25c6e5 --- /dev/null +++ b/gas/testsuite/gas/coff/func2.d @@ -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 index 00000000000..75f2069d919 --- /dev/null +++ b/gas/testsuite/gas/coff/func2.s @@ -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 index 00000000000..06b37f81e4c --- /dev/null +++ b/gas/testsuite/gas/coff/func3.d @@ -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 index 00000000000..5d411712039 --- /dev/null +++ b/gas/testsuite/gas/coff/func3.s @@ -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 index 00000000000..e7cd4445a7f --- /dev/null +++ b/gas/testsuite/gas/coff/func4.d @@ -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 index 00000000000..e9c75f4f15f --- /dev/null +++ b/gas/testsuite/gas/coff/func4.s @@ -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