Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Feb 1999 00:15:36 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        pixel@DotCom.FR (Emmanuel DELOGET)
Cc:        des@flood.ping.uio.no, hackers@FreeBSD.ORG
Subject:   Re: TEXT_SET() macro
Message-ID:  <199902130015.RAA28440@usr01.primenet.com>
In-Reply-To: <199902121506.PAA08837@excalibur.oceanis.net> from "Emmanuel DELOGET" at Feb 12, 99 04:06:19 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> ->> I wanna know how it's working both at compile time and at run time 
> ->> (for example, does a lkm (yes lkm, not kld, since I'm working on a 
> ->> 2.2.8 release...) can declare linker_sets, or add entries in a kernel 
> ->> linker_set, [for example , the sysctl_ one - seems that I'm very 
> ->> interested in sysctls :)]. Thaks a lot.

The answer is that it can declare linker sets for its own use, but
can not add entries to a kernel linker set, as in:

> -> You can declare sysctls in modules, but the sysctl code will not pick
> -> them up so it's pretty useless. There is work pending to make that
> -> possible.
> ->
> 	This seems that the sysctl_order function is called only on
> 	the system init (due to SYSINIT), but it may be possible
> 	to find a workaroud (I'm working on this for 2.2.8, 
> 	on the base of the D. Rabson patch for -current).

The reason that this doesn't work is that linker sets are an artifact
of the linker.

A set can only contain those things which were there at the time the
linker was run.

For kernel linker sets, this is whatever was there when the kernel
was compiled.

For linker sets in kernel modules, this is whatever was there at the
time the module was loaded.

Linker sets in modules are deceiving, if they shadow linker sets
in the kernel.  This is because the code is relinked against the
kernel symbol space as part of loading the module (this is true of
both the lkm and the kld code).

The deception is that, from the kernel's point of view, the linker
set that was shadowed did not change.  From the modules point of view,
it contains only the module data.


In general, linker sets are a structure with an element count,
followed by an array of pointers of element count length, followed
be a NULL pointer.

In application, the element count is not used, and instead the
lists are traversed until the NULL pointer is encountered.

Linker sets were originally implemented in the linker as a
technology to support C++ static constructors and construction
of pure virtual base class instances.  I haven't investigated
whether or not this use actually uses the element count, or if
it ignores it, and traverses, like our application of linker
sets for non-C++ array of object pointers aggregation.



In order to make this work for KLD's, the linker set agregation would
need to occur at runtime.  There are very good reasons for doing this,
the foremost being that an ELF section archiver could aggregate drivers
with a generic (tiny) kernel in order to support boot devices not
supported by the generic (tiny) kernel.  It is very easy to envision a
distribution kernel without any drivers or even VFS modules by default.

Making KLD's linker sets work is another good reason.


There are two technology changes which have to occur to be able to
support runtime instead of linktime aggregation:

1)	The element count *must* be deprecated entirely, for all
	cases.  This may be a mildly complex change to the C++
	compiler, if the element count is used instead of a list
	traversal.  This may be the case, if NULL is a valid tag
	for a constructor/destructor place holder.  A secondary
	issue is all code relying on linker set technology.  Making
	these changes would fully normalize the lists.

2)	Agregation of linker sets needs to span ELF sections.


This last item is the most important, since the first item is like
removing an appendix.

The kernel code would have to treat the linker sets as a list of
data on which a procedure needs to be run, *and which can be later
rerun*, as needed.

This means the linker set data itself can not be treated as static.

Finally, the body of the kernel and the body of divisible drivers
within the kernel must be treated seperately.  The way to do this
is to leverage the new ELF nature of the kernel, and implement the
kernel and the divisible drivers in seperate ELF sections.  This
allows the driver to be later severed, if necessary, without
damaging what would otherwise be a static aggregate list.

I know that GCC supports ELF section attribution of code via a
#pragma, per the Visual C++ compiler, in its effort to supply a
compiler capable of compiling Windows 95/98/NT/CE code, though I
don't know if this has been echo'ed into compilers for all
platforms (e.g.: Linux and FreeBSD).

You would probably have to implement an inline function identification
semantic, or something similar, in order to apply section naming to
entire drivers.

FreeBSD would also have to relink objects that implemented a single
driver from multiple source files, into a single section-attributed
module.

At that point, you would be able to, at load time, treat the sysctl
linker set data atrributed sections as a continuation of the
initialization iteration that occurred at system load.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199902130015.RAA28440>