diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ef5d566d4e165272fd54221fa8cf4fade88cd637..bb1dc7719e8cdc3f06a13f2573d89156b5f25e9c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -74,6 +74,7 @@ set (common_sources
      opts.c
      cpu_feature.c
      fiob.c
+     ffisyms.cc
      lua/fiber.cc
      lua/trigger.cc
      lua/admin.cc
diff --git a/src/ffisyms.cc b/src/ffisyms.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f7346dce0eb49c67ea1a03b7c053625ad93e81a8
--- /dev/null
+++ b/src/ffisyms.cc
@@ -0,0 +1,13 @@
+#include <bit/bit.h>
+#include <lib/msgpuck/msgpuck.h>
+
+/*
+ * A special hack to cc/ld to keep symbols in an optimized binary.
+ * Please add your symbols to this array if you plan to use it from LuaJIT FFI.
+ */
+void *ffi_symbols[] = {
+	(void *) bswap_u32,
+	(void *) bswap_u64,
+	(void *) mp_bswap_float,
+	(void *) mp_bswap_double
+};
diff --git a/src/tarantool.cc b/src/tarantool.cc
index c71d94aa9f6dabc011af720292b0347a28cb76fc..6309306f5e40e425c993c518ae3d72d52fd6e629 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -571,6 +571,13 @@ tarantool_free(void)
 		fclose(cfg_out);
 		free(cfg_log);
 	}
+
+	/* A hack for cc/ld, see ffisyms.c */
+	if (time(NULL) == 0) {
+		/* never executed */
+		extern void *ffi_symbols[];
+		write(0, ffi_symbols, 0);
+	}
 }
 
 int