* [PATCH] Use ld's garbage collection feature
@ 2006-06-05 0:31 Marcelo Tosatti
2006-06-05 2:51 ` Dmitry Torokhov
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Marcelo Tosatti @ 2006-06-05 0:31 UTC (permalink / raw)
To: linux-kernel; +Cc: David Woodhouse, Arjan van de Ven
[-- Attachment #1: Type: text/plain, Size: 14502 bytes --]
Hi,
Usage of ld's -gc-sections with gcc's -ffunction-sections has
been discussed several times in the past, with a few proposals being
submitted but none being merged (don't know why since it is really
useful).
So, the following patch adds a CONFIG_GCSECTIONS option to make use of
it, allowing the linker to discard unreferenced sections.
There are two main differences from previous attempts:
- Makes use of "-print-gc-sections" option (patch to binutils attached).
- Do not discard symbols referenced by modules (via KEEP directive from
linker script).
- Splits ksymtab* section into one section per member, allowing the
linker to do the sweeping job when CONFIG_MODULES is set (otherwise
exported unused symbols have a reference to them from ksymtab* sections,
preventing garbage collection).
Current implementation requires "make modules" to be run before "make
vmlinux" (need to know what functions used by modules must be kept), but
thats just silly and should be fixed inside the Makefile.
TODO:
- Do the same as done for ksymtab* to kcrctab* (CONFIG_MODVERSIONS)
- Fixup end_rodata breakage (either move it outside generic
vmlinux.lds.h or find a way to get "#include" expansion working
recursively).
- Very likely that KEEP() has been missed from a few unusual
sections.
- Recursive make invocation from Makefile is sort of ugly.
Results:
This config
http://hera.kernel.org/~marcelo/gcsections/config-test-gcsections
results in
http://hera.kernel.org/~marcelo/gcsections/dropped_sections.txt
sections being dropped.
vmlinux shrinks from 1090389 to 983933 bytes, or 106k (~= 10%).
I would like to see some equivalent of this merged, since its
_very_ useful. There are _many_ helper functions used by specific
configurations which can just be wasted completly from most builds.
For example
mm/built-in.o:.text.free_pages_and_swap_cache (only used by x86_64)
fs/built-in.o:.text.ilookup5_nowait
fs/built-in.o:.text.ilookup5 (only used by OCFS2 and VFAT)
kernel/built-in.o:.text.kallsyms_lookup_name (only used by PPC)
mm/built-in.o:.text.free_cold_page (unused!)
(check dropped_sections.txt for more fun)
Comments are welcome!
diff --git a/Makefile b/Makefile
index 3494c17..45c3f4e 100644
--- a/Makefile
+++ b/Makefile
@@ -571,11 +571,20 @@ vmlinux-lds := arch/$(ARCH)/kernel/vmli
# Rule to link vmlinux - also used during CONFIG_KALLSYMS
# May be overridden by arch/$(ARCH)/Makefile
+ifndef CONFIG_GCSECTIONS
quiet_cmd_vmlinux__ ?= LD $@
cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
-T $(vmlinux-lds) $(vmlinux-init) \
--start-group $(vmlinux-main) --end-group \
$(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
+else
+quiet_cmd_vmlinux__ ?= LD $@
+ cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \
+ -T $(vmlinux-lds) $(vmlinux-init) \
+ --start-group $(vmlinux-main) --end-group \
+ > arch/$(ARCH)/dropped_sections.txt \
+ $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
+endif
# Generate new vmlinux version
quiet_cmd_vmlinux_version = GEN .version
@@ -593,6 +602,27 @@ # Generate System.map
quiet_cmd_sysmap = SYSMAP
cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
+ifdef CONFIG_GCSECTIONS
+# Find undefined symbols inside modules, and add them to the linker
+# script with KEEP directive. Then rebuild the kernel.
+
+define update_used_symbols
+ $(Q)if [ $(MAKELEVEL) -eq "0" ]; then \
+ find . -name "*.ko" -exec nm {} \; |grep "U "|cut -f2 -dU | \
+ sed -e "s/ //g" > arch/$(ARCH)/undef_module_syms.txt; \
+ grep .text arch/$(ARCH)/dropped_sections.txt | sed -e s/.*://g \
+ > arch/$(ARCH)/drop_strip.txt; \
+ rm -f arch/$(ARCH)/kernel/vmlinux.ldskeep.h; \
+ cat arch/$(ARCH)/undef_module_syms.txt | while read line ; do \
+ egrep "$$line$$" arch/$(ARCH)/drop_strip.txt | \
+ while read L ; do echo KEEP\(*\($$L\)\) ; done \
+ >> arch/$(ARCH)/kernel/vmlinux.ldskeep.h ; true ; done; \
+ sh scripts/ksymbols-gen-keep.sh $(ARCH); \
+ GC_REBUILD_PASS=true $(MAKE) vmlinux \
+ ;fi
+endef
+endif
+
# Link of vmlinux
# If CONFIG_KALLSYMS is set .version is already updated
# Generate System.map and verify that the content is consistent
@@ -605,6 +635,8 @@ define rule_vmlinux__
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
+ $(update_used_symbols)
+
$(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) System.map' &&) \
$(cmd_sysmap) $@ System.map; \
@@ -803,8 +835,21 @@ archprepare: prepare1 scripts_basic
prepare0: archprepare FORCE
$(Q)$(MAKE) $(build)=.
+
+create_keep_files := keep.ksymstrings.txt keep.ksymtab.txt keep.ksymtabgpl.txt \
+ vmlinux.ldskeep.h
+
+create_keep_lists:
+ifndef GC_REBUILD_PASS
+ $(Q)$(foreach f, $(create_keep_files), \
+ rm -f arch/$(ARCH)/kernel/$(f); \
+ touch arch/$(ARCH)/kernel/$(f); \
+ )
+endif
+
# All the preparing..
-prepare prepare-all: prepare0
+prepare prepare-all: prepare0 create_keep_lists
+
# Leave this as default for preprocessing vmlinux.lds.S, which is now
# done in arch/$(ARCH)/kernel/Makefile
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 8dfa305..4a60635 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -691,6 +691,12 @@ config REGPARM
If unsure, say Y.
+config GCSECTIONS
+ bool "Garbage collect unused sections"
+ default n
+ help
+ Use ld's --gc-sections option to garbage collect unused sections.
+
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 3e4adb1..1a2da0d 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -24,9 +24,11 @@ LD := $(LD) -m elf_i386
CC := $(CC) -m32
endif
+ldflags-$(CONFIG_GCSECTIONS) += --gc-sections --print-gc-sections
+
LDFLAGS := -m elf_i386
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
-LDFLAGS_vmlinux :=
+LDFLAGS_vmlinux := $(ldflags-y)
CHECKFLAGS += -D__i386__
CFLAGS += -pipe -msoft-float
@@ -39,6 +41,8 @@ include $(srctree)/arch/i386/Makefile.cp
cflags-$(CONFIG_REGPARM) += -mregparm=3
+cflags-$(CONFIG_GCSECTIONS) += -ffunction-sections
+
# temporary until string.h is fixed
cflags-y += -ffreestanding
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 8831303..8c2cb26 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -21,6 +21,7 @@ SECTIONS
_text = .; /* Text and read-only data */
.text : AT(ADDR(.text) - LOAD_OFFSET) {
*(.text)
+ #include "vmlinux.ldskeep.h"
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
@@ -32,11 +33,30 @@ SECTIONS
. = ALIGN(16); /* Exception table */
__start___ex_table = .;
- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { KEEP(*(__ex_table)) }
__stop___ex_table = .;
RODATA
+ /* Kernel symbol table: Normal symbols */
+ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) {
+ VMLINUX_SYMBOL(__start___ksymtab) = .;
+ #include "keep.ksymtab.txt"
+ VMLINUX_SYMBOL(__stop___ksymtab) = .;
+ }
+
+ /* Kernel symbol table: GPL-only symbols */
+ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {
+ VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;
+ #include "keep.ksymtabgpl.txt"
+ VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;
+ }
+
+ /* Kernel symbol table: strings */
+ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {
+ #include "keep.ksymstrings.txt"
+ }
+
/* writeable */
.data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
*(.data)
@@ -74,7 +94,7 @@ SECTIONS
__smp_alt_begin = .;
__smp_alt_instructions = .;
.smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
- *(.smp_altinstructions)
+ KEEP(*(.smp_altinstructions))
}
__smp_alt_instructions_end = .;
. = ALIGN(4);
@@ -84,7 +104,7 @@ SECTIONS
}
__smp_locks_end = .;
.smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
- *(.smp_altinstr_replacement)
+ KEEP(*(.smp_altinstr_replacement))
}
. = ALIGN(4096);
__smp_alt_end = .;
@@ -100,33 +120,33 @@ SECTIONS
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
. = ALIGN(16);
__setup_start = .;
- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { KEEP(*(.init.setup)) }
__setup_end = .;
__initcall_start = .;
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ KEEP(*(.initcall1.init))
+ KEEP(*(.initcall2.init))
+ KEEP(*(.initcall3.init))
+ KEEP(*(.initcall4.init))
+ KEEP(*(.initcall5.init))
+ KEEP(*(.initcall6.init))
+ KEEP(*(.initcall7.init))
}
__initcall_end = .;
__con_initcall_start = .;
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
- *(.con_initcall.init)
+ KEEP(*(.con_initcall.init))
}
__con_initcall_end = .;
SECURITY_INIT
. = ALIGN(4);
__alt_instructions = .;
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
- *(.altinstructions)
+ KEEP(*(.altinstructions))
}
__alt_instructions_end = .;
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
- *(.altinstr_replacement)
+ KEEP(*(.altinstr_replacement))
}
/* .exit.text is discard at runtime, not link time, to deal with references
from .altinstructions and .eh_frame */
@@ -134,7 +154,7 @@ SECTIONS
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
. = ALIGN(4096);
__initramfs_start = .;
- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { KEEP(*(.init.ramfs)) }
__initramfs_end = .;
. = ALIGN(L1_CACHE_BYTES);
__per_cpu_start = .;
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9d11550..a967c04 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -24,16 +24,16 @@ #define RODATA \
/* PCI quirks */ \
.pci_fixup : AT(ADDR(.pci_fixup) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_pci_fixups_early) = .; \
- *(.pci_fixup_early) \
+ KEEP(*(.pci_fixup_early)) \
VMLINUX_SYMBOL(__end_pci_fixups_early) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_header) = .; \
- *(.pci_fixup_header) \
+ KEEP(*(.pci_fixup_header)) \
VMLINUX_SYMBOL(__end_pci_fixups_header) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_final) = .; \
- *(.pci_fixup_final) \
+ KEEP(*(.pci_fixup_final)) \
VMLINUX_SYMBOL(__end_pci_fixups_final) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
- *(.pci_fixup_enable) \
+ KEEP(*(.pci_fixup_enable)) \
VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
} \
\
@@ -96,7 +96,7 @@ #define RODATA \
/* Built-in module parameters. */ \
__param : AT(ADDR(__param) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___param) = .; \
- *(__param) \
+ KEEP(*(__param)) \
VMLINUX_SYMBOL(__stop___param) = .; \
}
diff --git a/include/linux/module.h b/include/linux/module.h
index eaec13d..4675cc0 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -181,6 +181,7 @@ #else
#define __CRC_SYMBOL(sym, sec)
#endif
+#ifndef CONFIG_GCSECTIONS
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
@@ -193,6 +194,24 @@ #define __EXPORT_SYMBOL(sym, sec) \
__attribute__((section("__ksymtab" sec), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
+#else
+/* For garbage collection, each symbol has its own
+ __ksymtab and __kstrtab section, which are later merged into
+ single ones.
+ */
+#define __EXPORT_SYMBOL(sym, sec) \
+ extern typeof(sym) sym; \
+ __CRC_SYMBOL(sym, sec) \
+ static const char __kstrtab_##sym[] \
+ __attribute__((section("__ksymtab_strings_" #sym))) \
+ = MODULE_SYMBOL_PREFIX #sym; \
+ static const struct kernel_symbol __ksymtab_##sym \
+ __attribute_used__ \
+ __attribute__((section("___ksymtab_" #sym sec), unused))\
+ = { (unsigned long)&sym, __kstrtab_##sym }
+
+#endif
+
#define EXPORT_SYMBOL(sym) \
__EXPORT_SYMBOL(sym, "")
diff --git a/scripts/ksymbols-gen-keep.sh b/scripts/ksymbols-gen-keep.sh
new file mode 100755
index 0000000..3f9fb9b
--- /dev/null
+++ b/scripts/ksymbols-gen-keep.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# Add symbols from special sections ksymtab,ksymtab_strings,ksymtab_gpl
+# which we do not want to be discarded into one linker script per
+# special section.
+#
+
+ARCH=$1
+
+rm -f vmlinux.nm
+nm vmlinux | grep "T " | cut -f 2 -d T | while read line
+ do echo "$line" >> vmlinux.nm
+done
+
+nm vmlinux | grep "D " | cut -f 2 -d D | while read line
+ do echo "$line" >> vmlinux.nm
+done
+
+nm vmlinux | grep "B " | cut -f 2 -d B | while read line
+ do echo "$line" >> vmlinux.nm
+done
+
+cat arch/$ARCH/kernel/vmlinux.ldskeep.h | while read line
+ do sed -e s/"KEEP(\*(.text."//g -e s/"))$"//g
+done >> vmlinux.nm
+
+# ksymtab_strings
+cat arch/$ARCH/dropped_sections.txt | sed -e "s/.*:__ksymtab_strings_//g" | \
+grep -v : | while read line
+ do grep $line$ vmlinux.nm
+done > keep.ksymstrings
+
+cat keep.ksymstrings | while read line ; do
+ echo KEEP\(*\("__ksymtab_strings_$line"\)\)
+done > keep.ksymstrings.txt
+
+# ksymtab
+egrep -v "ksymtab_strings|ksymtab_.*_gpl" arch/$ARCH/dropped_sections.txt | \
+sed -e "s/.*:___ksymtab_//g" | grep -v ":" | while read line
+ do grep $line$ vmlinux.nm
+done > keep.ksymtab
+
+cat keep.ksymtab | while read line
+ do echo "KEEP(*(___ksymtab_$line))"
+done > keep.ksymtab.txt
+
+# ksymtab gpl
+egrep "ksymtab_.*_gpl" arch/$ARCH/dropped_sections.txt | \
+sed -e "s/.*://g" -e s/___ksymtab_//g -e s/_gpl$//g | while read line
+ do grep $line$ vmlinux.nm
+done > keep.ksymtabgpl
+
+cat keep.ksymtabgpl | while read line
+ do echo KEEP\(*\(___ksymtab_"$line"_gpl\)\)
+done > keep.ksymtabgpl.txt
+
+rm -f keep.ksymstrings keep.ksymtab keep.ksymtabgpl
+
+mv keep.*.txt arch/$ARCH/kernel/
[-- Attachment #2: binutils-gc-print.patch --]
[-- Type: text/plain, Size: 2465 bytes --]
--- ./ld/ldmain.c.orig 2006-05-21 17:18:46.000000000 -0300
+++ ./ld/ldmain.c 2006-05-21 17:18:55.000000000 -0300
@@ -316,6 +316,7 @@ main (int argc, char **argv)
link_info.relax_pass = 1;
link_info.warn_shared_textrel = FALSE;
link_info.gc_sections = FALSE;
+ link_info.print_gc_sections = FALSE;
ldfile_add_arch ("");
--- ./ld/lexsup.c.orig 2006-05-21 17:06:21.000000000 -0300
+++ ./ld/lexsup.c 2006-05-21 17:18:27.000000000 -0300
@@ -124,6 +124,7 @@ enum option_values
OPTION_FORCE_EXE_SUFFIX,
OPTION_GC_SECTIONS,
OPTION_NO_GC_SECTIONS,
+ OPTION_PRINT_GC_SECTIONS,
OPTION_HASH_SIZE,
OPTION_CHECK_SECTIONS,
OPTION_NO_CHECK_SECTIONS,
@@ -370,6 +371,9 @@ static const struct ld_option ld_options
{ {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS},
'\0', NULL, N_("Don't remove unused sections (default)"),
TWO_DASHES },
+ { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS},
+ '\0', NULL, N_("Print removed unused sections"),
+ TWO_DASHES },
{ {"hash-size=<NUMBER>", required_argument, NULL, OPTION_HASH_SIZE},
'\0', NULL, N_("Set default hash table size close to <NUMBER>"),
TWO_DASHES },
@@ -812,6 +816,9 @@ parse_args (unsigned argc, char **argv)
case OPTION_GC_SECTIONS:
link_info.gc_sections = TRUE;
break;
+ case OPTION_PRINT_GC_SECTIONS:
+ link_info.print_gc_sections = TRUE;
+ break;
case OPTION_HELP:
help ();
xexit (0);
--- ./include/bfdlink.h.orig 2006-05-21 17:16:54.000000000 -0300
+++ ./include/bfdlink.h 2006-05-21 17:17:21.000000000 -0300
@@ -324,6 +324,9 @@ struct bfd_link_info
/* TRUE if unreferenced sections should be removed. */
unsigned int gc_sections: 1;
+ /* TRUE if should print removed unreferenced sections. */
+ unsigned int print_gc_sections: 1;
+
/* What to do with unresolved symbols in an object file.
When producing executables the default is GENERATE_ERROR.
When producing shared libraries the default is IGNORE. The
--- ./bfd/elflink.c.orig 2006-05-21 17:20:57.000000000 -0300
+++ ./bfd/elflink.c 2006-05-21 18:41:19.000000000 -0300
@@ -8978,6 +8978,9 @@ elf_gc_sweep (bfd *abfd, struct bfd_link
to remove a section from the output. */
o->flags |= SEC_EXCLUDE;
+ if (info->print_gc_sections == TRUE)
+ printf("%s:%s\n", sub->filename, o->name);
+
/* But we also have to update some of the relocation
info we collected before. */
if (gc_sweep_hook
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 0:31 [PATCH] Use ld's garbage collection feature Marcelo Tosatti
@ 2006-06-05 2:51 ` Dmitry Torokhov
2006-06-05 14:35 ` Marcelo Tosatti
2006-06-05 8:22 ` David Woodhouse
2006-06-05 10:03 ` David Woodhouse
2 siblings, 1 reply; 7+ messages in thread
From: Dmitry Torokhov @ 2006-06-05 2:51 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-kernel, David Woodhouse, Arjan van de Ven
On Sunday 04 June 2006 20:31, Marcelo Tosatti wrote:
> Current implementation requires "make modules" to be run before "make
> vmlinux" (need to know what functions used by modules must be kept), but
>
How will it work with out of tree modules? Or even modules one decides
to add later and use without rebooting?
--
Dmitry
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 2:51 ` Dmitry Torokhov
@ 2006-06-05 14:35 ` Marcelo Tosatti
0 siblings, 0 replies; 7+ messages in thread
From: Marcelo Tosatti @ 2006-06-05 14:35 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-kernel, David Woodhouse, Arjan van de Ven
On Sun, Jun 04, 2006 at 10:51:45PM -0400, Dmitry Torokhov wrote:
> On Sunday 04 June 2006 20:31, Marcelo Tosatti wrote:
> > Current implementation requires "make modules" to be run before "make
> > vmlinux" (need to know what functions used by modules must be kept), but
> >
>
> How will it work with out of tree modules? Or even modules one decides
> to add later and use without rebooting?
Right, exported symbols must be kept in that case. An extra option to
enable exported symbol gc as dwmw2 suggests should do the trick.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 0:31 [PATCH] Use ld's garbage collection feature Marcelo Tosatti
2006-06-05 2:51 ` Dmitry Torokhov
@ 2006-06-05 8:22 ` David Woodhouse
2006-06-05 10:03 ` David Woodhouse
2 siblings, 0 replies; 7+ messages in thread
From: David Woodhouse @ 2006-06-05 8:22 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-kernel, Arjan van de Ven
On Sun, 2006-06-04 at 21:31 -0300, Marcelo Tosatti wrote:
> - Do not discard symbols referenced by modules (via KEEP directive
> from linker script).
I think we should keep _all_ symbols which are exported, except perhaps
if some _extra_ config option hidden behing CONFIG_EMBEDDED is set. It
isn't acceptable to break the case of modules which you build only later
or out-of-tree.
I also want to play with '-fwhole-program --combine'. There's currently
a compiler bug with --combine getting on my tits, but if you #include
the whole of fs/jffs2/*.c or fs/ext3/*.c from one file and build that
with -fwhole-program, you also see a fair amount of benefit.
That would also render a certain amount of the gc-sections improvements
obsolete, although we can't use -fwhole-program in core code; only 'leaf
object' like drivers and filesystems so I think gc-sections is still
going to be a win.
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 0:31 [PATCH] Use ld's garbage collection feature Marcelo Tosatti
2006-06-05 2:51 ` Dmitry Torokhov
2006-06-05 8:22 ` David Woodhouse
@ 2006-06-05 10:03 ` David Woodhouse
2006-06-05 14:36 ` Marcelo Tosatti
2 siblings, 1 reply; 7+ messages in thread
From: David Woodhouse @ 2006-06-05 10:03 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-kernel, Arjan van de Ven
On Sun, 2006-06-04 at 21:31 -0300, Marcelo Tosatti wrote:
> +cflags-$(CONFIG_GCSECTIONS) += -ffunction-sections
Any reason you didn't also use -fdata-sections?
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 10:03 ` David Woodhouse
@ 2006-06-05 14:36 ` Marcelo Tosatti
2006-06-05 14:48 ` David Woodhouse
0 siblings, 1 reply; 7+ messages in thread
From: Marcelo Tosatti @ 2006-06-05 14:36 UTC (permalink / raw)
To: David Woodhouse; +Cc: linux-kernel, Arjan van de Ven
On Mon, Jun 05, 2006 at 11:03:42AM +0100, David Woodhouse wrote:
> On Sun, 2006-06-04 at 21:31 -0300, Marcelo Tosatti wrote:
> > +cflags-$(CONFIG_GCSECTIONS) += -ffunction-sections
>
> Any reason you didn't also use -fdata-sections?
Not really - will try.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Use ld's garbage collection feature
2006-06-05 14:36 ` Marcelo Tosatti
@ 2006-06-05 14:48 ` David Woodhouse
0 siblings, 0 replies; 7+ messages in thread
From: David Woodhouse @ 2006-06-05 14:48 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-kernel, Arjan van de Ven
On Mon, 2006-06-05 at 11:36 -0300, Marcelo Tosatti wrote:
> On Mon, Jun 05, 2006 at 11:03:42AM +0100, David Woodhouse wrote:
> > On Sun, 2006-06-04 at 21:31 -0300, Marcelo Tosatti wrote:
> > > +cflags-$(CONFIG_GCSECTIONS) += -ffunction-sections
> >
> > Any reason you didn't also use -fdata-sections?
>
> Not really - will try.
Btw, I filed two gcc bugs for the (first) things which prevent us from
building stuff like filesystems with something like
'gcc -fwhole-program --combine fs/jffs2/*.c'
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27898
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27899
--
dwmw2
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-06-05 14:48 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-05 0:31 [PATCH] Use ld's garbage collection feature Marcelo Tosatti
2006-06-05 2:51 ` Dmitry Torokhov
2006-06-05 14:35 ` Marcelo Tosatti
2006-06-05 8:22 ` David Woodhouse
2006-06-05 10:03 ` David Woodhouse
2006-06-05 14:36 ` Marcelo Tosatti
2006-06-05 14:48 ` David Woodhouse
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox