|
|
|
@ -350,3 +350,79 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); |
|
|
|
|
error UPB_TRACING_ENABLED Tracing should be disabled in production builds |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// Linker arrays combine elements from multiple translation units into a single |
|
|
|
|
// array that can be iterated over at runtime. |
|
|
|
|
// |
|
|
|
|
// It is an alternative to pre-main "registration" functions. |
|
|
|
|
// |
|
|
|
|
// Usage: |
|
|
|
|
// |
|
|
|
|
// // In N translation units. |
|
|
|
|
// UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3}; |
|
|
|
|
// |
|
|
|
|
// // At runtime: |
|
|
|
|
// UPB_LINKARR_DECLARE(foo_array, int); |
|
|
|
|
// |
|
|
|
|
// void f() { |
|
|
|
|
// const int* start = UPB_LINKARR_START(foo_array); |
|
|
|
|
// const int* stop = UPB_LINKARR_STOP(foo_array); |
|
|
|
|
// for (const int* p = start; p < stop; p++) { |
|
|
|
|
// // Windows can introduce zero padding, so we have to skip zeroes. |
|
|
|
|
// if (*p != 0) { |
|
|
|
|
// vec.push_back(*p); |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
#if defined(__ELF__) || defined(__wasm__) |
|
|
|
|
|
|
|
|
|
#define UPB_LINKARR_APPEND(name) \ |
|
|
|
|
__attribute__((retain, used, section("linkarr_" #name))) |
|
|
|
|
#define UPB_LINKARR_DECLARE(name, type) \ |
|
|
|
|
extern type const __start_linkarr_##name; \ |
|
|
|
|
extern type const __stop_linkarr_##name; \ |
|
|
|
|
UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1] = {0} |
|
|
|
|
#define UPB_LINKARR_START(name) (&__start_linkarr_##name) |
|
|
|
|
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) |
|
|
|
|
|
|
|
|
|
#elif defined(__MACH__) |
|
|
|
|
|
|
|
|
|
/* As described in: https://stackoverflow.com/a/22366882 */ |
|
|
|
|
#define UPB_LINKARR_APPEND(name) \ |
|
|
|
|
__attribute__((retain, used, section("__DATA,la_" #name))) |
|
|
|
|
#define UPB_LINKARR_DECLARE(name, type) \ |
|
|
|
|
extern type const __start_linkarr_##name __asm( \ |
|
|
|
|
"section$start$__DATA$la_" #name); \ |
|
|
|
|
extern type const __stop_linkarr_##name __asm( \ |
|
|
|
|
"section$end$__DATA$" \ |
|
|
|
|
"la_" #name); \ |
|
|
|
|
UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1] = {0} |
|
|
|
|
#define UPB_LINKARR_START(name) (&__start_linkarr_##name) |
|
|
|
|
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) |
|
|
|
|
|
|
|
|
|
#elif defined(_MSC_VER) && defined(__clang__) |
|
|
|
|
|
|
|
|
|
/* See: |
|
|
|
|
* https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 |
|
|
|
|
* https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 |
|
|
|
|
* https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ |
|
|
|
|
|
|
|
|
|
// Usage of __attribute__ here probably means this is Clang-specific, and would |
|
|
|
|
// not work on MSVC. |
|
|
|
|
#define UPB_LINKARR_APPEND(name) \ |
|
|
|
|
__declspec(allocate("la_" #name "$j")) __attribute__((retain, used)) |
|
|
|
|
#define UPB_LINKARR_DECLARE(name, type) \ |
|
|
|
|
__declspec(allocate("la_" #name "$a")) type __start_linkarr_##name; \ |
|
|
|
|
__declspec(allocate("la_" #name "$z")) type __stop_linkarr_##name; \ |
|
|
|
|
UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1] = {0} |
|
|
|
|
#define UPB_LINKARR_START(name) (&__start_linkarr_##name) |
|
|
|
|
#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
// Linker arrays are not supported on this platform. Make appends a no-op but |
|
|
|
|
// don't define the other macros. |
|
|
|
|
#define UPB_LINKARR_APPEND(name) |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|