Bug 5154 - aux_syscalls lookup tables needlessly included
Summary: aux_syscalls lookup tables needlessly included
Status: RESOLVED FIXED
Alias: None
Product: systemtap
Classification: Unclassified
Component: runtime (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-10 15:53 UTC by Frank Ch. Eigler
Modified: 2014-03-20 18:10 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Frank Ch. Eigler 2007-10-10 15:53:40 UTC
Similar to bug #3347, the new replacement lookup table code in
tapset/aux_syscalls.stp causes all the various lookup tables to be transcribed
into modules, whether or not they are actually used.  They should switch to a /*
pure */ style function as much as possible, so they can be elided if unused.
Comment 1 David Smith 2014-02-13 15:02:45 UTC
From looking at tapset/linux/aux_syscalls.stp, it looks like this work has been done, so I'm closing this one.
Comment 2 David Smith 2014-03-20 17:48:28 UTC
From looking at pass 3 output, the lookup tables are still being needlessly included. The *functions* are marked as pure (and get elided when not used), but the lookup tables themselves are always included.

Here's what the code looks like:

====
# ...

%{
static const _stp_val_array const _stp_XXXX_list[] = {
	V(XXX_1),
	V(XXX_2),
	{0, NULL}
};
%}

function _XXXX_str:string(val:long)
%{ /* pure */
	_stp_lookup_str(_stp_XXXX_list, STAP_ARG_val, STAP_RETVALUE,
			MAXSTRINGLEN);
%}
====

Here the translator can know that _XXXX_str() isn't used and elide it. However, it can't really know that that embedded-C block above it is used or unused, so it always includes it.

One possible solution here would be to move the lookup table inside the function, but still static. The lookup table would need to be static so it wouldn't be put on the limited kernel stack. In this scenario, if the translator elides the function, it would automatically elide the lookup table.
Comment 3 Josh Stone 2014-03-20 17:59:32 UTC
When not used, do the tables actually survive through compilation?  For unreferenced static const data, I'd expect gcc would just drop them.
Comment 4 David Smith 2014-03-20 18:10:33 UTC
(In reply to Josh Stone from comment #3)
> When not used, do the tables actually survive through compilation?  For
> unreferenced static const data, I'd expect gcc would just drop them.

Good question. It looks like you are correct, gcc is discarding that data. See the following:

====
# stap -p3 -e 'probe begin { println(_mmap_flags(0)); exit() }' | egrep _stp_.+_list
static const _stp_val_array const _stp_sockopt_level_list[] = {
static const _stp_val_array const _stp_signal_list[] = {
	const _stp_val_array * const array = _stp_signal_list;
static const _stp_val_array const _stp_semctl_list[] = {
static const _stp_val_array const _stp_fork_list[] = {
static const _stp_val_array const _stp_atflag_list[] = {
static const _stp_val_array const _stp_shmat_list[] = {
static const _stp_val_array const _stp_mprotect_list[] = {
static const _stp_val_array const _stp_mmap_list[] = {
  static const _stp_val_array const _stp_sa_handler_list[] = {
  static const _stp_val_array const _stp_sa_flags_list[] = {
  _stp_lookup_str(_stp_sa_handler_list, (long)act->sa_handler,
      _stp_lookup_or_str(_stp_sa_flags_list, act->sa_flags, ptr, len);
static const _stp_val_array const _stp_irq_list[] = {
	_stp_lookup_or_str(_stp_mmap_list, STAP_ARG_flags, STAP_RETVALUE, MAXSTRINGLEN);
#  stap -m test -p4 -e 'probe begin { println(_mmap_flags(0)); exit() }'
test.ko
# nm test.ko | egrep _stp_.+_list
0000000000000100 r _stp_mmap_list
====

From the above output, the source (-p3 output) contained ~15 lookup tables. But the final module only contained the one actually used.

I'll reclose this one.