Mon Aug 17 19:44:32 2009 UTC ()
Add support for R_ARM_PC24 relocations and fix R_ARM_ABS32.
Changes from PR/40309, but structure changed so there is a common error printf.
Compiles ok, but my quick kernel build failed to find module_init_md().


(dsl)
diff -r1.2 -r1.3 src/sys/arch/arm/arm32/kobj_machdep.c

cvs diff -r1.2 -r1.3 src/sys/arch/arm/arm32/kobj_machdep.c (expand / switch to unified diff)

--- src/sys/arch/arm/arm32/kobj_machdep.c 2008/04/28 20:23:13 1.2
+++ src/sys/arch/arm/arm32/kobj_machdep.c 2009/08/17 19:44:32 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kobj_machdep.c,v 1.2 2008/04/28 20:23:13 martin Exp $ */ 1/* $NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -42,27 +42,27 @@ @@ -42,27 +42,27 @@
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */ 52 */
53 53
54#include <sys/cdefs.h> 54#include <sys/cdefs.h>
55__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.2 2008/04/28 20:23:13 martin Exp $"); 55__KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.3 2009/08/17 19:44:32 dsl Exp $");
56 56
57#define ELFSIZE ARCH_ELFSIZE 57#define ELFSIZE ARCH_ELFSIZE
58 58
59#include <sys/param.h> 59#include <sys/param.h>
60#include <sys/systm.h> 60#include <sys/systm.h>
61#include <sys/kobj.h> 61#include <sys/kobj.h>
62#include <sys/exec.h> 62#include <sys/exec.h>
63#include <sys/exec_elf.h> 63#include <sys/exec_elf.h>
64 64
65#include <arm/cpufunc.h> 65#include <arm/cpufunc.h>
66 66
67int 67int
68kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data, 68kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
@@ -81,64 +81,84 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas @@ -81,64 +81,84 @@ kobj_reloc(kobj_t ko, uintptr_t relocbas
81 addend = rela->r_addend; 81 addend = rela->r_addend;
82 rtype = ELF_R_TYPE(rela->r_info); 82 rtype = ELF_R_TYPE(rela->r_info);
83 symidx = ELF_R_SYM(rela->r_info); 83 symidx = ELF_R_SYM(rela->r_info);
84 } else { 84 } else {
85 rel = (const Elf_Rel *)data; 85 rel = (const Elf_Rel *)data;
86 where = (Elf_Addr *) (relocbase + rel->r_offset); 86 where = (Elf_Addr *) (relocbase + rel->r_offset);
87 addend = *where; 87 addend = *where;
88 rtype = ELF_R_TYPE(rel->r_info); 88 rtype = ELF_R_TYPE(rel->r_info);
89 symidx = ELF_R_SYM(rel->r_info); 89 symidx = ELF_R_SYM(rel->r_info);
90 } 90 }
91 91
92 switch (rtype) { 92 switch (rtype) {
93 case R_ARM_NONE: /* none */ 93 case R_ARM_NONE: /* none */
94 break; 94 return 0;
95 95
96 case R_ARM_ABS32: 96 case R_ARM_ABS32:
97 addr = kobj_sym_lookup(ko, symidx); 97 addr = kobj_sym_lookup(ko, symidx);
98 if (addr == 0) 98 if (addr == 0)
99 return -1; 99 break;
100 if (*where != addr) 100 *where = addr + addend;
101 *where = addr; 101 return 0;
102 
103 break; 
104 102
105 case R_ARM_COPY: /* none */ 103 case R_ARM_COPY: /* none */
106 /* 104 /* There shouldn't be copy relocations in kernel objects. */
107 * There shouldn't be copy relocations in kernel 105 break;
108 * objects. 
109 */ 
110 printf("kobj_reloc: unexpected R_COPY relocation\n"); 
111 return -1; 
112 106
113 case R_ARM_JUMP_SLOT: 107 case R_ARM_JUMP_SLOT:
114 addr = kobj_sym_lookup(ko, symidx); 108 addr = kobj_sym_lookup(ko, symidx);
115 if (addr) { 109 if (addr == 0)
116 *where = addr; 110 break;
117 return 0; 111 *where = addr;
118 } 112 return 0;
119 return -1; 
120 113
121 case R_ARM_RELATIVE: /* A + B */ 114 case R_ARM_RELATIVE: /* A + B */
122 addr = relocbase + addend; 115 addr = relocbase + addend;
123 if (*where != addr) 116 if (*where != addr)
124 *where = addr; 117 *where = addr;
125 break; 118 return 0;
 119
 120 case R_ARM_PC24:
 121 if (local)
 122 return 0;
 123
 124 /* Remove the instruction from the 24 bit offset */
 125 addend &= 0x00ffffff;
 126
 127 /* Sign extend if necessary */
 128 if (addend & 0x00800000)
 129 addend |= 0xff000000;
 130
 131 addr = kobj_sym_lookup(ko, symidx);
 132 if (addr == 0)
 133 break;
 134
 135 addend += ((uint32_t *)addr - (uint32_t *)where);
 136
 137 if ((addend & 0xff800000) != 0x00000000 &&
 138 (addend & 0xff800000) != 0xff800000) {
 139 printf ("Relocation %x too far @ %p\n", addend, where);
 140 return -1;
 141 }
 142 *where = (*where & 0xff000000) | (addend & 0x00ffffff);
 143 return 0;
126 144
127 default: 145 default:
128 printf("kobj_reloc: unexpected relocation type %d\n", rtype); 146 break;
129 return -1; 
130 } 147 }
131 return 0; 148
 149 printf("kobj_reloc: unexpected/invalid relocation type %d @ %p symidx %u\n",
 150 rtype, where, symidx);
 151 return -1;
132} 152}
133 153
134int 154int
135kobj_machdep(kobj_t ko, void *base, size_t size, bool load) 155kobj_machdep(kobj_t ko, void *base, size_t size, bool load)
136{ 156{
137 157
138 if (load) { 158 if (load) {
139 cpu_idcache_wbinv_all(); 159 cpu_idcache_wbinv_all();
140 cpu_tlb_flushID(); 160 cpu_tlb_flushID();
141 } 161 }
142 162
143 return 0; 163 return 0;
144} 164}