diff --git a/stand/defs.mk b/stand/defs.mk --- a/stand/defs.mk +++ b/stand/defs.mk @@ -73,6 +73,10 @@ # Standard options: CFLAGS+= -nostdinc +CFLAGS+= -flto +.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" +CFLAGS+= -fshort-wchar +.endif # Allow CFLAGS_EARLY.file/target so that code that needs specific stack # of include paths can set them up before our include paths. Normally # the only thing that should be there are -I directives, and as few of diff --git a/stand/efi/Makefile.inc b/stand/efi/Makefile.inc --- a/stand/efi/Makefile.inc +++ b/stand/efi/Makefile.inc @@ -6,12 +6,10 @@ LDFLAGS+= -nostdlib .if ${MACHINE_CPUARCH} == "amd64" -CFLAGS+= -fshort-wchar CFLAGS+= -mno-red-zone .endif .if ${MACHINE_CPUARCH} == "aarch64" -CFLAGS+= -fshort-wchar CFLAGS+= -fPIC .endif diff --git a/stand/efi/boot1/Makefile b/stand/efi/boot1/Makefile --- a/stand/efi/boot1/Makefile +++ b/stand/efi/boot1/Makefile @@ -71,6 +71,9 @@ LDFLAGS+= -Wl,--no-dynamic-linker .endif +LDSYM_SCRIPT= ${.CURDIR}/../loader/Symbol.map +LDFLAGS+= -Wl,--version-script=${LDSYM_SCRIPT} + .if ${MACHINE_CPUARCH} == "aarch64" CFLAGS+= -mgeneral-regs-only .endif @@ -87,9 +90,9 @@ # as well as required string and memory functions for all platforms. # DPADD+= ${LIBEFI} ${LIBSA} -LDADD+= ${LIBEFI} ${LIBSA} +LDADD+= -Wl,--whole-archive ${LIBEFI} ${LIBSA} -Wl,--no-whole-archive -DPADD+= ${LDSCRIPT} +DPADD+= ${LDSCRIPT} ${LDSYM_SCRIPT} ${BOOT1}.efi: ${PROG} if ${NM} ${.ALLSRC} | grep ' U '; then \ diff --git a/stand/efi/libefi/devpath.c b/stand/efi/libefi/devpath.c --- a/stand/efi/libefi/devpath.c +++ b/stand/efi/libefi/devpath.c @@ -41,7 +41,7 @@ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID; static EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *fromTextProtocol; -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_lookup_image_devpath(EFI_HANDLE handle) { EFI_DEVICE_PATH *devpath; @@ -54,7 +54,7 @@ return (devpath); } -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_lookup_devpath(EFI_HANDLE handle) { EFI_DEVICE_PATH *devpath; @@ -67,7 +67,7 @@ return (devpath); } -void +void __attribute__((weak)) efi_close_devpath(EFI_HANDLE handle) { EFI_STATUS status; @@ -498,7 +498,7 @@ return (ptr); } -CHAR16 * +CHAR16 * __attribute__((weak)) efi_devpath_name(EFI_DEVICE_PATH *devpath) { EFI_STATUS status; @@ -517,14 +517,14 @@ return (toTextProtocol->ConvertDevicePathToText(devpath, TRUE, TRUE)); } -void +void __attribute__((weak)) efi_free_devpath_name(CHAR16 *text) { if (text != NULL) BS->FreePool(text); } -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_name_to_devpath(const char *path) { EFI_DEVICE_PATH *devpath; @@ -539,7 +539,7 @@ return (devpath); } -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_name_to_devpath16(CHAR16 *path) { EFI_STATUS status; @@ -558,13 +558,14 @@ return (fromTextProtocol->ConvertTextToDevicePath(path)); } -void efi_devpath_free(EFI_DEVICE_PATH *devpath) +void __attribute__((weak)) +efi_devpath_free(EFI_DEVICE_PATH *devpath) { BS->FreePool(devpath); } -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_devpath_last_node(EFI_DEVICE_PATH *devpath) { @@ -575,7 +576,7 @@ return (devpath); } -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_devpath_trim(EFI_DEVICE_PATH *devpath) { EFI_DEVICE_PATH *node, *copy; @@ -596,7 +597,7 @@ return (copy); } -EFI_HANDLE +EFI_HANDLE __attribute__((weak)) efi_devpath_handle(EFI_DEVICE_PATH *devpath) { EFI_STATUS status; @@ -614,7 +615,7 @@ return (h); } -bool +bool __attribute__((weak)) efi_devpath_match_node(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { size_t len; @@ -657,7 +658,7 @@ /* * Are two devpaths identical? */ -bool +bool __attribute__((weak)) efi_devpath_match(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { return _efi_devpath_match(devpath1, devpath2, false); @@ -668,13 +669,13 @@ * path node that specifies the partition information. If we match * up to that point, then we're on the same disk. */ -bool +bool __attribute__((weak)) efi_devpath_same_disk(EFI_DEVICE_PATH *devpath1, EFI_DEVICE_PATH *devpath2) { return _efi_devpath_match(devpath1, devpath2, true); } -bool +bool __attribute__((weak)) efi_devpath_is_prefix(EFI_DEVICE_PATH *prefix, EFI_DEVICE_PATH *path) { size_t len; @@ -707,7 +708,7 @@ * Skip over the 'prefix' part of path and return the part of the path * that starts with the first node that's a MEDIA_DEVICE_PATH. */ -EFI_DEVICE_PATH * +EFI_DEVICE_PATH * __attribute__((weak)) efi_devpath_to_media_path(EFI_DEVICE_PATH *path) { @@ -719,7 +720,7 @@ return (NULL); } -UINTN +UINTN __attribute__((weak)) efi_devpath_length(EFI_DEVICE_PATH *path) { EFI_DEVICE_PATH *start = path; @@ -729,7 +730,7 @@ return ((UINTN)path - (UINTN)start) + DevicePathNodeLength(path); } -EFI_HANDLE +EFI_HANDLE __attribute__((weak)) efi_devpath_to_handle(EFI_DEVICE_PATH *path, EFI_HANDLE *handles, unsigned nhandles) { unsigned i; diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -106,6 +106,9 @@ LDFLAGS+= -Wl,--no-dynamic-linker .endif +LDSYM_SCRIPT= ${.CURDIR}/../loader/Symbol.map +LDFLAGS+= -Wl,--version-script=${LDSYM_SCRIPT} + CLEANFILES+= ${LOADER}.efi ${LOADER}.efi: ${PROG} @@ -122,7 +125,7 @@ LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a -DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} -LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} ${LDSCRIPT} ${LDSYM_SCRIPT} +LDADD= -Wl,--whole-archive ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBSA} -Wl,--no-whole-archive .include diff --git a/stand/efi/loader/Symbol.map b/stand/efi/loader/Symbol.map new file mode 100644 --- /dev/null +++ b/stand/efi/loader/Symbol.map @@ -0,0 +1,4 @@ +EFILOADER_1.0 { + global: efi_main; + local: *; +}; diff --git a/stand/i386/gptboot/Makefile b/stand/i386/gptboot/Makefile --- a/stand/i386/gptboot/Makefile +++ b/stand/i386/gptboot/Makefile @@ -61,6 +61,6 @@ ${OBJCOPY} -S -O binary gptboot.out ${.TARGET} gptboot.out: ${BTXCRT} gptboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} + ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} --whole-archive ${LIBSA32} .include diff --git a/stand/i386/gptzfsboot/Makefile b/stand/i386/gptzfsboot/Makefile --- a/stand/i386/gptzfsboot/Makefile +++ b/stand/i386/gptzfsboot/Makefile @@ -77,7 +77,7 @@ gptzfsboot.out: ${BTXCRT} ${OBJS} \ ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} + ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} --whole-archive ${LIBI386} ${LIBSA32} zfsboot.o: ${ZFSSRC}/zfsimpl.c diff --git a/stand/i386/isoboot/Makefile b/stand/i386/isoboot/Makefile --- a/stand/i386/isoboot/Makefile +++ b/stand/i386/isoboot/Makefile @@ -59,6 +59,6 @@ ${OBJCOPY} -S -O binary isoboot.out ${.TARGET} isoboot.out: ${BTXCRT} isoboot.o sio.o drv.o cons.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBSA32} + ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} --whole-archive ${LIBSA32} .include diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile --- a/stand/i386/loader/Makefile +++ b/stand/i386/loader/Makefile @@ -85,6 +85,9 @@ LDFLAGS+= -Wl,-z,nostart-stop-gc .endif +LDSYM_SCRIPT= ${.CURDIR}/../loader/Symbol.map +LDFLAGS+= -Wl,--version-script=${LDSYM_SCRIPT} + # i386 standalone support library LIBI386= ${BOOTOBJ}/i386/libi386/libi386.a CFLAGS+= -I${BOOTSRC}/i386 @@ -128,8 +131,8 @@ # files. LDFLAGS+= ${BTXCRT} -DPADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} -LDADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} +DPADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} ${LDSYM_SCRIPT} +LDADD= -Wl,--whole-archive ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBI386} ${LIBSA32} -Wl,--no-whole-archive .if ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -DLOADER_PREFER_AMD64 diff --git a/stand/i386/loader/Symbol.map b/stand/i386/loader/Symbol.map new file mode 100644 --- /dev/null +++ b/stand/i386/loader/Symbol.map @@ -0,0 +1,4 @@ +BIOSLOADER_1.0 { + global: main; + local: *; +}; diff --git a/stand/i386/zfsboot/Makefile b/stand/i386/zfsboot/Makefile --- a/stand/i386/zfsboot/Makefile +++ b/stand/i386/zfsboot/Makefile @@ -87,7 +87,7 @@ ${OBJCOPY} -S -O binary zfsboot.out ${.TARGET} zfsboot.out: ${BTXCRT} ${OBJS} - ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} ${LIBI386} ${LIBSA32} + ${LD} ${LD_FLAGS} --defsym ORG=${ORG2} -T ${LDSCRIPT} -o ${.TARGET} ${.ALLSRC} --whole-archive ${LIBI386} ${LIBSA32} SRCS= zfsboot.c diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c --- a/stand/libsa/zfs/zfsimpl.c +++ b/stand/libsa/zfs/zfsimpl.c @@ -165,9 +165,9 @@ static int vdev_indirect_read(vdev_t *, const blkptr_t *, void *, off_t, size_t); static int vdev_mirror_read(vdev_t *, const blkptr_t *, void *, off_t, size_t); -vdev_indirect_mapping_t *vdev_indirect_mapping_open(spa_t *, objset_phys_t *, +vdev_indirect_mapping_t * __attribute__((weak)) vdev_indirect_mapping_open(spa_t *, objset_phys_t *, uint64_t); -vdev_indirect_mapping_entry_phys_t * +vdev_indirect_mapping_entry_phys_t * __attribute__((weak)) vdev_indirect_mapping_duplicate_adjacent_entries(vdev_t *, uint64_t, uint64_t, uint64_t *); @@ -293,7 +293,7 @@ return (rs); } -vdev_indirect_mapping_t * +vdev_indirect_mapping_t * __attribute__((weak)) vdev_indirect_mapping_open(spa_t *spa, objset_phys_t *os, uint64_t mapping_object) { @@ -506,7 +506,7 @@ * Finally, since we are doing an allocation, it is up to the caller to * free the array allocated in this function. */ -vdev_indirect_mapping_entry_phys_t * +vdev_indirect_mapping_entry_phys_t * __attribute__((weak)) vdev_indirect_mapping_duplicate_adjacent_entries(vdev_t *vd, uint64_t offset, uint64_t asize, uint64_t *copied_entries) { @@ -1729,7 +1729,7 @@ return (rv); } -int +int __attribute__((weak)) vdev_write_bootenv(vdev_t *vdev, nvlist_t *nvl) { vdev_boot_envblock_t *be; @@ -1791,7 +1791,7 @@ * Read the bootenv area from pool label, return the nvlist from it. * We return from first successful read. */ -nvlist_t * +nvlist_t * __attribute__((weak)) vdev_read_bootenv(vdev_t *vdev) { vdev_t *kid; @@ -3206,7 +3206,7 @@ return (zap_list(spa, &child_dir_zap) != 0); } -int +int __attribute__((weak)) zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *, uint64_t)) { diff --git a/stand/userboot/Symbol.map b/stand/userboot/Symbol.map new file mode 100644 --- /dev/null +++ b/stand/userboot/Symbol.map @@ -0,0 +1,4 @@ +USERBOOT_1.0 { + global: loader_main; + local: *; +}; diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile --- a/stand/userboot/userboot/Makefile +++ b/stand/userboot/userboot/Makefile @@ -48,6 +48,8 @@ NEWVERSWHAT= "User boot ${LOADER_INTERP}" ${MACHINE_CPUARCH} VERSION_FILE= ${.CURDIR}/../userboot/version +LDSYM_SCRIPT= ${.CURDIR}/../Symbol.map +LDFLAGS+= -Wl,--version-script=${LDSYM_SCRIPT} .if ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} LINKS+= ${BINDIR}/${SHLIB_NAME} ${BINDIR}/userboot.so @@ -63,7 +65,7 @@ # Always add MI sources .include "${BOOTSRC}/loader.mk" CFLAGS+= -I. -DPADD+= ${LDR_INTERP} ${LIBSA} -LDADD+= ${LDR_INTERP} ${LIBSA} +DPADD+= ${LDR_INTERP} ${LIBSA} ${LDSYM_SCRIPT} +LDADD+= -Wl,--whole-archive ${LDR_INTERP} ${LIBSA} -Wl,--no-whole-archive .include diff --git a/sys/cddl/boot/zfs/blkptr.c b/sys/cddl/boot/zfs/blkptr.c --- a/sys/cddl/boot/zfs/blkptr.c +++ b/sys/cddl/boot/zfs/blkptr.c @@ -43,7 +43,7 @@ * buf must be at least BPE_GET_PSIZE(bp) bytes long (which will never be * more than BPE_PAYLOAD_SIZE bytes). */ -void +void __attribute__((weak)) decode_embedded_bp_compressed(const blkptr_t *bp, void *buf) { int psize;