Skip to content

Commit

Permalink
makefile: enable garbage collection of code and data when hiding symbols
Browse files Browse the repository at this point in the history
This patch changes the main makefile to enable garbage collection of
code and data when linking kernel with most symbols hidden.

In essence it makes all object files compile with '-ffunction-sections
-fdata-sections' flags only when conf_hide_symbols is ON. This allows
linker to eliminate code and data (with --gc-sections) that is not
really used between various compilation units. As the result it allows
us to produce even smaller kernel ELF at around 4.3M, down from 5.1M
when we would hide symbols only. In order to see what exact code and
data gets eliminated, one can pass --print-gc-sections flags to the
linker like so:

./scripts/build image=native-example fs=rofs conf_hide_symbols=1 conf_linker_extra_options=--print-gc-sections

In addition this patch also changes the makefile to make linker use
version script generated by ./scripts/generate_version_script.sh which
is obnly enabled when conf_hide_symbols is ON. Using version script
(--version-script) plays some role in futher reducing number of symbols
down to what exactly we want to export in exported/<arch>/*symbols.

Signed-off-by: Waldemar Kozaczuk <[email protected]>
  • Loading branch information
wkozaczuk committed Dec 13, 2021
1 parent dee5a70 commit 730fd82
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
19 changes: 13 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ $(out)/libc/%.o: cc-hide-flags =
$(out)/libc/%.o: cxx-hide-flags =
$(out)/musl/%.o: cc-hide-flags =

kernel-defines = -D_KERNEL $(source-dialects) $(cc-hide-flags)
kernel-defines = -D_KERNEL $(source-dialects) $(cc-hide-flags) $(gc-flags)

# This play the same role as "_KERNEL", but _KERNEL unfortunately is too
# overloaded. A lot of files will expect it to be set no matter what, specially
Expand Down Expand Up @@ -323,6 +323,10 @@ cxx-hide-flags-0 =
cxx-hide-flags-1 = -fvisibility-inlines-hidden
cxx-hide-flags = $(cxx-hide-flags-$(conf_hide_symbols))

gc-flags-0 =
gc-flags-1 = -ffunction-sections -fdata-sections
gc-flags = $(gc-flags-$(conf_hide_symbols))

gcc-opt-Og := $(call compiler-flag, -Og, -Og, compiler/empty.cc)

CXXFLAGS = -std=gnu++11 $(COMMON) $(cxx-hide-flags)
Expand Down Expand Up @@ -1944,7 +1948,7 @@ $(out)/dummy-shlib.so: $(out)/dummy-shlib.o
$(call quiet, $(CXX) -nodefaultlibs -shared $(gcc-sysroot) -o $@ $^, LINK $@)

stage1_targets = $(out)/arch/$(arch)/boot.o $(out)/loader.o $(out)/runtime.o $(drivers:%=$(out)/%) $(objects:%=$(out)/%) $(out)/dummy-shlib.so
stage1: $(stage1_targets) links
stage1: $(stage1_targets) links $(out)/version_script
.PHONY: stage1

loader_options_dep = $(out)/arch/$(arch)/loader_options.ld
Expand All @@ -1955,17 +1959,21 @@ $(loader_options_dep): stage1
fi

ifeq ($(conf_hide_symbols),1)
linker_archives_options = --no-whole-archive $(libstdc++.a) $(libgcc.a) $(libgcc_eh.a) $(boost-libs) --exclude-libs libstdc++.a
linker_archives_options = --no-whole-archive $(libstdc++.a) $(libgcc.a) $(libgcc_eh.a) $(boost-libs) \
--exclude-libs libstdc++.a --gc-sections --version-script=$(out)/version_script
else
linker_archives_options = --whole-archive $(libstdc++.a) $(libgcc_eh.a) $(boost-libs) --no-whole-archive $(libgcc.a)
endif

$(out)/version_script: exported_symbols/$(arch)/*.symbols
$(call quiet, scripts/generate_version_script.sh $(out)/version_script, GEN version_script)

$(out)/loader.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/bootfs.o $(loader_options_dep)
$(call quiet, $(LD) -o $@ --defsym=OSV_KERNEL_BASE=$(kernel_base) \
--defsym=OSV_KERNEL_VM_BASE=$(kernel_vm_base) --defsym=OSV_KERNEL_VM_SHIFT=$(kernel_vm_shift) \
-Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags -L$(out)/arch/$(arch) \
$(^:%.ld=-T %.ld) \
$(linker_archives_options), \
$(linker_archives_options) $(conf_linker_extra_options), \
LINK loader.elf)
@# Build libosv.so matching this loader.elf. This is not a separate
@# rule because that caused bug #545.
Expand All @@ -1978,10 +1986,9 @@ $(out)/kernel.elf: $(stage1_targets) arch/$(arch)/loader.ld $(out)/empty_bootfs.
--defsym=OSV_KERNEL_VM_BASE=$(kernel_vm_base) --defsym=OSV_KERNEL_VM_SHIFT=$(kernel_vm_shift) \
-Bdynamic --export-dynamic --eh-frame-hdr --enable-new-dtags -L$(out)/arch/$(arch) \
$(^:%.ld=-T %.ld) \
$(linker_archives_options), \
$(linker_archives_options) $(conf_linker_extra_options), \
LINK kernel.elf)
$(call quiet, $(STRIP) $(out)/kernel.elf -o $(out)/kernel-stripped.elf, STRIP kernel.elf -> kernel-stripped.elf )
$(call very-quiet, cp $(out)/kernel-stripped.elf $(out)/kernel.elf)

$(out)/bsd/%.o: COMMON += -DSMP -D'__FBSDID(__str__)=extern int __bogus__'

Expand Down
1 change: 1 addition & 0 deletions conf/base.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ conf-DEBUG_BUILD=0

conf-debug_elf=0
conf_hide_symbols=0
conf_linker_extra_options=

0 comments on commit 730fd82

Please sign in to comment.