Prevent custom data sections from getting stripped off on Windows

#pragma data_seg(".my_section")
static Foo private_stuff = {};
#pragma data_seg()

exe.link_gc_sections = false; isn’t helping, how do I tell the linker not to strip off the section?

It seems like Clang silently ignores data_seg pragmas unless you specify -fms-extensions. I thought the option would be enabled by default on Windows, and Clang’s documentation even says:

To enable these extensions, use the -fms-extensions command-line option. This is the default for Windows targets.

However, it’s only the default for Windows MSVC (and UEFI) targets.

Anyway, if you want to use MSVC pragmas, then you can:

  1. Specify -fms-extensions on the command line.
  2. For completeness, you could set the target to, for instance, x86_64-windows-msvc or native-windows-msvc, but only if you’re willing to depend on MSVC and the Windows SDK (which is not necessary!).
1 Like

Ah, didn’t know something like that exists but the issue is the section gets stripped off if I don’t use private_stuff explicitly in any other place, was trying to do something like this later some other place.

By default msvc doesn’t seem to strip off that custom data section. But when targetting native-windows-msvc with zig it does.

Have to explicitly do something like this in order for the section to not get stripped off.

__declspec(dllexport) void* get_private_stuff(void) {
    return &private_stuff;
}

So was wondering if there is any flags to make it not do it?

Oh I see. In that case, you can force the compiler to emit the symbol by putting __attribute__((used)) before defining private_stuff, although it’s an unholy mixture of MSVC and GCC/Clang syntax. You’re already aware of link_gc_sections, which should be enough to keep the section in the final executable/DLL.

By the way, I was using objdump to test different options and attributes (so many…), and I realized that the name .my_section was truncated to .my_sect! It turns out that section names in PE files are limited to 8 characters. Sharing just in case you don’t know.

1 Like

Do I have to do the put __attribute__((used)) and then link_gc_sections = false?

In my testing only setting link_gc_sections = false didn’t help, it still stripped off the section.

Yeah I believe you need both. The attribute ensures that private_stuff and its containing section end up in an object file, even though none of your code references it. Setting link_gc_sections to false similarly ensures that the linker doesn’t throw away the section.

1 Like