I'm not sure to which mailing list this question should go, so apologies if I should be addressing the binutils list. I have put together a minimal working example of some behavior in recent gcc/ld versions that I cannot explain. I have a simple linker script for the purpose of locating related data together so that I can iterate it from a function in my program. Strangely, the type or contents of the data seem to have a drastic impact on the output size of the binary executable. First, version info: $ gcc --version; ld --version gcc (Debian 6.3.0-18) 6.3.0 20170516 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. GNU ld (GNU Binutils for Debian) 2.28 Copyright (C) 2017 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) a later version. This program has absolutely no warranty. My linker script, test.ld: SECTIONS { .rodata.foo : { PROVIDE_HIDDEN(foo_start = .); *(.foo) PROVIDE_HIDDEN(foo_end = .); } } INSERT AFTER .rodata My program source, test.c: #include <stdio.h> struct foo { int x, y; }; static const struct foo bar __attribute__ ((section (".foo"))) = { .x = 123, .y = 456, }; extern const struct foo foo_start[], foo_end[]; int main() { printf("%p %p\n", (void *)foo_start, (void *)foo_end); return 0; } I compile it as follows and find a generated a.out that is 8.7KB in size, as I would expect: $ gcc -T test.ld test.c $ ls -lh a.out -rwxr-xr-x 1 corey corey 8.7K Feb 22 11:10 a.out Now I make a small, seemingly benign change to my program - I edit struct foo to include a pointer to some static const int: #include <stdio.h> struct foo { int x; const int *y; }; static const int y = 456; static const struct foo bar __attribute__ ((section (".foo"))) = { .x = 123, .y = &y, }; extern const struct foo foo_start[], foo_end[]; int main() { printf("%p %p\n", (void *)foo_start, (void *)foo_end); return 0; } With this new source, I compile and find a generated a.out that is 2.1MB in size!: $ gcc -T test.ld test.c $ ls -lh a.out -rwxr-xr-x 1 corey corey 2.1M Feb 22 11:12 a.out I tried the same test on another machine with the following gcc/ld versions and did not see this problem; both programs resulted in an a.out of ~8.6KB or so: $ gcc --version; ld --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. GNU ld version 2.23.52.0.1-55.el7 20130226 Copyright 2013 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) a later version. This program has absolutely no warranty. Any thoughts or suggestions? Using the -Wl,-zmax-page-size=0x1000 option seems to reduce the binary size considerably, but given that a differently-versioned toolchain produced expected results, and that the unexpected result is exposed by simply changing the structure to include the address of another symbol, I'm more inclined to suspect that the root cause is either that I've done something wrong or that there's a toolchain bug somewhere, in which case -zmax-page-size would only be a workaround in lieu of a better fix. Thank you, Corey