Generalize ABI mechanism to shared objects

This patch make the ABI mechanism available to shared libraries other
than Genode's dynamic linker. It thereby allows us to introduce
intermediate ABIs at the granularity of shared libraries. This is useful
for slow-moving ABIs such as the libc's interface but it will also
become handy for the package management.

To implement the feature, the build system had to be streamlined a bit.
In particular, archive dependencies and shared-lib dependencies are now
handled separately, and the global list of 'SHARED_LIBS' is no more.
Now, the variable with the same name holds the per-target list of shared
libraries used by the target.
This commit is contained in:
Norman Feske 2016-12-29 18:27:45 +01:00
parent eb6f7e74cc
commit 3d7b92ea50
34 changed files with 271 additions and 216 deletions

View File

@ -42,7 +42,7 @@ INC_DIR += $(REP_DIR)/src/core/include \
$(REP_DIR)/src/include \
$(BASE_DIR)/src/include
LIBS += base-fiasco-common syscall-fiasco
LIBS += base-fiasco-common syscall-fiasco cxx
include $(GEN_CORE_DIR)/version.inc

View File

@ -1,6 +1,6 @@
include $(BASE_DIR)/lib/mk/base.inc
LIBS += base-foc-common syscall-foc
LIBS += base-foc-common syscall-foc cxx
SRC_CC += cap_map_remove.cc cap_alloc.cc
SRC_CC += thread_start.cc

View File

@ -1,6 +1,6 @@
GEN_CORE_DIR = $(BASE_DIR)/src/core
LIBS += base-foc-common syscall-foc
LIBS += base-foc-common syscall-foc cxx
SRC_CC += stack_area.cc \
core_log.cc \

View File

@ -4,7 +4,7 @@
# \date 2011-12-16
#
LIBS += core-hw-perf_counter base-hw-common
LIBS += core-hw-perf_counter base-hw-common cxx
# add include paths
INC_DIR += $(BASE_DIR)/../base-hw/src/core/include

View File

@ -7,4 +7,4 @@ include $(BASE_DIR)/lib/mk/base.inc
SRC_CC += platform_env.cc
LIBS += syscall-linux cxx
LIBS += syscall-linux

View File

@ -1,5 +1,5 @@
include $(BASE_DIR)/lib/mk/base.inc
LIBS += base-nova-common
LIBS += base-nova-common cxx
SRC_CC += thread_start.cc
SRC_CC += cache.cc

View File

@ -1,4 +1,4 @@
LIBS = base-nova-common
LIBS = base-nova-common cxx
GEN_CORE_DIR = $(BASE_DIR)/src/core

View File

@ -21,6 +21,7 @@ CC_OPT += -pipe \
-freorder-blocks -funit-at-a-time -fno-exceptions -fno-rtti \
-fno-stack-protector -fvisibility-inlines-hidden \
-fno-asynchronous-unwind-tables -std=gnu++0x
CC_OPT_PIC :=
ifeq ($(filter-out $(SPECS),32bit),)
CC_WARN += -Wframe-larger-than=92
CC_OPT += -mpreferred-stack-boundary=2 -mregparm=3

View File

@ -1,6 +1,6 @@
CC_OPT_PIC =
LIBS += okl4_boot_info base-okl4-common syscall-okl4
LIBS += okl4_boot_info base-okl4-common syscall-okl4 cxx
GEN_CORE_DIR = $(BASE_DIR)/src/core

View File

@ -1,6 +1,6 @@
include $(BASE_DIR)/lib/mk/base.inc
LIBS += base-pistachio-common syscall-pistachio
LIBS += base-pistachio-common syscall-pistachio cxx
SRC_CC += thread_start.cc
SRC_CC += cache.cc

View File

@ -1,4 +1,4 @@
LIBS = base-pistachio-common syscall-pistachio
LIBS = base-pistachio-common syscall-pistachio cxx
GEN_CORE_DIR = $(BASE_DIR)/src/core

View File

@ -36,7 +36,7 @@ SRC_CC += \
capability_space.cc \
pager.cc
LIBS += base-sel4-common syscall-sel4
LIBS += base-sel4-common syscall-sel4 cxx
INC_DIR += $(REP_DIR)/src/core/include $(GEN_CORE_DIR)/include \
$(REP_DIR)/src/include $(BASE_DIR)/src/include

View File

@ -4,8 +4,6 @@
# \date 2013-02-14
#
LIBS += cxx
SRC_CC += avl_tree.cc
SRC_CC += slab.cc
SRC_CC += allocator_avl.cc

View File

@ -1,5 +1,5 @@
#
# Generic ld.lib.so stub library
# Generic ld.lib.so ABI stub library
#
# This library is used to build kernel-independent dynamically linked
# executables. It does not contain any code or data but only the symbol
@ -9,27 +9,7 @@
# time, it is transparently replaced by the variant of the dynamic linker that
# matches the used kernel.
#
# The rule for generating 'symbols.s' is defined in the architecture-dependent
# 'spec/<architecture>/ld.mk' file.
#
SRC_S := symbols.s
SYMBOLS := $(BASE_DIR)/lib/symbols/ld
SHARED_LIB := yes
LD_OPT += -T$(BASE_DIR)/src/lib/ldso/linker.ld
symbols.s: $(MAKEFILE_LIST)
symbols.s: $(SYMBOLS)
$(MSG_CONVERT)$@
$(VERBOSE)\
sed -e "s/^\(\w\+\) D \(\w\+\)\$$/.data; .global \1; .type \1,%object; .size \1,\2; \1:/p" \
-e "s/^\(\w\+\) V/.data; .weak \1; .type \1,%object; \1:/p" \
-e "s/^\(\w\+\) T/.text; .global \1; .type \1,%function; \1:/p" \
-e "s/^\(\w\+\) R/.section .rodata; .global \1; \1:/p" \
-e "s/^\(\w\+\) W/.text; .weak \1; .type \1,%function; \1:/p" \
-e "s/^\(\w\+\) B/.bss; .global \1; .type \1,%object; \1:/p" \
$(SYMBOLS) > $@

View File

@ -184,8 +184,8 @@ _ZN6Genode18Signal_transmitterC1ENS_10CapabilityINS_14Signal_contextEEE T
_ZN6Genode18Signal_transmitterC2ENS_10CapabilityINS_14Signal_contextEEE T
_ZN6Genode18server_socket_pairEv T
_ZN6Genode20env_session_id_spaceEv T
_ZN6Genode25env_stack_area_region_mapE B
_ZN6Genode26env_stack_area_ram_sessionE B
_ZN6Genode25env_stack_area_region_mapE B 4
_ZN6Genode26env_stack_area_ram_sessionE B 4
_ZN6Genode29upgrade_pd_quota_non_blockingEm T
_ZN6Genode3Log3logEv T
_ZN6Genode3Log8_acquireENS0_4TypeE T
@ -618,8 +618,8 @@ dl_iterate_phdr T
dl_unwind_find_exidx T
genode_argc D 4
genode_argv D 8
genode_envp B
lx_environ B
genode_envp B 4
lx_environ B 4
memcpy W
memmove W
memset W

View File

@ -38,12 +38,14 @@ endif
append_lib_to_progress_log:
@echo "LIBS_READY += $(LIB)" >> $(LIB_PROGRESS_LOG)
LIB_MK_DIRS = $(foreach REP,$(REPOSITORIES),$(addprefix $(REP)/lib/mk/spec/,$(SPECS)) $(REP)/lib/mk)
LIB_MK_DIRS = $(foreach REP,$(REPOSITORIES),$(addprefix $(REP)/lib/mk/spec/, $(SPECS)) $(REP)/lib/mk)
SYMBOLS_DIRS = $(foreach REP,$(REPOSITORIES),$(addprefix $(REP)/lib/symbols/spec/,$(SPECS)) $(REP)/lib/symbols)
#
# Of all possible file locations, use the (first) one that actually exist.
#
LIB_MK = $(firstword $(wildcard $(addsuffix /$(LIB).mk,$(LIB_MK_DIRS))))
LIB_MK = $(firstword $(wildcard $(addsuffix /$(LIB).mk,$(LIB_MK_DIRS))))
SYMBOLS = $(firstword $(wildcard $(addsuffix /$(LIB), $(SYMBOLS_DIRS))))
#
# Sanity check to detect missing library description file
@ -74,26 +76,19 @@ include $(BASE_DIR)/mk/base-libs.mk
include $(LIB_MK)
ifdef SHARED_LIB
#
# For shared libraries, we have to make sure to build ldso support before
# building a shared library.
#
LIBS += ldso-startup
ifneq ($(LIB),$(DYNAMIC_LINKER))
LIBS += $(DYNAMIC_LINKER)
endif
#
# Ensure that startup_dyn is build for the dynamic programs that depend on a
# shared library. They add it to their dependencies as replacement for the
# static-case startup as soon as they recognize that they are dynamic.
# The current library in contrast filters-out startup_dyn from its
# dependencies before they get merged.
# Hide archive dependencies of shared libraries from users of the shared
# library. Library users examine the 'DEP_A_<lib>' variable to determine
# transitive dependencies. For shared libraries, this variable remains
# undefined.
#
DEP_VAR_NAME := DEP_$(LIB).lib.so
ifdef SHARED_LIB
DEP_A_VAR_NAME := PRIVATE_DEP_A_$(LIB)
else
DEP_VAR_NAME := DEP_$(LIB).lib
DEP_A_VAR_NAME := DEP_A_$(LIB)
endif
#
@ -116,30 +111,35 @@ generate_lib_rule_for_defect_library:
LIBS_TO_VISIT = $(filter-out $(LIBS_READY),$(LIBS))
generate_lib_rule:
ifneq ($(LIBS),)
@(echo "$(DEP_VAR_NAME) = $(foreach l,$(LIBS),$l.lib \$$(DEP_$l.lib))"; \
echo "") >> $(LIB_DEP_FILE)
endif
ifneq ($(DEP_MISSING_PORTS),)
@(echo "MISSING_PORTS += $(DEP_MISSING_PORTS)"; \
echo "") >> $(LIB_DEP_FILE)
endif
@for i in $(LIBS_TO_VISIT); do \
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk REP_DIR=$(REP_DIR) LIB=$$i; done
ifneq ($(LIBS),)
@(echo "$(DEP_A_VAR_NAME) = $(foreach l,$(LIBS),\$${ARCHIVE_NAME($l)} \$$(DEP_A_$l))"; \
echo "DEP_SO_$(LIB) = $(foreach l,$(LIBS),\$${SO_NAME($l)} \$$(DEP_SO_$l))"; \
echo "") >> $(LIB_DEP_FILE)
endif
@(echo "$(LIB).lib: check_ports $(addsuffix .lib,$(LIBS))"; \
echo " @\$$(MKDIR) -p \$$(LIB_CACHE_DIR)/$(LIB)"; \
echo " \$$(VERBOSE_MK)\$$(MAKE) $(VERBOSE_DIR) -C \$$(LIB_CACHE_DIR)/$(LIB) -f \$$(BASE_DIR)/mk/lib.mk \\"; \
echo " REP_DIR=$(REP_DIR) \\"; \
echo " LIB_MK=$(LIB_MK) \\"; \
echo " SYMBOLS=$(SYMBOLS) \\"; \
echo " LIB=$(LIB) \\"; \
echo " DEPS=\"\$$(sort \$$($(DEP_VAR_NAME)))\" \\"; \
echo " ARCHIVES=\"\$$(sort \$$($(DEP_A_VAR_NAME)))\" \\"; \
echo " SHARED_LIBS=\"\$$(sort \$$(DEP_SO_$(LIB)))\" \\"; \
echo " BUILD_BASE_DIR=$(BUILD_BASE_DIR) \\"; \
echo " SHELL=$(SHELL) \\"; \
echo " SHARED_LIBS=\"\$$(SHARED_LIBS)\"\\"; \
echo " INSTALL_DIR=\$$(INSTALL_DIR)"; \
echo "") >> $(LIB_DEP_FILE)
@for i in $(LIBS_TO_VISIT); do \
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk REP_DIR=$(REP_DIR) LIB=$$i; done
ifdef SHARED_LIB
@(echo "SHARED_LIBS += $(LIB)"; \
@(echo "SO_NAME($(LIB)) := $(LIB).lib.so"; \
echo "") >> $(LIB_DEP_FILE)
else
@(echo "ARCHIVE_NAME($(LIB)) := $(LIB).lib.a"; \
echo "") >> $(LIB_DEP_FILE)
endif

View File

@ -51,7 +51,10 @@ LIBS_TO_VISIT = $(filter-out $(LIBS_READY),$(LIBS))
#
gen_prg_rule:
ifneq ($(LIBS),)
@(echo "DEP_$(TARGET).prg = $(foreach l,$(LIBS),$l.lib \$$(DEP_$l.lib))"; \
@for i in $(LIBS_TO_VISIT); do \
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk REP_DIR=$(REP_DIR) LIB=$$i; done
@(echo "DEP_A_$(TARGET).prg = $(foreach l,$(LIBS),\$${ARCHIVE_NAME($l)} \$$(DEP_A_$l))"; \
echo "DEP_SO_$(TARGET).prg = $(foreach l,$(LIBS),\$${SO_NAME($l)} \$$(DEP_SO_$l))"; \
echo "") >> $(LIB_DEP_FILE)
endif
ifneq ($(DEP_MISSING_PORTS),)
@ -64,20 +67,18 @@ endif
echo " REP_DIR=$(REP_DIR) \\"; \
echo " PRG_REL_DIR=$(PRG_REL_DIR) \\"; \
echo " BUILD_BASE_DIR=$(BUILD_BASE_DIR) \\"; \
echo " DEPS=\"\$$(DEP_$(TARGET).prg)\" \\"; \
echo " ARCHIVES=\"\$$(sort \$$(DEP_A_$(TARGET).prg))\" \\"; \
echo " SHARED_LIBS=\"\$$(sort \$$(DEP_SO_$(TARGET).prg))\" \\"; \
echo " SHELL=$(SHELL) \\"; \
echo " INSTALL_DIR=\"\$$(INSTALL_DIR)\""; \
echo "") >> $(LIB_DEP_FILE)
@for i in $(LIBS_TO_VISIT); do \
$(MAKE) $(VERBOSE_DIR) -f $(BASE_DIR)/mk/dep_lib.mk REP_DIR=$(REP_DIR) LIB=$$i; done
#
# Make 'all' depend on the target, which triggers the building of the target
# and the traversal of the target's library dependencies. But we only do so
# if the target does not depend on any library with unsatisfied build
# requirements. In such a case, the target cannot be linked anyway.
#
@(echo ""; \
echo "ifeq (\$$(filter \$$(DEP_$(TARGET).prg:.lib=),\$$(INVALID_DEPS)),)"; \
@(echo "ifeq (\$$(filter \$$(DEP_A_$(TARGET).prg:.lib.a=) \$$(DEP_SO_$(TARGET).prg:.lib.so=) $(LIBS),\$$(INVALID_DEPS)),)"; \
echo "all: $(TARGET).prg"; \
echo "endif") >> $(LIB_DEP_FILE)
#

View File

@ -74,9 +74,13 @@ endif
#
# Compiling Rust sources
#
%.o: %.rs
%.rlib: %.rs
$(MSG_COMP)$@
$(VERBOSE)rustc $(CC_RUSTC_OPT) -o $@ $<
$(VERBOSE)rustc $(CC_RUSTC_OPT) --crate-type rlib -o $@ $<
%.o: %.rlib
$(MSG_CONVERT)$@
$(VERBOSE)ar p $< $*.0.o > $@
#
# Assembler files that must be preprocessed are fed to the C compiler.
@ -100,3 +104,62 @@ binary_%.o: %
$(MSG_CONVERT)$@
$(VERBOSE)echo ".global $(symbol_name)_start, $(symbol_name)_end; .data; .align 4; $(symbol_name)_start:; .incbin \"$<\"; $(symbol_name)_end:" |\
$(AS) $(AS_OPT) -f -o $@ -
#
# Generate assembler file from symbol list
#
# For undefined symbols (type U), we create a hard dependency by referencing
# the symbols from the assembly file. The reference is created in the form of
# a '.long' value with the address of the symbol. On x86_64, this is not
# possible for PIC code. Hence, we reference the symbol via a PIC-compatible
# movq instruction instead.
#
# If we declared the symbol as '.global' without using it, the undefined symbol
# gets discarded at link time unless it is directly referenced by the target.
# This is a problem in situations where the undefined symbol is resolved by an
# archive rather than the target. I.e., when linking posix.lib.a (which
# provides 'Libc::Component::construct'), the 'construct' function is merely
# referenced by the libc.lib.so's 'Component::construct' function. But this
# reference apparently does not suffice to keep the posix.lib.a's symbol. By
# adding a hard dependency, we force the linker to resolve the symbol and don't
# drop posix.lib.a.
#
ASM_SYM_DEPENDENCY := .long \1
ifeq ($(filter-out $(SPECS),x86_64),)
ASM_SYM_DEPENDENCY := movq \1@GOTPCREL(%rip), %rax
endif
%.symbols.s: %.symbols
$(MSG_CONVERT)$@
$(VERBOSE)\
sed -e "s/^\(\w\+\) D \(\w\+\)\$$/.data; .global \1; .type \1,%object; .size \1,\2; \1:/p" \
-e "s/^\(\w\+\) V/.data; .weak \1; .type \1,%object; \1:/p" \
-e "s/^\(\w\+\) T/.text; .global \1; .type \1,%function; \1:/p" \
-e "s/^\(\w\+\) R/.section .rodata; .global \1; \1:/p" \
-e "s/^\(\w\+\) W/.text; .weak \1; .type \1,%function; \1:/p" \
-e "s/^\(\w\+\) B \(\w\+\)\$$/.bss; .global \1; .type \1,%object; .size \1,\2; \1:/p" \
-e "s/^\(\w\+\) U/.text; .global \1; $(ASM_SYM_DEPENDENCY)/p" \
$< > $@
#
# Create local symbol links for the used shared libraries
#
# Depending on whether an ABI stub for a given shared library exists, we link
# the target against the ABI stub or the real shared library.
#
# We check if the symbolic links are up-to-date by filtering all links that
# already match the current shared library targets from the list. If the list
# is not empty we flag 'SHARED_LIBS' as phony to make sure that the symbolic
# links are recreated. E.g., if a symbol list is added for library, the next
# time a user of the library is linked, the ABI stub should be used instead of
# the library.
#
select_so = $(firstword $(wildcard $(LIB_CACHE_DIR)/$(1:.lib.so=)/$(1:.lib.so=).abi.so \
$(LIB_CACHE_DIR)/$(1:.lib.so=)/$(1:.lib.so=).lib.so))
ifneq ($(filter-out $(foreach s,$(SHARED_LIBS),$(realpath $s)), \
$(foreach s,$(SHARED_LIBS),$(call select_so,$s))),)
.PHONY: $(SHARED_LIBS)
endif
$(SHARED_LIBS):
$(VERBOSE)ln -sf $(call select_so,$@) $@

View File

@ -110,6 +110,12 @@ CC_OPT += $(CC_OPT_NOSTDINC) -g $(CC_MARCH) $(CC_OLEVEL) $(CC_OPT_DEP) $(CC_WARN
#
CC_OPT += $(CC_OPT_$(subst .,_,$*))
#
# Build program position independent as well
#
CC_OPT_PIC ?= -fPIC
CC_OPT += $(CC_OPT_PIC)
#
# Predefine C and C++ specific compiler options with their common values
#
@ -118,13 +124,11 @@ CC_C_OPT += $(CC_OPT)
CC_ADA_OPT += $(CC_OLEVEL) $(CC_WARN)
#
# Use the correct linker
# Rust-specific arguments
#
# Use the correct linker, include dependencies.
#
CC_RUSTC_OPT += -C linker=$(LD)
#
# Include dependencies
#
CC_RUSTC_OPT += $(foreach lib,$(LIBS),-L$(LIB_CACHE_DIR)/$(lib))
#

View File

@ -11,7 +11,8 @@
## BUILD_BASE_DIR - base of build directory tree
## LIB_CACHE_DIR - library build cache location
## INSTALL_DIR - program target build directory
## DEPS - library dependencies
## SHARED_LIBS - shared-library dependencies of the library
## ARCHIVES - archive dependencies of the library
## REP_DIR - repository where the library resides
## CONTRIB_DIR - location of ported 3rd-party source codes
##
@ -23,15 +24,6 @@ include $(BASE_DIR)/mk/base-libs.mk
#
all:
#
# Make a rlib or dylib instead of object file
#
ifndef SHARED_LIB
CC_RUSTC_OPT += --crate-type rlib
else
CC_RUSTC_OPT += --crate-type dylib
endif
#
# Include common utility functions
#
@ -79,15 +71,45 @@ ifdef SHARED_LIB
LIB_SO := $(addsuffix .lib.so,$(LIB))
INSTALL_SO := $(INSTALL_DIR)/$(LIB_SO)
LIB_FILENAME := $(LIB_SO)
else ifdef SRC_RS
LIB_RLIB := $(addsuffix .rlib,$(LIB))
LIB_FILENAME := $(LIB_RLIB)
else
LIB_A := $(addsuffix .lib.a,$(LIB))
LIB_FILENAME := $(LIB_A)
endif
LIB_TAG := $(addsuffix .lib.tag,$(LIB))
#
# If a symbol list is provided, we create an ABI stub named '<lib>.abi.so'
#
# The ABI-stub library does not contain any code or data but only the symbol
# information of the binary interface (ABI) of the shared library.
#
# The ABI stub is linked by the users of the library (executables or shared
# objects) instead of the real library. This effectively decouples the library
# users from the concrete library instance but binds them merely to the
# library's binary interface. Note that the ABI stub is not used at runtime at
# all. At runtime, the real library that implements the ABI is loaded by the
# dynamic linker.
#
# The symbol information are incorporated into the ABI stub via an assembly
# file named '<lib>.symbols.s' that is generated from the library's symbol
# list. We create a symbolic link from the symbol file to the local directory.
# By using '.symbols' as file extension, the pattern rule '%.symbols.s:
# %.symbols' defined in 'generic.mk' is automatically applied for creating the
# assembly file from the symbols file.
#
# The '.PRECIOUS' special target prevents make to remove the intermediate
# assembler file. Otherwise make would spill the build log with messages
# like "rm libc.symbols.s".
#
ifneq ($(SYMBOLS),)
ABI_SO := $(addsuffix .abi.so,$(LIB))
$(LIB).symbols:
$(VERBOSE)ln -sf $(SYMBOLS) $@
.PRECIOUS: $(LIB).symbols.s
endif
#
# Link libgcc to shared libraries
#
@ -98,16 +120,6 @@ ifdef SHARED_LIB
LIBGCC = $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name)
endif
#
# Build libraries position-independent
#
# This option is required for building shared objects but also for static
# libraries that are (potentially) linked against shared objects. Hence,
# we build all libraries with '-fPIC'.
#
CC_OPT_PIC ?= -fPIC
CC_OPT += $(CC_OPT_PIC)
#
# Print message for the currently built library
#
@ -130,11 +142,33 @@ all: $(LIB_TAG)
#
$(LIB_TAG) $(OBJECTS): $(HOST_TOOLS)
$(LIB_TAG): $(LIB_A) $(LIB_SO) $(INSTALL_SO) $(LIB_RLIB)
$(LIB_TAG): $(LIB_A) $(LIB_SO) $(ABI_SO) $(INSTALL_SO)
@touch $@
include $(BASE_DIR)/mk/generic.mk
#
# Rust support
#
# For a rust library, we create both an actual library (lib.a or lib.so) that
# is used for linking the final binary, and an rlib file that is required for
# compiling rust source codes that use the library. As the rlib is created from
# the file specified at 'SRC_RS' via the pattern rule '%.rlib: %.rs', its name
# corresponds to the source file, not the library name. To enable rustc to find
# the library when compiling dependent compilation units, we create an
# appropriately named symlink that points to the rlib file.
#
ifneq ($(SRC_RS),)
ifneq ($(words $(SRC_RS)),1)
$(error 'SRC_RC' of library $(LIB) has more than one element: $(SRC_RC))
endif
$(LIB_A): $(LIB).rlib
endif
.PRECIOUS: $(SRC_RC:.rs=.rlib)
$(LIB).rlib: $(SRC_RS:.rs=.rlib)
$(VERBOSE)ln -s $< $@
#
# Rule to build the <libname>.lib.a file
#
@ -147,71 +181,64 @@ $(LIB_A): $(OBJECTS)
$(MSG_MERGE)$(LIB_A)
$(VERBOSE)$(RM) -f $@
$(VERBOSE)$(AR) -rcs $@ $(OBJECTS)
#
# Rename from object to rlib
# Link ldso-startup library to each shared library
#
$(LIB_RLIB): $(OBJECTS)
$(MSG_RENAME)$(LIB_RLIB)
$(VERBOSE)cp $(OBJECTS) $(LIB_RLIB)
ifdef SHARED_LIB
override ARCHIVES += ldso-startup.lib.a
endif
#
# Don't link base libraries against shared libraries except for ld.lib.so
#
ifdef SHARED_LIB
ifneq ($(LIB_IS_DYNAMIC_LINKER),yes)
override DEPS := $(filter-out $(BASE_LIBS:=.lib),$(DEPS))
endif
override ARCHIVES := $(filter-out $(BASE_LIBS:=.lib.a),$(ARCHIVES))
endif
#
# The 'sort' is needed to ensure the same link order regardless
# of the find order, which uses to vary among different systems.
#
STATIC_LIBS := $(foreach l,$(DEPS:.lib=),$(LIB_CACHE_DIR)/$l/$l.lib.a)
STATIC_LIBS := $(sort $(wildcard $(STATIC_LIBS)))
STATIC_LIBS := $(sort $(foreach l,$(ARCHIVES:.lib.a=),$(LIB_CACHE_DIR)/$l/$l.lib.a))
STATIC_LIBS_BRIEF := $(subst $(LIB_CACHE_DIR),$$libs,$(STATIC_LIBS))
#
# Rule to build the <libname>.lib.so file
#
# The 'LIBS' variable may contain static and shared sub libraries. When linking
# the shared library, we have to link all shared sub libraries to the library
# to store the library-dependency information in the library. Because we do not
# know which sub libraries are static or shared prior calling 'build_libs.mk',
# we use an explicit call to the 'lib_so_wildcard' macro to determine the subset
# of libraries that are shared.
# When linking the shared library, we have to link all shared sub libraries
# (LIB_SO_DEPS) to the library to store the library-dependency information in
# the generated shared object.
#
# The 'ldso-startup/startup.o' object file, which contains the support code for
# constructing static objects must be specified as object file to prevent the
# linker from garbage-collecting it.
#
USED_SHARED_LIBS := $(filter $(DEPS:.lib=),$(SHARED_LIBS))
USED_SO_FILES := $(foreach s,$(USED_SHARED_LIBS),$(LIB_CACHE_DIR)/$s/$s.lib.so)
#
# Don't link ld libary against shared objects
#
USED_SO_FILES := $(filter-out %$(DYNAMIC_LINKER).lib.so,$(USED_SO_FILES))
#
# Default entry point of shared libraries
#
ENTRY_POINT ?= 0x0
ENTRY_POINT ?= 0x0
$(LIB_SO): $(STATIC_LIBS) $(OBJECTS) $(wildcard $(LD_SCRIPT_SO))
$(LIB_SO) $(ABI_SO): $(SHARED_LIBS)
$(LIB_SO): $(STATIC_LIBS) $(OBJECTS) $(wildcard $(LD_SCRIPT_SO)) $(LIB_SO_DEPS)
$(MSG_MERGE)$(LIB_SO)
$(VERBOSE)libs=$(LIB_CACHE_DIR); $(LD) -o $(LIB_SO) -shared --eh-frame-hdr \
$(LD_OPT) \
-T $(LD_SCRIPT_SO) \
--entry=$(ENTRY_POINT) \
--whole-archive \
--start-group \
$(USED_SO_FILES) $(STATIC_LIBS_BRIEF) $(OBJECTS) \
--end-group \
--no-whole-archive \
$(LD_OPT) -T $(LD_SCRIPT_SO) --entry=$(ENTRY_POINT) \
--whole-archive --start-group \
$(SHARED_LIBS) $(STATIC_LIBS_BRIEF) $(OBJECTS) \
--end-group --no-whole-archive \
$(LIBGCC)
$(ABI_SO): $(LIB).symbols.o
$(MSG_MERGE)$(ABI_SO)
$(VERBOSE)$(LD) -o $(ABI_SO) -shared --eh-frame-hdr $(LD_OPT) \
-T $(LD_SCRIPT_SO) \
--whole-archive --start-group \
$(LIB_SO_DEPS) $< \
--end-group --no-whole-archive
$(INSTALL_SO):
$(VERBOSE)ln -sf $(CURDIR)/$(LIB_SO) $@

View File

@ -11,6 +11,8 @@
## VERBOSE - build verboseness modifier
## VERBOSE_DIR - verboseness modifier for changing directories
## VERBOSE_MK - verboseness of make calls
## SHARED_LIBS - shared-library dependencies of the target
## ARCHIVES - archive dependencies of the target
## LIB_CACHE_DIR - library build cache location
##
@ -19,11 +21,6 @@
#
all:
#
# Tell rust to make an object file instead of anything else
#
CC_RUSTC_OPT += --emit obj
#
# Include common utility functions
#
@ -62,7 +59,6 @@ endif
#
CXX_LINK_OPT += $(CC_MARCH)
#
# Generic linker script for statically linked binaries
#
@ -95,23 +91,14 @@ message:
FORCE:
$(SRC_ADA:.adb=.o): FORCE
#
# The 'sort' is needed to ensure the same link order regardless
# of the find order, which uses to vary among different systems.
#
SHARED_LIBS := $(foreach l,$(DEPS:.lib=),$(LIB_CACHE_DIR)/$l/$l.lib.so)
SHARED_LIBS := $(sort $(wildcard $(SHARED_LIBS)))
#
# Use CXX for linking
#
LD_CMD ?= $(CXX)
LD_CMD += $(CXX_LINK_OPT)
ifeq ($(SHARED_LIBS),)
FILTER_DEPS := $(DEPS:.lib=)
LD_SCRIPTS := $(LD_SCRIPT_STATIC)
LD_SCRIPTS := $(LD_SCRIPT_STATIC)
else
#
@ -119,22 +106,14 @@ else
#
LD_OPT += --dynamic-list=$(call select_from_repositories,src/ld/genode_dyn.dl)
LD_SCRIPTS := $(LD_SCRIPT_DYN)
LD_CMD += -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
-Wl,--eh-frame-hdr
LD_SCRIPTS := $(LD_SCRIPT_DYN)
LD_CMD += -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
-Wl,--eh-frame-hdr -Wl,-rpath-link=.
#
# Filter out the base libraries since they will be provided by the LDSO library
#
FILTER_DEPS := $(filter-out $(BASE_LIBS),$(DEPS:.lib=))
SHARED_LIBS += $(LIB_CACHE_DIR)/$(DYNAMIC_LINKER)/$(DYNAMIC_LINKER).lib.so
#
# Build program position independent as well
#
CC_OPT_PIC ?= -fPIC
CC_OPT += $(CC_OPT_PIC)
override ARCHIVES := $(filter-out $(BASE_LIBS:=.lib.a),$(ARCHIVES))
endif
#
@ -142,7 +121,7 @@ endif
# commas othwerwise. For compatibilty with older tool chains, we use two -Wl
# parameters for both components of the linker command line.
#
LD_SCRIPT_PREFIX = -Wl,-T -Wl,
LD_SCRIPT_PREFIX := -Wl,-T -Wl,
#
# LD_SCRIPTS may be a list of linker scripts (e.g., in base-linux). Further,
@ -151,26 +130,7 @@ LD_SCRIPT_PREFIX = -Wl,-T -Wl,
#
LD_CMD += $(addprefix $(LD_SCRIPT_PREFIX), $(LD_SCRIPTS))
STATIC_LIBS := $(foreach l,$(FILTER_DEPS),$(LIB_CACHE_DIR)/$l/$l.lib.a)
STATIC_LIBS := $(sort $(wildcard $(STATIC_LIBS)))
#
# --whole-archive does not work with rlibs
#
RUST_LIBS := $(foreach l,$(FILTER_DEPS),$(LIB_CACHE_DIR)/$l/$l.rlib)
RUST_LIBS := $(sort $(wildcard $(RUST_LIBS)))
SHORT_RUST_LIBS := $(subst $(LIB_CACHE_DIR),$$libs,$(RUST_LIBS))
#
# For hybrid Linux/Genode programs, prevent the linkage Genode's cxx and base
# library because these functionalities are covered by the glibc or by
# 'src/platform/lx_hybrid.cc'.
#
ifeq ($(USE_HOST_LD_SCRIPT),yes)
STATIC_LIBS := $(filter-out $(LIB_CACHE_DIR)/startup/startup.lib.a, $(STATIC_LIBS))
STATIC_LIBS := $(filter-out $(LIB_CACHE_DIR)/base/base.lib.a, $(STATIC_LIBS))
STATIC_LIBS := $(filter-out $(LIB_CACHE_DIR)/cxx/cxx.lib.a, $(STATIC_LIBS))
endif
STATIC_LIBS := $(foreach l,$(ARCHIVES:.lib.a=),$(LIB_CACHE_DIR)/$l/$l.lib.a)
#
# We need the linker option '--whole-archive' to make sure that all library
@ -184,7 +144,7 @@ endif
# would go undetected if the search stops after the first match.
#
LINK_ITEMS := $(OBJECTS) $(STATIC_LIBS) $(SHARED_LIBS)
SHORT_LINK_ITEMS := $(subst $(LIB_CACHE_DIR),$$libs,$(LINK_ITEMS))
LINK_ITEMS_BRIEF := $(subst $(LIB_CACHE_DIR),$$libs,$(LINK_ITEMS))
#
# Trigger the build of host tools
@ -192,10 +152,9 @@ SHORT_LINK_ITEMS := $(subst $(LIB_CACHE_DIR),$$libs,$(LINK_ITEMS))
$(LINK_ITEMS) $(TARGET): $(HOST_TOOLS)
LD_CMD += -Wl,--whole-archive -Wl,--start-group
LD_CMD += $(SHORT_LINK_ITEMS)
LD_CMD += $(LINK_ITEMS_BRIEF)
LD_CMD += $(EXT_OBJECTS)
LD_CMD += -Wl,--no-whole-archive
LD_CMD += $(SHORT_RUST_LIBS)
LD_CMD += -Wl,--end-group
#
@ -211,7 +170,7 @@ LD_CMD += $(LD_LIBGCC)
# $(TARGET).
#
ifneq ($(OBJECTS),)
$(TARGET): $(LINK_ITEMS) $(wildcard $(LD_SCRIPTS))
$(TARGET): $(LINK_ITEMS) $(wildcard $(LD_SCRIPTS)) $(LIB_SO_DEPS)
$(MSG_LINK)$(TARGET)
$(VERBOSE)libs=$(LIB_CACHE_DIR); $(LD_CMD) -o $@
@ -225,6 +184,6 @@ endif
clean_prg_objects:
$(MSG_CLEAN)$(PRG_REL_DIR)
$(VERBOSE)$(RM) -f $(OBJECTS) $(OBJECTS:.o=.d) $(TARGET)
$(VERBOSE)$(RM) -f *.d *.i *.ii *.s *.ali
$(VERBOSE)$(RM) -f *.d *.i *.ii *.s *.ali *.lib.so
clean: clean_prg_objects

View File

@ -1,4 +1,4 @@
TARGET = rump_cgd
SRC_CC = cgd.cc main.cc random.cc
LIBS = rump rump_cgd jitterentropy
LIBS = base rump rump_cgd jitterentropy

View File

@ -1,5 +1,5 @@
TARGET = rump_fs
SRC_CC = main.cc file_system.cc random.cc
LIBS = rump rump_fs
LIBS = base rump rump_fs

View File

@ -0,0 +1,5 @@
SRC_CC = libc_mem_alloc.cc
include $(REP_DIR)/lib/mk/libc-common.inc
vpath libc_mem_alloc.cc $(REP_DIR)/src/lib/libc

View File

@ -2,7 +2,7 @@
# C Library including string, locale
#
LIBS = libc-string libc-locale libc-stdlib libc-stdio libc-gen libc-gdtoa \
libc-inet libc-stdtime libc-regex libc-compat libc-setjmp
libc-inet libc-stdtime libc-regex libc-compat libc-setjmp libc-mem
LIBS += base config vfs
@ -13,7 +13,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \
issetugid.cc errno.cc gai_strerror.cc clock_gettime.cc \
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
libc_mem_alloc.cc pread_pwrite.cc readv_writev.cc poll.cc \
pread_pwrite.cc readv_writev.cc poll.cc \
libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc signal.cc \
socket_operations.cc task.cc

View File

@ -1,4 +1,4 @@
LIBS = libcore-rust libc libc-stdlib ldso-startup
LIBS = libcore-rust libc
RLIB = liblibc/src
CC_RUSTC_OPT += --cfg 'target_os = "freebsd"'
include $(REP_DIR)/lib/mk/rust.inc

View File

@ -3,12 +3,15 @@ ___tolower T
___toupper T
__assert T
__error T
__flt_rounds T
__fpclassifyd T
__inet_addr T
__inet_aton T
__inet_nsap_ntoa T
__inet_ntoa T
__inet_ntop T
__inet_nsap_ntoa T
__inet_pton T
__isthreaded B
__isthreaded B 4
__mb_cur_max D 8
__srget T
__stderrp D 8
@ -110,7 +113,7 @@ endnetgrent T
endpwent W
endttyent T
endusershell T
environ B
environ B 8
erand48 T
err W
err_set_exit T
@ -436,11 +439,11 @@ offtime T
open T
opendir T
openlog T
optarg B
optarg B 8
opterr D 4
optind D 4
optopt B
optreset B
optopt B 4
optreset B 4
pathconf W
pause W
pclose T
@ -726,18 +729,18 @@ strunvisx T
strvis T
strvisx T
strxfrm T
suboptarg B
suboptarg B 8
swab T
swapcontext W
swprintf T
swscanf T
symlink T
sync W
sys_errlist D 376
sys_errlist D 752
sys_nerr R
sys_nsig R
sys_siglist D 128
sys_signame D 128
sys_siglist D 256
sys_signame D 256
sysconf T
sysctl T
sysctlbyname T
@ -779,7 +782,7 @@ ttyname T
ttyname_r T
ttyslot T
twalk T
tzname D 8
tzname D 16
tzset T
tzsetwall T
ualarm T
@ -888,8 +891,8 @@ xsi_sigpause T
# Symbols needed by libm
#
__mb_sb_limit D 4
_DefaultRuneLocale D 3156
_CurrentRuneLocale D 4
_DefaultRuneLocale D 4224
_CurrentRuneLocale D 8
__isinff T
__isinfl T
@ -897,10 +900,18 @@ __isinfl T
#
# Symbols needed by libc-resolv
#
__inet_nsap_addr T
_accept T
_bind T
_close T
_connect T
_fcntl T
_fstat T
_getpeername T
_getsockname T
_getsockopt T
_listen T
_nanosleep W
_pthread_getspecific W
_pthread_key_create W
_pthread_main_np W
@ -913,9 +924,12 @@ _pthread_rwlock_wrlock W
_pthread_setspecific W
_read T
_recvfrom T
_select W
_sendto T
_setsockopt T
_sigprocmask W
_socket T
_write T
_writev T

View File

@ -18,7 +18,7 @@ install_config {
</config>
}
build_boot_image "core init test-rust ld.lib.so libc.lib.so"
build_boot_image "core init test-rust ld.lib.so libc.lib.so libm.lib.so"
append qemu_args "-nographic -m 64"

View File

@ -83,7 +83,7 @@ CC_OPT += $(VBOX_CC_OPT)
# flag, therefore it gets added to CC_OPT instead of VBOX_CC_OPT.
CC_OPT += -fshort-wchar
LIBS += libc libm
LIBS += libc libm libc-mem
INC_DIR += $(REP_DIR)/src/virtualbox/include
INC_DIR += $(REP_DIR)/src/virtualbox/include/xpcom

View File

@ -88,7 +88,7 @@ CC_OPT += $(VBOX_CC_OPT)
# flag, therefore it gets added to CC_OPT instead of VBOX_CC_OPT.
CC_OPT += -fshort-wchar
LIBS += libc libm
LIBS += libc libm libc-mem
INC_DIR += $(REP_DIR)/src/virtualbox/include
INC_DIR += $(REP_DIR)/src/virtualbox/include/xpcom

View File

@ -86,8 +86,10 @@ endif
CONFIGURE_ARGS += $(CONFIGURE_VERBOSE)
LDFLAGS += -nostdlib $(CXX_LINK_OPT) $(CC_MARCH) -Wl,-T$(LD_SCRIPT_DYN) \
-Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
-Wl,--eh-frame-hdr
-Wl,-rpath-link=$(PWD) \
-Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
-Wl,--eh-frame-hdr
LIBTOOLFLAGS = --preserve-dup-deps
LIBGCC = $(shell $(CC) $(CC_MARCH) -print-libgcc-file-name)
@ -99,7 +101,7 @@ CPPFLAGS += -D_GNU_SOURCE=1
COMMON_CFLAGS_CXXFLAGS += -ffunction-sections $(CC_OLEVEL) $(CC_MARCH)
COMMON_CFLAGS_CXXFLAGS += -g
CFLAGS += $(COMMON_CFLAGS_CXXFLAGS)
CFLAGS += $(COMMON_CFLAGS_CXXFLAGS)
CXXFLAGS += $(COMMON_CFLAGS_CXXFLAGS)
#
@ -107,8 +109,8 @@ CXXFLAGS += $(COMMON_CFLAGS_CXXFLAGS)
# Unfortunately, the use of '--start-group' and '--end-group' does not suffice
# in all cases because 'libtool' strips those arguments from the 'LIBS' variable.
#
LDLIBS_A = $(filter %.a, $(sort $(LINK_ITEMS)) $(EXT_OBJECTS) $(LIBGCC))
LDLIBS_SO = $(filter %.so,$(sort $(LINK_ITEMS)) $(EXT_OBJECTS) $(LIBGCC))
LDLIBS_A = $(filter %.a, $(sort $(STATIC_LIBS)) $(EXT_OBJECTS) $(LIBGCC))
LDLIBS_SO = $(addprefix $(PWD)/,$(sort $(SHARED_LIBS)))
LDLIBS += $(LDLIBS_A) $(LDLIBS_SO) $(LDLIBS_A)
#
@ -119,7 +121,7 @@ Makefile reconfigure: $(MAKEFILE_LIST)
#
# Invoke configure script with the Genode environment
#
Makefile reconfigure: env.sh
Makefile reconfigure: env.sh $(SHARED_LIBS)
@$(MSG_CONFIG)$(TARGET)
$(VERBOSE)source env.sh && $(PKG_DIR)/configure $(ENV) $(CONFIGURE_ARGS) $(CONFIGURE_OUTPUT_FILTER)

View File

@ -27,6 +27,7 @@ INC_DIR += $(REP_DIR)/src/app/seoul/include
CC_WARN += -Wno-parentheses -Wall
CC_CXX_OPT += -march=core2
CC_CXX_OPT += -mssse3
CC_OPT_PIC :=
vpath %.cc $(SEOUL_CONTRIB_DIR)
vpath %.cc $(REP_DIR)/src/app/seoul

View File

@ -60,4 +60,4 @@ include $(REP_DIR)/mk/noux.mk
# Unfortunately, the use of '--start-group' and '--end-group' does not suffice
# in all cases because 'libtool' strips those arguments from the 'LIBS' variable.
#
LDLIBS += -Wl,--start-group $(sort $(LINK_ITEMS)) $(sort $(LINK_ITEMS)) $(LIBGCC) -Wl,--end-group
LDLIBS += -Wl,--start-group $(sort $(STATIC_LIBS)) $(sort $(STATIC_LIBS)) $(LIBGCC) -Wl,--end-group

View File

@ -90,7 +90,7 @@ foreach line [split $symbols "\n"] {
# linker copies the data from the shared library's symbol into the
# binary's BSS.
#
if {$type == "D"} {
if {($type == "D") || ($type == "B")} {
puts "$name $type $size_dec"
} else {
puts "$name $type"