diff --git a/ChangeLog b/ChangeLog index 6c9e3bf6d..371e910c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,118 @@ +2010-09-04 BVK Chaitanya + + * grub-core/normal/completion.c (grub_normal_do_completion): Fix + grub_free order. + +2010-09-04 BVK Chaitanya + + Support for passing block of commands as an argument to extcmds. + + * Makefile.util.def: Rules for new test. + * tests/grub_script_blockarg.in: New test. + * grub-core/tests/test_blockarg.c: New file, block argument + command used in the test. + + * include/grub/extcmd.h (grub_extcmd_context): New struct. + (grub_register_extcmd_prio): New function prototype. + (grub_extcmd_dispatcher): New function prototype. + * include/grub/command.h (GRUB_COMMAND_FLAG_BLOCKS): New command + type. + * include/grub/script_sh.h (struct grub_script): New members + `children', `next_siblings' and `refcnt' for block arguments and + reference counting. + (GRUB_SCRIPT_ARG_TYPE_BLOCK): New argument type. + (grub_script_arg): New member `script' for block argument. + (grub_script_argv): New member `script' for block argument. + (grub_parser_param): New member `scripts' for block argument. + (grub_script_mem_free): New extern function prototype. + (grub_script_ref): New function prototype. + (grub_script_unref): New function prototype. + + * grub-core/normal/dyncmd.c (grub_dyncmd_dispatcher): Moved to + extcmd form to support block arguments. + * grub-core/script/argv.c: Block arguments support. + * grub-core/script/execute.c: Likewise. + * grub-core/script/lexer.c: Likewise. + * grub-core/script/main.c: Likewise. + * grub-core/script/script.c: Likewise. + * grub-core/script/parser.y: Likewise. New `block' and `block0' + non-terminals. + + * grub-core/commands/acpi.c: Update extcmd implementations with + grub_extcmd_context_t. + * grub-core/commands/cat.c: Likewise. + * grub-core/commands/echo.c: Likewise. + * grub-core/commands/extcmd.c: Likewise. + * grub-core/commands/hashsum.c: Likewise. + * grub-core/commands/hdparm.c: Likewise. + * grub-core/commands/help.c: Likewise. + * grub-core/commands/hexdump.c: Likewise. + * grub-core/commands/i386/cpuid.c: Likewise. + * grub-core/commands/i386/pc/drivemap.c: Likewise. + * grub-core/commands/i386/pc/halt.c: Likewise. + * grub-core/commands/i386/pc/sendkey.c: Likewise. + * grub-core/commands/iorw.c: Likewise. + * grub-core/commands/keystatus.c: Likewise. + * grub-core/commands/loadenv.c: Likewise. + * grub-core/commands/ls.c: Likewise. + * grub-core/commands/lspci.c: Likewise. + * grub-core/commands/memrw.c: Likewise. + * grub-core/commands/probe.c: Likewise. + * grub-core/commands/search_wrap.c: Likewise. + * grub-core/commands/setpci.c: Likewise. + * grub-core/commands/sleep.c: Likewise. + * grub-core/disk/loopback.c: Likewise. + * grub-core/hello/hello.c: Likewise. + * grub-core/loader/i386/bsd.c: Likewise. + * grub-core/loader/xnu.c: Likewise. + * grub-core/term/gfxterm.c: Likewise. + * grub-core/term/serial.c: Likewise. + * grub-core/tests/lib/functional_test.c: Likewise. + +2010-09-04 BVK Chaitanya + + Multi-line quoted strings support. + + * grub-core/script/lexer.c (append_newline): Removed. + (grub_script_lexer_yywrap): Refactored. + (grub_script_lexer_init): Refactored. + * grub-core/script/yylex.l (yywrap): New function. + (grub_lexer_resplit): New function. + (grub_lexer_unput): New function. + * include/grub/script_sh.h (grub_lexer_param): New members, unput + and resplit. + * tests/grub_script_echo1.in: Added few more testcases. + +2010-09-04 Vladimir Serbinenko + + * grub-core/kern/misc.c: Don't add abort alias in utils. + Reported by: echoline. + +2010-09-03 BVK Chaitanya + + Add missing files into "make dist" tarball for other platforms. + + * gentpl.py (script): Use dist_noinst_DATA instead of EXTRA_DIST. + * conf/Makefile.common (dist_noinst_DATA): New variable. + * conf/Makefile.extra-dist: Added missing make dist files. + * grub-core/Makefile.core.def: Likewise. + +2010-09-03 Vladimir Serbinenko + + Compress grub_prefix. + + * grub-core/boot/i386/pc/lnxboot.S: Use + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE. + * grub-core/kern/i386/pc/startup.S: Move grub_prefix to compressed part. + * include/grub/offsets.h: Rename GRUB_MACHINE_DATA_END to + GRUB_MACHINE_PREFIX_END. All users updated. + (GRUB_KERNEL_I386_PC_PREFIX): Set to GRUB_KERNEL_I386_PC_RAW_SIZE. + (GRUB_KERNEL_I386_PC_PREFIX_END): Set to GRUB_KERNEL_I386_PC_PREFIX + + 0x40. + (GRUB_KERNEL_I386_PC_RAW_SIZE): Decrease. + * util/grub-mkimage.c (image_target_desc): Change data_end to + prefix_end. All users updated. + 2010-09-03 Vladimir Serbinenko * grub-core/loader/i386/bsd.c (grub_freebsd_boot): Set %ebp to sane diff --git a/Makefile.util.def b/Makefile.util.def index 5f2295c3e..a0ab3d3d9 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -501,6 +501,12 @@ script = { common = tests/grub_script_shift.in; }; +script = { + testcase; + name = grub_script_blockarg; + common = tests/grub_script_blockarg.in; +}; + script = { testcase; name = grub_script_return; diff --git a/conf/Makefile.common b/conf/Makefile.common index fe14c0e18..fca0f67ae 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -115,6 +115,7 @@ pkglib_SCRIPTS = noinst_PROGRAMS = grubconf_SCRIPTS = noinst_LIBRARIES = +dist_noinst_DATA = TESTS = EXTRA_DIST = diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index 3acef7af7..afedc7d28 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -5,6 +5,11 @@ EXTRA_DIST += gentpl.py EXTRA_DIST += Makefile.tpl EXTRA_DIST += Makefile.util.def +EXTRA_DIST += unicode + +EXTRA_DIST += util/import_gcry.py +EXTRA_DIST += util/import_unicode.py + EXTRA_DIST += docs/man EXTRA_DIST += docs/grub.cfg @@ -26,8 +31,8 @@ EXTRA_DIST += grub-core/genterminallist.sh EXTRA_DIST += grub-core/genparttoollist.sh EXTRA_DIST += grub-core/genemuinitheader.sh +EXTRA_DIST += grub-core/lib/libgcrypt/cipher EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h') EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/posix_wrap -name '*.h') -EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/libgcrypt_wrap -name '*.h') +EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h') diff --git a/gentpl.py b/gentpl.py index abfb20444..cd34fccff 100644 --- a/gentpl.py +++ b/gentpl.py @@ -478,7 +478,7 @@ chmod a+x [+ name +] """) r += gvar_add("CLEANFILES", "[+ name +]") - r += gvar_add("EXTRA_DIST", platform_sources(platform)) + r += gvar_add("dist_noinst_DATA", platform_sources(platform)) return r def module_rules(): diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 353b9d123..e27152706 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -137,6 +137,7 @@ kernel = { mips_yeeloong = term/at_keyboard.c; mips_yeeloong = term/serial.c; mips_yeeloong = video/sm712.c; + extra_dist = video/sm712_init.c; powerpc_ieee1275 = kern/ieee1275/init.c; powerpc_ieee1275 = kern/powerpc/cache.S; @@ -1009,6 +1010,9 @@ module = { powerpc = lib/powerpc/relocator_asm.S; powerpc = lib/powerpc/relocator.c; + extra_dist = lib/i386/relocator_common.S; + extra_dist = kern/powerpc/cache_flush.S; + enable = mips; enable = powerpc; enable = x86; @@ -1376,3 +1380,8 @@ module = { name = datehook; common = hook/datehook.c; }; + +module = { + name = test_blockarg; + common = tests/test_blockarg.c; +}; \ No newline at end of file diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S index b4f0030b8..9348553c3 100644 --- a/grub-core/boot/i386/pc/lnxboot.S +++ b/grub-core/boot/i386/pc/lnxboot.S @@ -185,7 +185,7 @@ real_code_2: call LOCAL(move_memory) /* Check for multiboot signature. */ - cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) + cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE) jz 1f movl (ramdisk_image - start), %esi diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 884ddf000..1f17b63d6 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -458,10 +458,9 @@ free_tables (void) } static grub_err_t -grub_cmd_acpi (struct grub_extcmd *cmd, - int argc, char **args) +grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; struct grub_acpi_rsdp_v10 *rsdp; struct efiemu_acpi_table *cur, *t; grub_err_t err; diff --git a/grub-core/commands/cat.c b/grub-core/commands/cat.c index 77a4cc793..a70118517 100644 --- a/grub-core/commands/cat.c +++ b/grub-core/commands/cat.c @@ -33,9 +33,9 @@ static const struct grub_arg_option options[] = }; static grub_err_t -grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; int dos = 0; grub_file_t file; char buf[GRUB_DISK_SECTOR_SIZE]; diff --git a/grub-core/commands/echo.c b/grub-core/commands/echo.c index 4fea091cb..6bc00eae8 100644 --- a/grub-core/commands/echo.c +++ b/grub-core/commands/echo.c @@ -30,9 +30,9 @@ static const struct grub_arg_option options[] = }; static grub_err_t -grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; int newline = 1; int i; diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c index 16796febf..ecf2d4133 100644 --- a/grub-core/commands/extcmd.c +++ b/grub-core/commands/extcmd.c @@ -21,20 +21,31 @@ #include #include #include +#include -static grub_err_t -grub_extcmd_dispatcher (struct grub_command *cmd, - int argc, char **args) +grub_err_t +grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, + struct grub_script *script) { int new_argc; char **new_args; struct grub_arg_option *parser; struct grub_arg_list *state; + struct grub_extcmd_context context; int maxargs = 0; grub_err_t ret; - grub_extcmd_t ext; + grub_extcmd_t ext = cmd->data; + + context.state = 0; + context.extcmd = ext; + context.script = script; + + if (! ext->options) + { + ret = (ext->func) (&context, argc, args); + return ret; + } - ext = cmd->data; parser = (struct grub_arg_option *) ext->options; while (parser && (parser++)->doc) maxargs++; @@ -44,8 +55,8 @@ grub_extcmd_dispatcher (struct grub_command *cmd, if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc)) { - ext->state = state; - ret = (ext->func) (ext, new_argc, new_args); + context.state = state; + ret = (ext->func) (&context, new_argc, new_args); grub_free (new_args); } else @@ -56,11 +67,18 @@ grub_extcmd_dispatcher (struct grub_command *cmd, return ret; } +static grub_err_t +grub_extcmd_dispatch (struct grub_command *cmd, int argc, char **args) +{ + return grub_extcmd_dispatcher (cmd, argc, args, 0); +} + grub_extcmd_t -grub_register_extcmd (const char *name, grub_extcmd_func_t func, - unsigned flags, const char *summary, - const char *description, - const struct grub_arg_option *parser) +grub_register_extcmd_prio (const char *name, grub_extcmd_func_t func, + unsigned flags, const char *summary, + const char *description, + const struct grub_arg_option *parser, + int prio) { grub_extcmd_t ext; grub_command_t cmd; @@ -69,8 +87,8 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, if (! ext) return 0; - cmd = grub_register_command_prio (name, grub_extcmd_dispatcher, - summary, description, 1); + cmd = grub_register_command_prio (name, grub_extcmd_dispatch, + summary, description, prio); if (! cmd) { grub_free (ext); @@ -88,6 +106,16 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, return ext; } +grub_extcmd_t +grub_register_extcmd (const char *name, grub_extcmd_func_t func, + unsigned flags, const char *summary, + const char *description, + const struct grub_arg_option *parser) +{ + return grub_register_extcmd_prio (name, func, flags, + summary, description, parser, 1); +} + void grub_unregister_extcmd (grub_extcmd_t ext) { diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index d5f551dbb..df85015a6 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -165,10 +165,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, } static grub_err_t -grub_cmd_hashsum (struct grub_extcmd *cmd, +grub_cmd_hashsum (struct grub_extcmd_context *ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; const char *hashname = NULL; const char *prefix = NULL; const gcry_md_spec_t *hash; @@ -177,7 +177,7 @@ grub_cmd_hashsum (struct grub_extcmd *cmd, unsigned unread = 0; for (i = 0; i < ARRAY_SIZE (aliases); i++) - if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0) + if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0) hashname = aliases[i].hashname; if (state[0].set) hashname = state[0].arg; diff --git a/grub-core/commands/hdparm.c b/grub-core/commands/hdparm.c index a3f8bbff0..54724077d 100644 --- a/grub-core/commands/hdparm.c +++ b/grub-core/commands/hdparm.c @@ -270,9 +270,9 @@ static int get_int_arg (const struct grub_arg_list *state) } static grub_err_t -grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state???? +grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state???? { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; /* Check command line. */ if (argc != 1) diff --git a/grub-core/commands/help.c b/grub-core/commands/help.c index e7d108c33..1ca46aa7e 100644 --- a/grub-core/commands/help.c +++ b/grub-core/commands/help.c @@ -27,7 +27,7 @@ #include static grub_err_t -grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, +grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, char **args) { int cnt = 0; @@ -112,7 +112,8 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, if (cnt++ > 0) grub_printf ("\n\n"); - if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) + if ((cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) && + ! (cmd->flags & GRUB_COMMAND_FLAG_DYNCMD)) grub_arg_show_help ((grub_extcmd_t) cmd->data); else grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary), diff --git a/grub-core/commands/hexdump.c b/grub-core/commands/hexdump.c index c1d4ecba9..6c518f649 100644 --- a/grub-core/commands/hexdump.c +++ b/grub-core/commands/hexdump.c @@ -34,9 +34,9 @@ static const struct grub_arg_option options[] = { }; static grub_err_t -grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; char buf[GRUB_DISK_SECTOR_SIZE * 4]; grub_ssize_t size, length; grub_disk_addr_t skip; diff --git a/grub-core/commands/i386/cpuid.c b/grub-core/commands/i386/cpuid.c index 6eebf91a1..412b284d0 100644 --- a/grub-core/commands/i386/cpuid.c +++ b/grub-core/commands/i386/cpuid.c @@ -43,7 +43,7 @@ static const struct grub_arg_option options[] = unsigned char grub_cpuid_has_longmode = 0; static grub_err_t -grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)), +grub_cmd_cpuid (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c index 4afc43358..7ecfe7454 100644 --- a/grub-core/commands/i386/pc/drivemap.c +++ b/grub-core/commands/i386/pc/drivemap.c @@ -196,13 +196,13 @@ list_mappings (void) } static grub_err_t -grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args) +grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args) { - if (cmd->state[OPTIDX_LIST].set) + if (ctxt->state[OPTIDX_LIST].set) { return list_mappings (); } - else if (cmd->state[OPTIDX_RESET].set) + else if (ctxt->state[OPTIDX_RESET].set) { /* Reset: just delete all mappings, freeing their memory. */ drivemap_node_t *curnode = map_head; @@ -216,7 +216,7 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args) map_head = 0; return GRUB_ERR_NONE; } - else if (!cmd->state[OPTIDX_SWAP].set && argc == 0) + else if (!ctxt->state[OPTIDX_SWAP].set && argc == 0) { /* No arguments */ return list_mappings (); @@ -248,11 +248,11 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args) } /* Set the mapping for the disk (overwrites any existing mapping). */ grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n", - cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping", + ctxt->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping", args[1], mapto, args[0], mapfrom); err = drivemap_set (mapto, mapfrom); /* If -s, perform the reverse mapping too (only if the first was OK). */ - if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE) + if (ctxt->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE) err = drivemap_set (mapfrom, mapto); return err; } diff --git a/grub-core/commands/i386/pc/halt.c b/grub-core/commands/i386/pc/halt.c index c237fe361..1e0aefa50 100644 --- a/grub-core/commands/i386/pc/halt.c +++ b/grub-core/commands/i386/pc/halt.c @@ -93,12 +93,12 @@ grub_halt (int no_apm) } static grub_err_t -grub_cmd_halt (grub_extcmd_t cmd, +grub_cmd_halt (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; int no_apm = 0; if (state[0].set) no_apm = 1; diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c index 6c5602dec..1f506b3cd 100644 --- a/grub-core/commands/i386/pc/sendkey.c +++ b/grub-core/commands/i386/pc/sendkey.c @@ -284,9 +284,9 @@ grub_sendkey_preboot (int noret __attribute__ ((unused))) } static grub_err_t -grub_cmd_sendkey (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; auto int find_key_code (char *key); auto int find_ascii_code (char *key); diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c index 474c8712e..bd0183794 100644 --- a/grub-core/commands/iorw.c +++ b/grub-core/commands/iorw.c @@ -36,7 +36,7 @@ static const struct grub_arg_option options[] = static grub_err_t -grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) +grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv) { grub_target_addr_t addr; grub_uint32_t value = 0; @@ -46,7 +46,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); - switch (cmd->cmd->name[sizeof ("in") - 1]) + switch (ctxt->extcmd->cmd->name[sizeof ("in") - 1]) { case 'l': value = grub_inl (addr); @@ -61,10 +61,10 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) break; } - if (cmd->state[0].set) + if (ctxt->state[0].set) { grub_snprintf (buf, sizeof (buf), "%x", value); - grub_env_set (cmd->state[0].arg, buf); + grub_env_set (ctxt->state[0].arg, buf); } else grub_printf ("0x%x\n", value); diff --git a/grub-core/commands/keystatus.c b/grub-core/commands/keystatus.c index 838792889..c83c00560 100644 --- a/grub-core/commands/keystatus.c +++ b/grub-core/commands/keystatus.c @@ -34,11 +34,11 @@ static const struct grub_arg_option options[] = #define grub_cur_term_input grub_term_get_current_input () static grub_err_t -grub_cmd_keystatus (grub_extcmd_t cmd, +grub_cmd_keystatus (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; int expect_mods = 0; int mods; diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c index d763b2d5e..381810a92 100644 --- a/grub-core/commands/loadenv.c +++ b/grub-core/commands/loadenv.c @@ -111,11 +111,11 @@ read_envblk_file (grub_file_t file) } static grub_err_t -grub_cmd_load_env (grub_extcmd_t cmd, +grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; grub_file_t file; grub_envblk_t envblk; @@ -143,11 +143,11 @@ grub_cmd_load_env (grub_extcmd_t cmd, } static grub_err_t -grub_cmd_list_env (grub_extcmd_t cmd, +grub_cmd_list_env (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; grub_file_t file; grub_envblk_t envblk; @@ -280,9 +280,9 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, } static grub_err_t -grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; grub_file_t file; grub_envblk_t envblk; struct blocklist *head = 0; diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c index 9ee0a7a31..b91ef2942 100644 --- a/grub-core/commands/ls.c +++ b/grub-core/commands/ls.c @@ -248,9 +248,9 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) } static grub_err_t -grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; if (argc == 0) grub_ls_list_devices (state[0].set); diff --git a/grub-core/commands/lspci.c b/grub-core/commands/lspci.c index a69bb35ad..bc52e060a 100644 --- a/grub-core/commands/lspci.c +++ b/grub-core/commands/lspci.c @@ -211,11 +211,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } static grub_err_t -grub_cmd_lspci (grub_extcmd_t cmd, +grub_cmd_lspci (grub_extcmd_context_t ctxt, int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - iospace = cmd->state[0].set; + iospace = ctxt->state[0].set; grub_pci_iterate (grub_lspci_iter); return GRUB_ERR_NONE; } diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c index 6a4d43be2..d28f45ec1 100644 --- a/grub-core/commands/memrw.c +++ b/grub-core/commands/memrw.c @@ -35,7 +35,7 @@ static const struct grub_arg_option options[] = static grub_err_t -grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) +grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv) { grub_target_addr_t addr; grub_uint32_t value = 0; @@ -45,7 +45,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments"); addr = grub_strtoul (argv[0], 0, 0); - switch (cmd->cmd->name[sizeof ("read_") - 1]) + switch (ctxt->extcmd->cmd->name[sizeof ("read_") - 1]) { case 'd': value = *((volatile grub_uint32_t *) addr); @@ -60,10 +60,10 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) break; } - if (cmd->state[0].set) + if (ctxt->state[0].set) { grub_snprintf (buf, sizeof (buf), "%x", value); - grub_env_set (cmd->state[0].arg, buf); + grub_env_set (ctxt->state[0].arg, buf); } else grub_printf ("0x%x\n", value); diff --git a/grub-core/commands/probe.c b/grub-core/commands/probe.c index c2cc599e9..f3941e029 100644 --- a/grub-core/commands/probe.c +++ b/grub-core/commands/probe.c @@ -45,9 +45,9 @@ static const struct grub_arg_option options[] = }; static grub_err_t -grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; grub_device_t dev; grub_fs_t fs; char *ptr; diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c index 2891d85d7..fff3fb47a 100644 --- a/grub-core/commands/search_wrap.c +++ b/grub-core/commands/search_wrap.c @@ -50,9 +50,9 @@ enum options }; static grub_err_t -grub_cmd_search (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; const char *var = 0; if (argc == 0) diff --git a/grub-core/commands/setpci.c b/grub-core/commands/setpci.c index aa09f5bbb..5e947cd7d 100644 --- a/grub-core/commands/setpci.c +++ b/grub-core/commands/setpci.c @@ -155,7 +155,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) } static grub_err_t -grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) +grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv) { const char *ptr; unsigned i; @@ -163,14 +163,14 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) pciid_check_value = 0; pciid_check_mask = 0; - if (cmd->state[0].set) + if (ctxt->state[0].set) { - ptr = cmd->state[0].arg; + ptr = ctxt->state[0].arg; pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff); if (grub_errno == GRUB_ERR_BAD_NUMBER) { grub_errno = GRUB_ERR_NONE; - ptr = cmd->state[0].arg; + ptr = ctxt->state[0].arg; } else pciid_check_mask |= 0xffff; @@ -191,11 +191,11 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) check_bus = check_device = check_function = 0; - if (cmd->state[1].set) + if (ctxt->state[1].set) { const char *optr; - ptr = cmd->state[1].arg; + ptr = ctxt->state[1].arg; optr = ptr; bus = grub_strtoul (ptr, (char **) &ptr, 16); if (grub_errno == GRUB_ERR_BAD_NUMBER) @@ -229,8 +229,8 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv) } } - if (cmd->state[2].set) - varname = cmd->state[2].arg; + if (ctxt->state[2].set) + varname = ctxt->state[2].arg; else varname = NULL; diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c index ead279506..ee0875cf7 100644 --- a/grub-core/commands/sleep.c +++ b/grub-core/commands/sleep.c @@ -60,9 +60,9 @@ grub_interruptible_millisleep (grub_uint32_t ms) } static grub_err_t -grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; int n; if (argc != 1) diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 509e9e33f..8153478ed 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -71,9 +71,9 @@ delete_loopback (const char *name) /* The command to add and remove loopback devices. */ static grub_err_t -grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = state = cmd->state; + struct grub_arg_list *state = ctxt->state; grub_file_t file; struct grub_loopback *newdev; grub_err_t ret; diff --git a/grub-core/hello/hello.c b/grub-core/hello/hello.c index eff07d941..183ee7798 100644 --- a/grub-core/hello/hello.c +++ b/grub-core/hello/hello.c @@ -27,7 +27,7 @@ #include static grub_err_t -grub_cmd_hello (struct grub_extcmd *cmd __attribute__ ((unused)), +grub_cmd_hello (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { diff --git a/grub-core/kern/i386/coreboot/startup.S b/grub-core/kern/i386/coreboot/startup.S index ec3a0e64b..592073776 100644 --- a/grub-core/kern/i386/coreboot/startup.S +++ b/grub-core/kern/i386/coreboot/startup.S @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). diff --git a/grub-core/kern/i386/ieee1275/startup.S b/grub-core/kern/i386/ieee1275/startup.S index 2a04753df..3ecf09598 100644 --- a/grub-core/kern/i386/ieee1275/startup.S +++ b/grub-core/kern/i386/ieee1275/startup.S @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/grub-core/kern/i386/pc/startup.S b/grub-core/kern/i386/pc/startup.S index b5e9a9b85..9b53deeb2 100644 --- a/grub-core/kern/i386/pc/startup.S +++ b/grub-core/kern/i386/pc/startup.S @@ -100,14 +100,6 @@ VARIABLE(grub_install_dos_part) .long 0xFFFFFFFF VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF -VARIABLE(grub_prefix) - /* to be filled by grub-mkimage */ - - /* - * Leave some breathing room for the prefix. - */ - - . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef APPLE_CC bss_start: @@ -450,6 +442,16 @@ gate_a20_check_state: */ . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_PREFIX +VARIABLE(grub_prefix) + /* to be filled by grub-mkimage */ + + /* + * Leave some breathing room for the prefix. + */ + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END + + /* * grub_exit() diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S index e705953b5..680de9dc4 100644 --- a/grub-core/kern/i386/qemu/startup.S +++ b/grub-core/kern/i386/qemu/startup.S @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Relocate to low memory. First we figure out our location. diff --git a/grub-core/kern/mips/startup.S b/grub-core/kern/mips/startup.S index 134853a9d..6811353ea 100644 --- a/grub-core/kern/mips/startup.S +++ b/grub-core/kern/mips/startup.S @@ -154,7 +154,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index 69fdc3d42..0bfa08992 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -990,7 +990,7 @@ grub_abort (void) grub_exit (); } -#ifndef APPLE_CC +#if ! defined (APPLE_CC) && !defined (GRUB_UTIL) /* GCC emits references to abort(). */ void abort (void) __attribute__ ((alias ("grub_abort"))); #endif diff --git a/grub-core/kern/powerpc/ieee1275/startup.S b/grub-core/kern/powerpc/ieee1275/startup.S index 526df1d91..0b1c23346 100644 --- a/grub-core/kern/powerpc/ieee1275/startup.S +++ b/grub-core/kern/powerpc/ieee1275/startup.S @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_MACHINE_DATA_END + . = _start + GRUB_KERNEL_MACHINE_PREFIX_END codestart: li 2, 0 diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index f0f47416d..f178f5d3c 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -42,7 +42,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = EXT_C(_start) + GRUB_KERNEL_MACHINE_DATA_END + . = EXT_C(_start) + GRUB_KERNEL_MACHINE_PREFIX_END codestart: /* Copy the modules past the end of the kernel image. diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c index d72c8195a..84459b15b 100644 --- a/grub-core/loader/i386/bsd.c +++ b/grub-core/loader/i386/bsd.c @@ -1372,10 +1372,10 @@ grub_bsd_parse_flags (const struct grub_arg_list *state, } static grub_err_t -grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[]) +grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) { kernel_type = KERNEL_TYPE_FREEBSD; - bootflags = grub_bsd_parse_flags (cmd->state, freebsd_flags); + bootflags = grub_bsd_parse_flags (ctxt->state, freebsd_flags); if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) { @@ -1429,16 +1429,16 @@ grub_cmd_freebsd (grub_extcmd_t cmd, int argc, char *argv[]) } static grub_err_t -grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[]) +grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) { grub_uint32_t bootdev; kernel_type = KERNEL_TYPE_OPENBSD; - bootflags = grub_bsd_parse_flags (cmd->state, openbsd_flags); + bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags); - if (cmd->state[OPENBSD_ROOT_ARG].set) + if (ctxt->state[OPENBSD_ROOT_ARG].set) { - const char *arg = cmd->state[OPENBSD_ROOT_ARG].arg; + const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg; int unit, part; if (*(arg++) != 'w' || *(arg++) != 'd') return grub_error (GRUB_ERR_BAD_ARGUMENT, @@ -1459,7 +1459,7 @@ grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[]) else bootdev = 0; - if (cmd->state[OPENBSD_SERIAL_ARG].set) + if (ctxt->state[OPENBSD_SERIAL_ARG].set) { struct grub_openbsd_bootarg_console serial; char *ptr; @@ -1468,9 +1468,9 @@ grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[]) grub_memset (&serial, 0, sizeof (serial)); - if (cmd->state[OPENBSD_SERIAL_ARG].arg) + if (ctxt->state[OPENBSD_SERIAL_ARG].arg) { - ptr = cmd->state[OPENBSD_SERIAL_ARG].arg; + ptr = ctxt->state[OPENBSD_SERIAL_ARG].arg; if (grub_memcmp (ptr, "com", sizeof ("com") - 1) != 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "only com0-com3 are supported"); @@ -1514,11 +1514,11 @@ grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[]) } static grub_err_t -grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[]) +grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[]) { grub_err_t err; kernel_type = KERNEL_TYPE_NETBSD; - bootflags = grub_bsd_parse_flags (cmd->state, netbsd_flags); + bootflags = grub_bsd_parse_flags (ctxt->state, netbsd_flags); if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE) { @@ -1551,15 +1551,15 @@ grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[]) grub_bsd_add_meta (NETBSD_BTINFO_BOOTPATH, bootpath, sizeof (bootpath)); } - if (cmd->state[NETBSD_ROOT_ARG].set) + if (ctxt->state[NETBSD_ROOT_ARG].set) { char root[GRUB_NETBSD_MAX_ROOTDEVICE_LEN]; grub_memset (root, 0, sizeof (root)); - grub_strncpy (root, cmd->state[NETBSD_ROOT_ARG].arg, + grub_strncpy (root, ctxt->state[NETBSD_ROOT_ARG].arg, sizeof (root) - 1); grub_bsd_add_meta (NETBSD_BTINFO_ROOTDEVICE, root, sizeof (root)); } - if (cmd->state[NETBSD_SERIAL_ARG].set) + if (ctxt->state[NETBSD_SERIAL_ARG].set) { struct grub_netbsd_btinfo_serial serial; char *ptr; @@ -1567,9 +1567,9 @@ grub_cmd_netbsd (grub_extcmd_t cmd, int argc, char *argv[]) grub_memset (&serial, 0, sizeof (serial)); grub_strcpy (serial.devname, "com"); - if (cmd->state[NETBSD_SERIAL_ARG].arg) + if (ctxt->state[NETBSD_SERIAL_ARG].arg) { - ptr = cmd->state[NETBSD_SERIAL_ARG].arg; + ptr = ctxt->state[NETBSD_SERIAL_ARG].arg; if (grub_memcmp (ptr, "com", sizeof ("com") - 1) == 0) { ptr += sizeof ("com") - 1; diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c index 17f850018..92532ed35 100644 --- a/grub-core/loader/xnu.c +++ b/grub-core/loader/xnu.c @@ -1364,15 +1364,15 @@ static const struct grub_arg_option xnu_splash_cmd_options[] = }; static grub_err_t -grub_cmd_xnu_splash (grub_extcmd_t cmd, +grub_cmd_xnu_splash (grub_extcmd_context_t ctxt, int argc, char *args[]) { grub_err_t err; if (argc != 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required"); - if (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && - grub_strcmp (cmd->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, + if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set && + grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg, "stretch") == 0) grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH; else diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c index d127f9baf..1b51dab3a 100644 --- a/grub-core/normal/completion.c +++ b/grub-core/normal/completion.c @@ -500,8 +500,8 @@ grub_normal_do_completion (char *buf, int *restore, fail: if (argc != 0) { - grub_free (argv); grub_free (argv[0]); + grub_free (argv); } grub_free (match); grub_errno = GRUB_ERR_NONE; diff --git a/grub-core/normal/dyncmd.c b/grub-core/normal/dyncmd.c index a3cafa514..3519253f6 100644 --- a/grub-core/normal/dyncmd.c +++ b/grub-core/normal/dyncmd.c @@ -23,16 +23,21 @@ #include #include #include +#include +#include #include static grub_err_t -grub_dyncmd_dispatcher (struct grub_command *cmd, +grub_dyncmd_dispatcher (struct grub_extcmd_context *ctxt, int argc, char **args) { - char *modname = cmd->data; + char *modname; grub_dl_t mod; grub_err_t ret; + grub_extcmd_t extcmd = ctxt->extcmd; + grub_command_t cmd = extcmd->cmd; + modname = extcmd->data; mod = grub_dl_load (modname); if (mod) { @@ -42,11 +47,17 @@ grub_dyncmd_dispatcher (struct grub_command *cmd, grub_dl_ref (mod); name = (char *) cmd->name; - grub_unregister_command (cmd); + grub_unregister_extcmd (extcmd); cmd = grub_command_find (name); if (cmd) - ret = (cmd->func) (cmd, argc, args); + { + if (cmd->flags & GRUB_COMMAND_FLAG_BLOCKS && + cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) + ret = grub_extcmd_dispatcher (cmd, argc, args, ctxt->script); + else + ret = (cmd->func) (cmd, argc, args); + } else ret = grub_errno; @@ -81,13 +92,14 @@ read_command_list (const char *prefix) for (ptr = grub_command_list; ptr; ptr = next) { next = ptr->next; - if (ptr->func == grub_dyncmd_dispatcher) + if (ptr->flags & GRUB_COMMAND_FLAG_DYNCMD) { if (last) last->next = ptr->next; else grub_command_list = ptr->next; grub_free (ptr); + grub_free (ptr->data); /* extcmd struct */ } else last = ptr; @@ -96,7 +108,7 @@ read_command_list (const char *prefix) for (;; grub_free (buf)) { char *p, *name, *modname; - grub_command_t cmd; + grub_extcmd_t cmd; int prio = 0; buf = grub_file_getline (file); @@ -139,16 +151,20 @@ read_command_list (const char *prefix) continue; } - cmd = grub_register_command_prio (name, - grub_dyncmd_dispatcher, - 0, N_("not loaded"), prio); + cmd = grub_register_extcmd_prio (name, + grub_dyncmd_dispatcher, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_FLAG_EXTCMD + | GRUB_COMMAND_FLAG_CMDLINE + | GRUB_COMMAND_FLAG_DYNCMD, + 0, N_("not loaded"), 0, + prio); if (! cmd) { grub_free (name); grub_free (modname); continue; } - cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD; cmd->data = modname; /* Update the active flag. */ diff --git a/grub-core/script/argv.c b/grub-core/script/argv.c index b69ee39c5..92449138b 100644 --- a/grub-core/script/argv.c +++ b/grub-core/script/argv.c @@ -18,6 +18,7 @@ */ #include +#include #include /* Return nearest power of two that is >= v. */ @@ -55,6 +56,7 @@ grub_script_argv_free (struct grub_script_argv *argv) argv->argc = 0; argv->args = 0; + argv->script = 0; } /* Prepare for next argc. */ @@ -63,7 +65,7 @@ grub_script_argv_next (struct grub_script_argv *argv) { char **p = argv->args; - if (argv->args && argv->args[argv->argc - 1] == 0) + if (argv->args && argv->argc && argv->args[argv->argc - 1] == 0) return 0; p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 2c3772ed8..e71c5345a 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -25,6 +25,7 @@ #include #include #include +#include /* Max digits for a char is 3 (0xFF is 255), similarly for an int it is sizeof (int) * 3, and one extra for a possible -ve sign. */ @@ -129,7 +130,7 @@ grub_env_special (const char *name) static char ** grub_script_env_get (const char *name, grub_script_arg_type_t type) { - struct grub_script_argv result = { 0, 0 }; + struct grub_script_argv result = { 0, 0, 0 }; if (grub_script_argv_next (&result)) goto fail; @@ -247,7 +248,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, int i; char **values = 0; struct grub_script_arg *arg = 0; - struct grub_script_argv result = { 0, 0 }; + struct grub_script_argv result = { 0, 0, 0 }; for (; arglist && arglist->arg; arglist = arglist->next) { @@ -273,6 +274,14 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, grub_free (values); break; + case GRUB_SCRIPT_ARG_TYPE_BLOCK: + if (grub_script_argv_append (&result, "{") || + grub_script_argv_append (&result, arg->str) || + grub_script_argv_append (&result, "}")) + goto fail; + result.script = arg->script; + break; + case GRUB_SCRIPT_ARG_TYPE_TEXT: if (grub_strlen (arg->str) && grub_script_argv_append (&result, arg->str)) @@ -351,7 +360,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) grub_script_function_t func = 0; char errnobuf[18]; char *cmdname; - struct grub_script_argv argv = { 0, 0 }; + struct grub_script_argv argv = { 0, 0, 0 }; /* Lookup the command. */ if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0]) @@ -395,7 +404,14 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute the GRUB command or function. */ if (grubcmd) - ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1); + { + if ((grubcmd->flags & GRUB_COMMAND_FLAG_BLOCKS) && + (grubcmd->flags & GRUB_COMMAND_FLAG_EXTCMD)) + ret = grub_extcmd_dispatcher (grubcmd, argv.argc - 1, argv.args + 1, + argv.script); + else + ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1); + } else ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1); @@ -466,8 +482,7 @@ grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { unsigned i; grub_err_t result; - struct grub_script_argv argv = { 0, 0 }; - + struct grub_script_argv argv = { 0, 0, 0 }; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; if (grub_script_arglist_to_argv (cmdfor->words, &argv)) @@ -537,7 +552,7 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - struct grub_script_argv argv = { 0, 0 }; + struct grub_script_argv argv = { 0, 0, 0 }; cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd; diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c index 64da45ed8..3ab40049f 100644 --- a/grub-core/script/lexer.c +++ b/grub-core/script/lexer.c @@ -38,68 +38,57 @@ grub_script_lexer_deref (struct grub_lexer_param *state) } /* Start recording all characters passing through the lexer. */ -void +unsigned grub_script_lexer_record_start (struct grub_parser_param *parser) { struct grub_lexer_param *lexer = parser->lexerstate; - lexer->record = 1; - lexer->recordpos = 0; - if (lexer->recording) /* reuse last record */ - return; + lexer->record++; + if (lexer->recording) + return lexer->recordpos; + lexer->recordpos = 0; lexer->recordlen = GRUB_LEXER_INITIAL_RECORD_SIZE; lexer->recording = grub_malloc (lexer->recordlen); if (!lexer->recording) { grub_script_yyerror (parser, 0); - lexer->record = 0; lexer->recordlen = 0; } + return lexer->recordpos; } char * -grub_script_lexer_record_stop (struct grub_parser_param *parser) +grub_script_lexer_record_stop (struct grub_parser_param *parser, unsigned offset) { - char *ptr; + int count; char *result; struct grub_lexer_param *lexer = parser->lexerstate; - auto char *compact (char *start, char *end); - char *compact (char *start, char *end) - { - /* Delete '{' and '}' characters and whitespaces. */ - while (*start && grub_isspace (*start)) start++; - if (*start == '{') start++; - while (*start && grub_isspace (*start)) start++; - - while (*end && grub_isspace (*end)) end--; - if (*end == '}') end--; - while (*end && grub_isspace (*end)) end--; - end[1] = '\0'; - - return start; - } - - if (!lexer->record || !lexer->recording) + if (!lexer->record) return 0; - /* XXX This is not necessary in BASH. */ + lexer->record--; + if (!lexer->recording) + return 0; - ptr = compact (lexer->recording, lexer->recording + lexer->recordpos - 1); - lexer->record = 0; - lexer->recordpos = 0; - - /* This memory would be freed by, grub_script_free. */ - result = grub_script_malloc (parser, grub_strlen (ptr) + 1); - if (result) - grub_strcpy (result, ptr); + count = lexer->recordpos - offset; + result = grub_script_malloc (parser, count + 1); + if (result) { + grub_strncpy (result, lexer->recording + offset, count); + result[count] = '\0'; + } + if (lexer->record == 0) + { + grub_free (lexer->recording); + lexer->recording = 0; + lexer->recordlen = 0; + lexer->recordpos = 0; + } return result; } -#define MAX(a,b) ((a) < (b) ? (b) : (a)) - /* Record STR if input recording is enabled. */ void grub_script_lexer_record (struct grub_parser_param *parser, char *str) @@ -108,21 +97,20 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) char *old; struct grub_lexer_param *lexer = parser->lexerstate; - if (!lexer->record) + if (!lexer->record || !lexer->recording) return; len = grub_strlen (str); if (lexer->recordpos + len + 1 > lexer->recordlen) { old = lexer->recording; - lexer->recordlen = MAX (len, lexer->recordlen) * 2; + lexer->recordlen = grub_max (len, lexer->recordlen) * 2; lexer->recording = grub_realloc (lexer->recording, lexer->recordlen); if (!lexer->recording) { grub_free (old); - lexer->record = 0; lexer->recordpos = 0; - lexer->recordlen /= 2; + lexer->recordlen = 0; grub_script_yyerror (parser, 0); return; } @@ -131,76 +119,86 @@ grub_script_lexer_record (struct grub_parser_param *parser, char *str) lexer->recordpos += len; } -/* Append '\n' to SRC, before '\0' */ -static char * -append_newline (const char *src) -{ - char *line; - grub_size_t len; - - len = grub_strlen (src); - line = grub_malloc (len + 2); - if (!line) - return 0; - - grub_strcpy (line, src); - - line[len] = '\n'; - line[len + 1] = '\0'; - return line; -} - /* Read next line of input if necessary, and set yyscanner buffers. */ int -grub_script_lexer_yywrap (struct grub_parser_param *parserstate) +grub_script_lexer_yywrap (struct grub_parser_param *parserstate, + const char *input) { int len; - char *line; - char *line2; + char *p = 0; + char *line = 0; YY_BUFFER_STATE buffer; struct grub_lexer_param *lexerstate = parserstate->lexerstate; - if (!lexerstate->refs) - return 0; + if (! lexerstate->refs && ! lexerstate->prefix && ! input) + return 1; - if (!lexerstate->getline) + if (! lexerstate->getline && ! input) { grub_script_yyerror (parserstate, "unexpected end of file"); - return 0; + return 1; } line = 0; - buffer = 0; - lexerstate->getline (&line, 1); - if (!line) - { - grub_script_yyerror (parserstate, 0); /* XXX this could be for ^C case? */ - return 0; - } - - len = grub_strlen (line); - if (line[len - 1] == '\n') - { - buffer = yy_scan_string (line, lexerstate->yyscanner); - } + if (! input) + lexerstate->getline (&line, 1); else + line = grub_strdup (input); + + /* Ensure '\n' at the end. */ + if (line && line[0] == '\0') { - line2 = append_newline (line); - if (line2) - { - buffer = yy_scan_string (line2, lexerstate->yyscanner); - grub_free (line2); - } + grub_free (line); + line = grub_strdup ("\n"); } + if (line && (len = grub_strlen(line)) && line[len - 1] != '\n') + { + p = grub_realloc (line, len + 2); + if (p) + { + p[len++] = '\n'; + p[len] = '\0'; + } + line = p; + } + + if (! line) + { + grub_script_yyerror (parserstate, "out of memory"); + return 1; + } + + /* Prepend any left over unput-text. */ + if (lexerstate->prefix) + { + int plen = grub_strlen (lexerstate->prefix); + + p = grub_malloc (len + plen + 1); + if (! p) + { + grub_free (line); + return 1; + } + grub_strcpy (p, lexerstate->prefix); + lexerstate->prefix = 0; + + grub_strcpy (p + plen, line); + grub_free (line); + + line = p; + len = len + plen; + } + + buffer = yy_scan_string (line, lexerstate->yyscanner); grub_free (line); - if (!buffer) + + if (! buffer) { grub_script_yyerror (parserstate, 0); - return 0; + return 1; } - - return 1; + return 0; } struct grub_lexer_param * @@ -208,7 +206,6 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script, grub_reader_getline_t getline) { int len; - char *script2; YY_BUFFER_STATE buffer; struct grub_lexer_param *lexerstate; @@ -232,34 +229,18 @@ grub_script_lexer_init (struct grub_parser_param *parser, char *script, return 0; } - buffer = 0; - script = script ? : "\n"; - len = grub_strlen (script); + yyset_extra (parser, lexerstate->yyscanner); + parser->lexerstate = lexerstate; - if (len != 0 && script[len - 1] == '\n') - { - buffer = yy_scan_string (script, lexerstate->yyscanner); - } - else - { - script2 = append_newline (script); - if (script2) - { - buffer = yy_scan_string (script2, lexerstate->yyscanner); - grub_free (script2); - } - } - - if (!buffer) + if (grub_script_lexer_yywrap (parser, script ?: "\n")) { + parser->lexerstate = 0; yylex_destroy (lexerstate->yyscanner); grub_free (lexerstate->yyscanner); - grub_free (lexerstate->text); grub_free (lexerstate); return 0; } - yyset_extra (parser, lexerstate->yyscanner); return lexerstate; } diff --git a/grub-core/script/main.c b/grub-core/script/main.c index 7caeb2661..6daace287 100644 --- a/grub-core/script/main.c +++ b/grub-core/script/main.c @@ -35,7 +35,7 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) grub_script_execute (parsed_script); /* The parsed script was executed, throw it away. */ - grub_script_free (parsed_script); + grub_script_unref (parsed_script); } return grub_errno; diff --git a/grub-core/script/parser.y b/grub-core/script/parser.y index 99cd2ee31..3faaf4736 100644 --- a/grub-core/script/parser.y +++ b/grub-core/script/parser.y @@ -20,6 +20,7 @@ %{ #include #include +#include #define YYFREE grub_free #define YYMALLOC grub_malloc @@ -34,6 +35,11 @@ struct grub_script_arglist *arglist; struct grub_script_arg *arg; char *string; + struct { + unsigned offset; + struct grub_script_mem *memory; + struct grub_script *scripts; + }; } %token GRUB_PARSER_TOKEN_BAD @@ -74,6 +80,7 @@ %token GRUB_PARSER_TOKEN_NAME "name" %token GRUB_PARSER_TOKEN_WORD "word" +%type block block0 %type word argument arguments0 arguments1 %type script_init script @@ -146,6 +153,74 @@ argument : "case" { $$ = grub_script_add_arglist (state, 0, $1); } | word { $$ = $1; } ; +/* + Block parameter is passed to commands in two forms: as unparsed + string and as pre-parsed grub_script object. Passing as grub_script + object makes memory management difficult, because: + + (1) Command may want to keep a reference to grub_script objects for + later use, so script framework may not free the grub_script + object after command completes. + + (2) Command may get called multiple times with same grub_script + object under loops, so we should not let command implementation + to free the grub_script object. + + To solve above problems, we rely on reference counting for + grub_script objects. Commands that want to keep the grub_script + object must take a reference to it. + + Other complexity comes with arbitrary nesting of grub_script + objects: a grub_script object may have commands with several block + parameters, and each block parameter may further contain multiple + block parameters nested. We use temporary variable, state->scripts + to collect nested child scripts (that are linked by siblings and + children members), and will build grub_scripts tree from bottom. + */ +block: "{" + { + grub_script_lexer_ref (state->lexerstate); + $$ = grub_script_lexer_record_start (state); + $$ = grub_script_mem_record (state); + + /* save currently known scripts. */ + $$ = state->scripts; + state->scripts = 0; + } + commands1 delimiters0 "}" + { + char *p; + struct grub_script_mem *memory; + struct grub_script *s = $2; + + memory = grub_script_mem_record_stop (state, $2); + if ((p = grub_script_lexer_record_stop (state, $2))) + *grub_strrchr (p, '}') = '\0'; + + $$ = grub_script_arg_add (state, 0, GRUB_SCRIPT_ARG_TYPE_BLOCK, p); + if (! $$ || ! ($$->script = grub_script_create ($3, memory))) + grub_script_mem_free (memory); + + else { + /* attach nested scripts to $$->script as children */ + $$->script->children = state->scripts; + + /* restore old scripts; append $$->script to siblings. */ + state->scripts = $2 ?: $$->script; + if (s) { + while (s->next_siblings) + s = s->next_siblings; + s->next_siblings = $$->script; + } + } + + grub_script_lexer_deref (state->lexerstate); + } +; +block0: /* Empty */ { $$ = 0; } + | block { $$ = $1; } +; + arguments0: /* Empty */ { $$ = 0; } | arguments1 { $$ = $1; } ; @@ -161,13 +236,19 @@ arguments1: argument arguments0 } ; -grubcmd: word arguments0 +grubcmd: word arguments0 block0 { - if ($1 && $2) { - $1->next = $2; - $1->argcount += $2->argcount; - $2->argcount = 0; - } + struct grub_script_arglist *x = $2; + + if ($3) + x = grub_script_add_arglist (state, $2, $3); + + if ($1 && x) + { + $1->next = x; + $1->argcount += x->argcount; + x->argcount = 0; + } $$ = grub_script_create_cmdline (state, $1); } ; @@ -191,10 +272,13 @@ commands1: newlines0 command } ; -function: "function" "name" +function: "function" "name" { grub_script_lexer_ref (state->lexerstate); state->func_mem = grub_script_mem_record (state); + + $$ = state->scripts; + state->scripts = 0; } delimiters0 "{" commands1 delimiters1 "}" { @@ -202,9 +286,14 @@ function: "function" "name" state->func_mem = grub_script_mem_record_stop (state, state->func_mem); script = grub_script_create ($6, state->func_mem); - if (script) - grub_script_function_create ($2, script); + if (! script) + grub_script_mem_free (state->func_mem); + else { + script->children = state->scripts; + grub_script_function_create ($2, script); + } + state->scripts = $3; grub_script_lexer_deref (state->lexerstate); } ; @@ -215,14 +304,16 @@ menuentry: "menuentry" } arguments1 { - grub_script_lexer_record_start (state); + $$ = grub_script_lexer_record_start (state); } delimiters0 "{" commands1 delimiters1 "}" { - char *menu_entry; - menu_entry = grub_script_lexer_record_stop (state); + char *def; + def = grub_script_lexer_record_stop (state, $4); + *grub_strrchr(def, '}') = '\0'; + grub_script_lexer_deref (state->lexerstate); - $$ = grub_script_create_cmdmenu (state, $3, menu_entry, 0); + $$ = grub_script_create_cmdmenu (state, $3, def, 0); } ; diff --git a/grub-core/script/script.c b/grub-core/script/script.c index 448bdf775..76d5aa518 100644 --- a/grub-core/script/script.c +++ b/grub-core/script/script.c @@ -54,7 +54,7 @@ grub_script_malloc (struct grub_parser_param *state, grub_size_t size) } /* Free all memory described by MEM. */ -static void +void grub_script_mem_free (struct grub_script_mem *mem) { struct grub_script_mem *memfree; @@ -94,9 +94,21 @@ grub_script_mem_record_stop (struct grub_parser_param *state, void grub_script_free (struct grub_script *script) { - if (!script) + struct grub_script *s; + struct grub_script *t; + + if (! script) return; - grub_script_mem_free (script->mem); + + if (script->mem) + grub_script_mem_free (script->mem); + + s = script->children; + while (s) { + t = s->next_siblings; + grub_script_unref (s); + s = t; + } grub_free (script); } @@ -119,6 +131,8 @@ grub_script_arg_add (struct grub_parser_param *state, return arg; argpart->type = type; + argpart->script = 0; + len = grub_strlen (str) + 1; argpart->str = grub_script_malloc (state, len); if (!argpart->str) @@ -335,16 +349,14 @@ grub_script_create (struct grub_script_cmd *cmd, struct grub_script_mem *mem) struct grub_script *parsed; parsed = grub_malloc (sizeof (*parsed)); - if (!parsed) - { - grub_script_mem_free (mem); - grub_free (cmd); - - return 0; - } + if (! parsed) + return 0; parsed->mem = mem; parsed->cmd = cmd; + parsed->refcnt = 0; + parsed->children = 0; + parsed->next_siblings = 0; return parsed; } @@ -359,7 +371,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline) struct grub_lexer_param *lexstate; struct grub_parser_param *parsestate; - parsed = grub_malloc (sizeof (*parsed)); + parsed = grub_script_create (0, 0); if (!parsed) return 0; @@ -397,6 +409,7 @@ grub_script_parse (char *script, grub_reader_getline_t getline) parsed->mem = grub_script_mem_record_stop (parsestate, membackup); parsed->cmd = parsestate->parsed; + parsed->children = parsestate->scripts; grub_script_lexer_fini (lexstate); grub_free (parsestate); diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index 45760c158..45728dfb4 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -58,6 +58,9 @@ #define YY_INPUT(buf,res,max) do { res = 0; } while (0) /* forward declarations */ +static int grub_lexer_unput (const char *input, yyscan_t yyscanner); +static int grub_lexer_resplit (const char *input, yyscan_t yyscanner); + static void grub_lexer_yyfree (void *, yyscan_t yyscanner); static void* grub_lexer_yyalloc (yy_size_t, yyscan_t yyscanner); static void* grub_lexer_yyrealloc (void*, yy_size_t, yyscan_t yyscanner); @@ -99,7 +102,7 @@ typedef size_t yy_size_t; %option never-interactive %option noyyfree noyyalloc noyyrealloc -%option nounistd nostdinit nodefault noyylineno noyywrap +%option nounistd nostdinit nodefault noyylineno /* Reduce lexer size, by not defining these. */ %option noyy_top_state @@ -118,13 +121,17 @@ CHAR [^{}|&$;<> \t\n\'\"\\] DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:]_]* -ESC \\. +ESC \\(.|\n) +SQCHR [^\'] +DQCHR {ESC}|[^\\\"] +DQSTR \"{DQCHR}*\" +SQSTR \'{SQCHR}*\' SPECIAL \?|\#|\*|\@ VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} -DQSTR \"([^\\\"]|{ESC})*\" -SQSTR \'[^\']*\' WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ +MULTILINE {WORD}?((\"{DQCHR}*)|(\'{SQCHR}*)|(\\\n)) + %x SPLIT %x DQUOTE %x SQUOTE @@ -171,34 +178,32 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ "function" { RECORD; return GRUB_PARSER_TOKEN_FUNCTION; } "menuentry" { RECORD; return GRUB_PARSER_TOKEN_MENUENTRY; } +{MULTILINE} { + if (grub_lexer_unput (yytext, yyscanner)) + return GRUB_PARSER_TOKEN_BAD; + } + {NAME} { RECORD; return GRUB_PARSER_TOKEN_NAME; } {WORD} { RECORD; - /* resplit yytext */ - grub_dprintf ("lexer", "word: [%s]\n", yytext); - yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); - if (yy_scan_string (yytext, yyscanner)) - { - yyextra->lexerstate->merge_start = 1; - yy_push_state (SPLIT, yyscanner); - } - else - { - grub_script_yyerror (yyextra, 0); - yypop_buffer_state (yyscanner); - return GRUB_PARSER_TOKEN_WORD; - } + yypush_buffer_state (YY_CURRENT_BUFFER, yyscanner); + if (grub_lexer_resplit (yytext, yyscanner)) + { + yypop_buffer_state (yyscanner); + return GRUB_PARSER_TOKEN_WORD; + } + yyextra->lexerstate->resplit = 1; } - -.|\n { - grub_script_yyerror (yyextra, "unrecognized token"); - return GRUB_PARSER_TOKEN_BAD; +. { + grub_script_yyerror (yyextra, yytext); + return GRUB_PARSER_TOKEN_BAD; } /* Split word into multiple args */ { \\. { COPY (yytext + 1, yyleng - 1); } + \\\n { /* ignore */ } \" { yy_push_state (DQUOTE, yyscanner); ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); @@ -216,6 +221,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ <> { yy_pop_state (yyscanner); yypop_buffer_state (yyscanner); + yyextra->lexerstate->resplit = 0; yyextra->lexerstate->merge_end = 1; ARG (GRUB_SCRIPT_ARG_TYPE_TEXT); } @@ -273,15 +279,20 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ <> { yypop_buffer_state (yyscanner); - if (! grub_script_lexer_yywrap (yyextra)) - { - yyextra->lexerstate->eof = 1; - return GRUB_PARSER_TOKEN_EOF; - } + yyextra->lexerstate->eof = 1; + return GRUB_PARSER_TOKEN_EOF; } - %% +int +yywrap (yyscan_t yyscanner) +{ + if (yyget_extra (yyscanner)->lexerstate->resplit) + return 1; + + return grub_script_lexer_yywrap (yyget_extra (yyscanner), 0); +} + static void grub_lexer_yyfree (void *ptr, yyscan_t yyscanner __attribute__ ((unused))) { @@ -301,8 +312,6 @@ grub_lexer_yyrealloc (void *ptr, yy_size_t size, return grub_realloc (ptr, size); } -#define MAX(a,b) ((a) < (b) ? (b) : (a)) - static void copy_string (struct grub_parser_param *parser, const char *str, unsigned hint) { int size; @@ -312,7 +321,7 @@ static void copy_string (struct grub_parser_param *parser, const char *str, unsi len = hint ? hint : grub_strlen (str); if (parser->lexerstate->used + len >= parser->lexerstate->size) { - size = MAX (len, parser->lexerstate->size) * 2; + size = grub_max (len, parser->lexerstate->size) * 2; ptr = grub_realloc (parser->lexerstate->text, size); if (!ptr) { @@ -326,3 +335,34 @@ static void copy_string (struct grub_parser_param *parser, const char *str, unsi grub_strcpy (parser->lexerstate->text + parser->lexerstate->used - 1, str); parser->lexerstate->used += len; } + +static int +grub_lexer_resplit (const char *text, yyscan_t yyscanner) +{ + /* resplit text */ + if (yy_scan_string (text, yyscanner)) + { + yyget_extra (yyscanner)->lexerstate->merge_start = 1; + yy_push_state (SPLIT, yyscanner); + return 0; + } + grub_script_yyerror (yyget_extra (yyscanner), 0); + return 1; +} + +static int +grub_lexer_unput (const char *text, yyscan_t yyscanner) +{ + struct grub_lexer_param *lexerstate = yyget_extra (yyscanner)->lexerstate; + + if (lexerstate->prefix) + grub_free (lexerstate->prefix); + + lexerstate->prefix = grub_strdup (text); + if (! lexerstate->prefix) + { + grub_script_yyerror (yyget_extra (yyscanner), "out of memory"); + return 1; + } + return 0; +} diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c index 5f88f91ed..3616eb453 100644 --- a/grub-core/term/gfxterm.c +++ b/grub-core/term/gfxterm.c @@ -1113,11 +1113,10 @@ static const struct grub_arg_option background_image_cmd_options[] = }; static grub_err_t -grub_gfxterm_background_image_cmd (grub_extcmd_t cmd __attribute__ ((unused)), - int argc, - char **args) +grub_gfxterm_background_image_cmd (grub_extcmd_context_t ctxt, + int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; /* Check that we have video adapter active. */ if (grub_video_get_info(NULL) != GRUB_ERR_NONE) diff --git a/grub-core/term/serial.c b/grub-core/term/serial.c index 2268788af..394fc1576 100644 --- a/grub-core/term/serial.c +++ b/grub-core/term/serial.c @@ -150,9 +150,9 @@ grub_serial_find (char *name) } static grub_err_t -grub_cmd_serial (grub_extcmd_t cmd, int argc, char **args) +grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) { - struct grub_arg_list *state = cmd->state; + struct grub_arg_list *state = ctxt->state; char pname[40]; char *name = NULL; struct grub_serial_port *port; diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c index 6aafe4dbb..82bf372c0 100644 --- a/grub-core/tests/lib/functional_test.c +++ b/grub-core/tests/lib/functional_test.c @@ -22,7 +22,7 @@ #include static grub_err_t -grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), +grub_functional_test (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { diff --git a/grub-core/tests/test_blockarg.c b/grub-core/tests/test_blockarg.c new file mode 100644 index 000000000..bb6f3c3f0 --- /dev/null +++ b/grub-core/tests/test_blockarg.c @@ -0,0 +1,51 @@ +/* test_blockarg.c - print and execute block argument */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_err_t +test_blockarg (grub_extcmd_context_t ctxt, int argc, char **args) +{ + if (! ctxt->script) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no block parameter"); + + grub_printf ("%s\n", args[argc - 1]); + grub_script_execute (ctxt->script); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(test_blockarg) +{ + cmd = grub_register_extcmd ("test_blockarg", test_blockarg, + GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_BLOCKS, + N_("BLOCK"), + N_("Print and execute block argument."), 0); +} + +GRUB_MOD_FINI(test_blockarg) +{ + grub_unregister_extcmd (cmd); +} diff --git a/include/grub/command.h b/include/grub/command.h index 6bd3d07c9..599b99437 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -37,6 +37,8 @@ #define GRUB_COMMAND_FLAG_EXTCMD 0x10 /* This is an dynamic command. */ #define GRUB_COMMAND_FLAG_DYNCMD 0x20 +/* This command accepts block arguments. */ +#define GRUB_COMMAND_FLAG_BLOCKS 0x40 struct grub_command; diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h index 03eaba8f8..773e47854 100644 --- a/include/grub/extcmd.h +++ b/include/grub/extcmd.h @@ -21,10 +21,12 @@ #include #include +#include struct grub_extcmd; +struct grub_extcmd_context; -typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd *cmd, +typedef grub_err_t (*grub_extcmd_func_t) (struct grub_extcmd_context *ctxt, int argc, char **args); /* The argcmd description. */ @@ -38,11 +40,21 @@ struct grub_extcmd const struct grub_arg_option *options; void *data; - - struct grub_arg_list *state; }; typedef struct grub_extcmd *grub_extcmd_t; +/* Command context for each instance of execution. */ +struct grub_extcmd_context +{ + struct grub_extcmd *extcmd; + + struct grub_arg_list *state; + + /* Script parameter, if any. */ + struct grub_script *script; +}; +typedef struct grub_extcmd_context *grub_extcmd_context_t; + grub_extcmd_t grub_register_extcmd (const char *name, grub_extcmd_func_t func, unsigned flags, @@ -50,6 +62,18 @@ grub_extcmd_t grub_register_extcmd (const char *name, const char *description, const struct grub_arg_option *parser); +grub_extcmd_t grub_register_extcmd_prio (const char *name, + grub_extcmd_func_t func, + unsigned flags, + const char *summary, + const char *description, + const struct grub_arg_option *parser, + int prio); + void grub_unregister_extcmd (grub_extcmd_t cmd); +grub_err_t +grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args, + struct grub_script *script); + #endif /* ! GRUB_EXTCMD_HEADER */ diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 7763e488c..47eb6c9bd 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -34,14 +34,17 @@ /* The offset of GRUB_INSTALL_BSD_PART. */ #define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_I386_PC_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_I386_PC_DATA_END 0x5c +/* The offset of multiboot signature. */ +#define GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE 0x1c /* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) +#define GRUB_KERNEL_I386_PC_RAW_SIZE 0x5D8 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX GRUB_KERNEL_I386_PC_RAW_SIZE + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_PREFIX_END (GRUB_KERNEL_I386_PC_PREFIX + 0x40) /* The segment where the kernel is loaded. */ #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 @@ -65,7 +68,7 @@ #define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 /* End of the data section. */ -#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 +#define GRUB_KERNEL_I386_QEMU_PREFIX_END 0x50 #define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 @@ -82,7 +85,7 @@ #define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 /* End of the data section. */ -#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END 0x114 #define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 @@ -91,7 +94,7 @@ #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 #define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 -#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END 0x44 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 @@ -105,29 +108,29 @@ #define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 #define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE -#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_I386_EFI_PREFIX 0x8 /* End of the data section. */ -#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 +#define GRUB_KERNEL_I386_EFI_PREFIX_END 0x50 /* The offset of GRUB_PREFIX. */ #define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 /* End of the data section. */ -#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 +#define GRUB_KERNEL_X86_64_EFI_PREFIX_END 0x50 #define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 -#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_PREFIX_END 0x42 #define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 #define GRUB_KERNEL_I386_MULTIBOOT_PREFIX GRUB_KERNEL_I386_COREBOOT_PREFIX -#define GRUB_KERNEL_I386_MULTIBOOT_DATA_END GRUB_KERNEL_I386_COREBOOT_DATA_END +#define GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END GRUB_KERNEL_I386_COREBOOT_PREFIX_END #define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 -#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_PREFIX_END 0x42 #define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 #define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 @@ -157,7 +160,7 @@ #define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) #define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_KERNEL_MACHINE_PREFIX_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX_END) #define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) #define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) #define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 844ef7930..172856e8a 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -40,8 +40,13 @@ struct grub_script_cmd struct grub_script { + unsigned refcnt; struct grub_script_mem *mem; struct grub_script_cmd *cmd; + + /* grub_scripts from block arguments. */ + struct grub_script *next_siblings; + struct grub_script *children; }; typedef enum @@ -50,7 +55,8 @@ typedef enum GRUB_SCRIPT_ARG_TYPE_TEXT, GRUB_SCRIPT_ARG_TYPE_DQVAR, GRUB_SCRIPT_ARG_TYPE_DQSTR, - GRUB_SCRIPT_ARG_TYPE_SQSTR + GRUB_SCRIPT_ARG_TYPE_SQSTR, + GRUB_SCRIPT_ARG_TYPE_BLOCK } grub_script_arg_type_t; /* A part of an argument. */ @@ -60,6 +66,9 @@ struct grub_script_arg char *str; + /* Parsed block argument. */ + struct grub_script *script; + /* Next argument part. */ struct grub_script_arg *next; }; @@ -69,6 +78,7 @@ struct grub_script_argv { unsigned argc; char **args; + struct grub_script *script; }; /* A complete argument. It consists of a list of one or more `struct @@ -194,6 +204,12 @@ struct grub_lexer_param /* Type of text. */ grub_script_arg_type_t type; + /* Flag to indicate resplit in progres. */ + unsigned resplit; + + /* Text that is unput. */ + char *prefix; + /* Flex scanner. */ void *yyscanner; @@ -217,6 +233,9 @@ struct grub_parser_param /* The memory that was used while parsing and scanning. */ struct grub_script_mem *memused; + /* The block argument scripts. */ + struct grub_script *scripts; + /* The result of the parser. */ struct grub_script_cmd *parsed; @@ -226,6 +245,8 @@ struct grub_parser_param void grub_script_init (void); void grub_script_fini (void); +void grub_script_mem_free (struct grub_script_mem *mem); + void grub_script_argv_free (struct grub_script_argv *argv); int grub_script_argv_next (struct grub_script_argv *argv); int grub_script_argv_append (struct grub_script_argv *argv, const char *s); @@ -287,9 +308,9 @@ struct grub_lexer_param *grub_script_lexer_init (struct grub_parser_param *parse void grub_script_lexer_fini (struct grub_lexer_param *); void grub_script_lexer_ref (struct grub_lexer_param *); void grub_script_lexer_deref (struct grub_lexer_param *); -void grub_script_lexer_record_start (struct grub_parser_param *); -char *grub_script_lexer_record_stop (struct grub_parser_param *); -int grub_script_lexer_yywrap (struct grub_parser_param *); +unsigned grub_script_lexer_record_start (struct grub_parser_param *); +char *grub_script_lexer_record_stop (struct grub_parser_param *, unsigned); +int grub_script_lexer_yywrap (struct grub_parser_param *, const char *input); void grub_script_lexer_record (struct grub_parser_param *, char *); /* Functions to track allocated memory. */ @@ -368,4 +389,24 @@ grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *c grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline); +static inline struct grub_script * +grub_script_ref (struct grub_script *script) +{ + if (script) + script->refcnt++; + return script; +} + +static inline void +grub_script_unref (struct grub_script *script) +{ + if (! script) + return; + + if (script->refcnt == 0) + grub_script_free (script); + else + script->refcnt--; +} + #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/tests/grub_script_blockarg.in b/tests/grub_script_blockarg.in new file mode 100644 index 000000000..783cee8e0 --- /dev/null +++ b/tests/grub_script_blockarg.in @@ -0,0 +1,41 @@ +#! /bin/bash + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +error_if_not () { + if test "$1" != "$2"; then + echo "[$1]" != "[$2]" + exit 1 + fi +} + +cmd='test_blockarg { true }' +v=`echo "$cmd" | @builddir@/grub-shell` +error_if_not "$v" '{ true }' + +tmp=`mktemp` +cmd='test_blockarg { test_blockarg { true } }' +echo "$cmd" | @builddir@/grub-shell >$tmp +error_if_not "`head -n1 $tmp|tail -n1`" '{ test_blockarg { true } }' +error_if_not "`head -n2 $tmp|tail -n1`" '{ true }' + +cmd='test_blockarg { test_blockarg { test_blockarg { true } }; test_blockarg { true } }' +echo "$cmd" | @builddir@/grub-shell >$tmp +error_if_not "`head -n1 $tmp|tail -n1`" '{ test_blockarg { test_blockarg { true } }; test_blockarg { true } }' +error_if_not "`head -n2 $tmp|tail -n1`" '{ test_blockarg { true } }' +error_if_not "`head -n3 $tmp|tail -n1`" '{ true }' +error_if_not "`head -n4 $tmp|tail -n1`" '{ true }' diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in index 554dd68ed..9415a3f73 100644 --- a/tests/grub_script_echo1.in +++ b/tests/grub_script_echo1.in @@ -57,3 +57,45 @@ e"$foo"${bar}o hello world foo=echo $foo 1234 + +echo "one +" +echo "one +\"" +echo "one +two" + +echo one"two +"three +echo one"two +\""three +echo one"two +\"three\" +four" + + +echo 'one +' +echo 'one +\' +echo 'one +two' +echo one'two +' +echo one'two +\' +echo one'two +\'three + +# echo "one\ +# two" +# echo 'one\ +# two' +# echo foo\ +# bar +# \ +# echo foo +# echo "one +# +# two" + diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4e151dd62..d798ad052 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -63,7 +63,7 @@ struct image_target_desc PLATFORM_FLAGS_LZMA = 1 } flags; unsigned prefix; - unsigned data_end; + unsigned prefix_end; unsigned raw_size; unsigned total_module_size; unsigned kernel_image_size; @@ -86,7 +86,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, - .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .prefix_end = GRUB_KERNEL_I386_COREBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -108,7 +108,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_COREBOOT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_MULTIBOOT_PREFIX, - .data_end = GRUB_KERNEL_I386_MULTIBOOT_DATA_END, + .prefix_end = GRUB_KERNEL_I386_MULTIBOOT_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -130,7 +130,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_PC, .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -148,7 +148,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_PC_PXE, .flags = PLATFORM_FLAGS_LZMA, .prefix = GRUB_KERNEL_I386_PC_PREFIX, - .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .prefix_end = GRUB_KERNEL_I386_PC_PREFIX_END, .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, @@ -166,7 +166,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_EFI_PREFIX, - .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .prefix_end = GRUB_KERNEL_I386_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -188,7 +188,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_I386_IEEE1275, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_I386_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -210,7 +210,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_QEMU, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, - .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .prefix_end = GRUB_KERNEL_I386_QEMU_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .compressed_size = TARGET_NO_FIELD, @@ -228,7 +228,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_EFI, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, - .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .prefix_end = GRUB_KERNEL_X86_64_EFI_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -250,7 +250,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_FLASH, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, @@ -270,7 +270,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_YEELOONG_ELF, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, - .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .prefix_end = GRUB_KERNEL_MIPS_YEELOONG_PREFIX_END, .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, @@ -290,7 +290,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_PPC, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX_END, .raw_size = 0, .total_module_size = TARGET_NO_FIELD, .kernel_image_size = TARGET_NO_FIELD, @@ -312,7 +312,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_SPARC64_RAW, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -330,7 +330,7 @@ struct image_target_desc image_targets[] = .id = IMAGE_SPARC64_AOUT, .flags = PLATFORM_FLAGS_NONE, .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, - .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .prefix_end = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX_END, .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, @@ -578,7 +578,7 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], total_module_size, &start_address, &rel_section, &reloc_size, &align, image_target); - if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) + if (image_target->prefix + strlen (prefix) + 1 > image_target->prefix_end) grub_util_error (_("prefix is too long")); strcpy (kernel_img + image_target->prefix, prefix);