1/* $NetBSD: kobj_machdep.c,v 1.5 2008/12/08 08:41:36 njoly Exp $ */
2
3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software developed for The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright 1996-1998 John D. Polstra.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 */
56
57#include <sys/cdefs.h>
58__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.5 2008/12/08 08:41:36 njoly Exp $");
59
60#define ELFSIZE ARCH_ELFSIZE
61
62#include <sys/param.h>
63#include <sys/systm.h>
64#include <sys/kernel.h>
65#include <sys/kobj.h>
66#include <sys/exec.h>
67#include <sys/exec_elf.h>
68#include <sys/xcall.h>
69
70#include <machine/cpufunc.h>
71
72int
73kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
74 bool isrela, bool local)
75{
76 Elf64_Addr *where, val;
77 Elf32_Addr *where32, val32;
78 Elf64_Addr addr;
79 Elf64_Addr addend;
80 uintptr_t rtype, symidx;
81 const Elf_Rel *rel;
82 const Elf_Rela *rela;
83
84 if (isrela) {
85 rela = (const Elf_Rela *)data;
86 where = (Elf64_Addr *)(relocbase + rela->r_offset);
87 addend = rela->r_addend;
88 rtype = ELF_R_TYPE(rela->r_info);
89 symidx = ELF_R_SYM(rela->r_info);
90 } else {
91 rel = (const Elf_Rel *)data;
92 where = (Elf64_Addr *)(relocbase + rel->r_offset);
93 rtype = ELF_R_TYPE(rel->r_info);
94 symidx = ELF_R_SYM(rel->r_info);
95 /* Addend is 32 bit on 32 bit relocs */
96 switch (rtype) {
97 case R_X86_64_PC32:
98 case R_X86_64_32:
99 case R_X86_64_32S:
100 addend = *(Elf32_Addr *)where;
101 break;
102 default:
103 addend = *where;
104 break;
105 }
106 }
107
108 switch (rtype) {
109 case R_X86_64_NONE: /* none */
110 break;
111
112 case R_X86_64_64: /* S + A */
113 addr = kobj_sym_lookup(ko, symidx);
114 if (addr == 0)
115 return -1;
116 val = addr + addend;
117 *where = val;
118 break;
119
120 case R_X86_64_PC32: /* S + A - P */
121 addr = kobj_sym_lookup(ko, symidx);
122 if (addr == 0)
123 return -1;
124 where32 = (Elf32_Addr *)where;
125 val32 = (Elf32_Addr)(addr + addend - (Elf64_Addr)where);
126 *where32 = val32;
127 break;
128
129 case R_X86_64_32: /* S + A */
130 case R_X86_64_32S: /* S + A sign extend */
131 addr = kobj_sym_lookup(ko, symidx);
132 if (addr == 0)
133 return -1;
134 val32 = (Elf32_Addr)(addr + addend);
135 where32 = (Elf32_Addr *)where;
136 *where32 = val32;
137 break;
138
139 case R_X86_64_GLOB_DAT: /* S */
140 case R_X86_64_JUMP_SLOT:/* XXX need addend + offset */
141 addr = kobj_sym_lookup(ko, symidx);
142 if (addr == 0)
143 return -1;
144 *where = addr;
145 break;
146
147 case R_X86_64_RELATIVE: /* B + A */
148 addr = relocbase + addend;
149 val = addr;
150 *where = val;
151 break;
152
153 default:
154 printf("kobj_reloc: unexpected relocation type %ld\n", rtype);
155 return -1;
156 }
157
158 return 0;
159}
160
161int
162kobj_machdep(kobj_t ko, void *base, size_t size, bool load)
163{
164 uint64_t where;
165
166 if (load) {
167 if (cold) {
168 wbinvd();
169 } else {
170 where = xc_broadcast(0, (xcfunc_t)wbinvd, NULL, NULL);
171 xc_wait(where);
172 }
173 }
174
175 return 0;
176}
177