Eliminate the generated ldscript for arm and arm64, and strip $a/$d marker

symbols from the linked kernel.

The main thrust of this change is to generate a kernel that has the arm
"marker" symbols stripped. Marker symbols start with $a, $d, $t or $x, and
are emitted by the compiler to tell other toolchain components about the
locations of data embedded in the instruction stream (literal-pool
stuff). They are used for generating mixed-endian binaries (which we don't
support). The linked kernel has approximately 21,000 such symbols in it,
wasting space (500K in kernel.full, 190K in the final linked kernel), and
sometimes obscuring function names in stack tracebacks.

This change also simplifies the way the kernel is linked. Instead of using
sed to generate two different ldscript files to generate both an elf kernel
and a binary (elf headers stripped) kernel, we now use a single ldscript
that refers to a "text_start" symbol, and we provide the value for that
symbol using --defsym on the linker command line.
This commit is contained in:
Ian Lepore 2019-12-29 18:17:12 +00:00
parent 150b9e85b6
commit 31333ebb99
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356180
4 changed files with 67 additions and 34 deletions

View File

@ -32,9 +32,6 @@ S= ../../..
INCLUDES+= -I$S/contrib/libfdt -I$S/gnu/dts/include
SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M}
SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M}
.if !defined(DEBUG) && !defined(PROFLEVEL)
STRIP_FLAGS = -S
.endif
@ -58,20 +55,41 @@ CFLAGS += -mllvm -arm-enable-ehabi
KERNVIRTADDR= 0xc0000000
.endif
# Use a custom SYSTEM_LD command to generate the elf kernel, so we can
# set the text segment start address, and also strip the "arm mapping
# symbols" which have names like $a.0 and $d.2; see the document
# "ELF for the ARM architecture" for more info on the mapping symbols.
SYSTEM_LD= \
${SYSTEM_LD_BASECMD} \
--defsym='text_start=${KERNVIRTADDR} + SIZEOF_HEADERS' \
-o ${.TARGET} ${SYSTEM_OBJS} vers.o; \
$(OBJCOPY) \
--wildcard \
--strip-symbol='$$[adt]*' \
${.TARGET}
# Generate the .bin (no elf headers) kernel as an extra build output.
# We must relink to generate the .bin kernel, because without headers the
# location of everything changes. We also strip the ARM marker symbols.
KERNEL_EXTRA+= ${KERNEL_KO}.bin
KERNEL_EXTRA_INSTALL+= ${KERNEL_KO}.bin
${KERNEL_KO}.bin: ${SYSTEM_DEP} vers.o
@echo "linking ${.TARGET}"
@${SYSTEM_LD_BASECMD} \
--defsym='text_start=${KERNVIRTADDR}' \
-o ${.TARGET} ${SYSTEM_OBJS} vers.o
${SIZE} ${.TARGET}
@${OBJCOPY} \
--wildcard \
--strip-symbol='$$[adt]*' \
--output-target=binary \
${.TARGET}
@chmod 755 ${.TARGET}
# hack because genassym.c includes sys/bus.h which includes these.
genassym.o: bus_if.h device_if.h
SYSTEM_LD_ = ${LD} -m ${LD_EMULATION} -Bdynamic -T ldscript.$M.noheader \
${_LDFLAGS} --no-warn-mismatch --warn-common --export-dynamic \
--dynamic-linker /red/herring \
-o ${FULLKERNEL}.noheader -X ${SYSTEM_OBJS} vers.o
SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// ldscript.$M \
>ldscript.$M.noheader; \
${SYSTEM_LD_}; \
${OBJCOPY} -S -O binary ${FULLKERNEL}.noheader \
${KERNEL_KO}.bin; \
rm ${FULLKERNEL}.noheader
%BEFORE_DEPEND
%OBJS
@ -84,10 +102,7 @@ SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// ldscript.$M \
%CLEAN
CLEAN+= ldscript.$M ${KERNEL_KO}.bin ldscript.$M.noheader
ldscript.$M: $S/conf/ldscript.$M
sed s/KERNVIRTADDR/${KERNVIRTADDR}/g > ldscript.$M < $S/conf/ldscript.$M
CLEAN+= ${KERNEL_KO}.bin
%RULES

View File

@ -27,24 +27,42 @@ S= ../../..
INCLUDES+= -I$S/contrib/libfdt
#SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M}
#SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M}
# Use a custom SYSTEM_LD command to generate the elf kernel, so we can
# set the text segment start address, and also strip the "arm mapping
# symbols" which have names like $a.0 and $d.2; see the document
# "ELF for the ARM architecture" for more info on the mapping symbols.
SYSTEM_LD= \
${SYSTEM_LD_BASECMD} \
--defsym='text_start=kernbase + SIZEOF_HEADERS' \
-o ${.TARGET} ${SYSTEM_OBJS} vers.o; \
$(OBJCOPY) \
--wildcard \
--strip-symbol='$$[adtx]*' \
${.TARGET}
# Generate the .bin (no elf headers) kernel as an extra build output.
# We must relink to generate the .bin kernel, because without headers the
# location of everything changes. We also strip the ARM marker symbols.
KERNEL_EXTRA+= ${KERNEL_KO}.bin
KERNEL_EXTRA_INSTALL+= ${KERNEL_KO}.bin
${KERNEL_KO}.bin: ${SYSTEM_DEP} vers.o
@echo "linking ${.TARGET}"
@${SYSTEM_LD_BASECMD} \
--defsym='text_start=kernbase' \
-o ${.TARGET} ${SYSTEM_OBJS} vers.o
${SIZE} ${.TARGET}
@${OBJCOPY} \
--wildcard \
--strip-symbol='$$[adtx]*' \
--output-target=binary \
${.TARGET}
@chmod 755 ${.TARGET}
.if !empty(DDB_ENABLED)
CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer
.endif
SYSTEM_LD_ = ${LD} -m ${LD_EMULATION} -Bdynamic -T ldscript.$M.noheader \
${_LDFLAGS} --no-warn-mismatch --warn-common --export-dynamic \
--dynamic-linker /red/herring \
-o ${FULLKERNEL}.noheader -X ${SYSTEM_OBJS} vers.o
SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// $(LDSCRIPT)\
>ldscript.$M.noheader;\
${SYSTEM_LD_}; \
${OBJCOPY} -S -O binary ${FULLKERNEL}.noheader \
${KERNEL_KO}.bin; \
rm ${FULLKERNEL}.noheader
%BEFORE_DEPEND
%OBJS
@ -56,7 +74,7 @@ SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// $(LDSCRIPT)\
%FILES.m
%CLEAN
CLEAN+= ldscript.$M ${KERNEL_KO}.bin ldscript.$M.noheader
CLEAN+= ${KERNEL_KO}.bin
%RULES

View File

@ -6,7 +6,7 @@ SEARCH_DIR(/usr/lib);
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = KERNVIRTADDR + SIZEOF_HEADERS;
. = text_start; /* This is set using --defsym= on the command line. */
.text :
{
*(.text)

View File

@ -6,7 +6,7 @@ SEARCH_DIR(/usr/lib);
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = kernbase + SIZEOF_HEADERS;
. = text_start; /* This is set using --defsym= on the command line. */
.text :
{
*(.text)