diff mbox series

[v1,3/7] DCE/DSE: Add a new scripts/Makefile.syscalls

Message ID df1ce8c514c3efc1323d5ed69e6ecbdb2542b960.1695679700.git.falcon@tinylab.org (mailing list archive)
State Changes Requested
Headers show
Series DCE/DSE: Add Dead Syscalls Elimination support, part1 | expand

Checks

Context Check Description
conchuod/cover_letter success Series has a cover letter
conchuod/tree_selection success Guessed tree name to be for-next at HEAD 0bb80ecc33a8
conchuod/fixes_present success Fixes tag not required for -next series
conchuod/maintainers_pattern success MAINTAINERS pattern errors before the patch: 5 and now 5
conchuod/verify_signedoff success Signed-off-by tag matches author and committer
conchuod/kdoc success Errors and warnings before: 0 this patch: 0
conchuod/build_rv64_clang_allmodconfig success Errors and warnings before: 9 this patch: 9
conchuod/module_param success Was 0 now: 0
conchuod/build_rv64_gcc_allmodconfig success Errors and warnings before: 9 this patch: 9
conchuod/build_rv32_defconfig success Build OK
conchuod/dtb_warn_rv64 success Errors and warnings before: 29 this patch: 29
conchuod/header_inline success No static functions without inline keyword in header files
conchuod/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
conchuod/build_rv64_nommu_k210_defconfig success Build OK
conchuod/verify_fixes success No Fixes tag
conchuod/build_rv64_nommu_virt_defconfig success Build OK

Commit Message

Zhangjin Wu Sept. 25, 2023, 10:38 p.m. UTC
When CONFIG_TRIM_UNUSED_SYSCALLS is enabled, get used syscalls from
CONFIG_USED_SYSCALLS. CONFIG_USED_SYSCALLS may be a list of used
syscalls or a file to store such a list.

If CONFIG_USED_SYSCALLS is configured as a list of the used syscalls,
directly record them in a used_syscalls variable, if it is a file to
store the list, record the file name to the used_syscalls_file variable
and put its content to the used_syscalls variable.

Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
---
 scripts/Makefile.syscalls | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 scripts/Makefile.syscalls

Comments

Arnd Bergmann Sept. 26, 2023, 5:55 a.m. UTC | #1
On Tue, Sep 26, 2023, at 00:38, Zhangjin Wu wrote:
> When CONFIG_TRIM_UNUSED_SYSCALLS is enabled, get used syscalls from
> CONFIG_USED_SYSCALLS. CONFIG_USED_SYSCALLS may be a list of used
> syscalls or a file to store such a list.
>
> If CONFIG_USED_SYSCALLS is configured as a list of the used syscalls,
> directly record them in a used_syscalls variable, if it is a file to
> store the list, record the file name to the used_syscalls_file variable
> and put its content to the used_syscalls variable.
>
> Signed-off-by: Zhangjin Wu <falcon@tinylab.org>

I like the idea of configuring the set of syscalls more, but we
should probably discuss the implementation of this here. You
introduce two new ways of doing this, on top of the existing
coarse-grained method (per syscall class Kconfig symbols).

Both methods seem a little awkward to me, but are doable
in principle if we can't come up with a better way. However,
I'd much prefer to not add both the Kconfig symbol and the
extra file here, since at least one of them is redundant.

Do you have automatic tooling to generate these lists from
a profile, or do you require manually writing them? Do you
have an example list?

      Arnd
Zhangjin Wu Oct. 3, 2023, 8:16 a.m. UTC | #2
Hi, Arnd

> On Tue, Sep 26, 2023, at 00:38, Zhangjin Wu wrote:
> > When CONFIG_TRIM_UNUSED_SYSCALLS is enabled, get used syscalls from
> > CONFIG_USED_SYSCALLS. CONFIG_USED_SYSCALLS may be a list of used
> > syscalls or a file to store such a list.
> >
> > If CONFIG_USED_SYSCALLS is configured as a list of the used syscalls,
> > directly record them in a used_syscalls variable, if it is a file to
> > store the list, record the file name to the used_syscalls_file variable
> > and put its content to the used_syscalls variable.
> >
> > Signed-off-by: Zhangjin Wu <falcon@tinylab.org>
> 
> I like the idea of configuring the set of syscalls more, but we
> should probably discuss the implementation of this here. You
> introduce two new ways of doing this, on top of the existing
> coarse-grained method (per syscall class Kconfig symbols).
> 
> Both methods seem a little awkward to me, but are doable
> in principle if we can't come up with a better way. However,
> I'd much prefer to not add both the Kconfig symbol and the
> extra file here, since at least one of them is redundant.
>

Ok, it is reasonable to remove this extra scripts/Makefile.syscalls if
we only support the configuring the set of syscalls via Kconfig symbol.

> Do you have automatic tooling to generate these lists from
> a profile, or do you require manually writing them? Do you
> have an example list?
>

Yes, we have but no generic tool across architectures, libcs and systems
and I plan to delay this work as the part3 patchset of the whole series.

I have tried two methods, one is objdumping of the binary, another
method is recording the used syscalls from the libc linking stage, both
of them are limited to single-application system, for complicated
system, the libraryopt [1] tool may be required to find used libcs at
first.

The objdumping method simply greps the 'syscall' instructions and
extract the syscall number from the 'num' register write instruction,
but I have encountered some exceptions, that is the nearest 'num'
register instruction is not just the one for the 'syscall' instruction
and therefore we may get a wrong syscall number, I do have a demo
script, but it is very ugly currently [2], and I have found Tim have
prepared such a python script too [3], not sure if it may get wrong
syscall number either, If not, it should be a good one for our future
development.

After getting the syscall numbers, it is not that hard to convert them
to syscall names with the help of <unistd.h> or let kernel directly
accept a setting of syscall number via the Kconfig symbol (I have tried
it, but it may make things not readable, so, the support is removed in
this patchset).

Another method we have tried is recording the used syscalls during the
linking stage of the libc (only for Nolibc currently) with the help of
sections-gc [4].

It uses such logic:

- Rename all of the my_syscall<N> macros to _my_syscall<N>
- The new my_syscall<N> use .pushsection to add empty and not really used .rodata.syscall.__NR_<syscall_name> sections
- Enable -ffunction-sections -fdata-sections, -Wl,--gc-sections and -Wl,--print-gc-sections
- The unused sys_<syscall_name> will be eliminated, record the syscall list as group1
- All of .rodata.syscall.__NR_<syscall_name> section will be eliminated, record the syscall list as group2
- "group2 - group1" should be the used syscalls

Basic test shows, this works well with Nolibc, but it requires to modify
the Libc source code.

Thanks,
Zhangjin Wu

---
[1]: http://libraryopt.sourceforge.net/
[2]: https://github.com/tinyclub/linux-lab/blob/master/tools/nolibc/dump.sh
[3]: https://github.com/tbird20d/auto-reduce/blob/master/programs/find-syscalls.py
[4]: https://lore.kernel.org/lkml/cbcbfbb37cabfd9aed6088c75515e4ea86006cff.1676594211.git.falcon@tinylab.org/

>       Arnd
diff mbox series

Patch

diff --git a/scripts/Makefile.syscalls b/scripts/Makefile.syscalls
new file mode 100644
index 000000000000..5864d3a85996
--- /dev/null
+++ b/scripts/Makefile.syscalls
@@ -0,0 +1,29 @@ 
+# SPDX-License-Identifier: GPL-2.0
+
+ifndef SCRIPTS_MAKEFILE_SYSCALLS
+  SCRIPTS_MAKEFILE_SYSCALLS = 1
+
+  ifdef CONFIG_TRIM_UNUSED_SYSCALLS
+    ifneq ($(wildcard $(CONFIG_USED_SYSCALLS)),)
+      used_syscalls_file = $(CONFIG_USED_SYSCALLS)
+      ifeq ($(shell test -s $(used_syscalls_file); echo $$?),0)
+        used_syscalls != cat $(CONFIG_USED_SYSCALLS)
+      endif
+    else
+      ifeq ($(subst /,,$(CONFIG_USED_SYSCALLS)),$(CONFIG_USED_SYSCALLS))
+        used_syscalls = $(CONFIG_USED_SYSCALLS)
+      else
+        $(error No such file: $(CONFIG_USED_SYSCALLS))
+      endif
+    endif
+
+    ifneq ($(used_syscalls),)
+      used_syscalls := $(subst $(space),|,$(strip $(used_syscalls)))
+    endif
+
+    used_syscalls_deps = $(used_syscalls_file) $(objtree)/.config
+
+    export used_syscalls used_syscalls_deps
+  endif # CONFIG_TRIM_UNUSED_SYSCALLS
+
+endif # SCRIPTS_MAKEFILE_SYSCALLS