tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kmodule: absolute symbols



In article <34ff5b41-51bb-fa19-b893-bbfff43f7d3a%m00nbsd.net@localhost>,
Maxime Villard  <max%m00nbsd.net@localhost> wrote:
>Throwing this here in case someone cares. In the kernel module relocator we
>don't support absolute symbols coming from the kernel, and it means that we
>can't modload a module containing for example:
>
>	extern char sigcode[];
>	printf("sigcode = %p\n", sigcode);
>
>Currently, absolute symbols work like this:
>
>     +-----------+    +---------+    +---------+
>     | sigcode   |    | sigcode |    | sigcode |
>     | SHN_UNDEF |    | SHBSS   |<~~~| SHN_ABS |
>     | Val = 0   |<---| Val = 0 |    | Val = 0 |
>     +-----------+    +---------+    +---------+
>        MODULE       KERNEL (MEM)    KERNEL (BIN)
>
>The kernel binary has a symbol entry for "sigcode" with st_shndx = SHN_ABS.
>When loaded in memory, st_shndx gets overwritten with SHBSS. Then, when
>modloading a kernel module, only the st_value field gets copied in the
>module version of the symbol.
>
>But for "sigcode" st_value evaluates to zero. Therefore kobj_sym_lookup
>returns a zero st_value, which is interpreted as an error in the kobj_reloc
>functions.
>
>To fix that:
>  * Don't overwrite SHN_ABS with SHBSS.
>  * Copy the st_shndx field into the module symbol.
>  * Change the return value of kobj_sym_lookup to be errno-like, giving the
>    address as argument.
>  * Still in kobj_sym_lookup, if st_shndx == SHN_ABS, take the value as-is and
>    don't return an error if it equals zero.
>
>Patch here [1]. Unless told otherwise I will commit this soon - fixing the
>other kobj_reloc functions along the way, obviously. There are also a few other
>things to be fixed but I'll do that later.
>
>Maxime
>
>(note: we've always had this issue, so what, no one has ever tried to
>modload COMPAT_16 on amd64?)

I would declare getval_unlocked as taking void *symp, remove the cast
in the call, and change:

	*symp = (void *)es;
to
	*(void **)symp = es;

to avoid casting every call...

christos



Home | Main Index | Thread Index | Old Index