o/build/mkpayload: port to llvm-objcopy

GNU and LLVM objcopy have some material differences in how they work.
LLVM is able to automatically assign VMAs, but needs --set-section-flags
for it. Use that and drop all the explicit VMAs.
Also with the new toolchain cc.objcopy_excutable is not populated, so we
need to get the executable path using the new action-based way.

Currently contains a hack to force static on to get our custom toolchain
for both host and cross-builds as GNU objcopy is not compatible.

Change-Id: I0a5ef1cbeb3f94326a2cef099c23c046df166bdd
Reviewed-on: https://review.monogon.dev/c/monogon/+/4214
Reviewed-by: Tim Windelschmidt <tim@monogon.tech>
Tested-by: Jenkins CI
diff --git a/osbase/build/mkpayload/def.bzl b/osbase/build/mkpayload/def.bzl
index fa10e83..925d682 100644
--- a/osbase/build/mkpayload/def.bzl
+++ b/osbase/build/mkpayload/def.bzl
@@ -3,6 +3,9 @@
 See https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images for more information.
 """
 
+load("@rules_cc//cc:action_names.bzl", "OBJ_COPY_ACTION_NAME")
+load("@rules_cc//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_toolchain", "use_cc_toolchain")
+load("//osbase/build:def.bzl", "build_static_transition")
 load("//osbase/build/mkverity:def.bzl", "VerityInfo")
 
 def _efi_unified_kernel_image_impl(ctx):
@@ -48,14 +51,25 @@
 
     # Append the objcopy parameter separately, as it's not of File type, and
     # it does not constitute an input, since it's part of the toolchain.
-    objcopy = ctx.toolchains["@bazel_tools//tools/cpp:toolchain_type"].cc.objcopy_executable
+    cc_toolchain = find_cpp_toolchain(ctx)
+    feature_configuration = cc_common.configure_features(
+        ctx = ctx,
+        cc_toolchain = cc_toolchain,
+        requested_features = ctx.features,
+        unsupported_features = ctx.disabled_features,
+    )
+    objcopy = cc_common.get_tool_for_action(
+        feature_configuration = feature_configuration,
+        action_name = OBJ_COPY_ACTION_NAME,
+    )
+
     args.append("-objcopy={}".format(objcopy))
 
     # Run mkpayload.
     ctx.actions.run(
         mnemonic = "GenEFIKernelImage",
         progress_message = "Generating EFI unified kernel image: {}".format(image.short_path),
-        inputs = inputs,
+        inputs = depset(inputs, transitive = [cc_toolchain.all_files]),
         outputs = [image],
         executable = ctx.file._mkpayload,
         arguments = args,
@@ -65,10 +79,11 @@
     return [DefaultInfo(files = depset([image]), runfiles = ctx.runfiles(files = [image]))]
 
 efi_unified_kernel_image = rule(
+    cfg = build_static_transition,
     implementation = _efi_unified_kernel_image_impl,
     attrs = {
         "kernel": attr.label(
-            doc = "The Linux kernel executable bzImage. Needs to have EFI handover and EFI stub enabled.",
+            doc = "The Linux kernel executable Image. Needs to have EFI stub enabled.",
             mandatory = True,
             allow_single_file = True,
         ),
@@ -125,8 +140,7 @@
             executable = True,
             cfg = "exec",
         ),
-    },
-    toolchains = [
-        "@bazel_tools//tools/cpp:toolchain_type",
-    ],
+    } | CC_TOOLCHAIN_ATTRS,
+    toolchains = use_cc_toolchain(),
+    fragments = ["cpp"],
 )
diff --git a/osbase/build/mkpayload/mkpayload.go b/osbase/build/mkpayload/mkpayload.go
index c1433f3..f486134 100644
--- a/osbase/build/mkpayload/mkpayload.go
+++ b/osbase/build/mkpayload/mkpayload.go
@@ -39,15 +39,14 @@
 	// as command line parameters.
 	sections = map[string]struct {
 		descr    string
-		vma      string
 		required bool
 		file     *string
 	}{
-		"linux":   {"Linux kernel image", "0x2000000", true, nil},
-		"initrd":  {"initramfs", "0x5000000", false, nil},
-		"osrel":   {"OS release file in text format", "0x20000", false, nil},
-		"cmdline": {"a file containting additional kernel command line parameters", "0x30000", false, nil},
-		"splash":  {"a splash screen image in BMP format", "0x40000", false, nil},
+		"linux":   {"Linux kernel image", true, nil},
+		"initrd":  {"initramfs", false, nil},
+		"osrel":   {"OS release file in text format", false, nil},
+		"cmdline": {"a file containting additional kernel command line parameters", false, nil},
+		"splash":  {"a splash screen image in BMP format", false, nil},
 	}
 	initrdList      stringList
 	objcopy         = flag.String("objcopy", "", "objcopy executable")
@@ -151,7 +150,7 @@
 		if *c.file != "" {
 			args = append(args, []string{
 				"--add-section", fmt.Sprintf(".%s=%s", name, *c.file),
-				"--change-section-vma", fmt.Sprintf(".%s=%s", name, c.vma),
+				fmt.Sprintf("--set-section-flags=.%s=data", name),
 			}...)
 		}
 	}
diff --git a/osbase/build/mkverity/def.bzl b/osbase/build/mkverity/def.bzl
index 417c883..bb5b8a4 100644
--- a/osbase/build/mkverity/def.bzl
+++ b/osbase/build/mkverity/def.bzl
@@ -1,3 +1,5 @@
+load("//osbase/build:def.bzl", "build_static_transition")
+
 # VerityInfo is emitted by verity_image, and contains a file enclosing a
 # singular dm-verity target table.
 VerityInfo = provider(
@@ -46,6 +48,7 @@
     ]
 
 verity_image = rule(
+    cfg = build_static_transition,
     implementation = _verity_image_impl,
     doc = """
       Build a dm-verity target image by appending Verity metadata to the source