xref: /netbsd/sys/arch/i386/i386/kobj_machdep.c (revision 29add945)
1*29add945Sskrll /*	$NetBSD: kobj_machdep.c,v 1.9 2023/04/28 07:33:56 skrll Exp $	*/
21dd75d28Sad 
31dd75d28Sad /*-
41dd75d28Sad  * Copyright (c) 2008 The NetBSD Foundation, Inc.
51dd75d28Sad  * All rights reserved.
61dd75d28Sad  *
70efea177Sad  * This code is derived from software developed for The NetBSD Foundation
80efea177Sad  * by Andrew Doran.
90efea177Sad  *
101dd75d28Sad  * Redistribution and use in source and binary forms, with or without
111dd75d28Sad  * modification, are permitted provided that the following conditions
121dd75d28Sad  * are met:
131dd75d28Sad  * 1. Redistributions of source code must retain the above copyright
141dd75d28Sad  *    notice, this list of conditions and the following disclaimer.
151dd75d28Sad  * 2. Redistributions in binary form must reproduce the above copyright
161dd75d28Sad  *    notice, this list of conditions and the following disclaimer in the
171dd75d28Sad  *    documentation and/or other materials provided with the distribution.
181dd75d28Sad  *
191dd75d28Sad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201dd75d28Sad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211dd75d28Sad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221dd75d28Sad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231dd75d28Sad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241dd75d28Sad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251dd75d28Sad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261dd75d28Sad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271dd75d28Sad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281dd75d28Sad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291dd75d28Sad  * POSSIBILITY OF SUCH DAMAGE.
301dd75d28Sad  */
311dd75d28Sad 
321dd75d28Sad /*-
331dd75d28Sad  * Copyright 1996-1998 John D. Polstra.
341dd75d28Sad  * All rights reserved.
351dd75d28Sad  *
361dd75d28Sad  * Redistribution and use in source and binary forms, with or without
371dd75d28Sad  * modification, are permitted provided that the following conditions
381dd75d28Sad  * are met:
391dd75d28Sad  * 1. Redistributions of source code must retain the above copyright
401dd75d28Sad  *    notice, this list of conditions and the following disclaimer.
411dd75d28Sad  * 2. Redistributions in binary form must reproduce the above copyright
421dd75d28Sad  *    notice, this list of conditions and the following disclaimer in the
431dd75d28Sad  *    documentation and/or other materials provided with the distribution.
441dd75d28Sad  *
451dd75d28Sad  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
461dd75d28Sad  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
471dd75d28Sad  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
481dd75d28Sad  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
491dd75d28Sad  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
501dd75d28Sad  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
511dd75d28Sad  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
521dd75d28Sad  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
531dd75d28Sad  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
541dd75d28Sad  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
551dd75d28Sad  */
561dd75d28Sad 
571dd75d28Sad #include <sys/cdefs.h>
58*29add945Sskrll __KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.9 2023/04/28 07:33:56 skrll Exp $");
591dd75d28Sad 
601dd75d28Sad #define	ELFSIZE		ARCH_ELFSIZE
611dd75d28Sad 
621dd75d28Sad #include <sys/param.h>
631dd75d28Sad #include <sys/systm.h>
64dff5d844Sad #include <sys/kernel.h>
651dd75d28Sad #include <sys/kobj.h>
661dd75d28Sad #include <sys/exec.h>
671dd75d28Sad #include <sys/exec_elf.h>
681dd75d28Sad #include <sys/xcall.h>
691dd75d28Sad 
701dd75d28Sad #include <machine/cpufunc.h>
711dd75d28Sad 
721dd75d28Sad int
kobj_reloc(kobj_t ko,uintptr_t relocbase,const void * data,bool isrela,bool local)731dd75d28Sad kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
741dd75d28Sad 	   bool isrela, bool local)
751dd75d28Sad {
761dd75d28Sad 	Elf_Addr *where;
771dd75d28Sad 	Elf_Addr addr;
781dd75d28Sad 	Elf_Addr addend;
791dd75d28Sad 	Elf_Word rtype, symidx;
801dd75d28Sad 	const Elf_Rel *rel;
811dd75d28Sad 	const Elf_Rela *rela;
8262592c33Smaxv 	int error;
831dd75d28Sad 
841dd75d28Sad 	if (isrela) {
851dd75d28Sad 		rela = (const Elf_Rela *)data;
861dd75d28Sad 		where = (Elf_Addr *) (relocbase + rela->r_offset);
871dd75d28Sad 		addend = rela->r_addend;
881dd75d28Sad 		rtype = ELF_R_TYPE(rela->r_info);
891dd75d28Sad 		symidx = ELF_R_SYM(rela->r_info);
901dd75d28Sad 	} else {
911dd75d28Sad 		rel = (const Elf_Rel *)data;
921dd75d28Sad 		where = (Elf_Addr *) (relocbase + rel->r_offset);
931dd75d28Sad 		addend = *where;
941dd75d28Sad 		rtype = ELF_R_TYPE(rel->r_info);
951dd75d28Sad 		symidx = ELF_R_SYM(rel->r_info);
961dd75d28Sad 	}
971dd75d28Sad 
98*29add945Sskrll 	const Elf_Sym *sym = kobj_symbol(ko, symidx);
99*29add945Sskrll 
100*29add945Sskrll 	if (!local && ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
101*29add945Sskrll 		return 0;
102*29add945Sskrll 	}
103*29add945Sskrll 
1041dd75d28Sad 	switch (rtype) {
1051dd75d28Sad 	case R_386_NONE:	/* none */
106eb4b641dSad 		return 0;
1071dd75d28Sad 
1081dd75d28Sad 	case R_386_32:		/* S + A */
10962592c33Smaxv 		error = kobj_sym_lookup(ko, symidx, &addr);
11062592c33Smaxv 		if (error)
1111dd75d28Sad 			return -1;
1121dd75d28Sad 		addr += addend;
1131dd75d28Sad 		break;
1141dd75d28Sad 
1151dd75d28Sad 	case R_386_PC32:	/* S + A - P */
11662592c33Smaxv 		error = kobj_sym_lookup(ko, symidx, &addr);
11762592c33Smaxv 		if (error)
1181dd75d28Sad 			return -1;
1191dd75d28Sad 		addr += addend - (Elf_Addr)where;
1201dd75d28Sad 		break;
1211dd75d28Sad 
1221dd75d28Sad 	case R_386_GLOB_DAT:	/* S */
12362592c33Smaxv 		error = kobj_sym_lookup(ko, symidx, &addr);
12462592c33Smaxv 		if (error)
1251dd75d28Sad 			return -1;
1261dd75d28Sad 		break;
1271dd75d28Sad 
1281dd75d28Sad 	case R_386_RELATIVE:
12975209c4dSad 		addr = relocbase + addend;
1301dd75d28Sad 		break;
1311dd75d28Sad 
1321dd75d28Sad 	default:
1331dd75d28Sad 		printf("kobj_reloc: unexpected relocation type %d\n", rtype);
1341dd75d28Sad 		return -1;
1351dd75d28Sad 	}
1361dd75d28Sad 
137eb4b641dSad 	*where = addr;
1381dd75d28Sad 	return 0;
1391dd75d28Sad }
1401dd75d28Sad 
1411dd75d28Sad int
kobj_machdep(kobj_t ko,void * base,size_t size,bool load)1421dd75d28Sad kobj_machdep(kobj_t ko, void *base, size_t size, bool load)
1431dd75d28Sad {
1441dd75d28Sad 	uint64_t where;
1451dd75d28Sad 
146e99d5fabSpooka 	/*
147e99d5fabSpooka 	 * Currently we want this to invalidate the Pentium 4 trace cache.
148e99d5fabSpooka 	 * Other caches are snoopably coherent.
149e99d5fabSpooka 	 */
1501dd75d28Sad 	if (load) {
151dff5d844Sad 		if (cold) {
152dff5d844Sad 			wbinvd();
153dff5d844Sad 		} else {
1541dd75d28Sad 			where = xc_broadcast(0, (xcfunc_t)wbinvd, NULL, NULL);
1551dd75d28Sad 			xc_wait(where);
1561dd75d28Sad 		}
157dff5d844Sad 	}
1581dd75d28Sad 
1591dd75d28Sad 	return 0;
1601dd75d28Sad }
161