head	1.35;
access;
symbols
	netbsd-11-0-RC5:1.35
	netbsd-11-0-RC4:1.35
	netbsd-11-0-RC3:1.35
	netbsd-11-0-RC2:1.35
	netbsd-11-0-RC1:1.35
	perseant-exfatfs-base-20250801:1.35
	netbsd-11:1.35.0.2
	netbsd-11-base:1.35
	netbsd-10-1-RELEASE:1.34
	perseant-exfatfs-base-20240630:1.34
	perseant-exfatfs:1.34.0.16
	perseant-exfatfs-base:1.34
	netbsd-8-3-RELEASE:1.31.8.1
	netbsd-9-4-RELEASE:1.34
	netbsd-10-0-RELEASE:1.34
	netbsd-10-0-RC6:1.34
	netbsd-10-0-RC5:1.34
	netbsd-10-0-RC4:1.34
	netbsd-10-0-RC3:1.34
	netbsd-10-0-RC2:1.34
	netbsd-10-0-RC1:1.34
	netbsd-10:1.34.0.14
	netbsd-10-base:1.34
	netbsd-9-3-RELEASE:1.34
	cjep_sun2x-base1:1.34
	cjep_sun2x:1.34.0.12
	cjep_sun2x-base:1.34
	cjep_staticlib_x-base1:1.34
	netbsd-9-2-RELEASE:1.34
	cjep_staticlib_x:1.34.0.10
	cjep_staticlib_x-base:1.34
	netbsd-9-1-RELEASE:1.34
	phil-wifi-20200421:1.34
	phil-wifi-20200411:1.34
	is-mlppp:1.34.0.8
	is-mlppp-base:1.34
	phil-wifi-20200406:1.34
	netbsd-8-2-RELEASE:1.31.8.1
	netbsd-9-0-RELEASE:1.34
	netbsd-9-0-RC2:1.34
	netbsd-9-0-RC1:1.34
	phil-wifi-20191119:1.34
	netbsd-9:1.34.0.6
	netbsd-9-base:1.34
	phil-wifi-20190609:1.34
	netbsd-8-1-RELEASE:1.31.8.1
	netbsd-8-1-RC1:1.31.8.1
	pgoyette-compat-merge-20190127:1.34
	pgoyette-compat-20190127:1.34
	pgoyette-compat-20190118:1.34
	pgoyette-compat-1226:1.34
	pgoyette-compat-1126:1.34
	pgoyette-compat-1020:1.34
	pgoyette-compat-0930:1.34
	pgoyette-compat-0906:1.34
	netbsd-7-2-RELEASE:1.29.4.1
	pgoyette-compat-0728:1.34
	netbsd-8-0-RELEASE:1.31.8.1
	phil-wifi:1.34.0.4
	phil-wifi-base:1.34
	pgoyette-compat-0625:1.34
	netbsd-8-0-RC2:1.31.8.1
	pgoyette-compat-0521:1.34
	pgoyette-compat-0502:1.34
	pgoyette-compat-0422:1.34
	netbsd-8-0-RC1:1.31.8.1
	pgoyette-compat-0415:1.34
	pgoyette-compat-0407:1.34
	pgoyette-compat-0330:1.34
	pgoyette-compat-0322:1.34
	pgoyette-compat-0315:1.34
	netbsd-7-1-2-RELEASE:1.29.4.1
	pgoyette-compat:1.34.0.2
	pgoyette-compat-base:1.34
	netbsd-7-1-1-RELEASE:1.29.4.1
	matt-nb8-mediatek:1.31.8.1.0.2
	matt-nb8-mediatek-base:1.31.8.1
	perseant-stdc-iso10646:1.33.0.2
	perseant-stdc-iso10646-base:1.33
	netbsd-8:1.31.0.8
	netbsd-8-base:1.31
	prg-localcount2-base3:1.31
	prg-localcount2-base2:1.31
	prg-localcount2-base1:1.31
	prg-localcount2:1.31.0.6
	prg-localcount2-base:1.31
	pgoyette-localcount-20170426:1.31
	bouyer-socketcan-base1:1.31
	pgoyette-localcount-20170320:1.31
	netbsd-7-1:1.29.4.1.0.4
	netbsd-7-1-RELEASE:1.29.4.1
	netbsd-7-1-RC2:1.29.4.1
	netbsd-7-nhusb-base-20170116:1.29.4.1
	bouyer-socketcan:1.31.0.4
	bouyer-socketcan-base:1.31
	pgoyette-localcount-20170107:1.31
	netbsd-7-1-RC1:1.29.4.1
	pgoyette-localcount-20161104:1.31
	netbsd-7-0-2-RELEASE:1.29
	localcount-20160914:1.31
	netbsd-7-nhusb:1.29.4.1.0.2
	netbsd-7-nhusb-base:1.29.4.1
	pgoyette-localcount-20160806:1.31
	pgoyette-localcount-20160726:1.31
	pgoyette-localcount:1.31.0.2
	pgoyette-localcount-base:1.31
	netbsd-7-0-1-RELEASE:1.29
	netbsd-7-0:1.29.0.6
	netbsd-7-0-RELEASE:1.29
	netbsd-7-0-RC3:1.29
	netbsd-7-0-RC2:1.29
	netbsd-7-0-RC1:1.29
	netbsd-5-2-3-RELEASE:1.23.4.1
	netbsd-5-1-5-RELEASE:1.23
	netbsd-6-0-6-RELEASE:1.28
	netbsd-6-1-5-RELEASE:1.28
	netbsd-7:1.29.0.4
	netbsd-7-base:1.29
	yamt-pagecache-base9:1.29
	yamt-pagecache-tag8:1.28
	netbsd-6-1-4-RELEASE:1.28
	netbsd-6-0-5-RELEASE:1.28
	tls-earlyentropy:1.29.0.2
	tls-earlyentropy-base:1.29
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.29
	riastradh-drm2-base3:1.28
	netbsd-6-1-3-RELEASE:1.28
	netbsd-6-0-4-RELEASE:1.28
	netbsd-5-2-2-RELEASE:1.23.4.1
	netbsd-5-1-4-RELEASE:1.23
	netbsd-6-1-2-RELEASE:1.28
	netbsd-6-0-3-RELEASE:1.28
	netbsd-5-2-1-RELEASE:1.23.4.1
	netbsd-5-1-3-RELEASE:1.23
	netbsd-6-1-1-RELEASE:1.28
	riastradh-drm2-base2:1.28
	riastradh-drm2-base1:1.28
	riastradh-drm2:1.28.0.14
	riastradh-drm2-base:1.28
	netbsd-6-1:1.28.0.18
	netbsd-6-0-2-RELEASE:1.28
	netbsd-6-1-RELEASE:1.28
	netbsd-6-1-RC4:1.28
	netbsd-6-1-RC3:1.28
	agc-symver:1.28.0.16
	agc-symver-base:1.28
	netbsd-6-1-RC2:1.28
	netbsd-6-1-RC1:1.28
	yamt-pagecache-base8:1.28
	netbsd-5-2:1.23.4.1.0.2
	netbsd-6-0-1-RELEASE:1.28
	yamt-pagecache-base7:1.28
	netbsd-5-2-RELEASE:1.23.4.1
	netbsd-5-2-RC1:1.23.4.1
	matt-nb6-plus-nbase:1.28
	yamt-pagecache-base6:1.28
	netbsd-6-0:1.28.0.12
	netbsd-6-0-RELEASE:1.28
	netbsd-6-0-RC2:1.28
	tls-maxphys:1.28.0.10
	tls-maxphys-base:1.29
	matt-nb6-plus:1.28.0.8
	matt-nb6-plus-base:1.28
	netbsd-6-0-RC1:1.28
	yamt-pagecache-base5:1.28
	yamt-pagecache-base4:1.28
	netbsd-6:1.28.0.6
	netbsd-6-base:1.28
	netbsd-5-1-2-RELEASE:1.23
	netbsd-5-1-1-RELEASE:1.23
	yamt-pagecache-base3:1.28
	yamt-pagecache-base2:1.28
	yamt-pagecache:1.28.0.4
	yamt-pagecache-base:1.28
	cherry-xenmp:1.28.0.2
	cherry-xenmp-base:1.28
	bouyer-quota2-nbase:1.27
	bouyer-quota2:1.27.0.2
	bouyer-quota2-base:1.27
	matt-mips64-premerge-20101231:1.27
	matt-nb5-mips64-premerge-20101231:1.23
	matt-nb5-pq3:1.23.0.14
	matt-nb5-pq3-base:1.23
	netbsd-5-1:1.23.0.12
	netbsd-5-1-RELEASE:1.23
	netbsd-5-1-RC4:1.23
	matt-nb5-mips64-k15:1.23
	netbsd-5-1-RC3:1.23
	netbsd-5-1-RC2:1.23
	netbsd-5-1-RC1:1.23
	netbsd-5-0-2-RELEASE:1.23
	matt-nb5-mips64-premerge-20091211:1.23
	matt-premerge-20091211:1.25
	matt-nb5-mips64-u2-k2-k4-k7-k8-k9:1.23
	matt-nb4-mips64-k7-u2a-k9b:1.23
	matt-nb5-mips64-u1-k1-k5:1.23
	matt-nb5-mips64:1.23.0.10
	netbsd-5-0-1-RELEASE:1.23
	jym-xensuspend-nbase:1.24
	netbsd-5-0:1.23.0.8
	netbsd-5-0-RELEASE:1.23
	netbsd-5-0-RC4:1.23
	netbsd-5-0-RC3:1.23
	netbsd-5-0-RC2:1.23
	jym-xensuspend:1.23.0.6
	jym-xensuspend-base:1.24
	netbsd-5-0-RC1:1.23
	netbsd-5:1.23.0.4
	netbsd-5-base:1.23
	matt-mips64-base2:1.23
	matt-mips64:1.21.0.22
	netbsd-4-0-1-RELEASE:1.21
	wrstuden-revivesa-base-3:1.23
	wrstuden-revivesa-base-2:1.23
	wrstuden-fixsa-newbase:1.21
	wrstuden-revivesa-base-1:1.21
	yamt-pf42-base4:1.21
	yamt-pf42-base3:1.21
	hpcarm-cleanup-nbase:1.21
	yamt-pf42-baseX:1.21
	yamt-pf42-base2:1.21
	wrstuden-revivesa:1.21.0.20
	wrstuden-revivesa-base:1.21
	yamt-pf42:1.21.0.18
	yamt-pf42-base:1.21
	keiichi-mipv6:1.21.0.16
	keiichi-mipv6-base:1.21
	matt-armv6-nbase:1.21
	matt-armv6-prevmlocking:1.21
	wrstuden-fixsa-base-1:1.21
	netbsd-4-0:1.21.0.14
	netbsd-4-0-RELEASE:1.21
	cube-autoconf:1.21.0.12
	cube-autoconf-base:1.21
	netbsd-4-0-RC5:1.21
	netbsd-4-0-RC4:1.21
	netbsd-4-0-RC3:1.21
	netbsd-4-0-RC2:1.21
	netbsd-4-0-RC1:1.21
	matt-armv6:1.21.0.10
	matt-armv6-base:1.21
	matt-mips64-base:1.21
	hpcarm-cleanup:1.21.0.8
	hpcarm-cleanup-base:1.21
	netbsd-3-1-1-RELEASE:1.17
	netbsd-3-0-3-RELEASE:1.17
	wrstuden-fixsa:1.21.0.6
	wrstuden-fixsa-base:1.21
	abandoned-netbsd-4-base:1.21
	abandoned-netbsd-4:1.21.0.2
	netbsd-3-1:1.17.0.14
	netbsd-3-1-RELEASE:1.17
	netbsd-3-0-2-RELEASE:1.17
	netbsd-3-1-RC4:1.17
	netbsd-3-1-RC3:1.17
	netbsd-3-1-RC2:1.17
	netbsd-3-1-RC1:1.17
	netbsd-4:1.21.0.4
	netbsd-4-base:1.21
	netbsd-3-0-1-RELEASE:1.17
	netbsd-3-0:1.17.0.12
	netbsd-3-0-RELEASE:1.17
	netbsd-3-0-RC6:1.17
	netbsd-3-0-RC5:1.17
	netbsd-3-0-RC4:1.17
	netbsd-3-0-RC3:1.17
	netbsd-3-0-RC2:1.17
	netbsd-3-0-RC1:1.17
	netbsd-2-0-3-RELEASE:1.17
	netbsd-2-1:1.17.0.10
	netbsd-2-1-RELEASE:1.17
	netbsd-2-1-RC6:1.17
	netbsd-2-1-RC5:1.17
	netbsd-2-1-RC4:1.17
	netbsd-2-1-RC3:1.17
	netbsd-2-1-RC2:1.17
	netbsd-2-1-RC1:1.17
	netbsd-2-0-2-RELEASE:1.17
	netbsd-3:1.17.0.8
	netbsd-3-base:1.17
	netbsd-2-0-1-RELEASE:1.17
	netbsd-2:1.17.0.6
	netbsd-2-base:1.17
	netbsd-2-0-RELEASE:1.17
	netbsd-2-0-RC5:1.17
	netbsd-2-0-RC4:1.17
	netbsd-2-0-RC3:1.17
	netbsd-2-0-RC2:1.17
	netbsd-2-0-RC1:1.17
	netbsd-1-6:1.17.0.4
	netbsd-2-0:1.17.0.2
	netbsd-2-0-base:1.17
	fvdl_fs64_base:1.16;
locks; strict;
comment	@ * @;


1.35
date	2025.04.16.18.01.01;	author riastradh;	state Exp;
branches;
next	1.34;
commitid	FdxbxVQBZrL1SiRF;

1.34
date	2017.08.10.19.03.27;	author joerg;	state Exp;
branches
	1.34.16.1;
next	1.33;
commitid	UgH5577k4GrjpH2A;

1.33
date	2017.06.20.15.02.54;	author joerg;	state Exp;
branches;
next	1.32;
commitid	1nkrkvZcpVWLI7Wz;

1.32
date	2017.06.19.11.57.02;	author joerg;	state Exp;
branches;
next	1.31;
commitid	pYVYx1tH1kZmHYVz;

1.31
date	2016.04.14.20.17.07;	author skrll;	state Exp;
branches
	1.31.8.1;
next	1.30;
commitid	7xdAu6FeGesilD2z;

1.30
date	2014.08.25.20.40.53;	author joerg;	state Exp;
branches;
next	1.29;
commitid	hm6gwLhn9YorHMNx;

1.29
date	2014.03.21.01.43.33;	author matt;	state Exp;
branches
	1.29.4.1;
next	1.28;
commitid	EkRygujaIyB1svtx;

1.28
date	2011.03.25.18.07.07;	author joerg;	state Exp;
branches
	1.28.4.1
	1.28.10.1;
next	1.27;

1.27
date	2010.08.06.16.33.19;	author joerg;	state Exp;
branches;
next	1.26;

1.26
date	2010.01.13.20.17.23;	author christos;	state Exp;
branches;
next	1.25;

1.25
date	2009.08.29.13.46.55;	author jmmv;	state Exp;
branches;
next	1.24;

1.24
date	2009.03.16.02.46.48;	author lukem;	state Exp;
branches;
next	1.23;

1.23
date	2008.07.24.06.51.59;	author skrll;	state Exp;
branches
	1.23.4.1
	1.23.6.1;
next	1.22;

1.22
date	2008.07.24.04.39.26;	author matt;	state Exp;
branches;
next	1.21;

1.21
date	2006.05.21.04.17.35;	author mrg;	state Exp;
branches
	1.21.20.1;
next	1.20;

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

1.19
date	2005.08.15.10.52.42;	author skrll;	state Exp;
branches;
next	1.18;

1.18
date	2005.07.24.08.02.23;	author skrll;	state Exp;
branches;
next	1.17;

1.17
date	2003.07.24.10.12.30;	author skrll;	state Exp;
branches
	1.17.4.1;
next	1.16;

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

1.15
date	2002.09.26.22.26.27;	author mycroft;	state Exp;
branches;
next	1.14;

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

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

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

1.11
date	2002.09.12.20.21.02;	author mycroft;	state Exp;
branches;
next	1.10;

1.10
date	2002.09.11.14.19.31;	author junyoung;	state Exp;
branches;
next	1.9;

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

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

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

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

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

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

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

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

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

1.34.16.1
date	2025.08.02.05.55.03;	author perseant;	state Exp;
branches;
next	;
commitid	23j6GFaDws3O875G;

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

1.29.4.1
date	2016.03.06.18.17.56;	author martin;	state Exp;
branches;
next	;
commitid	Ns3WeAQc8ORoVBXy;

1.28.4.1
date	2014.05.22.11.37.14;	author yamt;	state Exp;
branches;
next	;
commitid	VmckIax9CgOhKwBx;

1.28.10.1
date	2014.08.20.00.02.23;	author tls;	state Exp;
branches;
next	;
commitid	jTnpym9Qu0o4R1Nx;

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

1.23.6.1
date	2009.05.13.19.18.42;	author jym;	state Exp;
branches;
next	;

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

1.17.4.1
date	2003.07.24.10.12.30;	author tron;	state dead;
branches;
next	1.17.4.2;

1.17.4.2
date	2004.05.28.08.31.23;	author tron;	state Exp;
branches;
next	;


desc
@@


1.35
log
@ld.elf_so/arch/vax: Add copyright notice from the original.

Bulk originally copied from libexec/ld.elf_so/reloc.c rev. 1.58.
@
text
@/*	$NetBSD: mdreloc.c,v 1.34 2017/08/10 19:03:27 joerg 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.
 */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.34 2017/08/10 19:03:27 joerg Exp $");
#endif /* not lint */

#include <sys/types.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);
static inline int _rtld_relocate_plt_object(const Obj_Entry *,
    const Elf_Rela *, Elf_Addr *);

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_Rela *rela = 0, *relalim;
	Elf_Addr relasz = 0;
	Elf_Addr *where;

	for (; dynp->d_tag != DT_NULL; dynp++) {
		switch (dynp->d_tag) {
		case DT_RELA:
			rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_RELASZ:
			relasz = dynp->d_un.d_val;
			break;
		}
	}
	relalim = (const Elf_Rela *)((const uint8_t *)rela + relasz);
	for (; rela < relalim; rela++) {
		where = (Elf_Addr *)(relocbase + rela->r_offset);
		*where = (Elf_Addr)(relocbase + rela->r_addend);
	}
}

int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
	const Elf_Rela *rela;
	const Elf_Sym *def = NULL;
	const Obj_Entry *defobj = NULL;
	unsigned long last_symnum = ULONG_MAX;

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

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

		switch (ELF_R_TYPE(rela->r_info)) {
		case R_TYPE(32):	/* word32 S + A */
		case R_TYPE(GLOB_DAT):	/* word32 S + A */
			symnum = ELF_R_SYM(rela->r_info);
			if (last_symnum != symnum) {
				last_symnum = symnum;
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
			}
			break;

		default:
			break;
		}

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

		case R_TYPE(32):	/* word32 S + A */
		case R_TYPE(GLOB_DAT):	/* word32 S + A */
			tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
			    rela->r_addend);

			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):	/* word32 B + A */
			tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
			if (*where != tmp)
				*where = tmp;
			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, "
			    "addend = %p, contents = %p",
			    (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));
			_rtld_error("%s: Unsupported relocation type %ld "
			    "in non-PLT relocations",
			    obj->path, (u_long) ELF_R_TYPE(rela->r_info));
			return -1;
		}
	}
	return 0;
}

int
_rtld_relocate_plt_lazy(Obj_Entry *obj)
{
	const Elf_Rela *rela;

	if (!obj->relocbase)
		return 0;

	for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);

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

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

	return 0;
}

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

	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;
		new_value = _rtld_resolve_ifunc(defobj, def);
	} else {
		new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
		    rela->r_addend);
	}
	rdbg(("bind now/fixup pltgot %p in %s --> old=%p new=%p", where,
	    defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
	if (*where != new_value)
		*where = new_value;

	if (tp)
		*tp = new_value - rela->r_addend;

	return 0;
}

caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
	const Elf_Rela *rela = (const Elf_Rela *)((const uint8_t *)obj->pltrela + reloff);
	Elf_Addr result;
	int err;

	result = 0;	/* XXX gcc */

	_rtld_shared_enter();
	err = _rtld_relocate_plt_object(obj, rela, &result);
	if (err)
		_rtld_die();
	_rtld_shared_exit();

	return (caddr_t)result;
}

int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
	const Elf_Rela *rela;

	for (rela = obj->pltrela; rela < obj->pltrelalim; rela++)
		if (_rtld_relocate_plt_object(obj, rela, NULL) < 0)
			return -1;

	return 0;
}
@


1.34
log
@Add IRELATIVE support for ARM, X86 and PowerPC.
@
text
@d1 32
a32 1
/*	$NetBSD: mdreloc.c,v 1.33 2017/06/20 15:02:54 joerg Exp $	*/
d36 1
a36 1
__RCSID("$NetBSD: mdreloc.c,v 1.33 2017/06/20 15:02:54 joerg Exp $");
@


1.34.16.1
log
@Sync with HEAD
@
text
@d1 1
a1 32
/*	$NetBSD: mdreloc.c,v 1.35 2025/04/16 18:01:01 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.
 */
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.35 2025/04/16 18:01:01 riastradh Exp $");
@


1.33
log
@Add back symnum, fix debug print.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:02 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.32 2017/06/19 11:57:02 joerg Exp $");
d139 1
a139 1
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
@


1.32
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.31 2016/04/14 20:17:07 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $");
d61 1
d124 1
a124 1
			    "addend = %p, contents = %p, symbol = %s",
d128 1
a128 2
			    (void *)*where,
			    obj->strtab + obj->symtab[symnum].st_name));
@


1.31
log
@Remove duplicated __RCSIDs I added years ago - I blame CVS.

Spotted by Miod Vallat
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:53 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:53 joerg Exp $");
d54 3
a59 2
		const Elf_Sym   *def;
		const Obj_Entry *defobj;
a60 1
		unsigned long	 symnum;
d63 17
a79 1
		symnum = ELF_R_SYM(rela->r_info);
a86 4
			def = _rtld_find_symdef(symnum, obj, &defobj, false);
			if (def == NULL)
				return -1;

d124 2
a125 1
			    symnum, (u_long)ELF_R_TYPE(rela->r_info),
@


1.31.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.31 2016/04/14 20:17:07 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.31 2016/04/14 20:17:07 skrll Exp $");
a53 3
	const Elf_Sym *def = NULL;
	const Obj_Entry *defobj = NULL;
	unsigned long last_symnum = ULONG_MAX;
d57 2
d60 1
a60 1
		unsigned long    symnum;
d63 1
a63 17

		switch (ELF_R_TYPE(rela->r_info)) {
		case R_TYPE(32):	/* word32 S + A */
		case R_TYPE(GLOB_DAT):	/* word32 S + A */
			symnum = ELF_R_SYM(rela->r_info);
			if (last_symnum != symnum) {
				last_symnum = symnum;
				def = _rtld_find_symdef(symnum, obj, &defobj,
				    false);
				if (def == NULL)
					return -1;
			}
			break;

		default:
			break;
		}
d71 4
d111 2
a112 3
			    "addend = %p, contents = %p",
			    (u_long)ELF_R_SYM(rela->r_info),
			    (u_long)ELF_R_TYPE(rela->r_info),
d114 2
a115 1
			    (void *)*where));
@


1.30
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.29 2014/03/21 01:43:33 matt Exp $	*/
d5 1
a5 6
__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
#endif /* not lint */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
@


1.29
log
@Improve some of the rdbg messages to print the address of the pltgot slot
being modified.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
d169 8
a176 2
	new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
	    rela->r_addend);
@


1.29.4.1
log
@Catch up to -current, via patch, requested by christos in ticket #1126:
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.29 2014/03/21 01:43:33 matt Exp $");
d169 2
a170 8
	if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
		if (tp == NULL)
			return 0;
		new_value = _rtld_resolve_ifunc(defobj, def);
	} else {
		new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
		    rela->r_addend);
	}
@


1.28
log
@Add basic locking to ld.elf_so.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.27 2010/08/06 16:33:19 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.27 2010/08/06 16:33:19 joerg Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.27 2010/08/06 16:33:19 joerg Exp $");
d145 2
a146 1
		rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
d171 1
a171 1
	rdbg(("bind now/fixup in %s --> old=%p new=%p",
@


1.28.10.1
log
@Rebase to HEAD as of a few days ago.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d5 1
a5 1
__RCSID("$NetBSD$");
d10 1
a10 1
__RCSID("$NetBSD$");
d145 1
a145 2
		rdbg(("lazy fixup pltgot %p in %s --> %p", where, obj->path,
		    (void *)*where));
d170 1
a170 1
	rdbg(("bind now/fixup pltgot %p in %s --> old=%p new=%p", where,
@


1.28.4.1
log
@sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs.  ("Protocol error: too many arguments")
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
d145 1
a145 2
		rdbg(("lazy fixup pltgot %p in %s --> %p", where, obj->path,
		    (void *)*where));
d170 1
a170 1
	rdbg(("bind now/fixup pltgot %p in %s --> old=%p new=%p", where,
@


1.27
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.26 2010/01/13 20:17:23 christos Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.26 2010/01/13 20:17:23 christos Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.26 2010/01/13 20:17:23 christos Exp $");
d190 1
d194 1
@


1.26
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.25 2009/08/29 13:46:55 jmmv Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.25 2009/08/29 13:46:55 jmmv Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.25 2009/08/29 13:46:55 jmmv Exp $");
a13 1
#include <sys/stat.h>
d56 1
a56 1
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
@


1.25
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.24 2009/03/16 02:46:48 lukem Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.24 2009/03/16 02:46:48 lukem Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.24 2009/03/16 02:46:48 lukem Exp $");
d159 1
d161 1
a161 1
	assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
d163 2
a164 2
	def = _rtld_find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true);
	if (def == NULL)
d166 2
d192 1
a192 1
	if (err || result == 0)
@


1.24
log
@Fix const issues (cast const pointers to "const uint8_t *" instead of "caddr_t")

NOTE: change based on ../i386/mdreloc.c 1.27
XXX: not compile tested
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.23 2008/07/24 06:51:59 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2008/07/24 06:51:59 skrll Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2008/07/24 06:51:59 skrll Exp $");
d123 1
a123 1
			    "in non-PLT relocations\n",
@


1.23
log
@RCSID police
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.22 2008/07/24 04:39:26 matt Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.22 2008/07/24 04:39:26 matt Exp $");
d10 1
a10 1
__RCSID("$NetBSD$");
d49 1
a49 1
	relalim = (const Elf_Rela *)((caddr_t)rela + relasz);
d182 1
a182 1
	const Elf_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
@


1.23.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.23 2008/07/24 06:51:59 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2008/07/24 06:51:59 skrll Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.23 2008/07/24 06:51:59 skrll Exp $");
a158 1
	unsigned long info = rela->r_info;
d160 1
a160 1
	assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
d162 2
a163 2
	def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
	if (__predict_false(def == NULL))
a164 2
	if (__predict_false(def == &_rtld_sym_zero))
		return 0;
d189 1
a189 1
	if (err)
@


1.23.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.24 2009/03/16 02:46:48 lukem Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.24 2009/03/16 02:46:48 lukem Exp $");
d10 1
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.24 2009/03/16 02:46:48 lukem Exp $");
d49 1
a49 1
	relalim = (const Elf_Rela *)((const uint8_t *)rela + relasz);
d182 1
a182 1
	const Elf_Rela *rela = (const Elf_Rela *)((const uint8_t *)obj->pltrela + reloff);
@


1.22
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.21 2006/05/21 04:17:35 mrg Exp $	*/
d5 6
a10 1
__RCSID("$NetBSD: mdreloc.c,v 1.21 2006/05/21 04:17:35 mrg Exp $");
@


1.21
log
@avoid more GCC4 uninitialised variable problems.  (sh3 known, vax guessed.)
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.20 2005/08/20 19:01:17 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD: mdreloc.c,v 1.20 2005/08/20 19:01:17 skrll Exp $");
d184 1
a184 1
	if (err)
@


1.21.20.1
log
@Sync with wrstuden-revivesa-base-2.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.21 2006/05/21 04:17:35 mrg Exp $	*/
d5 1
a5 6
__RCSID("$NetBSD: mdreloc.c,v 1.21 2006/05/21 04:17:35 mrg Exp $");
#endif /* not lint */

#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD$");
d184 1
a184 1
	if (err || result == 0)
@


1.20
log
@Add __RCSID.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.19 2005/08/15 10:52:42 skrll Exp $	*/
d5 1
a5 1
__RCSID("$NetBSD$");
d181 2
@


1.19
log
@KNF
@
text
@d1 6
a6 1
/*	$NetBSD: mdreloc.c,v 1.18 2005/07/24 08:02:23 skrll Exp $	*/
@


1.18
log
@Support immediate PLT binding on vax. Tested on simh.

Nearly there...
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.17 2003/07/24 10:12:30 skrll Exp $	*/
d12 2
a13 2
static inline int _rtld_relocate_plt_object(const Obj_Entry *obj,
    const Elf_Rela *rela, Elf_Addr *tp);
@


1.17
log
@ANSIfy and de-__P().
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.16 2002/10/03 20:39:23 mycroft Exp $	*/
d12 2
d142 2
a143 2
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
a144 1
	const Elf_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
d154 1
a154 1
		_rtld_die();
d163 30
a192 1
	return (caddr_t)(new_value - rela->r_addend);
@


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


1.17.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 163
/*	$NetBSD: mdreloc.c,v 1.17.4.1 2004/05/28 08:31:23 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_Rela *rela = 0, *relalim;
	Elf_Addr relasz = 0;
	Elf_Addr *where;

	for (; dynp->d_tag != DT_NULL; dynp++) {
		switch (dynp->d_tag) {
		case DT_RELA:
			rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
			break;
		case DT_RELASZ:
			relasz = dynp->d_un.d_val;
			break;
		}
	}
	relalim = (const Elf_Rela *)((caddr_t)rela + relasz);
	for (; rela < relalim; rela++) {
		where = (Elf_Addr *)(relocbase + rela->r_offset);
		*where = (Elf_Addr)(relocbase + rela->r_addend);
	}
}

int
_rtld_relocate_nonplt_objects(const Obj_Entry *obj)
{
	const Elf_Rela *rela;

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

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

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

		case R_TYPE(32):	/* word32 S + A */
		case R_TYPE(GLOB_DAT):	/* word32 S + A */
			def = _rtld_find_symdef(symnum, 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(("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):	/* word32 B + A */
			tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
			if (*where != tmp)
				*where = tmp;
			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, "
			    "addend = %p, contents = %p, symbol = %s",
			    symnum, (u_long)ELF_R_TYPE(rela->r_info),
			    (void *)rela->r_offset, (void *)rela->r_addend,
			    (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(rela->r_info));
			return -1;
		}
	}
	return 0;
}

int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
	const Elf_Rela *rela;

	if (!obj->relocbase)
		return 0;

	for (rela = obj->pltrela; rela < obj->pltrelalim; rela++) {
		Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);

		assert(ELF_R_TYPE(rela->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_Rela *rela = (const Elf_Rela *)((caddr_t)obj->pltrela + reloff);
	Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	Elf_Addr new_value;
	const Elf_Sym  *def;
	const Obj_Entry *defobj;

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

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

	new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
	    rela->r_addend);
	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 - rela->r_addend);
}
@


1.16
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.15 2002/09/26 22:26:27 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;
d120 1
a120 2
_rtld_relocate_plt_lazy(obj)
	const Obj_Entry *obj;
d141 1
a141 3
_rtld_bind(obj, reloff)
	const Obj_Entry *obj;
	Elf_Word reloff;
@


1.15
log
@Implement a self-relocate function for the VAX.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.14 2002/09/26 20:42:12 mycroft Exp $	*/
d128 1
a128 1
	if (!obj->isdynamic)
@


1.14
log
@Remove the `self' args to _rtld_relocate_objects() and
_rtld_relocate_nonplt_objects().
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.13 2002/09/25 07:27:55 mycroft Exp $	*/
d10 1
d18 26
@


1.13
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.12 2002/09/12 22:56:31 mycroft Exp $	*/
d20 1
a20 1
_rtld_relocate_nonplt_objects(obj, self)
a21 1
	bool self;
@


1.12
log
@Nuke -DRTLD_RELOCATE_SELF and `dodebug' from orbit.
@
text
@d1 1
a1 1
/*	$NetBSD: mdreloc.c,v 1.11 2002/09/12 20:21:02 mycroft Exp $	*/
d10 1
d118 2
a119 2
int
_rtld_relocate_plt_object(obj, rela, addrp)
d121 1
a121 2
	const Elf_Rela *rela;
	caddr_t *addrp;
d123 1
d133 1
a133 1
		return -1;
d142 1
a142 2
	*addrp = (caddr_t)(new_value - rela->r_addend);
	return 0;
@


1.11
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.10 2002/09/11 14:19:31 junyoung Exp $	*/
d19 1
a19 1
_rtld_relocate_nonplt_objects(obj, self, dodebug)
a21 1
	bool dodebug;
d50 1
a50 1
			rdbg(dodebug, ("32/GLOB_DAT %s in %s --> %p in %s",
d59 1
a59 1
			rdbg(dodebug, ("RELATIVE in %s --> %p", obj->path,
d76 1
a76 1
			rdbg(dodebug, ("COPY (avoid in main)"));
d80 1
a80 1
			rdbg(dodebug, ("sym = %lu, type = %lu, offset = %p, "
d96 1
a96 1
_rtld_relocate_plt_lazy(obj, dodebug)
a97 1
	bool dodebug;
d111 1
a111 2
		rdbg(dodebug, ("fixup !main in %s --> %p", obj->path,
		    (void *)*where));
d118 1
a118 1
_rtld_relocate_plt_object(obj, rela, addrp, dodebug)
a121 1
	bool dodebug;
d136 1
a136 1
	rdbg(dodebug, ("bind now/fixup in %s --> old=%p new=%p",
@


1.10
log
@Add $NetBSD$.
@
text
@d1 1
a1 1
/*	$NetBSD$	*/
d8 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
@d1 2
@


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
@d66 1
a66 1
			if (!obj->mainprog) {
d98 1
a98 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;
d93 1
a93 1
	Obj_Entry *obj;
d117 1
a117 1
	Obj_Entry *obj;
@


1.5
log
@Partially fix up some debug printf()s that don't need to use defobj.
@
text
@d90 53
@


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
@d47 2
a48 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
@d26 1
d29 1
d37 1
a37 2
			def = _rtld_find_symdef(rela->r_info, obj, &defobj,
			    false);
a75 2
			def = _rtld_find_symdef(rela->r_info, obj, &defobj,
			    true);
d78 1
a78 2
			    (u_long)ELF_R_SYM(rela->r_info),
			    (u_long)ELF_R_TYPE(rela->r_info),
d81 1
a81 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 15
	Elf_Addr        *where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
	const Elf_Sym   *def;
	const Obj_Entry *defobj;
	Elf_Addr         tmp;

	switch (ELF_R_TYPE(rela->r_info)) {

	case R_TYPE(NONE):
		break;

	case R_TYPE(32):	/* word32 S + A */
	case R_TYPE(GLOB_DAT):	/* word32 S + A */
		def = _rtld_find_symdef(rela->r_info, obj, &defobj, false);
		if (def == NULL)
			return -1;
d21 46
a66 27
		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):	/* word32 B + A */
		tmp = (Elf_Addr)(obj->relocbase + rela->r_addend);
		if (*where != tmp)
			*where = tmp;
		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(
d68 19
a86 1
			    obj->path);
a88 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 73
@
