Skip to contentSkip to conversation

Improve ld.lld-21+ compatibility when building i386-pc target

PATCH In review Nicholas Vinson 2 participants 12 messages Mar 4 – Mar 5

lore
Share & tools
lore
#0 lore raw

v4 cover Improve ld.lld-21+ compatibility when building i386-pc target

Starting with ld.llvm-21, any attempt create a non-relocatable binary and set one more secton addresses below 0x400000 results in a linker error. Furthermore, the differences between ld.bfd and ld.lld made finding a proper set of command-line flags tht worked with both linkers and bypass the image base address restriction difficult. Therefore, the approach of using a custom linker script was adopted to solve the issue.

This approach was tested using:

../configure CC=clang CXX=clang++ LDFLAGS="-fuse-ld=lld" TARGET_LDFLAGS="-fuse-ld=lld" --with-platform=pc ../configure CC=clang CXX=clang++ --with-platform=pc (both with ld.lld as the default and ld.bfd as the default) ../configure CC=gcc CXX=g++ --with-platform=pc

and a VM was used for testing. To build the disk images the VM was booted with, the following scripts were used:

EFI disk:

efi_disk_image.sh new file +23 -0
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: gpt
+label-id: ABEB6772-65C7-4391-BF21-B616916286B9
+size=1M, type=21686148-6449-6E6F-744E-656564454649, uuid=9892A604-439E-4401-A372-AAD5E99EADBB
+type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=FCE5EBB3-C887-4FDE-93C5-7670CC3914BF
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F "${LOOP_DEV}p2"
+
+mount "${LOOP_DEV}p2" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p2"
+losetup -d "${LOOP_DEV}"

--

MBR image:

mbr_disk_image.sh new file +22 -0
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: dos
+label-id: 0x12345678
+type=83, bootable
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F -O ^has_journal "${LOOP_DEV}p1"
+
+mount "${LOOP_DEV}p1" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p1"
+losetup -d "${LOOP_DEV}"

--

In all cases, the VM successfully booted to the standard GRUB prompt.

Nicholas Vinson (9):
i386/pc/int.h: move GRUB_MACHINE_PCBIOS ifdef
grub-core: Update kernel image generation
Revert "configure: Print a more helpful error if autoconf-archive is
not installed"
Revert "configure: Check linker for --image-base support" Revert "INSTALL: Add note that the GNU Autoconf Archive may be needed"
configure: drop -Ttext checks for i386-pc
configure.ac: Add --image-base check for non-i386 i386-cygwin-img-ld.sc -> i386-cygwin-img.lds conf/i386-cygwin-img.lds: Update to use _grub_text_base symbol

 .gitignore                                    |  3 +-
 INSTALL                                       |  1 -
 acinclude.m4                                  | 18 ++++--
 conf/Makefile.extra-dist                      |  3 +-
 ...6-cygwin-img-ld.sc => i386-cygwin-img.lds} |  1 +
 conf/i386-pc-kernel.lds                       | 51 ++++++++++++++++
 configure.ac                                  | 59 ++++++++++++-------
 grub-core/Makefile.core.def                   | 31 +++++-----
 include/grub/i386/pc/int.h                    |  2 +-
 m4/ax_check_link_flag.m4                      | 53 +++++++++++++++++
 10 files changed, 177 insertions(+), 45 deletions(-)
 rename conf/{i386-cygwin-img-ld.sc => i386-cygwin-img.lds} (97%)
 create mode 100644 conf/i386-pc-kernel.lds
 create mode 100644 m4/ax_check_link_flag.m4
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#1 lore raw

PATCH v4 1/9 i386/pc/int.h: move GRUB_MACHINE_PCBIOS ifdef

Modern compilers aer becoming more strict and starting to warn when certain attributes are ignored. The regparam attribute is such an attribute.

Moreover, the function

void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno, struct
grub_bios_int_registers *regs) __attribute__ ((regparm(3)));

is only defined with the i386-pc target.

Update i386/pc/int.h so grub_bios_interrupt() is only declared when GRUB_MACHINE_PCBIOS is defined. This addresses the issue of declaring a function that is not defined for non-i386-pc targets and prevents the "attribute ignored" diagnostic message.

---
 include/grub/i386/pc/int.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/grub/i386/pc/int.h +1 -1
index a60104001..ee13195d3 100644
@@ -22,11 +22,11 @@
 #include <grub/symbol.h>
 #include <grub/i386/pc/int_types.h>
 
+#ifdef GRUB_MACHINE_PCBIOS
 void EXPORT_FUNC (grub_bios_interrupt) (grub_uint8_t intno,
 					struct grub_bios_int_registers *regs)
      __attribute__ ((regparm(3)));
 
-#ifdef GRUB_MACHINE_PCBIOS
 extern struct grub_i386_idt *EXPORT_VAR(grub_realidt);
 #endif
 
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#2 lore raw

PATCH v4 2/9 grub-core: Update kernel image generation

In reply to Nicholas Vinson

The i386-pc kernel image fails to build because of changes made to address ld.lld-21 and newer linking issues. Specifically, with ld.lld-21, if you try to set the text section address below image base address when linking a non-relocatable binary, ld.lld wil fail to link.

Switching to using a customized linker script solves the issue and is a more robost solution to supporting multiple linkers than attempting to find a set of command-line flags that satisified all supported linkers and links the kernel properly. In the worst case, continued use of command-line flags could result in having to create code branches to support various linkers.

For example, when dealing with just ld.bfd and ld.lld, the behavioral differences between the two made finding a proper subset of flags that worked impossible. The previous attempt dropped -Ttext for --image-base, which has been proven not to work. The simplest correction, -Wl,--image-base=0 -Wl,-Ttext, did not work because that option resulted in a GRUB kernel that entered into a tight infinite refresh loop.

Moreover, ld.lld does not order the sections the same way ld.bfd does, and that results in object files with gaps or holes when sections are stripped. I suspect, but did not investigate, that this plays a role in the infinite refresh loop I mentioned earlier.

The easiest way to resolve all this is to use customized linker scripts. These scripts, by default, override any default configuration the linker would otherwise impose, allow for complete control in aligning sections, and allows GRUB to specify where in the load segment each section goes.

This patch series does require linkers to support the --defsym flag, which requires its argument to be of the form 'sym=address' as 'sym address' is not supported.

---
 conf/i386-pc-kernel.lds | 51 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 conf/i386-pc-kernel.lds
conf/i386-pc-kernel.lds new file +51 -0
new file mode 100644
index 000000000..d40c7736c
@@ -0,0 +1,51 @@
+ENTRY(_start)
+
+/*
+ * Align sections to a 16-byte boundary. This guarantees ABI compatibility with
+ * C generated code
+ */
+SECTION_ALIGN = 0x10;
+
+PHDRS {
+    text PT_LOAD FLAGS(7) /* PF_R | PF_W | PF_X */;
+}
+
+SECTIONS
+{
+    /*
+     * Set section alignment to 1. This allows sections to be aligned without
+     * creating holes in the VMA space or gaps in the file.
+     */
+    . = _grub_text_base;
+    .text ALIGN(0x1) : {
+        _start = .;
+        *(.text .text.*)
+        . = ALIGN(SECTION_ALIGN);
+    } :text
+    .rodata ALIGN(0x1) : {
+        *(.rodata .rodata.*)
+        . = ALIGN(SECTION_ALIGN);
+    } :text
+    .module_license ALIGN(0x1) : {
+        *(.module_license)
+        . = ALIGN(SECTION_ALIGN);
+    } :text
+    .data ALIGN(0x1) : {
+        *(.data .data.*)
+        . = ALIGN(SECTION_ALIGN);
+        _edata = .;
+    } :text
+    .bss ALIGN(0x1) : {
+        __bss_start = .;
+        *(.bss .bss.*)
+        *(COMMON)
+        . = ALIGN(SECTION_ALIGN);
+        _end = .;
+    } :text
+    /DISCARD/ : {
+        *(.interp)
+        *(.note*)
+        *(.comment)
+        *(.build-id)
+    }
+}
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#3 lore raw

PATCH v4 3/9 Revert "configure: Print a more helpful error if autoconf-archive is not installed"

In reply to Nicholas Vinson

This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.

---
 configure.ac | 5 -----
 1 file changed, 5 deletions(-)
configure.ac +0 -5
index d8ca1b7c1..45f19f188 100644
@@ -1792,11 +1792,6 @@ LIBS=""
 # Defined in acinclude.m4.
 grub_ASM_USCORE
 grub_PROG_TARGET_CC
-
-# The error message produced by autoconf if autoconf-archive is not installed is
-# quite misleading and not very helpful. So, try point people in the right direction.
-m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
-
 if test "x$TARGET_APPLE_LINKER" != x1 ; then
 AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
     [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#4 lore raw

PATCH v4 4/9 Revert "configure: Check linker for --image-base support"

In reply to Nicholas Vinson

This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.

---
 acinclude.m4 |  5 -----
 configure.ac | 14 ++------------
 2 files changed, 2 insertions(+), 17 deletions(-)
acinclude.m4 +0 -5
index 70c1912f8..fa7840f09 100644
@@ -79,11 +79,6 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
 [AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
 AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
 [cat > conftest.c <<\EOF
-asm (
-    ".globl start, _start, __start\n"
-    ".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
-    ".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
-);
 void cmain (void);
 void
 cmain (void)
configure.ac +2 -12
index 45f19f188..209c0fb11 100644
@@ -1461,6 +1461,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
   TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
   TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
   TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
+  TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
   TARGET_IMG_CFLAGS=
 else
   TARGET_APPLE_LINKER=0
@@ -1468,6 +1469,7 @@ else
   TARGET_IMG_LDSCRIPT=
   TARGET_IMG_LDFLAGS='-Wl,-N'
   TARGET_IMG_LDFLAGS_AC='-Wl,-N'
+  TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
   TARGET_IMG_CFLAGS=
 fi
 
@@ -1793,18 +1795,6 @@ LIBS=""
 grub_ASM_USCORE
 grub_PROG_TARGET_CC
 if test "x$TARGET_APPLE_LINKER" != x1 ; then
-AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
-    [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
-    [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
-    [],
-    [AC_LANG_SOURCE([
-asm (".globl start; start:");
-asm (".globl _start; _start:");
-asm (".globl __start; __start:");
-void __main (void);
-void __main (void) {}
-int main (void);
-    ])])
 grub_PROG_OBJCOPY_ABSOLUTE
 fi
 grub_PROG_LD_BUILD_ID_NONE
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#5 lore raw

PATCH v4 5/9 Revert "INSTALL: Add note that the GNU Autoconf Archive may be needed"

In reply to Nicholas Vinson

This reverts commit a90ccbac677db62fc0c1940cda4388370ac8a04b.

---
 INSTALL | 1 -
 1 file changed, 1 deletion(-)
INSTALL +0 -1
index 7ac1c7cc8..7e5397f58 100644
@@ -56,7 +56,6 @@ need the following.
 * Python 3 (NOTE: python 2.6 should still work, but it's not tested)
 * Autoconf 2.64 or later
 * Automake 1.14 or later
-* GNU Autoconf Archive (autoconf-archive on Debian)
 
 Your distro may package cross-compiling toolchains such as the following
 incomplete list on Debian: gcc-aarch64-linux-gnu, gcc-arm-linux-gnueabihf,
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#6 lore raw

PATCH v4 6/9 configure: drop -Ttext checks for i386-pc

In reply to Nicholas Vinson

The i386-pc target now uses a linker script, so -Ttext is no longer required. However, a new variable TARGET_IMG_BASE_LDOPT_ARG_SEP is introduced to handle the fact that when using --defsym the argument separator must be '='. The space character ' ' is a syntax error.

Finally, EXTRA_DIST is updated to track the linker script used.

---
 acinclude.m4                | 13 ++++++++++++-
 conf/Makefile.extra-dist    |  1 +
 configure.ac                | 29 ++++++++++++++++++++++++++---
 grub-core/Makefile.core.def | 31 ++++++++++++++++---------------
 4 files changed, 55 insertions(+), 19 deletions(-)
acinclude.m4 +12 -1
index fa7840f09..478aab6d3 100644
@@ -93,7 +93,18 @@ else
 fi
 grub_cv_prog_objcopy_absolute=yes
 for link_addr in 0x2000 0x8000 0x7C00; do
-  if AC_TRY_COMMAND([${CC-cc} ${TARGET_CFLAGS} ${TARGET_LDFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},$link_addr conftest.o -o conftest.exec]); then :
+
+  target_img_base_ld="${TARGET_IMG_BASE_LDOPT}"
+  case "$target_img_base_ld" in
+    *_grub_text_base)
+      target_img_base_ld="${target_img_base_ld}=$link_addr"
+    ;;
+    *)
+      target_img_base_ld="${target_img_base_ld},$link_addr"
+    ;;
+  esac
+
+  if AC_TRY_COMMAND([${CC-cc} ${TARGET_CFLAGS} ${TARGET_LDFLAGS} -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${target_img_base_ld} conftest.o -o conftest.exec]); then :
   else
     AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
   fi
conf/Makefile.extra-dist +1 -0
index d22b6c862..892df8208 100644
@@ -17,6 +17,7 @@ EXTRA_DIST += docs/grub.cfg
 EXTRA_DIST += docs/osdetect.cfg
 
 EXTRA_DIST += conf/i386-cygwin-img-ld.sc
+EXTRA_DIST += conf/i386-pc-kernel.lds
 
 EXTRA_DIST += grub-core/Makefile.core.def
 EXTRA_DIST += grub-core/Makefile.gcry.def
configure.ac +26 -3
index 209c0fb11..c924431c7 100644
@@ -1454,6 +1454,7 @@ if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_c
    TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20'
    TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20'
    TARGET_IMG_BASE_LDOPT="-Wl,-image_base"
+   TARGET_IMG_BASE_LDOPT_ARG_SEP=","
    TARGET_LDFLAGS_OLDMAGIC=""
 elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then
   TARGET_APPLE_LINKER=0
@@ -1461,7 +1462,8 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
   TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
   TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
   TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
-  TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+  TARGET_IMG_BASE_LDOPT=
+  TARGET_IMG_BASE_LDOPT_ARG_SEP=","
   TARGET_IMG_CFLAGS=
 else
   TARGET_APPLE_LINKER=0
@@ -1469,7 +1471,16 @@ else
   TARGET_IMG_LDSCRIPT=
   TARGET_IMG_LDFLAGS='-Wl,-N'
   TARGET_IMG_LDFLAGS_AC='-Wl,-N'
-  TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+  if test "x$target_cpu-$platform" != "xi386-pc"; then
+    TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+    TARGET_IMG_BASE_LDOPT_ARG_SEP=","
+  else
+    TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
+    TARGET_IMG_BASE_LDOPT_ARG_SEP="="
+    TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-pc-kernel.lds"
+    TARGET_IMG_LDFLAGS="${TARGET_IMG_LDFLAGS} -Wl,-T${TARGET_IMG_LDSCRIPT}"
+    TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-pc-kernel.lds"
+  fi
   TARGET_IMG_CFLAGS=
 fi
 
@@ -1802,7 +1813,18 @@ if test "x$target_cpu" = xi386; then
   if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then
     if test ! -z "$TARGET_IMG_LDSCRIPT"; then
       # Check symbols provided by linker script.
-      CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},0x8000"
+      target_img_base_ld="${TARGET_IMG_BASE_LDOPT}"
+      case "$target_img_base_ld" in
+        *_grub_text_base)
+          target_img_base_ld="${target_img_base_ld}="
+        ;;
+        *)
+          target_img_base_ld="${target_img_base_ld},"
+        ;;
+      esac
+      target_img_base_ld="${target_img_base_ld}0x8000"
+      CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${target_img_base_ld}"
+      target_img_base_ld=""
     fi
     grub_CHECK_BSS_START_SYMBOL
     grub_CHECK_END_SYMBOL
@@ -2404,6 +2426,7 @@ AC_SUBST(TARGET_CCASFLAGS)
 AC_SUBST(TARGET_IMG_LDFLAGS)
 AC_SUBST(TARGET_IMG_CFLAGS)
 AC_SUBST(TARGET_IMG_BASE_LDOPT)
+AC_SUBST(TARGET_IMG_BASE_LDOPT_ARG_SEP)
 AC_SUBST(TARGET_APPLE_LINKER)
 
 AC_SUBST(HOST_CFLAGS)
grub-core/Makefile.core.def +16 -15
index 0cf155128..1a91e53d6 100644
@@ -10,6 +10,7 @@ transform_data = {
   installdir = noinst;
   name = genmod.sh;
   common = genmod.sh.in;
+  i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
 };
 
 transform_data = {
@@ -82,21 +83,21 @@ kernel = {
   riscv64_efi_stripflags   = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame';
 
   i386_pc_ldflags          = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags          = '$(TARGET_IMG_BASE_LDOPT),0x9000';
+  i386_pc_ldflags          = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x9000';
   i386_qemu_ldflags        = '$(TARGET_IMG_LDFLAGS)';
-  i386_qemu_ldflags        = '$(TARGET_IMG_BASE_LDOPT),0x9000';
+  i386_qemu_ldflags        = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x9000';
   i386_coreboot_ldflags    = '$(TARGET_IMG_LDFLAGS)';
-  i386_coreboot_ldflags    = '$(TARGET_IMG_BASE_LDOPT),0x9000';
+  i386_coreboot_ldflags    = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x9000';
   i386_multiboot_ldflags   = '$(TARGET_IMG_LDFLAGS)';
-  i386_multiboot_ldflags   = '$(TARGET_IMG_BASE_LDOPT),0x9000';
+  i386_multiboot_ldflags   = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x9000';
   i386_ieee1275_ldflags    = '$(TARGET_IMG_LDFLAGS)';
-  i386_ieee1275_ldflags    = '$(TARGET_IMG_BASE_LDOPT),0x10000';
+  i386_ieee1275_ldflags    = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x10000';
   i386_xen_ldflags         = '$(TARGET_IMG_LDFLAGS)';
-  i386_xen_ldflags         = '$(TARGET_IMG_BASE_LDOPT),0';
+  i386_xen_ldflags         = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0';
   x86_64_xen_ldflags       = '$(TARGET_IMG_LDFLAGS)';
   x86_64_xen_ldflags       = '$(TARGET_IMG_BASE_LDOPT),0';
   i386_xen_pvh_ldflags     = '$(TARGET_IMG_LDFLAGS)';
-  i386_xen_pvh_ldflags     = '$(TARGET_IMG_BASE_LDOPT),0x100000';
+  i386_xen_pvh_ldflags     = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x100000';
 
   mips_loongson_ldflags    = '-Wl,-Ttext,0x80200000';
   powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
@@ -450,10 +451,10 @@ image = {
   sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S;
 
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x7C00';
 
   i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_BOOT_MACHINE_LINK_ADDR)';
+  i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)$(GRUB_BOOT_MACHINE_LINK_ADDR)';
   i386_qemu_ccasflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
 
   /* The entry point for a.out binaries on sparc64 starts
@@ -478,7 +479,7 @@ image = {
   cppflags = '-DHYBRID_BOOT=1';
   
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x7C00';
 
   objcopyflags = '-O binary';
   enable = i386_pc;
@@ -489,7 +490,7 @@ image = {
 
   i386_pc = boot/i386/pc/cdboot.S;
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x7C00';
 
   sparc64_ieee1275 = boot/sparc64/ieee1275/boot.S;
 
@@ -509,7 +510,7 @@ image = {
   i386_pc = boot/i386/pc/pxeboot.S;
 
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x7C00';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x7C00';
 
   objcopyflags = '-O binary';
   enable = i386_pc;
@@ -520,7 +521,7 @@ image = {
   i386_pc = boot/i386/pc/diskboot.S;
 
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8000';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x8000';
 
   sparc64_ieee1275 = boot/sparc64/ieee1275/diskboot.S;
   sparc64_ieee1275_ldflags = '-Wl,-Ttext=0x4200';
@@ -536,7 +537,7 @@ image = {
   i386_pc = boot/i386/pc/lnxboot.S;
 
   i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
-  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x6000';
+  i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x6000';
 
   objcopyflags = '-O binary';
   enable = i386_pc;
@@ -578,7 +579,7 @@ image = {
   i386_pc_nodist = rs_decoder.h;
 
   objcopyflags = '-O binary';
-  ldflags = '$(TARGET_IMG_LDFLAGS) $(TARGET_IMG_BASE_LDOPT),0x8200';
+  ldflags = '$(TARGET_IMG_LDFLAGS) $(TARGET_IMG_BASE_LDOPT)$(TARGET_IMG_BASE_LDOPT_ARG_SEP)0x8200';
   enable = i386_pc;
 };
 
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#7 lore raw

PATCH v4 7/9 configure.ac: Add --image-base check for non-i386

In reply to Nicholas Vinson

Configure check grub_PROG_OBJCOPY_ABSOLUTE is run for all non-Apple targets. With ld.lld-21, the check fails for addresses below image base address (which ld.lld-21 assumes is 0x200000).

Fix by checking if linker support --image-base flag, and if it does, include "--image-base 0" to TARGET_IMG_BASE_LDOPT.

The AX_CHECK_LINK_FLAG macro has been added to avoid a dependency on autoconf-archive.

Note: I tried this approach with i386-pc, but I ended up with a grub image that failed to boot correctly.

---
 .gitignore               |  3 ++-
 configure.ac             | 13 +++++++++-
 m4/ax_check_link_flag.m4 | 53 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 m4/ax_check_link_flag.m4
.gitignore +2 -1
index db16295ad..f61f4805f 100644
@@ -238,7 +238,8 @@ widthspec.bin
 /lzocompress_test
 /luks1_test
 /luks2_test
-/m4/
+/m4/*
+!/m4/ax_check_link_flag.m4
 /minixfs_test
 /missing
 /netboot_test
configure.ac +12 -1
index c924431c7..061767c34 100644
@@ -1472,7 +1472,18 @@ else
   TARGET_IMG_LDFLAGS='-Wl,-N'
   TARGET_IMG_LDFLAGS_AC='-Wl,-N'
   if test "x$target_cpu-$platform" != "xi386-pc"; then
-    TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
+    AX_CHECK_LINK_FLAG([-Wl,--image-base,0],
+        [TARGET_IMG_BASE_LDOPT="-Wl,--image-base,0 -Wl,-Ttext"],
+        [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
+        [],
+        [AC_LANG_SOURCE([
+    asm (".globl start; start:");
+    asm (".globl _start; _start:");
+    asm (".globl __start; __start:");
+    void __main (void);
+    void __main (void) {}
+    int main (void);
+        ])])
     TARGET_IMG_BASE_LDOPT_ARG_SEP=","
   else
     TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
m4/ax_check_link_flag.m4 new file +53 -0

53 lines not on this page · raw message

Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#8 lore raw

PATCH v4 8/9 i386-cygwin-img-ld.sc -> i386-cygwin-img.lds

In reply to Nicholas Vinson

Rename i386-cygwin-img-ld.sc to i386-cygwin-img.lds as 'lds' is the preferred extension for linker scripts.

---
 conf/Makefile.extra-dist                            | 2 +-
 conf/{i386-cygwin-img-ld.sc => i386-cygwin-img.lds} | 0
 configure.ac                                        | 4 ++--
 3 files changed, 3 insertions(+), 3 deletions(-)
 rename conf/{i386-cygwin-img-ld.sc => i386-cygwin-img.lds} (100%)
conf/Makefile.extra-dist +1 -1
index 892df8208..393693ffc 100644
@@ -16,7 +16,7 @@ EXTRA_DIST += docs/autoiso.cfg
 EXTRA_DIST += docs/grub.cfg
 EXTRA_DIST += docs/osdetect.cfg
 
-EXTRA_DIST += conf/i386-cygwin-img-ld.sc
+EXTRA_DIST += conf/i386-cygwin-img.lds
 EXTRA_DIST += conf/i386-pc-kernel.lds
 
 EXTRA_DIST += grub-core/Makefile.core.def
conf/i386-cygwin-img.lds renamed from conf/i386-cygwin-img-ld.sc +0 -0
similarity index 100%
rename from conf/i386-cygwin-img-ld.sc
rename to conf/i386-cygwin-img.lds
configure.ac +2 -2
index 061767c34..94218e014 100644
@@ -1459,9 +1459,9 @@ if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_c
 elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then
   TARGET_APPLE_LINKER=0
   TARGET_LDFLAGS_OLDMAGIC="-Wl,-N"
-  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
+  TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img.lds"
   TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
-  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
+  TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img.lds"
   TARGET_IMG_BASE_LDOPT=
   TARGET_IMG_BASE_LDOPT_ARG_SEP=","
   TARGET_IMG_CFLAGS=
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#9 lore raw

PATCH v4 9/9 conf/i386-cygwin-img.lds: Update to use _grub_text_base symbol

In reply to Nicholas Vinson

This patch updates conf/i386-cygwin-img.lds to use the _grub_text_base symbol just like conf/i386-pc-kernel.lds. It also updates configure.ac to account for this change.

---
 conf/i386-cygwin-img.lds | 1 +
 configure.ac             | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)
conf/i386-cygwin-img.lds +1 -0
index 578da91b0..e7ed1c523 100644
@@ -2,6 +2,7 @@
 
 SECTIONS
 {
+  . = _grub_text_base;
   .text :
   {
     start = . ;
configure.ac +1 -1
index 94218e014..560c8a320 100644
@@ -1462,7 +1462,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
   TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img.lds"
   TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
   TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img.lds"
-  TARGET_IMG_BASE_LDOPT=
+  TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
   TARGET_IMG_BASE_LDOPT_ARG_SEP=","
   TARGET_IMG_CFLAGS=
 else
Signature · 7 lines
2.53.0


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel
#10 lore raw
In reply to Nicholas Vinson
Quoted 75 lines · Nicholas Vinson

Starting with ld.llvm-21, any attempt create a non-relocatable binary and set one more secton addresses below 0x400000 results in a linker error. Furthermore, the differences between ld.bfd and ld.lld made finding a proper set of command-line flags tht worked with both linkers and bypass the image base address restriction difficult. Therefore, the approach of using a custom linker script was adopted to solve the issue.

This approach was tested using:

../configure CC=clang CXX=clang++ LDFLAGS="-fuse-ld=lld" TARGET_LDFLAGS="-fuse-ld=lld" --with-platform=pc ../configure CC=clang CXX=clang++ --with-platform=pc (both with ld.lld as the default and ld.bfd as the default) ../configure CC=gcc CXX=g++ --with-platform=pc

and a VM was used for testing. To build the disk images the VM was booted with, the following scripts were used:

EFI disk:

efi_disk_image.sh new file +23 -1
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: gpt
+label-id: ABEB6772-65C7-4391-BF21-B616916286B9
+size=1M, type=21686148-6449-6E6F-744E-656564454649, uuid=9892A604-439E-4401-A372-AAD5E99EADBB
+type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=FCE5EBB3-C887-4FDE-93C5-7670CC3914BF
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F "${LOOP_DEV}p2"
+
+mount "${LOOP_DEV}p2" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p2"
+losetup -d "${LOOP_DEV}"
--

MBR image:

mbr_disk_image.sh new file +22 -1
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: dos
+label-id: 0x12345678
+type=83, bootable
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F -O ^has_journal "${LOOP_DEV}p1"
+
+mount "${LOOP_DEV}p1" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p1"
+losetup -d "${LOOP_DEV}"
--

In all cases, the VM successfully booted to the standard GRUB prompt.

Quoted 11 lines

Nicholas Vinson (9):
i386/pc/int.h: move GRUB_MACHINE_PCBIOS ifdef
grub-core: Update kernel image generation
Revert "configure: Print a more helpful error if autoconf-archive is
not installed"
Revert "configure: Check linker for --image-base support" Revert "INSTALL: Add note that the GNU Autoconf Archive may be needed"
configure: drop -Ttext checks for i386-pc
configure.ac: Add --image-base check for non-i386 i386-cygwin-img-ld.sc -> i386-cygwin-img.lds conf/i386-cygwin-img.lds: Update to use _grub_text_base symbol

In general Reviewed-by: Daniel Kiper <[email protected]> but...

configure.ac +3 -3
index 560c8a320..d19fb625d 100644
@@ -1462,8 +1462,8 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
   TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img.lds"
   TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
   TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img.lds"
-  TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
-  TARGET_IMG_BASE_LDOPT_ARG_SEP=","
+  TARGET_IMG_BASE_LDOPT="-Wl,--defsym=_grub_text_base"
+  TARGET_IMG_BASE_LDOPT_ARG_SEP="="
   TARGET_IMG_CFLAGS=
 else
   TARGET_APPLE_LINKER=0
@@ -1486,7 +1486,7 @@ else
         ])])
     TARGET_IMG_BASE_LDOPT_ARG_SEP=","
   else
-    TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
+    TARGET_IMG_BASE_LDOPT="-Wl,--defsym=_grub_text_base"
     TARGET_IMG_BASE_LDOPT_ARG_SEP="="
     TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-pc-kernel.lds"
     TARGET_IMG_LDFLAGS="${TARGET_IMG_LDFLAGS} -Wl,-T${TARGET_IMG_LDSCRIPT}"

The ld man is clear: --defsym=symbol=expression

If you are OK with proposed changes I will make them for you.

Daniel

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

#11 lore raw
Quoted 115 lines · Daniel Kiper
Quoted 75 lines · Nicholas Vinson

Starting with ld.llvm-21, any attempt create a non-relocatable binary and set one more secton addresses below 0x400000 results in a linker error. Furthermore, the differences between ld.bfd and ld.lld made finding a proper set of command-line flags tht worked with both linkers and bypass the image base address restriction difficult. Therefore, the approach of using a custom linker script was adopted to solve the issue.

This approach was tested using:

../configure CC=clang CXX=clang++ LDFLAGS="-fuse-ld=lld" TARGET_LDFLAGS="-fuse-ld=lld" --with-platform=pc ../configure CC=clang CXX=clang++ --with-platform=pc (both with ld.lld as the default and ld.bfd as the default) ../configure CC=gcc CXX=g++ --with-platform=pc

and a VM was used for testing. To build the disk images the VM was booted with, the following scripts were used:

EFI disk:

efi_disk_image.sh new file +23 -1
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: gpt
+label-id: ABEB6772-65C7-4391-BF21-B616916286B9
+size=1M, type=21686148-6449-6E6F-744E-656564454649, uuid=9892A604-439E-4401-A372-AAD5E99EADBB
+type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=FCE5EBB3-C887-4FDE-93C5-7670CC3914BF
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F "${LOOP_DEV}p2"
+
+mount "${LOOP_DEV}p2" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p2"
+losetup -d "${LOOP_DEV}"
--

MBR image:

mbr_disk_image.sh new file +22 -1
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -xe
+
+dd if=/dev/zero of=grub.img bs=1M count=100 status=progress
+
+sfdisk --force --no-reread --no-tell-kernel grub.img <<EOF
+label: dos
+label-id: 0x12345678
+type=83, bootable
+EOF
+
+LOOP_DEV=$(losetup --show -fP grub.img)
+sleep 1
+
+mkfs.ext4 -F -O ^has_journal "${LOOP_DEV}p1"
+
+mount "${LOOP_DEV}p1" /mnt/gentoo
+./grub-install -v --directory ./grub-core --locale-directory /usr/share/locale --boot-directory=/mnt/gentoo "${LOOP_DEV}"
+
+umount "${LOOP_DEV}p1"
+losetup -d "${LOOP_DEV}"
--

In all cases, the VM successfully booted to the standard GRUB prompt.

Quoted 11 lines

Nicholas Vinson (9):
i386/pc/int.h: move GRUB_MACHINE_PCBIOS ifdef
grub-core: Update kernel image generation
Revert "configure: Print a more helpful error if autoconf-archive is
not installed"
Revert "configure: Check linker for --image-base support" Revert "INSTALL: Add note that the GNU Autoconf Archive may be needed"
configure: drop -Ttext checks for i386-pc
configure.ac: Add --image-base check for non-i386 i386-cygwin-img-ld.sc -> i386-cygwin-img.lds conf/i386-cygwin-img.lds: Update to use _grub_text_base symbol

In general Reviewed-by: Daniel Kiper <[email protected]> but...

configure.ac +3 -3
index 560c8a320..d19fb625d 100644
@@ -1462,8 +1462,8 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
    TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img.lds"
    TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
    TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img.lds"
-  TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
-  TARGET_IMG_BASE_LDOPT_ARG_SEP=","
+  TARGET_IMG_BASE_LDOPT="-Wl,--defsym=_grub_text_base"
+  TARGET_IMG_BASE_LDOPT_ARG_SEP="="
    TARGET_IMG_CFLAGS=
  else
    TARGET_APPLE_LINKER=0
@@ -1486,7 +1486,7 @@ else
          ])])
      TARGET_IMG_BASE_LDOPT_ARG_SEP=","
    else
-    TARGET_IMG_BASE_LDOPT="-Wl,--defsym,_grub_text_base"
+    TARGET_IMG_BASE_LDOPT="-Wl,--defsym=_grub_text_base"
      TARGET_IMG_BASE_LDOPT_ARG_SEP="="
      TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-pc-kernel.lds"
      TARGET_IMG_LDFLAGS="${TARGET_IMG_LDFLAGS} -Wl,-T${TARGET_IMG_LDSCRIPT}"
Quoted 3 lines

The ld man is clear: --defsym=symbol=expression

If you are OK with proposed changes I will make them for you.

I am OK with those changes.

Thank you!
Nicholas Vinson

Quoted 2 lines

Daniel

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel