From 91b12bf12a99ebc57fe8ceb73ac53ed73a3ed2e4 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 5 Jul 2019 08:39:59 -0500 Subject: [PATCH] nozero: Work around gcc 9 size pessimization MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit gcc 9 decided [1] that implicitly-zero-initialized static const buffers belong in .rodata rather than .bss (for the extra safety to ensure you can't accidentally modify the buffer contents). However, this inflates our binary size. Avoiding 'const' puts things back in .bss, and it's still easy enough to prove (with reduced scope in nozero.c to match what was already in plugins.c) that the buffer is not modified in spite of dropping the keyword that would let the compiler prove it on our behalf. [1] https://gcc.gnu.org/ml/gcc/2019-04/msg00034.html Reported-by: Thomas Weißschuh Signed-off-by: Eric Blake --- filters/nozero/nozero.c | 6 +++++- server/plugins.c | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/filters/nozero/nozero.c b/filters/nozero/nozero.c index 16ec710b..035caae3 100644 --- a/filters/nozero/nozero.c +++ b/filters/nozero/nozero.c @@ -45,7 +45,6 @@ #define MAX_WRITE (64 * 1024 * 1024) -static const char buffer[MAX_WRITE]; static enum ZeroMode { NONE, EMULATE, @@ -110,7 +109,12 @@ nozero_zero (struct nbdkit_next_ops *next_ops, void *nxdata, return next_ops->zero (nxdata, count, offs, flags, err); while (count) { + /* Always contains zeroes, but we can't use const or else gcc 9 + * will use .rodata instead of .bss and inflate the binary size. + */ + static /* const */ char buffer[MAX_WRITE]; uint32_t size = MIN (count, MAX_WRITE); + if (next_ops->pwrite (nxdata, buffer, size, offs, flags, err) == -1) return -1; offs += size; diff --git a/server/plugins.c b/server/plugins.c index 85736bbc..8eed2dd8 100644 --- a/server/plugins.c +++ b/server/plugins.c @@ -668,7 +668,10 @@ plugin_zero (struct backend *b, struct connection *conn, threadlocal_set_error (0); while (count) { - static const char buf[MAX_REQUEST_SIZE]; /* Always contains zeroes */ + /* Always contains zeroes, but we can't use const or else gcc 9 + * will use .rodata instead of .bss and inflate the binary size. + */ + static /* const */ char buf[MAX_REQUEST_SIZE]; uint32_t limit = MIN (count, sizeof buf); r = plugin_pwrite (b, conn, buf, limit, offset, flags, err); -- 2.11.4.GIT