head	1.48;
access;
symbols
	netbsd-11-0-RC5:1.48
	netbsd-11-0-RC4:1.48
	netbsd-11-0-RC3:1.48
	netbsd-11-0-RC2:1.48
	netbsd-11-0-RC1:1.48
	perseant-exfatfs-base-20250801:1.48
	netbsd-11:1.48.0.2
	netbsd-11-base:1.48
	netbsd-10-1-RELEASE:1.41.12.1
	perseant-exfatfs-base-20240630:1.43
	perseant-exfatfs:1.43.0.2
	perseant-exfatfs-base:1.43
	netbsd-8-3-RELEASE:1.37.8.1
	netbsd-9-4-RELEASE:1.41.4.1
	netbsd-10-0-RELEASE:1.41.12.1
	netbsd-10-0-RC6:1.41.12.1
	netbsd-10-0-RC5:1.41.12.1
	netbsd-10-0-RC4:1.41.12.1
	netbsd-10-0-RC3:1.41.12.1
	netbsd-10-0-RC2:1.41.12.1
	netbsd-10-0-RC1:1.41.12.1
	netbsd-10:1.41.0.12
	netbsd-10-base:1.41
	netbsd-9-3-RELEASE:1.41
	cjep_sun2x-base1:1.41
	cjep_sun2x:1.41.0.10
	cjep_sun2x-base:1.41
	cjep_staticlib_x-base1:1.41
	netbsd-9-2-RELEASE:1.41
	cjep_staticlib_x:1.41.0.8
	cjep_staticlib_x-base:1.41
	netbsd-9-1-RELEASE:1.41
	phil-wifi-20200421:1.41
	phil-wifi-20200411:1.41
	is-mlppp:1.41.0.6
	is-mlppp-base:1.41
	phil-wifi-20200406:1.41
	netbsd-8-2-RELEASE:1.37.8.1
	netbsd-9-0-RELEASE:1.41
	netbsd-9-0-RC2:1.41
	netbsd-9-0-RC1:1.41
	phil-wifi-20191119:1.41
	netbsd-9:1.41.0.4
	netbsd-9-base:1.41
	phil-wifi-20190609:1.41
	netbsd-8-1-RELEASE:1.37.8.1
	netbsd-8-1-RC1:1.37.8.1
	pgoyette-compat-merge-20190127:1.40.2.1
	pgoyette-compat-20190127:1.41
	pgoyette-compat-20190118:1.41
	pgoyette-compat-1226:1.41
	pgoyette-compat-1126:1.41
	pgoyette-compat-1020:1.41
	pgoyette-compat-0930:1.41
	pgoyette-compat-0906:1.41
	netbsd-7-2-RELEASE:1.35.8.1
	pgoyette-compat-0728:1.41
	netbsd-8-0-RELEASE:1.37.8.1
	phil-wifi:1.41.0.2
	phil-wifi-base:1.41
	pgoyette-compat-0625:1.41
	netbsd-8-0-RC2:1.37.8.1
	pgoyette-compat-0521:1.41
	pgoyette-compat-0502:1.41
	pgoyette-compat-0422:1.41
	netbsd-8-0-RC1:1.37.8.1
	pgoyette-compat-0415:1.41
	pgoyette-compat-0407:1.41
	pgoyette-compat-0330:1.40
	pgoyette-compat-0322:1.40
	pgoyette-compat-0315:1.40
	netbsd-7-1-2-RELEASE:1.35.8.1
	pgoyette-compat:1.40.0.2
	pgoyette-compat-base:1.40
	netbsd-7-1-1-RELEASE:1.35.8.1
	matt-nb8-mediatek:1.37.8.1.0.2
	matt-nb8-mediatek-base:1.37.8.1
	perseant-stdc-iso10646:1.38.0.2
	perseant-stdc-iso10646-base:1.38
	netbsd-8:1.37.0.8
	netbsd-8-base:1.37
	prg-localcount2-base3:1.37
	prg-localcount2-base2:1.37
	prg-localcount2-base1:1.37
	prg-localcount2:1.37.0.6
	prg-localcount2-base:1.37
	pgoyette-localcount-20170426:1.37
	bouyer-socketcan-base1:1.37
	pgoyette-localcount-20170320:1.37
	netbsd-7-1:1.35.8.1.0.4
	netbsd-7-1-RELEASE:1.35.8.1
	netbsd-7-1-RC2:1.35.8.1
	netbsd-7-nhusb-base-20170116:1.35.8.1
	bouyer-socketcan:1.37.0.4
	bouyer-socketcan-base:1.37
	pgoyette-localcount-20170107:1.37
	netbsd-7-1-RC1:1.35.8.1
	pgoyette-localcount-20161104:1.37
	netbsd-7-0-2-RELEASE:1.35
	localcount-20160914:1.37
	netbsd-7-nhusb:1.35.8.1.0.2
	netbsd-7-nhusb-base:1.35.8.1
	pgoyette-localcount-20160806:1.37
	pgoyette-localcount-20160726:1.37
	pgoyette-localcount:1.37.0.2
	pgoyette-localcount-base:1.37
	netbsd-7-0-1-RELEASE:1.35
	netbsd-7-0:1.35.0.10
	netbsd-7-0-RELEASE:1.35
	netbsd-7-0-RC3:1.35
	netbsd-7-0-RC2:1.35
	netbsd-7-0-RC1:1.35
	netbsd-5-2-3-RELEASE:1.26.4.1
	netbsd-5-1-5-RELEASE:1.26
	netbsd-6-0-6-RELEASE:1.34
	netbsd-6-1-5-RELEASE:1.34.6.1
	netbsd-7:1.35.0.8
	netbsd-7-base:1.35
	yamt-pagecache-base9:1.35
	yamt-pagecache-tag8:1.34.4.1
	netbsd-6-1-4-RELEASE:1.34.6.1
	netbsd-6-0-5-RELEASE:1.34
	tls-earlyentropy:1.35.0.6
	tls-earlyentropy-base:1.35
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.35
	riastradh-drm2-base3:1.35
	netbsd-6-1-3-RELEASE:1.34.6.1
	netbsd-6-0-4-RELEASE:1.34
	netbsd-5-2-2-RELEASE:1.26.4.1
	netbsd-5-1-4-RELEASE:1.26
	netbsd-6-1-2-RELEASE:1.34.6.1
	netbsd-6-0-3-RELEASE:1.34
	netbsd-5-2-1-RELEASE:1.26.4.1
	netbsd-5-1-3-RELEASE:1.26
	netbsd-6-1-1-RELEASE:1.34.6.1
	riastradh-drm2-base2:1.35
	riastradh-drm2-base1:1.35
	riastradh-drm2:1.35.0.2
	riastradh-drm2-base:1.35
	netbsd-6-1:1.34.6.1.0.2
	netbsd-6-0-2-RELEASE:1.34
	netbsd-6-1-RELEASE:1.34.6.1
	netbsd-6-1-RC4:1.34.6.1
	netbsd-6-1-RC3:1.34.6.1
	agc-symver:1.35.0.4
	agc-symver-base:1.35
	netbsd-6-1-RC2:1.34.6.1
	netbsd-6-1-RC1:1.34.6.1
	yamt-pagecache-base8:1.35
	netbsd-5-2:1.26.4.1.0.2
	netbsd-6-0-1-RELEASE:1.34
	yamt-pagecache-base7:1.35
	netbsd-5-2-RELEASE:1.26.4.1
	netbsd-5-2-RC1:1.26.4.1
	matt-nb6-plus-nbase:1.34
	yamt-pagecache-base6:1.34
	netbsd-6-0:1.34.0.12
	netbsd-6-0-RELEASE:1.34
	netbsd-6-0-RC2:1.34
	tls-maxphys:1.34.0.10
	tls-maxphys-base:1.35
	matt-nb6-plus:1.34.0.8
	matt-nb6-plus-base:1.34
	netbsd-6-0-RC1:1.34
	yamt-pagecache-base5:1.34
	yamt-pagecache-base4:1.34
	netbsd-6:1.34.0.6
	netbsd-6-base:1.34
	netbsd-5-1-2-RELEASE:1.26
	netbsd-5-1-1-RELEASE:1.26
	yamt-pagecache-base3:1.34
	yamt-pagecache-base2:1.34
	yamt-pagecache:1.34.0.4
	yamt-pagecache-base:1.34
	cherry-xenmp:1.34.0.2
	cherry-xenmp-base:1.34
	bouyer-quota2-nbase:1.32
	bouyer-quota2:1.32.0.2
	bouyer-quota2-base:1.32
	matt-mips64-premerge-20101231:1.32
	matt-nb5-mips64-premerge-20101231:1.26
	matt-nb5-pq3:1.26.0.14
	matt-nb5-pq3-base:1.26
	netbsd-5-1:1.26.0.12
	netbsd-5-1-RELEASE:1.26
	netbsd-5-1-RC4:1.26
	matt-nb5-mips64-k15:1.26
	netbsd-5-1-RC3:1.26
	netbsd-5-1-RC2:1.26
	netbsd-5-1-RC1:1.26
	netbsd-5-0-2-RELEASE:1.26
	matt-nb5-mips64-premerge-20091211:1.26
	matt-premerge-20091211:1.28
	matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.26
	matt-nb4-mips64-k7-u2a-k9b:1.26
	matt-nb5-mips64-u1-k1-k5:1.26
	matt-nb5-mips64:1.26.0.10
	netbsd-5-0-1-RELEASE:1.26
	jym-xensuspend-nbase:1.27
	netbsd-5-0:1.26.0.8
	netbsd-5-0-RELEASE:1.26
	netbsd-5-0-RC4:1.26
	netbsd-5-0-RC3:1.26
	netbsd-5-0-RC2:1.26
	jym-xensuspend:1.26.0.6
	jym-xensuspend-base:1.27
	netbsd-5-0-RC1:1.26
	netbsd-5:1.26.0.4
	netbsd-5-base:1.26
	matt-mips64-base2:1.26
	matt-mips64:1.23.0.14
	netbsd-4-0-1-RELEASE:1.22
	wrstuden-revivesa-base-3:1.26
	wrstuden-revivesa-base-2:1.26
	wrstuden-fixsa-newbase:1.22
	wrstuden-revivesa-base-1:1.23
	yamt-pf42-base4:1.23
	yamt-pf42-base3:1.23
	hpcarm-cleanup-nbase:1.23
	yamt-pf42-baseX:1.23
	yamt-pf42-base2:1.23
	wrstuden-revivesa:1.23.0.12
	wrstuden-revivesa-base:1.23
	yamt-pf42:1.23.0.10
	yamt-pf42-base:1.23
	keiichi-mipv6:1.23.0.8
	keiichi-mipv6-base:1.23
	matt-armv6-nbase:1.23
	matt-armv6-prevmlocking:1.23
	wrstuden-fixsa-base-1:1.22
	netbsd-4-0:1.22.0.8
	netbsd-4-0-RELEASE:1.22
	cube-autoconf:1.23.0.6
	cube-autoconf-base:1.23
	netbsd-4-0-RC5:1.22
	netbsd-4-0-RC4:1.22
	netbsd-4-0-RC3:1.22
	netbsd-4-0-RC2:1.22
	netbsd-4-0-RC1:1.22
	matt-armv6:1.23.0.4
	matt-armv6-base:1.23
	matt-mips64-base:1.23
	hpcarm-cleanup:1.23.0.2
	hpcarm-cleanup-base:1.23
	netbsd-3-1-1-RELEASE:1.19
	netbsd-3-0-3-RELEASE:1.19
	wrstuden-fixsa:1.22.0.6
	wrstuden-fixsa-base:1.22
	abandoned-netbsd-4-base:1.22
	abandoned-netbsd-4:1.22.0.2
	netbsd-3-1:1.19.0.14
	netbsd-3-1-RELEASE:1.19
	netbsd-3-0-2-RELEASE:1.19
	netbsd-3-1-RC4:1.19
	netbsd-3-1-RC3:1.19
	netbsd-3-1-RC2:1.19
	netbsd-3-1-RC1:1.19
	netbsd-4:1.22.0.4
	netbsd-4-base:1.22
	netbsd-3-0-1-RELEASE:1.19
	netbsd-3-0:1.19.0.12
	netbsd-3-0-RELEASE:1.19
	netbsd-3-0-RC6:1.19
	netbsd-3-0-RC5:1.19
	netbsd-3-0-RC4:1.19
	netbsd-3-0-RC3:1.19
	netbsd-3-0-RC2:1.19
	netbsd-3-0-RC1:1.19
	netbsd-2-0-3-RELEASE:1.19
	netbsd-2-1:1.19.0.10
	netbsd-2-1-RELEASE:1.19
	netbsd-2-1-RC6:1.19
	netbsd-2-1-RC5:1.19
	netbsd-2-1-RC4:1.19
	netbsd-2-1-RC3:1.19
	netbsd-2-1-RC2:1.19
	netbsd-2-1-RC1:1.19
	netbsd-2-0-2-RELEASE:1.19
	netbsd-3:1.19.0.8
	netbsd-3-base:1.19
	netbsd-2-0-1-RELEASE:1.19
	netbsd-2:1.19.0.6
	netbsd-2-base:1.19
	netbsd-2-0-RELEASE:1.19
	netbsd-2-0-RC5:1.19
	netbsd-2-0-RC4:1.19
	netbsd-2-0-RC3:1.19
	netbsd-2-0-RC2:1.19
	netbsd-2-0-RC1:1.19
	netbsd-1-6:1.19.0.4
	netbsd-2-0:1.19.0.2
	netbsd-2-0-base:1.19
	fvdl_fs64_base:1.18;
locks; strict;
comment	@ * @;


1.48
date	2025.04.16.17.37.48;	author riastradh;	state Exp;
branches;
next	1.47;
commitid	J3p1tLYgOnh7KiRF;

1.47
date	2024.11.30.01.04.05;	author christos;	state Exp;
branches;
next	1.46;
commitid	9IgKMo5UmOjDDBzF;

1.46
date	2024.11.04.15.46.45;	author christos;	state Exp;
branches;
next	1.45;
commitid	EtZlJovg9AWXmlwF;

1.45
date	2024.11.03.22.24.20;	author christos;	state Exp;
branches;
next	1.44;
commitid	odNoWahGdF04BfwF;

1.44
date	2024.08.03.21.59.58;	author riastradh;	state Exp;
branches;
next	1.43;
commitid	R5nq4VHUPO6kqqkF;

1.43
date	2023.06.04.20.02.29;	author martin;	state Exp;
branches
	1.43.2.1;
next	1.42;
commitid	LsPIvBnnJInHsFrE;

1.42
date	2023.06.04.01.24.57;	author joerg;	state Exp;
branches;
next	1.41;
commitid	jBAtDE6SYslzbzrE;

1.41
date	2018.04.03.21.10.27;	author joerg;	state Exp;
branches
	1.41.4.1
	1.41.12.1;
next	1.40;
commitid	pNUMy9CwSMm3w2xA;

1.40
date	2017.11.06.21.16.04;	author joerg;	state Exp;
branches
	1.40.2.1;
next	1.39;
commitid	XwUFbplE2Hyqj1eA;

1.39
date	2017.08.10.19.03.26;	author joerg;	state Exp;
branches;
next	1.38;
commitid	UgH5577k4GrjpH2A;

1.38
date	2017.06.19.11.57.01;	author joerg;	state Exp;
branches;
next	1.37;
commitid	pYVYx1tH1kZmHYVz;

1.37
date	2014.08.31.20.06.22;	author joerg;	state Exp;
branches
	1.37.8.1;
next	1.36;
commitid	0aijKisx03iujyOx;

1.36
date	2014.08.25.20.40.52;	author joerg;	state Exp;
branches;
next	1.35;
commitid	hm6gwLhn9YorHMNx;

1.35
date	2012.11.07.07.24.46;	author apb;	state Exp;
branches
	1.35.8.1;
next	1.34;

1.34
date	2011.03.25.18.07.05;	author joerg;	state Exp;
branches
	1.34.4.1
	1.34.6.1
	1.34.10.1;
next	1.33;

1.33
date	2011.03.12.22.54.36;	author joerg;	state Exp;
branches;
next	1.32;

1.32
date	2010.08.06.16.33.18;	author joerg;	state Exp;
branches;
next	1.31;

1.31
date	2010.01.14.11.58.32;	author skrll;	state Exp;
branches;
next	1.30;

1.30
date	2010.01.13.22.34.07;	author skrll;	state Exp;
branches;
next	1.29;

1.29
date	2010.01.13.20.17.22;	author christos;	state Exp;
branches;
next	1.28;

1.28
date	2009.08.29.13.46.54;	author jmmv;	state Exp;
branches;
next	1.27;

1.27
date	2009.03.16.02.44.47;	author lukem;	state Exp;
branches;
next	1.26;

1.26
date	2008.07.24.04.39.25;	author matt;	state Exp;
branches
	1.26.4.1
	1.26.6.1;
next	1.25;

1.25
date	2008.07.23.18.16.42;	author christos;	state Exp;
branches;
next	1.24;

1.24
date	2008.07.22.22.27.07;	author christos;	state Exp;
branches;
next	1.23;

1.23
date	2007.02.23.01.17.11;	author matt;	state Exp;
branches
	1.23.12.1;
next	1.22;

1.22
date	2006.03.18.23.09.34;	author christos;	state Exp;
branches;
next	1.21;

1.21
date	2005.08.20.19.01.17;	author skrll;	state Exp;
branches;
next	1.20;

1.20
date	2005.06.01.14.15.13;	author lukem;	state Exp;
branches;
next	1.19;

1.19
date	2003.07.24.10.12.28;	author skrll;	state Exp;
branches
	1.19.4.1;
next	1.18;

1.18
date	2002.10.03.20.39.22;	author mycroft;	state Exp;
branches;
next	1.17;

1.17
date	2002.09.26.20.42.11;	author mycroft;	state Exp;
branches;
next	1.16;

1.16
date	2002.09.25.07.27.52;	author mycroft;	state Exp;
branches;
next	1.15;

1.15
date	2002.09.17.07.29.49;	author junyoung;	state Exp;
branches;
next	1.14;

1.14
date	2002.09.12.22.56.30;	author mycroft;	state Exp;
branches;
next	1.13;

1.13
date	2002.09.12.20.21.00;	author mycroft;	state Exp;
branches;
next	1.12;

1.12
date	2002.09.11.17.23.25;	author mycroft;	state Exp;
branches;
next	1.11;

1.11
date	2002.09.11.14.19.30;	author junyoung;	state Exp;
branches;
next	1.10;

1.10
date	2002.09.09.14.08.08;	author mycroft;	state Exp;
branches;
next	1.9;

1.9
date	2002.09.06.15.17.56;	author mycroft;	state Exp;
branches;
next	1.8;

1.8
date	2002.09.06.13.20.32;	author mycroft;	state Exp;
branches;
next	1.7;

1.7
date	2002.09.06.03.12.06;	author mycroft;	state Exp;
branches;
next	1.6;

1.6
date	2002.09.06.03.05.36;	author mycroft;	state Exp;
branches;
next	1.5;

1.5
date	2002.09.05.21.31.33;	author mycroft;	state Exp;
branches;
next	1.4;

1.4
date	2002.09.05.21.21.10;	author mycroft;	state Exp;
branches;
next	1.3;

1.3
date	2002.09.05.20.08.17;	author mycroft;	state Exp;
branches;
next	1.2;

1.2
date	2002.09.05.18.25.46;	author mycroft;	state Exp;
branches;
next	1.1;

1.1
date	2002.09.05.15.38.26;	author mycroft;	state Exp;
branches;
next	;

1.43.2.1
date	2025.08.02.05.55.02;	author perseant;	state Exp;
branches;
next	;
commitid	23j6GFaDws3O875G;

1.41.4.1
date	2023.08.04.12.55.48;	author martin;	state Exp;
branches;
next	;
commitid	WQUk0iGBkKS39tzE;

1.41.12.1
date	2023.08.01.16.34.59;	author martin;	state Exp;
branches;
next	;
commitid	ygiHGMga8HEgs6zE;

1.40.2.1
date	2018.04.07.04.12.09;	author pgoyette;	state Exp;
branches;
next	;
commitid	ZMkKSYuBapz7LsxA;

1.37.8.1
date	2017.07.04.12.47.59;	author martin;	state Exp;
branches;
next	;
commitid	WH1NGk1BGSqEwUXz;

1.35.8.1
date	2016.03.06.18.17.55;	author martin;	state Exp;
branches;
next	;
commitid	Ns3WeAQc8ORoVBXy;

1.34.4.1
date	2013.01.16.05.32.30;	author yamt;	state Exp;
branches;
next	;

1.34.6.1
date	2012.11.18.18.50.56;	author msaitoh;	state Exp;
branches;
next	;

1.34.10.1
date	2012.11.20.03.00.46;	author tls;	state Exp;
branches;
next	;

1.26.4.1
date	2012.03.17.18.28.36;	author bouyer;	state Exp;
branches;
next	;

1.26.6.1
date	2009.05.13.19.18.41;	author jym;	state Exp;
branches;
next	;

1.23.12.1
date	2008.09.18.04.39.18;	author wrstuden;	state Exp;
branches;
next	;

1.19.4.1
date	2003.07.24.10.12.28;	author tron;	state dead;
branches;
next	1.19.4.2;

1.19.4.2
date	2004.05.28.08.31.22;	author tron;	state Exp;
branches;
next	;


desc
@@


1.48
log
@ld.elf_so/arch/i386: Add ELF references.

Also copy the copyright notice from the file this one was originally
derived from back in 2002.
@
text
@/*	$NetBSD: mdreloc.c,v 1.47 2024/11/30 01:04:05 christos Exp $	*/

/*
 * Copyright 1996 John D. Polstra.
 * Copyright 1996 Matt Thomas <matt@@3am-software.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by John Polstra.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * i386 ELF relocations.
 *
 * References:
 *
 *	[ABI386-4] System V Application Binary Interface: Intel386
 *	Architecture Processor Supplement, Fourth Edition, 1997-03-19,
 *	The Santa Cruz Operation, Inc.
 *	https://www.sco.com/developers/devspecs/abi386-4.pdf
 *	https://web.archive.org/web/20250329184450/https://www.sco.com/developers/devspecs/abi386-4.pdf
 *
 * Note: Intel and SuSE have published an update to the i386 ELF
 * supplement, but it is not entirely compatible (e.g., it requires
 * 16-byte alignment for the stack pointer, not just 4-byte alignment),
 * so it is not reliable as a normative reference:
 *
 *	[ABI386-2015] System V Application Binary Interface: Intel386
 *	Architecture Processor Supplement, Version 1.0, 2015-02-03.
 *	https://uclibc.org/docs/psABI-i386.pdf
 *	https://web.archive.org/web/20250118211449/https://uclibc.org/docs/psABI-i386.pdf
 *	https://gitlab.com/x86-psABIs/i386-ABI
 */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.47 2024/11/30 01:04:05 christos Exp $");
#endif /* not lint */

#include <sys/types.h>
#include <machine/lwp_private.h>

#include "debug.h"
#include "rtld.h"

void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);

#define rdbg_symname(obj, rela) \
	((obj)->strtab + (obj)->symtab[ELF_R_SYM((rela)->r_info)].st_name)

void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
	obj->pltgot[1] = (Elf_Addr) obj;
	obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}

void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
	const Elf_Rel *rel = 0, *rellim;
	Elf_Addr relsz = 0;
	Elf_Addr *where;

	for (; dynp->d_tag != DT_NULL; dynp++) {
		switch (dynp->d_tag) {
		case DT_REL:
			rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_RELSZ:
			relsz = dynp->d_un.d_val;
			break;
		}
	}
	if (rel == 0 || relsz == 0)
		return;
	rellim = (const Elf_Rel *)((const uint8_t *)rel + relsz);
	for (; rel < rellim; rel++) {
		where = (Elf_Addr *)(relocbase + rel->r_offset);
		*where += (Elf_Addr)relocbase;
	}
}

int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
	const Elf_Rel *rel;
	Elf_Addr target = 0;
	const Elf_Sym   *def = NULL;
	const Obj_Entry *defobj = NULL;
	unsigned long last_symnum = ULONG_MAX;

	for (rel = obj->rel; rel < obj->rellim; rel++) {
		Elf_Addr        *where;
		Elf_Addr         tmp;
		unsigned long	 symnum;

		where = (Elf_Addr *)(obj->relocbase + rel->r_offset);

		switch (ELF_R_TYPE(rel->r_info)) {
		case R_TYPE(PC32):
		case R_TYPE(GOT32):
		case R_TYPE(32):
		case R_TYPE(GLOB_DAT):
		case R_TYPE(TLS_TPOFF):
		case R_TYPE(TLS_TPOFF32):
		case R_TYPE(TLS_DTPMOD32):
		case R_TYPE(TLS_DTPOFF32):
			symnum = ELF_R_SYM(rel->r_info);
			if (symnum != last_symnum) {
				last_symnum = symnum;
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
			}
			break;
		default:
			break;
		}


		switch (ELF_R_TYPE(rel->r_info)) {
		case R_TYPE(NONE):
			break;

#if 1 /* XXX should not occur */
		case R_TYPE(PC32):
			target = (Elf_Addr)(defobj->relocbase + def->st_value);

			*where += target - (Elf_Addr)where;
			rdbg(("PC32 %s in %s --> %p in %s",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where, defobj->path));
			break;

		case R_TYPE(GOT32):
#endif
		case R_TYPE(32):
		case R_TYPE(GLOB_DAT):
			target = (Elf_Addr)(defobj->relocbase + def->st_value);

			tmp = target + *where;
			if (*where != tmp)
				*where = tmp;
			rdbg(("32/GLOB_DAT %s in %s --> %p in %s",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where, defobj->path));
			break;


		case R_TYPE(IRELATIVE):
			/* IFUNC relocations are handled in _rtld_call_ifunc */
			if (obj->ifunc_remaining_nonplt == 0) {
				obj->ifunc_remaining_nonplt =
				    obj->rellim - rel;
			}
			/* FALL-THROUGH */

		case R_TYPE(RELATIVE):
			*where += (Elf_Addr)obj->relocbase;
			rdbg(("RELATIVE in %s --> %p", obj->path,
			    (void *)*where));
			break;

		case R_TYPE(COPY):
			/*
			 * These are deferred until all other relocations have
			 * been done.  All we do here is make sure that the
			 * COPY relocation is not in a shared library.  They
			 * are allowed only in executable files.
			 */
			if (obj->isdynamic) {
				_rtld_error(
			"%s: Unexpected R_COPY relocation in shared library",
				    obj->path);
				return -1;
			}
			rdbg(("COPY (avoid in main)"));
			break;

		case R_TYPE(TLS_TPOFF):
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
				return -1;

			*where += (Elf_Addr)(def->st_value - defobj->tlsoffset);

			rdbg(("TLS_TPOFF %s in %s --> %p",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where));
			break;

		case R_TYPE(TLS_TPOFF32):
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
				return -1;

			*where += (Elf_Addr)(defobj->tlsoffset - def->st_value);
			rdbg(("TLS_TPOFF32 %s in %s --> %p",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where));
			break;

		case R_TYPE(TLS_DTPMOD32):
			*where = (Elf_Addr)(defobj->tlsindex);

			rdbg(("TLS_DTPMOD32 %s in %s --> %p",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where));
			break;

		case R_TYPE(TLS_DTPOFF32):
			*where = (Elf_Addr)(def->st_value);

			rdbg(("TLS_DTPOFF32 %s in %s --> %p",
			    rdbg_symname(obj, rel),
			    obj->path, (void *)*where));

			break;

		default:
			rdbg(("sym = %lu, type = %lu, offset = %p, "
			    "contents = %p, symbol = %s",
			    (u_long)ELF_R_SYM(rel->r_info),
			    (u_long)ELF_R_TYPE(rel->r_info),
			    (void *)rel->r_offset, (void *)*where,
			    rdbg_symname(obj, rel)));
			_rtld_error("%s: Unsupported relocation type %ld "
			    "in non-PLT relocations",
			    obj->path, (u_long) ELF_R_TYPE(rel->r_info));
			return -1;
		}
	}
	return 0;
}

int
_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
	const Elf_Rel *rel;

	for (rel = obj->pltrellim; rel-- > obj->pltrel; ) {
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);

		assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT) ||
		       ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE));

		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE))
			obj->ifunc_remaining = obj->pltrellim - rel;

		/* Just relocate the GOT slots pointing into the PLT */
		*where += (Elf_Addr)obj->relocbase;
		rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
	}

	return 0;
}

static inline int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
	Elf_Addr *tp)
{
	Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
	Elf_Addr target;
	const Elf_Sym *def;
	const Obj_Entry *defobj;
	unsigned long info = rel->r_info;

	if (ELF_R_TYPE(info) == R_TYPE(IRELATIVE))
		return 0;

	assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));

	def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
	if (__predict_false(def == NULL))
		return -1;
	if (__predict_false(def == &_rtld_sym_zero))
		return 0;

	if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
		if (tp == NULL)
			return 0;
		target = _rtld_resolve_ifunc(defobj, def);
	} else {
		target = (Elf_Addr)(defobj->relocbase + def->st_value);
	}

	rdbg(("bind now/fixup in %s --> old=%p new=%p",
	    defobj->strtab + def->st_name, (void *)*where,
	    (void *)target));
	if (*where != target)
		*where = target;
	if (tp)
		*tp = target;
	return 0;
}

caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
	const Elf_Rel *rel = (const Elf_Rel *)((const uint8_t *)obj->pltrel
	    + reloff);
	Elf_Addr new_value;
	int err;

	new_value = 0;	/* XXX gcc */

	_rtld_shared_enter();
	err = _rtld_relocate_plt_object(obj, rel, &new_value);
	if (err)
		_rtld_die();
	_rtld_shared_exit();

	return (caddr_t)new_value;
}

int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
	const Elf_Rel *rel;
	int err = 0;

	for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
		err = _rtld_relocate_plt_object(obj, rel, NULL);
		if (err)
			break;
	}
	return err;
}

/*
 * i386 specific GNU variant of __tls_get_addr using register based
 * argument passing.
 */
#define	DTV_MAX_INDEX(dtv)	((size_t)((dtv)[-1]))

__dso_public __attribute__((__regparm__(1))) void *
___tls_get_addr(void *arg_)
{
	size_t *arg = (size_t *)arg_;
	void **dtv;
	struct tls_tcb *tcb = __lwp_getprivate_fast();
	size_t idx = arg[0], offset = arg[1];

	dtv = tcb->tcb_dtv;

	if (__predict_true(idx < DTV_MAX_INDEX(dtv) && dtv[idx] != NULL))
		return (uint8_t *)dtv[idx] + offset;

	return _rtld_tls_get_addr(tcb, idx, offset);
}
@


1.47
log
@Create a new header lwp_private.h to contain _lwp_getprivate_fast,
_lwp_gettcb_fast, _lwp_settcb and remove them from mcontext.h, so that:
1. we don't need special hacks to hide them
2. we can include <lwp.h> where needed to get the necessary prototypes
   without redefining them locally.
@
text
@d1 55
a55 1
/*	$NetBSD: mdreloc.c,v 1.46 2024/11/04 15:46:45 christos Exp $	*/
d59 1
a59 1
__RCSID("$NetBSD: mdreloc.c,v 1.46 2024/11/04 15:46:45 christos Exp $");
@


1.46
log
@Undo previous lwp.h change
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.44 2024/08/03 21:59:58 riastradh Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.44 2024/08/03 21:59:58 riastradh Exp $");
d9 1
a9 1
#include <sys/ucontext.h>
@


1.45
log
@Split __lwp_getprivate_fast and __lwp_*tcb from mcontext.h into a separate
lwp.h file.
@
text
@d9 1
a9 1
#include <lwp.h>
@


1.44
log
@ld.elf_so(1): Nix trailing whitespace.

No functional change intended.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $");
d9 1
a9 1
#include <sys/ucontext.h>
@


1.43
log
@Avoid using uninitialized variable "symnum" when building with DEBUG
enabled by borrowing the rdbg_symname() macro from arch/x86_64.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.42 2023/06/04 01:24:57 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.42 2023/06/04 01:24:57 joerg Exp $");
d260 1
a260 1
	    defobj->strtab + def->st_name, (void *)*where, 
d293 1
a293 1
	
@


1.43.2.1
log
@Sync with HEAD
@
text
@d1 1
a1 55
/*	$NetBSD: mdreloc.c,v 1.48 2025/04/16 17:37:48 riastradh Exp $	*/

/*
 * Copyright 1996 John D. Polstra.
 * Copyright 1996 Matt Thomas <matt@@3am-software.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by John Polstra.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * i386 ELF relocations.
 *
 * References:
 *
 *	[ABI386-4] System V Application Binary Interface: Intel386
 *	Architecture Processor Supplement, Fourth Edition, 1997-03-19,
 *	The Santa Cruz Operation, Inc.
 *	https://www.sco.com/developers/devspecs/abi386-4.pdf
 *	https://web.archive.org/web/20250329184450/https://www.sco.com/developers/devspecs/abi386-4.pdf
 *
 * Note: Intel and SuSE have published an update to the i386 ELF
 * supplement, but it is not entirely compatible (e.g., it requires
 * 16-byte alignment for the stack pointer, not just 4-byte alignment),
 * so it is not reliable as a normative reference:
 *
 *	[ABI386-2015] System V Application Binary Interface: Intel386
 *	Architecture Processor Supplement, Version 1.0, 2015-02-03.
 *	https://uclibc.org/docs/psABI-i386.pdf
 *	https://web.archive.org/web/20250118211449/https://uclibc.org/docs/psABI-i386.pdf
 *	https://gitlab.com/x86-psABIs/i386-ABI
 */
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.48 2025/04/16 17:37:48 riastradh Exp $");
d9 1
a9 1
#include <machine/lwp_private.h>
d260 1
a260 1
	    defobj->strtab + def->st_name, (void *)*where,
d293 1
a293 1

@


1.42
log
@Fix interactions of initial-exec TLS model and dlopen

(1) If an initial-exec relocation was used for a non-local symbol
(i.e. the definition of the symbol is in a different DSO), the
computation of the static TLS offset used the wrong DSO.
This would effectively mean the wrong address was computed
(PR toolchain/50277, PR pkg/57445).

Fix this by forcing the computation of the correct DSO (the one defining
the symbol).

This code uses __UNCONST to avoid the vast interface changes for this
special case.

(2) If symbols from a DSO loaded via dlopen are used with both
global-dynamic/local-dynamic and initial-exec relocations AND
a initial-exec relocation was resolved first in a thread, a split brain
situation could exist where the dynamic relocations would use one memory
block (separate allocation) and the initial-exec relocations the static
per-thread TLS space.

(3) If the initial-exec relocation in (2) is seen after any thread has
already used a GD/LD allocation, bail out. Since IE relocations are used
only in the GOT, this will prevent the dlopen. This is a bit more
aggressive than necessary, but a full blown reference counting doesn't
seem to be justified.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $");
d18 3
d103 1
a103 1
			    obj->strtab + obj->symtab[symnum].st_name,
d117 1
a117 1
			    obj->strtab + obj->symtab[symnum].st_name,
d160 1
a160 1
			    obj->strtab + obj->symtab[symnum].st_name,
d171 1
a171 1
			    obj->strtab + obj->symtab[symnum].st_name,
d179 1
a179 1
			    obj->strtab + obj->symtab[symnum].st_name,
d187 1
a187 1
			    obj->strtab + obj->symtab[symnum].st_name,
d198 1
a198 1
			    obj->strtab + obj->symtab[symnum].st_name));
@


1.41
log
@Rework ifunc support to address a number of short comings:
- Move to a shared _rtld_call_ifunc for rel and rela architectures
- Architectures using rel format must patch IRELATIVE non-PLT
  relocations like RELATIVE in additition to the later ifunc handling
- Consistently record the delta to the end of the relocation group for
  non-PLT IRELATIVE relocations

Hidden ifunc is now supported on all ifunc platforms, even when using
-fno-plt. The combination of -fno-plt and relro is broken due to
incorrect GNU ld output though.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.40 2017/11/06 21:16:04 joerg Exp $");
d150 2
a151 2
			if (!defobj->tls_done &&
			    _rtld_tls_offset_allocate(obj))
d162 2
a163 2
			if (!defobj->tls_done &&
			    _rtld_tls_offset_allocate(obj))
@


1.41.4.1
log
@Pull up following revision(s), all via patch,
(requested by riastradh in ticket #1699):

	distrib/sets/lists/tests/shl.mi: revision 1.14
	distrib/sets/lists/tests/shl.mi: revision 1.15
	distrib/sets/lists/tests/shl.mi: revision 1.16
	tests/libexec/ld.elf_so/helper_def_static/h_def_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_def_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_def_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_onlyuse_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_static/Makefile: revision 1.2
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.75
	distrib/sets/lists/tests/mi: revision 1.1265
	libexec/ld.elf_so/arch/sh3/mdreloc.c: revision 1.36
	libexec/ld.elf_so/rtld.c: revision 1.214
	tests/libexec/ld.elf_so/helper_onlydef_static/Makefile: revision 1.1
	distrib/sets/lists/debug/mi: revision 1.400
	tests/libexec/ld.elf_so/helper_onlydef_static/Makefile: revision 1.2
	distrib/sets/lists/debug/mi: revision 1.401
	distrib/sets/lists/debug/mi: revision 1.402
	tests/libexec/ld.elf_so/helper_dso2/Makefile: revision 1.2
	distrib/sets/lists/debug/mi: revision 1.403
	tests/libexec/ld.elf_so/helper_symver_dso0/Makefile: revision 1.2
	libexec/ld.elf_so/arch/x86_64/mdreloc.c: revision 1.48
	distrib/sets/lists/debug/mi: revision 1.406
	tests/libexec/ld.elf_so/helper_use_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_use_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_ifunc_dso/Makefile: revision 1.2
	libexec/ld.elf_so/arch/sparc64/mdreloc.c: revision 1.70
	libexec/ld.elf_so/arch/aarch64/mdreloc.c: revision 1.18
	tests/libexec/ld.elf_so/helper_abuse_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_abuse_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/Makefile: revision 1.13
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.46
	libexec/ld.elf_so/rtld.h: revision 1.146
	tests/libexec/ld.elf_so/Makefile: revision 1.14
	distrib/sets/lists/debug/shl.mi: revision 1.306
	tests/libexec/ld.elf_so/Makefile: revision 1.15
	tests/libexec/ld.elf_so/helper_abuse_static/Makefile: revision 1.1
	distrib/sets/lists/debug/shl.mi: revision 1.307
	tests/libexec/ld.elf_so/Makefile: revision 1.16
	tests/libexec/ld.elf_so/helper_abuse_static/Makefile: revision 1.2
	distrib/sets/lists/debug/shl.mi: revision 1.308
	tests/libexec/ld.elf_so/Makefile: revision 1.17
	distrib/sets/lists/debug/shl.mi: revision 1.309
	tests/libexec/ld.elf_so/Makefile: revision 1.18
	tests/libexec/ld.elf_so/Makefile: revision 1.19
	libexec/ld.elf_so/tls.c: revision 1.16
	libexec/ld.elf_so/tls.c: revision 1.17
	libexec/ld.elf_so/tls.c: revision 1.18
	libexec/ld.elf_so/tls.c: revision 1.19
	tests/libexec/ld.elf_so/helper_onlydef_static/h_onlydef_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/h_use_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/h_use_static.c: revision 1.2
	tests/libexec/ld.elf_so/helper_def_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_def_static/Makefile: revision 1.2
	libexec/ld.elf_so/arch/hppa/hppa_reloc.c: revision 1.50
	distrib/sets/lists/debug/shl.mi: revision 1.310
	libexec/ld.elf_so/README.TLS: revision 1.6
	distrib/sets/lists/debug/shl.mi: revision 1.311
	distrib/sets/lists/debug/shl.mi: revision 1.314
	tests/libexec/ld.elf_so/helper_dso3/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_symver_dso1/Makefile: revision 1.4
	libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.63
	tests/libexec/ld.elf_so/helper_def_dynamic/h_def_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlydef/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlydef/Makefile: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.10
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.11
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.12
	libexec/ld.elf_so/map_object.c: revision 1.66
	tests/libexec/ld.elf_so/helper.mk: revision 1.1
	libexec/ld.elf_so/arch/sparc/mdreloc.c: revision 1.57
	libexec/ld.elf_so/map_object.c: revision 1.67
	tests/libexec/ld.elf_so/helper_onlydef/h_onlydef.c: revision 1.1
	tests/libexec/ld.elf_so/helper_symver_dso2/Makefile: revision 1.4
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.3
	tests/libexec/ld.elf_so/helper_use_dynamic/h_use_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_abuse_static/h_abuse_static.c: revision 1.1
	libexec/ld.elf_so/arch/riscv/mdreloc.c: revision 1.9
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.1
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.3
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.4
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.5
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.6
	libexec/ld.elf_so/arch/m68k/mdreloc.c: revision 1.34
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.7
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.42
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.8
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.43
	libexec/ld.elf_so/arch/or1k/mdreloc.c: revision 1.4
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.9
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_abuse_dynamic/h_abuse_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/h_onlyctor_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_static/h_onlyuse_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/h_onlyuse_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_dso1/Makefile: revision 1.2
	distrib/sets/lists/tests/shl.mi: revision 1.12
	distrib/sets/lists/tests/shl.mi: revision 1.13
	libexec/ld.elf_so/arch/alpha/alpha_reloc.c: revision 1.44

ld.elf_so: New test for extern initial-exec TLS, PR toolchain/50277.

ld.elf_so: Fix extern TLS test to match PR toolchain/50277.
Now it's actually testing the problem.
ld.elf_so: Nix inadvertently committed private test program.
ld.elf_so: Fix set lists for MKDEBUG=yes builds with t_tls_extern.

ld.elf_so: Sprinkle tls debug messages.

ld.elf_so: Make tls alloc debug messages more detailed and greppable.

ld.elf_so: Test variations on PR toolchain/50277.

ld.elf_so: Test extern dynamic TLS too.

ld.elf_so: Factor out logic in TLS tests to make writing more easier.
No functional change intended.

ld.elf_so: Test TLS abuse of static def, dynamic use and vice versa.

ld.elf_so: Shorter test names.
No functional non-cosmetic change intended.

ld.elf_so: Separately test eager and lazy resolution of def tls ptr.
eager: before loading use library
lazy: after loading use library

Add recent ld.elf_so test helpers debug info
ld.elf_so: Add new files to debug/shl.mi.

ld.elf_so: tls_extern dynamic_defabuse_eager must xfail differently.
If a symbol has already been resolved as dynamic TLS, any library
that tries to use it as static TLS cannot be dlopened.

ld.elf_so: Test another edge case of mismatched TLS models.
One library defines a symbol and _doesn't_ use it, so it has no
indication of whether the symbol is for static TLS or dynamic TLS,
and then two other libraries use it in different ways.

ld.elf_so: Test dynamic-then-static abuse via ctor.

ld.elf_so: Fix missing tab in debug/shl.mi in last change.

Fix interactions of initial-exec TLS model and dlopen

(1) If an initial-exec relocation was used for a non-local symbol
(i.e. the definition of the symbol is in a different DSO), the
computation of the static TLS offset used the wrong DSO.

This would effectively mean the wrong address was computed
(PR toolchain/50277, PR pkg/57445).
Fix this by forcing the computation of the correct DSO (the one defining
the symbol).
This code uses __UNCONST to avoid the vast interface changes for this
special case.

(2) If symbols from a DSO loaded via dlopen are used with both
global-dynamic/local-dynamic and initial-exec relocations AND
a initial-exec relocation was resolved first in a thread, a split brain
situation could exist where the dynamic relocations would use one memory
block (separate allocation) and the initial-exec relocations the static
per-thread TLS space.

(3) If the initial-exec relocation in (2) is seen after any thread has
already used a GD/LD allocation, bail out. Since IE relocations are used
only in the GOT, this will prevent the dlopen. This is a bit more
aggressive than necessary, but a full blown reference counting doesn't
seem to be justified.
Avoid using uninitialized variable "symnum" when building with DEBUG
enabled by borrowing the rdbg_symname() macro from arch/x86_64.
ld.elf_so: Sprinkle more debug messages on dlopen and error.

PR pkg/57445

Fix MKDEBUGLIB build by adding these installed files to the debug
set list.

One could argue that these files are not of any use, so why install
them?  I don't have a good argument either way, and this is (for
now) a simple work-around for PR bin/57455   Please feel free to
commit a different fix to avoid installing these files at all.

Fix markup of libh_ MKDEBUGLIB=yes only files

TLS variant I archs need to fudge the offset by the size of the TCB.
tests/libexec/ld.elf_so: Fix helper library makefiles.
1. Consolidate logic into a single helper.mk to reduce duplication.
2. Set NO* variables, not MK* variables which are reserved for user.
3. Avoid eager X!= in favour of lazy ${X:sh}.
4. Mark _g.a set list entries obsolete.  Never should've been built!
PR misc/57462
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $");
a17 3
#define rdbg_symname(obj, rela) \
	((obj)->strtab + (obj)->symtab[ELF_R_SYM((rela)->r_info)].st_name)

d100 1
a100 1
			    rdbg_symname(obj, rel),
d114 1
a114 1
			    rdbg_symname(obj, rel),
d150 2
a151 2
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
d157 1
a157 1
			    rdbg_symname(obj, rel),
d162 2
a163 2
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
d168 1
a168 1
			    rdbg_symname(obj, rel),
d176 1
a176 1
			    rdbg_symname(obj, rel),
d184 1
a184 1
			    rdbg_symname(obj, rel),
d195 1
a195 1
			    rdbg_symname(obj, rel)));
@


1.41.12.1
log
@Pull up following revision(s) (requested by riastradh in ticket #297):

	distrib/sets/lists/tests/shl.mi: revision 1.14
	distrib/sets/lists/tests/shl.mi: revision 1.15
	distrib/sets/lists/tests/shl.mi: revision 1.16
	tests/libexec/ld.elf_so/helper_def_static/h_def_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_def_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_def_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_onlyuse_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_static/Makefile: revision 1.2
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.75
	distrib/sets/lists/tests/mi: revision 1.1265
	libexec/ld.elf_so/arch/sh3/mdreloc.c: revision 1.36
	libexec/ld.elf_so/rtld.c: revision 1.214
	tests/libexec/ld.elf_so/helper_onlydef_static/Makefile: revision 1.1
	distrib/sets/lists/debug/mi: revision 1.400
	tests/libexec/ld.elf_so/helper_onlydef_static/Makefile: revision 1.2
	distrib/sets/lists/debug/mi: revision 1.401
	distrib/sets/lists/debug/mi: revision 1.402
	tests/libexec/ld.elf_so/helper_dso2/Makefile: revision 1.2
	distrib/sets/lists/debug/mi: revision 1.403
	tests/libexec/ld.elf_so/helper_symver_dso0/Makefile: revision 1.2
	libexec/ld.elf_so/arch/x86_64/mdreloc.c: revision 1.48
	distrib/sets/lists/debug/mi: revision 1.406
	tests/libexec/ld.elf_so/helper_use_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_use_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_ifunc_dso/Makefile: revision 1.2
	libexec/ld.elf_so/arch/sparc64/mdreloc.c: revision 1.70
	libexec/ld.elf_so/arch/aarch64/mdreloc.c: revision 1.18
	tests/libexec/ld.elf_so/helper_abuse_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_abuse_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/Makefile: revision 1.13
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.46
	libexec/ld.elf_so/rtld.h: revision 1.146
	tests/libexec/ld.elf_so/Makefile: revision 1.14
	distrib/sets/lists/debug/shl.mi: revision 1.306
	tests/libexec/ld.elf_so/Makefile: revision 1.15
	tests/libexec/ld.elf_so/helper_abuse_static/Makefile: revision 1.1
	distrib/sets/lists/debug/shl.mi: revision 1.307
	tests/libexec/ld.elf_so/Makefile: revision 1.16
	tests/libexec/ld.elf_so/helper_abuse_static/Makefile: revision 1.2
	distrib/sets/lists/debug/shl.mi: revision 1.308
	tests/libexec/ld.elf_so/Makefile: revision 1.17
	distrib/sets/lists/debug/shl.mi: revision 1.309
	tests/libexec/ld.elf_so/Makefile: revision 1.18
	tests/libexec/ld.elf_so/Makefile: revision 1.19
	libexec/ld.elf_so/tls.c: revision 1.16
	libexec/ld.elf_so/tls.c: revision 1.17
	libexec/ld.elf_so/tls.c: revision 1.18
	libexec/ld.elf_so/tls.c: revision 1.19
	tests/libexec/ld.elf_so/helper_onlydef_static/h_onlydef_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/h_use_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/h_use_static.c: revision 1.2
	tests/libexec/ld.elf_so/helper_def_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_def_static/Makefile: revision 1.2
	libexec/ld.elf_so/arch/hppa/hppa_reloc.c: revision 1.50
	distrib/sets/lists/debug/shl.mi: revision 1.310
	libexec/ld.elf_so/README.TLS: revision 1.6
	distrib/sets/lists/debug/shl.mi: revision 1.311
	distrib/sets/lists/debug/shl.mi: revision 1.314
	tests/libexec/ld.elf_so/helper_dso3/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_symver_dso1/Makefile: revision 1.4
	libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.63
	tests/libexec/ld.elf_so/helper_def_dynamic/h_def_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlydef/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlydef/Makefile: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.10
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.11
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.12
	libexec/ld.elf_so/map_object.c: revision 1.66
	tests/libexec/ld.elf_so/helper.mk: revision 1.1
	libexec/ld.elf_so/arch/sparc/mdreloc.c: revision 1.57
	libexec/ld.elf_so/map_object.c: revision 1.67
	tests/libexec/ld.elf_so/helper_onlydef/h_onlydef.c: revision 1.1
	tests/libexec/ld.elf_so/helper_symver_dso2/Makefile: revision 1.4
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_use_static/Makefile: revision 1.3
	tests/libexec/ld.elf_so/helper_use_dynamic/h_use_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_abuse_static/h_abuse_static.c: revision 1.1
	libexec/ld.elf_so/arch/riscv/mdreloc.c: revision 1.9
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.1
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.3
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.4
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.5
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.6
	libexec/ld.elf_so/arch/m68k/mdreloc.c: revision 1.34
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.7
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.42
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.8
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.43
	libexec/ld.elf_so/arch/or1k/mdreloc.c: revision 1.4
	tests/libexec/ld.elf_so/t_tls_extern.c: revision 1.9
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/Makefile: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/Makefile: revision 1.2
	tests/libexec/ld.elf_so/helper_abuse_dynamic/h_abuse_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyctor_dynamic/h_onlyctor_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_static/h_onlyuse_static.c: revision 1.1
	tests/libexec/ld.elf_so/helper_onlyuse_dynamic/h_onlyuse_dynamic.c: revision 1.1
	tests/libexec/ld.elf_so/helper_dso1/Makefile: revision 1.2
	distrib/sets/lists/tests/shl.mi: revision 1.12
	distrib/sets/lists/tests/shl.mi: revision 1.13
	libexec/ld.elf_so/arch/alpha/alpha_reloc.c: revision 1.44
	(all via patch)

ld.elf_so: New test for extern initial-exec TLS, PR toolchain/50277.

ld.elf_so: Fix extern TLS test to match PR toolchain/50277.
Now it's actually testing the problem.
ld.elf_so: Nix inadvertently committed private test program.
ld.elf_so: Fix set lists for MKDEBUG=yes builds with t_tls_extern.

ld.elf_so: Sprinkle tls debug messages.

ld.elf_so: Make tls alloc debug messages more detailed and greppable.

ld.elf_so: Test variations on PR toolchain/50277.

ld.elf_so: Test extern dynamic TLS too.

ld.elf_so: Factor out logic in TLS tests to make writing more easier.
No functional change intended.

ld.elf_so: Test TLS abuse of static def, dynamic use and vice versa.

ld.elf_so: Shorter test names.
No functional non-cosmetic change intended.

ld.elf_so: Separately test eager and lazy resolution of def tls ptr.
eager: before loading use library
lazy: after loading use library

Add recent ld.elf_so test helpers debug info
ld.elf_so: Add new files to debug/shl.mi.

ld.elf_so: tls_extern dynamic_defabuse_eager must xfail differently.
If a symbol has already been resolved as dynamic TLS, any library
that tries to use it as static TLS cannot be dlopened.

ld.elf_so: Test another edge case of mismatched TLS models.
One library defines a symbol and _doesn't_ use it, so it has no
indication of whether the symbol is for static TLS or dynamic TLS,
and then two other libraries use it in different ways.

ld.elf_so: Test dynamic-then-static abuse via ctor.

ld.elf_so: Fix missing tab in debug/shl.mi in last change.

Fix interactions of initial-exec TLS model and dlopen
(1) If an initial-exec relocation was used for a non-local symbol
(i.e. the definition of the symbol is in a different DSO), the
computation of the static TLS offset used the wrong DSO.
This would effectively mean the wrong address was computed
(PR toolchain/50277, PR pkg/57445).
Fix this by forcing the computation of the correct DSO (the one defining
the symbol).
This code uses __UNCONST to avoid the vast interface changes for this
special case.
(2) If symbols from a DSO loaded via dlopen are used with both
global-dynamic/local-dynamic and initial-exec relocations AND
a initial-exec relocation was resolved first in a thread, a split brain
situation could exist where the dynamic relocations would use one memory
block (separate allocation) and the initial-exec relocations the static
per-thread TLS space.
(3) If the initial-exec relocation in (2) is seen after any thread has
already used a GD/LD allocation, bail out. Since IE relocations are used
only in the GOT, this will prevent the dlopen. This is a bit more
aggressive than necessary, but a full blown reference counting doesn't
seem to be justified.
Avoid using uninitialized variable "symnum" when building with DEBUG
enabled by borrowing the rdbg_symname() macro from arch/x86_64.
ld.elf_so: Sprinkle more debug messages on dlopen and error.
PR pkg/57445
Fix MKDEBUGLIB build by adding these installed files to the debug
set list.
XXX
One could argue that these files are not of any use, so why install
them?  I don't have a good argument either way, and this is (for
now) a simple work-around for PR bin/57455   Please feel free to
commit a different fix to avoid installing these files at all.
Fix markup of libh_ MKDEBUGLIB=yes only files
TLS variant I archs need to fudge the offset by the size of the TCB.
tests/libexec/ld.elf_so: Fix helper library makefiles.
1. Consolidate logic into a single helper.mk to reduce duplication.
2. Set NO* variables, not MK* variables which are reserved for user.
3. Avoid eager X!= in favour of lazy ${X:sh}.
4. Mark _g.a set list entries obsolete.  Never should've been built!
PR misc/57462
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.43 2023/06/04 20:02:29 martin Exp $");
a17 3
#define rdbg_symname(obj, rela) \
	((obj)->strtab + (obj)->symtab[ELF_R_SYM((rela)->r_info)].st_name)

d100 1
a100 1
			    rdbg_symname(obj, rel),
d114 1
a114 1
			    rdbg_symname(obj, rel),
d150 2
a151 2
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
d157 1
a157 1
			    rdbg_symname(obj, rel),
d162 2
a163 2
			if (!defobj->tls_static &&
			    _rtld_tls_offset_allocate(__UNCONST(defobj)))
d168 1
a168 1
			    rdbg_symname(obj, rel),
d176 1
a176 1
			    rdbg_symname(obj, rel),
d184 1
a184 1
			    rdbg_symname(obj, rel),
d195 1
a195 1
			    rdbg_symname(obj, rel)));
@


1.40
log
@init/fini for the main program is handled by crt0.o, so ifunc handling
is skipped right now as it iterates the same list. Don't repeat that
mistake and explicitly take care of it in the dynamic linker.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.39 2017/08/10 19:03:26 joerg Exp $");
d118 9
a226 20
void
_rtld_call_ifunc(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
{
	const Elf_Rel *rel;
	Elf_Addr *where, target;

	while (obj->ifunc_remaining > 0 && _rtld_objgen == cur_objgen) {
		rel = obj->pltrellim - obj->ifunc_remaining;
		--obj->ifunc_remaining;
		if (ELF_R_TYPE(rel->r_info) == R_TYPE(IRELATIVE)) {
			where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
			_rtld_exclusive_exit(mask);
			target = _rtld_resolve_ifunc2(obj, *where);
			_rtld_exclusive_enter(mask);
			if (*where != target)
				*where = target;
		}
	}
}

@


1.40.2.1
log
@Sync with HEAD.  77 conflicts resolved - all of them $NetBSD$
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.41 2018/04/03 21:10:27 joerg Exp $");
a117 9

		case R_TYPE(IRELATIVE):
			/* IFUNC relocations are handled in _rtld_call_ifunc */
			if (obj->ifunc_remaining_nonplt == 0) {
				obj->ifunc_remaining_nonplt =
				    obj->rellim - rel;
			}
			/* FALL-THROUGH */

d218 20
@


1.39
log
@Add IRELATIVE support for ARM, X86 and PowerPC.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.38 2017/06/19 11:57:01 joerg Exp $");
a200 3
	if (!obj->relocbase)
		return 0;

@


1.38
log
@Replace COMBREL with just-in-time check in _rtld_relocate_nonplt_objects.

The COMBREL logic predates thread-safety of the dynamic linker and
breaks the use of shared locks for the common symbol lookup case. It is
unlikely to provide any benefit for lazy binding or PLT lookups, so
provide equivalent functionality in the non-PLT relocation handling loop
by checking if the symbol used by the current relocation is the same as
the one used during the last lookup. No inter-object cachine is done as
it is also unlikely to be benefical.

Testing with Firefox startup on AMD64 shows a small performance gain by
the new method.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $");
d197 1
a197 1
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
d204 1
a204 1
	for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
d207 5
a211 1
		assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
d221 20
d251 3
@


1.37
log
@Remove (now duplicated) target computation.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.36 2014/08/25 20:40:52 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.36 2014/08/25 20:40:52 joerg Exp $");
d56 3
a61 2
		const Elf_Sym   *def;
		const Obj_Entry *defobj;
d66 23
a88 1
		symnum = ELF_R_SYM(rel->r_info);
a95 3
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;
a107 3
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;
a140 4
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

a152 4
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

a163 4
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

a171 4
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

d183 2
a184 1
			    symnum, (u_long)ELF_R_TYPE(rel->r_info),
@


1.37.8.1
log
@Pull up following revision(s) (requested by joerg in ticket #64):
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.40
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.41
	libexec/ld.elf_so/arch/hppa/hppa_reloc.c: revision 1.44
	libexec/ld.elf_so/arch/riscv/mdreloc.c: revision 1.3
	libexec/ld.elf_so/arch/aarch64/mdreloc.c: revision 1.3
	libexec/ld.elf_so/arch/sparc64/mdreloc.c: revision 1.60
	libexec/ld.elf_so/arch/m68k/mdreloc.c: revision 1.32
	libexec/ld.elf_so/arch/sparc64/mdreloc.c: revision 1.61
	libexec/ld.elf_so/arch/or1k/mdreloc.c: revision 1.2
	libexec/ld.elf_so/arch/sparc/mdreloc.c: revision 1.50
	libexec/ld.elf_so/arch/sh3/mdreloc.c: revision 1.33
	libexec/ld.elf_so/arch/sh3/mdreloc.c: revision 1.34
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.39
	libexec/ld.elf_so/symbol.c: revision 1.68
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.66
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.67
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.68
	libexec/ld.elf_so/arch/x86_64/mdreloc.c: revision 1.42
	libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.54
	libexec/ld.elf_so/Makefile: revision 1.137
	libexec/ld.elf_so/arch/vax/mdreloc.c: revision 1.32
	libexec/ld.elf_so/rtld.h: revision 1.127
	libexec/ld.elf_so/arch/vax/mdreloc.c: revision 1.33
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.38
	libexec/ld.elf_so/arch/alpha/alpha_reloc.c: revision 1.42
	libexec/ld.elf_so/map_object.c: revision 1.58
	libexec/ld.elf_so/arch/sparc/mdreloc.c: revision 1.49
Replace COMBREL with just-in-time check in _rtld_relocate_nonplt_objects.
The COMBREL logic predates thread-safety of the dynamic linker and
breaks the use of shared locks for the common symbol lookup case. It is
unlikely to provide any benefit for lazy binding or PLT lookups, so
provide equivalent functionality in the non-PLT relocation handling loop
by checking if the symbol used by the current relocation is the same as
the one used during the last lookup. No inter-object cachine is done as
it is also unlikely to be benefical.
Testing with Firefox startup on AMD64 shows a small performance gain by
the new method.
Drop symbol number from default branch diagnostic, it isn't set at this
point and most likely not valid either.
Expand symnum, GCC's uninitialized used tracking is too imprecise.
Fix C&P bug. Deal with more MIPS hacks overriding def.
Add last_symnum, move up def and defobj.
Add back symnum, fix debug print.
Replace last use of r_type.
Fix indentation.
Fix indentation.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $");
a55 3
	const Elf_Sym   *def = NULL;
	const Obj_Entry *defobj = NULL;
	unsigned long last_symnum = ULONG_MAX;
d59 2
d65 1
a65 23

		switch (ELF_R_TYPE(rel->r_info)) {
		case R_TYPE(PC32):
		case R_TYPE(GOT32):
		case R_TYPE(32):
		case R_TYPE(GLOB_DAT):
		case R_TYPE(TLS_TPOFF):
		case R_TYPE(TLS_TPOFF32):
		case R_TYPE(TLS_DTPMOD32):
		case R_TYPE(TLS_DTPOFF32):
			symnum = ELF_R_SYM(rel->r_info);
			if (symnum != last_symnum) {
				last_symnum = symnum;
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
			}
			break;
		default:
			break;
		}

d73 3
d88 3
d124 4
d140 4
d155 4
d167 4
d182 1
a182 2
			    (u_long)ELF_R_SYM(rel->r_info),
			    (u_long)ELF_R_TYPE(rel->r_info),
@


1.36
log
@Add basic support for indirect functions. It allows providing a public
function symbol with an implementation choosen at run time.
Refactor calls to functions by address in ld.elf_so to create temporary
function descriptors on the stack, if the address is not leaked outside.

Limitations:
- no support for initialising static storage with function pointers
- no support for unnamed resolver functions

Inspired by FreeBSD's r228435 by kib@@freebsd.org.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $");
a240 1
	target = (Elf_Addr)(defobj->relocbase + def->st_value);
@


1.35
log
@Add support for R_386_TLS_TPOFF32.  This patch was created by
Nick Hudson for PR 47061.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.34 2011/03/25 18:07:05 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.34 2011/03/25 18:07:05 joerg Exp $");
d233 8
@


1.35.8.1
log
@Catch up to -current, via patch, requested by christos in ticket #1126:
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $");
d233 1
a233 8
	if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
		if (tp == NULL)
			return 0;
		target = _rtld_resolve_ifunc(defobj, def);
	} else {
		target = (Elf_Addr)(defobj->relocbase + def->st_value);
	}

@


1.34
log
@Add basic locking to ld.elf_so.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.33 2011/03/12 22:54:36 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.33 2011/03/12 22:54:36 joerg Exp $");
d132 1
a132 1
			*where = (Elf_Addr)(def->st_value - defobj->tlsoffset);
d139 15
@


1.34.4.1
log
@sync with (a bit old) head
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.34 2011/03/25 18:07:05 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.34 2011/03/25 18:07:05 joerg Exp $");
d132 1
a132 1
			*where += (Elf_Addr)(def->st_value - defobj->tlsoffset);
a138 15
		case R_TYPE(TLS_TPOFF32):
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

			if (!defobj->tls_done &&
			    _rtld_tls_offset_allocate(obj))
				return -1;

			*where += (Elf_Addr)(defobj->tlsoffset - def->st_value);
			rdbg(("TLS_TPOFF32 %s in %s --> %p",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where));
			break;

@


1.34.10.1
log
@Resync to 2012-11-19 00:00:00 UTC
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $");
d132 1
a132 1
			*where += (Elf_Addr)(def->st_value - defobj->tlsoffset);
a138 15
		case R_TYPE(TLS_TPOFF32):
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

			if (!defobj->tls_done &&
			    _rtld_tls_offset_allocate(obj))
				return -1;

			*where += (Elf_Addr)(defobj->tlsoffset - def->st_value);
			rdbg(("TLS_TPOFF32 %s in %s --> %p",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where));
			break;

@


1.34.6.1
log
@Pull up following revision(s) (requested by apb in ticket #667):
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.35
Add support in ld.elf_so for relocation type R_386_TLS_TPOFF32.
Fixes PR#47061.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d5 1
a5 1
__RCSID("$NetBSD$");
d132 1
a132 1
			*where += (Elf_Addr)(def->st_value - defobj->tlsoffset);
a138 15
		case R_TYPE(TLS_TPOFF32):
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

			if (!defobj->tls_done &&
			    _rtld_tls_offset_allocate(obj))
				return -1;

			*where += (Elf_Addr)(defobj->tlsoffset - def->st_value);
			rdbg(("TLS_TPOFF32 %s in %s --> %p",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where));
			break;

@


1.33
log
@Add TLS support for AMD64, i386 and SH3.

This material is based upon work partially supported by
The NetBSD Foundation under a contract with Joerg Sonnenberger.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.32 2010/08/06 16:33:18 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.32 2010/08/06 16:33:18 joerg Exp $");
d239 1
d243 1
@


1.32
log
@Reduce header pollution for mdreloc.c. Make Obj_Entry argument of
_rtld_relocate_nonplt_objects non-const in preparation for TLS support.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.31 2010/01/14 11:58:32 skrll Exp $");
d9 1
d123 41
d259 22
@


1.31
log
@Wrap a few long lines.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.30 2010/01/13 22:34:07 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.30 2010/01/13 22:34:07 skrll Exp $");
a8 1
#include <sys/stat.h>
d51 1
a51 1
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
@


1.30
log
@Shut gcc up.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.29 2010/01/13 20:17:22 christos Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.29 2010/01/13 20:17:22 christos Exp $");
d191 2
a192 1
	const Elf_Rel *rel = (const Elf_Rel *)((const uint8_t *)obj->pltrel + reloff);
@


1.29
log
@PR/39240: Satoshi Suetake: Don't fail when attempting to resolve weak symbols
when we are doing immediate binding, leave them alone and they will be dealt
with later during lazy binding. From skrll@@
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.28 2009/08/29 13:46:54 jmmv Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.28 2009/08/29 13:46:54 jmmv Exp $");
d195 2
@


1.28
log
@Remove trailing \n in calls to _rtld_error: a newline is automatically
added by a call to the function.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.27 2009/03/16 02:44:47 lukem Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.27 2009/03/16 02:44:47 lukem Exp $");
d167 1
d169 1
a169 1
	assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
d171 2
a172 2
	def = _rtld_find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true);
	if (def == NULL)
d174 3
d196 1
a196 1
	if (err || new_value == 0)
@


1.27
log
@Fix const issues (cast const pointers to "const uint8_t *" instead of "caddr_t")
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.26 2008/07/24 04:39:25 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.26 2008/07/24 04:39:25 matt Exp $");
d130 1
a130 1
			    "in non-PLT relocations\n",
@


1.26
log
@Refactor common code to _rtld_relocate_plt_object to i386 and arm so they
act like the other versions.
In _rtld_bind, if the result is 0, call _rtld_die.
Initialize _rtld_sym_zero.st_value to -_rtld_objself.maprelocbase.  Now when
the symbol is resolved, st_value + maprelocbase will equal 0 and the above
check in _rtld_bind will fire and a call to NULL will be avoided.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.25 2008/07/23 18:16:42 christos Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.25 2008/07/23 18:16:42 christos Exp $");
d44 1
a44 1
	rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
d187 1
a187 1
	const Elf_Rel *rel = (const Elf_Rel *)((caddr_t)obj->pltrel + reloff);
@


1.26.4.1
log
@Pull up following revision(s) via patch (requested by skrll in ticket #1724):
	rescue/list.ldd: revision 1.4
	lib/libc/dlfcn/dlfcn_elf.c: revision 1.7
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.57
	distrib/sets/lists/comp/mi: revision 1.1512
	share/man/man3/Makefile: revision 1.56
	libexec/ld.elf_so/arch/mips/mips_reloc.c: revision 1.58
	usr.bin/ldd/ldd.c: revision 1.15
	libexec/ld.elf_so/rtld.h: revision 1.84
	share/man/man3/dl_iterate_phdr.3: revision 1.1
	libexec/ld.elf_so/rtld.c: revision 1.129
	libexec/ld.elf_so/arch/powerpc/ppc_reloc.c: revision 1.44
	libexec/ld.elf_so/rtld.h: revision 1.89
	libexec/ld.elf_so/arch/x86_64/mdreloc.c: revision 1.36
	libexec/ld.elf_so/map_object.c: revision 1.41
	libexec/ld.elf_so/arch/x86_64/mdreloc.c: revision 1.37
	libexec/ld.elf_so/arch/sparc64/mdreloc.c: revision 1.46
	include/link_elf.h: revision 1.10
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.29
	libexec/ld.elf_so/arch/vax/mdreloc.c: revision 1.26
	libexec/ld.elf_so/arch/alpha/alpha_reloc.c: revision 1.34
	libexec/ld.elf_so/arch/hppa/hppa_reloc.c: revision 1.31
	libexec/ld.elf_so/arch/alpha/alpha_reloc.c: revision 1.35
	libexec/ld.elf_so/Makefile: revision 1.94
	libexec/ld.elf_so/arch/hppa/hppa_reloc.c: revision 1.32
	libexec/ld.elf_so/Makefile: revision 1.95
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.31
	libexec/ld.elf_so/Makefile: revision 1.96
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.32
	libexec/ld.elf_so/reloc.c: revision 1.98
	libexec/ld.elf_so/arch/arm/mdreloc.c: revision 1.33
	sys/sys/exec_elf.h: revision 1.106
	libexec/ld.elf_so/rtld.c: revision 1.130
	libexec/ld.elf_so/load.c: revision 1.37
	libexec/ld.elf_so/rtld.c: revision 1.131
	libexec/ld.elf_so/load.c: revision 1.38
	libexec/ld.elf_so/rtld.h: revision 1.90
	libexec/ld.elf_so/headers.c: revision 1.36
	libexec/ld.elf_so/rtld.h: revision 1.95
	libexec/ld.elf_so/arch/i386/mdreloc.c: revision 1.30
	libexec/ld.elf_so/arch/m68k/mdreloc.c: revision 1.25
	libexec/ld.elf_so/symbol.c: revision 1.50
	libexec/ld.elf_so/symbol.c: revision 1.51
	libexec/ld.elf_so/arch/sparc/mdreloc.c: revision 1.43
	libexec/ld.elf_so/symbol.c: revision 1.52
	libexec/ld.elf_so/arch/sh3/mdreloc.c: revision 1.27
	libexec/ld.elf_so/symbol.c: revision 1.54
PR/39240: Satoshi Suetake: Don't fail when attempting to resolve weak symbols
when we are doing immediate binding, leave them alone and they will be dealt
with later during lazy binding. From skrll@@
Implement negative cache checks for symbol lookups.
Uses the Donelist idea from FreeBSD.
Use alloca(3) instead of local xmalloc for creating our DoneLists.
This allows threaded programs to use us a little better, PR lib/43005.
Implement dl_iterate_phdr.
Somewhat taken from FreeBSD. Manual page from OpenBSD.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.26 2008/07/24 04:39:25 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.26 2008/07/24 04:39:25 matt Exp $");
a166 1
	unsigned long info = rel->r_info;
d168 1
a168 1
	assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
d170 2
a171 2
	def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
	if (__predict_false(def == NULL))
a172 3
	if (__predict_false(def == &_rtld_sym_zero))
		return 0;

a190 2
	new_value = 0;	/* XXX gcc */

d192 1
a192 1
	if (err)
@


1.26.6.1
log
@Sync with HEAD.

Third (and last) commit. See http://mail-index.netbsd.org/source-changes/2009/05/13/msg221222.html
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.27 2009/03/16 02:44:47 lukem Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.27 2009/03/16 02:44:47 lukem Exp $");
d44 1
a44 1
	rellim = (const Elf_Rel *)((const uint8_t *)rel + relsz);
d187 1
a187 1
	const Elf_Rel *rel = (const Elf_Rel *)((const uint8_t *)obj->pltrel + reloff);
@


1.25
log
@abort() if we are trying to use an undefined weak symbol from the plt. Remove
check from relocate_plt_object() since we cannot return _rtld_sym_zero anymore.
Code from gimpy.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.24 2008/07/22 22:27:07 christos Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.24 2008/07/22 22:27:07 christos Exp $");
d159 3
a161 2
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
a162 1
	const Elf_Rel *rel = (const Elf_Rel *)((caddr_t)obj->pltrel + reloff);
d164 2
a165 2
	Elf_Addr new_value;
	const Elf_Sym  *def;
d172 21
a193 5
	new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
	rdbg(("bind now/fixup in %s --> old=%p new=%p",
	    defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
	if (*where != new_value)
		*where = new_value;
d202 1
d205 3
a207 17
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
		Elf_Addr target;
		const Elf_Sym *def;
		const Obj_Entry *defobj;
		
		assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
		
		def = _rtld_find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
		    true);
		if (def == NULL)
			return -1;
		target = (Elf_Addr)(defobj->relocbase + def->st_value);
		rdbg(("bind now/fixup in %s --> old=%p new=%p",
		    defobj->strtab + def->st_name, (void *)*where, 
		    (void *)target));
		if (*where != target)
			*where = target;
d209 1
a209 1
	return 0;
@


1.24
log
@handle sym_zero like x86_64; other ports might need this too.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.23 2007/02/23 01:17:11 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2007/02/23 01:17:11 matt Exp $");
a166 1
	const char *name;
a172 6
	if (def == &_rtld_sym_zero)
		name = obj->strtab +
		    obj->symtab[ELF_R_SYM(rel->r_info)].st_name;
	else
		name = defobj->strtab + def->st_name;

d175 1
a175 1
	    name, (void *)*where, (void *)new_value));
@


1.23
log
@Remove MD COMBRELOC support since it's now MI.
Enable COMBRELOC for all arches
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.22 2006/03/18 23:09:34 christos Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.22 2006/03/18 23:09:34 christos Exp $");
d167 1
d174 5
d182 1
a182 1
	    defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
@


1.23.12.1
log
@Sync with wrstuden-revivesa-base-2.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.23 2007/02/23 01:17:11 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2007/02/23 01:17:11 matt Exp $");
d159 2
a160 3
static inline int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
	Elf_Addr *tp)
d162 1
d164 2
a165 2
	Elf_Addr target;
	const Elf_Sym *def;
d172 3
a174 2
		return -1;
	target = (Elf_Addr)(defobj->relocbase + def->st_value);
d176 3
a178 19
	    defobj->strtab + def->st_name, (void *)*where, 
	    (void *)target));
	if (*where != target)
		*where = target;
	if (tp)
		*tp = target;
	return 0;
}

caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
	const Elf_Rel *rel = (const Elf_Rel *)((caddr_t)obj->pltrel + reloff);
	Elf_Addr new_value;
	int err;

	err = _rtld_relocate_plt_object(obj, rel, &new_value);
	if (err || new_value == 0)
		_rtld_die();
a186 1
	int err = 0;
d189 17
a205 3
		err = _rtld_relocate_plt_object(obj, rel, NULL);
		if (err)
			break;
d207 1
a207 1
	return err;
@


1.22
log
@Coverity CID 923: Avoid NULL deref.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.21 2005/08/20 19:01:17 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.21 2005/08/20 19:01:17 skrll Exp $");
a54 4
#define COMBRELOC
#ifdef COMBRELOC
	unsigned long lastsym = -1;
#endif
d73 4
a76 13
#ifdef COMBRELOC
			if (symnum != lastsym) {
#endif
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
				target = (Elf_Addr)(defobj->relocbase +
				    def->st_value);
#ifdef COMBRELOC
				lastsym = symnum;
			}
#endif
d88 4
a91 13
#ifdef COMBRELOC
			if (symnum != lastsym) {
#endif
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
				target = (Elf_Addr)(defobj->relocbase +
				    def->st_value);
#ifdef COMBRELOC
				lastsym = symnum;
			}
#endif
@


1.21
log
@Add __RCSID.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.20 2005/06/01 14:15:13 lukem Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD$");
d42 2
@


1.20
log
@appease gcc -Wuninitialized
@
text
@d1 6
a6 1
/*	$NetBSD: mdreloc.c,v 1.19 2003/07/24 10:12:28 skrll Exp $	*/
@


1.19
log
@ANSIfy and de-__P().
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.18 2002/10/03 20:39:22 mycroft Exp $	*/
d52 1
a52 1
	Elf_Addr target;
@


1.19.4.1
log
@file mdreloc.c was added on branch netbsd-1-6 on 2004-05-28 08:31:22 +0000
@
text
@d1 223
@


1.19.4.2
log
@Apply patch (request by skrll in ticket #1702):
Bring "ld.elf_so" (mostly) in sync with NetBSD-current:
- MI and MD (e.g. under NetBSD-alpha) performance improvements
- RTLD_SELF, RTLD_NEXT, RTLD_DEFAULT support
- much better structured code
- closes PR bin/25464
@
text
@a0 223
/*	$NetBSD: mdreloc.c,v 1.19.4.1 2004/05/28 08:31:22 tron Exp $	*/

#include <sys/types.h>
#include <sys/stat.h>

#include "debug.h"
#include "rtld.h"

void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);

void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
	obj->pltgot[1] = (Elf_Addr) obj;
	obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}

void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
	const Elf_Rel *rel = 0, *rellim;
	Elf_Addr relsz = 0;
	Elf_Addr *where;

	for (; dynp->d_tag != DT_NULL; dynp++) {
		switch (dynp->d_tag) {
		case DT_REL:
			rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_RELSZ:
			relsz = dynp->d_un.d_val;
			break;
		}
	}
	rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
	for (; rel < rellim; rel++) {
		where = (Elf_Addr *)(relocbase + rel->r_offset);
		*where += (Elf_Addr)relocbase;
	}
}

int
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
{
	const Elf_Rel *rel;
#define COMBRELOC
#ifdef COMBRELOC
	unsigned long lastsym = -1;
#endif
	Elf_Addr target;

	for (rel = obj->rel; rel < obj->rellim; rel++) {
		Elf_Addr        *where;
		const Elf_Sym   *def;
		const Obj_Entry *defobj;
		Elf_Addr         tmp;
		unsigned long	 symnum;

		where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
		symnum = ELF_R_SYM(rel->r_info);

		switch (ELF_R_TYPE(rel->r_info)) {
		case R_TYPE(NONE):
			break;

#if 1 /* XXX should not occur */
		case R_TYPE(PC32):
#ifdef COMBRELOC
			if (symnum != lastsym) {
#endif
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
				target = (Elf_Addr)(defobj->relocbase +
				    def->st_value);
#ifdef COMBRELOC
				lastsym = symnum;
			}
#endif

			*where += target - (Elf_Addr)where;
			rdbg(("PC32 %s in %s --> %p in %s",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where, defobj->path));
			break;

		case R_TYPE(GOT32):
#endif
		case R_TYPE(32):
		case R_TYPE(GLOB_DAT):
#ifdef COMBRELOC
			if (symnum != lastsym) {
#endif
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
				target = (Elf_Addr)(defobj->relocbase +
				    def->st_value);
#ifdef COMBRELOC
				lastsym = symnum;
			}
#endif

			tmp = target + *where;
			if (*where != tmp)
				*where = tmp;
			rdbg(("32/GLOB_DAT %s in %s --> %p in %s",
			    obj->strtab + obj->symtab[symnum].st_name,
			    obj->path, (void *)*where, defobj->path));
			break;

		case R_TYPE(RELATIVE):
			*where += (Elf_Addr)obj->relocbase;
			rdbg(("RELATIVE in %s --> %p", obj->path,
			    (void *)*where));
			break;

		case R_TYPE(COPY):
			/*
			 * These are deferred until all other relocations have
			 * been done.  All we do here is make sure that the
			 * COPY relocation is not in a shared library.  They
			 * are allowed only in executable files.
			 */
			if (obj->isdynamic) {
				_rtld_error(
			"%s: Unexpected R_COPY relocation in shared library",
				    obj->path);
				return -1;
			}
			rdbg(("COPY (avoid in main)"));
			break;

		default:
			rdbg(("sym = %lu, type = %lu, offset = %p, "
			    "contents = %p, symbol = %s",
			    symnum, (u_long)ELF_R_TYPE(rel->r_info),
			    (void *)rel->r_offset, (void *)*where,
			    obj->strtab + obj->symtab[symnum].st_name));
			_rtld_error("%s: Unsupported relocation type %ld "
			    "in non-PLT relocations\n",
			    obj->path, (u_long) ELF_R_TYPE(rel->r_info));
			return -1;
		}
	}
	return 0;
}

int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
	const Elf_Rel *rel;

	if (!obj->relocbase)
		return 0;

	for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);

		assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));

		/* Just relocate the GOT slots pointing into the PLT */
		*where += (Elf_Addr)obj->relocbase;
		rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
	}

	return 0;
}

caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
	const Elf_Rel *rel = (const Elf_Rel *)((caddr_t)obj->pltrel + reloff);
	Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
	Elf_Addr new_value;
	const Elf_Sym  *def;
	const Obj_Entry *defobj;

	assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));

	def = _rtld_find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true);
	if (def == NULL)
		_rtld_die();

	new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
	rdbg(("bind now/fixup in %s --> old=%p new=%p",
	    defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
	if (*where != new_value)
		*where = new_value;

	return (caddr_t)new_value;
}

int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
	const Elf_Rel *rel;
	
	for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
		Elf_Addr target;
		const Elf_Sym *def;
		const Obj_Entry *defobj;
		
		assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
		
		def = _rtld_find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
		    true);
		if (def == NULL)
			return -1;
		target = (Elf_Addr)(defobj->relocbase + def->st_value);
		rdbg(("bind now/fixup in %s --> old=%p new=%p",
		    defobj->strtab + def->st_name, (void *)*where, 
		    (void *)target));
		if (*where != target)
			*where = target;
	}
	return 0;
}
@


1.18
log
@Skip the lazy PLT relocation if relocbase==0 (useful if libraries are loaded
at their VMA address).
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.17 2002/09/26 20:42:11 mycroft Exp $	*/
d11 1
a11 1
caddr_t _rtld_bind __P((const Obj_Entry *, Elf_Word));
d21 1
a21 3
_rtld_relocate_nonplt_self(dynp, relocbase)
	Elf_Dyn *dynp;
	Elf_Addr relocbase;
d45 1
a45 2
_rtld_relocate_nonplt_objects(obj)
	const Obj_Entry *obj;
d154 1
a154 2
_rtld_relocate_plt_lazy(obj)
	const Obj_Entry *obj;
d175 1
a175 3
_rtld_bind(obj, reloff)
	const Obj_Entry *obj;
	Elf_Word reloff;
@


1.17
log
@Remove the `self' args to _rtld_relocate_objects() and
_rtld_relocate_nonplt_objects().
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.16 2002/09/25 07:27:52 mycroft Exp $	*/
d162 1
a162 1
	if (!obj->isdynamic)
@


1.16
log
@Push the _rtld_bind() interface into MD code -- it's just a trivial wrapper
anyway.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.15 2002/09/17 07:29:49 junyoung Exp $	*/
d47 1
a47 1
_rtld_relocate_nonplt_objects(obj, self)
a48 1
	bool self;
a55 3

	if (self)
		return 0;
@


1.15
log
@Make immediate binding work again by actually implementing
_rtld_relocate_plt_objects(). Note that this is for i386 only;
any efforts to make it work on other platforms are left to
those who are using them...
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.14 2002/09/12 22:56:30 mycroft Exp $	*/
d11 1
d182 2
a183 2
int
_rtld_relocate_plt_object(obj, rela, addrp)
d185 1
a185 2
	const Elf_Rela *rela;
	caddr_t *addrp;
d187 2
a188 1
	Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
d193 1
a193 1
	assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
d195 1
a195 1
	def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
d197 1
a197 1
		return -1;
d205 1
a205 2
	*addrp = (caddr_t)new_value;
	return 0;
@


1.14
log
@Nuke -DRTLD_RELOCATE_SELF and `dodebug' from orbit.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.13 2002/09/12 20:21:00 mycroft Exp $	*/
d205 27
@


1.13
log
@_rtld_bind_start() is not used in MI code, so declare it in the MD code.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.12 2002/09/11 17:23:25 mycroft Exp $	*/
d46 1
a46 1
_rtld_relocate_nonplt_objects(obj, self, dodebug)
a48 1
	bool dodebug;
d91 1
a91 1
			rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
d117 1
a117 1
			rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
d124 1
a124 1
			rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
d141 1
a141 1
			rdbg(dodebug, ("COPY (avoid in main)"));
d145 1
a145 1
			rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
d160 1
a160 1
_rtld_relocate_plt_lazy(obj, dodebug)
a161 1
	bool dodebug;
d175 1
a175 2
		rdbg(dodebug, ("fixup !main in %s --> %p", obj->path,
		    (void *)*where));
d182 1
a182 1
_rtld_relocate_plt_object(obj, rela, addrp, dodebug)
a185 1
	bool dodebug;
d199 1
a199 1
	rdbg(dodebug, ("bind now/fixup in %s --> old=%p new=%p",
@


1.12
log
@Split the `self' case out of _rtld_relocate_nonplt_objects, into a new function
_rtld_relocate_nonplt_self(), which is called from _rtld_start.
Now we're completely relocated before main() is called.
We also no longer need _GOT_END_, so junk the ld script.

This code assumes that ld.elf_so only contains RELATIVE relocs, but that's
supposed to be the case for -Bsymbolic anyway.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.11 2002/09/11 14:19:30 junyoung Exp $	*/
d9 1
@


1.11
log
@Add $NetBSD$.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d9 2
d18 26
d57 3
d123 3
a125 14
		    {
			extern Elf_Addr	_GLOBAL_OFFSET_TABLE_[];
			extern Elf_Addr	_GOT_END_[];

			/* This is the ...iffy hueristic. */
			if (!self ||
			    (caddr_t)where < (caddr_t)_GLOBAL_OFFSET_TABLE_ ||
			    (caddr_t)where >= (caddr_t)_GOT_END_) {
				*where += (Elf_Addr)obj->relocbase;
				rdbg(dodebug, ("RELATIVE in %s --> %p",
				    obj->path, (void *)*where));
			} else
				rdbg(dodebug, ("RELATIVE in %s stays at %p",
				    obj->path, (void *)*where));
a126 1
		    }
@


1.10
log
@Get rid of RTLD_RELOCATE_SELF on i386.
* Add a ld.so.script that exports _GOT_END_.
* Prebind the GOT in _rtld_start.
* Skip over GOT relocs in _rtld_relocate_nonplt_objects().
This makes debugging work better at least.
@
text
@d1 2
@


1.9
log
@Pass down an additional flag to _rtld_relocate_nonplt_objects() which
indicates whether we're relocating ld.elf_so itself.  Use this in some places
rather than hackish tests on `dodebug'.  (The Alpha and HPPA `dodebug' tests
were actually noops, because RTLD_RELOCATE_SELF is not set, and therefore
dodebug is always true.)
@
text
@d90 14
a103 3
			*where += (Elf_Addr)obj->relocbase;
			rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
			    (void *)*where));
d105 1
@


1.8
log
@Introduce a new flag, `isdynamic', which is used to remember whether the
executable was of type ET_DYN.  Use this instead of `mainprog' to determine
whether we need to do base-relative fixups of the PLT.  (This allows loading
non-relocatable objects, should we desire to do that at some point...)
@
text
@d15 1
a15 1
_rtld_relocate_nonplt_objects(obj, dodebug)
d17 1
@


1.7
log
@Re-poison a lot of consts, now that the mark shite is gone.
@
text
@d101 1
a101 1
			if (!obj->mainprog) {
d132 1
a132 1
	if (obj->mainprog)
@


1.6
log
@Split _rtld_relocate_plt_object() into two MD functions:
* _rtld_relocate_plt_lazy() fixes up all the relocs pointing to the PLT.  (On
  most platforms it just does a simple base-relative fixup; on SPARC it does
  nothing.)
* _rtld_relocate_plt_object() does immediate binding for a PLT entry.
The basic gist is that this saves a bit of time on SPARC (where the iteration
through the pltrela table was gratuitous), and a little less time on all other
platforms.  A whole lot of #ifdef'ed crap is moved out of reloc.c, too.

NOT tested on: hppa sh x86_64
@
text
@d16 1
a16 1
	Obj_Entry *obj;
d127 1
a127 1
	Obj_Entry *obj;
d151 1
a151 1
	Obj_Entry *obj;
@


1.5
log
@Partially fix up some debug printf()s that don't need to use defobj.
@
text
@d20 1
d122 52
@


1.4
log
@A few things:
* Pass a symbol number to _rtld_find_symdef(), not a r_info.
* Don't try to do a symbol lookup when we find an unsupported relocation;
  instead get the symbol name from the referencing object's strtab.
* Add preliminary support for `-z combreloc'-style startup optimization on
  i386, `#ifdef COMBRELOC'.
@
text
@d27 2
d42 1
a42 1
			if (symnum != lastsym)
a43 3
			{
				const Elf_Sym   *def;
				const Obj_Entry *defobj;
d52 1
a53 1
			}
d57 2
a58 2
			    defobj->strtab + def->st_name, obj->path,
			    (void *)*where, defobj->path));
d66 1
a66 1
			if (symnum != lastsym)
a67 3
			{
				const Elf_Sym   *def;
				const Obj_Entry *defobj;
d76 1
a77 1
			}
d83 2
a84 2
			    defobj->strtab + def->st_name, obj->path,
			    (void *)*where, defobj->path));
@


1.3
log
@Rename _rtld_relocate_nonplt_object() to _rtld_relocate_nonplt_objects(),
and push the outer loop into it.  This actually shaves a couple % off startup
time at least on PCs.
@
text
@d20 4
a26 2
		const Elf_Sym   *def;
		const Obj_Entry *defobj;
d28 1
d31 1
d39 16
a54 4
			def = _rtld_find_symdef(rel->r_info, obj, &defobj,
			    false);
			if (def == NULL)
				return -1;
d56 1
a56 2
			*where += (Elf_Addr)(defobj->relocbase + def->st_value) -
			    (Elf_Addr)where;
d66 16
a81 4
			def = _rtld_find_symdef(rel->r_info, obj, &defobj,
			    false);
			if (def == NULL)
				return -1;
d83 1
a83 2
			tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
			    *where);
a113 2
			def = _rtld_find_symdef(rel->r_info, obj, &defobj,
			    true);
d116 1
a116 2
			    (u_long)ELF_R_SYM(rel->r_info),
			    (u_long)ELF_R_TYPE(rel->r_info),
d118 1
a118 1
			    def ? defobj->strtab + def->st_name : "??"));
@


1.2
log
@Split _rtld_relocate_nonplt_object() into separate MD files.
@
text
@d15 1
a15 1
_rtld_relocate_nonplt_object(obj, rela, dodebug)
a16 1
	const Elf_Rela *rela;
d19 1
a19 4
	Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	const Elf_Sym   *def;
	const Obj_Entry *defobj;
	Elf_Addr         tmp;
d21 11
a31 4
	switch (ELF_R_TYPE(rela->r_info)) {

	case R_TYPE(NONE):
		break;
d34 12
a45 11
	case R_TYPE(PC32):
		def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
		if (def == NULL)
			return -1;

		*where += (Elf_Addr)(defobj->relocbase + def->st_value) -
		    (Elf_Addr)where;
		rdbg(dodebug, ("PC32 %s in %s --> %p in %s",
		    defobj->strtab + def->st_name, obj->path,
		    (void *)*where, defobj->path));
		break;
d47 1
a47 1
	case R_TYPE(GOT32):
d49 31
a79 30
	case R_TYPE(32):
	case R_TYPE(GLOB_DAT):
		def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
		if (def == NULL)
			return -1;

		tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
		    rela->r_addend);
		if (*where != tmp)
			*where = tmp;
		rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
		    defobj->strtab + def->st_name, obj->path,
		    (void *)*where, defobj->path));
		break;

	case R_TYPE(RELATIVE):
		*where += (Elf_Addr)obj->relocbase;
		rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
		    (void *)*where));
		break;

	case R_TYPE(COPY):
		/*
		 * These are deferred until all other relocations have
		 * been done.  All we do here is make sure that the COPY
		 * relocation is not in a shared library.  They are allowed
		 * only in executable files.
		 */
		if (!obj->mainprog) {
			_rtld_error(
d81 18
a98 1
			    obj->path);
a100 16
		rdbg(dodebug, ("COPY (avoid in main)"));
		break;

	default:
		def = _rtld_find_symdef(rela->r_info, obj, &defobj, true);
		rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
		    "addend = %p, contents = %p, symbol = %s",
		    (u_long)ELF_R_SYM(rela->r_info),
		    (u_long)ELF_R_TYPE(rela->r_info),
		    (void *)rela->r_offset, (void *)rela->r_addend,
		    (void *)*where,
		    def ? defobj->strtab + def->st_name : "??"));
		_rtld_error("%s: Unsupported relocation type %ld "
		    "in non-PLT relocations\n",
		    obj->path, (u_long) ELF_R_TYPE(rela->r_info));
		return -1;
@


1.1
log
@Make _rtld_setup_pltgot() a consistent interface on all platforms.
@
text
@d13 85
@
