Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/Makefile.common	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -35,5 +35,4 @@
 #   DEFS               compiler defines
 #   EXTRA_CFLAGS       additional flags to pass to C compiler
-#   LINKER_SCRIPT      linker script
 #   PRE_DEPEND         targets required for dependency check
 #
@@ -113,4 +112,6 @@
 LIBPOSIX_PREFIX = $(LIB_PREFIX)/posix
 LIBDLTEST_PREFIX = $(LIB_PREFIX)/dltest
+
+STARTUP_OBJECT = $(LIBC_PREFIX)/arch/$(UARCH)/src/entry.o
 
 AFLAGS = --fatal-warnings
@@ -140,12 +141,7 @@
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a $(LIBSOFTINT_PREFIX)/libsoftint.a
 
-ifeq ($(LINK_DYNAMIC),y)
-	LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld
-else
+ifneq ($(LINK_DYNAMIC),y)
 	LDFLAGS += -static
-	LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld
-endif
-
-LIB_LINKER_SCRIPT = $(LIBC_PREFIX)/arch/$(UARCH)/_link-shlib.ld
+endif
 
 INCLUDES_FLAGS = $(LIBC_INCLUDES_FLAGS)
@@ -301,11 +297,11 @@
 
 ifneq ($(BINARY),)
-$(BINARY): $(LINKER_SCRIPT) $(OBJECTS) $(LIBTAGS) $(BASE_LIBS)
-	$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) -T $(LINKER_SCRIPT) -Wl,-Map,$@.map -o $@ $(OBJECTS) $(LIBARGS) $(BASE_LIBS)
+$(BINARY): $(OBJECTS) $(LIBTAGS) $(BASE_LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Map,$@.map -o $@ $(STARTUP_OBJECT) $(OBJECTS) $(LIBARGS) $(BASE_LIBS)
 endif
 
 ifneq ($(TEST_BINARY),)
-$(TEST_BINARY): $(LINKER_SCRIPT) $(TEST_OBJECTS) $(TEST_BINARY_LIBS) $(LIBTAGS) $(BASE_LIBS)
-	$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) -T $(LINKER_SCRIPT) -Wl,-Map,$@.map -o $@ $(TEST_OBJECTS) $(TEST_BINARY_LIBS) $(LIBARGS) $(BASE_LIBS)
+$(TEST_BINARY): $(TEST_OBJECTS) $(TEST_BINARY_LIBS) $(LIBTAGS) $(BASE_LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Map,$@.map -o $@ $(STARTUP_OBJECT) $(TEST_OBJECTS) $(TEST_BINARY_LIBS) $(LIBARGS) $(BASE_LIBS)
 endif
 
@@ -323,6 +319,6 @@
 	$(AR) rc $@ $(LOBJECTS)
 
-$(SLIBRARY): $(LIB_LINKER_SCRIPT) $(LIBRARY).la
-	$(CC) $(CFLAGS) $(LIB_LDFLAGS) $(EXTRA_LDFLAGS) -T $(LIB_LINKER_SCRIPT) -Wl,-Map,$@.map -o $@ -Wl,--whole-archive $(LIBRARY).la -Wl,--no-whole-archive
+$(SLIBRARY): $(LIBRARY).la
+	$(CC) $(CFLAGS) $(LIB_LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Map,$@.map -o $@ -Wl,--whole-archive $(LIBRARY).la -Wl,--no-whole-archive
 
 $(LSONAME):
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/lib/c/Makefile	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -33,12 +33,4 @@
 CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
 
-LINKER_SCRIPTS = \
-	$(LIBC_PREFIX)/arch/$(UARCH)/_link.ld \
-	$(LIBC_PREFIX)/arch/$(UARCH)/_link-shlib.ld \
-	$(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld
-
-PRE_DEPEND =
-EXTRA_OUTPUT = $(LINKER_SCRIPTS)
-EXTRA_CLEAN = $(LINKER_SCRIPTS)
 LIBRARY = libc
 SOVERSION = 0.0
@@ -190,13 +182,4 @@
 include $(USPACE_PREFIX)/Makefile.common
 
-$(LIBC_PREFIX)/arch/$(UARCH)/_link.ld: $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld.in
-	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PATH=$(CURDIR) -E -x c $< | grep -v "^\#" > $@
-
-$(LIBC_PREFIX)/arch/$(UARCH)/_link-shlib.ld: $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld.in
-	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PATH=$(CURDIR) -DSHLIB -E -x c $< | grep -v "^\#" > $@
-
-$(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld: $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld.in
-	$(CC) $(DEFS) $(CFLAGS) -DLIBC_PATH=$(CURDIR) -DDLEXE -E -x c $< | grep -v "^\#" > $@
-
 AUTOCHECK = $(realpath $(ROOT_PATH)/tools/autocheck.awk)
 
Index: uspace/lib/c/arch/abs32le/_link.ld.in
===================================================================
--- uspace/lib/c/arch/abs32le/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,62 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x1000;
-
-	.data : {
-		*(.data);
-		*(.data.rel*);
-	} :data
-
-	.got.plt : {
-		*(.got.plt);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.sbss : {
-		*(.scommon);
-		*(.sbss);
-	}
-
-	.bss : {
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/amd64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/amd64/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,75 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-	debug PT_NOTE;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x1000;
-
-	.data : {
-		*(.data);
-		*(.data.rel*);
-	} :data
-
-	.got.plt : {
-		*(.got.plt);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-#ifdef CONFIG_LINE_DEBUG
-	.comment 0 : { *(.comment); } :debug
-	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
-	.debug_aranges 0 : { *(.debug_aranges); } :debug
-	.debug_info 0 : { *(.debug_info); } :debug
-	.debug_line 0 : { *(.debug_line); } :debug
-	.debug_loc 0 : { *(.debug_loc); } :debug
-	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
-	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
-	.debug_ranges 0 : { *(.debug_ranges); } :debug
-	.debug_str 0 : { *(.debug_str); } :debug
-#endif
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/arm32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/arm32/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,60 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x1000;
-
-	.data : {
-		*(.opd);
-		*(.data .data.*);
-		*(.sdata);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.sbss);
-		*(.scommon);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/ia32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ia32/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,134 +1,0 @@
-#ifndef SHLIB
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-#endif
-
-PHDRS {
-#if defined(DLEXE)
-	interp PT_INTERP;
-#endif
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-#if defined(SHLIB) || defined(DLEXE)
-	dynamic PT_DYNAMIC;
-#endif
-	debug PT_NOTE;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-#if defined(SHLIB) || defined(DLEXE)
-	.rel.plt : {
-		*(.rel.plt);
-	}
-	/*
-	 *.rel.dyn MUST FOLLOW IMMEDIATELY after .rel.plt
-	 * without alignment gap or DT_REL will be broken
-	 */
-	.rel.dyn : {
-		*(.rel.*);
-	} :text
-
-	.plt : {
-		*(.plt);
-	} :text
-
-	.dynsym : {
-		*(.dynsym);
-	} :text
-
-	.dynstr : {
-		*(.dynstr);
-	} :text
-
-	.hash : {
-		*(.hash .gnu.hash);
-	} :text
-#endif
-
-#if defined(DLEXE)
-	.interp : {
-		*(.interp);
-	} :interp :text
-#endif
-
-	. = . + 0x1000;
-
-#if defined(SHLIB) || defined(DLEXE)
-	.dynamic : {
-		*(.dynamic);
-	} :data :dynamic
-#endif
-
-	.data : {
-		*(.data);
-	} :data
-
-#if defined(SHLIB) || defined(DLEXE)
-	.data.rel : {
-		*(.data.rel .data.rel.*);
-	} :data
-
-	.got : {
-		*(.got);
-	} :data
-#endif
-
-	.got.plt : {
-		*(.got.plt);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.dynbss);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-#ifdef CONFIG_LINE_DEBUG
-	.comment 0 : { *(.comment); } :debug
-	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
-	.debug_aranges 0 : { *(.debug_aranges); } :debug
-	.debug_info 0 : { *(.debug_info); } :debug
-	.debug_line 0 : { *(.debug_line); } :debug
-	.debug_loc 0 : { *(.debug_loc); } :debug
-	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
-	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
-	.debug_ranges 0 : { *(.debug_ranges); } :debug
-	.debug_str 0 : { *(.debug_str); } :debug
-#endif
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/ia64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ia64/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,69 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	/* Workaround proper alignment of the .init section */
-	. = ALIGN(., 16);
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x4000;
-
-	.got : {
-		/* Tell the linker where we expect GP to point. */
-		__gp = .;
-		*(.got .got.*);
-	} :data
-
-	.data : {
-		*(.opd);
-		*(.data .data.*);
-		*(.sdata);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.sbss);
-		*(.scommon);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/mips32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips32/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,67 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(__start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x4000;
-
-	.data : {
-		*(.data);
-		*(.data.rel*);
-	} :data
-
-	.got : {
-		_gp = .;
-		*(.got);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.sbss : {
-		*(.scommon);
-		*(.sbss);
-	}
-
-	.bss : {
-		*(.bss);
-		*(COMMON);
-	} :data
-
-	_end = .;
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/mips32eb/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips32eb/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../mips32/_link.ld.in
Index: uspace/lib/c/arch/ppc32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ppc32/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,72 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-	debug PT_NOTE;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x1000;
-
-	.data : {
-		*(.data);
-		*(.sdata);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.sbss);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-#ifdef CONFIG_LINE_DEBUG
-	.comment 0 : { *(.comment); } :debug
-	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
-	.debug_aranges 0 : { *(.debug_aranges); } :debug
-	.debug_info 0 : { *(.debug_info); } :debug
-	.debug_line 0 : { *(.debug_line); } :debug
-	.debug_loc 0 : { *(.debug_loc); } :debug
-	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
-	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
-	.debug_ranges 0 : { *(.debug_ranges); } :debug
-	.debug_str 0 : { *(.debug_str); } :debug
-#endif
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/riscv64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/riscv64/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,71 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-	debug PT_NOTE;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-		*(.srodata .srodata.*);
-	} :text
-
-	. = . + 0x1000;
-
-	.data : {
-		*(.data);
-		*(.sdata);
-		*(.data.rel*);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.scommon);
-		*(.sbss);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-#ifdef CONFIG_LINE_DEBUG
-	.comment 0 : { *(.comment); } :debug
-	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
-	.debug_aranges 0 : { *(.debug_aranges); } :debug
-	.debug_info 0 : { *(.debug_info); } :debug
-	.debug_line 0 : { *(.debug_line); } :debug
-	.debug_loc 0 : { *(.debug_loc); } :debug
-	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
-	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
-	.debug_ranges 0 : { *(.debug_ranges); } :debug
-	.debug_str 0 : { *(.debug_str); } :debug
-#endif
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/c/arch/sparc64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/sparc64/_link.ld.in	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ 	(revision )
@@ -1,76 +1,0 @@
-STARTUP(LIBC_PATH/arch/UARCH/src/entry.o)
-ENTRY(_start)
-
-PHDRS {
-	text PT_LOAD FILEHDR PHDRS FLAGS(5);
-	data PT_LOAD FLAGS(6);
-	tls PT_TLS;
-	debug PT_NOTE;
-}
-
-SECTIONS {
-#ifdef SHLIB
-	. = SEGMENT_START("text-segment", 0);
-#else
-	. = SEGMENT_START("text-segment", 0x400000);
-	PROVIDE (__executable_start = .);
-#endif
-	. = . + SIZEOF_HEADERS;
-
-	.init : {
-		*(.init);
-	} :text
-
-	.text : {
-		*(.text .text.*);
-		*(.rodata .rodata.*);
-	} :text
-
-	. = . + 0x4000;
-
-	.got : {
-		 *(.got*);
-	} :data
-
-	.data : {
-		*(.data);
-		*(.sdata);
-	} :data
-
-	.tdata : {
-		*(.tdata);
-		*(.tdata.*);
-		*(.gnu.linkonce.td.*);
-	} :data :tls
-
-	.tbss : {
-		*(.tbss);
-		*(.tbss.*);
-		*(.gnu.linkonce.tb.*);
-	} :data :tls
-
-	.bss : {
-		*(.sbss);
-		*(COMMON);
-		*(.bss);
-	} :data
-
-	_end = .;
-
-#ifdef CONFIG_LINE_DEBUG
-	.comment 0 : { *(.comment); } :debug
-	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
-	.debug_aranges 0 : { *(.debug_aranges); } :debug
-	.debug_info 0 : { *(.debug_info); } :debug
-	.debug_line 0 : { *(.debug_line); } :debug
-	.debug_loc 0 : { *(.debug_loc); } :debug
-	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
-	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
-	.debug_ranges 0 : { *(.debug_ranges); } :debug
-	.debug_str 0 : { *(.debug_str); } :debug
-#endif
-
-	/DISCARD/ : {
-		*(*);
-	}
-}
Index: uspace/lib/pcut/Makefile
===================================================================
--- uspace/lib/pcut/Makefile	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/lib/pcut/Makefile	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -36,4 +36,4 @@
 
 test-libpcut-%: $(LIBRARY).a
-	$(CC) $(CFLAGS) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $@ $(STARTUP) $^ $(LIBRARY).a $(BASE_LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(STARTUP_OBJECT) $^ $(LIBRARY).a $(BASE_LIBS)
 
Index: uspace/lib/pcut/update-from-master.sh
===================================================================
--- uspace/lib/pcut/update-from-master.sh	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/lib/pcut/update-from-master.sh	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -80,5 +80,5 @@
 
 test-libpcut-%: $(LIBRARY).a
-	$(CC) $(CFLAGS) $(LDFLAGS) -T $(LINKER_SCRIPT) -o $@ $(STARTUP) $^ $(LIBRARY).a $(BASE_LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(STARTUP_OBJECT) $^ $(LIBRARY).a $(BASE_LIBS)
 
 EOF_MAKEFILE_TAIL
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/lib/posix/Makefile	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -36,7 +36,5 @@
 
 SPECS = gcc.specs
-LIBC_LINKER_SCRIPT = $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld
-LIBC_STARTUP_FILE = $(shell sed -n -e 's/^.*STARTUP(\(.*\)).*$$/\1/p' $(LIBC_LINKER_SCRIPT))
-EXPORT_LINKER_SCRIPT = link.ld
+LIBC_STARTUP_FILE = $(STARTUP_OBJECT)
 EXPORT_STARTUP_FILE = crt0.o
 
@@ -49,5 +47,4 @@
 	$(LIBRARY).a \
 	$(EXPORT_STARTUP_FILE) \
-	$(EXPORT_LINKER_SCRIPT) \
 	$(SPECS)
 
@@ -55,5 +52,5 @@
 EXTRA_CLEAN = $(INCLUDE_LIBC)
 
-EXTRA_OUTPUT = $(SPECS) $(EXPORT_LINKER_SCRIPT) $(EXPORT_STARTUP_FILE)
+EXTRA_OUTPUT = $(SPECS) $(EXPORT_STARTUP_FILE)
 
 SOURCES = \
@@ -90,6 +87,5 @@
 
 EXPORT_LDFLAGS = \
-	-L$$(HELENOS_EXPORT_ROOT)/lib \
-	-T link.ld
+	-L$$(HELENOS_EXPORT_ROOT)/lib
 
 EXPORT_LDLIBS = \
@@ -111,7 +107,4 @@
 	echo '$(EXPORT_LDLIBS)' >> $@.new
 	mv $@.new $@
-
-$(EXPORT_LINKER_SCRIPT): $(LIBC_LINKER_SCRIPT)
-	sed 's/STARTUP(.*)/STARTUP(crt0.o)/' $< > $@
 
 $(EXPORT_STARTUP_FILE): $(LIBC_STARTUP_FILE)
Index: uspace/srv/loader/Makefile
===================================================================
--- uspace/srv/loader/Makefile	(revision 774aa33295605fdbbdcdc06516322c0665399f63)
+++ uspace/srv/loader/Makefile	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -29,6 +29,19 @@
 
 USPACE_PREFIX = ../..
+ROOT_PATH = $(USPACE_PREFIX)/..
+CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config
 
-EXTRA_LDFLAGS = -Wl,-Ttext-segment=0x70000000
+include $(CONFIG_MAKEFILE)
+
+ifeq ($(UARCH),ia64)
+	# IA64 has a peculiar linker script with a fixed data segment address.
+	# Because the loader is a separate nonrelocatable binary in the same
+	# address space as the application, we provide a modified copy of
+	# the default linker script to work around that.
+	EXTRA_LDFLAGS = -T elf64_ia64_loader.x
+else
+	# On all other architectures, we can simply move the text segment.
+	EXTRA_LDFLAGS = -Wl,-Ttext-segment=0x70000000
+endif
 
 BINARY = loader
Index: uspace/srv/loader/elf64_ia64_loader.x
===================================================================
--- uspace/srv/loader/elf64_ia64_loader.x	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
+++ uspace/srv/loader/elf64_ia64_loader.x	(revision a05ec6671002c451fceb01aa0ab3f71f004efb6d)
@@ -0,0 +1,263 @@
+/* Default linker script, for normal executables */
+/* Copyright (C) 2014-2018 Free Software Foundation, Inc.
+   Copying and distribution of this script, with or without modification,
+   are permitted in any medium without royalty provided the copyright
+   notice and this notice are preserved.  */
+OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little",
+	      "elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start)
+SEARCH_DIR("=/lib");
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x7FFF000000000000)); . = SEGMENT_START("text-segment", 0x7FFF000000000000) + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.init       : { *(.rel.init) }
+  .rela.init      : { *(.rela.init) }
+  .rel.text       : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
+  .rela.text      : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
+  .rel.fini       : { *(.rel.fini) }
+  .rela.fini      : { *(.rela.fini) }
+  .rel.rodata     : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
+  .rela.rodata    : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
+  .rel.data.rel.ro   : { *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) }
+  .rela.data.rel.ro   : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
+  .rel.data       : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+  .rela.data      : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
+  .rel.tdata	  : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
+  .rela.tdata	  : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
+  .rel.tbss	  : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
+  .rela.tbss	  : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
+  .rel.ctors      : { *(.rel.ctors) }
+  .rela.ctors     : { *(.rela.ctors) }
+  .rel.dtors      : { *(.rel.dtors) }
+  .rela.dtors     : { *(.rela.dtors) }
+  .rel.got        : { *(.rel.got) }
+  .rela.got       : { *(.rela.got) }
+  .rel.sdata      : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) }
+  .rela.sdata     : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) }
+  .rel.sbss       : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) }
+  .rela.sbss      : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) }
+  .rel.sdata2     : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) }
+  .rela.sdata2    : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) }
+  .rel.sbss2      : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) }
+  .rela.sbss2     : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
+  .rel.bss        : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+  .rela.bss       : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+  .rel.iplt       :
+    {
+      PROVIDE_HIDDEN (__rel_iplt_start = .);
+      *(.rel.iplt)
+      PROVIDE_HIDDEN (__rel_iplt_end = .);
+    }
+  .rela.iplt      :
+    {
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      *(.rela.iplt)
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  .rel.plt        :
+    {
+      *(.rel.plt)
+    }
+  .rela.plt       :
+    {
+      *(.rela.plt)
+    }
+  .rela.IA_64.pltoff   : { *(.rela.IA_64.pltoff) }
+  .init           :
+  {
+    KEEP (*(SORT_NONE(.init)))
+  } =0x00300000010070000002000001000400
+  .plt            : { *(.plt) }
+  .iplt           : { *(.iplt) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
+    *(.text.exit .text.exit.*)
+    *(.text.startup .text.startup.*)
+    *(.text.hot .text.hot.*)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x00300000010070000002000001000400
+  .fini           :
+  {
+    KEEP (*(SORT_NONE(.fini)))
+  } =0x00300000010070000002000001000400
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .sdata2         :
+  {
+    *(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
+  }
+  .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
+  .opd            : { *(.opd) }
+  .IA_64.unwind_info   : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) }
+  .IA_64.unwind   : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table
+  .gcc_except_table.*) }
+  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
+  /* These sections are generated by the Sun/Oracle C++ compiler.  */
+  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges
+  .exception_ranges*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
+  /* Thread Local Storage sections  */
+  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array     :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array     :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .got            : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+  .IA_64.pltoff   : { *(.IA_64.pltoff) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata          :
+  {
+    *(.sdata .sdata.* .gnu.linkonce.s.*)
+  }
+  _edata = .; PROVIDE (edata = .);
+  . = .;
+  __bss_start = .;
+  .sbss           :
+  {
+    *(.dynsbss)
+    *(.sbss .sbss.* .gnu.linkonce.sb.*)
+    *(.scommon)
+  }
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  . = ALIGN(64 / 8);
+  . = SEGMENT_START("ldata-segment", .);
+  . = ALIGN(64 / 8);
+  _end = .; PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end ) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  /* DWARF Extension.  */
+  .debug_macro    0 : { *(.debug_macro) }
+  .debug_addr     0 : { *(.debug_addr) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
+
