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