From 234d93464adb152ad0c5ba958c5b6cac893a5149 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 08:10:01 +0100 Subject: [PATCH 01/48] * grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays. * grub-core/net/drivers/ieee1275/ofnet.c: Likewise. --- ChangeLog | 5 ++ grub-core/disk/ieee1275/ofdisk.c | 83 ++++++++++++++++---------- grub-core/net/drivers/ieee1275/ofnet.c | 41 ++++++++----- 3 files changed, 81 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 33206cdac..024faf8a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays. + * grub-core/net/drivers/ieee1275/ofnet.c: Likewise. + 2013-12-03 Colin Watson * grub-core/Makefile.core.def (setjmp): Distribute diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index 2a31ecdb1..6870b3958 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -31,11 +31,14 @@ static grub_ieee1275_ihandle_t last_ihandle; struct ofdisk_hash_ent { char *devpath; + char *open_path; + char *grub_devpath; int is_boot; int is_cdrom; /* Pointer to shortest available name on nodes representing canonical names, otherwise NULL. */ const char *shortest; + const char *grub_shortest; struct ofdisk_hash_ent *next; }; @@ -70,12 +73,50 @@ ofdisk_hash_add_real (char *devpath) { struct ofdisk_hash_ent *p; struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)]; + const char *iptr; + char *optr; p = grub_zalloc (sizeof (*p)); if (!p) return NULL; p->devpath = devpath; + + p->grub_devpath = grub_malloc (sizeof ("ieee1275/") + + 2 * grub_strlen (p->devpath)); + + if (!p->grub_devpath) + { + grub_free (p); + return NULL; + } + + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) + { + p->open_path = grub_malloc (grub_strlen (p->devpath) + 3); + if (!p->open_path) + { + grub_free (p->grub_devpath); + grub_free (p); + return NULL; + } + optr = grub_stpcpy (p->open_path, p->devpath); + *optr++ = ':'; + *optr++ = '0'; + *optr = '\0'; + } + else + p->open_path = p->devpath; + + optr = grub_stpcpy (p->grub_devpath, "ieee1275/"); + for (iptr = p->devpath; *iptr; ) + { + if (*iptr == ',') + *optr++ = '\\'; + *optr++ = *iptr++; + } + *optr = 0; + p->next = *head; *head = p; return p; @@ -104,7 +145,8 @@ ofdisk_hash_add (char *devpath, char *curcan) if (!curcan) { - p->shortest = devpath; + p->shortest = p->devpath; + p->grub_shortest = p->grub_devpath; if (check_string_cdrom (devpath)) p->is_cdrom = 1; return p; @@ -125,7 +167,10 @@ ofdisk_hash_add (char *devpath, char *curcan) { if (!pcan->shortest || grub_strlen (pcan->shortest) > grub_strlen (devpath)) - pcan->shortest = devpath; + { + pcan->shortest = p->devpath; + pcan->grub_shortest = p->grub_devpath; + } } return p; @@ -288,21 +333,8 @@ grub_ofdisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, if (!ent->is_boot && ent->is_cdrom) continue; - { - char buffer[sizeof ("ieee1275/") + 2 * grub_strlen (ent->shortest)]; - const char *iptr; - char *optr; - optr = grub_stpcpy (buffer, "ieee1275/"); - for (iptr = ent->shortest; *iptr; ) - { - if (*iptr == ',') - *optr++ = '\\'; - *optr++ = *iptr++; - } - *optr = 0; - if (hook (buffer, hook_data)) - return 1; - } + if (hook (ent->grub_shortest, hook_data)) + return 1; } } return 0; @@ -396,7 +428,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) if (!op) return grub_errno; disk->id = (unsigned long) op; - disk->data = op->devpath; + disk->data = op->open_path; } return 0; @@ -428,20 +460,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) last_ihandle = 0; last_devpath = NULL; - if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0)) - { - char name2[grub_strlen (disk->data) + 3]; - char *p; - - grub_strcpy (name2, disk->data); - p = name2 + grub_strlen (name2); - *p++ = ':'; - *p++ = '0'; - *p = 0; - grub_ieee1275_open (name2, &last_ihandle); - } - else - grub_ieee1275_open (disk->data, &last_ihandle); + grub_ieee1275_open (disk->data, &last_ihandle); if (! last_ihandle) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); last_devpath = disk->data; diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c index 7ecc05571..4483c9122 100644 --- a/grub-core/net/drivers/ieee1275/ofnet.c +++ b/grub-core/net/drivers/ieee1275/ofnet.c @@ -28,6 +28,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); struct grub_ofnetcard_data { char *path; + char *suffix; grub_ieee1275_ihandle_t handle; }; @@ -37,18 +38,7 @@ card_open (struct grub_net_card *dev) int status; struct grub_ofnetcard_data *data = dev->data; - if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX)) - { - char path[grub_strlen (data->path) + - sizeof (":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512")]; - - /* The full string will prevent a bootp packet to be sent. Just put some valid ip in there. */ - grub_snprintf (path, sizeof (path), "%s%s", data->path, - ":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512"); - status = grub_ieee1275_open (path, &(data->handle)); - } - else - status = grub_ieee1275_open (data->path, &(data->handle)); + status = grub_ieee1275_open (data->path, &(data->handle)); if (status) return grub_error (GRUB_ERR_IO, "Couldn't open network card."); @@ -146,8 +136,9 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path) FOR_NET_CARDS (card) { char *bootp_response; - char *cardpath; char *canon; + char c; + struct grub_ofnetcard_data *data; grub_ssize_t size = -1; unsigned int i; @@ -155,8 +146,11 @@ grub_ieee1275_net_config_real (const char *devpath, char **device, char **path) if (card->driver != &ofdriver) continue; - cardpath = ((struct grub_ofnetcard_data *) card->data)->path; - canon = grub_ieee1275_canonicalise_devname (cardpath); + data = card->data; + c = *data->suffix; + *data->suffix = '\0'; + canon = grub_ieee1275_canonicalise_devname (data->path); + *data->suffix = c; if (grub_strcmp (devpath, canon) != 0) { grub_free (canon); @@ -224,7 +218,22 @@ search_net_devices (struct grub_ieee1275_devalias *alias) return 1; } - ofdata->path = grub_strdup (alias->path); +#define SUFFIX ":speed=auto,duplex=auto,1.1.1.1,dummy,1.1.1.1,1.1.1.1,5,5,1.1.1.1,512" + + if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX)) + ofdata->path = grub_malloc (grub_strlen (alias->path) + sizeof (SUFFIX)); + else + ofdata->path = grub_malloc (grub_strlen (alias->path) + 1); + if (!ofdata->path) + { + grub_print_error (); + return 0; + } + ofdata->suffix = grub_stpcpy (ofdata->path, alias->path); + if (!grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_OFNET_SUFFIX)) + grub_memcpy (ofdata->suffix, SUFFIX, sizeof (SUFFIX)); + else + *ofdata->suffix = '\0'; grub_ieee1275_finddevice (ofdata->path, &devhandle); From 40b5739ff955fed86fd859ed0526bf624d8900ef Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 08:26:13 +0100 Subject: [PATCH 02/48] * grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71 minutes. --- ChangeLog | 5 +++++ grub-core/kern/uboot/init.c | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 024faf8a0..5e0da02c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71 + minutes. + 2013-12-04 Vladimir Serbinenko * grub-core/disk/ieee1275/ofdisk.c: Remove variable length arrays. diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c index 9d7924c04..775b689e9 100644 --- a/grub-core/kern/uboot/init.c +++ b/grub-core/kern/uboot/init.c @@ -61,7 +61,13 @@ grub_uboot_get_boot_data (void) static grub_uint64_t uboot_timer_ms (void) { - return (grub_uint64_t) grub_uboot_get_timer (timer_start) / 1000; + static grub_uint32_t last = 0, high = 0; + grub_uint32_t cur = grub_uboot_get_timer (timer_start); + if (cur < last) + high++; + last = cur; + return grub_divmod64 ((((grub_uint64_t) high) << 32) | cur, + 1000, 0); } void From 47f88cc94e1200c3ab5efd5ebc32dfa6f2487dc9 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 08:39:22 +0100 Subject: [PATCH 03/48] * grub-core/kern/efi/efi.c: Remove variable length arrays. --- ChangeLog | 4 ++++ grub-core/kern/efi/efi.c | 13 +++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e0da02c5..c1f2b61c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/kern/efi/efi.c: Remove variable length arrays. + 2013-12-04 Vladimir Serbinenko * grub-core/kern/uboot/init.c (uboot_timer_ms): Fix overflow after 71 diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c index 2a910bbdf..a9b5b3972 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c @@ -741,12 +741,17 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) case GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE: { grub_efi_file_path_device_path_t *fp; - grub_uint8_t buf[(len - 4) * 2 + 1]; + grub_uint8_t *buf; fp = (grub_efi_file_path_device_path_t *) dp; - *grub_utf16_to_utf8 (buf, fp->path_name, - (len - 4) / sizeof (grub_efi_char16_t)) - = '\0'; + buf = grub_malloc ((len - 4) * 2 + 1); + if (buf) + *grub_utf16_to_utf8 (buf, fp->path_name, + (len - 4) / sizeof (grub_efi_char16_t)) + = '\0'; + else + grub_errno = GRUB_ERR_NONE; grub_printf ("/File(%s)", buf); + grub_free (buf); } break; case GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE: From 85eb579ad9e762f711cdcfe973683e7652dae174 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 08:42:35 +0100 Subject: [PATCH 04/48] * include/grub/types.h: Declare all byteswaps as inline functions except compile-time ones. Solves variable shadowing in constructions like cpu_to_le (le_to_cpu(x) + 1). --- ChangeLog | 8 ++++++++ include/grub/types.h | 47 +++++++++++++++++++++----------------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index c1f2b61c7..38e128462 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-12-04 Vladimir Serbinenko + + * include/grub/types.h: Declare all byteswaps as inline functions + except compile-time ones. + + Solves variable shadowing in constructions like + cpu_to_le (le_to_cpu(x) + 1). + 2013-12-04 Vladimir Serbinenko * grub-core/kern/efi/efi.c: Remove variable length arrays. diff --git a/include/grub/types.h b/include/grub/types.h index 8c737aa6f..e8c2f68f9 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -153,11 +153,10 @@ typedef grub_uint64_t grub_off_t; typedef grub_uint64_t grub_disk_addr_t; /* Byte-orders. */ -#define grub_swap_bytes16(x) \ -({ \ - grub_uint16_t _x = (x); \ - (grub_uint16_t) ((_x << 8) | (_x >> 8)); \ -}) +static inline grub_uint16_t grub_swap_bytes16(grub_uint16_t _x) +{ + return (grub_uint16_t) ((_x << 8) | (_x >> 8)); +} #define grub_swap_bytes16_compile_time(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) #define grub_swap_bytes32_compile_time(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000UL) >> 24)) @@ -185,27 +184,25 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) return __builtin_bswap64(x); } #else /* not gcc 4.3 or newer */ -#define grub_swap_bytes32(x) \ -({ \ - grub_uint32_t _x = (x); \ - (grub_uint32_t) ((_x << 24) \ - | ((_x & (grub_uint32_t) 0xFF00UL) << 8) \ - | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) \ - | (_x >> 24)); \ -}) +static inline grub_uint32_t grub_swap_bytes32(grub_uint32_t _x) +{ + return ((_x << 24) + | ((_x & (grub_uint32_t) 0xFF00UL) << 8) + | ((_x & (grub_uint32_t) 0xFF0000UL) >> 8) + | (_x >> 24)); +} -#define grub_swap_bytes64(x) \ -({ \ - grub_uint64_t _x = (x); \ - (grub_uint64_t) ((_x << 56) \ - | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) \ - | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) \ - | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) \ - | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) \ - | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) \ - | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) \ - | (_x >> 56)); \ -}) +static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t _x) +{ + return ((_x << 56) + | ((_x & (grub_uint64_t) 0xFF00ULL) << 40) + | ((_x & (grub_uint64_t) 0xFF0000ULL) << 24) + | ((_x & (grub_uint64_t) 0xFF000000ULL) << 8) + | ((_x & (grub_uint64_t) 0xFF00000000ULL) >> 8) + | ((_x & (grub_uint64_t) 0xFF0000000000ULL) >> 24) + | ((_x & (grub_uint64_t) 0xFF000000000000ULL) >> 40) + | (_x >> 56)); +} #endif /* not gcc 4.3 or newer */ #ifdef GRUB_CPU_WORDS_BIGENDIAN From bb6e299ccbeb4c042c9922ddc3035eab38926303 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 09:48:36 +0100 Subject: [PATCH 05/48] * grub-core/kern/i386/qemu/init.c: Remove variable length arrays. --- ChangeLog | 4 ++++ grub-core/kern/i386/qemu/init.c | 21 ++++++--------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 38e128462..277258148 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/kern/i386/qemu/init.c: Remove variable length arrays. + 2013-12-04 Vladimir Serbinenko * include/grub/types.h: Declare all byteswaps as inline functions diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c index e05ccee96..09da1e97f 100644 --- a/grub-core/kern/i386/qemu/init.c +++ b/grub-core/kern/i386/qemu/init.c @@ -96,17 +96,8 @@ struct iterator_ctx grub_size_t nresources; }; -static int -count_cards (grub_pci_device_t dev __attribute__ ((unused)), - grub_pci_id_t pciid __attribute__ ((unused)), - void *data) -{ - int *cnt = data; - - (*cnt)++; - - return 0; -} +/* We don't support bridges, so can't have more than 32 devices. */ +#define MAX_DEVICES 32 static int find_resources (grub_pci_device_t dev, @@ -116,6 +107,9 @@ find_resources (grub_pci_device_t dev, struct iterator_ctx *ctx = data; int bar; + if (ctx->nresources >= MAX_DEVICES * 6) + return 1; + for (bar = 0; bar < 6; bar++) { grub_pci_address_t addr; @@ -190,13 +184,10 @@ enable_cards (grub_pci_device_t dev, static void grub_pci_assign_addresses (void) { - int ncards = 0; struct iterator_ctx ctx; - grub_pci_iterate (count_cards, &ncards); - { - struct resource resources[ncards * 6]; + struct resource resources[MAX_DEVICES * 6]; int done; unsigned i; ctx.nresources = 0; From cd15c394ccd9b786685c058059ffa386af8e8439 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 10:05:33 +0100 Subject: [PATCH 06/48] * grub-core/osdep/windows/emuconsole.c (grub_console_putchar): Remove variable length arrays. * grub-core/term/efi/console.c (grub_console_putchar): Likewise. --- ChangeLog | 6 ++++++ grub-core/osdep/windows/emuconsole.c | 4 ++-- grub-core/term/efi/console.c | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 277258148..649e86699 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/osdep/windows/emuconsole.c (grub_console_putchar): + Remove variable length arrays. + * grub-core/term/efi/console.c (grub_console_putchar): Likewise. + 2013-12-04 Vladimir Serbinenko * grub-core/kern/i386/qemu/init.c: Remove variable length arrays. diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c index a2acf2637..8d7483c3f 100644 --- a/grub-core/osdep/windows/emuconsole.c +++ b/grub-core/osdep/windows/emuconsole.c @@ -37,7 +37,7 @@ static void grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), const struct grub_unicode_glyph *c) { - TCHAR str[2 + c->ncomb]; + TCHAR str[2 + 30]; unsigned i, j; DWORD written; @@ -47,7 +47,7 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), else str[0] = (c->base & 0xffff); j = 1; - for (i = 0; i < c->ncomb; i++) + for (i = 0; i < c->ncomb && j+1 < ARRAY_SIZE (str); i++) if (c->base < 0xffff) str[j++] = grub_unicode_get_comb (c)[i].code; str[j] = 0; diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index a000fa648..a37eb841c 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -69,7 +69,7 @@ static void grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), const struct grub_unicode_glyph *c) { - grub_efi_char16_t str[2 + c->ncomb]; + grub_efi_char16_t str[2 + 30]; grub_efi_simple_text_output_interface_t *o; unsigned i, j; @@ -84,7 +84,7 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), else str[0] = (grub_efi_char16_t) map_char (c->base & 0xffff); j = 1; - for (i = 0; i < c->ncomb; i++) + for (i = 0; i < c->ncomb && j + 1 < ARRAY_SIZE (str); i++) if (c->base < 0xffff) str[j++] = grub_unicode_get_comb (c)[i].code; str[j] = 0; From 60d5e9cbd928516a0d5623e5ea1d15ff1f122d8d Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 10:08:57 +0100 Subject: [PATCH 07/48] * configure.ac: Add -Wvla if compiler supports it. --- ChangeLog | 4 ++++ configure.ac | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 649e86699..97b03decf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-04 Vladimir Serbinenko + + * configure.ac: Add -Wvla if compiler supports it. + 2013-12-04 Vladimir Serbinenko * grub-core/osdep/windows/emuconsole.c (grub_console_putchar): diff --git a/configure.ac b/configure.ac index e49243c51..888d477d5 100644 --- a/configure.ac +++ b/configure.ac @@ -422,6 +422,26 @@ esac # For gnulib. gl_INIT +WARN_FLAGS="-Wall -W -Wshadow -Wold-style-definition -Wpointer-arith -Wundef -Wextra -Wattributes -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmultichar -Wnonnull -Woverflow -Wparentheses -Wpointer-arith -Wpointer-to-int-cast -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstrict-aliasing -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wnested-externs -Wstrict-prototypes -Wpointer-sign" +EXTRA_WARN_FLAGS="-Wvla" + +HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" + +AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [ + SAVED_CFLAGS="$CFLAGS" + grub_cv_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$HOST_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x" + fi + done + CFLAGS="$SAVED_CFLAGS" +]) + +HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" + # # Check for target programs. # @@ -472,8 +492,6 @@ LDFLAGS="$TARGET_LDFLAGS" LIBS="" # debug flags. -WARN_FLAGS="-Wall -W -Wshadow -Wold-style-definition -Wpointer-arith -Wundef -Wextra -Wattributes -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmultichar -Wnonnull -Woverflow -Wparentheses -Wpointer-arith -Wpointer-to-int-cast -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstrict-aliasing -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wnested-externs -Wstrict-prototypes -Wpointer-sign" -HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations" TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g" @@ -481,6 +499,21 @@ if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align" fi +AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [ + LDFLAGS="$TARGET_LDFLAGS -nostdlib -static" + + grub_cv_target_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$TARGET_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x" + fi + done +]) + +TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags" + AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang] [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [[ From 6f07c4e4070f674f64e079f33ef7da949e51b21a Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 10:25:53 +0100 Subject: [PATCH 08/48] Pass font config to config.h and not by TARGET_CFLAGS as adding arguments doesn't work if TARGET_CFLAGS is specified on command line. --- ChangeLog | 6 ++++++ config.h.in | 1 + configure.ac | 6 ++++++ grub-core/Makefile.am | 4 ---- grub-core/Makefile.core.def | 1 - grub-core/font/font.c | 6 +++--- grub-core/normal/charset.c | 4 ++-- include/grub/term.h | 2 +- 8 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 97b03decf..acff45e79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-04 Vladimir Serbinenko + + Pass font config to config.h and not by TARGET_CFLAGS as adding + arguments doesn't work if TARGET_CFLAGS is specified on command + line. + 2013-12-04 Vladimir Serbinenko * configure.ac: Add -Wvla if compiler supports it. diff --git a/config.h.in b/config.h.in index 436512f2b..33a3a2487 100644 --- a/config.h.in +++ b/config.h.in @@ -28,6 +28,7 @@ #elif defined (GRUB_UTIL) || !defined (GRUB_MACHINE) #include #else +#define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@ /* Define if C symbols get an underscore after compilation. */ #define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ /* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */ diff --git a/configure.ac b/configure.ac index 888d477d5..69be355c4 100644 --- a/configure.ac +++ b/configure.ac @@ -1555,6 +1555,12 @@ AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) +if test x$FONT_SOURCE != x ; then + HAVE_FONT_SOURCE=1 +else + HAVE_FONT_SOURCE=0 +fi +AC_SUBST(HAVE_FONT_SOURCE) AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 9bc68f77b..f69da18c3 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -10,10 +10,6 @@ CCAS=$(TARGET_CC) RANLIB=$(TARGET_RANLIB) STRIP=$(TARGET_STRIP) -if COND_HAVE_FONT_SOURCE -TARGET_CFLAGS += -DUSE_ASCII_FALLBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1 -endif - MACHO2IMG=$(top_builddir)/grub-macho2img AM_CFLAGS = $(TARGET_CFLAGS) diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index c2b01d437..57abb4910 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -88,7 +88,6 @@ kernel = { mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; mips_arc_cppflags = '-DGRUB_DECOMPRESSOR_LINK_ADDR=$(TARGET_DECOMPRESSOR_LINK_ADDR)'; - mips_loongson_cppflags = '-DUSE_ASCII_FALLBACK'; i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)'; emu_cflags = '$(CFLAGS_GNULIB)'; emu_cppflags = '$(CPPFLAGS_GNULIB)'; diff --git a/grub-core/font/font.c b/grub-core/font/font.c index d603dbe04..14b93e172 100644 --- a/grub-core/font/font.c +++ b/grub-core/font/font.c @@ -33,7 +33,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); -#ifdef USE_ASCII_FALLBACK +#if HAVE_FONT_SOURCE #include "ascii.h" #endif @@ -110,14 +110,14 @@ static struct grub_font null_font; /* Flag to ensure module is initialized only once. */ static grub_uint8_t font_loader_initialized; -#ifdef USE_ASCII_FALLBACK +#if HAVE_FONT_SOURCE static struct grub_font_glyph *ascii_font_glyph[0x80]; #endif static struct grub_font_glyph * ascii_glyph_lookup (grub_uint32_t code) { -#ifdef USE_ASCII_FALLBACK +#if HAVE_FONT_SOURCE static int ascii_failback_initialized = 0; if (code >= 0x80) diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c index 439dc8ea4..05e42e6c7 100644 --- a/grub-core/normal/charset.c +++ b/grub-core/normal/charset.c @@ -49,7 +49,7 @@ #include #include -#ifdef HAVE_UNIFONT_WIDTHSPEC +#if HAVE_FONT_SOURCE #include "widthspec.h" #endif @@ -387,7 +387,7 @@ grub_unicode_get_comb_type (grub_uint32_t c) return GRUB_UNICODE_COMB_NONE; } -#ifdef HAVE_UNIFONT_WIDTHSPEC +#if HAVE_FONT_SOURCE grub_size_t grub_unicode_estimate_width (const struct grub_unicode_glyph *c) diff --git a/include/grub/term.h b/include/grub/term.h index 17cf071c1..528c53008 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -398,7 +398,7 @@ grub_term_cls (struct grub_term_output *term) } } -#ifdef HAVE_UNIFONT_WIDTHSPEC +#if HAVE_FONT_SOURCE grub_size_t grub_unicode_estimate_width (const struct grub_unicode_glyph *c); From 8a3f0a24b5d4ecc92753e76f008d2f693c330f8c Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 10:28:23 +0100 Subject: [PATCH 09/48] * grub-core/kern/emu/main.c: Ignore missing prototype for main. --- ChangeLog | 4 ++++ grub-core/kern/emu/main.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index acff45e79..96aacf1fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/kern/emu/main.c: Ignore missing prototype for main. + 2013-12-04 Vladimir Serbinenko Pass font config to config.h and not by TARGET_CFLAGS as adding diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 94c2902f6..39fa3be10 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -166,6 +166,8 @@ static struct argp argp = { +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + int main (int argc, char *argv[]) { From b73b70ebcad53b7958843ee304b53ec399871edd Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 12:20:56 +0100 Subject: [PATCH 10/48] * configure.ac: Add -no-integrated-as if {addme|ame} isn't supported. * INSTALL: Note that GRUBwas successfully compiled with clang 3.2 for ppc. --- ChangeLog | 6 ++++++ INSTALL | 4 ++-- configure.ac | 24 +++++++++++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96aacf1fb..d27eaba8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-04 Vladimir Serbinenko + + * configure.ac: Add -no-integrated-as if {addme|ame} isn't supported. + * INSTALL: Note that GRUBwas successfully compiled with clang 3.2 for + ppc. + 2013-12-04 Vladimir Serbinenko * grub-core/kern/emu/main.c: Ignore missing prototype for main. diff --git a/INSTALL b/INSTALL index ad27f3d88..7602323b1 100644 --- a/INSTALL +++ b/INSTALL @@ -23,8 +23,8 @@ configuring the GRUB. Note: clang 3.3 or later works for mips(el) earlier versions fail to generate .reginfo and hence gprel relocations fail. - Note: clang 3.4 or later works for powerpc - earlier versions suffer from vacopy bug (#15286) + Note: clang 3.2 or later works for powerpc + earlier versions not tested Note: clang has no support for generating 64-bit sparc code and hence you can't compile GRUB for sparc64 with clang Note: clang has no support for ia64 and hence you can't compile GRUB diff --git a/configure.ac b/configure.ac index 69be355c4..c371a85b3 100644 --- a/configure.ac +++ b/configure.ac @@ -515,7 +515,9 @@ AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags" AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang] -[AC_COMPILE_IFELSE( +[ +CFLAGS="$TARGET_CFLAGS" +AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [[ #ifdef __clang__ #error "is clang" @@ -533,6 +535,26 @@ if test "x$grub_cv_cc_target_clang" = xyes && ( test "x$target_cpu" = xi386 \ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as" fi +if test "x$grub_cv_cc_target_clang" = xyes && test "x$target_cpu" = xpowerpc; then +AC_CACHE_CHECK([if clang can handle ame instruction], [grub_cv_cc_target_clang_ame] +[ +CFLAGS="$TARGET_CFLAGS" +AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([], [[ + unsigned int a = 0, b = 0; + asm volatile ("{ame|addme} %0,%1" : "=r" (a) : "r" (b)); + if (a) + return 1; +]])], +[grub_cv_cc_target_clang_ame=yes], [grub_cv_cc_target_clang_ame=no])]) + # clang <= 3.3 doesn't handle most of ppc assembly, not even inline assembly + # used by gcrypt + if test x$grub_cv_cc_target_clang_ame = xno ; then + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as" + TARGET_CFLAGS="$TARGET_CCASFLAGS -no-integrated-as" + fi +fi + if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" fi From bdb6090d83651e4a44d163f48f9292cfb3f7eff8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 12:42:09 +0100 Subject: [PATCH 11/48] * configure.ac: Allow compilation with older GCC for ARM. --- ChangeLog | 4 ++++ configure.ac | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d27eaba8e..ccd9e8e34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-04 Vladimir Serbinenko + + * configure.ac: Allow compilation with older GCC for ARM. + 2013-12-04 Vladimir Serbinenko * configure.ac: Add -no-integrated-as if {addme|ame} isn't supported. diff --git a/configure.ac b/configure.ac index c371a85b3..c00110c94 100644 --- a/configure.ac +++ b/configure.ac @@ -903,7 +903,7 @@ CFLAGS="$TARGET_CFLAGS" # -mno-unaligned-access -mstrict-align if test "$target_cpu" = arm; then AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [ - grub_cv_target_cc_strict_align=unknown + grub_cv_target_cc_strict_align= for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do CFLAGS="$TARGET_CFLAGS $arg -Werror" LDFLAGS="$TARGET_LDFLAGS" @@ -914,13 +914,21 @@ if test "$target_cpu" = arm; then fi done]) - if test x"$grub_cv_target_cc_strict_align" = xunknown; then - AC_MSG_ERROR([couldnt instruct compiler not to use unaligned access]) - fi TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align" if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments" fi + AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned], + [CFLAGS="$TARGET_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifdef __ARM_FEATURE_UNALIGNED +#error "unaligned" +#endif + ]])], + [grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])]) + if test x$grub_cv_cc_target_emits_unaligned = xyes; then + AC_MSG_ERROR([compiler generates unaligned accesses]) + fi fi # Set them to their new values for the tests below. From e3046431daac7f83463aee2d07157afec974a80c Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 14:32:04 +0100 Subject: [PATCH 12/48] * conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition as it's no longer necessarry. --- ChangeLog | 5 +++++ conf/Makefile.common | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ccd9e8e34..2ba98abdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-04 Vladimir Serbinenko + + * conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition + as it's no longer necessarry. + 2013-12-04 Vladimir Serbinenko * configure.ac: Allow compilation with older GCC for ARM. diff --git a/conf/Makefile.common b/conf/Makefile.common index 8a71f136e..811573f39 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -73,7 +73,7 @@ grubconfdir = $(sysconfdir)/grub.d platformdir = $(pkglibdir)/$(target_cpu)-$(platform) starfielddir = $(pkgdatadir)/themes/starfield -CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition +CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib CFLAGS_POSIX = -fno-builtin From 3a82f8bb482eb428e10f7fbaa2aea3ff8be86567 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 4 Dec 2013 13:35:39 +0000 Subject: [PATCH 13/48] Fix grub-shell to avoid breaking "make distcheck" Copying the themes directory in grub-shell isn't parallel-test-friendly and breaks on the second test when the source directory is read-only (as in "make distcheck"). Instead, add a hidden --themes-directory option to grub-mkrescue et al, and use it in grub-shell. --- ChangeLog | 8 ++++++++ include/grub/util/install.h | 4 ++++ tests/util/grub-shell.in | 5 +++-- util/grub-install-common.c | 20 ++++++++++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ba98abdd..b7e716f46 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-12-04 Colin Watson + + Copying the themes directory in grub-shell isn't + parallel-test-friendly and breaks on the second test when the source + directory is read-only (as in "make distcheck"). Instead, add a + hidden --themes-directory option to grub-mkrescue et al, and use it + in grub-shell. + 2013-12-04 Vladimir Serbinenko * conf/Makefile.common (CFLAGS_GNULIB): Remove -Wno-old-style-definition diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 9bf3e5f13..4ba00f55b 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -50,6 +50,9 @@ { "locale-directory", GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, \ N_("DIR"), 0, \ N_("use translations under DIR [default=%s]"), 1 }, \ + { "themes-directory", GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use themes under DIR [default=%s]"), 1 }, \ { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ "FILE", OPTION_HIDDEN, 0, 1 }, \ /* TRANSLATORS: "embed" is a verb (command description). "*/ \ @@ -107,6 +110,7 @@ enum grub_install_options { GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, GRUB_INSTALL_OPTIONS_DIRECTORY2, GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, + GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE }; diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 5f20b64e0..d9a5253e2 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -347,9 +347,10 @@ if test -z "$debug"; then fi if [ x$boot != xnet ] && [ x$boot != xemu ]; then - cp -R "@srcdir@/themes" "@builddir@" pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ - --rom-directory="${rom_directory}" $mkimage_extra_arg ${mkrescue_args} \ + --rom-directory="${rom_directory}" \ + --themes-directory="@srcdir@/themes" \ + $mkimage_extra_arg ${mkrescue_args} \ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ ${files} >/dev/null 2>&1 fi diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 03c6f13ec..9d9bae709 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -60,6 +60,8 @@ grub_install_help_filter (int key, const char *text, return xasprintf(text, grub_util_get_pkglibdir ()); case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: return xasprintf(text, grub_util_get_localedir ()); + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + return grub_util_path_concat (2, grub_util_get_pkgdatadir (), "themes"); default: return (char *) text; } @@ -220,6 +222,7 @@ struct install_list install_fonts = { 1, 0, 0, 0 }; struct install_list install_themes = { 1, 0, 0, 0 }; char *grub_install_source_directory = NULL; char *grub_install_locale_directory = NULL; +char *grub_install_themes_directory = NULL; void grub_install_push_module (const char *val) @@ -320,6 +323,10 @@ grub_install_parse (int key, char *arg) free (grub_install_locale_directory); grub_install_locale_directory = xstrdup (arg); return 1; + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + free (grub_install_themes_directory); + grub_install_themes_directory = xstrdup (arg); + return 1; case GRUB_INSTALL_OPTIONS_INSTALL_MODULES: handle_install_list (&install_modules, arg, 0); return 1; @@ -667,6 +674,7 @@ grub_install_copy_files (const char *src, { char *dst_platform, *dst_locale, *dst_fonts; const char *pkgdatadir = grub_util_get_pkgdatadir (); + char *themes_dir; { char *platform; @@ -781,14 +789,20 @@ grub_install_copy_files (const char *src, install_themes.entries[1] = NULL; } + if (grub_install_themes_directory) + themes_dir = xstrdup (grub_install_themes_directory); + else + themes_dir = grub_util_path_concat (2, grub_util_get_pkgdatadir (), + "themes"); + for (i = 0; i < install_themes.n_entries; i++) { - char *srcf = grub_util_path_concat (4, pkgdatadir, "themes", + char *srcf = grub_util_path_concat (3, themes_dir, install_themes.entries[i], "theme.txt"); if (grub_util_is_regular (srcf)) { - char *srcd = grub_util_path_concat (3, pkgdatadir, "themes", + char *srcd = grub_util_path_concat (2, themes_dir, install_themes.entries[i]); char *dstd = grub_util_path_concat (3, dst, "themes", install_themes.entries[i]); @@ -800,6 +814,8 @@ grub_install_copy_files (const char *src, free (srcf); } + free (themes_dir); + if (install_fonts.is_default) { install_fonts.is_default = 0; From 382b500ebe0450f5949c75ca09d67d390880d505 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 14:53:25 +0100 Subject: [PATCH 14/48] * configure.ac: Move all warning options that may be absent in gcc >= 3.1 to optional. Note: while this allows to compile with older GCC, official requirements remain the same and no support for older GCC. --- ChangeLog | 8 ++++++++ configure.ac | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b7e716f46..bd80d1a80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-12-04 Vladimir Serbinenko + + * configure.ac: Move all warning options that may be absent in + gcc >= 3.1 to optional. + + Note: while this allows to compile with older GCC, official requirements + remain the same and no support for older GCC. + 2013-12-04 Colin Watson Copying the themes directory in grub-shell isn't diff --git a/configure.ac b/configure.ac index c00110c94..fec093b96 100644 --- a/configure.ac +++ b/configure.ac @@ -422,8 +422,8 @@ esac # For gnulib. gl_INIT -WARN_FLAGS="-Wall -W -Wshadow -Wold-style-definition -Wpointer-arith -Wundef -Wextra -Wattributes -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmultichar -Wnonnull -Woverflow -Wparentheses -Wpointer-arith -Wpointer-to-int-cast -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstrict-aliasing -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings -Wnested-externs -Wstrict-prototypes -Wpointer-sign" -EXTRA_WARN_FLAGS="-Wvla" +WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wpointer-arith -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wundef -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes" +EXTRA_WARN_FLAGS="-Wold-style-definition -Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign" HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" From 4a73746a040073679e62cf7877436ed4e8345184 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 19:54:37 +0100 Subject: [PATCH 15/48] * grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad so it doesn't land in the middle of loaded image. --- ChangeLog | 5 +++++ grub-core/boot/sparc64/ieee1275/boot.S | 6 +++++- include/grub/sparc64/ieee1275/boot.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bd80d1a80..8fba56c05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-04 Vladimir Serbinenko + + * grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad + so it doesn't land in the middle of loaded image. + 2013-12-04 Vladimir Serbinenko * configure.ac: Move all warning options that may be absent in diff --git a/grub-core/boot/sparc64/ieee1275/boot.S b/grub-core/boot/sparc64/ieee1275/boot.S index 0ab9a4af3..efe090e0c 100644 --- a/grub-core/boot/sparc64/ieee1275/boot.S +++ b/grub-core/boot/sparc64/ieee1275/boot.S @@ -48,7 +48,7 @@ kernel_byte: .xword (2 << 9) boot_path_end: kernel_address: .word GRUB_BOOT_MACHINE_KERNEL_ADDR #else -#define boot_path (_start + 512) +#define boot_path (_start + 512 + SCRATCH_PAD_BOOT_SIZE) #define boot_path_end (_start + 1024) #include @@ -140,7 +140,11 @@ prom_call: boot_continue: mov %o7, PIC_REG /* PIC base */ +#ifndef CDBOOT sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */ +#else + GET_ABS(_start + 512, %l1) /* OF argument slots */ +#endif /* Find the /chosen node so we can fetch the stdout handle, * and thus perform console output. diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 60edc712e..a54e47566 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -27,6 +27,7 @@ #define SCRATCH_PAD_BOOT 0x5000 #define SCRATCH_PAD_DISKBOOT 0x4000 +#define SCRATCH_PAD_BOOT_SIZE 0x110 #define GET_ABS(symbol, reg) \ add PIC_REG, (symbol - pic_base), reg From e5ed2f69478fb37b8b9c7f96601d5e3139243da8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Wed, 4 Dec 2013 20:05:24 +0100 Subject: [PATCH 16/48] Handle unaligned .bss on sparc64. Current code improperly assumes that both __bss_start and _end are aligned to 8-bytes. Eliminating this assumption and explicitly align modules. --- ChangeLog | 8 ++++++ grub-core/kern/sparc64/ieee1275/crt0.S | 34 +++++++++++++++++++++----- include/grub/offsets.h | 3 ++- util/grub-mkimagexx.c | 5 ++++ util/mkimage.c | 9 ++++--- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8fba56c05..d60acab3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2013-12-05 Vladimir Serbinenko + + Handle unaligned .bss on sparc64. + + Current code improperly assumes that both __bss_start and _end are + aligned to 8-bytes. Eliminating this assumption and explicitly align + modules. + 2013-12-04 Vladimir Serbinenko * grub-core/boot/sparc64/ieee1275/boot.S [CDBOOT]: Move scratchpad diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S index 9d91fba48..79b6bb325 100644 --- a/grub-core/kern/sparc64/ieee1275/crt0.S +++ b/grub-core/kern/sparc64/ieee1275/crt0.S @@ -36,10 +36,14 @@ codestart: /* Copy the modules past the end of the kernel image. * They are currently sitting in the BSS. */ - sethi %hi(__bss_start), %o2 - or %o2, %lo(__bss_start), %o2 - sethi %hi(_end), %o3 - or %o3, %lo(_end), %o3 + sethi %hi(__bss_start + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2 + or %o2, %lo(__bss_start + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o2 + srl %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2 + sll %o2, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o2 + sethi %hi(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3 + or %o3, %lo(_end + GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN - 1), %o3 + srl %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3 + sll %o3, GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN, %o3 sethi %hi(grub_total_module_size), %o4 lduw [%o4 + %lo(grub_total_module_size)], %o4 @@ -67,16 +71,34 @@ codestart: /* Now it's safe to clear out the BSS. */ sethi %hi(__bss_start), %o2 or %o2, %lo(__bss_start), %o2 - sethi %hi(_end), %o3 - or %o3, %lo(_end), %o3 +1: stb %g0, [%o2] + add %o2, 1, %o2 + and %o2, 7, %o3 + brnz %o3, 1b + nop + + sethi %hi(_end - 1), %o3 + or %o3, %lo(_end - 1), %o3 + srl %o3, 3, %o3 + sll %o3, 3, %o3 1: stx %g0, [%o2] add %o2, 8, %o2 cmp %o2, %o3 blt,pt %xcc, 1b nop + + sethi %hi(_end), %o3 + or %o3, %lo(_end), %o3 +1: stb %g0, [%o2] + add %o2, 1, %o2 + cmp %o2, %o3 + blt,pt %xcc, 1b + nop + sethi %hi(grub_ieee1275_original_stack), %o2 stx %o1, [%o2 + %lo(grub_ieee1275_original_stack)] sethi %hi(grub_ieee1275_entry_fn), %o2 call grub_main stx %o0, [%o2 + %lo(grub_ieee1275_entry_fn)] 1: ba,a 1b + nop diff --git a/include/grub/offsets.h b/include/grub/offsets.h index 0a7b89a6d..a666e898b 100644 --- a/include/grub/offsets.h +++ b/include/grub/offsets.h @@ -111,7 +111,8 @@ #define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 -#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN 0x1 +#define GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN 3 +#define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN (1 << GRUB_KERNEL_SPARC64_IEEE1275_LOG_MOD_ALIGN) #define GRUB_KERNEL_MIPS_LOONGSON_MOD_ALIGN 0x1 #define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1 diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 5240fe2aa..7d2f0412d 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -1356,6 +1356,11 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, else *bss_size = 0; + if (image_target->id == IMAGE_SPARC64_AOUT + || image_target->id == IMAGE_SPARC64_RAW + || image_target->id == IMAGE_SPARC64_CDCORE) + *kernel_sz = ALIGN_UP (*kernel_sz, image_target->mod_align); + if (image_target->id == IMAGE_EFI) { symtab_section = NULL; diff --git a/util/mkimage.c b/util/mkimage.c index 9b482712c..11d4a474b 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -383,7 +383,8 @@ static const struct grub_install_image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, }, { .dirname = "sparc64-ieee1275", @@ -398,7 +399,8 @@ static const struct grub_install_image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, }, { .dirname = "sparc64-ieee1275", @@ -413,7 +415,8 @@ static const struct grub_install_image_target_desc image_targets[] = .decompressor_uncompressed_addr = TARGET_NO_FIELD, .section_align = 1, .vaddr_offset = 0, - .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, }, { .dirname = "ia64-efi", From bbeee1c4a358b00bd33268d0161fd23cae7f8274 Mon Sep 17 00:00:00 2001 From: Leif Lindholm Date: Wed, 4 Dec 2013 12:59:21 +0000 Subject: [PATCH 17/48] grub-core/lib/fdt.c: correctly update size_dt_struct in add_subnode() --- ChangeLog | 4 ++++ grub-core/lib/fdt.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index d60acab3f..840a40405 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-05 Leif Lindholm + + * grub-core/kern/fdt.c: Update struct size when adding node. + 2013-12-05 Vladimir Serbinenko Handle unaligned .bss on sparc64. diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c index 9b77e1c67..9c886fceb 100644 --- a/grub-core/lib/fdt.c +++ b/grub-core/lib/fdt.c @@ -132,6 +132,7 @@ static int add_subnode (void *fdt, int parentoffset, const char *name) + parentoffset); grub_uint32_t *end = (void *) struct_end (fdt); unsigned int entry_size = node_entry_size (name); + unsigned int struct_size = grub_fdt_get_size_dt_struct(fdt); char *node_name; SKIP_NODE_NAME(node_name, token, end); @@ -167,6 +168,7 @@ insert: token[entry_size / sizeof(*token) - 2] = 0; /* padding bytes */ grub_strcpy((char *) (token + 1), name); token[entry_size / sizeof(*token) - 1] = grub_cpu_to_be32(FDT_END_NODE); + grub_fdt_set_size_dt_struct (fdt, struct_size + entry_size); return ((grub_addr_t) token - (grub_addr_t) fdt - grub_fdt_get_off_dt_struct(fdt)); } From 0480665b9de31aefc7f1d95448efdf8349997fe9 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 5 Dec 2013 13:51:52 +0000 Subject: [PATCH 18/48] On Linux, read partition start offsets from sysfs if possible This lets us cope with block device drivers that don't implement HDIO_GETGEO. Fixes Ubuntu bug #1237519. * grub-core/osdep/linux/hostdisk.c (sysfs_partition_path): New function. (sysfs_partition_start): Likewise. (grub_util_find_partition_start_os): Try sysfs_partition_start before HDIO_GETGEO. --- ChangeLog | 12 +++++ grub-core/osdep/linux/hostdisk.c | 89 ++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/ChangeLog b/ChangeLog index 840a40405..d8e3563d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2013-12-05 Colin Watson + + On Linux, read partition start offsets from sysfs if possible, to + cope with block device drivers that don't implement HDIO_GETGEO. + Fixes Ubuntu bug #1237519. + + * grub-core/osdep/linux/hostdisk.c (sysfs_partition_path): New + function. + (sysfs_partition_start): Likewise. + (grub_util_find_partition_start_os): Try sysfs_partition_start + before HDIO_GETGEO. + 2013-12-05 Leif Lindholm * grub-core/kern/fdt.c: Update struct size when adding node. diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c index a2c80f39d..74d87a43c 100644 --- a/grub-core/osdep/linux/hostdisk.c +++ b/grub-core/osdep/linux/hostdisk.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -93,12 +95,99 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec return nr; } +static char * +sysfs_partition_path (const char *dev, const char *entry) +{ + const char *argv[7]; + int fd; + pid_t pid; + FILE *udevadm; + char *buf = NULL; + size_t len = 0; + char *path = NULL; + + argv[0] = "udevadm"; + argv[1] = "info"; + argv[2] = "--query"; + argv[3] = "path"; + argv[4] = "--name"; + argv[5] = dev; + argv[6] = NULL; + + pid = grub_util_exec_pipe (argv, &fd); + + if (!pid) + return NULL; + + /* Parent. Read udevadm's output. */ + udevadm = fdopen (fd, "r"); + if (!udevadm) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "udevadm", strerror (errno)); + close (fd); + goto out; + } + + if (getline (&buf, &len, udevadm) > 0) + { + char *newline; + + newline = strchr (buf, '\n'); + if (newline) + *newline = '\0'; + path = xasprintf ("/sys%s/%s", buf, entry); + } + +out: + if (udevadm) + fclose (udevadm); + waitpid (pid, NULL, 0); + free (buf); + + return path; +} + +static int +sysfs_partition_start (const char *dev, grub_disk_addr_t *start) +{ + char *path; + FILE *fp; + unsigned long long val; + int ret = 0; + + path = sysfs_partition_path (dev, "start"); + if (!path) + return 0; + + fp = grub_util_fopen (path, "r"); + if (!fp) + goto out; + + if (fscanf (fp, "%llu", &val) == 1) + { + *start = (grub_disk_addr_t) val; + ret = 1; + } + +out: + free (path); + if (fp) + fclose (fp); + + return ret; +} + grub_disk_addr_t grub_util_find_partition_start_os (const char *dev) { + grub_disk_addr_t start; grub_util_fd_t fd; struct hd_geometry hdg; + if (sysfs_partition_start (dev, &start)) + return start; + fd = open (dev, O_RDONLY); if (fd == -1) { From 59b38922a1ea2b27995a686c3c2de8558a0f26dc Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 5 Dec 2013 15:48:27 +0000 Subject: [PATCH 19/48] Pacify compiler warning * grub-core/osdep/linux/hostdisk.c (grub_util_find_partition_start_os): Initialise start to avoid spurious compiler warning. --- ChangeLog | 6 ++++++ grub-core/osdep/linux/hostdisk.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d8e3563d9..4e110ca3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-05 Colin Watson + + * grub-core/osdep/linux/hostdisk.c + (grub_util_find_partition_start_os): Initialise start to avoid + spurious compiler warning. + 2013-12-05 Colin Watson On Linux, read partition start offsets from sysfs if possible, to diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c index 74d87a43c..abaaf2847 100644 --- a/grub-core/osdep/linux/hostdisk.c +++ b/grub-core/osdep/linux/hostdisk.c @@ -181,7 +181,7 @@ out: grub_disk_addr_t grub_util_find_partition_start_os (const char *dev) { - grub_disk_addr_t start; + grub_disk_addr_t start = 0; grub_util_fd_t fd; struct hd_geometry hdg; From b0f311f412ac18ff2158126aba9b18ab2608662e Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Thu, 5 Dec 2013 17:05:21 +0100 Subject: [PATCH 20/48] * util/grub-install.c: Mention Boot* variable. --- ChangeLog | 4 ++++ util/grub-install.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4e110ca3a..c5dadaecc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-05 Vladimir Serbinenko + + * util/grub-install.c: Mention Boot* variable. + 2013-12-05 Colin Watson * grub-core/osdep/linux/hostdisk.c diff --git a/util/grub-install.c b/util/grub-install.c index 2d6ef757a..7a1db422b 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -232,7 +232,7 @@ static struct argp_option options[] = { N_("disk module to use (biosdisk or native). " "This option is only available on BIOS target."), 2}, {"no-nvram", OPTION_NO_NVRAM, 0, 0, - N_("don't update the `boot-device' NVRAM variable. " + N_("don't update the `boot-device'/`Boot*' NVRAM variables. " "This option is only available on EFI and IEEE1275 targets."), 2}, {"skip-fs-probe",'s',0, 0, N_("do not probe for filesystems in DEVICE"), 0}, From aa437b58903b9927ee6cf2930a662d5503f14c90 Mon Sep 17 00:00:00 2001 From: Mike Gilbert Date: Wed, 4 Dec 2013 10:24:21 -0500 Subject: [PATCH 21/48] gentpl.py: Use python3-style print function --- ChangeLog | 5 +++++ INSTALL | 2 +- gentpl.py | 4 +++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5dadaecc..c680ba1b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-05 Mike Gilbert + + * INSTALL: Raise minimum python version to 2.6. + * gentpl.py: Use python3-style print function. + 2013-12-05 Vladimir Serbinenko * util/grub-install.c: Mention Boot* variable. diff --git a/INSTALL b/INSTALL index 7602323b1..b91d975c3 100644 --- a/INSTALL +++ b/INSTALL @@ -54,7 +54,7 @@ To build GRUB's graphical terminal (gfxterm), you need: If you use a development snapshot or want to hack on GRUB you may need the following. -* Python 2.5.2 or later +* Python 2.6 or later * Autoconf 2.60 or later * Automake 1.10.1 or later diff --git a/gentpl.py b/gentpl.py index 1d4583c68..02bf33523 100644 --- a/gentpl.py +++ b/gentpl.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . +from __future__ import print_function + __metaclass__ = type from optparse import OptionParser @@ -434,7 +436,7 @@ def output(s, section=''): def write_output(section=''): for s in outputs.get(section, []): - print s, + print(s, end='') # # Global variables From a846dd4b3aa2c4b3f8a593f5c122726f2e5deb7b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Thu, 5 Dec 2013 23:07:10 +0100 Subject: [PATCH 22/48] * util/grub-mkimagexx.c: Fix reloc section generation for ia64. --- ChangeLog | 4 ++++ util/grub-mkimagexx.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c680ba1b5..6fac2eacd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-05 Vladimir Serbinenko + + * util/grub-mkimagexx.c: Fix reloc section generation for ia64. + 2013-12-05 Mike Gilbert * INSTALL: Raise minimum python version to 2.6. diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index 7d2f0412d..b562fddf2 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -1432,7 +1432,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, section_entsize, num_sections, strtab, ia64jmp_off + image_target->vaddr_offset, - 2 * ia64jmpnum + got, + 2 * ia64jmpnum + (got / 8), image_target); } From 8c534b85f1c6b29e2ab680578ae158601c398d33 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 6 Dec 2013 09:18:55 +0100 Subject: [PATCH 23/48] Revamp relocation handling. Move more code to common dl.c. Add missing veneers for arm and arm64. Decreases kernel size by 70 bytes on i386-pc (40-50 compressed) --- ChangeLog | 7 + grub-core/kern/arm/dl.c | 274 ++++++++++++++++---------- grub-core/kern/arm/dl_helper.c | 150 +++++++------- grub-core/kern/arm64/dl.c | 204 ++++++++----------- grub-core/kern/arm64/dl_helper.c | 39 ++-- grub-core/kern/dl.c | 42 +++- grub-core/kern/emu/full.c | 5 +- grub-core/kern/i386/dl.c | 93 +++------ grub-core/kern/ia64/dl.c | 170 +++++++--------- grub-core/kern/mips/dl.c | 326 ++++++++++++++----------------- grub-core/kern/powerpc/dl.c | 152 ++++++-------- grub-core/kern/sparc64/dl.c | 158 ++++++--------- grub-core/kern/x86_64/dl.c | 142 ++++++-------- include/grub/arm/reloc.h | 25 ++- include/grub/arm64/reloc.h | 4 +- include/grub/dl.h | 21 +- util/grub-mkimagexx.c | 184 ++++++++++++++--- util/mkimage.c | 88 +++++++++ 18 files changed, 1097 insertions(+), 987 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6fac2eacd..ee38108f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-12-06 Vladimir Serbinenko + + Revamp relocation handling. + + Move more code to common dl.c. Add missing veneers for arm and arm64. + Decreases kernel size by 70 bytes on i386-pc (40-50 compressed) + 2013-12-05 Vladimir Serbinenko * util/grub-mkimagexx.c: Fix reloc section generation for ia64. diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c index 4563a52f9..26da0ac22 100644 --- a/grub-core/kern/arm/dl.c +++ b/grub-core/kern/arm/dl.c @@ -25,45 +25,113 @@ #include #include +struct trampoline_arm +{ +#define ARM_LOAD_IP 0xe59fc000 +#define ARM_BX 0xe12fff1c +#define ARM_MOV_PC 0xe1a0f00c + grub_uint32_t load_ip; /* ldr ip, [pc] */ + grub_uint32_t bx; /* bx ip or mov pc, ip*/ + grub_uint32_t addr; +}; + +static grub_uint16_t thumb_template[8] = + { + 0x468c, /* mov ip, r1 */ + 0x4903, /* ldr r1, [pc, #12] ; (10 <.text+0x10>) */ + /* Exchange R1 and IP in limited Thumb instruction set. + IP gets negated but we compensate it by C code. */ + /* R1 IP */ + /* -A R1 */ + 0x4461, /* add r1, ip */ /* R1-A R1 */ + 0x4249, /* negs r1, r1 */ /* A-R1 R1 */ + 0x448c, /* add ip, r1 */ /* A-R1 A */ + 0x4249, /* negs r1, r1 */ /* R1-A A */ + 0x4461, /* add r1, ip */ /* R1 A */ + 0x4760 /* bx ip */ + }; + +struct trampoline_thumb +{ + grub_uint16_t template[8]; + grub_uint32_t neg_addr; +}; + +#pragma GCC diagnostic ignored "-Wcast-align" + +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + unsigned i; + + *tramp = 0; + *got = 0; + + for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize)) + if (s->sh_type == SHT_REL) + { + const Elf_Rel *rel, *max; + + for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + switch (ELF_R_TYPE (rel->r_info)) + { + case R_ARM_CALL: + case R_ARM_JUMP24: + { + *tramp += sizeof (struct trampoline_arm); + break; + } + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + { + *tramp += sizeof (struct trampoline_thumb); + break; + } + } + } + + grub_dprintf ("dl", "trampoline size %x\n", *tramp); + + return GRUB_ERR_NONE; +} + /************************************************* * Runtime dynamic linker with helper functions. * *************************************************/ -static grub_err_t -do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod) +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - grub_dl_segment_t seg; - Elf_Rel *rel; - Elf_Sym *sym; - int i, entnum; + Elf_Rel *rel, *max; - entnum = relhdr->sh_size / sizeof (Elf_Rel); - - /* Find the target segment for this relocation section. */ - for (seg = mod->segment ; seg ; seg = seg->next) - if (seg->section == relhdr->sh_info) - break; - if (!seg) - return grub_error (GRUB_ERR_EOF, N_("relocation segment not found")); - - rel = (Elf_Rel *) ((grub_addr_t) e + relhdr->sh_offset); - - /* Step through all relocations */ - for (i = 0, sym = mod->symtab; i < entnum; i++) + for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) { Elf_Addr *target, sym_addr; - int relsym, reltype; grub_err_t retval; + Elf_Sym *sym; - if (seg->size < rel[i].r_offset) + if (seg->size < rel->r_offset) return grub_error (GRUB_ERR_BAD_MODULE, "reloc offset is out of the segment"); - relsym = ELF_R_SYM (rel[i].r_info); - reltype = ELF_R_TYPE (rel[i].r_info); - target = (void *) ((grub_addr_t) seg->addr + rel[i].r_offset); + target = (void *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - sym_addr = sym[relsym].st_value; + sym_addr = sym->st_value; - switch (reltype) + switch (ELF_R_TYPE (rel->r_info)) { case R_ARM_ABS32: { @@ -76,16 +144,58 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod) case R_ARM_CALL: case R_ARM_JUMP24: { - retval = grub_arm_reloc_jump24 (target, sym_addr); - if (retval != GRUB_ERR_NONE) - return retval; + grub_int32_t offset; + + sym_addr += grub_arm_jump24_get_offset (target); + offset = sym_addr - (grub_uint32_t) target; + + if ((sym_addr & 1) || !grub_arm_jump24_check_offset (offset)) + { + struct trampoline_arm *tp = mod->trampptr; + mod->trampptr = tp + 1; + tp->load_ip = ARM_LOAD_IP; + tp->bx = (sym_addr & 1) ? ARM_BX : ARM_MOV_PC; + tp->addr = sym_addr + 8; + offset = (grub_uint8_t *) tp - (grub_uint8_t *) target - 8; + } + if (!grub_arm_jump24_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "trampoline out of range"); + grub_arm_jump24_set_offset (target, offset); } break; case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: { /* Thumb instructions can be 16-bit aligned */ - retval = grub_arm_reloc_thm_call ((grub_uint16_t *) target, sym_addr); + grub_int32_t offset; + + sym_addr += grub_arm_thm_call_get_offset ((grub_uint16_t *) target); + + grub_dprintf ("dl", " sym_addr = 0x%08x\n", sym_addr); + + offset = sym_addr - (grub_uint32_t) target; + + grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n", + target, sym_addr, offset); + + if (!(sym_addr & 1) || (offset < -0x200000 || offset >= 0x200000)) + { + struct trampoline_thumb *tp = mod->trampptr; + mod->trampptr = tp + 1; + grub_memcpy (tp->template, thumb_template, sizeof (tp->template)); + tp->neg_addr = -sym_addr - 4; + offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1; + } + + if (offset < -0x200000 || offset >= 0x200000) + return grub_error (GRUB_ERR_BAD_MODULE, + "trampoline out of range"); + + grub_dprintf ("dl", " relative destination = %p\n", + (char *) target + offset); + + retval = grub_arm_thm_call_set_offset ((grub_uint16_t *) target, offset); if (retval != GRUB_ERR_NONE) return retval; } @@ -98,15 +208,37 @@ do_relocations (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod) case R_ARM_THM_JUMP19: { /* Thumb instructions can be 16-bit aligned */ - retval = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr); - if (retval != GRUB_ERR_NONE) - return retval; + grub_int32_t offset; + + if (!(sym_addr & 1)) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("Relocation targeting wrong execution state")); + + sym_addr += grub_arm_thm_jump19_get_offset ((grub_uint16_t *) target); + + offset = sym_addr - (grub_uint32_t) target; + + if (!grub_arm_thm_jump19_check_offset (offset) + || !(sym_addr & 1)) + { + struct trampoline_thumb *tp = mod->gotptr; + mod->gotptr = tp + 1; + grub_memcpy (tp->template, thumb_template, sizeof (tp->template)); + tp->neg_addr = -sym_addr - 4; + offset = ((grub_uint8_t *) tp - (grub_uint8_t *) target - 4) | 1; + } + + if (!grub_arm_thm_jump19_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "trampoline out of range"); + + grub_arm_thm_jump19_set_offset ((grub_uint16_t *) target, offset); } break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("relocation 0x%x is not implemented yet"), - reltype); + ELF_R_TYPE (rel->r_info)); } } @@ -130,77 +262,3 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } - -/* - * Verify that provided ELF header contains reference to a symbol table - */ -static int -has_symtab (Elf_Ehdr * e) -{ - int i; - Elf_Shdr *s; - - for (i = 0, s = (Elf_Shdr *) ((grub_uint32_t) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((grub_uint32_t) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - return 1; - - return 0; -} - -/* - * grub_arch_dl_relocate_symbols(): - * Only externally visible function in this file. - * Locates the relocations section of the ELF object, and calls - * do_relocations() to deal with it. - */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) -{ - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - unsigned i; - - if (!has_symtab (e)) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); - -#define FIRST_SHDR(x) ((Elf_Shdr *) ((grub_addr_t)(x) + (x)->e_shoff)) -#define NEXT_SHDR(x, y) ((Elf_Shdr *) ((grub_addr_t)(y) + (x)->e_shentsize)) - - for (i = 0, s = FIRST_SHDR (e); i < e->e_shnum; i++, s = NEXT_SHDR (e, s)) - { - grub_err_t ret; - - switch (s->sh_type) - { - case SHT_REL: - { - /* Relocations, no addends */ - ret = do_relocations (s, e, mod); - if (ret != GRUB_ERR_NONE) - return ret; - } - break; - case SHT_NULL: - case SHT_PROGBITS: - case SHT_SYMTAB: - case SHT_STRTAB: - case SHT_NOBITS: - case SHT_ARM_ATTRIBUTES: - break; - case SHT_RELA: - default: - { - grub_dprintf ("dl", "unhandled section_type: %d (0x%08x)\n", - s->sh_type, s->sh_type); - return GRUB_ERR_NOT_IMPLEMENTED_YET; - }; - } - } - -#undef FIRST_SHDR -#undef NEXT_SHDR - - return GRUB_ERR_NONE; -} diff --git a/grub-core/kern/arm/dl_helper.c b/grub-core/kern/arm/dl_helper.c index 68a9e3bbf..5721939c1 100644 --- a/grub-core/kern/arm/dl_helper.c +++ b/grub-core/kern/arm/dl_helper.c @@ -38,8 +38,6 @@ grub_arm_reloc_abs32 (Elf32_Word *target, Elf32_Addr sym_addr) tmp = grub_le_to_cpu32 (*target); tmp += sym_addr; *target = grub_cpu_to_le32 (tmp); - grub_dprintf ("dl", " %s: reloc_abs32 0x%08x => 0x%08x", __FUNCTION__, - (unsigned int) sym_addr, (unsigned int) tmp); return GRUB_ERR_NONE; } @@ -51,37 +49,16 @@ grub_arm_reloc_abs32 (Elf32_Word *target, Elf32_Addr sym_addr) * little-endian, requiring some additional fiddling. * ********************************************************************/ -/* - * R_ARM_THM_CALL/THM_JUMP24 - * - * Relocate Thumb (T32) instruction set relative branches: - * B.W, BL and BLX - */ -grub_err_t -grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) +grub_int32_t +grub_arm_thm_call_get_offset (grub_uint16_t *target) { - grub_int32_t offset, offset_low, offset_high; - grub_uint32_t sign, j1, j2, is_blx; - grub_uint32_t insword, insmask; + grub_uint32_t sign, j1, j2; + grub_uint32_t insword; + grub_int32_t offset; /* Extract instruction word in alignment-safe manner */ insword = (grub_le_to_cpu16 (*target) << 16) | (grub_le_to_cpu16(*(target + 1))); - insmask = 0xf800d000; - - /* B.W/BL or BLX? Affects range and expected target state */ - if (((insword >> 12) & 0xd) == 0xc) - is_blx = 1; - else - is_blx = 0; - - /* If BLX, target symbol must be ARM (target address LSB == 0) */ - if (is_blx && (sym_addr & 1)) - return grub_error (GRUB_ERR_BAD_MODULE, - N_("Relocation targeting wrong execution state")); - - offset_low = -16777216; - offset_high = is_blx ? 16777212 : 16777214; /* Extract bitfields from instruction words */ sign = (insword >> 26) & 1; @@ -95,22 +72,32 @@ grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) if (offset & (1 << 24)) offset -= (1 << 25); - grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr); + return offset; +} - offset += sym_addr; -#ifndef GRUB_UTIL - offset -= (grub_uint32_t) target; -#endif +grub_err_t +grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset) +{ + grub_uint32_t sign, j1, j2; + const grub_uint32_t insmask = 0xf800d000; + grub_uint32_t insword; + int is_blx; - grub_dprintf("dl", " %s: target=%p, sym_addr=0x%08x, offset=%d\n", - is_blx ? "BLX" : "BL", target, sym_addr, offset); + /* Extract instruction word in alignment-safe manner */ + insword = (grub_le_to_cpu16 (*target) << 16) + | (grub_le_to_cpu16(*(target + 1))); - if ((offset < offset_low) || (offset > offset_high)) - return grub_error (GRUB_ERR_BAD_MODULE, - N_("THM_CALL Relocation out of range.")); + if (((insword >> 12) & 0xd) == 0xc) + is_blx = 1; + else + is_blx = 0; - grub_dprintf ("dl", " relative destination = %p", - (char *) target + offset); + if (!is_blx && !(offset & 1)) + return grub_error (GRUB_ERR_BAD_MODULE, "bl/b.w targettting ARM"); + + /* Transform blx into bl if necessarry. */ + if (is_blx && (offset & 1)) + insword |= (1 << 12); /* Reassemble instruction word */ sign = (offset >> 24) & 1; @@ -130,21 +117,15 @@ grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) return GRUB_ERR_NONE; } -/* - * R_ARM_THM_JUMP19 - * - * Relocate conditional Thumb (T32) B.W - */ -grub_err_t -grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) +grub_int32_t +grub_arm_thm_jump19_get_offset (grub_uint16_t *target) { grub_int32_t offset; - grub_uint32_t insword, insmask; + grub_uint32_t insword; /* Extract instruction word in alignment-safe manner */ - insword = grub_le_to_cpu16 ((*target)) << 16 - | grub_le_to_cpu16 (*(target + 1)); - insmask = 0xfbc0d000; + insword = (grub_le_to_cpu16 (*target) << 16) + | (grub_le_to_cpu16(*(target + 1))); /* Extract and sign extend offset */ offset = ((insword >> 26) & 1) << 19 @@ -156,18 +137,22 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) if (offset & (1 << 20)) offset -= (1 << 21); - /* Adjust and re-truncate offset */ - offset += sym_addr; -#ifndef GRUB_UTIL - offset -= (grub_uint32_t) target; -#endif - if ((offset > 1048574) || (offset < -1048576)) - return grub_error (GRUB_ERR_BAD_MODULE, - N_("THM_JUMP19 Relocation out of range.")); + return offset; +} + +void +grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset) +{ + grub_uint32_t insword; + const grub_uint32_t insmask = 0xfbc0d000; offset >>= 1; offset &= 0xfffff; + /* Extract instruction word in alignment-safe manner */ + insword = grub_le_to_cpu16 ((*target)) << 16 + | grub_le_to_cpu16 (*(target + 1)); + /* Reassemble instruction word and write back */ insword &= insmask; insword |= ((offset >> 19) & 1) << 26 @@ -177,9 +162,15 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) | (offset & 0x7ff); *target = grub_cpu_to_le16 (insword >> 16); *(target + 1) = grub_cpu_to_le16 (insword & 0xffff); - return GRUB_ERR_NONE; } +int +grub_arm_thm_jump19_check_offset (grub_int32_t offset) +{ + if ((offset > 1048574) || (offset < -1048576)) + return 0; + return 1; +} /*********************************************************** @@ -188,35 +179,38 @@ grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) * ARM instructions are 32-bit in size and 32-bit aligned. * ***********************************************************/ -/* - * R_ARM_JUMP24 - * - * Relocate ARM (A32) B - */ -grub_err_t -grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) +grub_int32_t +grub_arm_jump24_get_offset (grub_uint32_t *target) { - grub_uint32_t insword; grub_int32_t offset; - - if (sym_addr & 1) - return grub_error (GRUB_ERR_BAD_MODULE, - N_("Relocation targeting wrong execution state")); + grub_uint32_t insword; insword = grub_le_to_cpu32 (*target); offset = (insword & 0x00ffffff) << 2; if (offset & 0x02000000) offset -= 0x04000000; - offset += sym_addr; -#ifndef GRUB_UTIL - offset -= (grub_uint32_t) target; -#endif + return offset; +} + +int +grub_arm_jump24_check_offset (grub_int32_t offset) +{ + if (offset >= 0x02000000 || offset < -0x02000000) + return 0; + return 1; +} + +void +grub_arm_jump24_set_offset (grub_uint32_t *target, + grub_int32_t offset) +{ + grub_uint32_t insword; + + insword = grub_le_to_cpu32 (*target); insword &= 0xff000000; insword |= (offset >> 2) & 0x00ffffff; *target = grub_cpu_to_le32 (insword); - - return GRUB_ERR_NONE; } diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c index afd0de2f3..07756110d 100644 --- a/grub-core/kern/arm64/dl.c +++ b/grub-core/kern/arm64/dl.c @@ -25,6 +25,15 @@ #include #include +struct trampoline +{ +#define LDR 0x58000050 +#define BR 0xd61f0200 + grub_uint32_t ldr; /* ldr x16, 8 */ + grub_uint32_t br; /* br x16 */ + grub_uint64_t addr; +}; + /* * Check if EHDR is a valid ELF header. */ @@ -42,59 +51,76 @@ grub_arch_dl_check_header (void *ehdr) return GRUB_ERR_NONE; } +#pragma GCC diagnostic ignored "-Wcast-align" + +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e = ehdr; + const Elf_Shdr *s; + unsigned i; + + *tramp = 0; + *got = 0; + + for (i = 0, s = (const Elf_Shdr *) ((grub_addr_t) e + e->e_shoff); + i < e->e_shnum; + i++, s = (const Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize)) + if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA) + { + const Elf_Rel *rel, *max; + + for (rel = (const Elf_Rel *) ((grub_addr_t) e + s->sh_offset), + max = rel + s->sh_size / s->sh_entsize; + rel < max; + rel = (const Elf_Rel *) ((grub_addr_t) rel + s->sh_entsize)) + switch (ELF_R_TYPE (rel->r_info)) + { + case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: + { + *tramp += sizeof (struct trampoline); + break; + } + } + } + + return GRUB_ERR_NONE; +} + /* * Unified function for both REL and RELA */ -static grub_err_t -do_relX (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod) +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - grub_err_t retval; - grub_dl_segment_t segment; - Elf_Rel *rel; - Elf_Rela *rela; - Elf_Sym *symbol; - int i, entnum; - unsigned long long entsize; + Elf_Rel *rel, *max; - /* Find the target segment for this relocation section. */ - for (segment = mod->segment ; segment != 0 ; segment = segment->next) - if (segment->section == relhdr->sh_info) - break; - if (!segment) - return grub_error (GRUB_ERR_EOF, N_("relocation segment not found")); - - rel = (Elf_Rel *) ((grub_addr_t) e + relhdr->sh_offset); - rela = (Elf_Rela *) rel; - if (relhdr->sh_type == SHT_RELA) - entsize = sizeof (Elf_Rela); - else - entsize = sizeof (Elf_Rel); - - entnum = relhdr->sh_size / entsize; - retval = GRUB_ERR_NONE; - - grub_dprintf("dl", "Processing %d relocation entries.\n", entnum); - - /* Step through all relocations */ - for (i = 0, symbol = mod->symtab; i < entnum; i++) + for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) { + Elf_Sym *sym; void *place; - grub_uint64_t sym_addr, symidx, reltype; + grub_uint64_t sym_addr; - if (rel->r_offset >= segment->size) + if (rel->r_offset >= seg->size) return grub_error (GRUB_ERR_BAD_MODULE, "reloc offset is out of the segment"); - symidx = ELF_R_SYM (rel->r_info); - reltype = ELF_R_TYPE (rel->r_info); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - sym_addr = symbol[symidx].st_value; - if (relhdr->sh_type == SHT_RELA) - sym_addr += rela->r_addend; + sym_addr = sym->st_value; + if (s->sh_type == SHT_RELA) + sym_addr += ((Elf_Rela *) rel)->r_addend; - place = (void *) ((grub_addr_t) segment->addr + rel->r_offset); + place = (void *) ((grub_addr_t) seg->addr + rel->r_offset); - switch (reltype) + switch (ELF_R_TYPE (rel->r_info)) { case R_AARCH64_ABS64: { @@ -108,92 +134,32 @@ do_relX (Elf_Shdr * relhdr, Elf_Ehdr * e, grub_dl_t mod) break; case R_AARCH64_CALL26: case R_AARCH64_JUMP26: - retval = grub_arm64_reloc_xxxx26 (place, sym_addr); + { + grub_int64_t offset = sym_addr - (grub_uint64_t) place; + + if (!grub_arm_64_check_xxxx26_offset (offset)) + { + struct trampoline *tp = mod->trampptr; + mod->trampptr = tp + 1; + tp->ldr = LDR; + tp->br = BR; + tp->addr = sym_addr; + offset = (grub_uint8_t *) tp - (grub_uint8_t *) place; + } + + if (!grub_arm_64_check_xxxx26_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("Trampoline out of range")); + + grub_arm64_set_xxxx26_offset (place, offset); + } break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("relocation 0x%x is not implemented yet"), - reltype); - } - - if (retval != GRUB_ERR_NONE) - break; - - rel = (Elf_Rel *) ((grub_addr_t) rel + entsize); - rela++; - } - - return retval; -} - -/* - * Verify that provided ELF header contains reference to a symbol table - */ -static int -has_symtab (Elf_Ehdr * e) -{ - int i; - Elf_Shdr *s; - - for (i = 0, s = (Elf_Shdr *) ((grub_addr_t) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((grub_addr_t) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - return 1; - - return 0; -} - -/* - * grub_arch_dl_relocate_symbols(): - * Locates the relocations section of the ELF object, and calls - * do_relX() to deal with it. - */ -grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) -{ - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - unsigned i; - - if (!has_symtab (e)) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); - -#define FIRST_SHDR(x) ((Elf_Shdr *) ((grub_addr_t)(x) + (x)->e_shoff)) -#define NEXT_SHDR(x, y) ((Elf_Shdr *) ((grub_addr_t)(y) + (x)->e_shentsize)) - - for (i = 0, s = FIRST_SHDR (e); i < e->e_shnum; i++, s = NEXT_SHDR (e, s)) - { - grub_err_t ret; - - switch (s->sh_type) - { - case SHT_REL: - case SHT_RELA: - { - ret = do_relX (s, e, mod); - if (ret != GRUB_ERR_NONE) - return ret; - } - break; - case SHT_ARM_ATTRIBUTES: - case SHT_NOBITS: - case SHT_NULL: - case SHT_PROGBITS: - case SHT_SYMTAB: - case SHT_STRTAB: - break; - default: - { - grub_dprintf ("dl", "unhandled section_type: %d (0x%08x)\n", - s->sh_type, s->sh_type); - return GRUB_ERR_NOT_IMPLEMENTED_YET; - }; + ELF_R_TYPE (rel->r_info)); } } -#undef FIRST_SHDR -#undef NEXT_SHDR - return GRUB_ERR_NONE; } diff --git a/grub-core/kern/arm64/dl_helper.c b/grub-core/kern/arm64/dl_helper.c index 6f99087e3..d213ab93e 100644 --- a/grub-core/kern/arm64/dl_helper.c +++ b/grub-core/kern/arm64/dl_helper.c @@ -25,46 +25,31 @@ #include #include -static grub_ssize_t -sign_compress_offset (grub_ssize_t offset, int bitpos) -{ - return offset & ((1LL << (bitpos + 1)) - 1); -} - /* * grub_arm64_reloc_xxxx26(): * * JUMP26/CALL26 relocations for B and BL instructions. */ -grub_err_t -grub_arm64_reloc_xxxx26 (grub_uint32_t *place, Elf64_Addr adjust) +int +grub_arm_64_check_xxxx26_offset (grub_int64_t offset) { - grub_uint32_t insword, insmask; - grub_ssize_t offset; const grub_ssize_t offset_low = -(1 << 27), offset_high = (1 << 27) - 1; - insword = grub_le_to_cpu32 (*place); - insmask = 0xfc000000; - - offset = adjust; -#ifndef GRUB_UTIL - offset -= (grub_addr_t) place; -#endif - if ((offset < offset_low) || (offset > offset_high)) - { - return grub_error (GRUB_ERR_BAD_MODULE, - N_("CALL26 Relocation out of range")); - } + return 0; + return 1; +} + +void +grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset) +{ + const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000); grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%llx\n", place, offset > 0 ? '+' : '-', offset < 0 ? (long long) -(unsigned long long) offset : offset); - offset = sign_compress_offset (offset, 27) >> 2; - - *place = grub_cpu_to_le32 ((insword & insmask) | offset); - - return GRUB_ERR_NONE; + *place &= insmask; + *place |= grub_cpu_to_le32 (offset >> 2) & ~insmask; } diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index 1d6841479..f01fcfd4f 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -229,7 +229,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) unsigned i; Elf_Shdr *s; grub_size_t tsize = 0, talign = 1; -#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) +#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__) grub_size_t tramp; grub_size_t got; grub_err_t err; @@ -245,7 +245,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) talign = s->sh_addralign; } -#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) +#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__) err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); if (err) return err; @@ -314,12 +314,14 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) mod->segment = seg; } } -#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) +#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__) ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); mod->tramp = ptr; + mod->trampptr = ptr; ptr += tramp; ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_GOT_ALIGN); mod->got = ptr; + mod->gotptr = ptr; ptr += got; #endif @@ -352,6 +354,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) #else mod->symtab = (Elf_Sym *) ((char *) e + s->sh_offset); #endif + mod->symsize = s->sh_entsize; sym = mod->symtab; size = s->sh_size; entsize = s->sh_entsize; @@ -561,6 +564,37 @@ grub_dl_flush_cache (grub_dl_t mod) grub_arch_sync_caches (mod->base, mod->sz); } +static grub_err_t +grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +{ + Elf_Ehdr *e = ehdr; + Elf_Shdr *s; + unsigned i; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); + i < e->e_shnum; + i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) + if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA) + { + grub_dl_segment_t seg; + grub_err_t err; + + /* Find the target segment. */ + for (seg = mod->segment; seg; seg = seg->next) + if (seg->section == s->sh_info) + break; + + if (seg) + { + err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg); + if (err) + return err; + } + } + + return GRUB_ERR_NONE; +} + /* Load a module from core memory. */ grub_dl_t grub_dl_load_core_noinit (void *addr, grub_size_t size) @@ -607,7 +641,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) || grub_dl_resolve_dependencies (mod, e) || grub_dl_load_segments (mod, e) || grub_dl_resolve_symbols (mod, e) - || grub_arch_dl_relocate_symbols (mod, e)) + || grub_dl_relocate_symbols (mod, e)) { mod->fini = 0; grub_dl_unload (mod); diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index 8034c637b..e056ded97 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -39,10 +39,13 @@ grub_arch_dl_check_header (void *ehdr) } grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { (void) mod; (void) ehdr; + (void) s; + (void) seg; return GRUB_ERR_BAD_MODULE; } diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c index c5539cb05..1346da5cc 100644 --- a/grub-core/kern/i386/dl.c +++ b/grub-core/kern/i386/dl.c @@ -40,75 +40,42 @@ grub_arch_dl_check_header (void *ehdr) /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; + Elf_Rel *rel, *max; - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) + { + Elf_Word *addr; + Elf_Sym *sym; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - entsize = s->sh_entsize; + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) - { - grub_dl_segment_t seg; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_386_32: + *addr += sym->st_value; + break; - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) - { - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - { - Elf_Word *addr; - Elf_Sym *sym; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_386_32: - *addr += sym->st_value; - break; - - case R_386_PC32: - *addr += (sym->st_value - (Elf_Word) seg->addr - - rel->r_offset); - break; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } - } - } + case R_386_PC32: + *addr += (sym->st_value - (grub_addr_t) addr); + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c index 91a2645ce..e623cdc81 100644 --- a/grub-core/kern/ia64/dl.c +++ b/grub-core/kern/ia64/dl.c @@ -46,118 +46,82 @@ grub_arch_dl_check_header (void *ehdr) /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - grub_uint64_t *gp, *gpptr; - struct grub_ia64_trampoline *tr; + Elf_Rela *rel, *max; - gp = (grub_uint64_t *) mod->base; - gpptr = (grub_uint64_t *) mod->got; - tr = mod->tramp; + for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rela *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) + { + grub_addr_t addr; + Elf_Sym *sym; + grub_uint64_t value; - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + if (seg->size < (rel->r_offset & ~3)) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + addr = (grub_addr_t) seg->addr + rel->r_offset; + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - entsize = s->sh_entsize; + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) + switch (ELF_R_TYPE (rel->r_info)) + { + case R_IA64_PCREL21B: { - Elf_Rela *rel, *max; + grub_uint64_t noff; + struct grub_ia64_trampoline *tr = mod->trampptr; + grub_ia64_make_trampoline (tr, value); + noff = ((char *) tr - (char *) (addr & ~3)) >> 4; + mod->trampptr = tr + 1; - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - { - grub_addr_t addr; - Elf_Sym *sym; - grub_uint64_t value; - - if (seg->size < (rel->r_offset & ~3)) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (grub_addr_t) seg->addr + rel->r_offset; - sym = (Elf_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - - /* On the PPC the value does not have an explicit - addend, add it. */ - value = sym->st_value + rel->r_addend; - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_IA64_PCREL21B: - { - grub_uint64_t noff; - grub_ia64_make_trampoline (tr, value); - noff = ((char *) tr - (char *) (addr & ~3)) >> 4; - tr++; - - if (noff & ~MASK19) - return grub_error (GRUB_ERR_BAD_OS, - "trampoline offset too big (%lx)", noff); - grub_ia64_add_value_to_slot_20b (addr, noff); - } - break; - case R_IA64_SEGREL64LSB: - *(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr; - break; - case R_IA64_FPTR64LSB: - case R_IA64_DIR64LSB: - *(grub_uint64_t *) addr += value; - break; - case R_IA64_PCREL64LSB: - *(grub_uint64_t *) addr += value - addr; - break; - case R_IA64_GPREL22: - grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) gp); - break; - - case R_IA64_LTOFF22X: - case R_IA64_LTOFF22: - if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) - value = *(grub_uint64_t *) sym->st_value + rel->r_addend; - case R_IA64_LTOFF_FPTR22: - *gpptr = value; - grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) gp); - gpptr++; - break; - - /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ - case R_IA64_LDXMOV: - break; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } + if (noff & ~MASK19) + return grub_error (GRUB_ERR_BAD_OS, + "trampoline offset too big (%lx)", noff); + grub_ia64_add_value_to_slot_20b (addr, noff); } - } + break; + case R_IA64_SEGREL64LSB: + *(grub_uint64_t *) addr += value - (grub_addr_t) seg->addr; + break; + case R_IA64_FPTR64LSB: + case R_IA64_DIR64LSB: + *(grub_uint64_t *) addr += value; + break; + case R_IA64_PCREL64LSB: + *(grub_uint64_t *) addr += value - addr; + break; + case R_IA64_GPREL22: + grub_ia64_add_value_to_slot_21 (addr, value - (grub_addr_t) mod->base); + break; + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + value = *(grub_uint64_t *) sym->st_value + rel->r_addend; + case R_IA64_LTOFF_FPTR22: + { + grub_uint64_t *gpptr = mod->gotptr; + *gpptr = value; + grub_ia64_add_value_to_slot_21 (addr, (grub_addr_t) gpptr - (grub_addr_t) mod->base); + mod->gotptr = gpptr + 1; + break; + } + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c index b97510a1e..8c057e01d 100644 --- a/grub-core/kern/mips/dl.c +++ b/grub-core/kern/mips/dl.c @@ -58,23 +58,13 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, { const Elf_Ehdr *e = ehdr; const Elf_Shdr *s; - unsigned i; /* FIXME: suboptimal. */ grub_size_t gp_size = 0; + unsigned i; *tramp = 0; *got = 0; - /* Find a symbol table. */ - for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; - - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); - for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff); i < e->e_shnum; i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize)) @@ -106,192 +96,166 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - /* FIXME: suboptimal. */ - grub_uint32_t *gp, *gpptr; grub_uint32_t gp0; + Elf_Ehdr *e = ehdr; - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + if (!mod->reginfo) + { + unsigned i; + Elf_Shdr *ri; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + /* Find reginfo. */ + for (i = 0, ri = (Elf_Shdr *) ((char *) ehdr + e->e_shoff); + i < e->e_shnum; + i++, ri = (Elf_Shdr *) ((char *) ri + e->e_shentsize)) + if (ri->sh_type == SHT_MIPS_REGINFO) + break; + if (i == e->e_shnum) + return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found"); + mod->reginfo = (grub_uint32_t *)((char *) ehdr + ri->sh_offset); + } - entsize = s->sh_entsize; + gp0 = mod->reginfo[5]; + Elf_Rel *rel, *max; - /* Find reginfo. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_MIPS_REGINFO) - break; + for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) + { + grub_uint8_t *addr; + Elf_Sym *sym; + grub_uint32_t sym_value; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, "no reginfo found"); + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5]; - - gpptr = gp = mod->got; - - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_REL) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) + addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); + sym_value = sym->st_value; + if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy) + sym_value = (grub_addr_t) mod->got; + else if (sym_value == (grub_addr_t) &_gp_disp_dummy) + { + sym_value = (grub_addr_t) mod->got - (grub_addr_t) addr; + if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16) + /* ABI mandates +4 even if partner lui doesn't + immediately precede addiu. */ + sym_value += 4; + } + switch (ELF_R_TYPE (rel->r_info)) + { + case R_MIPS_HI16: { - Elf_Rel *rel, *max; - - for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - { - grub_uint8_t *addr; - Elf_Sym *sym; - grub_uint32_t sym_value; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - sym_value = sym->st_value; - if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy) - sym_value = (grub_addr_t) gp; - else if (sym_value == (grub_addr_t) &_gp_disp_dummy) - { - sym_value = (grub_addr_t) gp - (grub_addr_t) addr; - if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16) - /* ABI mandates +4 even if partner lui doesn't - immediately precede addiu. */ - sym_value += 4; - } - switch (ELF_R_TYPE (rel->r_info)) - { - case R_MIPS_HI16: - { - grub_uint32_t value; - Elf_Rel *rel2; + grub_uint32_t value; + Elf_Rel *rel2; #ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; + addr += 2; #endif - /* Handle partner lo16 relocation. Lower part is - treated as signed. Hence add 0x8000 to compensate. - */ - value = (*(grub_uint16_t *) addr << 16) - + sym_value + 0x8000; - for (rel2 = rel + 1; rel2 < max; rel2++) - if (ELF_R_SYM (rel2->r_info) - == ELF_R_SYM (rel->r_info) - && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) - { - value += *(grub_int16_t *) - ((char *) seg->addr + rel2->r_offset + /* Handle partner lo16 relocation. Lower part is + treated as signed. Hence add 0x8000 to compensate. + */ + value = (*(grub_uint16_t *) addr << 16) + + sym_value + 0x8000; + for (rel2 = rel + 1; rel2 < max; rel2++) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (rel->r_info) + && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) + { + value += *(grub_int16_t *) + ((char *) seg->addr + rel2->r_offset #ifdef GRUB_CPU_WORDS_BIGENDIAN - + 2 + + 2 #endif - ); - break; - } - *(grub_uint16_t *) addr = (value >> 16) & 0xffff; - } - break; - case R_MIPS_LO16: -#ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; -#endif - *(grub_uint16_t *) addr += sym_value & 0xffff; - break; - case R_MIPS_32: - *(grub_uint32_t *) addr += sym_value; - break; - case R_MIPS_GPREL32: - *(grub_uint32_t *) addr = sym_value - + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp; - break; - - case R_MIPS_26: - { - grub_uint32_t value; - grub_uint32_t raw; - raw = (*(grub_uint32_t *) addr) & 0x3ffffff; - value = raw << 2; - value += sym_value; - raw = (value >> 2) & 0x3ffffff; - - *(grub_uint32_t *) addr = - raw | ((*(grub_uint32_t *) addr) & 0xfc000000); - } - break; - case R_MIPS_GOT16: - if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) - { - Elf_Rel *rel2; - /* Handle partner lo16 relocation. Lower part is - treated as signed. Hence add 0x8000 to compensate. - */ - sym_value += (*(grub_uint16_t *) addr << 16) - + 0x8000; - for (rel2 = rel + 1; rel2 < max; rel2++) - if (ELF_R_SYM (rel2->r_info) - == ELF_R_SYM (rel->r_info) - && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) - { - sym_value += *(grub_int16_t *) - ((char *) seg->addr + rel2->r_offset -#ifdef GRUB_CPU_WORDS_BIGENDIAN - + 2 -#endif - ); - break; - } - sym_value &= 0xffff0000; - *(grub_uint16_t *) addr = 0; - } - case R_MIPS_CALL16: - /* FIXME: reuse*/ -#ifdef GRUB_CPU_WORDS_BIGENDIAN - addr += 2; -#endif - *gpptr = sym_value + *(grub_uint16_t *) addr; - *(grub_uint16_t *) addr - = sizeof (grub_uint32_t) * (gpptr - gp); - gpptr++; - break; - case R_MIPS_JALR: - break; - default: - { - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - break; - } - } + ); + break; + } + *(grub_uint16_t *) addr = (value >> 16) & 0xffff; } - } + break; + case R_MIPS_LO16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr += sym_value & 0xffff; + break; + case R_MIPS_32: + *(grub_uint32_t *) addr += sym_value; + break; + case R_MIPS_GPREL32: + *(grub_uint32_t *) addr = sym_value + + *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)mod->got; + break; + + case R_MIPS_26: + { + grub_uint32_t value; + grub_uint32_t raw; + raw = (*(grub_uint32_t *) addr) & 0x3ffffff; + value = raw << 2; + value += sym_value; + raw = (value >> 2) & 0x3ffffff; + + *(grub_uint32_t *) addr = + raw | ((*(grub_uint32_t *) addr) & 0xfc000000); + } + break; + case R_MIPS_GOT16: + if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) + { + Elf_Rel *rel2; + /* Handle partner lo16 relocation. Lower part is + treated as signed. Hence add 0x8000 to compensate. + */ + sym_value += (*(grub_uint16_t *) addr << 16) + + 0x8000; + for (rel2 = rel + 1; rel2 < max; rel2++) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (rel->r_info) + && ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16) + { + sym_value += *(grub_int16_t *) + ((char *) seg->addr + rel2->r_offset +#ifdef GRUB_CPU_WORDS_BIGENDIAN + + 2 +#endif + ); + break; + } + sym_value &= 0xffff0000; + *(grub_uint16_t *) addr = 0; + } + case R_MIPS_CALL16: + { + grub_uint32_t *gpptr = mod->gotptr; + /* FIXME: reuse*/ +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *gpptr = sym_value + *(grub_uint16_t *) addr; + *(grub_uint16_t *) addr + = sizeof (grub_uint32_t) * (gpptr - (grub_uint32_t *) mod->got); + mod->gotptr = gpptr + 1; + break; + } + case R_MIPS_JALR: + break; + default: + { + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + break; + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c index e87423438..ec204f35b 100644 --- a/grub-core/kern/powerpc/dl.c +++ b/grub-core/kern/powerpc/dl.c @@ -101,109 +101,77 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; - struct trampoline *tptr = mod->tramp; + Elf_Rela *rel, *max; - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rela *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) + { + Elf_Word *addr; + Elf_Sym *sym; + grub_uint32_t value; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - entsize = s->sh_entsize; + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; + /* On the PPC the value does not have an explicit + addend, add it. */ + value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info)) + { + case GRUB_ELF_R_PPC_ADDR16_LO: + *(Elf_Half *) addr = value; + break; - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) + case GRUB_ELF_R_PPC_REL24: { - Elf_Rela *rel, *max; + Elf_Sword delta = value - (Elf_Word) addr; - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) + if (delta << 6 >> 6 != delta) { - Elf_Word *addr; - Elf_Sym *sym; - grub_uint32_t value; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - - /* On the PPC the value does not have an explicit - addend, add it. */ - value = sym->st_value + rel->r_addend; - switch (ELF_R_TYPE (rel->r_info)) - { - case GRUB_ELF_R_PPC_ADDR16_LO: - *(Elf_Half *) addr = value; - break; - - case GRUB_ELF_R_PPC_REL24: - { - Elf_Sword delta = value - (Elf_Word) addr; - - if (delta << 6 >> 6 != delta) - { - grub_memcpy (tptr, &trampoline_template, - sizeof (*tptr)); - delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; - tptr->lis |= (((value) >> 16) & 0xffff); - tptr->ori |= ((value) & 0xffff); - tptr++; - } - - if (delta << 6 >> 6 != delta) - return grub_error (GRUB_ERR_BAD_MODULE, - "relocation overflow"); - *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); - break; - } - - case GRUB_ELF_R_PPC_ADDR16_HA: - *(Elf_Half *) addr = (value + 0x8000) >> 16; - break; - - case GRUB_ELF_R_PPC_ADDR32: - *addr = value; - break; - - case GRUB_ELF_R_PPC_REL32: - *addr = value - (Elf_Word) addr; - break; - - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } + struct trampoline *tptr = mod->trampptr; + grub_memcpy (tptr, &trampoline_template, + sizeof (*tptr)); + delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr; + tptr->lis |= (((value) >> 16) & 0xffff); + tptr->ori |= ((value) & 0xffff); + mod->trampptr = tptr + 1; } + + if (delta << 6 >> 6 != delta) + return grub_error (GRUB_ERR_BAD_MODULE, + "relocation overflow"); + *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); + break; } - } + + case GRUB_ELF_R_PPC_ADDR16_HA: + *(Elf_Half *) addr = (value + 0x8000) >> 16; + break; + + case GRUB_ELF_R_PPC_ADDR32: + *addr = value; + break; + + case GRUB_ELF_R_PPC_REL32: + *addr = value - (Elf_Word) addr; + break; + + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c index d188c4f23..fa086ff5c 100644 --- a/grub-core/kern/sparc64/dl.c +++ b/grub-core/kern/sparc64/dl.c @@ -42,106 +42,74 @@ grub_arch_dl_check_header (void *ehdr) /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf_Ehdr *e = ehdr; - Elf_Shdr *s; - Elf_Word entsize; - unsigned i; + Elf_Rela *rel, *max; - /* Find a symbol table. */ - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset), + max = (Elf_Rela *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rela *) ((char *) rel + s->sh_entsize)) + { + Elf_Word *addr; + Elf_Sym *sym; + Elf_Addr value; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - entsize = s->sh_entsize; + addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; - - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) - { - Elf_Rela *rel, *max; - - for (rel = (Elf_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - { - Elf_Word *addr; - Elf_Sym *sym; - Elf_Addr value; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset); - sym = (Elf_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - - value = sym->st_value + rel->r_addend; - switch (ELF_R_TYPE (rel->r_info) & 0xff) - { - case R_SPARC_32: /* 3 V-word32 */ - if (value & 0xFFFFFFFF00000000) - return grub_error (GRUB_ERR_BAD_MODULE, - "address out of 32 bits range"); - *addr = value; - break; - case R_SPARC_WDISP30: /* 7 V-disp30 */ - if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) && - (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) - != 0xFFFFFFFF00000000)) - return grub_error (GRUB_ERR_BAD_MODULE, - "displacement out of 30 bits range"); - *addr = (*addr & 0xC0000000) | - (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) & - 0x3FFFFFFF); - break; - case R_SPARC_HH22: /* 9 V-imm22 */ - *addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF); - break; - case R_SPARC_HM10: /* 12 T-simm13 */ - *addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF); - break; - case R_SPARC_HI22: /* 9 V-imm22 */ - *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); - break; - case R_SPARC_LO10: /* 12 T-simm13 */ - *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF); - break; - case R_SPARC_64: /* 32 V-xwords64 */ - *(Elf_Xword *) addr = value; - break; - case R_SPARC_OLO10: - *addr = (*addr & ~0x1fff) - | (((value & 0x3ff) + - (ELF_R_TYPE (rel->r_info) >> 8)) - & 0x1fff); - break; - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } - } - } + value = sym->st_value + rel->r_addend; + switch (ELF_R_TYPE (rel->r_info) & 0xff) + { + case R_SPARC_32: /* 3 V-word32 */ + if (value & 0xFFFFFFFF00000000) + return grub_error (GRUB_ERR_BAD_MODULE, + "address out of 32 bits range"); + *addr = value; + break; + case R_SPARC_WDISP30: /* 7 V-disp30 */ + if (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) && + (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) + != 0xFFFFFFFF00000000)) + return grub_error (GRUB_ERR_BAD_MODULE, + "displacement out of 30 bits range"); + *addr = (*addr & 0xC0000000) | + (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) & + 0x3FFFFFFF); + break; + case R_SPARC_HH22: /* 9 V-imm22 */ + *addr = (*addr & 0xFFC00000) | ((value >> 42) & 0x3FFFFF); + break; + case R_SPARC_HM10: /* 12 T-simm13 */ + *addr = (*addr & 0xFFFFFC00) | ((value >> 32) & 0x3FF); + break; + case R_SPARC_HI22: /* 9 V-imm22 */ + *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); + break; + case R_SPARC_LO10: /* 12 T-simm13 */ + *addr = (*addr & 0xFFFFFC00) | (value & 0x3FF); + break; + case R_SPARC_64: /* 32 V-xwords64 */ + *(Elf_Xword *) addr = value; + break; + case R_SPARC_OLO10: + *addr = (*addr & ~0x1fff) + | (((value & 0x3ff) + + (ELF_R_TYPE (rel->r_info) >> 8)) + & 0x1fff); + break; + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + } return GRUB_ERR_NONE; } diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c index 17c121544..e00e51d40 100644 --- a/grub-core/kern/x86_64/dl.c +++ b/grub-core/kern/x86_64/dl.c @@ -40,101 +40,69 @@ grub_arch_dl_check_header (void *ehdr) /* Relocate symbols. */ grub_err_t -grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) { - Elf64_Ehdr *e = ehdr; - Elf64_Shdr *s; - Elf64_Word entsize; - unsigned i; + Elf64_Rela *rel, *max; - /* Find a symbol table. */ - for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_SYMTAB) - break; + for (rel = (Elf64_Rela *) ((char *) ehdr + s->sh_offset), + max = (Elf64_Rela *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf64_Rela *) ((char *) rel + s->sh_entsize)) + { + Elf64_Word *addr32; + Elf64_Xword *addr64; + Elf64_Sym *sym; - if (i == e->e_shnum) - return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table")); + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); - entsize = s->sh_entsize; + addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); + addr64 = (Elf64_Xword *) addr32; + sym = (Elf64_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (rel->r_info)); - for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize)) - if (s->sh_type == SHT_RELA) - { - grub_dl_segment_t seg; + switch (ELF_R_TYPE (rel->r_info)) + { + case R_X86_64_64: + *addr64 += rel->r_addend + sym->st_value; + break; - /* Find the target segment. */ - for (seg = mod->segment; seg; seg = seg->next) - if (seg->section == s->sh_info) - break; - - if (seg) + case R_X86_64_PC32: { - Elf64_Rela *rel, *max; - - for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset), - max = rel + s->sh_size / s->sh_entsize; - rel < max; - rel++) - { - Elf64_Word *addr32; - Elf64_Xword *addr64; - Elf64_Sym *sym; - - if (seg->size < rel->r_offset) - return grub_error (GRUB_ERR_BAD_MODULE, - "reloc offset is out of the segment"); - - addr32 = (Elf64_Word *) ((char *) seg->addr + rel->r_offset); - addr64 = (Elf64_Xword *) addr32; - sym = (Elf64_Sym *) ((char *) mod->symtab - + entsize * ELF_R_SYM (rel->r_info)); - - switch (ELF_R_TYPE (rel->r_info)) - { - case R_X86_64_64: - *addr64 += rel->r_addend + sym->st_value; - break; - - case R_X86_64_PC32: - { - grub_int64_t value; - value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value - - (Elf64_Xword) seg->addr - rel->r_offset; - if (value != (grub_int32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - - case R_X86_64_32: - { - grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value; - if (value != (grub_uint32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - case R_X86_64_32S: - { - grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value; - if (value != (grub_int32_t) value) - return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); - *addr32 = value; - } - break; - - default: - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("relocation 0x%x is not implemented yet"), - ELF_R_TYPE (rel->r_info)); - } - } + grub_int64_t value; + value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value - + (Elf64_Xword) seg->addr - rel->r_offset; + if (value != (grub_int32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; } - } + break; + + case R_X86_64_32: + { + grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value; + if (value != (grub_uint32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; + } + break; + case R_X86_64_32S: + { + grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value; + if (value != (grub_int32_t) value) + return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range"); + *addr32 = value; + } + break; + + default: + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (rel->r_info)); + } + } return GRUB_ERR_NONE; } diff --git a/include/grub/arm/reloc.h b/include/grub/arm/reloc.h index 50d070f01..b938037a0 100644 --- a/include/grub/arm/reloc.h +++ b/include/grub/arm/reloc.h @@ -20,8 +20,27 @@ #define GRUB_ARM_RELOC_H 1 grub_err_t grub_arm_reloc_abs32 (grub_uint32_t *addr, Elf32_Addr sym_addr); -grub_err_t grub_arm_reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr); -grub_err_t grub_arm_reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr); -grub_err_t grub_arm_reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr); + +int +grub_arm_thm_call_check_offset (grub_int32_t offset, int is_thumb); +grub_int32_t +grub_arm_thm_call_get_offset (grub_uint16_t *target); +grub_err_t +grub_arm_thm_call_set_offset (grub_uint16_t *target, grub_int32_t offset); + +grub_int32_t +grub_arm_thm_jump19_get_offset (grub_uint16_t *target); +void +grub_arm_thm_jump19_set_offset (grub_uint16_t *target, grub_int32_t offset); +int +grub_arm_thm_jump19_check_offset (grub_int32_t offset); + +grub_int32_t +grub_arm_jump24_get_offset (grub_uint32_t *target); +int +grub_arm_jump24_check_offset (grub_int32_t offset); +void +grub_arm_jump24_set_offset (grub_uint32_t *target, + grub_int32_t offset); #endif diff --git a/include/grub/arm64/reloc.h b/include/grub/arm64/reloc.h index 606d71c77..4aed3d715 100644 --- a/include/grub/arm64/reloc.h +++ b/include/grub/arm64/reloc.h @@ -19,6 +19,8 @@ #ifndef GRUB_ARM64_RELOC_H #define GRUB_ARM64_RELOC_H 1 -grub_err_t grub_arm64_reloc_xxxx26 (grub_uint32_t *target, Elf64_Addr sym_addr); +int grub_arm_64_check_xxxx26_offset (grub_int64_t offset); +void +grub_arm64_set_xxxx26_offset (grub_uint32_t *place, grub_int64_t offset); #endif diff --git a/include/grub/dl.h b/include/grub/dl.h index d1d20d9d2..6c758c01a 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -177,11 +177,17 @@ struct grub_dl grub_dl_dep_t dep; grub_dl_segment_t segment; Elf_Sym *symtab; + grub_size_t symsize; void (*init) (struct grub_dl *mod); void (*fini) (void); -#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) +#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__) void *got; + void *gotptr; void *tramp; + void *trampptr; +#endif +#ifdef __mips__ + grub_uint32_t *reginfo; #endif void *base; grub_size_t sz; @@ -232,7 +238,11 @@ grub_err_t grub_dl_register_symbol (const char *name, void *addr, int isfunc, grub_dl_t mod); grub_err_t grub_arch_dl_check_header (void *ehdr); -grub_err_t grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr); +#ifndef GRUB_UTIL +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg); +#endif #if defined (_mips) #define GRUB_LINKER_HAVE_INIT 1 @@ -256,11 +266,16 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); #endif -#if defined (__powerpc__) || defined (__mips__) +#if defined (__powerpc__) || defined (__mips__) || defined (__arm__) #define GRUB_ARCH_DL_TRAMP_ALIGN 4 #define GRUB_ARCH_DL_GOT_ALIGN 4 #endif +#if defined (__aarch64__) +#define GRUB_ARCH_DL_TRAMP_ALIGN 8 +#define GRUB_ARCH_DL_GOT_ALIGN 8 +#endif + #endif #endif /* ! GRUB_DL_H */ diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c index b562fddf2..b7c01ab1a 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c @@ -493,6 +493,85 @@ SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, } #endif +#ifdef MKIMAGE_ELF32 +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static grub_size_t +arm_get_trampoline_size (Elf_Ehdr *e, + Elf_Shdr *sections, + Elf_Half section_entsize, + Elf_Half num_sections, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + grub_size_t ret = 0; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr sym_addr; + + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + sym_addr += (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + + switch (ELF_R_TYPE (info)) + { + case R_ARM_ABS32: + case R_ARM_V4BX: + break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + if (!(sym_addr & 1)) + ret += 8; + break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + if (sym_addr & 1) + ret += 16; + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet!"), ELF_R_TYPE (info)); + break; + } + } + } + return ret; +} +#endif + /* Deal with relocation information. This function relocates addresses within the virtual address space starting from 0. So only relative addresses can be fully resolved. Absolute addresses must be relocated @@ -512,6 +591,8 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); grub_uint64_t *gpptr = (void *) (pe_target + got_off); #define MASK19 ((1 << 19) - 1) +#else + grub_uint32_t *tr = (void *) (pe_target + tramp_off); #endif for (i = 0, s = sections; @@ -731,13 +812,13 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, case R_AARCH64_JUMP26: case R_AARCH64_CALL26: { - grub_err_t err; sym_addr -= offset; sym_addr -= SUFFIX (entry_point); - err = grub_arm64_reloc_xxxx26((grub_uint32_t *)target, + if (!grub_arm_64_check_xxxx26_offset (sym_addr)) + grub_util_error ("%s", _("CALL26 Relocation out of range")); + + grub_arm64_set_xxxx26_offset((grub_uint32_t *)target, sym_addr); - if (err) - grub_util_error ("%s", grub_errmsg); } break; default: @@ -764,32 +845,74 @@ SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr); } break; + /* Happens when compiled with -march=armv4. + Since currently we need at least armv5, keep bx as-is. + */ + case R_ARM_V4BX: + break; case R_ARM_THM_CALL: case R_ARM_THM_JUMP24: - { - grub_err_t err; - grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) target, sym_addr); - sym_addr -= offset; - /* Thumb instructions can be 16-bit aligned */ - err = grub_arm_reloc_thm_call ((grub_uint16_t *) target, - sym_addr); - if (err) - grub_util_error ("%s", grub_errmsg); - } - break; case R_ARM_THM_JUMP19: { grub_err_t err; - grub_util_info (" THM_JUMP19:\toffset=%d\t(0x%08x)", - sym_addr, sym_addr); - sym_addr -= offset; + grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) target, sym_addr); + if (!(sym_addr & 1)) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + if (!grub_arm_jump24_check_offset (new_offset)) + return grub_util_error ("jump24 relocation out of range"); + + tr[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */ + tr[1] = grub_host_to_target32 (((new_offset >> 2) & 0xffffff) | 0xea000000); /* b new_offset */ + tr += 2; + sym_addr = tr_addr | 1; + } + sym_addr -= offset; /* Thumb instructions can be 16-bit aligned */ - err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr); + if (ELF_R_TYPE (info) == R_ARM_THM_JUMP19) + err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr); + else + err = grub_arm_reloc_thm_call ((grub_uint16_t *) target, + sym_addr); if (err) grub_util_error ("%s", grub_errmsg); } break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + { + grub_err_t err; + grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) target, sym_addr); + if (sym_addr & 1) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + + /* There is no immediate version of bx, only register one... */ + tr[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */ + tr[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */ + tr[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */ + tr[3] = grub_host_to_target32 (new_offset | 1); + tr += 4; + sym_addr = tr_addr; + } + sym_addr -= offset; + err = grub_arm_reloc_jump24 (target, + sym_addr); + if (err) + grub_util_error ("%s", grub_errmsg); + } + break; + default: grub_util_error (_("relocation 0x%x is not implemented yet!"), ELF_R_TYPE (info)); break; @@ -1054,11 +1177,13 @@ SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, case EM_ARM: switch (ELF_R_TYPE (info)) { + case R_ARM_V4BX: /* Relative relocations do not require fixup entries. */ case R_ARM_JUMP24: case R_ARM_THM_CALL: case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: + case R_ARM_CALL: { Elf_Addr addr; @@ -1280,7 +1405,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, Elf_Off section_offset; Elf_Half section_entsize; grub_size_t kernel_size; - grub_size_t ia64jmp_off = 0, ia64_toff = 0, ia64_got_off = 0; + grub_size_t ia64jmp_off = 0, tramp_off = 0, ia64_got_off = 0; unsigned ia64jmpnum = 0; Elf_Shdr *symtab_section = 0; grub_size_t got = 0; @@ -1373,6 +1498,21 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, break; } +#ifdef MKIMAGE_ELF32 + if (image_target->elf_target == EM_ARM) + { + grub_size_t tramp; + + *kernel_sz = ALIGN_UP (*kernel_sz, 16); + + tramp = arm_get_trampoline_size (e, sections, section_entsize, + num_sections, image_target); + + tramp_off = *kernel_sz; + *kernel_sz += ALIGN_UP (tramp, 16); + } +#endif + #ifdef MKIMAGE_ELF64 if (image_target->elf_target == EM_IA_64) { @@ -1382,7 +1522,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, grub_ia64_dl_get_tramp_got_size (e, &tramp, &got); - ia64_toff = *kernel_sz; + tramp_off = *kernel_sz; *kernel_sz += ALIGN_UP (tramp, 16); ia64jmp_off = *kernel_sz; @@ -1424,7 +1564,7 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size, SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, num_sections, strtab, - out_img, ia64_toff, ia64_got_off, + out_img, tramp_off, ia64_got_off, image_target); *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, diff --git a/util/mkimage.c b/util/mkimage.c index 11d4a474b..ad12f8a76 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -834,6 +834,94 @@ struct fixup_block_list struct grub_pe32_fixup_block b; }; +/* + * R_ARM_THM_CALL/THM_JUMP24 + * + * Relocate Thumb (T32) instruction set relative branches: + * B.W, BL and BLX + */ +static grub_err_t +grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + offset = grub_arm_thm_call_get_offset (target); + + grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr); + + offset += sym_addr; + + grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n", + target, sym_addr, offset); + + /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel + is bigger than 2M (currently under 150K) then we probably have a problem + somewhere else. */ + if (offset < -0x200000 || offset >= 0x200000) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("THM_CALL Relocation out of range.")); + + grub_dprintf ("dl", " relative destination = %p", + (char *) target + offset); + + return grub_arm_thm_call_set_offset (target, offset); +} + +/* + * R_ARM_THM_JUMP19 + * + * Relocate conditional Thumb (T32) B.W + */ +static grub_err_t +grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (!(sym_addr & 1)) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("Relocation targeting wrong execution state")); + + offset = grub_arm_thm_jump19_get_offset (target); + + /* Adjust and re-truncate offset */ + offset += sym_addr; + + if (!grub_arm_thm_jump19_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("THM_JUMP19 Relocation out of range.")); + + grub_arm_thm_jump19_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + +/* + * R_ARM_JUMP24 + * + * Relocate ARM (A32) B + */ +static grub_err_t +grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (sym_addr & 1) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("Relocation targeting wrong execution state")); + + offset = grub_arm_jump24_get_offset (target); + offset += sym_addr; + + if (!grub_arm_jump24_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + N_("JUMP24 Relocation out of range.")); + + + grub_arm_jump24_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + #pragma GCC diagnostic ignored "-Wcast-align" #define MKIMAGE_ELF32 1 From 896f483d496f1654f01fc726f80f5a299777d8dd Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 6 Dec 2013 10:02:24 +0100 Subject: [PATCH 24/48] * configure.ac: Fix a typo. --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee38108f7..1f876c348 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-06 Vladimir Serbinenko + + * configure.ac: Fix a typo. + 2013-12-06 Vladimir Serbinenko Revamp relocation handling. diff --git a/configure.ac b/configure.ac index fec093b96..0cd666051 100644 --- a/configure.ac +++ b/configure.ac @@ -551,7 +551,7 @@ AC_COMPILE_IFELSE( # used by gcrypt if test x$grub_cv_cc_target_clang_ame = xno ; then TARGET_CCASFLAGS="$TARGET_CCASFLAGS -no-integrated-as" - TARGET_CFLAGS="$TARGET_CCASFLAGS -no-integrated-as" + TARGET_CFLAGS="$TARGET_CFLAGS -no-integrated-as" fi fi From 41822625603d37495e6fdb2257100e0c393be883 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Fri, 6 Dec 2013 11:58:17 +0100 Subject: [PATCH 25/48] Don't add -mlong-calls when compiling with clang. --- ChangeLog | 4 ++++ conf/Makefile.common | 2 +- configure.ac | 12 ++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1f876c348..203038e1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-06 Vladimir Serbinenko + + Don't add -mlong-calls when compiling with clang. + 2013-12-06 Vladimir Serbinenko * configure.ac: Fix a typo. diff --git a/conf/Makefile.common b/conf/Makefile.common index 811573f39..4ec2b811e 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -11,7 +11,7 @@ if COND_sparc64_ieee1275 LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax endif if COND_arm - CFLAGS_PLATFORM += -mthumb-interwork -mlong-calls + CFLAGS_PLATFORM += -mthumb-interwork CCASFLAGS_PLATFORM = -mthumb-interwork LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache endif diff --git a/configure.ac b/configure.ac index 0cd666051..d13cd3d6b 100644 --- a/configure.ac +++ b/configure.ac @@ -848,6 +848,18 @@ if test "$target_cpu"-"$platform" = x86_64-efi; then TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone" fi +if test "x$target_cpu" = xarm; then + AC_CACHE_CHECK([whether option -mlong-calls works], grub_cv_cc_mlong_calls, [ + CFLAGS="$TARGET_CFLAGS -mlong-calls -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mlong_calls=yes], + [grub_cv_cc_mlong_calls=no]) + ]) + if test "x$grub_cv_cc_mlong_calls" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mlong-calls" + fi +fi + # # Compiler features. # From ad73cc3312476346b14a1925dadb16fd55839df7 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 7 Dec 2013 14:24:25 +0400 Subject: [PATCH 26/48] fix use of grub-probe instead of ${grub_probe} --- ChangeLog | 5 +++++ util/grub.d/30_os-prober.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 203038e1f..aa1c7a076 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-07 Andrey Borzenkov + + * util/grub.d/30_os-prober.in: Fix use of grub-probe instead of + ${grub_probe}. + 2013-12-06 Vladimir Serbinenko Don't add -mlong-calls when compiling with clang. diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in index 3d1b93893..0470e6685 100644 --- a/util/grub.d/30_os-prober.in +++ b/util/grub.d/30_os-prober.in @@ -112,7 +112,7 @@ for OS in ${OSPROBED} ; do LONGNAME="`echo ${OS} | cut -d ':' -f 2 | tr '^' ' '`" LABEL="`echo ${OS} | cut -d ':' -f 3 | tr '^' ' '`" BOOT="`echo ${OS} | cut -d ':' -f 4`" - UUID="`grub-probe --target=fs_uuid --device ${DEVICE%@*}`" + UUID="`${grub_probe} --target=fs_uuid --device ${DEVICE%@*}`" EXPUUID="$UUID" if [ x"${DEVICE#*@}" != x ] ; then From 3100cdc7f9983636fb86cb4e29d995ce2ebc12dd Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 7 Dec 2013 14:29:00 +0400 Subject: [PATCH 27/48] add grub_qsort_strcmp to use when sorting array of strings Compare function used in qsort gets arguments by reference, so strcmp cannot be used directly - it expects pointer to char, but gets pointer to pointer to char. Introduce new helper grub_qsort_strcmp and use it in grub-install. This helper is going to be used in a couple more places as well so add it to global file, not in grub-install.c. --- ChangeLog | 7 +++++++ include/grub/util/misc.h | 2 ++ util/grub-install.c | 2 +- util/misc.c | 8 ++++++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa1c7a076..ee27fccd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-12-07 Andrey Borzenkov + + * util/misc.c (grub_qsort_strcmp): Add qsort helper function to sort + strings. + * include/grub/util/misc.h: Define it ... + * util/grub-install.c (device_map_check_duplicates): ... and use it. + 2013-12-07 Andrey Borzenkov * util/grub.d/30_os-prober.in: Fix use of grub-probe instead of diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 6aacf237a..192874d42 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -47,4 +47,6 @@ void grub_util_init_nls (void); void grub_util_host_init (int *argc, char ***argv); +int grub_qsort_strcmp (const void *, const void *); + #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/util/grub-install.c b/util/grub-install.c index 7a1db422b..db5e0c321 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -586,7 +586,7 @@ device_map_check_duplicates (const char *dev_map) fclose (fp); - qsort (d, filled, sizeof (d[0]), (int (*) (const void *, const void *))strcmp); + qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp); for (i = 0; i + 1 < filled; i++) if (strcmp (d[i], d[i+1]) == 0) diff --git a/util/misc.c b/util/misc.c index 0de340bbe..9eb1fc13c 100644 --- a/util/misc.c +++ b/util/misc.c @@ -256,3 +256,11 @@ void grub_register_exported_symbols (void) { } + +/* Used in comparison of arrays of strings with qsort */ +int +grub_qsort_strcmp (const void *p1, const void *p2) +{ + return strcmp(*(char **)p1, *(char **)p2); +} + From 4861b6c85191b8fbe1254b538d70f09bbda64adc Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 11:39:35 +0100 Subject: [PATCH 28/48] * Makefile.am: Remove partial font files if generation failed. --- ChangeLog | 4 ++++ Makefile.am | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee27fccd8..6ff5baa4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-07 Vladimir Serbinenko + + * Makefile.am: Remove partial font files if generation failed. + 2013-12-07 Andrey Borzenkov * util/misc.c (grub_qsort_strcmp): Add qsort helper function to sort diff --git a/Makefile.am b/Makefile.am index 1a69e2e9d..0a2c0991e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -103,7 +103,7 @@ EXTRA_DIST += $(starfield_theme_files) EXTRA_DIST += $(srcdir)/themes/starfield/src/slider_s.xcf $(srcdir)/themes/starfield/src/slider_n.xcf $(srcdir)/themes/starfield/src/slider_c.xcf $(srcdir)/themes/starfield/src/blob_nw.xcf $(srcdir)/themes/starfield/src/bootmenu/center.xcf $(srcdir)/themes/starfield/src/bootmenu/corner.xcf $(srcdir)/themes/starfield/src/bootmenu/side.xcf $(srcdir)/themes/starfield/src/terminalbox/side.xcf $(srcdir)/themes/starfield/src/terminalbox/corner.xcf $(srcdir)/themes/starfield/src/terminalbox/center.xcf unicode.pf2: $(FONT_SOURCE) build-grub-mkfont - ./build-grub-mkfont -o $@ $(FONT_SOURCE) + ./build-grub-mkfont -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1) CLEANFILES += unicode.pf2 # Arrows and lines are needed to draw the menu, so always include them @@ -111,19 +111,19 @@ UNICODE_ARROWS=0x2190-0x2193 UNICODE_LINES=0x2501-0x251B ascii.pf2: $(FONT_SOURCE) build-grub-mkfont - ./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) + ./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) CLEANFILES += ascii.pf2 euro.pf2: $(FONT_SOURCE) build-grub-mkfont - ./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) + ./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1) CLEANFILES += euro.pf2 ascii.h: $(FONT_SOURCE) build-grub-gen-asciih - ./build-grub-gen-asciih $(FONT_SOURCE) $@ + ./build-grub-gen-asciih $(FONT_SOURCE) $@ || (rm -f $@; exit 1) CLEANFILES += ascii.h widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec - ./build-grub-gen-widthspec $(FONT_SOURCE) $@ + ./build-grub-gen-widthspec $(FONT_SOURCE) $@ || (rm -f $@; exit 1) CLEANFILES += widthspec.h # Install config.h into platformdir From 0277eab7013df71eeeec1dc4b7bffbdc810dcb94 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 11:46:46 +0100 Subject: [PATCH 29/48] * configure.ac: Skip unifont 6.3 pcf and bdf. --- ChangeLog | 4 ++++ configure.ac | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6ff5baa4a..990bf5bf3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-07 Vladimir Serbinenko + + * configure.ac: Skip unifont 6.3 pcf and bdf. + 2013-12-07 Vladimir Serbinenko * Makefile.am: Remove partial font files if generation failed. diff --git a/configure.ac b/configure.ac index d13cd3d6b..e9f53f64f 100644 --- a/configure.ac +++ b/configure.ac @@ -1324,6 +1324,11 @@ FONT_SOURCE= for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; do if test -f "$dir/unifont.$ext"; then + md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')" + # PCF and BDF from version 6.3 isn't hanled properly by libfreetype. + if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then + continue; + fi FONT_SOURCE="$dir/unifont.$ext" break 2 fi From 5ff249072ddf833fa9391b3d262fc9332823b49f Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 11:47:19 +0100 Subject: [PATCH 30/48] * configure.ac: Make unifont mandatory on coreboot. --- ChangeLog | 4 ++++ configure.ac | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 990bf5bf3..7ac6c39ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-07 Vladimir Serbinenko + + * configure.ac: Make unifont mandatory on coreboot. + 2013-12-07 Vladimir Serbinenko * configure.ac: Skip unifont 6.3 pcf and bdf. diff --git a/configure.ac b/configure.ac index e9f53f64f..02bc6885f 100644 --- a/configure.ac +++ b/configure.ac @@ -1270,8 +1270,8 @@ if test x"$grub_build_mkfont_excuse" = x ; then else enable_build_grub_mkfont=no fi -if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 ); then - AC_MSG_ERROR([qemu, powerpc-ieee1275 and loongson ports needs build-time grub-mkfont]) +if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then + AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports needs build-time grub-mkfont]) fi AC_SUBST([build_freetype_cflags]) @@ -1339,8 +1339,8 @@ if test x"$enable_build_grub_mkfont" = xno ; then FONT_SOURCE= fi -if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 ); then - AC_MSG_ERROR([qemu, powerpc-ieee1275 and loongson ports need unifont]) +if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$target_cpu"-"$platform" = xpowerpc-ieee1275 || test "x$platform" = xcoreboot ); then + AC_MSG_ERROR([qemu, powerpc-ieee1275, coreboot and loongson ports need unifont]) fi AC_SUBST([FONT_SOURCE]) From f585c905054b8c74e6e0a67341e84accfb816912 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 7 Dec 2013 15:00:37 +0400 Subject: [PATCH 31/48] fix partition module names when /boot is on diskfilter /usr/local/grub2/sbin/grub-install: info: grub-mkimage --directory '/usr/local/grub2/lib/grub/i386-pc' --prefix '(mduuid/e6d1dcf06cea72140bafae74a8677f36)/grub' --output '/boot/grub/i386-pc/core.img' --format 'i386-pc' --compression 'auto' 'ext2' 'msdos' 'msdos' 'diskfilter' 'mdraid1x' 'biosdisk' . /usr/local/grub2/sbin/grub-install: error: cannot open `/usr/local/grub2/lib/grub/i386-pc/msdos.mod': No such file or directory. Introduce common helper for both diskfilter and non-diskfilter case that converts partition map names into module names. --- ChangeLog | 6 ++++++ util/grub-install.c | 37 ++++++++++++++++++++++++------------- util/grub-setup.c | 41 ++++++++++++++++++++++++++++++++++++++++- util/setup.c | 26 +------------------------- 4 files changed, 71 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7ac6c39ec..8d650572a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-07 Andrey Borzenkov + + * util/grub-install.c (push_partmap_module): Add helper to convert + partmap names to module names and use it in probe_mods(). Fixes + failure to find partmap modules in diskfilter case. + 2013-12-07 Vladimir Serbinenko * configure.ac: Make unifont mandatory on coreboot. diff --git a/util/grub-install.c b/util/grub-install.c index db5e0c321..4cc557eea 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -322,6 +322,21 @@ probe_raid_level (grub_disk_t disk) return ((struct grub_diskfilter_lv *) disk->data)->segments->type; } +static void +push_partmap_module (const char *map) +{ + char buf[50]; + + if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0) + { + grub_install_push_module ("part_bsd"); + return; + } + + snprintf (buf, sizeof (buf), "part_%s", map); + grub_install_push_module (buf); +} + static void probe_mods (grub_disk_t disk) { @@ -333,21 +348,11 @@ probe_mods (grub_disk_t disk) grub_util_info ("no partition map found for %s", disk->name); for (part = disk->partition; part; part = part->parent) - { - char buf[50]; - if (strcmp (part->partmap->name, "openbsd") == 0 - || strcmp (part->partmap->name, "netbsd") == 0) - { - grub_install_push_module ("part_bsd"); - continue; - } - snprintf (buf, sizeof (buf), "part_%s", part->partmap->name); - grub_install_push_module (buf); - } + push_partmap_module (part->partmap->name); if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) { - grub_diskfilter_get_partmap (disk, grub_install_push_module); + grub_diskfilter_get_partmap (disk, push_partmap_module); have_abstractions = 1; } @@ -1098,7 +1103,13 @@ main (int argc, char *argv[]) { if (install_device[0] == '(' && install_device[grub_strlen (install_device) - 1] == ')') - install_drive = xstrdup (install_device); + { + + size_t len = grub_strlen (install_device) - 2; + install_drive = xmalloc (len + 1); + memcpy (install_drive, install_device + 1, len); + install_drive[len] = '\0'; + } else { grub_util_pull_device (install_device); diff --git a/util/grub-setup.c b/util/grub-setup.c index cc3af5d26..90b9de013 100644 --- a/util/grub-setup.c +++ b/util/grub-setup.c @@ -209,9 +209,23 @@ DEVICE must be an OS device (e.g. /dev/sda)."), NULL, help_filter, NULL }; +static char * +get_device_name (char *dev) +{ + size_t len = strlen (dev); + + if (dev[0] != '(' || dev[len - 1] != ')') + return 0; + + dev[len - 1] = '\0'; + return dev + 1; +} + int main (int argc, char *argv[]) { + char *root_dev = NULL; + char *dest_dev = NULL; struct arguments arguments; grub_util_host_init (&argc, &argv); @@ -250,11 +264,34 @@ main (int argc, char *argv[]) grub_mdraid1x_init (); grub_lvm_init (); + dest_dev = get_device_name (arguments.device); + if (! dest_dev) + { + /* Possibly, the user specified an OS device file. */ + dest_dev = grub_util_get_grub_dev (arguments.device); + if (! dest_dev) + { + char *program = xstrdup(program_name); + fprintf (stderr, _("Invalid device `%s'.\n"), arguments.device); + argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program); + free(program); + exit(1); + } + grub_util_info ("transformed OS device `%s' into GRUB device `%s'", + arguments.device, dest_dev); + } + else + { + /* For simplicity. */ + dest_dev = xstrdup (dest_dev); + grub_util_info ("Using `%s' as GRUB device", dest_dev); + } + /* Do the real work. */ GRUB_SETUP_FUNC (arguments.dir ? : DEFAULT_DIRECTORY, arguments.boot_file ? : DEFAULT_BOOT_FILE, arguments.core_file ? : DEFAULT_CORE_FILE, - arguments.device, arguments.force, + dest_dev, arguments.force, arguments.fs_probe, arguments.allow_floppy); /* Free resources. */ @@ -266,6 +303,8 @@ main (int argc, char *argv[]) free (arguments.dir); free (arguments.dev_map); free (arguments.device); + free (root_dev); + free (dest_dev); return 0; } diff --git a/util/setup.c b/util/setup.c index c1de3d23c..337c304ef 100644 --- a/util/setup.c +++ b/util/setup.c @@ -247,13 +247,12 @@ identify_partmap (grub_disk_t disk __attribute__ ((unused)), void SETUP (const char *dir, const char *boot_file, const char *core_file, - const char *dev, int force, + const char *dest, int force, int fs_probe, int allow_floppy) { char *core_path; char *boot_img, *core_img, *boot_path; char *root = 0; - char *dest = 0; size_t boot_size, core_size; #ifdef GRUB_SETUP_BIOS grub_uint16_t core_sectors; @@ -270,28 +269,6 @@ SETUP (const char *dir, #endif bl.last_length = 0; - { - size_t len = strlen (dev); - - if (len > 2 && dev[0] == '(' && dev[len - 1] == ')') - { - dest = xmalloc (len - 1); - strncpy (dest, dev + 1, len - 2); - dest[len - 2] = '\0'; - } - } - - if (! dest) - { - /* Possibly, the user specified an OS device file. */ - dest = grub_util_get_grub_dev (dev); - if (! dest) - grub_util_error (_("Invalid device `%s'.\n"), dev); - grub_util_info ("transformed OS device `%s' into GRUB device `%s'", - dev, dest); - } - - /* Read the boot image by the OS service. */ boot_path = grub_util_get_path (dir, boot_file); boot_size = grub_util_get_image_size (boot_path); @@ -326,7 +303,6 @@ SETUP (const char *dir, dest_dev = grub_device_open (dest); if (! dest_dev) grub_util_error ("%s", grub_errmsg); - free (dest); core_dev = dest_dev; From 92e9352ded7f5d2d9c3a36f28522f2131178c415 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 7 Dec 2013 18:58:19 +0400 Subject: [PATCH 32/48] second attempt to fix using grub device name as install device grub-install already resolved passed install device to grub device. So do the same as grub-setup and strip parenthesis if we get legacy (hdX). I accidentally commited revert of 69ca97c820a623f85baf2db1627e19bef9c24e44 and this patch as part of f585c905054b8c74e6e0a67341e84accfb816912. So this commit just adds ChangeLog entry and cosmetic whitespace fix. --- ChangeLog | 6 ++++++ util/grub-install.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8d650572a..d7b982294 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-07 Andrey Borzenkov + + Revert commit 69ca97c820, it caused failures when using OS device name + in grub-install. Instead just strip off parenthesis in grub-install + if (hdX) was passed. + 2013-12-07 Andrey Borzenkov * util/grub-install.c (push_partmap_module): Add helper to convert diff --git a/util/grub-install.c b/util/grub-install.c index 4cc557eea..7596ad91e 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1104,7 +1104,6 @@ main (int argc, char *argv[]) if (install_device[0] == '(' && install_device[grub_strlen (install_device) - 1] == ')') { - size_t len = grub_strlen (install_device) - 2; install_drive = xmalloc (len + 1); memcpy (install_drive, install_device + 1, len); From 4c4ea9c7b5deedff6e629d169bda2d381f849520 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 16:09:39 +0100 Subject: [PATCH 33/48] Merge GRUBFS and GRUB_FS variables. --- ChangeLog | 4 ++++ util/grub-mkconfig.in | 4 ++++ util/grub.d/10_linux.in | 8 +------- util/grub.d/20_linux_xen.in | 8 +------- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7b982294..b27c22d20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-07 Vladimir Serbinenko + + Merge GRUBFS and GRUB_FS variables. + 2013-12-07 Andrey Borzenkov Revert commit 69ca97c820, it caused failures when using OS device name diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 016ee8259..7b85c8817 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -139,6 +139,10 @@ GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_u # choosing Hurd filesystem module. GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" +if [ x"$GRUB_FS" = xunknown ]; then + GRUB_FS="$(stat -f --printf=%T / || echo unknown)" +fi + if test -f ${sysconfdir}/default/grub ; then . ${sysconfdir}/default/grub fi diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index e27d6f75e..00d193159 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -51,13 +51,7 @@ else LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} fi -GRUBFS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" - -if [ x"$GRUBFS" = x ]; then - GRUBFS="$(stat -f --printf=%T / || true)" -fi - -case x"$GRUBFS" in +case x"$GRUB_FS" in xbtrfs) rootsubvol="`make_system_path_relative_to_its_root /`" rootsubvol="${rootsubvol#/}" diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in index f12f05934..a60843500 100644 --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in @@ -59,13 +59,7 @@ if [ "${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" ]; then GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT}" fi -GRUBFS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2>/dev/null || true`" - -if [ x"$GRUBFS" = x ]; then - GRUBFS="$(stat -f --printf=%T /)" -fi - -case x"$GRUBFS" in +case x"$GRUB_FS" in xbtrfs) rootsubvol="`make_system_path_relative_to_its_root /`" rootsubvol="${rootsubvol#/}" From f23bc65103d045f899f02ade6dd9d1f964cdb707 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 16:18:22 +0100 Subject: [PATCH 34/48] Transform -C option to grub-mkstandalone to --core-compress available in all grub-install flavours. --- ChangeLog | 5 +++++ include/grub/util/install.h | 12 +++++++----- util/grub-install-common.c | 30 +++++++++++++++++++++++------- util/grub-install.c | 6 ++---- util/grub-mknetdir.c | 3 +-- util/grub-mkrescue.c | 37 +++++++++++++++---------------------- util/grub-mkstandalone.c | 30 ++++++------------------------ 7 files changed, 59 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index b27c22d20..435420d82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-07 Vladimir Serbinenko + + Transform -C option to grub-mkstandalone to --core-compress available + in all grub-install flavours. + 2013-12-07 Vladimir Serbinenko Merge GRUBFS and GRUB_FS variables. diff --git a/include/grub/util/install.h b/include/grub/util/install.h index 4ba00f55b..beca2d25d 100644 --- a/include/grub/util/install.h +++ b/include/grub/util/install.h @@ -41,6 +41,9 @@ { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ "no,xz,gz,lzo", OPTION_ARG_OPTIONAL, \ N_("compress GRUB files [optional]"), 1 }, \ + {"core-compress", GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, \ + N_("xz|none|auto"), \ + 0, N_("choose the compression to use for core image"), 2}, \ /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \ { "directory", 'd', N_("DIR"), 0, \ N_("use images and modules under DIR [default=%s/]"), 1 }, \ @@ -111,7 +114,8 @@ enum grub_install_options { GRUB_INSTALL_OPTIONS_DIRECTORY2, GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, - GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE + GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, + GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS }; extern char *grub_install_source_directory; @@ -146,15 +150,13 @@ void grub_install_make_image_wrap (const char *dir, const char *prefix, const char *outname, char *memdisk_path, char *config_path, - const char *format, int note, - grub_compression_t comp); + const char *format, int note); void grub_install_make_image_wrap_file (const char *dir, const char *prefix, FILE *fp, const char *outname, char *memdisk_path, char *config_path, - const char *mkimage_target, int note, - grub_compression_t comp); + const char *mkimage_target, int note); int grub_install_copy_file (const char *src, diff --git a/util/grub-install-common.c b/util/grub-install-common.c index 9d9bae709..ea500cc5a 100644 --- a/util/grub-install-common.c +++ b/util/grub-install-common.c @@ -297,12 +297,30 @@ handle_install_list (struct install_list *il, const char *val, static char **pubkeys; static size_t npubkeys; +static grub_compression_t compression; int grub_install_parse (int key, char *arg) { switch (key) { + case 'C': + if (grub_strcmp (arg, "xz") == 0) + { +#ifdef HAVE_LIBLZMA + compression = GRUB_COMPRESSION_XZ; +#else + grub_util_error ("%s", + _("grub-mkimage is compiled without XZ support")); +#endif + } + else if (grub_strcmp (arg, "none") == 0) + compression = GRUB_COMPRESSION_NONE; + else if (grub_strcmp (arg, "auto") == 0) + compression = GRUB_COMPRESSION_AUTO; + else + grub_util_error (_("Unknown compression format %s"), arg); + return 1; case 'k': pubkeys = xrealloc (pubkeys, sizeof (pubkeys[0]) @@ -401,8 +419,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, FILE *fp, const char *outname, char *memdisk_path, char *config_path, - const char *mkimage_target, int note, - grub_compression_t comp) + const char *mkimage_target, int note) { const struct grub_install_image_target_desc *tgt; const char *const compnames[] = @@ -468,7 +485,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, "--format '%s' --compression '%s' %s %s\n", dir, prefix, outname, mkimage_target, - compnames[comp], note ? "--note" : "", s); + compnames[compression], note ? "--note" : "", s); tgt = grub_install_get_image_target (mkimage_target); if (!tgt) @@ -477,7 +494,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, pubkeys, npubkeys, config_path, tgt, - note, comp); + note, compression); while (dc--) grub_install_pop_module (); } @@ -486,8 +503,7 @@ void grub_install_make_image_wrap (const char *dir, const char *prefix, const char *outname, char *memdisk_path, char *config_path, - const char *mkimage_target, int note, - grub_compression_t comp) + const char *mkimage_target, int note) { FILE *fp; @@ -497,7 +513,7 @@ grub_install_make_image_wrap (const char *dir, const char *prefix, strerror (errno)); grub_install_make_image_wrap_file (dir, prefix, fp, outname, memdisk_path, config_path, - mkimage_target, note, comp); + mkimage_target, note); grub_util_file_sync (fp); fclose (fp); } diff --git a/util/grub-install.c b/util/grub-install.c index 7596ad91e..0aa7f48b4 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -1368,8 +1368,7 @@ main (int argc, char *argv[]) /* output */ imgfile, /* memdisk */ NULL, have_load_cfg ? load_cfg : NULL, - /* image target */ mkimage_target, - 0, GRUB_COMPRESSION_AUTO); + /* image target */ mkimage_target, 0); /* Backward-compatibility kludges. */ switch (platform) { @@ -1399,8 +1398,7 @@ main (int argc, char *argv[]) /* output */ dst, /* memdisk */ NULL, have_load_cfg ? load_cfg : NULL, - /* image target */ mkimage_target, - 0, GRUB_COMPRESSION_AUTO); + /* image target */ mkimage_target, 0); } break; case GRUB_INSTALL_PLATFORM_ARM_EFI: diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c index 40ca7248b..26f4c0eb4 100644 --- a/util/grub-mknetdir.c +++ b/util/grub-mknetdir.c @@ -149,8 +149,7 @@ process_input_dir (const char *input_dir, enum grub_install_plat platform) output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); grub_install_make_image_wrap (input_dir, prefix, output, 0, load_cfg, - targets[platform].mkimage_target, 0, - GRUB_COMPRESSION_AUTO); + targets[platform].mkimage_target, 0); grub_install_pop_module (); /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */ diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c index d212cb645..3e19cb720 100644 --- a/util/grub-mkrescue.c +++ b/util/grub-mkrescue.c @@ -241,8 +241,7 @@ write_part (FILE *f, const char *srcdir) static void make_image_abs (enum grub_install_plat plat, const char *mkimage_target, - const char *output, - grub_compression_t compress) + const char *output) { char *load_cfg; FILE *load_cfg_f; @@ -266,8 +265,7 @@ make_image_abs (enum grub_install_plat plat, grub_install_push_module ("iso9660"); grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output, 0, load_cfg, - mkimage_target, 0, - compress); + mkimage_target, 0); grub_install_pop_module (); grub_install_pop_module (); grub_util_unlink (load_cfg); @@ -276,12 +274,10 @@ make_image_abs (enum grub_install_plat plat, static void make_image (enum grub_install_plat plat, const char *mkimage_target, - const char *output_sub, - grub_compression_t compress) + const char *output_sub) { char *out = grub_util_path_concat (2, boot_grub, output_sub); - make_image_abs (plat, mkimage_target, - out, GRUB_COMPRESSION_AUTO); + make_image_abs (plat, mkimage_target, out); free (out); } @@ -307,8 +303,7 @@ make_image_fwdisk_abs (enum grub_install_plat plat, grub_install_push_module ("iso9660"); grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, - 0, load_cfg, mkimage_target, 0, - GRUB_COMPRESSION_AUTO); + 0, load_cfg, mkimage_target, 0); grub_install_pop_module (); } @@ -483,8 +478,7 @@ main (int argc, char *argv[]) grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], "/boot/grub", output, 0, load_cfg, - "i386-pc-eltorito", 0, - GRUB_COMPRESSION_AUTO); + "i386-pc-eltorito", 0); xorriso_push ("-b"); xorriso_push ("boot/grub/i386-pc/eltorito.img"); @@ -528,8 +522,7 @@ main (int argc, char *argv[]) grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], "/boot/grub", output, 0, load_cfg, - "i386-pc", 0, - GRUB_COMPRESSION_AUTO); + "i386-pc", 0); sz = ftello (sa); fflush (sa); grub_util_fd_sync (fileno (sa)); @@ -554,7 +547,7 @@ main (int argc, char *argv[]) grub_install_push_module ("pata"); grub_install_push_module ("ahci"); grub_install_push_module ("at_keyboard"); - make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf", GRUB_COMPRESSION_AUTO); + make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf"); grub_install_pop_module (); grub_install_pop_module (); grub_install_pop_module (); @@ -775,22 +768,22 @@ main (int argc, char *argv[]) make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe"); grub_install_push_module ("pata"); - make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf", GRUB_COMPRESSION_AUTO); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf"); - make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf", GRUB_COMPRESSION_XZ); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf"); - make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin", GRUB_COMPRESSION_XZ); - make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin", GRUB_COMPRESSION_XZ); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin"); - make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf", GRUB_COMPRESSION_AUTO); + make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf"); grub_install_push_module ("at_keyboard"); - make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img", GRUB_COMPRESSION_AUTO); + make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img"); grub_install_push_module ("ahci"); - make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf", GRUB_COMPRESSION_AUTO); + make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf"); grub_install_pop_module (); grub_install_pop_module (); grub_install_pop_module (); diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c index 3097f704d..6ee5e588a 100644 --- a/util/grub-mkstandalone.c +++ b/util/grub-mkstandalone.c @@ -25,7 +25,6 @@ #include #include -static grub_compression_t compression; static char *output_image; static char **files; static int nfiles; @@ -35,8 +34,7 @@ static FILE *memdisk; enum { OPTION_OUTPUT = 'o', - OPTION_FORMAT = 'C', - OPTION_COMPRESION = 'C' + OPTION_FORMAT = 'O' }; static struct argp_option options[] = { @@ -44,8 +42,7 @@ static struct argp_option options[] = { {"output", 'o', N_("FILE"), 0, N_("save output in FILE [required]"), 2}, {"format", 'O', N_("FILE"), 0, 0, 2}, - {"compression", 'C', N_("xz|none|auto"), - 0, N_("choose the compression to use for core image"), 2}, + {"compression", 'C', N_("xz|none|auto"), OPTION_HIDDEN, 0, 2}, {0, 0, 0, 0, 0, 0} }; @@ -70,6 +67,9 @@ help_filter (int key, const char *text, void *input __attribute__ ((unused))) static error_t argp_parser (int key, char *arg, struct argp_state *state) { + if (key == 'C') + key = GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS; + if (grub_install_parse (key, arg)) return 0; @@ -95,23 +95,6 @@ argp_parser (int key, char *arg, struct argp_state *state) break; } - case 'C': - if (grub_strcmp (arg, "xz") == 0) - { -#ifdef HAVE_LIBLZMA - compression = GRUB_COMPRESSION_XZ; -#else - grub_util_error ("%s", - _("grub-mkimage is compiled without XZ support")); -#endif - } - else if (grub_strcmp (arg, "none") == 0) - compression = GRUB_COMPRESSION_NONE; - else if (grub_strcmp (arg, "auto") == 0) - compression = GRUB_COMPRESSION_AUTO; - else - grub_util_error (_("Unknown compression format %s"), arg); - break; case ARGP_KEY_ARG: files[nfiles++] = xstrdup (arg); break; @@ -365,8 +348,7 @@ main (int argc, char *argv[]) grub_install_make_image_wrap (grub_install_source_directory, "(memdisk)/boot/grub", output_image, memdisk_img, NULL, - grub_util_get_target_name (format), 0, - compression); + grub_util_get_target_name (format), 0); grub_util_unlink (memdisk_img); return 0; From bb05e313ebce4e7f959c5577cad5d2c1ec0360be Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sat, 7 Dec 2013 20:00:48 +0400 Subject: [PATCH 35/48] use light-gray as default color in normal.mod for consistency Defalut font color on PC console seems to be light-gray; this is what user also gets in rescue prompt and what is defined as GRUB_TERM_DEFAULT_NORMAL_COLOR. But normal.mod defaults to white. This makes unpleasant visual effect as colors are changed after kernel is booted. Use the same color eveywhere for consistency and default to light-gray as this is also what at least Linux kernel is using by default. --- ChangeLog | 6 ++++++ grub-core/normal/main.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 435420d82..59f440013 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-07 Andrey Borzenkov + + * grub-core/normal/main.c (INIT): Set default color to light-gray + to match GRUB_TERM_DEFAULT_NORMAL_COLOR (i.e. rescue mode), Linux + and apparently BIOS defaults. + 2013-12-07 Vladimir Serbinenko Transform -C option to grub-mkstandalone to --core-compress available diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 778de61cd..991a59524 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -572,8 +572,8 @@ GRUB_MOD_INIT(normal) grub_env_export ("color_highlight"); /* Set default color names. */ - grub_env_set ("color_normal", "white/black"); - grub_env_set ("color_highlight", "black/white"); + grub_env_set ("color_normal", "light-gray/black"); + grub_env_set ("color_highlight", "black/light-gray"); for (i = 0; i < ARRAY_SIZE (features); i++) { From c50e5f454345d83662f3f4cf375f391073ea528c Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Sun, 8 Dec 2013 00:00:26 +0400 Subject: [PATCH 36/48] Update color_normal and color_highlight defaults (light-gray instead of white) --- ChangeLog | 5 +++++ docs/grub.texi | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 59f440013..f146edba8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-07 Andrey Borzenkov + + * docs/grub.texi (Environment): Update color_normal and color_highlight + defaults (light-gray instead of white). + 2013-12-07 Andrey Borzenkov * grub-core/normal/main.c (INIT): Set default color to light-gray diff --git a/docs/grub.texi b/docs/grub.texi index 6144740f7..54b02fd52 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3123,7 +3123,7 @@ This variable contains the ``highlight'' foreground and background terminal colors, separated by a slash (@samp{/}). Setting this variable changes those colors. For the available color names, @pxref{color_normal}. -The default is @samp{black/white}. +The default is @samp{black/light-gray}. @node color_normal @@ -3152,7 +3152,7 @@ those colors. Each color must be a name from the following list: @item white @end itemize -The default is @samp{white/black}. +The default is @samp{light-gray/black}. The color support support varies from terminal to terminal. From c8fd2ddf6dfc99bf390c0e6f68679b01bc287441 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sat, 7 Dec 2013 23:28:20 +0100 Subject: [PATCH 37/48] * util/grub-mkfont.c: Replace stpcpy with grub_stpcpy. --- ChangeLog | 4 ++++ util/grub-mkfont.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f146edba8..ca2e17fe8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-07 Vladimir Serbinenko + + * util/grub-mkfont.c: Replace stpcpy with grub_stpcpy. + 2013-12-07 Andrey Borzenkov * docs/grub.texi (Environment): Update color_normal and color_highlight diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index 242dd01ee..d3a8af05c 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -821,9 +821,9 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) font_name = xmalloc (strlen (font_info->name) + strlen (&style_name[1]) + 3 + 20); - ptr = stpcpy (font_name, font_info->name); + ptr = grub_stpcpy (font_name, font_info->name); *ptr++ = ' '; - ptr = stpcpy (ptr, &style_name[1]); + ptr = grub_stpcpy (ptr, &style_name[1]); *ptr++ = ' '; snprintf (ptr, 20, "%d", font_info->size); From c311ced5d79d408e24f93bc8986cfac0c0810ce8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 02:59:21 +0100 Subject: [PATCH 38/48] Make arm-emu work. --- ChangeLog | 4 ++++ conf/Makefile.common | 2 ++ grub-core/kern/emu/cache.c | 2 +- grub-core/kern/emu/cache_s.S | 2 +- grub-core/kern/emu/full.c | 8 +++++--- grub-core/kern/emu/lite.c | 6 ++++++ grub-core/kern/misc.c | 2 +- grub-core/tests/video_checksum.c | 4 ++-- 8 files changed, 22 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca2e17fe8..0a725555b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-08 Vladimir Serbinenko + + Make arm-emu work. + 2013-12-07 Vladimir Serbinenko * util/grub-mkfont.c: Replace stpcpy with grub_stpcpy. diff --git a/conf/Makefile.common b/conf/Makefile.common index 4ec2b811e..47f3b9a03 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -13,8 +13,10 @@ endif if COND_arm CFLAGS_PLATFORM += -mthumb-interwork CCASFLAGS_PLATFORM = -mthumb-interwork +if !COND_emu LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache endif +endif if COND_arm64 CFLAGS_PLATFORM += -mcmodel=large endif diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c index 543e457e5..4a701f44a 100644 --- a/grub-core/kern/emu/cache.c +++ b/grub-core/kern/emu/cache.c @@ -1,5 +1,5 @@ -#if defined(__ia64__) +#if defined(__ia64__) || defined (__arm__) || defined (__aarch64__) #include void __clear_cache (char *beg, char *end); diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S index 8ca695c28..7fbebb80d 100644 --- a/grub-core/kern/emu/cache_s.S +++ b/grub-core/kern/emu/cache_s.S @@ -23,7 +23,7 @@ FUNCTION (grub_arch_sync_caches) .set macro #elif defined(__powerpc__) #include "../powerpc/cache.S" -#elif defined(__ia64__) +#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c index e056ded97..03888d8ec 100644 --- a/grub-core/kern/emu/full.c +++ b/grub-core/kern/emu/full.c @@ -49,12 +49,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, return GRUB_ERR_BAD_MODULE; } -#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__) -void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), - grub_size_t *tramp, grub_size_t *got) +#if !defined (__i386__) && !defined (__x86_64__) && !defined (__sparc__) +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), + grub_size_t *tramp, grub_size_t *got) { *tramp = 0; *got = 0; + return GRUB_ERR_BAD_MODULE; } #endif diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index 00b811bf5..be1e67876 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -17,6 +17,12 @@ #include "../powerpc/dl.c" #elif defined(__ia64__) #include "../ia64/dl.c" +#elif defined(__arm__) +#include "../arm/dl_helper.c" +#include "../arm/dl.c" +#elif defined(__aarch64__) +#include "../arm64/dl_helper.c" +#include "../arm64/dl.c" #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index cbd2748ed..05cb1faf7 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -628,7 +628,7 @@ grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r) return q; } -#ifndef GRUB_UTIL +#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) #if defined (__arm__) diff --git a/grub-core/tests/video_checksum.c b/grub-core/tests/video_checksum.c index 996b936cb..f8927555f 100644 --- a/grub-core/tests/video_checksum.c +++ b/grub-core/tests/video_checksum.c @@ -350,7 +350,7 @@ grub_video_capture_write_bmp (const char *fname, for (y = mode_info->height - 1; y >= 0; y--) { - grub_uint32_t *iptr = (grub_uint32_t *) ((grub_uint8_t *) ptr + mode_info->pitch * y); + grub_uint32_t *iptr = (grub_uint32_t *) ptr + (mode_info->pitch / 4) * y; int x; grub_uint8_t *optr = buffer; for (x = 0; x < (int) mode_info->width; x++) @@ -421,7 +421,7 @@ grub_video_capture_write_bmp (const char *fname, for (y = mode_info->height - 1; y >= 0; y--) { - grub_uint16_t *iptr = (grub_uint16_t *) ((grub_uint8_t *) ptr + mode_info->pitch * y); + grub_uint16_t *iptr = (grub_uint16_t *) ptr + (mode_info->pitch / 2) * y; int x; grub_uint8_t *optr = buffer; for (x = 0; x < (int) mode_info->width; x++) From b75db69ac1780a0fe2b3c732407370f203b90c73 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 10:50:59 +0100 Subject: [PATCH 39/48] * configure.ac: Check for freetype library usability. --- ChangeLog | 4 ++++ configure.ac | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0a725555b..284be912a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-08 Vladimir Serbinenko + + * configure.ac: Check for freetype library usability. + 2013-12-08 Vladimir Serbinenko Make arm-emu work. diff --git a/configure.ac b/configure.ac index 02bc6885f..1e329c67d 100644 --- a/configure.ac +++ b/configure.ac @@ -1201,10 +1201,14 @@ if test x"$grub_mkfont_excuse" = x ; then freetype_cflags=`$FREETYPE --cflags` freetype_libs=`$FREETYPE --libs` SAVED_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $freetype_cflags" + LIBS="$LIBS $freetype_libs" AC_CHECK_HEADERS([ft2build.h], [], [grub_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_mkfont_excuse=["freetype2 library unusable"]]) CPPFLAGS="$SAVED_CPPFLAGS" + LIBS="$SAVED_LIBS" fi if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then @@ -1256,9 +1260,13 @@ if test x"$grub_build_mkfont_excuse" = x ; then build_freetype_cflags=`$BUILD_FREETYPE --cflags` build_freetype_libs=`$BUILD_FREETYPE --libs` SAVED_CPPFLAGS_2="$CPPFLAGS" + SAVED_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $build_freetype_cflags" + LIBS="$LIBS $build_freetype_libs" AC_CHECK_HEADERS([ft2build.h], [], [grub_build_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], [grub_build_mkfont_excuse=["freetype2 library unusable"]]) + LIBS="$SAVED_LIBS" CPPFLAGS="$SAVED_CPPFLAGS_2" fi From d5c14e1e2649880877bbba2672ed89aa26946dcb Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 17:49:02 +0100 Subject: [PATCH 40/48] Fix mips-emu compilation. --- ChangeLog | 4 ++++ grub-core/Makefile.am | 2 -- grub-core/kern/emu/cache.c | 13 ++++++++++++- grub-core/kern/emu/cache_s.S | 17 +---------------- grub-core/kern/mips/cache.S | 1 - include/grub/cache.h | 6 ++---- include/grub/mips/cache.h | 27 --------------------------- include/grub/misc.h | 2 +- include/grub/time.h | 7 +++++++ 9 files changed, 27 insertions(+), 52 deletions(-) delete mode 100644 include/grub/mips/cache.h diff --git a/ChangeLog b/ChangeLog index 284be912a..07f8dfb96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-08 Vladimir Serbinenko + + Fix mips-emu compilation. + 2013-12-08 Vladimir Serbinenko * configure.ac: Check for freetype library usability. diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index f69da18c3..5b804c7d4 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -169,7 +169,6 @@ endif if COND_mips_qemu_mips KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h @@ -181,7 +180,6 @@ if COND_mips_loongson KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h -KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h diff --git a/grub-core/kern/emu/cache.c b/grub-core/kern/emu/cache.c index 4a701f44a..b6f6faca2 100644 --- a/grub-core/kern/emu/cache.c +++ b/grub-core/kern/emu/cache.c @@ -1,6 +1,7 @@ +#include + #if defined(__ia64__) || defined (__arm__) || defined (__aarch64__) -#include void __clear_cache (char *beg, char *end); @@ -9,5 +10,15 @@ grub_arch_sync_caches (void *address, grub_size_t len) { __clear_cache (address, (char *) address + len); } + +#elif defined (__mips__) +void _flush_cache (void *address, grub_size_t len, int type); + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + return _flush_cache (address, len, 0); +} + #endif diff --git a/grub-core/kern/emu/cache_s.S b/grub-core/kern/emu/cache_s.S index 7fbebb80d..76cf7560d 100644 --- a/grub-core/kern/emu/cache_s.S +++ b/grub-core/kern/emu/cache_s.S @@ -6,24 +6,9 @@ /* Nothing is necessary. */ #elif defined(__sparc__) #include "../sparc64/cache.S" -#elif defined(__mips__) -/* On MIPS we must go through standard functions. */ -#include - -FUNCTION (grub_cpu_flush_cache) -FUNCTION (grub_arch_sync_caches) - .set nomacro - .set noreorder - lui $t0, %hi(_flush_cache) - addui $t0, $t0, %lo(_flush_cache) - move $a3, $zero - jr $t0 - nop - .set reorder - .set macro #elif defined(__powerpc__) #include "../powerpc/cache.S" -#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) +#elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || defined(__mips__) #else #error "No target cpu type is defined" #endif diff --git a/grub-core/kern/mips/cache.S b/grub-core/kern/mips/cache.S index cca4b30fe..78e40bcea 100644 --- a/grub-core/kern/mips/cache.S +++ b/grub-core/kern/mips/cache.S @@ -4,7 +4,6 @@ .set noreorder .set nomacro -FUNCTION (grub_cpu_flush_cache) FUNCTION (grub_arch_sync_caches) #include "cache_flush.S" j $ra diff --git a/include/grub/cache.h b/include/grub/cache.h index 292830566..c6a0b0ba4 100644 --- a/include/grub/cache.h +++ b/include/grub/cache.h @@ -23,10 +23,6 @@ #include #include -#ifdef _mips -#include -#endif - #if defined (__i386__) || defined (__x86_64__) static inline void grub_arch_sync_caches (void *address __attribute__ ((unused)), @@ -37,6 +33,7 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); #endif +#ifndef GRUB_MACHINE_EMU #ifdef _mips void EXPORT_FUNC(grub_arch_sync_dma_caches) (void *address, grub_size_t len); #else @@ -46,5 +43,6 @@ grub_arch_sync_dma_caches (void *address __attribute__ ((unused)), { } #endif +#endif #endif /* ! GRUB_CACHE_HEADER */ diff --git a/include/grub/mips/cache.h b/include/grub/mips/cache.h deleted file mode 100644 index c3470571e..000000000 --- a/include/grub/mips/cache.h +++ /dev/null @@ -1,27 +0,0 @@ -/* cache.h - Flush the processor's cache. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2007 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 . - */ - -#ifndef GRUB_CPU_CACHE_H -#define GRUB_CPU_CACHE_H 1 - -#include -#include - -void EXPORT_FUNC(grub_cpu_flush_cache) (void *start, grub_size_t size, int type); -#endif diff --git a/include/grub/misc.h b/include/grub/misc.h index d80da3349..be74d9082 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -429,7 +429,7 @@ void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); /* Halt the system, using APM if possible. If NO_APM is true, don't * use APM even if it is available. */ void grub_halt (int no_apm) __attribute__ ((noreturn)); -#elif defined (__mips__) +#elif defined (__mips__) && !defined (GRUB_MACHINE_EMU) void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); #else void grub_halt (void) __attribute__ ((noreturn)); diff --git a/include/grub/time.h b/include/grub/time.h index 949452680..64ac99a12 100644 --- a/include/grub/time.h +++ b/include/grub/time.h @@ -21,7 +21,14 @@ #include #include +#ifndef GRUB_MACHINE_EMU #include +#else +static inline void +grub_cpu_idle(void) +{ +} +#endif void EXPORT_FUNC(grub_millisleep) (grub_uint32_t ms); grub_uint64_t EXPORT_FUNC(grub_get_time_ms) (void); From a19293cb7586223541d5f80ae58cbe29df03f87f Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:07:41 +0100 Subject: [PATCH 41/48] Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c and implement windows variant. --- ChangeLog | 5 +++ grub-core/Makefile.core.def | 3 ++ grub-core/kern/dl.c | 20 +++++------- grub-core/osdep/dl.c | 5 +++ grub-core/osdep/unix/dl.c | 61 ++++++++++++++++++++++++++++++++++++ grub-core/osdep/windows/dl.c | 59 ++++++++++++++++++++++++++++++++++ include/grub/dl.h | 7 +++++ 7 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 grub-core/osdep/dl.c create mode 100644 grub-core/osdep/unix/dl.c create mode 100644 grub-core/osdep/windows/dl.c diff --git a/ChangeLog b/ChangeLog index 07f8dfb96..6f90aada0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-08 Vladimir Serbinenko + + Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c + and implement windows variant. + 2013-12-08 Vladimir Serbinenko Fix mips-emu compilation. diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 57abb4910..0a4eba56b 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -282,6 +282,9 @@ kernel = { emu = osdep/emuconsole.c; extra_dist = osdep/unix/emuconsole.c; extra_dist = osdep/windows/emuconsole.c; + emu = osdep/dl.c; + extra_dist = osdep/unix/dl.c; + extra_dist = osdep/windows/dl.c; emu = osdep/sleep.c; emu = osdep/init.c; emu = osdep/emunet.c; diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c index f01fcfd4f..90589f75b 100644 --- a/grub-core/kern/dl.c +++ b/grub-core/kern/dl.c @@ -38,10 +38,6 @@ #define GRUB_MODULES_MACHINE_READONLY #endif -#ifdef GRUB_MACHINE_EMU -#include -#endif - #pragma GCC diagnostic ignored "-Wcast-align" @@ -258,21 +254,15 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) #endif #ifdef GRUB_MACHINE_EMU - if (talign < 8192 * 16) - talign = 8192 * 16; - tsize = ALIGN_UP (tsize, 8192 * 16); -#endif - + mod->base = grub_osdep_dl_memalign (talign, tsize); +#else mod->base = grub_memalign (talign, tsize); +#endif if (!mod->base) return grub_errno; mod->sz = tsize; ptr = mod->base; -#ifdef GRUB_MACHINE_EMU - mprotect (mod->base, tsize, PROT_READ | PROT_WRITE | PROT_EXEC); -#endif - for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum; i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) @@ -782,7 +772,11 @@ grub_dl_unload (grub_dl_t mod) grub_free (dep); } +#ifdef GRUB_MACHINE_EMU + grub_dl_osdep_dl_free (mod->base); +#else grub_free (mod->base); +#endif grub_free (mod->name); #ifdef GRUB_MODULES_MACHINE_READONLY grub_free (mod->symtab); diff --git a/grub-core/osdep/dl.c b/grub-core/osdep/dl.c new file mode 100644 index 000000000..c51174763 --- /dev/null +++ b/grub-core/osdep/dl.c @@ -0,0 +1,5 @@ +#if defined (__MINGW32__) || defined (__CYGWIN__) +#include "windows/dl.c" +#else +#include "unix/dl.c" +#endif diff --git a/grub-core/osdep/unix/dl.c b/grub-core/osdep/unix/dl.c new file mode 100644 index 000000000..562b101a2 --- /dev/null +++ b/grub-core/osdep/unix/dl.c @@ -0,0 +1,61 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 +#include +#include + +void * +grub_osdep_dl_memalign (grub_size_t align, grub_size_t size) +{ + void *ret; + if (align < 8192 * 16) + align = 8192 * 16; + size = ALIGN_UP (size, 8192 * 16); + +#if defined(HAVE_POSIX_MEMALIGN) + if (posix_memalign (&ret, align, size) != 0) + ret = 0; +#elif defined(HAVE_MEMALIGN) + ret = memalign (align, size); +#else +#error "Complete this" +#endif + + if (!ret) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + return NULL; + } + + mprotect (ret, size, PROT_READ | PROT_WRITE | PROT_EXEC); + return ret; +} + +void +grub_dl_osdep_dl_free (void *ptr) +{ + if (ptr) + free (ptr); +} diff --git a/grub-core/osdep/windows/dl.c b/grub-core/osdep/windows/dl.c new file mode 100644 index 000000000..b18a4a009 --- /dev/null +++ b/grub-core/osdep/windows/dl.c @@ -0,0 +1,59 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 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 +#include +#include + +void * +grub_osdep_dl_memalign (grub_size_t align, grub_size_t size) +{ + void *ret; + if (align > 4096) + { + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, N_("too large alignment")); + return NULL; + } + + size = ALIGN_UP (size, 4096); + + ret = VirtualAlloc (NULL, size, MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + + if (!ret) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + return NULL; + } + + return ret; +} + +void +grub_dl_osdep_dl_free (void *ptr) +{ + if (!ptr) + return; + VirtualFree (ptr, 0, MEM_RELEASE); +} diff --git a/include/grub/dl.h b/include/grub/dl.h index 6c758c01a..58b636f16 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -210,6 +210,13 @@ extern grub_dl_t EXPORT_VAR(grub_dl_head); #define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) +#ifdef GRUB_MACHINE_EMU +void * +grub_osdep_dl_memalign (grub_size_t align, grub_size_t size); +void +grub_dl_osdep_dl_free (void *ptr); +#endif + static inline void grub_dl_init (grub_dl_t mod) { From fbbfb6ab11112dec9e35023595bada364814ce7e Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:10:05 +0100 Subject: [PATCH 42/48] * grub-core/kern/ia64/efi/init.c: Fix alignment code so it doesn't truncate incomplete lines but instead flushes them. --- ChangeLog | 5 +++++ grub-core/kern/ia64/efi/init.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6f90aada0..e7b4e9fe1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-08 Vladimir Serbinenko + + * grub-core/kern/ia64/efi/init.c: Fix alignment code so it doesn't + truncate incomplete lines but instead flushes them. + 2013-12-08 Vladimir Serbinenko Move OS-dependent mprotect for module loading to grub-core/osdep/*/dl.c diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index 5587d9cd8..f00509833 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -79,6 +79,7 @@ void grub_arch_sync_caches (void *address, grub_size_t len) { /* Cache line length is at least 32. */ + len += (grub_uint64_t)address & 0x1f; grub_uint64_t a = (grub_uint64_t)address & ~0x1f; /* Flush data. */ From 50b3a68db94aa9733160721b203b2a3d257842e7 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:12:20 +0100 Subject: [PATCH 43/48] Remove grub_memalign on emu. --- ChangeLog | 4 ++++ grub-core/kern/emu/mm.c | 23 ----------------------- grub-core/net/netbuff.c | 4 ++++ include/grub/mm.h | 2 ++ 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7b4e9fe1..2ee7d46ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-08 Vladimir Serbinenko + + Remove grub_memalign on emu. + 2013-12-08 Vladimir Serbinenko * grub-core/kern/ia64/efi/init.c: Fix alignment code so it doesn't diff --git a/grub-core/kern/emu/mm.c b/grub-core/kern/emu/mm.c index 10e1cc0d9..f262e95e3 100644 --- a/grub-core/kern/emu/mm.c +++ b/grub-core/kern/emu/mm.c @@ -62,26 +62,3 @@ grub_realloc (void *ptr, grub_size_t size) grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); return ret; } - -#if defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_MEMALIGN) -void * -grub_memalign (grub_size_t align, grub_size_t size) -{ - void *p; - - if (align < sizeof (void *)) - align = sizeof (void *); - -#if defined(HAVE_POSIX_MEMALIGN) - if (posix_memalign (&p, align, size) != 0) - p = 0; -#elif defined(HAVE_MEMALIGN) - p = memalign (align, size); -#endif - - if (!p) - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); - - return p; -} -#endif diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c index 47b0506ed..e97ecd23e 100644 --- a/grub-core/net/netbuff.c +++ b/grub-core/net/netbuff.c @@ -83,7 +83,11 @@ grub_netbuff_alloc (grub_size_t len) len = NETBUFFMINLEN; len = ALIGN_UP (len, NETBUFF_ALIGN); +#ifdef GRUB_MACHINE_EMU + data = grub_malloc (len + sizeof (*nb)); +#else data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); +#endif if (!data) return NULL; nb = (struct grub_net_buff *) ((grub_properly_aligned_t *) data diff --git a/include/grub/mm.h b/include/grub/mm.h index c6660af71..28e2e53eb 100644 --- a/include/grub/mm.h +++ b/include/grub/mm.h @@ -33,7 +33,9 @@ void *EXPORT_FUNC(grub_malloc) (grub_size_t size); void *EXPORT_FUNC(grub_zalloc) (grub_size_t size); void EXPORT_FUNC(grub_free) (void *ptr); void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); +#ifndef GRUB_MACHINE_EMU void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); +#endif void grub_mm_check_real (const char *file, int line); #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); From fa7eb63decd0fe5a7114d710608952529497eef7 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:14:32 +0100 Subject: [PATCH 44/48] * grub-core/kern/emu/lite.c: Add missing include of ../ia64/dl_helper.c. --- ChangeLog | 4 ++++ grub-core/kern/emu/lite.c | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2ee7d46ba..c62eeb03c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-12-08 Vladimir Serbinenko + + * grub-core/kern/emu/lite.c: Add missing include of ../ia64/dl_helper.c. + 2013-12-08 Vladimir Serbinenko Remove grub_memalign on emu. diff --git a/grub-core/kern/emu/lite.c b/grub-core/kern/emu/lite.c index be1e67876..b2fc93d7f 100644 --- a/grub-core/kern/emu/lite.c +++ b/grub-core/kern/emu/lite.c @@ -16,6 +16,7 @@ #elif defined(__powerpc__) #include "../powerpc/dl.c" #elif defined(__ia64__) +#include "../ia64/dl_helper.c" #include "../ia64/dl.c" #elif defined(__arm__) #include "../arm/dl_helper.c" From 11e4167a35c6eecfadc8e27da2dc5e8cc313a2cd Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:16:32 +0100 Subject: [PATCH 45/48] * grub-core/osdep/windows/emuconsole.c: Remove unsigned comparison >= 0. But ensure that the variables in question are indeed unsigned. --- ChangeLog | 5 +++++ grub-core/osdep/windows/emuconsole.c | 8 +++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c62eeb03c..9e2ed0c60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-08 Vladimir Serbinenko + + * grub-core/osdep/windows/emuconsole.c: Remove unsigned comparison >= 0. + But ensure that the variables in question are indeed unsigned. + 2013-12-08 Vladimir Serbinenko * grub-core/kern/emu/lite.c: Add missing include of ../ia64/dl_helper.c. diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c index 8d7483c3f..4fb3693cc 100644 --- a/grub-core/osdep/windows/emuconsole.c +++ b/grub-core/osdep/windows/emuconsole.c @@ -108,11 +108,9 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) ret = ir.Event.KeyEvent.uChar.UnicodeChar; if (ret == 0) { - if (ir.Event.KeyEvent.wVirtualKeyCode >= 0 - && ir.Event.KeyEvent.wVirtualKeyCode - < ARRAY_SIZE (windows_codes) - && windows_codes[(int) ir.Event.KeyEvent.wVirtualKeyCode]) - ret = windows_codes[(int) ir.Event.KeyEvent.wVirtualKeyCode]; + unsigned kc = ir.Event.KeyEvent.wVirtualKeyCode; + if (kc < ARRAY_SIZE (windows_codes) && windows_codes[kc]) + ret = windows_codes[kc]; else continue; if (ir.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) From 388f3cd0d1758338d6f27f7fb542d6148b922b35 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:19:42 +0100 Subject: [PATCH 46/48] * include/grub/kernel.h [__sparc__]: Restrict sparc64-ieee1275 to right platform rather than leaking to sparc64-emu. --- ChangeLog | 5 +++++ include/grub/kernel.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9e2ed0c60..f4691f3a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-08 Vladimir Serbinenko + + * include/grub/kernel.h [__sparc__]: Restrict sparc64-ieee1275 to + right platform rather than leaking to sparc64-emu. + 2013-12-08 Vladimir Serbinenko * grub-core/osdep/windows/emuconsole.c: Remove unsigned comparison >= 0. diff --git a/include/grub/kernel.h b/include/grub/kernel.h index a5067ef79..20ddf2da2 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -78,7 +78,7 @@ struct grub_module_info64 #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ - || defined (__sparc__) || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) + || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) /* FIXME: stack is between 2 heap regions. Move it. */ #define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 #endif From d14772c455f429191219cc9ac285471b68545de4 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:21:10 +0100 Subject: [PATCH 47/48] * grub-core/kern/emu/main.c: Silence missing prototypes to allow emu compilation with GCC <= 4.2. * grub-core/kern/emu/argp_common.c: Likewise. --- ChangeLog | 6 ++++++ grub-core/kern/emu/argp_common.c | 2 ++ grub-core/kern/emu/main.c | 2 ++ 3 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index f4691f3a4..d03b15c6d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-12-08 Vladimir Serbinenko + + * grub-core/kern/emu/main.c: Silence missing prototypes to allow emu + compilation with GCC <= 4.2. + * grub-core/kern/emu/argp_common.c: Likewise. + 2013-12-08 Vladimir Serbinenko * include/grub/kernel.h [__sparc__]: Restrict sparc64-ieee1275 to diff --git a/grub-core/kern/emu/argp_common.c b/grub-core/kern/emu/argp_common.c index e519b529e..4aca01550 100644 --- a/grub-core/kern/emu/argp_common.c +++ b/grub-core/kern/emu/argp_common.c @@ -20,6 +20,8 @@ #include #include +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + #define _GNU_SOURCE 1 #include #include diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c index 39fa3be10..eddb192f9 100644 --- a/grub-core/kern/emu/main.c +++ b/grub-core/kern/emu/main.c @@ -44,6 +44,8 @@ #include #include +#pragma GCC diagnostic ignored "-Wmissing-prototypes" + #include "progname.h" #include From 78b2b0a1a0f282071e4616881ae64070bfefe7f8 Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Sun, 8 Dec 2013 18:27:40 +0100 Subject: [PATCH 48/48] * grub-core/kern/ia64/efi/init.c (grub_arch_sync_caches): Move to ... * grub-core/kern/ia64/cache.c (grub_arch_sync_caches): ... here. --- ChangeLog | 5 +++++ grub-core/Makefile.core.def | 1 + grub-core/kern/ia64/cache.c | 35 ++++++++++++++++++++++++++++++++++ grub-core/kern/ia64/efi/init.c | 15 --------------- 4 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 grub-core/kern/ia64/cache.c diff --git a/ChangeLog b/ChangeLog index d03b15c6d..200393209 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-12-08 Vladimir Serbinenko + + * grub-core/kern/ia64/efi/init.c (grub_arch_sync_caches): Move to ... + * grub-core/kern/ia64/cache.c (grub_arch_sync_caches): ... here. + 2013-12-08 Vladimir Serbinenko * grub-core/kern/emu/main.c: Silence missing prototypes to allow emu diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 0a4eba56b..060de4449 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -193,6 +193,7 @@ kernel = { ia64_efi = kern/ia64/efi/init.c; ia64_efi = kern/ia64/dl.c; ia64_efi = kern/ia64/dl_helper.c; + ia64_efi = kern/ia64/cache.c; arm_efi = kern/arm/efi/init.c; arm_efi = kern/arm/efi/misc.c; diff --git a/grub-core/kern/ia64/cache.c b/grub-core/kern/ia64/cache.c new file mode 100644 index 000000000..13efd308f --- /dev/null +++ b/grub-core/kern/ia64/cache.c @@ -0,0 +1,35 @@ +/* init.c - initialize an ia64-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 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 + +void +grub_arch_sync_caches (void *address, grub_size_t len) +{ + /* Cache line length is at least 32. */ + len += (grub_uint64_t)address & 0x1f; + grub_uint64_t a = (grub_uint64_t)address & ~0x1f; + + /* Flush data. */ + for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20) + asm volatile ("fc.i %0" : : "r" (a)); + /* Sync and serialize. Maybe extra. */ + asm volatile (";; sync.i;; srlz.i;;"); +} diff --git a/grub-core/kern/ia64/efi/init.c b/grub-core/kern/ia64/efi/init.c index f00509833..b5ecbd091 100644 --- a/grub-core/kern/ia64/efi/init.c +++ b/grub-core/kern/ia64/efi/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -74,17 +73,3 @@ grub_machine_fini (int flags) if (flags & GRUB_LOADER_FLAG_NORETURN) grub_efi_fini (); } - -void -grub_arch_sync_caches (void *address, grub_size_t len) -{ - /* Cache line length is at least 32. */ - len += (grub_uint64_t)address & 0x1f; - grub_uint64_t a = (grub_uint64_t)address & ~0x1f; - - /* Flush data. */ - for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20) - asm volatile ("fc.i %0" : : "r" (a)); - /* Sync and serialize. Maybe extra. */ - asm volatile (";; sync.i;; srlz.i;;"); -}