]> git.draconx.ca Git - rrace.git/commitdiff
Avoid linking against libXt/libXm string tables.
authorNick Bowler <nbowler@draconx.ca>
Sat, 7 Jan 2023 16:19:27 +0000 (11:19 -0500)
committerNick Bowler <nbowler@draconx.ca>
Sun, 8 Jan 2023 05:46:55 +0000 (00:46 -0500)
The libXt and libXm libraries contain huge (about 25 kB in total)
constant string tables, and the header files define macros that
offset these tables rather than using normal C strings.

The trouble is, on ELF systems with position-independent libraries,
accessing these tables from a program is very expensive.  Compilers
most commonly emit copy relocations that literally just duplicate
the entire table at runtime into the program's data segment.

As far as I can tell, this completely eliminates any possible advantage
of these tables: you use twice as much memory in a single program, the
copied data is not shareable between processes, and there is extra work
to actually perform these relocations.

Letting the program define its own strings avoids these relocations
and is substantially smaller, because only a handful of strings from
the tables are actually used.

They can still be shared if the program itself is compiled as PIC,
which adds GOT indirection to all accesses to the string table.  But
this actually increases the size of the program more than just using
normal string literals does.

Maybe these made sense to have in the library at some point in the
past, maybe once upon a time C compilers didn't merge string literals
between translation units and these tables were the solution.

I don't think these tables make sense today.  Fortunately, the headers
provide an option to disable this nonsense, at least for our program,
which we can just define in config.h.

configure.ac

index 4be4c2aa21ff49799df1c8e4ced50a512f2af92b..064c3247e7c31428343dda1b86c3ef0c4f9aeaa5 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright © 2022 Nick Bowler
+dnl Copyright © 2022-2023 Nick Bowler
 dnl
 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
 dnl This is free software: you are free to do what the fuck you want to.
@@ -98,6 +98,20 @@ AS_IF([test x"$dx_cv_motif_have_pixmap_and_string" = x"yes"],
     [Define to 1 if Motif supports XmPIXMAP_AND_STRING])])
 ])
 
+dnl On ELF systems, linking a program against a string table in shared
+dnl library is very expensive and actually makes things much worse than
+dnl just duplicating the needed strings in the program.
+dnl
+dnl It may help a little bit when static linking or on other shared
+dnl library implementations, which could maybe be auto-detected with
+dnl a configure test, but the penalty for setting these anyway is
+dnl very small (couple hundred bytes of rodata).
+m4_foreach_w([lib], [Xt Xm],
+[AC_DEFINE(m4_toupper(m4_defn([lib]))[STRINGDEFINES], [1],
+[Define to 1 to avoid using the string tables from lib]m4_defn([lib])[.
+On some platforms, or when statically linking lib]m4_defn([lib])[,
+leaving this undefined may reduce the executable size somewhat.])])
+
 AC_CONFIG_TESTDIR([.], [t:.])
 DX_PROG_AUTOTEST
 AM_CONDITIONAL([HAVE_AUTOTEST], [test x"$dx_cv_autotest_works" = x"yes"])