aboutsummaryrefslogtreecommitdiffstats
path: root/com32
diff options
context:
space:
mode:
authorGene Cumm <gene.cumm@gmail.com>2016-01-19 06:37:41 -0500
committerGene Cumm <gene.cumm@gmail.com>2016-01-19 06:41:59 -0500
commit7cd1ed60e37f36db859a2ca3d6ee261f98dafdac (patch)
treefaa89c0124e259f8d63bb1da2755b9da42b14e6e /com32
parent496bb8c2a19ccf9e8c6c67b925c492c924c9378a (diff)
parent19d0d592ee115e8772b7dc6d5594748a49b63b0c (diff)
downloadsyslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.tar.gz
syslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.tar.xz
syslinux-7cd1ed60e37f36db859a2ca3d6ee261f98dafdac.zip
Merge 'git://github.com/Celelibi/syslinux.git/fix/bios/tail-call-stack-overflows'
FIXME: this circumvents some of the issue but is not the cleanest and may reoccur.
Diffstat (limited to 'com32')
-rw-r--r--com32/elflink/ldlinux/execute.c4
-rw-r--r--com32/elflink/ldlinux/ldlinux.c28
2 files changed, 23 insertions, 9 deletions
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 653c880d..39555715 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -44,6 +44,7 @@ const struct image_types image_boot_types[] = {
{ NULL, 0 },
};
+extern jmp_buf __return_to_command_prompt;
extern int create_args_and_load(char *);
__export void execute(const char *cmdline, uint32_t type, bool sysappend)
@@ -136,7 +137,8 @@ __export void execute(const char *cmdline, uint32_t type, bool sysappend)
/* Restore the console */
ldlinux_console_init();
- ldlinux_enter_command();
+ /* Jump back to the main to call ldlinux_enter_command */
+ longjmp(__return_to_command_prompt, 1);
} else if (type == IMAGE_TYPE_CONFIG) {
char *argv[] = { LDLINUX, NULL, NULL };
char *config;
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 9b01dd3a..0172117b 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -31,6 +31,8 @@ static const struct file_ext file_extensions[] = {
{ NULL, 0 },
};
+jmp_buf __return_to_command_prompt;
+
/*
* Return a pointer to one byte after the last character of the
* command.
@@ -302,6 +304,7 @@ __export int main(int argc __unused, char **argv)
const void *adv;
const char *cmdline;
size_t count = 0;
+ int retval;
ldlinux_console_init();
@@ -333,16 +336,25 @@ __export int main(int argc __unused, char **argv)
if (!syslinux_setadv(ADV_BOOTONCE, 0, NULL))
syslinux_adv_write();
- load_kernel(cmdline); /* Shouldn't return */
- ldlinux_enter_command();
- }
-
- if (!forceprompt && !shift_is_held())
- ldlinux_auto_boot();
+ /*
+ * The corresponding longjmp is located in the execute function
+ * after a COM32 module has returned.
+ */
+ retval = setjmp(__return_to_command_prompt);
+ if (retval == 0)
+ load_kernel(cmdline); /* Shouldn't return */
+ } else {
+ retval = setjmp(__return_to_command_prompt);
+ if (retval == 0) {
+ if (!forceprompt && !shift_is_held())
+ ldlinux_auto_boot();
- if (defaultlevel > 1)
- ldlinux_auto_boot();
+ if (defaultlevel > 1)
+ ldlinux_auto_boot();
+ }
+ }
+ retval = setjmp(__return_to_command_prompt);
ldlinux_enter_command();
return 0;
}