1 /*
2  * Copyright (c) 2023 Yonatan Schachter
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Header file for binary descriptors
10  * @ingroup bindesc
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_
14 #define ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_
15 
16 /**
17  * @defgroup bindesc Binary Descriptors
18  * @ingroup os_services
19  * @{
20  */
21 
22 #include <zephyr/sys/util_macro.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif /* __cplusplus */
27 
28 /*
29  * Corresponds to the definitions in scripts/west_commands/bindesc.py.
30  * Do not change without syncing the definitions in both files!
31  */
32 
33 /** Magic number used to identify binary descriptor sections in firmware images */
34 #define BINDESC_MAGIC 0xb9863e5a7ea46046
35 /** Required memory alignment for binary descriptor entries */
36 #define BINDESC_ALIGNMENT 4
37 
38 /** @name Binary Descriptor Types */
39 /** @{ */
40 #define BINDESC_TYPE_UINT            0x0 /**< Unsigned integer data */
41 #define BINDESC_TYPE_STR             0x1 /**< String data */
42 #define BINDESC_TYPE_BYTES           0x2 /**< Byte array data */
43 #define BINDESC_TYPE_DESCRIPTORS_END 0xf /**< Marks the end of binary descriptor section */
44 /** @} */
45 
46 /** Size of the header of a binary descriptor entry */
47 /* Needed as sizeof ignores the data as it's a flexible array */
48 #define BINDESC_ENTRY_HEADER_SIZE (sizeof(struct bindesc_entry))
49 
50 /**
51  * @brief Macros for defining binary descriptors in firmware images
52  * @defgroup bindesc_define Binary Descriptor Definition
53  * @ingroup bindesc
54  * @{
55  */
56 
57 /*
58  * Corresponds to the definitions in scripts/west_commands/bindesc.py.
59  * Do not change without syncing the definitions in both files!
60  */
61 
62 /** The app version string such as "1.2.3" */
63 #define BINDESC_ID_APP_VERSION_STRING 0x800
64 
65 /** The app version major such as 1 */
66 #define BINDESC_ID_APP_VERSION_MAJOR 0x801
67 
68 /** The app version minor such as 2 */
69 #define BINDESC_ID_APP_VERSION_MINOR 0x802
70 
71 /** The app version patchlevel such as 3 */
72 #define BINDESC_ID_APP_VERSION_PATCHLEVEL 0x803
73 
74 /** The app version number such as 0x10203 */
75 #define BINDESC_ID_APP_VERSION_NUMBER 0x804
76 
77 /** The app git reference such as "v3.3.0-18-g2c85d9224fca" */
78 #define BINDESC_ID_APP_BUILD_VERSION 0x805
79 
80 /** The kernel version string such as "3.4.0" */
81 #define BINDESC_ID_KERNEL_VERSION_STRING 0x900
82 
83 /** The kernel version major such as 3 */
84 #define BINDESC_ID_KERNEL_VERSION_MAJOR 0x901
85 
86 /** The kernel version minor such as 4 */
87 #define BINDESC_ID_KERNEL_VERSION_MINOR 0x902
88 
89 /** The kernel version patchlevel such as 0 */
90 #define BINDESC_ID_KERNEL_VERSION_PATCHLEVEL 0x903
91 
92 /** The kernel version number such as 0x30400 */
93 #define BINDESC_ID_KERNEL_VERSION_NUMBER 0x904
94 
95 /** The kernel git reference such as "v3.3.0-18-g2c85d9224fca" */
96 #define BINDESC_ID_KERNEL_BUILD_VERSION 0x905
97 
98 /** The year the image was compiled in */
99 #define BINDESC_ID_BUILD_TIME_YEAR 0xa00
100 
101 /** The month of the year the image was compiled in */
102 #define BINDESC_ID_BUILD_TIME_MONTH 0xa01
103 
104 /** The day of the month the image was compiled in */
105 #define BINDESC_ID_BUILD_TIME_DAY 0xa02
106 
107 /** The hour of the day the image was compiled in */
108 #define BINDESC_ID_BUILD_TIME_HOUR 0xa03
109 
110 /** The minute the image was compiled in */
111 #define BINDESC_ID_BUILD_TIME_MINUTE 0xa04
112 
113 /** The second the image was compiled in */
114 #define BINDESC_ID_BUILD_TIME_SECOND 0xa05
115 
116 /** The UNIX time (seconds since midnight of 1970/01/01) the image was compiled in */
117 #define BINDESC_ID_BUILD_TIME_UNIX 0xa06
118 
119 /** The date and time of compilation such as "2023/02/05 00:07:04" */
120 #define BINDESC_ID_BUILD_DATE_TIME_STRING 0xa07
121 
122 /** The date of compilation such as "2023/02/05" */
123 #define BINDESC_ID_BUILD_DATE_STRING 0xa08
124 
125 /** The time of compilation such as "00:07:04" */
126 #define BINDESC_ID_BUILD_TIME_STRING 0xa09
127 
128 /** The name of the host that compiled the image */
129 #define BINDESC_ID_HOST_NAME 0xb00
130 
131 /** The C compiler name */
132 #define BINDESC_ID_C_COMPILER_NAME 0xb01
133 
134 /** The C compiler version */
135 #define BINDESC_ID_C_COMPILER_VERSION 0xb02
136 
137 /** The C++ compiler name */
138 #define BINDESC_ID_CXX_COMPILER_NAME 0xb03
139 
140 /** The C++ compiler version */
141 #define BINDESC_ID_CXX_COMPILER_VERSION 0xb04
142 
143 /** The end of binary descriptor section */
144 #define BINDESC_TAG_DESCRIPTORS_END BINDESC_TAG(DESCRIPTORS_END, 0x0fff)
145 
146 /**
147  * @cond INTERNAL_HIDDEN
148  */
149 
150 /*
151  * Utility macro to generate a tag from a type and an ID
152  *
153  * type - Type of the descriptor, UINT, STR or BYTES
154  * id - Unique ID for the descriptor, must fit in 12 bits
155  */
156 #define BINDESC_TAG(type, id) ((BINDESC_TYPE_##type & 0xf) << 12 | (id & 0x0fff))
157 
158 /**
159  * @brief Utility macro to get the type of a bindesc tag
160  *
161  * @param tag Tag to get the type of
162  */
163 #define BINDESC_GET_TAG_TYPE(tag) ((tag >> 12) & 0xf)
164 
165 /**
166  * @endcond
167  */
168 
169 #if !defined(_LINKER) || defined(__DOXYGEN__)
170 
171 #include <zephyr/sys/byteorder.h>
172 #include <zephyr/device.h>
173 
174 /**
175  * @cond INTERNAL_HIDDEN
176  */
177 
178 /*
179  * Utility macro to get the name of a bindesc entry
180  */
181 #define BINDESC_NAME(name) bindesc_entry_##name
182 
183 /* Convenience helper for declaring a binary descriptor entry. */
184 #define __BINDESC_ENTRY_DEFINE(name)							\
185 	__aligned(BINDESC_ALIGNMENT) const struct bindesc_entry BINDESC_NAME(name)	\
186 	__in_section(_bindesc_entry, static, name) __used __noasan
187 
188 /**
189  * @endcond
190  */
191 
192 /**
193  * @brief Define a binary descriptor of type string.
194  *
195  * @details
196  * Define a string that is registered in the binary descriptor header.
197  * The defined string can be accessed using @ref BINDESC_GET_STR
198  *
199  * @note The defined string is not static, so its name must not collide with
200  * any other symbol in the executable.
201  *
202  * @param name Name of the descriptor
203  * @param id Unique ID of the descriptor
204  * @param value A string value for the descriptor
205  */
206 #define BINDESC_STR_DEFINE(name, id, value)							\
207 	__BINDESC_ENTRY_DEFINE(name) = {							\
208 		.tag = BINDESC_TAG(STR, id),							\
209 		.len = (uint16_t)sizeof(value),							\
210 		.data = value,									\
211 	};											\
212 	BUILD_ASSERT(sizeof(value) <= CONFIG_BINDESC_DEFINE_MAX_DATA_SIZE,			\
213 		     "Bindesc " STRINGIFY(name) " exceeded maximum size, consider reducing the"	\
214 		     " size or changing CONFIG_BINDESC_DEFINE_MAX_DATA_SIZE. ")
215 
216 /**
217  * @brief Define a binary descriptor of type uint.
218  *
219  * @details
220  * Define an integer that is registered in the binary descriptor header.
221  * The defined integer can be accessed using @ref BINDESC_GET_UINT
222  *
223  * @note The defined integer is not static, so its name must not collide with
224  * any other symbol in the executable.
225  *
226  * @param name Name of the descriptor
227  * @param id Unique ID of the descriptor
228  * @param value An integer value for the descriptor
229  */
230 #define BINDESC_UINT_DEFINE(name, id, value)		\
231 	__BINDESC_ENTRY_DEFINE(name) = {		\
232 		.tag = BINDESC_TAG(UINT, id),		\
233 		.len = (uint16_t)sizeof(uint32_t),	\
234 		.data = sys_uint32_to_array(value),	\
235 	}
236 
237 /**
238  * @brief Define a binary descriptor of type bytes.
239  *
240  * @details
241  * Define a uint8_t array that is registered in the binary descriptor header.
242  * The defined array can be accessed using @ref BINDESC_GET_BYTES.
243  * The value should be given as an array literal, wrapped in parentheses, for
244  * example:
245  *
246  *     BINDESC_BYTES_DEFINE(name, id, ({1, 2, 3, 4}));
247  *
248  * @note The defined array is not static, so its name must not collide with
249  * any other symbol in the executable.
250  *
251  * @param name Name of the descriptor
252  * @param id Unique ID of the descriptor
253  * @param value A uint8_t array as data for the descriptor
254  */
255 #define BINDESC_BYTES_DEFINE(name, id, value)							\
256 	__BINDESC_ENTRY_DEFINE(name) = {							\
257 		.tag = BINDESC_TAG(BYTES, id),							\
258 		.len = (uint16_t)sizeof((uint8_t [])__DEBRACKET value),				\
259 		.data = __DEBRACKET value,							\
260 	};											\
261 	BUILD_ASSERT(sizeof((uint8_t [])__DEBRACKET value) <=					\
262 		     CONFIG_BINDESC_DEFINE_MAX_DATA_SIZE,					\
263 		     "Bindesc " STRINGIFY(name) " exceeded maximum size, consider reducing the"	\
264 		     " size or changing CONFIG_BINDESC_DEFINE_MAX_DATA_SIZE. ")
265 
266 /**
267  * @brief Get the value of a string binary descriptor
268  *
269  * @details
270  * Get the value of a string binary descriptor, previously defined by
271  * BINDESC_STR_DEFINE.
272  *
273  * @param name Name of the descriptor
274  */
275 #define BINDESC_GET_STR(name) BINDESC_NAME(name).data
276 
277 /**
278  * @brief Get the value of a uint binary descriptor
279  *
280  * @details
281  * Get the value of a uint binary descriptor, previously defined by
282  * BINDESC_UINT_DEFINE.
283  *
284  * @param name Name of the descriptor
285  */
286 #define BINDESC_GET_UINT(name) *(uint32_t *)&(BINDESC_NAME(name).data)
287 
288 /**
289  * @brief Get the value of a bytes binary descriptor
290  *
291  * @details
292  * Get the value of a string binary descriptor, previously defined by
293  * BINDESC_BYTES_DEFINE. The returned value can be accessed as an array:
294  *
295  *     for (size_t i = 0; i < BINDESC_GET_SIZE(name); i++)
296  *         BINDESC_GET_BYTES(name)[i];
297  *
298  * @param name Name of the descriptor
299  */
300 #define BINDESC_GET_BYTES(name) BINDESC_NAME(name).data
301 
302 /**
303  * @brief Get the size of a binary descriptor
304  *
305  * @details
306  * Get the size of a binary descriptor. This is particularly useful for
307  * bytes binary descriptors where there's no null terminator.
308  *
309  * @param name Name of the descriptor
310  */
311 #define BINDESC_GET_SIZE(name) BINDESC_NAME(name).len
312 
313 /**
314  * @}
315  */
316 
317 /**
318  * @brief Functions for reading binary descriptors from firmware images
319  * @defgroup bindesc_read Binary Descriptor Reading
320  * @ingroup bindesc
321  * @{
322  */
323 
324 /**
325  * @brief Structure for a binary descriptor entry
326  */
327 struct bindesc_entry {
328 	/** Tag of the entry */
329 	uint16_t tag;
330 	/** Length of the descriptor data */
331 	uint16_t len;
332 	/** Value of the entry. This is either an integer or a string */
333 	uint8_t data[];
334 } __packed;
335 
336 /** @cond INTERNAL_HIDDEN */
337 /*
338  * We're assuming that `struct bindesc_entry` has a specific layout in
339  * memory, so it's worth making sure that the layout is really what we
340  * think it is. If these assertions fail for your toolchain/platform,
341  * please open a bug report.
342  */
343 BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout");
344 BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout");
345 BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout");
346 /** @endcond */
347 
348 /**
349  * @brief Handle for reading binary descriptors from firmware images
350  */
351 struct bindesc_handle {
352 	/** @cond INTERNAL_HIDDEN */
353 	const uint8_t *address;
354 	enum {
355 		BINDESC_HANDLE_TYPE_RAM,
356 		BINDESC_HANDLE_TYPE_MEMORY_MAPPED_FLASH,
357 		BINDESC_HANDLE_TYPE_FLASH,
358 	} type;
359 	size_t size_limit;
360 #if IS_ENABLED(CONFIG_BINDESC_READ_FLASH)
361 	const struct device *flash_device;
362 	uint8_t buffer[sizeof(struct bindesc_entry) +
363 			CONFIG_BINDESC_READ_FLASH_MAX_DATA_SIZE] __aligned(BINDESC_ALIGNMENT);
364 #endif /* IS_ENABLED(CONFIG_BINDESC_READ_FLASH) */
365 	/** @endcond */
366 };
367 
368 /**
369  * @brief Callback type to be called on descriptors found during a walk
370  *
371  * @param entry Current descriptor
372  * @param user_data The user_data given to @ref bindesc_foreach
373  *
374  * @return Any non zero value will halt the walk
375  */
376 typedef int (*bindesc_callback_t)(const struct bindesc_entry *entry, void *user_data);
377 
378 /**
379  * @brief Open an image's binary descriptors for reading, from a memory mapped flash
380  *
381  * @details
382  * Initializes a bindesc handle for subsequent calls to bindesc API.
383  * Memory mapped flash is any flash that can be directly accessed by the CPU,
384  * without needing to use the flash API for copying the data to RAM.
385  *
386  * @param[out] handle Bindesc handle to be given to subsequent calls
387  * @param offset The offset from the beginning of the flash that the bindesc magic can be found at
388  *
389  * @retval 0 On success
390  * @retval -ENOENT If no bindesc magic was found at the given offset
391  */
392 int bindesc_open_memory_mapped_flash(struct bindesc_handle *handle, size_t offset);
393 
394 /**
395  * @brief Open an image's binary descriptors for reading, from RAM
396  *
397  * @details
398  * Initializes a bindesc handle for subsequent calls to bindesc API.
399  * It's assumed that the whole bindesc context was copied to RAM prior to calling
400  * this function, either by the user or by a bootloader.
401  *
402  * @note The given address must be aligned to @ref BINDESC_ALIGNMENT
403  *
404  * @param[out] handle Bindesc handle to be given to subsequent calls
405  * @param address The address that the bindesc magic can be found at
406  * @param max_size Maximum size of the given buffer
407  *
408  * @retval 0 On success
409  * @retval -ENOENT If no bindesc magic was found at the given address
410  * @retval -EINVAL If the given address is not aligned
411  */
412 int bindesc_open_ram(struct bindesc_handle *handle, const uint8_t *address, size_t max_size);
413 
414 /**
415  * @brief Open an image's binary descriptors for reading, from flash
416  *
417  * @details
418  * Initializes a bindesc handle for subsequent calls to bindesc API.
419  * As opposed to reading bindesc from RAM or memory mapped flash, this
420  * backend requires reading the data from flash to an internal buffer
421  * using the flash API
422  *
423  * @param[out] handle Bindesc handle to be given to subsequent calls
424  * @param offset The offset from the beginning of the flash that the bindesc magic can be found at
425  * @param flash_device Flash device to read descriptors from
426  *
427  * @kconfig_dep{CONFIG_BINDESC_READ_FLASH}
428  *
429  * @retval 0 On success
430  * @retval -ENOENT If no bindesc magic was found at the given offset
431  */
432 int bindesc_open_flash(struct bindesc_handle *handle, size_t offset,
433 		       const struct device *flash_device);
434 
435 /**
436  * @brief Walk the binary descriptors and run a user defined callback on each of them
437  *
438  * @note
439  * If the callback returns a non zero value, the walk stops.
440  *
441  * @param handle An initialized bindesc handle
442  * @param callback A user defined callback to be called on each descriptor
443  * @param user_data User defined data to be given to the callback
444  *
445  * @return If the walk was finished prematurely by the callback,
446  *         return the callback's retval, zero otherwise
447  */
448 int bindesc_foreach(struct bindesc_handle *handle, bindesc_callback_t callback, void *user_data);
449 
450 /**
451  * @brief Find a specific descriptor of type string
452  *
453  * @warning
454  * When using the flash backend, result will be invalidated by the next call to any bindesc API.
455  * Use the value immediately or copy it elsewhere.
456  *
457  * @param handle An initialized bindesc handle
458  * @param id ID to search for
459  * @param result Pointer to the found string
460  *
461  * @retval 0 If the descriptor was found
462  * @retval -ENOENT If the descriptor was not found
463  */
464 int bindesc_find_str(struct bindesc_handle *handle, uint16_t id, const char **result);
465 
466 /**
467  * @brief Find a specific descriptor of type uint
468  *
469  * @warning
470  * When using the flash backend, result will be invalidated by the next call to any bindesc API.
471  * Use the value immediately or copy it elsewhere.
472  *
473  * @param handle An initialized bindesc handle
474  * @param id ID to search for
475  * @param result Pointer to the found uint
476  *
477  * @retval 0 If the descriptor was found
478  * @retval -ENOENT If the descriptor was not found
479  */
480 int bindesc_find_uint(struct bindesc_handle *handle, uint16_t id, const uint32_t **result);
481 
482 /**
483  * @brief Find a specific descriptor of type bytes
484  *
485  * @warning
486  * When using the flash backend, result will be invalidated by the next call to any bindesc API.
487  * Use the value immediately or copy it elsewhere.
488  *
489  * @param handle An initialized bindesc handle
490  * @param id ID to search for
491  * @param result Pointer to the found bytes
492  * @param result_size Size of the found bytes
493  *
494  * @retval 0 If the descriptor was found
495  * @retval -ENOENT If the descriptor was not found
496  */
497 int bindesc_find_bytes(struct bindesc_handle *handle, uint16_t id, const uint8_t **result,
498 		       size_t *result_size);
499 
500 /**
501  * @brief Get the size of an image's binary descriptors
502  *
503  * @details
504  * Walks the binary descriptor structure to caluculate the total size of the structure
505  * in bytes. This is useful, for instance, if the whole structure is to be copied to RAM.
506  *
507  * @param handle An initialized bindesc handle
508  * @param result Pointer to write result to
509  *
510  * @return 0 On success, negative errno otherwise
511  */
512 int bindesc_get_size(struct bindesc_handle *handle, size_t *result);
513 
514 /**
515  * @}
516  */
517 
518 #if defined(CONFIG_BINDESC_KERNEL_VERSION_STRING)
519 extern const struct bindesc_entry BINDESC_NAME(kernel_version_string);
520 #endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_STRING) */
521 
522 #if defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR)
523 extern const struct bindesc_entry BINDESC_NAME(kernel_version_major);
524 #endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */
525 
526 #if defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR)
527 extern const struct bindesc_entry BINDESC_NAME(kernel_version_minor);
528 #endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */
529 
530 #if defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL)
531 extern const struct bindesc_entry BINDESC_NAME(kernel_version_patchlevel);
532 #endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */
533 
534 #if defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER)
535 extern const struct bindesc_entry BINDESC_NAME(kernel_version_number);
536 #endif /* defined(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */
537 
538 #if defined(CONFIG_BINDESC_KERNEL_BUILD_VERSION)
539 extern const struct bindesc_entry BINDESC_NAME(kernel_build_version);
540 #endif /* defined(CONFIG_BINDESC_KERNEL_BUILD_VERSION) */
541 
542 #if defined(CONFIG_BINDESC_APP_VERSION_STRING)
543 extern const struct bindesc_entry BINDESC_NAME(app_version_string);
544 #endif /* defined(CONFIG_BINDESC_APP_VERSION_STRING) */
545 
546 #if defined(CONFIG_BINDESC_APP_VERSION_MAJOR)
547 extern const struct bindesc_entry BINDESC_NAME(app_version_major);
548 #endif /* defined(CONFIG_BINDESC_APP_VERSION_MAJOR) */
549 
550 #if defined(CONFIG_BINDESC_APP_VERSION_MINOR)
551 extern const struct bindesc_entry BINDESC_NAME(app_version_minor);
552 #endif /* defined(CONFIG_BINDESC_APP_VERSION_MINOR) */
553 
554 #if defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL)
555 extern const struct bindesc_entry BINDESC_NAME(app_version_patchlevel);
556 #endif /* defined(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */
557 
558 #if defined(CONFIG_BINDESC_APP_VERSION_NUMBER)
559 extern const struct bindesc_entry BINDESC_NAME(app_version_number);
560 #endif /* defined(CONFIG_BINDESC_APP_VERSION_NUMBER) */
561 
562 #if defined(CONFIG_BINDESC_APP_BUILD_VERSION)
563 extern const struct bindesc_entry BINDESC_NAME(app_build_version);
564 #endif /* defined(CONFIG_BINDESC_APP_BUILD_VERSION) */
565 
566 #if defined(CONFIG_BINDESC_BUILD_TIME_YEAR)
567 extern const struct bindesc_entry BINDESC_NAME(build_time_year);
568 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_YEAR) */
569 
570 #if defined(CONFIG_BINDESC_BUILD_TIME_MONTH)
571 extern const struct bindesc_entry BINDESC_NAME(build_time_month);
572 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_MONTH) */
573 
574 #if defined(CONFIG_BINDESC_BUILD_TIME_DAY)
575 extern const struct bindesc_entry BINDESC_NAME(build_time_day);
576 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_DAY) */
577 
578 #if defined(CONFIG_BINDESC_BUILD_TIME_HOUR)
579 extern const struct bindesc_entry BINDESC_NAME(build_time_hour);
580 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_HOUR) */
581 
582 #if defined(CONFIG_BINDESC_BUILD_TIME_MINUTE)
583 extern const struct bindesc_entry BINDESC_NAME(build_time_minute);
584 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_MINUTE) */
585 
586 #if defined(CONFIG_BINDESC_BUILD_TIME_SECOND)
587 extern const struct bindesc_entry BINDESC_NAME(build_time_second);
588 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_SECOND) */
589 
590 #if defined(CONFIG_BINDESC_BUILD_TIME_UNIX)
591 extern const struct bindesc_entry BINDESC_NAME(build_time_unix);
592 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_UNIX) */
593 
594 #if defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING)
595 extern const struct bindesc_entry BINDESC_NAME(build_date_time_string);
596 #endif /* defined(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */
597 
598 #if defined(CONFIG_BINDESC_BUILD_DATE_STRING)
599 extern const struct bindesc_entry BINDESC_NAME(build_date_string);
600 #endif /* defined(CONFIG_BINDESC_BUILD_DATE_STRING) */
601 
602 #if defined(CONFIG_BINDESC_BUILD_TIME_STRING)
603 extern const struct bindesc_entry BINDESC_NAME(build_time_string);
604 #endif /* defined(CONFIG_BINDESC_BUILD_TIME_STRING) */
605 
606 #if defined(CONFIG_BINDESC_HOST_NAME)
607 extern const struct bindesc_entry BINDESC_NAME(host_name);
608 #endif /* defined(CONFIG_BINDESC_HOST_NAME) */
609 
610 #if defined(CONFIG_BINDESC_C_COMPILER_NAME)
611 extern const struct bindesc_entry BINDESC_NAME(c_compiler_name);
612 #endif /* defined(CONFIG_BINDESC_C_COMPILER_NAME) */
613 
614 #if defined(CONFIG_BINDESC_C_COMPILER_VERSION)
615 extern const struct bindesc_entry BINDESC_NAME(c_compiler_version);
616 #endif /* defined(CONFIG_BINDESC_C_COMPILER_VERSION) */
617 
618 #if defined(CONFIG_BINDESC_CXX_COMPILER_NAME)
619 extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_name);
620 #endif /* defined(CONFIG_BINDESC_CXX_COMPILER_NAME) */
621 
622 #if defined(CONFIG_BINDESC_CXX_COMPILER_VERSION)
623 extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version);
624 #endif /* defined(CONFIG_BINDESC_CXX_COMPILER_VERSION) */
625 
626 #endif /* !defined(_LINKER) */
627 
628 #ifdef __cplusplus
629 }
630 #endif
631 
632 /**
633  * @}
634  */
635 
636 #endif /* ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ */
637