bool avr_need_copy_data_p = false;
bool avr_has_rodata_p = false;
+/* To track if we satisfy __call_main from AVR-LibC. */
+bool avr_no_call_main_p = false;
+
/* Counts how often pass avr-fuse-add has been executed. Is is kept in
sync with cfun->machine->n_avr_fuse_add_executed and serves as an
insn condition for shift insn splitters. */
NULL, *attributes);
}
+#if defined WITH_AVRLIBC
+ if (avropt_call_main == 0
+ && TREE_CODE (node) == FUNCTION_DECL
+ && MAIN_NAME_P (DECL_NAME (node)))
+ {
+ const char *s_section_name = nullptr;
+
+ if (tree a_sec = lookup_attribute ("section", *attributes))
+ if (TREE_VALUE (a_sec))
+ if (tree t_section_name = TREE_VALUE (TREE_VALUE (a_sec)))
+ if (TREE_CODE (t_section_name) == STRING_CST)
+ s_section_name = TREE_STRING_POINTER (t_section_name);
+
+ bool in_init9_p = s_section_name && !strcmp (s_section_name, ".init9");
+
+ if (s_section_name && !in_init9_p)
+ {
+ warning (OPT_Wattributes, "%<section(\"%s\")%> attribute on main"
+ " function inhibits %<-mno-call-main%>", s_section_name);
+ }
+ else
+ {
+ if (!lookup_attribute ("noreturn", *attributes))
+ *attributes = tree_cons (get_identifier ("noreturn"),
+ NULL_TREE, *attributes);
+ // Put main into section .init9 so that it is executed even
+ // though it's not called.
+ if (!in_init9_p)
+ {
+ tree init9 = build_string (1 + strlen (".init9"), ".init9");
+ tree arg = build_tree_list (NULL_TREE, init9);
+ *attributes = tree_cons (get_identifier ("section"),
+ arg, *attributes);
+ }
+ avr_no_call_main_p = true;
+ }
+ } // -mno-call-main
+#endif // AVR-LibC
+
avr_handle_isr_attribute (node, attributes, "signal");
avr_handle_isr_attribute (node, attributes, "interrupt");
if (avr_need_clear_bss_p)
fputs (".global __do_clear_bss\n", asm_out_file);
+
+ /* Don't let __call_main call main() and exit().
+ Defining this symbol will keep the code from being pulled
+ in from lib<mcu>.a as requested by AVR-LibC's gcrt1.S.
+ We invoke main() by other means: putting it in .init9. */
+
+ if (avr_no_call_main_p)
+ fputs (".global __call_main\n"
+ "__call_main = 0\n", asm_out_file);
}
@gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args -mcvt
-mbranch-cost=@var{cost} -mfuse-add=@var{level} -mfuse-move=@var{level}
-mcall-prologues -mgas-isr-prologues -mint8 -mflmap
--mdouble=@var{bits} -mlong-double=@var{bits}
+-mdouble=@var{bits} -mlong-double=@var{bits} -mno-call-main
-mn_flash=@var{size} -mfract-convert-truncate -mno-interrupts
-mmain-is-OS_task -mrelax -mrmw -mstrict-X -mtiny-stack
-mrodata-in-ram -msplit-bit-shift -msplit-ldst
attaching attribute @ref{AVR Function Attributes,,@code{OS_task}}
to @code{main}. It is activated per default if optimization is on.
+@opindex mno-call-main
+@opindex mcall-main
+@item -mno-call-main
+Don't run @code{main} by means of
+@example
+XCALL main
+XJMP exit
+@end example
+Instead, put @code{main} in section
+@w{@uref{https://avrdudes.github.io/avr-libc/avr-libc-user-manual/mem_sections.html#sec_dot_init,@code{.init9}}}
+so that no call is required.
+By setting this options the user asserts that @code{main} will not return.
+
+This option can be used for devices with very limited resources in order
+to save a few bytes of code and stack space. It will work as expected since
+@w{@uref{https://github.com/avrdudes/avr-libc/issues/1012,AVR-LibC v2.3}}.
+With older versions, there will be no performance gain.
+
@opindex mno-interrupts
@item -mno-interrupts
Generated code is not compatible with hardware interrupts.
@opindex nodevicelib
@item -nodevicelib
-Don't link against AVR-LibC's device specific library @code{lib<mcu>.a}.
+Don't link against AVR-LibC's device specific library @code{lib@var{mcu}.a}.
+
+Notice that since AVR-LibC v2.3, that library contains code that is
+essential for the correct functioning of a program. In particular,
+it contains parts of the startup code like:
+@w{@uref{https://github.com/avrdudes/avr-libc/issues/1011,@code{__init_sp}}}
+to initialize the stack pointer with symbol @code{__stack},
+@w{@uref{https://github.com/avrdudes/avr-libc/issues/1010,@code{__init_cvt}}}
+to set up the hardware to use a compact vector table with @option{-mcvt},
+@w{@uref{https://github.com/avrdudes/avr-libc/issues/1012,@code{__call_main}}}
+to call @code{main} and @code{exit}, and
+@w{@uref{https://github.com/avrdudes/avr-libc/issues/931,@code{__do_flmap_init}}}
+to set up FLMAP according to symbol @code{__flmap}.
@opindex nodevicespecs
@item -nodevicespecs