diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 9a47f8a3db..e33d22fc4b 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -50,16 +50,26 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT const EmptyCord empty_cord_; #if defined(PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED) + +// We add a single dummy entry to guarantee the section is never empty. +struct DummyWeakDefault { + const Message* m; + WeakDescriptorDefaultTail tail; +}; +DummyWeakDefault dummy_weak_default __attribute__((section("pb_defaults"))) = { + nullptr, {&dummy_weak_default.m, sizeof(dummy_weak_default)}}; + extern "C" { // When using --descriptor_implicit_weak_messages we expect the default instance // objects to live in the `pb_defaults` section. We load them all using the // __start/__end symbols provided by the linker. // Each object is its own type and size, so we use a `char` to load them -// appropriately. These are weak because the section might not exist at all. -__attribute__((weak)) extern const char __start_pb_defaults; -__attribute__((weak)) extern const char __stop_pb_defaults; +// appropriately. +extern const char __start_pb_defaults; +extern const char __stop_pb_defaults; } static void InitWeakDefaults() { + StrongPointer(&dummy_weak_default); // force link the dummy entry. // We don't know the size of each object, but we know the layout of the tail. // It contains a WeakDescriptorDefaultTail object. // As such, we iterate the section backwards.