linker: move last section id constant to c-code

Move creation of last section id from ld linker script LONG() usage to
C code with last section attribute.

The use of `LONG()` works correctly with ld but lld emits a warning
because .last_section section is not allocated as there are no matching
input sections and discards the `LONG()` call, meaning the last section
identifier will not be present in the flash.
> ld.lld: warning: ignoring memory region assignment for
>                             non-allocatable section '.last_section'

Placing the last section id in `.last_section` in C code makes lld
allocate the memory for the id and thereby create the output section
with the correct output.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
diff --git a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
index aed26ab..ba5413c 100644
--- a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
+++ b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld
@@ -366,11 +366,9 @@
     /* Must be last in romable region */
     SECTION_PROLOGUE(.last_section,,)
     {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-      /* Fill last section with a word to ensure location counter and actual rom
-       * region data usage match. */
-      LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
-#endif
+      /* .last_section contains a fixed word to ensure location counter and actual
+       * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+      KEEP(*(.last_section))
     } GROUP_LINK_IN(ROMABLE_REGION)
 
     /* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
index ff11d49..278620d 100644
--- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
+++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld
@@ -412,11 +412,9 @@
 /* Must be last in romable region */
 SECTION_PROLOGUE(.last_section,,)
 {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-  /* Fill last section with a word to ensure location counter and actual rom
-   * region data usage match. */
-  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
-#endif
+  /* .last_section contains a fixed word to ensure location counter and actual
+   * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+  KEEP(*(.last_section))
 } GROUP_LINK_IN(ROMABLE_REGION)
 
 /* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld
index d5a4e25..ee29e43 100644
--- a/include/zephyr/arch/arm64/scripts/linker.ld
+++ b/include/zephyr/arch/arm64/scripts/linker.ld
@@ -351,11 +351,9 @@
     /* Must be last in romable region */
     SECTION_PROLOGUE(.last_section,,)
     {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-      /* Fill last section with a word to ensure location counter and actual rom
-       * region data usage match. */
-      LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
-#endif
+      /* .last_section contains a fixed word to ensure location counter and actual
+       * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+      KEEP(*(.last_section))
     } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
 
     /* To provide the image size as a const expression,
diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld
index 87aa159..a63bc03 100644
--- a/include/zephyr/arch/riscv/common/linker.ld
+++ b/include/zephyr/arch/riscv/common/linker.ld
@@ -454,15 +454,13 @@
 /* Must be last in romable region */
 SECTION_PROLOGUE(.last_section,,)
 {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-  /* Fill last section with a word to ensure location counter and actual rom
-   * region data usage match. */
-  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
+  /* .last_section contains a fixed word to ensure location counter and actual
+   * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+  KEEP(*(.last_section))
   /* __rom_region_size is used when configuring the PMP entry of the ROM region.
    * Addresses (pmpaddr) in PMP registers need to be aligned to 4. Align
    * __rom_region_size to 4 to meet that requirement. */
   MPU_MIN_SIZE_ALIGN
-#endif
 } GROUP_LINK_IN(ROMABLE_REGION)
 
 /* To provide the image size as a const expression,
diff --git a/lib/utils/CMakeLists.txt b/lib/utils/CMakeLists.txt
index 7062d69..aca2e69 100644
--- a/lib/utils/CMakeLists.txt
+++ b/lib/utils/CMakeLists.txt
@@ -28,3 +28,5 @@
   ${ZEPHYR_BASE}/kernel/include
   ${ZEPHYR_BASE}/arch/${ARCH}/include
 )
+
+zephyr_sources_ifdef(CONFIG_LINKER_LAST_SECTION_ID last_section_id.c)
diff --git a/lib/utils/last_section_id.c b/lib/utils/last_section_id.c
new file mode 100644
index 0000000..02a2065
--- /dev/null
+++ b/lib/utils/last_section_id.c
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2025, Nordic Semiconductor ASA
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ */
+#include <zephyr/types.h>
+
+static uint32_t last_id __attribute__((section(".last_section"))) __attribute__((__used__)) =
+	CONFIG_LINKER_LAST_SECTION_ID_PATTERN;
diff --git a/soc/andestech/ae350/linker.ld b/soc/andestech/ae350/linker.ld
index ae10cab..36e4e51 100644
--- a/soc/andestech/ae350/linker.ld
+++ b/soc/andestech/ae350/linker.ld
@@ -421,11 +421,9 @@
 /* Must be last in romable region */
 SECTION_PROLOGUE(.last_section,,)
 {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-  /* Fill last section with a word to ensure location counter and actual rom
-   * region data usage match. */
-  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
-#endif
+  /* .last_section contains a fixed word to ensure location counter and actual
+   * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+  KEEP(*(.last_section))
 } GROUP_LINK_IN(ROMABLE_REGION)
 
 /* Because ROMABLE_REGION != RAMABLE_REGION in XIP-system, it is valid
diff --git a/soc/infineon/cat1b/cyw20829/linker.ld b/soc/infineon/cat1b/cyw20829/linker.ld
index 2395740..5f6b02e 100644
--- a/soc/infineon/cat1b/cyw20829/linker.ld
+++ b/soc/infineon/cat1b/cyw20829/linker.ld
@@ -466,11 +466,9 @@
 /* Must be last in romable region */
 SECTION_PROLOGUE(.last_section,,)
 {
-#ifdef CONFIG_LINKER_LAST_SECTION_ID
-  /* Fill last section with a word to ensure location counter and actual rom
-   * region data usage match. */
-  LONG(CONFIG_LINKER_LAST_SECTION_ID_PATTERN)
-#endif
+  /* .last_section contains a fixed word to ensure location counter and actual
+   * rom region data usage match when CONFIG_LINKER_LAST_SECTION_ID=y. */
+  KEEP(*(.last_section))
 } GROUP_LINK_IN(ROMABLE_REGION)
 
 /* To provide the image size as a const expression,