On 30 Sep 2021, Kees Cook said: > On Wed, Sep 29, 2021 at 10:51:47PM +0100, Nick Alcock wrote: >> It would be useful if there were a mapping between kernel symbol and module >> name that only changed when the kernel source code is changed. This mapping >> should not change simply because a module becomes built into the kernel. >> >> It might also be useful if there were reliable symbol size information to >> determine whether an address is within a symbol or outside it, especially >> given that there could be huge gaps between symbols. > > This is a pretty cool series, but I'm left wondering "for what reason?" :) > Perhaps I missed the specific rationale; there was a lot to run. ;) The underlying rationale that the earliest, crude version of this patch was written for is that DTrace allows symbol and type names to be module-qualified (e.g. hid`names) and we don't want people's scripts to break just because they recompile the kernel to make things a module versus not. But this problem is not DTrace-specific: given that names are not unique across the kernel when things are built as modules, many tracing tools that introspect the values of kernel symbols etc might want to let users qualify names with the modules they apply to, and more or less none of those are going to want a script that asks for "foo in the bar module" to suddenly become invalid because the user changed CONFIG_FOO=m to CONFIG_FOO=y. Obviously, if they change it to CONFIG_FOO=n, any script that uses names from FOO is going to break: there's nothing we can do about that. But not breaking the m/y case seems like a simple quality-of- implementation issue to make it easier to redistribute scripts to anyone using FOO no matter what their module/non-module configuration, and a nice easy one to fix, if only we could easily tell what the module/symbol mapping was. And with this patch we can (at minimal cost). (I have also found it to be useful for by-hand stuff, when I can't remember where the heck some symbol with a non-qualified name is, usually a file-scope variable: it's faster to grep kallmodsyms than to do a tags lookup, let alone a grep, if I'm debugging something I know is loaded into the kernel right now. Which often one is if one is reproducing the bug... and often the module a symbol is part of is informative. This is, obviously, crude, but it's still more useful to have more module names there than fewer if one is doing this sort of thing.) (As an aside, this is not all a tracing system needs to do to get this sort of thing right, particularly where types are concerned: it's still possible to have conflicting type names across translation units within a single module. CTF deals with that case perfectly well via child CTF dicts, and GNU ld splits ambiguously-defined types out so that the user can say "foo_t in the bar module in wombat.c" in the rare cases where ambiguity exists.) > It would be useful, sure, but is there something that does, in fact, > need this, or would like this if it were available? Since this provides > a userspace API, what would be consuming that API? For example, when > Syscall User Dispatch was added, it was clear it was for Wine[1]. We have a long-term consumer in DTrace (e.g. <https://github.com/oracle/dtrace-utils/blob/dev/libdtrace/dt_module.c#L1323>). (But since we control this consumer we are quite happy to change the format of kallmodsyms, integrate it with kallsyms so that kallsyms just provides the same information if the file format break were acceptable, or whatever you think most sensible. We just want this information somehow. :) e.g. the code there doesn't yet handle the symbol-in-multiple-modules case: I'll have to add that.) But this feels useful enough to me that I'm hoping that more consumers will grow. I'm sure SystemTap would find it useful, and I'm hoping bpftrace etc might as well once that starts to handle modules. They're all going to need some sort of namespace-qualification and then they're all going to run into the same script-stability problem as soon as users try to share scripts at all. We can make that problem largely go away :) -- NULL && (void)