Port-arm archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: ARM kernel module supported reloc types
On Sat, Dec 27, 2008 at 04:22:26PM +1300, Lloyd Parkes wrote:
> Rafal,
> Are you sure the relocs for PC24 are out of range? I've been looking
> at this over the past few days before I saw your message in the archive.
>
> As far as I can tell, the actual offset is a word offset, not a byte
> offset, so the address range is effectively +/- 32MB. That's a whole
> lot of address space for kernel code. Of course, it might be that
> modules are loaded into far flung parts of the address space.
Right, the offset is the low 24-bits right-shifted by 2, so you're right
about the offset.
In my case, I think the offset for at least 'printf' in the example module
was indeed > 32MB. Note that I was running an monolithic INSTALL kernel
and to get at the modules and stuff I wanted to play with had to re-mount
the real root FS over NFS, so there's quite a bit of stuff going on before
I could get to the module.
Since that point, I haven't had much NetBSD hacking time, so I haven't had
a chance to play with any of the suggestions Andrew offered later in the
thread (create new module_map, submap module_map from kernel_map)... I'll
attach my PC24 reloc patch below in case it's helpful (or in case you find
it's indeed buggy ;)).
--rafal
PS: I'm mostly AFK for the next week or so, but let me know if you do make
any progress.
--
Time is an illusion; lunchtime, doubly so. |/\/\| Rafal Boni
-- Ford Prefect |\/\/|
rafal%pobox.com@localhost
:100644 100644 901d01f... 6ff9326... M sys/arch/arm/arm32/kobj_machdep.c
diff --git a/sys/arch/arm/arm32/kobj_machdep.c
b/sys/arch/arm/arm32/kobj_machdep.c
index 901d01f..6ff9326 100644
--- a/sys/arch/arm/arm32/kobj_machdep.c
+++ b/sys/arch/arm/arm32/kobj_machdep.c
@@ -93,6 +93,31 @@ kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
case R_ARM_NONE: /* none */
break;
+ case R_ARM_PC24: { /* S - PC + (SignExt(A & 0xffffff)) << 2 */
+ Elf_Addr tmp;
+
+ /* Truncate (and sign-extend if needed) 24-bit addend */
+ addend &= 0x00ffffff;
+ if (addend & 0x00800000)
+ addend |= 0xff000000;
+
+ addr = kobj_sym_lookup(ko, symidx);
+ if (addr == 0)
+ return -1;
+ tmp = addr - (Elf_Addr)where + (addend << 2);
+ printf("kobj_reloc: R_PC24 relocation @ %p -- base = %#lx, addr
= %#lx, addend = %#lx, out = %#lx\n", where, (long)relocbase, (long)addr,
(long)addend, (long)tmp);
+ if ((tmp & 0xfe000000) != 0xfe000000 &&
+ (tmp & 0xfe000000) != 0) {
+ printf("kobj_reloc: failed R_PC24 relocation @ %p (disp
%ld (%#lx) out of range)\n", where, (long)tmp, (long)tmp);
+ return -1;
+ }
+
+ tmp >>= 2;
+ if ((*where & 0x00ffffff) != (tmp & 0x00ffffff))
+ *where = (*where & 0xff000000) | (tmp & 0x00ffffff);
+ break;
+ }
+
case R_ARM_ABS32:
addr = kobj_sym_lookup(ko, symidx);
if (addr == 0)
@@ -125,7 +150,7 @@ kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data,
break;
default:
- printf("kobj_reloc: unexpected relocation type %d\n", rtype);
+ printf("kobj_reloc: unexpected relocation type %d @ %p\n",
rtype, where);
return -1;
}
return 0;
Home |
Main Index |
Thread Index |
Old Index