From 2821e6f89beca6d720904d80fc2ee851e9ac301f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 17 Nov 2013 13:58:19 +0000 Subject: [PATCH] Remove use of nested functions from hwmatch. --- debian/patches/gfxpayload_dynamic.patch | 163 ++++++++++++------------ grub-core/commands/i386/pc/hwmatch.c | 159 ++++++++++++----------- 2 files changed, 166 insertions(+), 156 deletions(-) diff --git a/debian/patches/gfxpayload_dynamic.patch b/debian/patches/gfxpayload_dynamic.patch index e6548d3ae..c8b3dfd15 100644 --- a/debian/patches/gfxpayload_dynamic.patch +++ b/debian/patches/gfxpayload_dynamic.patch @@ -5,7 +5,7 @@ Description: Add configure option to enable gfxpayload=keep dynamically Author: Evan Broder Author: Colin Watson Forwarded: no -Last-Update: 2013-11-15 +Last-Update: 2013-11-17 Index: b/configure.ac =================================================================== @@ -53,7 +53,7 @@ Index: b/grub-core/commands/i386/pc/hwmatch.c =================================================================== --- /dev/null +++ b/grub-core/commands/i386/pc/hwmatch.c -@@ -0,0 +1,141 @@ +@@ -0,0 +1,146 @@ +/* hwmatch.c - Match hardware against a whitelist/blacklist. */ +/* + * GRUB -- GRand Unified Bootloader @@ -85,99 +85,104 @@ Index: b/grub-core/commands/i386/pc/hwmatch.c + +GRUB_MOD_LICENSE ("GPLv3+"); + ++/* Context for grub_cmd_hwmatch. */ ++struct hwmatch_ctx ++{ ++ grub_file_t matches_file; ++ int class_match; ++ int match; ++}; ++ ++/* Helper for grub_cmd_hwmatch. */ ++static int ++hwmatch_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) ++{ ++ struct hwmatch_ctx *ctx = data; ++ grub_pci_address_t addr; ++ grub_uint32_t class, baseclass, vendor, device; ++ grub_pci_id_t subpciid; ++ grub_uint32_t subvendor, subdevice, subclass; ++ char *id, *line; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); ++ class = grub_pci_read (addr); ++ baseclass = class >> 24; ++ ++ if (ctx->class_match != baseclass) ++ return 0; ++ ++ vendor = pciid & 0xffff; ++ device = pciid >> 16; ++ ++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR); ++ subpciid = grub_pci_read (addr); ++ ++ subclass = (class >> 16) & 0xff; ++ subvendor = subpciid & 0xffff; ++ subdevice = subpciid >> 16; ++ ++ id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x", ++ vendor, device, subvendor, subdevice, ++ baseclass, subclass); ++ ++ grub_file_seek (ctx->matches_file, 0); ++ while ((line = grub_file_getline (ctx->matches_file)) != NULL) ++ { ++ char *anchored_line; ++ regex_t regex; ++ int ret; ++ ++ if (! *line || *line == '#') ++ { ++ grub_free (line); ++ continue; ++ } ++ ++ anchored_line = grub_xasprintf ("^%s$", line); ++ ret = regcomp (®ex, anchored_line, REG_EXTENDED | REG_NOSUB); ++ grub_free (anchored_line); ++ if (ret) ++ { ++ grub_free (line); ++ continue; ++ } ++ ++ ret = regexec (®ex, id, 0, NULL, 0); ++ regfree (®ex); ++ grub_free (line); ++ if (! ret) ++ { ++ ctx->match = 1; ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ +static grub_err_t +grub_cmd_hwmatch (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ -+ grub_file_t matches_file; -+ int class_match; -+ int match = 0; ++ struct hwmatch_ctx ctx = { .match = 0 }; + char *match_str; + -+ auto int NESTED_FUNC_ATTR hwmatch_iter (grub_pci_device_t dev, -+ grub_pci_id_t pciid); -+ -+ int NESTED_FUNC_ATTR hwmatch_iter (grub_pci_device_t dev, -+ grub_pci_id_t pciid) -+ { -+ grub_pci_address_t addr; -+ grub_uint32_t class, baseclass, vendor, device; -+ grub_pci_id_t subpciid; -+ grub_uint32_t subvendor, subdevice, subclass; -+ char *id, *line; -+ -+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); -+ class = grub_pci_read (addr); -+ baseclass = class >> 24; -+ -+ if (class_match != baseclass) -+ return 0; -+ -+ vendor = pciid & 0xffff; -+ device = pciid >> 16; -+ -+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR); -+ subpciid = grub_pci_read (addr); -+ -+ subclass = (class >> 16) & 0xff; -+ subvendor = subpciid & 0xffff; -+ subdevice = subpciid >> 16; -+ -+ id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x", -+ vendor, device, subvendor, subdevice, -+ baseclass, subclass); -+ -+ grub_file_seek (matches_file, 0); -+ while ((line = grub_file_getline (matches_file)) != NULL) -+ { -+ char *anchored_line; -+ regex_t regex; -+ int ret; -+ -+ if (! *line || *line == '#') -+ { -+ grub_free (line); -+ continue; -+ } -+ -+ anchored_line = grub_xasprintf ("^%s$", line); -+ ret = regcomp (®ex, anchored_line, REG_EXTENDED | REG_NOSUB); -+ grub_free (anchored_line); -+ if (ret) -+ { -+ grub_free (line); -+ continue; -+ } -+ -+ ret = regexec (®ex, id, 0, NULL, 0); -+ regfree (®ex); -+ grub_free (line); -+ if (! ret) -+ { -+ match = 1; -+ return 1; -+ } -+ } -+ -+ return 0; -+ } -+ + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "list file and class required"); + -+ matches_file = grub_file_open (args[0]); -+ if (! matches_file) ++ ctx.matches_file = grub_file_open (args[0]); ++ if (! ctx.matches_file) + return grub_errno; + -+ class_match = grub_strtol (args[1], 0, 10); ++ ctx.class_match = grub_strtol (args[1], 0, 10); + -+ grub_pci_iterate (hwmatch_iter); ++ grub_pci_iterate (hwmatch_iter, &ctx); + -+ match_str = grub_xasprintf ("%d", match); ++ match_str = grub_xasprintf ("%d", ctx.match); + grub_env_set ("match", match_str); + grub_free (match_str); + -+ grub_file_close (matches_file); ++ grub_file_close (ctx.matches_file); + + return GRUB_ERR_NONE; +} diff --git a/grub-core/commands/i386/pc/hwmatch.c b/grub-core/commands/i386/pc/hwmatch.c index 5627eb41d..c9f7c9f19 100644 --- a/grub-core/commands/i386/pc/hwmatch.c +++ b/grub-core/commands/i386/pc/hwmatch.c @@ -29,99 +29,104 @@ GRUB_MOD_LICENSE ("GPLv3+"); +/* Context for grub_cmd_hwmatch. */ +struct hwmatch_ctx +{ + grub_file_t matches_file; + int class_match; + int match; +}; + +/* Helper for grub_cmd_hwmatch. */ +static int +hwmatch_iter (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) +{ + struct hwmatch_ctx *ctx = data; + grub_pci_address_t addr; + grub_uint32_t class, baseclass, vendor, device; + grub_pci_id_t subpciid; + grub_uint32_t subvendor, subdevice, subclass; + char *id, *line; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class = grub_pci_read (addr); + baseclass = class >> 24; + + if (ctx->class_match != baseclass) + return 0; + + vendor = pciid & 0xffff; + device = pciid >> 16; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR); + subpciid = grub_pci_read (addr); + + subclass = (class >> 16) & 0xff; + subvendor = subpciid & 0xffff; + subdevice = subpciid >> 16; + + id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x", + vendor, device, subvendor, subdevice, + baseclass, subclass); + + grub_file_seek (ctx->matches_file, 0); + while ((line = grub_file_getline (ctx->matches_file)) != NULL) + { + char *anchored_line; + regex_t regex; + int ret; + + if (! *line || *line == '#') + { + grub_free (line); + continue; + } + + anchored_line = grub_xasprintf ("^%s$", line); + ret = regcomp (®ex, anchored_line, REG_EXTENDED | REG_NOSUB); + grub_free (anchored_line); + if (ret) + { + grub_free (line); + continue; + } + + ret = regexec (®ex, id, 0, NULL, 0); + regfree (®ex); + grub_free (line); + if (! ret) + { + ctx->match = 1; + return 1; + } + } + + return 0; +} + static grub_err_t grub_cmd_hwmatch (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - grub_file_t matches_file; - int class_match; - int match = 0; + struct hwmatch_ctx ctx = { .match = 0 }; char *match_str; - auto int NESTED_FUNC_ATTR hwmatch_iter (grub_pci_device_t dev, - grub_pci_id_t pciid); - - int NESTED_FUNC_ATTR hwmatch_iter (grub_pci_device_t dev, - grub_pci_id_t pciid) - { - grub_pci_address_t addr; - grub_uint32_t class, baseclass, vendor, device; - grub_pci_id_t subpciid; - grub_uint32_t subvendor, subdevice, subclass; - char *id, *line; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class = grub_pci_read (addr); - baseclass = class >> 24; - - if (class_match != baseclass) - return 0; - - vendor = pciid & 0xffff; - device = pciid >> 16; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_SUBVENDOR); - subpciid = grub_pci_read (addr); - - subclass = (class >> 16) & 0xff; - subvendor = subpciid & 0xffff; - subdevice = subpciid >> 16; - - id = grub_xasprintf ("v%04xd%04xsv%04xsd%04xbc%02xsc%02x", - vendor, device, subvendor, subdevice, - baseclass, subclass); - - grub_file_seek (matches_file, 0); - while ((line = grub_file_getline (matches_file)) != NULL) - { - char *anchored_line; - regex_t regex; - int ret; - - if (! *line || *line == '#') - { - grub_free (line); - continue; - } - - anchored_line = grub_xasprintf ("^%s$", line); - ret = regcomp (®ex, anchored_line, REG_EXTENDED | REG_NOSUB); - grub_free (anchored_line); - if (ret) - { - grub_free (line); - continue; - } - - ret = regexec (®ex, id, 0, NULL, 0); - regfree (®ex); - grub_free (line); - if (! ret) - { - match = 1; - return 1; - } - } - - return 0; - } - if (argc < 2) return grub_error (GRUB_ERR_BAD_ARGUMENT, "list file and class required"); - matches_file = grub_file_open (args[0]); - if (! matches_file) + ctx.matches_file = grub_file_open (args[0]); + if (! ctx.matches_file) return grub_errno; - class_match = grub_strtol (args[1], 0, 10); + ctx.class_match = grub_strtol (args[1], 0, 10); - grub_pci_iterate (hwmatch_iter); + grub_pci_iterate (hwmatch_iter, &ctx); - match_str = grub_xasprintf ("%d", match); + match_str = grub_xasprintf ("%d", ctx.match); grub_env_set ("match", match_str); grub_free (match_str); - grub_file_close (matches_file); + grub_file_close (ctx.matches_file); return GRUB_ERR_NONE; }