1125902b6SBryan Drewery 2125902b6SBryan Drewery# Setup variables for the linker. 3125902b6SBryan Drewery# 4125902b6SBryan Drewery# LINKER_TYPE is the major type of linker. Currently binutils and lld support 5125902b6SBryan Drewery# automatic detection. 6125902b6SBryan Drewery# 7125902b6SBryan Drewery# LINKER_VERSION is a numeric constant equal to: 8125902b6SBryan Drewery# major * 10000 + minor * 100 + tiny 9125902b6SBryan Drewery# It too can be overridden on the command line. 10125902b6SBryan Drewery# 11cdd89b98SEd Maste# LINKER_FEATURES may contain one or more of the following, based on 12cdd89b98SEd Maste# linker support for that feature: 13cdd89b98SEd Maste# 14cdd89b98SEd Maste# - build-id: support for generating a Build-ID note 1548164080SEd Maste# - retpoline: support for generating PLT with retpoline speculative 1648164080SEd Maste# execution vulnerability mitigation 17*973bbdabSJose Luis Duran# - bti-report: support for specifying how to report the missing 18*973bbdabSJose Luis Duran# Branch Target Identification (BTI) property (AArch64) 19cdd89b98SEd Maste# 20a7d84af8SBryan Drewery# LINKER_FREEBSD_VERSION is the linker's internal source version. 21a7d84af8SBryan Drewery# 2208154765SBryan Drewery# These variables with an X_ prefix will also be provided if XLD is set. 2308154765SBryan Drewery# 24125902b6SBryan Drewery# This file may be included multiple times, but only has effect the first time. 25125902b6SBryan Drewery# 26125902b6SBryan Drewery 27125902b6SBryan Drewery.if !target(__<bsd.linker.mk>__) 28125902b6SBryan Drewery__<bsd.linker.mk>__: 29125902b6SBryan Drewery 3074f65486SAlex Richardson_ld_vars=LD $${_empty_var_} 3174f65486SAlex Richardson.if !empty(_WANT_TOOLCHAIN_CROSS_VARS) 3274f65486SAlex Richardson# Only the toplevel makefile needs to compute the X_LINKER_* variables. 3374f65486SAlex Richardson_ld_vars+=XLD X_ 3474f65486SAlex Richardson.endif 3574f65486SAlex Richardson 3674f65486SAlex Richardson.for ld X_ in ${_ld_vars} 3708154765SBryan Drewery.if ${ld} == "LD" || !empty(XLD) 3819fad655SBryan Drewery# Try to import LINKER_TYPE and LINKER_VERSION from parent make. 3919fad655SBryan Drewery# The value is only used/exported for the same environment that impacts 4019fad655SBryan Drewery# LD and LINKER_* settings here. 41a7d84af8SBryan Drewery_exported_vars= ${X_}LINKER_TYPE ${X_}LINKER_VERSION ${X_}LINKER_FEATURES \ 42a7d84af8SBryan Drewery ${X_}LINKER_FREEBSD_VERSION 4319fad655SBryan Drewery${X_}_ld_hash= ${${ld}}${MACHINE}${PATH} 4419fad655SBryan Drewery${X_}_ld_hash:= ${${X_}_ld_hash:hash} 45489377c0SAlex Richardson# Only import if none of the vars are set differently somehow else. 4619fad655SBryan Drewery_can_export= yes 4719fad655SBryan Drewery.for var in ${_exported_vars} 48489377c0SAlex Richardson.if defined(${var}) && (!defined(${var}__${${X_}_ld_hash}) || ${${var}__${${X_}_ld_hash}} != ${${var}}) 49489377c0SAlex Richardson.if defined(${var}__${${X_}_ld_hash}) 50bca92be6SJohn Baldwin.info Cannot import ${X_}LINKER variables since cached ${var} is different: ${${var}__${${X_}_ld_hash}} != ${${var}} 51489377c0SAlex Richardson.endif 5219fad655SBryan Drewery_can_export= no 5319fad655SBryan Drewery.endif 5419fad655SBryan Drewery.endfor 5519fad655SBryan Drewery.if ${_can_export} == yes 5619fad655SBryan Drewery.for var in ${_exported_vars} 57dc3c6ad6SAlex Richardson.if defined(${var}__${${X_}_ld_hash}) 58dc3c6ad6SAlex Richardson${var}= ${${var}__${${X_}_ld_hash}} 5919fad655SBryan Drewery.endif 6019fad655SBryan Drewery.endfor 6119fad655SBryan Drewery.endif 6219fad655SBryan Drewery 6308154765SBryan Drewery.if ${ld} == "LD" || (${ld} == "XLD" && ${XLD} != ${LD}) 64ec39013eSBryan Drewery.if !defined(${X_}LINKER_TYPE) || !defined(${X_}LINKER_VERSION) 6501c4f3a7SAlex Richardson_ld_version!= (${${ld}} -v 2>&1 || echo none) | sed -n 1p 66125902b6SBryan Drewery.if ${_ld_version} == "none" 67d786d510SEd Maste.warning Unable to determine linker type from ${ld}=${${ld}} 68125902b6SBryan Drewery.endif 69125902b6SBryan Drewery.if ${_ld_version:[1..2]} == "GNU ld" 7083cff1f8SEd Maste${X_}LINKER_TYPE= bfd 71a7d84af8SBryan Drewery${X_}LINKER_FREEBSD_VERSION= 0 72d54b0ffeSDimitry Andric_v= ${_ld_version:M[1-9]*.[0-9]*:[1]} 73f8147dadSAlex Richardson.elif ${_ld_version:MLLD} 74f8147dadSAlex Richardson# Strip any leading PACKAGE_VENDOR string (e.g. "Homebrew") 75f8147dadSAlex Richardson_ld_version:=${_ld_version:[*]:C/^.* LLD /LLD /:[@]} 7608154765SBryan Drewery${X_}LINKER_TYPE= lld 77125902b6SBryan Drewery_v= ${_ld_version:[2]} 78c246b393SDimitry Andric.if ${_ld_version:[3]} == "(FreeBSD" 799caf7b36SDimitry Andric${X_}LINKER_FREEBSD_VERSION:= ${_ld_version:[4]:C/.*-([^-]*)\)/\1/} 80c246b393SDimitry Andric.else 81c246b393SDimitry Andric${X_}LINKER_FREEBSD_VERSION= 0 82c246b393SDimitry Andric.endif 83c4177f5bSJessica Clarke.elif ${_ld_version:[1]:S/-classic$//} == "@(\#)PROGRAM:ld" 8401c4f3a7SAlex Richardson# bootstrap linker on MacOS 8501c4f3a7SAlex Richardson${X_}LINKER_TYPE= mac 867f9318a0SJessica Clarke_v= ${_ld_version:[2]:C/PROJECT:(ld64|dyld)-//} 8701c4f3a7SAlex Richardson# Convert version 409.12 to 409.12.0 so that the echo + awk below works 8801c4f3a7SAlex Richardson.if empty(_v:M[1-9]*.[0-9]*.[0-9]*) && !empty(_v:M[1-9]*.[0-9]*) 8901c4f3a7SAlex Richardson_v:=${_v}.0 9001c4f3a7SAlex Richardson.else 9101c4f3a7SAlex Richardson# Some versions do not contain a minor version so we need to append .0.0 there 9201c4f3a7SAlex Richardson_v:=${_v}.0.0 9301c4f3a7SAlex Richardson.endif 94125902b6SBryan Drewery.else 95d786d510SEd Maste.warning Unknown linker from ${ld}=${${ld}}: ${_ld_version}, defaulting to bfd 96d786d510SEd Maste${X_}LINKER_TYPE= bfd 97d786d510SEd Maste_v= 2.17.50 98125902b6SBryan Drewery.endif 99d54b0ffeSDimitry Andric${X_}LINKER_VERSION!= echo "${_v:M[1-9]*.[0-9]*}" | \ 10008154765SBryan Drewery awk -F. '{print $$1 * 10000 + $$2 * 100 + $$3;}' 10108154765SBryan Drewery.undef _ld_version 10208154765SBryan Drewery.undef _v 103cdd89b98SEd Maste${X_}LINKER_FEATURES= 104cdd89b98SEd Maste.if ${${X_}LINKER_TYPE} != "bfd" || ${${X_}LINKER_VERSION} > 21750 105cdd89b98SEd Maste${X_}LINKER_FEATURES+= build-id 106ff8f1e83SEd Maste${X_}LINKER_FEATURES+= ifunc 107cdd89b98SEd Maste.endif 1080869dcebSJohn Baldwin.if ${${X_}LINKER_TYPE} == "bfd" && ${${X_}LINKER_VERSION} > 21750 1090869dcebSJohn Baldwin${X_}LINKER_FEATURES+= riscv-relaxations 1100869dcebSJohn Baldwin.endif 11148164080SEd Maste.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 60000 11248164080SEd Maste${X_}LINKER_FEATURES+= retpoline 11348164080SEd Maste.endif 11491b31c10SAlex Richardson.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 90000 11591b31c10SAlex Richardson${X_}LINKER_FEATURES+= ifunc-noplt 11691b31c10SAlex Richardson.endif 117*973bbdabSJose Luis Duran.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 140000 118*973bbdabSJose Luis Duran${X_}LINKER_FEATURES+= bti-report 119*973bbdabSJose Luis Duran.endif 120ec39013eSBryan Drewery.endif 1216f81bd02SBryan Drewery.else 1226f81bd02SBryan Drewery# Use LD's values 1236f81bd02SBryan DreweryX_LINKER_TYPE= ${LINKER_TYPE} 1246f81bd02SBryan DreweryX_LINKER_VERSION= ${LINKER_VERSION} 125cdd89b98SEd MasteX_LINKER_FEATURES= ${LINKER_FEATURES} 126a7d84af8SBryan DreweryX_LINKER_FREEBSD_VERSION= ${LINKER_FREEBSD_VERSION} 12708154765SBryan Drewery.endif # ${ld} == "LD" || (${ld} == "XLD" && ${XLD} != ${LD}) 12808154765SBryan Drewery 12919fad655SBryan Drewery# Export the values so sub-makes don't have to look them up again, using the 13019fad655SBryan Drewery# hash key computed above. 13119fad655SBryan Drewery.for var in ${_exported_vars} 132dc3c6ad6SAlex Richardson${var}__${${X_}_ld_hash}:= ${${var}} 133dc3c6ad6SAlex Richardson.export-env ${var}__${${X_}_ld_hash} 134dc3c6ad6SAlex Richardson.undef ${var}__${${X_}_ld_hash} 13519fad655SBryan Drewery.endfor 13619fad655SBryan Drewery 13708154765SBryan Drewery.endif # ${ld} == "LD" || !empty(XLD) 13808154765SBryan Drewery.endfor # .for ld in LD XLD 13908154765SBryan Drewery 140125902b6SBryan Drewery 141125902b6SBryan Drewery.endif # !target(__<bsd.linker.mk>__) 142