summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Wong <gtw@gnu.org>2009-09-11 23:06:39 -0600
committerGary Wong <gtw@gnu.org>2009-09-11 23:06:39 -0600
commitd51ca09b1e85c78df4f0490b7c1ffbf3e6034bed (patch)
tree382bdf793d4cb37ba36e96643c8ba1fe7e2bc97d
parentd4d66325598a872099c946de60855f991c588142 (diff)
Move initialisation code into its own section, if supported by the linker.
-rw-r--r--ChangeLog11
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac82
-rw-r--r--decorate-core.c8
-rw-r--r--decorate-render.c6
-rw-r--r--gwm.c72
-rw-r--r--gwm.h5
-rw-r--r--gwm.ld10
-rw-r--r--gwm.ld.in10
-rw-r--r--window-table.c4
10 files changed, 169 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 50ee58c..22ebaba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-09-11 Gary Wong <gtw@gnu.org>
+
+ * decorate-core.c (decorate_core_init): Moved to the initialisation
+ section.
+ * decorate-render.c (decorate_render_init, decorate_compat_init):
+ Likewise.
+ * window-table.c (table_init, stack_init): Likewise.
+ * gwm.c (setup_display, unknown): Likewise.
+ (init): New function.
+ (main) [HAVE_INIT_SECTION]: Deallocate the initialisation section.
+
2009-09-10 Gary Wong <gtw@gnu.org>
* gwm.c (setup_display): Make sure the root event mask change is
diff --git a/Makefile.am b/Makefile.am
index 7c2f588..4c7387c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,9 @@ bin_PROGRAMS = gwm
AM_CFLAGS = @PKG_CFLAGS@
gwm_LDADD = @PKG_LIBS@
+if LINKER_SCRIPTS
+gwm_LDFLAGS = -Wl,-Tgwm.ld
+endif
gwm_SOURCES = \
actions.c actions.h \
button.c button.h \
diff --git a/configure.ac b/configure.ac
index 535aac9..7342276 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,8 @@
AC_INIT(gwm, 0.0, gtw@gnu.org)
+AC_PREREQ([2.60])
AC_CONFIG_SRCDIR(gwm.c)
AM_INIT_AUTOMAKE
-AC_CONFIG_FILES(Makefile)
+AC_CONFIG_FILES(Makefile gwm.ld)
AC_CONFIG_HEADERS(config.h)
if test -f config.options; then
@@ -42,7 +43,6 @@ AC_DEFUN([GWM_OPTIONAL_PACKAGE],[
fi
])
-AC_DEFINE(_GNU_SOURCE, 1, [Enable GNU extensions on systems that have them.])
AH_BOTTOM([/* If we haven't been told that we're debugging, assume we aren't. */
#ifndef DEBUG
#define NDEBUG 1
@@ -50,6 +50,7 @@ AH_BOTTOM([/* If we haven't been told that we're debugging, assume we aren't. */
# Checks for programs:
AC_PROG_CC
+AC_USE_SYSTEM_EXTENSIONS
PKG_PROG_PKG_CONFIG
# Checks for libraries:
@@ -79,7 +80,7 @@ AM_CONDITIONAL(RENDER, [test x$gwm_found_render = xyes])
AC_SEARCH_LIBS(iconv, iconv)
# Checks for header files:
-AC_CHECK_HEADERS(iconv.h mcheck.h poll.h)
+AC_CHECK_HEADERS(iconv.h mcheck.h sys/mman.h poll.h sys/param.h)
# Checks for types:
AC_TYPE_UINT64_T
@@ -87,8 +88,79 @@ AC_TYPE_UINT64_T
# Checks for functions:
AC_CHECK_FUNCS(iconv mtrace ppoll)
-PKG_CFLAGS=`$PKG_CONFIG --cflags $gwm_packages`
-PKG_LIBS=`$PKG_CONFIG --libs $gwm_packages`
+# Check for a reasonable section alignment to pass to the linker. First,
+# try looking for typical compile-time constants in system header files...
+AC_MSG_CHECKING([linker section alignment])
+gwm_align=512
+gwm_found_align=no
+while test $gwm_align -le 65536; do
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if EXEC_PAGESIZE == ]] $gwm_align [[ || PAGE_SIZE == ]] $gwm_align [[ || PAGESIZE == ]] $gwm_align [[
+int main() { return 0; }
+#else
+Failure.
+#endif
+]])], [gwm_found_align=yes; break], [])
+ gwm_align=$(expr $gwm_align \* 2)
+done
+if test $gwm_found_align = no; then
+ # No luck so far...
+ if test $cross_compiling != yes; then
+ for gwm_prog in pagesize "getconf PAGE_SIZE"; do
+ if $gwm_prog > /dev/null 2>&1; then
+ gwm_align=512
+ gwm_found_align=no
+ while test $gwm_align -le 65536; do
+ if test $($gwm_prog 2> /dev/null) = $gwm_align; then
+ gwm_found_align=yes
+ break
+ fi
+ gwm_align=$(expr $gwm_align \* 2)
+ done
+ if test $gwm_found_align = yes; then break; fi
+ fi
+ done
+ fi
+fi
+if test $gwm_found_align = no; then
+ gwm_align=4096 # complete guess
+fi
+AC_MSG_RESULT([$gwm_align])
+SECTION_ALIGN=$gwm_align
+AC_SUBST(SECTION_ALIGN)
+
+AC_MSG_CHECKING([for linker script support])
+gwm_ldflags="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,-Tconftest.ld"
+cat > conftest.ld <<EOF
+SECTIONS
+{
+ init_start = .;
+ .gwminit.text : { init*(.text ) }
+ .gwminit.rodata : { init*(.rodata ) }
+ init_end = .;
+}
+INSERT AFTER .text;
+EOF
+AC_LINK_IFELSE([AC_LANG_SOURCE([[
+extern char init_start, init_end;
+int main() { (void) ( &init_end - &init_start ); return 0; }
+]])], [gwm_linker_scripts=yes
+ AC_DEFINE(HAVE_INIT_SECTION, 1)
+ AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)])
+LDFLAGS="$gwm_ldflags"
+AM_CONDITIONAL(LINKER_SCRIPTS, [test x$gwm_linker_scripts = xyes])
+AH_TEMPLATE(HAVE_INIT_SECTION,[Define if the linker supports scripts (used to locate the init section).])
+
+PKG_CFLAGS=$($PKG_CONFIG --cflags $gwm_packages)
+PKG_LIBS=$($PKG_CONFIG --libs $gwm_packages)
AC_SUBST(PKG_CFLAGS)
AC_SUBST(PKG_LIBS)
diff --git a/decorate-core.c b/decorate-core.c
index 79bc693..9e5d6b1 100644
--- a/decorate-core.c
+++ b/decorate-core.c
@@ -331,17 +331,17 @@ static void handle_get_default_map( unsigned int sequence, void *reply,
}
}
-extern void decorate_core_init( void ) {
+extern INIT void decorate_core_init( void ) {
int i;
uint32_t n;
- const char *font_name = "-*-lucida-bold-r-normal-sans-" FONT_SIZE_STRING
- "-*-*-*-p-*-iso10646-1", /* FIXME allow font selection */
+ const char *font_name = "-*-lucida-bold-r-normal-sans-"
+ FONT_SIZE_STRING "-*-*-*-p-*-iso10646-1", /* FIXME allow selection */
*cursor_font_name = "cursor";
xcb_char2b_t c2;
union callback_param p;
xcb_font_t cursor_font;
- static const int cursor_glyphs[ NUM_CURSORS ] = {
+ static INITD const int cursor_glyphs[ NUM_CURSORS ] = {
134, /* CURSOR_TL */
138, /* CURSOR_T */
136, /* CURSOR_TR */
diff --git a/decorate-render.c b/decorate-render.c
index 3ae193a..23b9fdd 100644
--- a/decorate-render.c
+++ b/decorate-render.c
@@ -1030,12 +1030,12 @@ static void handle_get_default_map( unsigned int sequence, void *reply,
}
}
-static void decorate_compat_init( void ) {
+static INIT void decorate_compat_init( void ) {
int i;
const char *cursor_font_name = "cursor";
xcb_font_t cursor_font;
- static const int cursor_glyphs[ NUM_CURSORS ] = {
+ static INITD const int cursor_glyphs[ NUM_CURSORS ] = {
134, /* CURSOR_TL */
138, /* CURSOR_T */
136, /* CURSOR_TR */
@@ -1072,7 +1072,7 @@ static void decorate_compat_init( void ) {
}
}
-extern int decorate_render_init( void ) {
+extern INIT int decorate_render_init( void ) {
xcb_render_query_version_cookie_t render_cookie;
xcb_render_query_pict_formats_cookie_t formats_cookie;
diff --git a/gwm.c b/gwm.c
index e744520..2f58a17 100644
--- a/gwm.c
+++ b/gwm.c
@@ -29,6 +29,9 @@
#if HAVE_MCHECK_H
#include <mcheck.h>
#endif
+#if HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
#if HAVE_POLL_H
#include <poll.h>
#endif
@@ -110,24 +113,6 @@ static const char *const atom_names[ NUM_ATOMS ] = {
xcb_atom_t prop_atoms[ NUM_PROPS ];
xcb_atom_t prop_types[ NUM_PROPS ];
-static const xcb_extension_t *const extensions[ EXTENSIONS_SIZE ] = {
-#if USE_COMPOSITE
- &xcb_composite_id,
-#endif
-#if USE_DAMAGE
- &xcb_damage_id,
-#endif
-#if USE_RENDER
- &xcb_render_id,
-#endif
-#if USE_SHAPE
- &xcb_shape_id,
-#endif
-#if USE_XFIXES
- &xcb_xfixes_id
-#endif
-};
-
int have_extension[ EXTENSIONS_SIZE ];
uint8_t extension_event[ EXTENSIONS_SIZE ],
extension_error[ EXTENSIONS_SIZE ];
@@ -1620,8 +1605,25 @@ static const event_handler *const handlers[] = {
childless_handlers
};
-static void setup_display( void ) {
+static INIT void setup_display( void ) {
+ static INITD const xcb_extension_t *const extensions[ EXTENSIONS_SIZE ] = {
+#if USE_COMPOSITE
+ &xcb_composite_id,
+#endif
+#if USE_DAMAGE
+ &xcb_damage_id,
+#endif
+#if USE_RENDER
+ &xcb_render_id,
+#endif
+#if USE_SHAPE
+ &xcb_shape_id,
+#endif
+#if USE_XFIXES
+ &xcb_xfixes_id
+#endif
+ };
int i;
xcb_intern_atom_cookie_t atom_cookies[ NUM_ATOMS ];
const xcb_setup_t *setup;
@@ -2543,7 +2545,7 @@ retry_root:
#endif
}
-static void unknown( char *opt ) {
+static INIT void unknown( char *opt ) {
printf( "%s: unknown option %s\n"
"Usage: %s [OPTION]...\n"
@@ -2551,13 +2553,12 @@ static void unknown( char *opt ) {
argv0, opt, argv0, argv0 );
}
-extern int main( int argc, char *argv[] ) {
+static INIT void init( int argc, char *argv[] ) {
int i, j;
struct sigaction sa;
- int which_signal;
static int flag_help, flag_version;
- static const struct option {
+ static INITD const struct option {
const char *opt;
int *flag;
} options[] = {
@@ -2590,7 +2591,7 @@ extern int main( int argc, char *argv[] ) {
if( j == NUM_OPTIONS ) {
unknown( argv[ i ] );
- return 1;
+ exit( 1 );
}
} else if( argv[ i ][ 1 ] != '-' ) {
for( j = 0; j < NUM_OPTIONS; j++ )
@@ -2603,13 +2604,13 @@ extern int main( int argc, char *argv[] ) {
if( j == NUM_OPTIONS ) {
unknown( argv[ i ] );
- return 1;
+ exit( 1 );
}
}
} else {
unknown( argv[ i ] );
- return 1;
+ exit( 1 );
}
if( flag_help ) {
@@ -2627,14 +2628,14 @@ extern int main( int argc, char *argv[] ) {
"Please send bug reports to <" PACKAGE_BUGREPORT ">.\n",
argv0 );
- return 0;
+ exit( 0 );
}
if( flag_version ) {
puts( PACKAGE_STRING "\nPlease send bug reports to <"
PACKAGE_BUGREPORT ">." );
- return 0;
+ exit( 0 );
}
sa.sa_handler = catch_signal;
@@ -2652,6 +2653,21 @@ extern int main( int argc, char *argv[] ) {
sigaction( SIGCHLD, &sa, NULL );
setup_display();
+}
+
+extern int main( int argc, char *argv[] ) {
+
+ int which_signal;
+
+ init( argc, argv );
+
+#if HAVE_INIT_SECTION
+ {
+ extern char init_start, init_end;
+
+ munmap( &init_start, &init_end - &init_start );
+ }
+#endif
handle_events();
which_signal = signal_caught;
diff --git a/gwm.h b/gwm.h
index 608aaad..5ae7468 100644
--- a/gwm.h
+++ b/gwm.h
@@ -33,6 +33,11 @@
#define PURE __attribute__((pure))
#endif
+#if HAVE_INIT_SECTION
+#define INIT __attribute__((section( ".gwminit.text" ) ))
+#define INITD __attribute__((section( ".gwminit.rodata" ) ))
+#endif
+
#define SEND_EVENT_MASK 0x80
extern MALLOC void *xmalloc( size_t size );
diff --git a/gwm.ld b/gwm.ld
new file mode 100644
index 0000000..d6d0617
--- /dev/null
+++ b/gwm.ld
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ . = ALIGN (4096);
+ init_start = .;
+ .gwminit.text : { init*(.text ) }
+ .gwminit.rodata : { init*(.rodata ) }
+ . = ALIGN (4096);
+ init_end = .;
+}
+INSERT AFTER .text;
diff --git a/gwm.ld.in b/gwm.ld.in
new file mode 100644
index 0000000..c69b83d
--- /dev/null
+++ b/gwm.ld.in
@@ -0,0 +1,10 @@
+SECTIONS
+{
+ . = ALIGN (@SECTION_ALIGN@);
+ init_start = .;
+ .gwminit.text : { *(.gwminit.text ) }
+ .gwminit.rodata : { *(.gwminit.rodata ) }
+ . = ALIGN (@SECTION_ALIGN@);
+ init_end = .;
+}
+INSERT AFTER .text;
diff --git a/window-table.c b/window-table.c
index 2f8f575..fb71d86 100644
--- a/window-table.c
+++ b/window-table.c
@@ -40,7 +40,7 @@
struct window_table windows, update_windows;
-extern void table_init( struct window_table *table ) {
+extern INIT void table_init( struct window_table *table ) {
table->used = 0;
table->n = 32;
@@ -363,7 +363,7 @@ extern struct gwm_window *lookup_window( xcb_window_t w ) {
struct window_stack window_stack;
-extern void stack_init( struct window_stack *stack ) {
+extern INIT void stack_init( struct window_stack *stack ) {
stack->used = 0;
stack->n = 32;