All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix GCC 12 build error
@ 2022-03-17  6:43 Michael Chang
  2022-03-17  6:43 ` [PATCH 1/3] mkimage: Fix dangling pointer may be used error Michael Chang
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Michael Chang @ 2022-03-17  6:43 UTC (permalink / raw)
  To: grub-devel

The tested gcc version is:

 abuild@mazu:~> gcc --version
 gcc (SUSE Linux) 12.0.1 20220307 (experimental) [revision 40c1d4a07e5798c01e4364336c9617550744861d]
 Copyright (C) 2022 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Although it may not catch all build errors as there are quite many
combinations of cpu architecture and platform which grub supports. The
work is as far as I can get right now and I'd like to have them reviewed
before anyone running into similar problems.

Thanks,
Michael

Michael Chang (3):
  mkimage: Fix dangling pointer may be used error
  Fix -Werror=array-bounds array subscript 0 is outside array bounds
  reed_solomon: Fix array subscript 0 is outside array bounds

 grub-core/bus/cs5536.c                |  4 ++--
 grub-core/commands/acpi.c             |  4 ++--
 grub-core/commands/efi/loadbios.c     |  9 +++++----
 grub-core/commands/i386/pc/drivemap.c |  9 ++++++---
 grub-core/commands/i386/pc/sendkey.c  | 12 ++++++------
 grub-core/disk/i386/pc/biosdisk.c     |  4 ++--
 grub-core/fs/cbfs.c                   |  2 +-
 grub-core/kern/i386/pc/acpi.c         |  4 ++--
 grub-core/kern/i386/pc/mmap.c         |  2 +-
 grub-core/lib/reed_solomon.c          |  9 +++++++++
 grub-core/loader/i386/multiboot_mbi.c |  2 +-
 grub-core/loader/multiboot_mbi2.c     |  4 ++--
 grub-core/mmap/i386/pc/mmap.c         | 26 +++++++++++++-------------
 grub-core/net/drivers/i386/pc/pxe.c   | 12 ++++++------
 grub-core/term/i386/pc/console.c      |  5 ++---
 grub-core/term/i386/pc/vga_text.c     |  6 +++---
 grub-core/term/ns8250.c               |  7 ++++++-
 grub-core/video/i386/pc/vbe.c         |  6 +++---
 include/grub/compiler.h               | 11 +++++++++++
 util/mkimage.c                        | 21 +++++++++++++++++++++
 20 files changed, 104 insertions(+), 55 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] mkimage: Fix dangling pointer may be used error
  2022-03-17  6:43 [PATCH 0/3] Fix GCC 12 build error Michael Chang
@ 2022-03-17  6:43 ` Michael Chang
  2022-03-22 20:59   ` Daniel Kiper
  2022-03-17  6:43 ` [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds Michael Chang
  2022-03-17  6:43 ` [PATCH 3/3] reed_solomon: Fix " Michael Chang
  2 siblings, 1 reply; 10+ messages in thread
From: Michael Chang @ 2022-03-17  6:43 UTC (permalink / raw)
  To: grub-devel

The warning is real as long as dangling pointer to 'tmp_' may be used if
o32 and o64 are both null. However that is not going to happen and can
be ignored safely because the PE_OHDR is being used in a context that
either o32 or o64 must have been properly initialized. Sadly compiler
seems not to always optimize that unused _tmp away so explicit
suppression remain needed here.

../util/mkimage.c: In function 'grub_install_generate_image':
../util/mkimage.c:1422:41: error: dangling pointer to 'tmp_' may be used [-Werror=dangling-pointer=]
 1422 |         PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
../util/mkimage.c:857:28: note: 'tmp_' declared here
  857 |   __typeof__((o64)->field) tmp_;                \
      |                            ^~~~

Signed-off-by: Michael Chang <mchang@suse.com>
---
 util/mkimage.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/util/mkimage.c b/util/mkimage.c
index 21c2db7362..43078c71cd 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -1383,6 +1383,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
 	    section = (struct grub_pe32_section_table *)(o64 + 1);
 	  }
 
+#if __GNUC__ >= 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdangling-pointer"
+#endif
 	PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
 	PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
 	PE_OHDR (o32, o64, image_base) = 0;
@@ -1402,6 +1406,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
 	/* The sections.  */
 	PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma);
 	PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
+#if __GNUC__ >= 12
+#pragma GCC diagnostic pop
+#endif
 	section = init_pe_section (image_target, section, ".text",
 				   &vma, layout.exec_size,
 				   image_target->section_align,
@@ -1411,10 +1418,17 @@ grub_install_generate_image (const char *dir, const char *prefix,
 				   GRUB_PE32_SCN_MEM_READ);
 
 	scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
+#if __GNUC__ >= 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdangling-pointer"
+#endif
 	/* ALIGN_UP (sbat_size, GRUB_PE32_FILE_ALIGNMENT) is done earlier. */
 	PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size + sbat_size +
 							       ALIGN_UP (total_module_size,
 									 GRUB_PE32_FILE_ALIGNMENT));
+#if __GNUC__ >= 12
+#pragma GCC diagnostic pop
+#endif
 
 	section = init_pe_section (image_target, section, ".data",
 				   &vma, scn_size, image_target->section_align,
@@ -1445,8 +1459,15 @@ grub_install_generate_image (const char *dir, const char *prefix,
 	  }
 
 	scn_size = layout.reloc_size;
+#if __GNUC__ >= 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdangling-pointer"
+#endif
 	PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
 	PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
+#if __GNUC__ >= 12
+#pragma GCC diagnostic pop
+#endif
 	memcpy (pe_img + raw_data, layout.reloc_section, scn_size);
 	init_pe_section (image_target, section, ".reloc",
 			 &vma, scn_size, image_target->section_align,
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds
  2022-03-17  6:43 [PATCH 0/3] Fix GCC 12 build error Michael Chang
  2022-03-17  6:43 ` [PATCH 1/3] mkimage: Fix dangling pointer may be used error Michael Chang
@ 2022-03-17  6:43 ` Michael Chang
  2022-03-22 21:19   ` Daniel Kiper
  2022-03-17  6:43 ` [PATCH 3/3] reed_solomon: Fix " Michael Chang
  2 siblings, 1 reply; 10+ messages in thread
From: Michael Chang @ 2022-03-17  6:43 UTC (permalink / raw)
  To: grub-devel

The grub is failing to build with gcc-12 in many places like this:

In function 'init_cbfsdisk',
    inlined from 'grub_mod_init' at ../../grub-core/fs/cbfs.c:391:3:
../../grub-core/fs/cbfs.c:345:7: error: array subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned int[]'} [-Werror=array-bounds]
  345 |   ptr = *(grub_uint32_t *) 0xfffffffc;
      |   ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is caused by gcc regression in 11/12 [1]. In a nut shell, the
warning is about detected invalid accesses at non-zero offsets to null
pointers. Since hardwired constant address is treated as NULL plus an
offset in the same underlying code, the warning is therefore triggered.

Instead of inserting #pragma all over the places where literal pointers
are accessed to avoid diagnosing array-bounds, we can try to borrow the
idea from linux kernel that the absolute_pointer macro [2][3] is used to
disconnect a pointer using literal address from it's original object,
hence gcc won't be able to make assumptions on the boundary while doing
pointer arithmetic. With that we can greatly reduce the code we have to
cover up by making initial literal pointer assignment to use the new
wrapper but not having to track everywhere literal pointers are
accessed. This also makes code looks cleaner.

[1]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
[2]
https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
[3]
https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31

Signed-off-by: Michael Chang <mchang@suse.com>
---
 grub-core/bus/cs5536.c                |  4 ++--
 grub-core/commands/acpi.c             |  4 ++--
 grub-core/commands/efi/loadbios.c     |  9 +++++----
 grub-core/commands/i386/pc/drivemap.c |  9 ++++++---
 grub-core/commands/i386/pc/sendkey.c  | 12 ++++++------
 grub-core/disk/i386/pc/biosdisk.c     |  4 ++--
 grub-core/fs/cbfs.c                   |  2 +-
 grub-core/kern/i386/pc/acpi.c         |  4 ++--
 grub-core/kern/i386/pc/mmap.c         |  2 +-
 grub-core/loader/i386/multiboot_mbi.c |  2 +-
 grub-core/loader/multiboot_mbi2.c     |  4 ++--
 grub-core/mmap/i386/pc/mmap.c         | 26 +++++++++++++-------------
 grub-core/net/drivers/i386/pc/pxe.c   | 12 ++++++------
 grub-core/term/i386/pc/console.c      |  5 ++---
 grub-core/term/i386/pc/vga_text.c     |  6 +++---
 grub-core/term/ns8250.c               |  7 ++++++-
 grub-core/video/i386/pc/vbe.c         |  6 +++---
 include/grub/compiler.h               | 11 +++++++++++
 18 files changed, 74 insertions(+), 55 deletions(-)

diff --git a/grub-core/bus/cs5536.c b/grub-core/bus/cs5536.c
index 8c90ed598d..1e51f62606 100644
--- a/grub-core/bus/cs5536.c
+++ b/grub-core/bus/cs5536.c
@@ -331,8 +331,8 @@ grub_cs5536_init_geode (grub_pci_device_t dev)
 
   {
     volatile grub_uint32_t *oc;
-    oc = grub_pci_device_map_range (dev, 0x05022000,
-				    GRUB_CS5536_USB_OPTION_REGS_SIZE);
+    oc = grub_absolute_pointer (grub_pci_device_map_range (dev, 0x05022000,
+				    GRUB_CS5536_USB_OPTION_REGS_SIZE));
 
     oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX] =
       (oc[GRUB_CS5536_USB_OPTION_REG_UOCMUX]
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index 1215f2a62e..4721730b39 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -168,7 +168,7 @@ grub_acpi_create_ebda (void)
   struct grub_acpi_rsdp_v10 *v1;
   struct grub_acpi_rsdp_v20 *v2;
 
-  ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)0x40e)) << 4);
+  ebda = (grub_uint8_t *) (grub_addr_t) ((*((grub_uint16_t *)grub_absolute_pointer(0x40e))) << 4);
   grub_dprintf ("acpi", "EBDA @%p\n", ebda);
   if (ebda)
     ebda_kb_len = *(grub_uint16_t *) ebda;
@@ -298,7 +298,7 @@ grub_acpi_create_ebda (void)
       *target = 0;
 
   grub_dprintf ("acpi", "Switching EBDA\n");
-  (*((grub_uint16_t *) 0x40e)) = ((grub_addr_t) targetebda) >> 4;
+  (*((grub_uint16_t *) grub_absolute_pointer(0x40e))) = ((grub_addr_t) targetebda) >> 4;
   grub_dprintf ("acpi", "EBDA switched\n");
 
   return GRUB_ERR_NONE;
diff --git a/grub-core/commands/efi/loadbios.c b/grub-core/commands/efi/loadbios.c
index 5c7725f8bd..574e410466 100644
--- a/grub-core/commands/efi/loadbios.c
+++ b/grub-core/commands/efi/loadbios.c
@@ -46,7 +46,7 @@ enable_rom_area (void)
   grub_uint32_t *rom_ptr;
   grub_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
 
-  rom_ptr = (grub_uint32_t *) VBIOS_ADDR;
+  rom_ptr = grub_absolute_pointer (VBIOS_ADDR);
   if (*rom_ptr != BLANK_MEM)
     {
       grub_puts_ (N_("ROM image is present."));
@@ -96,8 +96,8 @@ fake_bios_data (int use_rom)
   void *acpi, *smbios;
   grub_uint16_t *ebda_seg_ptr, *low_mem_ptr;
 
-  ebda_seg_ptr = (grub_uint16_t *) EBDA_SEG_ADDR;
-  low_mem_ptr = (grub_uint16_t *) LOW_MEM_ADDR;
+  ebda_seg_ptr = grub_absolute_pointer (EBDA_SEG_ADDR);
+  low_mem_ptr = grub_absolute_pointer (LOW_MEM_ADDR);
   if ((*ebda_seg_ptr) || (*low_mem_ptr))
     return;
 
@@ -132,7 +132,8 @@ fake_bios_data (int use_rom)
   *ebda_seg_ptr = FAKE_EBDA_SEG;
   *low_mem_ptr = (FAKE_EBDA_SEG >> 6);
 
-  *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr;
+  /* *((grub_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr; */
+  *((grub_uint16_t *) (grub_absolute_pointer (FAKE_EBDA_SEG << 4))) = 640 - *low_mem_ptr;
 
   if (acpi)
     grub_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c
index 3fb22dc460..5e13f82eb5 100644
--- a/grub-core/commands/i386/pc/drivemap.c
+++ b/grub-core/commands/i386/pc/drivemap.c
@@ -31,9 +31,6 @@
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
-/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
-static grub_uint32_t *const int13slot = (grub_uint32_t *) (4 * 0x13);
-
 /* Remember to update enum opt_idxs accordingly.  */
 static const struct grub_arg_option options[] = {
   /* TRANSLATORS: In this file "mapping" refers to a change GRUB makes so if
@@ -280,6 +277,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
   grub_uint8_t *handler_base = 0;
   /* Address of the map within the deployed bundle.  */
   int13map_node_t *handler_map;
+  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
+  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);
+
 
   int i;
   int entries = 0;
@@ -354,6 +354,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
 static grub_err_t
 uninstall_int13_handler (void)
 {
+  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
+  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);
+
   if (! grub_drivemap_oldhandler)
     return GRUB_ERR_NONE;
 
diff --git a/grub-core/commands/i386/pc/sendkey.c b/grub-core/commands/i386/pc/sendkey.c
index 184befabfb..282bb5d428 100644
--- a/grub-core/commands/i386/pc/sendkey.c
+++ b/grub-core/commands/i386/pc/sendkey.c
@@ -216,12 +216,12 @@ static grub_err_t
 grub_sendkey_postboot (void)
 {
   /* For convention: pointer to flags.  */
-  grub_uint32_t *flags = (grub_uint32_t *) 0x417;
+  grub_uint32_t *flags = grub_absolute_pointer (0x417);
 
   *flags = oldflags;
 
-  *((volatile char *) 0x41a) = 0x1e;
-  *((volatile char *) 0x41c) = 0x1e;
+  *((volatile char *) grub_absolute_pointer (0x41a)) = 0x1e;
+  *((volatile char *) grub_absolute_pointer (0x41c)) = 0x1e;
 
   return GRUB_ERR_NONE;
 }
@@ -231,13 +231,13 @@ static grub_err_t
 grub_sendkey_preboot (int noret __attribute__ ((unused)))
 {
   /* For convention: pointer to flags.  */
-  grub_uint32_t *flags = (grub_uint32_t *) 0x417;
+  grub_uint32_t *flags = grub_absolute_pointer (0x417);
 
   oldflags = *flags;
 
   /* Set the sendkey.  */
-  *((volatile char *) 0x41a) = 0x1e;
-  *((volatile char *) 0x41c) = keylen + 0x1e;
+  *((volatile char *) grub_absolute_pointer (0x41a)) = 0x1e;
+  *((volatile char *) grub_absolute_pointer (0x41c)) = keylen + 0x1e;
   grub_memcpy ((char *) 0x41e, sendkey, 0x20);
 
   /* Transform "any ctrl" to "right ctrl" flag.  */
diff --git a/grub-core/disk/i386/pc/biosdisk.c b/grub-core/disk/i386/pc/biosdisk.c
index 81fd4e832c..49e4e8a14f 100644
--- a/grub-core/disk/i386/pc/biosdisk.c
+++ b/grub-core/disk/i386/pc/biosdisk.c
@@ -367,7 +367,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
       if (version)
 	{
 	  struct grub_biosdisk_drp *drp
-	    = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+	    = (struct grub_biosdisk_drp *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 
 	  /* Clear out the DRP.  */
 	  grub_memset (drp, 0, sizeof (*drp));
@@ -654,7 +654,7 @@ grub_disk_biosdisk_fini (void)
 GRUB_MOD_INIT(biosdisk)
 {
   struct grub_biosdisk_cdrp *cdrp
-    = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+    = (struct grub_biosdisk_cdrp *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
   grub_uint8_t boot_drive;
 
   if (grub_disk_firmware_is_tainted)
diff --git a/grub-core/fs/cbfs.c b/grub-core/fs/cbfs.c
index 581215ef18..8ab7106afb 100644
--- a/grub-core/fs/cbfs.c
+++ b/grub-core/fs/cbfs.c
@@ -342,7 +342,7 @@ init_cbfsdisk (void)
   grub_uint32_t ptr;
   struct cbfs_header *head;
 
-  ptr = *(grub_uint32_t *) 0xfffffffc;
+  ptr = *((grub_uint32_t *) grub_absolute_pointer (0xfffffffc));
   head = (struct cbfs_header *) (grub_addr_t) ptr;
   grub_dprintf ("cbfs", "head=%p\n", head);
 
diff --git a/grub-core/kern/i386/pc/acpi.c b/grub-core/kern/i386/pc/acpi.c
index 297f5d05f3..0a69eba7b5 100644
--- a/grub-core/kern/i386/pc/acpi.c
+++ b/grub-core/kern/i386/pc/acpi.c
@@ -27,7 +27,7 @@ grub_machine_acpi_get_rsdpv1 (void)
   grub_uint8_t *ebda, *ptr;
 
   grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
-  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4);
   ebda_len = * (grub_uint16_t *) ebda;
   if (! ebda_len) /* FIXME do we really need this check? */
     goto scan_bios;
@@ -55,7 +55,7 @@ grub_machine_acpi_get_rsdpv2 (void)
   grub_uint8_t *ebda, *ptr;
 
   grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
-  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
+  ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) grub_absolute_pointer (0x40e))) << 4);
   ebda_len = * (grub_uint16_t *) ebda;
   if (! ebda_len) /* FIXME do we really need this check? */
     goto scan_bios;
diff --git a/grub-core/kern/i386/pc/mmap.c b/grub-core/kern/i386/pc/mmap.c
index ef2faa2ab6..53fcf45af6 100644
--- a/grub-core/kern/i386/pc/mmap.c
+++ b/grub-core/kern/i386/pc/mmap.c
@@ -143,7 +143,7 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
 {
   grub_uint32_t cont = 0;
   struct grub_machine_mmap_entry *entry
-    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+    = (struct grub_machine_mmap_entry *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
   int e820_works = 0;
 
   while (1)
diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c
index ff1a846af9..11a6e224ff 100644
--- a/grub-core/loader/i386/multiboot_mbi.c
+++ b/grub-core/loader/i386/multiboot_mbi.c
@@ -293,7 +293,7 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig,
   struct grub_vbe_mode_info_block *mode_info;
 #if GRUB_MACHINE_HAS_VBE
   grub_vbe_status_t status;
-  void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  void *scratch = grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 
   status = grub_vbe_bios_get_controller_info (scratch);
   if (status != GRUB_VBE_STATUS_OK)
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index 6d680d6715..00a48413c0 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -504,7 +504,7 @@ static void
 fill_vbe_tag (struct multiboot_tag_vbe *tag)
 {
   grub_vbe_status_t status;
-  void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  void *scratch = grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 
   tag->type = MULTIBOOT_TAG_TYPE_VBE;
   tag->size = 0;
@@ -577,7 +577,7 @@ retrieve_video_parameters (grub_properly_aligned_t **ptrorig)
 #if defined (GRUB_MACHINE_PCBIOS)
       {
 	grub_vbe_status_t status;
-	void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+	void *scratch = grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 	status = grub_vbe_bios_get_mode (scratch);
 	vbe_mode = *(grub_uint32_t *) scratch;
 	if (status != GRUB_VBE_STATUS_OK)
diff --git a/grub-core/mmap/i386/pc/mmap.c b/grub-core/mmap/i386/pc/mmap.c
index 6ab4f67309..b9c5b0a002 100644
--- a/grub-core/mmap/i386/pc/mmap.c
+++ b/grub-core/mmap/i386/pc/mmap.c
@@ -80,13 +80,13 @@ preboot (int noreturn __attribute__ ((unused)))
     = min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16;
 
   /* Correct BDA. */
-  *((grub_uint16_t *) 0x413) = grub_mmap_get_lower () >> 10;
+  *((grub_uint16_t *) grub_absolute_pointer (0x413)) = grub_mmap_get_lower () >> 10;
 
   /* Save old interrupt handlers. */
-  grub_machine_mmaphook_int12offset = *((grub_uint16_t *) 0x48);
-  grub_machine_mmaphook_int12segment = *((grub_uint16_t *) 0x4a);
-  grub_machine_mmaphook_int15offset = *((grub_uint16_t *) 0x54);
-  grub_machine_mmaphook_int15segment = *((grub_uint16_t *) 0x56);
+  grub_machine_mmaphook_int12offset = *((grub_uint16_t *) grub_absolute_pointer (0x48));
+  grub_machine_mmaphook_int12segment = *((grub_uint16_t *) grub_absolute_pointer (0x4a));
+  grub_machine_mmaphook_int15offset = *((grub_uint16_t *) grub_absolute_pointer (0x54));
+  grub_machine_mmaphook_int15segment = *((grub_uint16_t *) grub_absolute_pointer (0x56));
 
   grub_dprintf ("mmap", "hooktarget = %p\n", hooktarget);
 
@@ -94,11 +94,11 @@ preboot (int noreturn __attribute__ ((unused)))
   grub_memcpy (hooktarget, &grub_machine_mmaphook_start,
 	       &grub_machine_mmaphook_end - &grub_machine_mmaphook_start);
 
-  *((grub_uint16_t *) 0x4a) = ((grub_addr_t) hooktarget) >> 4;
-  *((grub_uint16_t *) 0x56) = ((grub_addr_t) hooktarget) >> 4;
-  *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
+  *((grub_uint16_t *) grub_absolute_pointer (0x4a)) = ((grub_addr_t) hooktarget) >> 4;
+  *((grub_uint16_t *) grub_absolute_pointer (0x56)) = ((grub_addr_t) hooktarget) >> 4;
+  *((grub_uint16_t *) grub_absolute_pointer (0x48)) = &grub_machine_mmaphook_int12
     - &grub_machine_mmaphook_start;
-  *((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15
+  *((grub_uint16_t *) grub_absolute_pointer (0x54)) = &grub_machine_mmaphook_int15
     - &grub_machine_mmaphook_start;
 
   return GRUB_ERR_NONE;
@@ -108,10 +108,10 @@ static grub_err_t
 preboot_rest (void)
 {
   /* Restore old interrupt handlers. */
-  *((grub_uint16_t *) 0x48) = grub_machine_mmaphook_int12offset;
-  *((grub_uint16_t *) 0x4a) = grub_machine_mmaphook_int12segment;
-  *((grub_uint16_t *) 0x54) = grub_machine_mmaphook_int15offset;
-  *((grub_uint16_t *) 0x56) = grub_machine_mmaphook_int15segment;
+  *((grub_uint16_t *) grub_absolute_pointer (0x48)) = grub_machine_mmaphook_int12offset;
+  *((grub_uint16_t *) grub_absolute_pointer (0x4a)) = grub_machine_mmaphook_int12segment;
+  *((grub_uint16_t *) grub_absolute_pointer (0x54)) = grub_machine_mmaphook_int15offset;
+  *((grub_uint16_t *) grub_absolute_pointer (0x56)) = grub_machine_mmaphook_int15segment;
 
   return GRUB_ERR_NONE;
 }
diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c
index 997010cf15..db17186ee7 100644
--- a/grub-core/net/drivers/i386/pc/pxe.c
+++ b/grub-core/net/drivers/i386/pc/pxe.c
@@ -174,7 +174,7 @@ grub_pxe_recv (struct grub_net_card *dev __attribute__ ((unused)))
   grub_uint8_t *ptr, *end;
   struct grub_net_buff *buf;
 
-  isr = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  isr = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 
   if (!in_progress)
     {
@@ -256,11 +256,11 @@ grub_pxe_send (struct grub_net_card *dev __attribute__ ((unused)),
   struct grub_pxe_undi_tbd *tbd;
   char *buf;
 
-  trans = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  trans = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
   grub_memset (trans, 0, sizeof (*trans));
-  tbd = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128);
+  tbd = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 128);
   grub_memset (tbd, 0, sizeof (*tbd));
-  buf = (void *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256);
+  buf = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + 256);
   grub_memcpy (buf, pack->data, pack->tail - pack->data);
 
   trans->tbd = SEGOFS ((grub_addr_t) tbd);
@@ -287,7 +287,7 @@ static grub_err_t
 grub_pxe_open (struct grub_net_card *dev __attribute__ ((unused)))
 {
   struct grub_pxe_undi_open *ou;
-  ou = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  ou = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
   grub_memset (ou, 0, sizeof (*ou));
   ou->pkt_filter = 4;
   grub_pxe_call (GRUB_PXENV_UNDI_OPEN, ou, pxe_rm_entry);
@@ -382,7 +382,7 @@ GRUB_MOD_INIT(pxe)
   if (! pxenv)
     return;
 
-  ui = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  ui = (void *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
   grub_memset (ui, 0, sizeof (*ui));
   grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry);
 
diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
index d44937c305..9403390f1f 100644
--- a/grub-core/term/i386/pc/console.c
+++ b/grub-core/term/i386/pc/console.c
@@ -238,12 +238,11 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
   return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL);
 }
 
-static const struct grub_machine_bios_data_area *bios_data_area =
-  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
-
 static int
 grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
 {
+  const struct grub_machine_bios_data_area *bios_data_area =
+  (struct grub_machine_bios_data_area *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR);
   /* conveniently GRUB keystatus is modelled after BIOS one.  */
   return bios_data_area->keyboard_flag_lower & ~0x80;
 }
diff --git a/grub-core/term/i386/pc/vga_text.c b/grub-core/term/i386/pc/vga_text.c
index 88fecc5ea5..669d06fad7 100644
--- a/grub-core/term/i386/pc/vga_text.c
+++ b/grub-core/term/i386/pc/vga_text.c
@@ -45,15 +45,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
 static struct grub_term_coordinate grub_curr_pos;
 
 #ifdef __mips__
-#define VGA_TEXT_SCREEN		((grub_uint16_t *) 0xb00b8000)
+#define VGA_TEXT_SCREEN		((grub_uint16_t *) grub_absolute_pointer (0xb00b8000))
 #define cr_read grub_vga_cr_read
 #define cr_write grub_vga_cr_write
 #elif defined (MODE_MDA)
-#define VGA_TEXT_SCREEN		((grub_uint16_t *) 0xb0000)
+#define VGA_TEXT_SCREEN		((grub_uint16_t *) grub_absolute_pointer (0xb0000))
 #define cr_read grub_vga_cr_bw_read
 #define cr_write grub_vga_cr_bw_write
 #else
-#define VGA_TEXT_SCREEN		((grub_uint16_t *) 0xb8000)
+#define VGA_TEXT_SCREEN		((grub_uint16_t *) grub_absolute_pointer (0xb8000))
 #define cr_read grub_vga_cr_read
 #define cr_write grub_vga_cr_write
 #endif
diff --git a/grub-core/term/ns8250.c b/grub-core/term/ns8250.c
index 59801839bd..83b25990c2 100644
--- a/grub-core/term/ns8250.c
+++ b/grub-core/term/ns8250.c
@@ -28,7 +28,6 @@
 
 #ifdef GRUB_MACHINE_PCBIOS
 #include <grub/machine/memory.h>
-static const unsigned short *serial_hw_io_addr = (const unsigned short *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
 #define GRUB_SERIAL_PORT_NUM 4
 #else
 #include <grub/machine/serial.h>
@@ -237,6 +236,9 @@ static struct grub_serial_port com_ports[GRUB_SERIAL_PORT_NUM];
 void
 grub_ns8250_init (void)
 {
+#ifdef GRUB_MACHINE_PCBIOS
+  const unsigned short *serial_hw_io_addr = (const unsigned short *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR);
+#endif
   unsigned i;
   for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++)
     if (serial_hw_io_addr[i])
@@ -272,6 +274,9 @@ grub_ns8250_init (void)
 grub_port_t
 grub_ns8250_hw_get_port (const unsigned int unit)
 {
+#ifdef GRUB_MACHINE_PCBIOS
+  const unsigned short *serial_hw_io_addr = (const unsigned short *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR);
+#endif
   if (unit < GRUB_SERIAL_PORT_NUM
       && !(dead_ports & (1 << unit)))
     return serial_hw_io_addr[unit];
diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c
index 0e65b5206c..a0bb9af098 100644
--- a/grub-core/video/i386/pc/vbe.c
+++ b/grub-core/video/i386/pc/vbe.c
@@ -514,7 +514,7 @@ grub_vbe_probe (struct grub_vbe_info_block *info_block)
 
       /* Use low memory scratch area as temporary storage
          for VESA BIOS call.  */
-      vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+      vbe_ib = (struct grub_vbe_info_block *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 
       /* Prepare info block.  */
       grub_memset (vbe_ib, 0, sizeof (*vbe_ib));
@@ -574,7 +574,7 @@ grub_vbe_get_preferred_mode (unsigned int *width, unsigned int *height)
 
   /* Use low memory scratch area as temporary storage for VESA BIOS calls.  */
   flat_panel_info = (struct grub_vbe_flat_panel_info *)
-    (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + sizeof (struct grub_video_edid_info));
+    grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + sizeof (struct grub_video_edid_info));
 
   if (controller_info.version >= 0x200
       && (grub_vbe_bios_get_ddc_capabilities (&ddc_level) & 0xff)
@@ -676,7 +676,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode,
 	  == GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL)
 	{
 	  struct grub_vbe_palette_data *palette
-	    = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+	    = (struct grub_vbe_palette_data *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_SCRATCH_ADDR);
 	  unsigned i;
 
 	  /* Make sure that the BIOS can reach the palette.  */
diff --git a/include/grub/compiler.h b/include/grub/compiler.h
index 8f3be3ae70..e159f0e292 100644
--- a/include/grub/compiler.h
+++ b/include/grub/compiler.h
@@ -56,4 +56,15 @@
 #  define CLANG_PREREQ(maj,min) 0
 #endif
 
+#if defined(__GNUC__)
+#  define grub_absolute_pointer(val)					\
+({									\
+	unsigned long __ptr;						\
+	__asm__ ("" : "=r"(__ptr) : "0"((void *)(val)));		\
+	(void *) (__ptr);						\
+})
+#else
+#  define grub_absolute_pointer(val) ((void *)(val))
+#endif
+
 #endif /* ! GRUB_COMPILER_HEADER */
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] reed_solomon: Fix array subscript 0 is outside array bounds
  2022-03-17  6:43 [PATCH 0/3] Fix GCC 12 build error Michael Chang
  2022-03-17  6:43 ` [PATCH 1/3] mkimage: Fix dangling pointer may be used error Michael Chang
  2022-03-17  6:43 ` [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds Michael Chang
@ 2022-03-17  6:43 ` Michael Chang
  2022-03-17  7:41   ` Paul Menzel
  2022-03-22 21:21   ` Daniel Kiper
  2 siblings, 2 replies; 10+ messages in thread
From: Michael Chang @ 2022-03-17  6:43 UTC (permalink / raw)
  To: grub-devel

The grub_absolute_pointer() is a compound expression that can only work
within a function. We are out of luck here when the pointer variables
require global definition due to ATTRIBUTE_TEXT that have to use fully
initialized global definition because of the way linkers work.

 static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;

For the reason given above, use gcc diagnostic pragmas to suppress the
array-bounds warning.

Signed-off-by: Michael Chang <mchang@suse.com>
---
 grub-core/lib/reed_solomon.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c
index 82779a296b..562bd2e3e3 100644
--- a/grub-core/lib/reed_solomon.c
+++ b/grub-core/lib/reed_solomon.c
@@ -102,6 +102,11 @@ static gf_single_t errvals[256];
 static gf_single_t eqstat[65536 + 256];
 #endif
 
+#if __GNUC__ == 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+
 static gf_single_t
 gf_mul (gf_single_t a, gf_single_t b)
 {
@@ -319,6 +324,10 @@ decode_block (gf_single_t *ptr, grub_size_t s,
     }
 }
 
+#if __GNUC__ == 12
+#pragma GCC diagnostic pop
+#endif
+
 #if !defined (STANDALONE)
 static void
 encode_block (gf_single_t *ptr, grub_size_t s,
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] reed_solomon: Fix array subscript 0 is outside array bounds
  2022-03-17  6:43 ` [PATCH 3/3] reed_solomon: Fix " Michael Chang
@ 2022-03-17  7:41   ` Paul Menzel
  2022-03-17  8:59     ` Michael Chang
  2022-03-22 21:21   ` Daniel Kiper
  1 sibling, 1 reply; 10+ messages in thread
From: Paul Menzel @ 2022-03-17  7:41 UTC (permalink / raw)
  To: Michael Chang; +Cc: grub-devel

Dear Michael,


Thank you for working on that.


Am 17.03.22 um 07:43 schrieb Michael Chang via Grub-devel:
> The grub_absolute_pointer() is a compound expression that can only work
> within a function. We are out of luck here when the pointer variables
> require global definition due to ATTRIBUTE_TEXT that have to use fully
> initialized global definition because of the way linkers work.
> 
>   static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;
> 
> For the reason given above, use gcc diagnostic pragmas to suppress the
> array-bounds warning.

Can you please share the exact GCC warning messages?


Kind regards,

Paul


> Signed-off-by: Michael Chang <mchang@suse.com>
> ---
>   grub-core/lib/reed_solomon.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c
> index 82779a296b..562bd2e3e3 100644
> --- a/grub-core/lib/reed_solomon.c
> +++ b/grub-core/lib/reed_solomon.c
> @@ -102,6 +102,11 @@ static gf_single_t errvals[256];
>   static gf_single_t eqstat[65536 + 256];
>   #endif
>   
> +#if __GNUC__ == 12
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Warray-bounds"
> +#endif
> +
>   static gf_single_t
>   gf_mul (gf_single_t a, gf_single_t b)
>   {
> @@ -319,6 +324,10 @@ decode_block (gf_single_t *ptr, grub_size_t s,
>       }
>   }
>   
> +#if __GNUC__ == 12
> +#pragma GCC diagnostic pop
> +#endif
> +
>   #if !defined (STANDALONE)
>   static void
>   encode_block (gf_single_t *ptr, grub_size_t s,


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] reed_solomon: Fix array subscript 0 is outside array bounds
  2022-03-17  7:41   ` Paul Menzel
@ 2022-03-17  8:59     ` Michael Chang
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Chang @ 2022-03-17  8:59 UTC (permalink / raw)
  To: Paul Menzel, grub-devel

On Thu, Mar 17, 2022 at 08:41:32AM +0100, Paul Menzel wrote:
> Dear Michael,
> 
> 
> Thank you for working on that.
> 
> 
> Am 17.03.22 um 07:43 schrieb Michael Chang via Grub-devel:
> > The grub_absolute_pointer() is a compound expression that can only work
> > within a function. We are out of luck here when the pointer variables
> > require global definition due to ATTRIBUTE_TEXT that have to use fully
> > initialized global definition because of the way linkers work.
> > 
> >   static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;
> > 
> > For the reason given above, use gcc diagnostic pragmas to suppress the
> > array-bounds warning.
> 
> Can you please share the exact GCC warning messages?

Yes. It is very long so I didn't put in the description:

[  184s] ../../grub-core/lib/reed_solomon.c: In function 'pol_evaluate':
[  184s] ../../grub-core/lib/reed_solomon.c:147:39: error: array subscript [1, 255] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   147 |         s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn];
[  184s]       |                            ~~~~~~~~~~~^~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:147:21: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   147 |         s ^= gf_powx[(int) gf_powx_inv[pol[i]] + log_xn];
[  184s]       |              ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] In function 'gf_mul',
[  184s]     inlined from 'gf_mul' at ../../grub-core/lib/reed_solomon.c:106:1:
[  184s] ../../grub-core/lib/reed_solomon.c:110:35: error: array subscript [1, 255] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   110 |   return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]];
[  184s]       |                        ~~~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:110:58: error: array subscript [1, 255] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   110 |   return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]];
[  184s]       |                                               ~~~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:110:17: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   110 |   return gf_powx[(int) gf_powx_inv[a] + (int) gf_powx_inv[b]];
[  184s]       |          ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c: In function 'gauss_solve.constprop':
[  184s] ../../grub-core/lib/reed_solomon.c:231:21: error: array subscript 0 is outside array bounds of 'int[0]' [-Werror=array-bounds]
[  184s]   231 |       if (chosenstat[i] == -1)
[  184s]       |           ~~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:235:14: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   235 |       s ^= eq[i * (m + 1) + m];
[  184s]       |            ~~^~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:234:24: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   234 |         s ^= gf_mul (eq[i * (m + 1) + j], sol[j]);
[  184s]       |                      ~~^~~~~~~~~~~~~~~~~
[  184s] In function 'gauss_eliminate',
[  184s]     inlined from 'gauss_solve.constprop' at ../../grub-core/lib/reed_solomon.c:227:3:
[  184s] ../../grub-core/lib/reed_solomon.c:201:39: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   201 |       for (nzidx = 0; nzidx < m && (eq[i * (m + 1) + nzidx] == 0);
[  184s]       |                                     ~~^~~~~~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:205:17: error: array subscript 0 is outside array bounds of 'int[0]' [-Werror=array-bounds]
[  184s]   205 |       chosen[i] = nzidx;
[  184s]       |       ~~~~~~~~~~^~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:206:24: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   206 |       r = gf_invert (eq[i * (m + 1) + nzidx]);
[  184s]       |                      ~~^~~~~~~~~~~~~~~~~~~~~
[  184s] In function 'gf_invert',
[  184s]     inlined from 'gauss_eliminate' at ../../grub-core/lib/reed_solomon.c:206:11,
[  184s]     inlined from 'gauss_solve.constprop' at ../../grub-core/lib/reed_solomon.c:227:3:
[  184s] ../../grub-core/lib/reed_solomon.c:116:41: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   116 |   return gf_powx[255 - (int) gf_powx_inv[a]];
[  184s]       |                              ~~~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:116:17: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   116 |   return gf_powx[255 - (int) gf_powx_inv[a]];
[  184s]       |          ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] In function 'gauss_eliminate',
[  184s]     inlined from 'gauss_solve.constprop' at ../../grub-core/lib/reed_solomon.c:227:3:
[  184s] ../../grub-core/lib/reed_solomon.c:211:23: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   211 |           gf_single_t rr = eq[j * (m + 1) + nzidx];
[  184s]       |                       ^~
[  184s] ../../grub-core/lib/reed_solomon.c:213:46: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   213 |             eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr);
[  184s]       |                                            ~~^~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:213:15: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   213 |             eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr);
[  184s]       |             ~~^~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:213:33: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   213 |             eq[j * (m + 1) + k] ^= gf_mul (eq[i * (m + 1) + k], rr);
[  184s]       |                                 ^~
[  184s] ../../grub-core/lib/reed_solomon.c:208:41: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   208 |         eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r);
[  184s]       |                                       ~~^~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:208:29: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   208 |         eq[i * (m + 1) + j] = gf_mul (eq[i * (m + 1) + j], r);
[  184s]       |         ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c: In function 'gauss_solve.constprop':
[  184s] ../../grub-core/lib/reed_solomon.c:224:19: error: array subscript 0 is outside array bounds of 'int[0]' [-Werror=array-bounds]
[  184s]   224 |     chosenstat[i] = -1;
[  184s]       |     ~~~~~~~~~~~~~~^~~~
[  184s] In function 'init_powx',
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:412:3:
[  184s] ../../grub-core/lib/reed_solomon.c:125:18: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   125 |   gf_powx_inv[0] = 0;
[  184s]       |   ~~~~~~~~~~~~~~~^~~
[  184s] In function 'rs_recover',
[  184s]     inlined from 'decode_block' at ../../grub-core/lib/reed_solomon.c:315:7,
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:426:7:
[  184s] ../../grub-core/lib/reed_solomon.c:251:11: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   251 |     if (sy[i] != 0)
[  184s]       |         ~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:279:24: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   279 |     eqstat[errnum] = sy[0];
[  184s]       |                      ~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:279:20: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   279 |     eqstat[errnum] = sy[0];
[  184s]       |     ~~~~~~~~~~~~~~~^~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:292:16: error: array subscript 0 is outside array bounds of 'int[0]' [-Werror=array-bounds]
[  184s]   292 |       mm[errpos[i]] ^= errvals[i];
[  184s]       |          ~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:292:9: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   292 |       mm[errpos[i]] ^= errvals[i];
[  184s]       |       ~~^~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:292:31: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   292 |       mm[errpos[i]] ^= errvals[i];
[  184s]       |                        ~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:292:21: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   292 |       mm[errpos[i]] ^= errvals[i];
[  184s]       |       ~~~~~~~~~~~~~~^~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:286:47: error: array subscript [1, 2147483646] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   286 |         eqstat[(errnum + 1) * i + errnum] = sy[i];
[  184s]       |                                             ~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:286:43: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   286 |         eqstat[(errnum + 1) * i + errnum] = sy[i];
[  184s]       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:284:56: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   284 |                                                  eqstat[(errnum + 1) * (i - 1)
[  184s]       |                                                  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
[  184s]   285 |                                                         + j]);
[  184s]       |                                                         ~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:283:56: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   283 |           eqstat[(errnum + 1) * i + j] = gf_mul (errpot[j],
[  184s]       |                                                  ~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:283:40: error: array subscript [2, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   283 |           eqstat[(errnum + 1) * i + j] = gf_mul (errpot[j],
[  184s]       |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
[  184s]   284 |                                                  eqstat[(errnum + 1) * (i - 1)
[  184s]       |                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s]   285 |                                                         + j]);
[  184s]       |                                                         ~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:278:17: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   278 |       eqstat[j] = 1;
[  184s]       |       ~~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:271:58: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   271 |     if (pol_evaluate (sigma, rs2 - 1, 255 - i) == gf_powx[i])
[  184s]       |                                                   ~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:273:24: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   273 |         errpot[errnum] = gf_powx[i];
[  184s]       |         ~~~~~~~~~~~~~~~^~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:274:26: error: array subscript [0, 536870911] is outside array bounds of 'int[0]' [-Werror=array-bounds]
[  184s]   274 |         errpos[errnum++] = s + rs - i - 1;
[  184s]       |         ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:265:16: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   265 |       sigma[i] = 0;
[  184s]       |       ~~~~~~~~~^~~
[  184s] ../../grub-core/lib/reed_solomon.c:262:39: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   262 |         eqstat[i * (rs2 + 1) + j] = sy[i+j];
[  184s]       |                                     ~~^~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:262:35: error: array subscript [0, 2147483647] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   262 |         eqstat[i * (rs2 + 1) + j] = sy[i+j];
[  184s]       |         ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
[  184s] In function 'decode_block',
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:426:7:
[  184s] ../../grub-core/lib/reed_solomon.c:318:41: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   318 |         ptr[SECTOR_SIZE * j + i] = mstat[j];
[  184s]       |                                    ~~~~~^~~
[  184s] In function 'rs_recover',
[  184s]     inlined from 'decode_block' at ../../grub-core/lib/reed_solomon.c:315:7,
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:426:7:
[  184s] ../../grub-core/lib/reed_solomon.c:248:11: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   248 |     sy[i] = pol_evaluate (mm, s + rs - 1, i);
[  184s]       |     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] In function 'decode_block',
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:426:7:
[  184s] ../../grub-core/lib/reed_solomon.c:313:23: error: array subscript [1, 8388608] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   313 |         mstat[j + ds] = rptr[SECTOR_SIZE * j + i];
[  184s]       |         ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:311:18: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   311 |         mstat[j] = ptr[SECTOR_SIZE * j + i];
[  184s]       |         ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
[  184s] In function 'init_powx',
[  184s]     inlined from 'grub_reed_solomon_recover' at ../../grub-core/lib/reed_solomon.c:412:3:
[  184s] ../../grub-core/lib/reed_solomon.c:128:18: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   128 |       gf_powx[i] = cur;
[  184s]       |       ~~~~~~~~~~~^~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:129:24: error: array subscript [255, 509] is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   129 |       gf_powx[i + 255] = cur;
[  184s]       |       ~~~~~~~~~~~~~~~~~^~~~~
[  184s] ../../grub-core/lib/reed_solomon.c:130:24: error: array subscript 0 is outside array bounds of 'gf_single_t[0]' {aka 'unsigned char[]'} [-Werror=array-bounds]
[  184s]   130 |       gf_powx_inv[cur] = i;
[  184s]       |       ~~~~~~~~~~~~~~~~~^~~

Btw, here's completed list of global pointer with constant address for
your reference.

static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;
static gf_single_t * const gf_powx_inv ATTRIBUTE_TEXT = (void *) 0x100200;
static int *const chosenstat ATTRIBUTE_TEXT = (void *) 0x100300;
static gf_single_t *const sigma ATTRIBUTE_TEXT = (void *) 0x100700;
static gf_single_t *const errpot ATTRIBUTE_TEXT = (void *) 0x100800;
static int *const errpos ATTRIBUTE_TEXT = (void *) 0x100900;
static gf_single_t *const sy ATTRIBUTE_TEXT = (void *) 0x100d00;
static gf_single_t *const mstat ATTRIBUTE_TEXT = (void *) 0x100e00;
static gf_single_t *const errvals ATTRIBUTE_TEXT = (void *) 0x100f00;
static gf_single_t *const eqstat ATTRIBUTE_TEXT = (void *) 0x101000;

Thanks,
Michael

> 
> 
> Kind regards,
> 
> Paul
> 
> 
> > Signed-off-by: Michael Chang <mchang@suse.com>
> > ---
> >   grub-core/lib/reed_solomon.c | 9 +++++++++
> >   1 file changed, 9 insertions(+)
> > 
> > diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c
> > index 82779a296b..562bd2e3e3 100644
> > --- a/grub-core/lib/reed_solomon.c
> > +++ b/grub-core/lib/reed_solomon.c
> > @@ -102,6 +102,11 @@ static gf_single_t errvals[256];
> >   static gf_single_t eqstat[65536 + 256];
> >   #endif
> > +#if __GNUC__ == 12
> > +#pragma GCC diagnostic push
> > +#pragma GCC diagnostic ignored "-Warray-bounds"
> > +#endif
> > +
> >   static gf_single_t
> >   gf_mul (gf_single_t a, gf_single_t b)
> >   {
> > @@ -319,6 +324,10 @@ decode_block (gf_single_t *ptr, grub_size_t s,
> >       }
> >   }
> > +#if __GNUC__ == 12
> > +#pragma GCC diagnostic pop
> > +#endif
> > +
> >   #if !defined (STANDALONE)
> >   static void
> >   encode_block (gf_single_t *ptr, grub_size_t s,



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] mkimage: Fix dangling pointer may be used error
  2022-03-17  6:43 ` [PATCH 1/3] mkimage: Fix dangling pointer may be used error Michael Chang
@ 2022-03-22 20:59   ` Daniel Kiper
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Kiper @ 2022-03-22 20:59 UTC (permalink / raw)
  To: Michael Chang; +Cc: grub-devel

On Thu, Mar 17, 2022 at 02:43:40PM +0800, Michael Chang via Grub-devel wrote:
> The warning is real as long as dangling pointer to 'tmp_' may be used if
> o32 and o64 are both null. However that is not going to happen and can
> be ignored safely because the PE_OHDR is being used in a context that
> either o32 or o64 must have been properly initialized. Sadly compiler
> seems not to always optimize that unused _tmp away so explicit
> suppression remain needed here.
>
> ../util/mkimage.c: In function 'grub_install_generate_image':
> ../util/mkimage.c:1422:41: error: dangling pointer to 'tmp_' may be used [-Werror=dangling-pointer=]
>  1422 |         PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
> ../util/mkimage.c:857:28: note: 'tmp_' declared here
>   857 |   __typeof__((o64)->field) tmp_;                \
>       |                            ^~~~
>
> Signed-off-by: Michael Chang <mchang@suse.com>

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>

Daniel


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds
  2022-03-17  6:43 ` [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds Michael Chang
@ 2022-03-22 21:19   ` Daniel Kiper
  2022-03-23  4:51     ` Michael Chang
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Kiper @ 2022-03-22 21:19 UTC (permalink / raw)
  To: Michael Chang; +Cc: grub-devel

On Thu, Mar 17, 2022 at 02:43:41PM +0800, Michael Chang via Grub-devel wrote:
> The grub is failing to build with gcc-12 in many places like this:
>
> In function 'init_cbfsdisk',
>     inlined from 'grub_mod_init' at ../../grub-core/fs/cbfs.c:391:3:
> ../../grub-core/fs/cbfs.c:345:7: error: array subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned int[]'} [-Werror=array-bounds]
>   345 |   ptr = *(grub_uint32_t *) 0xfffffffc;
>       |   ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> This is caused by gcc regression in 11/12 [1]. In a nut shell, the
> warning is about detected invalid accesses at non-zero offsets to null

May I ask you to be more consistent and use NULL instead of null everywhere?

> pointers. Since hardwired constant address is treated as NULL plus an
> offset in the same underlying code, the warning is therefore triggered.
>
> Instead of inserting #pragma all over the places where literal pointers
> are accessed to avoid diagnosing array-bounds, we can try to borrow the
> idea from linux kernel that the absolute_pointer macro [2][3] is used to
> disconnect a pointer using literal address from it's original object,
> hence gcc won't be able to make assumptions on the boundary while doing
> pointer arithmetic. With that we can greatly reduce the code we have to
> cover up by making initial literal pointer assignment to use the new
> wrapper but not having to track everywhere literal pointers are
> accessed. This also makes code looks cleaner.
>
> [1]
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
> [2]
> https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
> [3]
> https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31
>
> Signed-off-by: Michael Chang <mchang@suse.com>

[...]

> diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c
> index 3fb22dc460..5e13f82eb5 100644
> --- a/grub-core/commands/i386/pc/drivemap.c
> +++ b/grub-core/commands/i386/pc/drivemap.c
> @@ -31,9 +31,6 @@
>
>  GRUB_MOD_LICENSE ("GPLv3+");
>
> -/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> -static grub_uint32_t *const int13slot = (grub_uint32_t *) (4 * 0x13);
> -
>  /* Remember to update enum opt_idxs accordingly.  */
>  static const struct grub_arg_option options[] = {
>    /* TRANSLATORS: In this file "mapping" refers to a change GRUB makes so if
> @@ -280,6 +277,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
>    grub_uint8_t *handler_base = 0;
>    /* Address of the map within the deployed bundle.  */
>    int13map_node_t *handler_map;
> +  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> +  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);

This shuffling looks strange and should be explained in the commit message.
I understood what is going here when I took a look at patch #3.

> +

Please drop this empty line addition.

>    int i;
>    int entries = 0;
> @@ -354,6 +354,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
>  static grub_err_t
>  uninstall_int13_handler (void)
>  {
> +  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> +  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);

WRT shuffling, ditto.

> +
>    if (! grub_drivemap_oldhandler)
>      return GRUB_ERR_NONE;

[...]

> diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
> index d44937c305..9403390f1f 100644
> --- a/grub-core/term/i386/pc/console.c
> +++ b/grub-core/term/i386/pc/console.c
> @@ -238,12 +238,11 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
>    return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL);
>  }
>
> -static const struct grub_machine_bios_data_area *bios_data_area =
> -  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
> -
>  static int
>  grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
>  {
> +  const struct grub_machine_bios_data_area *bios_data_area =
> +  (struct grub_machine_bios_data_area *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR);

Ditto and below...

>    /* conveniently GRUB keystatus is modelled after BIOS one.  */
>    return bios_data_area->keyboard_flag_lower & ~0x80;
>  }

[...]

> diff --git a/include/grub/compiler.h b/include/grub/compiler.h
> index 8f3be3ae70..e159f0e292 100644
> --- a/include/grub/compiler.h
> +++ b/include/grub/compiler.h
> @@ -56,4 +56,15 @@
>  #  define CLANG_PREREQ(maj,min) 0
>  #endif
>
> +#if defined(__GNUC__)
> +#  define grub_absolute_pointer(val)					\
> +({									\
> +	unsigned long __ptr;						\

I think grub_addr_t would be more appropriate here. But this requires
include/grub/types.h. So, maybe we should move this macro there.

> +	__asm__ ("" : "=r"(__ptr) : "0"((void *)(val)));		\

s/__asm__/asm/

Why did you decide to use "asm() version" of this macro [1] instead of more
C-ish one [2]? Anyway, I would mention the idea comes from the Linux
kernel RELOC_HIDE() macro.

Daniel

[1] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31
[2] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] reed_solomon: Fix array subscript 0 is outside array bounds
  2022-03-17  6:43 ` [PATCH 3/3] reed_solomon: Fix " Michael Chang
  2022-03-17  7:41   ` Paul Menzel
@ 2022-03-22 21:21   ` Daniel Kiper
  1 sibling, 0 replies; 10+ messages in thread
From: Daniel Kiper @ 2022-03-22 21:21 UTC (permalink / raw)
  To: Michael Chang; +Cc: grub-devel

On Thu, Mar 17, 2022 at 02:43:42PM +0800, Michael Chang via Grub-devel wrote:
> The grub_absolute_pointer() is a compound expression that can only work
> within a function. We are out of luck here when the pointer variables
> require global definition due to ATTRIBUTE_TEXT that have to use fully
> initialized global definition because of the way linkers work.
>
>  static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;
>
> For the reason given above, use gcc diagnostic pragmas to suppress the
> array-bounds warning.
>
> Signed-off-by: Michael Chang <mchang@suse.com>

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>

Daniel


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds
  2022-03-22 21:19   ` Daniel Kiper
@ 2022-03-23  4:51     ` Michael Chang
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Chang @ 2022-03-23  4:51 UTC (permalink / raw)
  To: The development of GNU GRUB

On Tue, Mar 22, 2022 at 10:19:26PM +0100, Daniel Kiper wrote:
> On Thu, Mar 17, 2022 at 02:43:41PM +0800, Michael Chang via Grub-devel wrote:
> > The grub is failing to build with gcc-12 in many places like this:
> >
> > In function 'init_cbfsdisk',
> >     inlined from 'grub_mod_init' at ../../grub-core/fs/cbfs.c:391:3:
> > ../../grub-core/fs/cbfs.c:345:7: error: array subscript 0 is outside array bounds of 'grub_uint32_t[0]' {aka 'unsigned int[]'} [-Werror=array-bounds]
> >   345 |   ptr = *(grub_uint32_t *) 0xfffffffc;
> >       |   ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
> > This is caused by gcc regression in 11/12 [1]. In a nut shell, the
> > warning is about detected invalid accesses at non-zero offsets to null
> 
> May I ask you to be more consistent and use NULL instead of null everywhere?

Yes, no problem.

> 
> > pointers. Since hardwired constant address is treated as NULL plus an
> > offset in the same underlying code, the warning is therefore triggered.
> >
> > Instead of inserting #pragma all over the places where literal pointers
> > are accessed to avoid diagnosing array-bounds, we can try to borrow the
> > idea from linux kernel that the absolute_pointer macro [2][3] is used to
> > disconnect a pointer using literal address from it's original object,
> > hence gcc won't be able to make assumptions on the boundary while doing
> > pointer arithmetic. With that we can greatly reduce the code we have to
> > cover up by making initial literal pointer assignment to use the new
> > wrapper but not having to track everywhere literal pointers are
> > accessed. This also makes code looks cleaner.
> >
> > [1]
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578
> > [2]
> > https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
> > [3]
> > https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31
> >
> > Signed-off-by: Michael Chang <mchang@suse.com>
> 
> [...]
> 
> > diff --git a/grub-core/commands/i386/pc/drivemap.c b/grub-core/commands/i386/pc/drivemap.c
> > index 3fb22dc460..5e13f82eb5 100644
> > --- a/grub-core/commands/i386/pc/drivemap.c
> > +++ b/grub-core/commands/i386/pc/drivemap.c
> > @@ -31,9 +31,6 @@
> >
> >  GRUB_MOD_LICENSE ("GPLv3+");
> >
> > -/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> > -static grub_uint32_t *const int13slot = (grub_uint32_t *) (4 * 0x13);
> > -
> >  /* Remember to update enum opt_idxs accordingly.  */
> >  static const struct grub_arg_option options[] = {
> >    /* TRANSLATORS: In this file "mapping" refers to a change GRUB makes so if
> > @@ -280,6 +277,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
> >    grub_uint8_t *handler_base = 0;
> >    /* Address of the map within the deployed bundle.  */
> >    int13map_node_t *handler_map;
> > +  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> > +  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);
> 
> This shuffling looks strange and should be explained in the commit message.
> I understood what is going here when I took a look at patch #3.

Yes the shuffling was due to the same reasoning provided in patch 3.
I'll include it to flesh out in the commit message.

> 
> > +
> 
> Please drop this empty line addition.

OK.

> 
> >    int i;
> >    int entries = 0;
> > @@ -354,6 +354,9 @@ install_int13_handler (int noret __attribute__ ((unused)))
> >  static grub_err_t
> >  uninstall_int13_handler (void)
> >  {
> > +  /* Real mode IVT slot (seg:off far pointer) for interrupt 0x13.  */
> > +  grub_uint32_t *int13slot = (grub_uint32_t *) grub_absolute_pointer (4 * 0x13);
> 
> WRT shuffling, ditto.

OK.

> 
> > +
> >    if (! grub_drivemap_oldhandler)
> >      return GRUB_ERR_NONE;
> 
> [...]
> 
> > diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
> > index d44937c305..9403390f1f 100644
> > --- a/grub-core/term/i386/pc/console.c
> > +++ b/grub-core/term/i386/pc/console.c
> > @@ -238,12 +238,11 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
> >    return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL);
> >  }
> >
> > -static const struct grub_machine_bios_data_area *bios_data_area =
> > -  (struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
> > -
> >  static int
> >  grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
> >  {
> > +  const struct grub_machine_bios_data_area *bios_data_area =
> > +  (struct grub_machine_bios_data_area *) grub_absolute_pointer (GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR);
> 
> Ditto and below...

OK.

> 
> >    /* conveniently GRUB keystatus is modelled after BIOS one.  */
> >    return bios_data_area->keyboard_flag_lower & ~0x80;
> >  }
> 
> [...]
> 
> > diff --git a/include/grub/compiler.h b/include/grub/compiler.h
> > index 8f3be3ae70..e159f0e292 100644
> > --- a/include/grub/compiler.h
> > +++ b/include/grub/compiler.h
> > @@ -56,4 +56,15 @@
> >  #  define CLANG_PREREQ(maj,min) 0
> >  #endif
> >
> > +#if defined(__GNUC__)
> > +#  define grub_absolute_pointer(val)					\
> > +({									\
> > +	unsigned long __ptr;						\
> 
> I think grub_addr_t would be more appropriate here. But this requires
> include/grub/types.h. So, maybe we should move this macro there.

Looks good to me. I will do in next version,

> 
> > +	__asm__ ("" : "=r"(__ptr) : "0"((void *)(val)));		\
> 
> s/__asm__/asm/

OK.

> 
> Why did you decide to use "asm() version" of this macro [1] instead of more
> C-ish one [2]?

The C-ish one doesn't work as it is acting as fallback for compilers
other than gcc without the need for such hack.

> Anyway, I would mention the idea comes from the Linux
> kernel RELOC_HIDE() macro.

I will add a comment to referencing it.

Thanks a lot for review,
Michael

> 
> Daniel
> 
> [1] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler-gcc.h#L31
> [2] https://elixir.bootlin.com/linux/v5.16.14/source/include/linux/compiler.h#L180
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-03-23  4:51 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-17  6:43 [PATCH 0/3] Fix GCC 12 build error Michael Chang
2022-03-17  6:43 ` [PATCH 1/3] mkimage: Fix dangling pointer may be used error Michael Chang
2022-03-22 20:59   ` Daniel Kiper
2022-03-17  6:43 ` [PATCH 2/3] Fix -Werror=array-bounds array subscript 0 is outside array bounds Michael Chang
2022-03-22 21:19   ` Daniel Kiper
2022-03-23  4:51     ` Michael Chang
2022-03-17  6:43 ` [PATCH 3/3] reed_solomon: Fix " Michael Chang
2022-03-17  7:41   ` Paul Menzel
2022-03-17  8:59     ` Michael Chang
2022-03-22 21:21   ` Daniel Kiper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.