https://gcc.gnu.org/g:f31d4844cf3c35566ba7e06a2097dc51ea55369d
commit r17-4844-gf31d4844cf3c35566ba7e06a2097dc51ea55369d Author: Georg-Johann Lay <[email protected]> Date: Fri Oct 2 20:08:26 2026 +0200 AVR: Support new option -mprune-vectab. This patch adds -mprune-vectab as a new target option. It acts as a front end for the linker's --prune-vectab option that has been added as https://sourceware.org/PR34679. The compiler option has only an effect when the linker actually supports --prune-vectab, which is tested for in configure.ac. gcc/ * configure.ac [target=avr-*.*]: Test linker for --prune-vectab, and AC_DEFINE HAVE_LD_AVR_PRUNE_VECTAB if supported. * config.in: Rebuild. * configure: Rebuild. * config/avr/avr.opt (-mprune-vectab): New target option. * config/avr/specs.h (LINK_SPEC): Add %(link_prune_vectab). * config/avr/gen-avr-mmcu-specs.cc (print_mcu) [HAVE_LD_AVR_PRUNE_VECTAB]: Emit link_prune_vectab spec. * config/avr/avr.opt.urls: Rebuild. * doc/invoke.texi (AVR Options): Document -mprune-vectab. Diff: --- gcc/config.in | 6 ++++++ gcc/config/avr/avr.opt | 4 ++++ gcc/config/avr/avr.opt.urls | 3 +++ gcc/config/avr/gen-avr-mmcu-specs.cc | 6 ++++++ gcc/config/avr/specs.h | 1 + gcc/configure | 13 +++++++++++++ gcc/configure.ac | 10 ++++++++++ gcc/doc/invoke.texi | 28 ++++++++++++++++++++++++++-- 8 files changed, 69 insertions(+), 2 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index b90caa0dd57a..d4d864e858f3 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1726,6 +1726,12 @@ #endif +/* Define if your linker supports --prune-vectab. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_AVR_PRUNE_VECTAB +#endif + + /* Define if your linker supports -z bndplt */ #ifndef USED_FOR_TARGET #undef HAVE_LD_BNDPLT_SUPPORT diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index c94385f53700..4c81aa8df2c7 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -99,6 +99,10 @@ mrelax Target Optimization Optimization. Relax branches. +mprune-vectab +Target Optimization +Optimization. Prune AVR-LibC vector table provided relaxation is on. + mpmem-wrap-around Target Make the linker relaxation machine assume that a program counter wrap-around occurs. diff --git a/gcc/config/avr/avr.opt.urls b/gcc/config/avr/avr.opt.urls index e0c725e8d1a8..97cbc1bc9231 100644 --- a/gcc/config/avr/avr.opt.urls +++ b/gcc/config/avr/avr.opt.urls @@ -48,6 +48,9 @@ UrlSuffix(gcc/AVR-Options.html#index-mtiny-stack) mrelax UrlSuffix(gcc/AVR-Options.html#index-mrelax) +mprune-vectab +UrlSuffix(gcc/AVR-Options.html#index-mprune-vectab) + mpmem-wrap-around UrlSuffix(gcc/AVR-Options.html#index-mpmem-wrap-around) diff --git a/gcc/config/avr/gen-avr-mmcu-specs.cc b/gcc/config/avr/gen-avr-mmcu-specs.cc index 470d40538e53..c72cf904bff9 100644 --- a/gcc/config/avr/gen-avr-mmcu-specs.cc +++ b/gcc/config/avr/gen-avr-mmcu-specs.cc @@ -376,6 +376,12 @@ print_mcu (const avr_mcu_t *mcu, const McuInfo &mi) if (mcu->text_section_start != 0x0) fprintf (f, "\t%%{!Ttext:-Ttext 0x%lX}", 0UL + mcu->text_section_start); fprintf (f, "\n\n"); + + fprintf (f, "*link_prune_vectab:\n"); +#if defined (WITH_AVRLIBC) && defined (HAVE_LD_AVR_PRUNE_VECTAB) + fprintf (f, "\t%%{!r:%%{mprune-vectab:--prune-vectab}}"); +#endif // Have --prune-vectab + fprintf (f, "\n\n"); } // -m[no-]rodata-in-ram affects linking. Sanity check its usage. diff --git a/gcc/config/avr/specs.h b/gcc/config/avr/specs.h index b50f7040941e..dfa212c072a0 100644 --- a/gcc/config/avr/specs.h +++ b/gcc/config/avr/specs.h @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see "%(link_data_start) " \ "%(link_text_start) " \ "%(link_relax) " \ + "%(link_prune_vectab) " \ "%(link_pmem_wrap) " \ "%(link_rodata_in_ram) " \ "%(link_no_call_main) " \ diff --git a/gcc/configure b/gcc/configure index 2d211a0beaea..b1dd8fa48ad8 100755 --- a/gcc/configure +++ b/gcc/configure @@ -29375,6 +29375,19 @@ $as_echo "$as_me: WARNING: support for avrxmega4_flmap requires Binutils 2.42 or $as_echo "$as_me: WARNING: see \`config.log' for details" >&2;} fi rm -f conftest.s conftest.o conftest.elf + + # Check for linker --prune-vectab. + gcc_cv_ld_avr_prune_vectab=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for --prune-vectab support" >&5 +$as_echo_n "checking linker for --prune-vectab support... " >&6; } + if $gcc_cv_ld --help 2>&1 | grep -- '--prune-vectab' > /dev/null; then + gcc_cv_ld_avr_prune_vectab=yes + +$as_echo "#define HAVE_LD_AVR_PRUNE_VECTAB 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_avr_prune_vectab" >&5 +$as_echo "$gcc_cv_ld_avr_prune_vectab" >&6; } ;; cris-*-*) diff --git a/gcc/configure.ac b/gcc/configure.ac index a4878c4a9f96..d6f07f4ddb8c 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4880,6 +4880,16 @@ EOF AC_MSG_WARN([[see `config.log' for details]]) fi rm -f conftest.s conftest.o conftest.elf + + # Check for linker --prune-vectab. + gcc_cv_ld_avr_prune_vectab=no + AC_MSG_CHECKING(linker for --prune-vectab support) + if $gcc_cv_ld --help 2>&1 | grep -- '--prune-vectab' > /dev/null; then + gcc_cv_ld_avr_prune_vectab=yes + AC_DEFINE(HAVE_LD_AVR_PRUNE_VECTAB, 1, + [Define if your linker supports --prune-vectab.]) + fi + AC_MSG_RESULT($gcc_cv_ld_avr_prune_vectab) ;; cris-*-*) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index bd992cc99b9a..41a4f3dc544e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -990,7 +990,7 @@ Objective-C and Objective-C++ Dialects}. -mcall-prologues -mgas-isr-prologues -mint8 -mflmap -mdouble=@var{bits} -mlong-double=@var{bits} -mno-call-main -mn_flash=@var{size} -mfract-convert-truncate -mno-interrupts --mmain-is-OS_task -moptimize -mrelax -mpmem-wrap-around +-mmain-is-OS_task -moptimize -mrelax -mpmem-wrap-around -mprune-vectab -mrmw -mstrict-addr-space-subsets -mstrict-X -mtiny-stack -mrodata-in-ram -msplit-bit-shift -msplit-ldst -mshort-calls -mskip-bug -muse-nonzero-bits -nodevicelib -nodevicespecs @@ -24513,6 +24513,29 @@ differ from instructions in the assembly code. Relaxing must be turned on if linker stubs are needed, see the section on @code{EIND} and linker stubs below. +@opindex mprune-vectab +@item -mprune-vectab +Remove unused entries in the AVR-LibC interrupt vector table during relaxing. +An entry is unused when it targets @code{__bad_interrupt} and all following +entries are also unused. + +Setting @option{-mprune-vectab} just adds the @option{--prune-vectab} option +to the linker's command line, provided the required GNU Binutils +support (@w{@uref{https://sourceware.org/PR34679,,PR34679}}) is available. +Otherwise, or when relaxing is not enabled, the option has no effect. + +What is not supported are jumps like +@example + JMP 0x18 +@end example +that target a vector table entry that is not the reset vector. Use code like +@example + JMP __vectors + 0x18 +@end example +instead. +This option makes it harder to find rogue IRQs that lack an interrupt service +routine (ISR) and whose IRQ vector is located beyond the last used one. + @opindex mstrict-addr-space-subsets @item -mstrict-addr-space-subsets Impose strict named address space subset relations. Without this option, @@ -24590,7 +24613,8 @@ Enabled by default. @subsubsection AVR Optimization Options The following options are pure optimization options. Options @option{-mgas-isr-prologues}, @option{-mmain-is-OS_task}, -@option{-mno-call-main} and @option{-mrelax} from above are only +@option{-mno-call-main}, @option{-mrelax} and @option{-mprune-vectab} +from above are only @emph{almost} optimization options, since there are rare occasions where their different code generation matters.
