Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arch: Add support for mips architecture #80

Closed
wants to merge 0 commits into from

Conversation

jaqchen
Copy link

@jaqchen jaqchen commented Apr 16, 2022

There exists mainly two variants of ABIs in the linux kernel
for MIPS architecture, o32 and n32/n64. The register sets are
largely the same between 32-bit and 64-bit MIPS processors,
so single arch/mips.c is added to support both.
Note that configure option `--enable-n32n64 can be specified
to enable n32/n64 ABI for 32-bit MIPS build.

@jaqchen
Copy link
Author

jaqchen commented Apr 16, 2022

I've tested the patch on openwrt/MIPS32 devices, PLY works fine.
However, there is an issue for MIPS64 build, which I think needs further fix if the PR is merged:
make[3]: Entering directory '/home/yejq/program/ply/mips64/src/ply'
cd /home/yejq/program/ply/mips64/../src/ply &&
mips64-buildroot-linux-musl-ld -m elf64btsmip -r -b binary -o /home/yejq/program/ply/mips64/src/ply/self-test.o self-test.sh
/bin/bash ../../libtool --tag=CC --mode=link mips64-buildroot-linux-musl-gcc -g -O2 -o ply ply-ply.o ../libply/libply.la self-test.o
libtool: link: mips64-buildroot-linux-musl-gcc -g -O2 -o .libs/ply ply-ply.o self-test.o ../libply/.libs/libply.so
/home/yejq/program/buildroot-2021.11.1/output/host/lib/gcc/mips64-buildroot-linux-musl/10.3.0/../../../../mips64-buildroot-linux-musl/bin/ld: self-test.o: warning: linking abicalls files with non-abicalls files
/home/yejq/program/buildroot-2021.11.1/output/host/lib/gcc/mips64-buildroot-linux-musl/10.3.0/../../../../mips64-buildroot-linux-musl/bin/ld: self-test.o: linking mips:4000 module with previous mips:isa64r6 modules
/home/yejq/program/buildroot-2021.11.1/output/host/lib/gcc/mips64-buildroot-linux-musl/10.3.0/../../../../mips64-buildroot-linux-musl/bin/ld: self-test.o: linking -mnan=legacy module with previous -mnan=2008 modules
/home/yejq/program/buildroot-2021.11.1/output/host/lib/gcc/mips64-buildroot-linux-musl/10.3.0/../../../../mips64-buildroot-linux-musl/bin/ld: failed to merge target specific data of file self-test.o
collect2: error: ld returned 1 exit status

For MIPS64, the root cause is different types object files:
ply-ply.o: ELF 64-bit MSB relocatable, MIPS, MIPS64 rel6 version 1 (SYSV), with debug_info, not stripped
self-test.o: ELF 32-bit MSB relocatable, MIPS, N32 MIPS-III version 1 (SYSV), not stripped

@jaqchen jaqchen closed this Apr 16, 2022
@jaqchen jaqchen reopened this Apr 16, 2022
Copy link
Collaborator

@wkz wkz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff!

Thank you for your contribution. The code looks good. I just hope we can simplify the changes to the build system a bit.

Regarding your comment about the 64-bit support: Can we just drop it for now? Rather than building something that has no hope of working anyway?

configure.ac Outdated
Comment on lines 39 to 46
AM_CONDITIONAL([MIPS_ARCH], [AS_CASE([$host], [mips*], [true], [false])])
AM_CONDITIONAL([MIPS64_CPU], [AS_CASE([$host], [mips64*], [true], [false])])
AM_COND_IF([MIPS_ARCH], [AC_ARG_ENABLE(mips-n32n64,
AS_HELP_STRING([--enable-mips-n32n64], [enable n32/n64 (instead of o32) ABI for mips architecture]),
[if test x$enableval = xyes ; then
AC_DEFINE(USE_MIPS_N32, 1, [enable n32/n64 ABI for mips architecture])
fi])])
AM_COND_IF([MIPS64_CPU], [AC_DEFINE(USE_MIPS_64BIT, 1, [enable USE_MIPS64_BIT for mips64 cpus])])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this information be available via $host_cpu? I.e. isn't this set via the --host argument to configure?

It seems unlikely that existing architectures all fit into the existing AC_CANONICAL_HOST, but MIPS needs this extra logic.

Copy link
Author

@jaqchen jaqchen Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I'm not against dropping support for MIPS64 entirely, since I have many MIPS32 devices but none MIPS64 devices :)
Yes, $host_cpu and $host get set by --host argument, I will try to simplify changes to configure.ac, leaving only mips-n32n64 configure option.

Comment on lines 19 to 24
if MIPS_ARCH
libply_la_SOURCES = arch/mips.c
else
libply_la_SOURCES = arch/@arch@.c
endif
libply_la_SOURCES += \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be needed, @arch@ should already hold the correct value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember that a few months ago, configuring with different --host parameters, results in different @arch@:
with --host=mips-linux-gcc, @arch@ will be mips, while configuring with --host=mipsel-buildroot-linux-musl-gcc, @arch@ will be mipsel. I will try again later, to make sure about it.

{ .name = "cp0_status", .type = &t_reg_t },
{ .name = "hi", .type = &t_reg_t },
{ .name = "lo", .type = &t_reg_t },
#if 0 /* Let's pretend that CPU_HAS_SMARTMIPS could never be defined: */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a MIPS guru. Why are we allowed to pretend that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my MIPS32 Linux kernel build, CONFIG_CPU_HAS_SMARTMIPS is not defined; On buildroot/qemu_mips64 kernel build, the option is not defined either. I think the option is so rarely enabled, I would like to drop it; otherwise, another --enable-smartmips configuration option will be needed.

Comment on lines 45 to 56
#ifndef USE_MIPS_64BIT
/* pad for 32-bit system; refer to linux/arch/mips/include/asm/ptrace.h */
{ .name = "uarg0", .type = &t_reg_t },
{ .name = "uarg1", .type = &t_reg_t },
{ .name = "uarg2", .type = &t_reg_t },
{ .name = "uarg3", .type = &t_reg_t },
{ .name = "uarg4", .type = &t_reg_t },
{ .name = "uarg5", .type = &t_reg_t },
{ .name = "uarg6", .type = &t_reg_t },
{ .name = "uarg7", .type = &t_reg_t },
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there is no uprobe support yet this could be fine for now, but just for my understanding: Is the layout for struct pt_regs different for a kernel thread and a user thread? I.e. when we add uprobe support do we need to have another type for that?

Copy link
Author

@jaqchen jaqchen Apr 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is other struct pt_regs defined in arch/mips/include/uapi/asm/ptrace.h, which does not have 8 padding userspace registers. The kernel documentation says it is specifically used for ptrace:

This struct defines the registers as used by PTRACE_{GET,SET}REGS.

So I recon that the layout for kernel threads and user threads are identical on MIPS32. However, for MIPS64, 8 padding userspace registers are not present in struct pt_regs (accordding to arch/mips/include/asm/ptrace.h). If support for MIPS64 is to be dropped, the code can be simplified a lot.

@jaqchen
Copy link
Author

jaqchen commented Apr 23, 2022

I've updated the PR, thanks @wkz

@jaqchen
Copy link
Author

jaqchen commented Apr 25, 2022

I've just received an email notifying CI build failures about the PR, and have checked the details:

--2022-04-25 08:43:46-- https://nightly.link/westermo/netbox/actions/artifacts/95999414.zip
Reusing existing connection to nightly.link:443.
HTTP request sent, awaiting response... 404 Not Found
2022-04-25 08:43:47 ERROR 404: Not Found.

I think the error is not related to the PR; but if I was wrong, what should I do to pass CI checks?

@guidosarducci
Copy link

@jaqchen Hello and thank you for taking on this work! I had been meaning to look at this after fixing the BPF infrastructure on OpenWrt some time ago. Could you share the build or packaging recipe you've used on OpenWrt? I'd like to get this included if possible. I'd also like to take a closer look at the MIPS64 problems you encountered -- have you discovered anything more since the first build failure?

@wkz
Copy link
Collaborator

wkz commented Dec 4, 2022

@jaqchen I'm so sorry that this fell off my radar. Thank you @guidosarducci, for triggering a notification 😄

I have a fix for the build issue. I've also started to look at ways of figuring out the selected ABI without having to pass explicit defines. Can't make any promises on the timeline, but I have every intention of merging this ASAP.

@guidosarducci
Copy link

Thanks for the great news! Looking forward to it...

@wkz
Copy link
Collaborator

wkz commented Dec 9, 2022

Merged with some additions in 1d12ea7.

I added support for mips64 while I was at it, and tried to figure out the proper layout of pt_regs based on different defines set by GCC based on the selected compiler options (ABI, SmartMIPS, etc.).

@jaqchen I'm sorry this took me so long. Could you verify that everything still works as expected on your target system? Then I'll whip up a new release.

@guidosarducci Maybe you could also try it out?

@jaqchen
Copy link
Author

jaqchen commented Dec 12, 2022

Sorry for the late reply.

Could you verify that everything still works as expected on your target system?

Current patch works well for my MIPS32 target devices, which I've simplified a lot.

I'd also like to take a closer look at the MIPS64 problems you encountered.

I remember that the build-failure for MIPS64 cannot be resolved for now, because the way self-test.sh got linked into PLY executable in src/ply/Makefile.am:

$(LD) -r -b binary -o $(abs_builddir)/self-test.o self-test.sh

The generated object self-test.o cannot be linked again correctly. I didn't find any useful options for LD to avoid the problem.
I suggest support for MIPS64 should be dropped for now.

@jaqchen
Copy link
Author

jaqchen commented Dec 12, 2022

Oh, so much progress has been made for MIPS target, GREAT AND THANKS! ^_^

@wkz
Copy link
Collaborator

wkz commented Dec 12, 2022

Oh, so much progress has been made for MIPS target, GREAT AND THANKS! ^_^

Does that mean that the master branch works for your system? 😄

@guidosarducci
Copy link

Merged with some additions in 1d12ea7.

I added support for mips64 while I was at it, and tried to figure out the proper layout of pt_regs based on different defines set by GCC based on the selected compiler options (ABI, SmartMIPS, etc.).

@jaqchen I'm sorry this took me so long. Could you verify that everything still works as expected on your target system? Then I'll whip up a new release.

@guidosarducci Maybe you could also try it out?

I just started looking at packaging it for OpenWrt so I should have more to say shortly. @jaqchen Did you have a hacked OpenWrt Makefile or any "gotchas" to be aware of from your prior work? Thanks!

@jaqchen
Copy link
Author

jaqchen commented Dec 14, 2022

Could you verify that everything still works as expected on your target system?

Does that mean that the master branch works for your system?

The latest PLY (updated in Dec 9) works fine for my MIPS32 target @guidosarducci @wkz :

root@OpenWrt:/tmp# uname -a
Linux OpenWrt 5.10.111 #0 Fri Apr 22 07:23:49 2022 mips GNU/Linux
root@OpenWrt:/tmp# opkg install ply_2022-12-09-1d12ea77-1_mipsel_24kc.ipk 
Installing ply (2022-12-09-1d12ea77-1) to root...
Configuring ply.
root@OpenWrt:/tmp# ply --version
ply c59704334c-dirty (linux-version:330351~5.10.111)
root@OpenWrt:/tmp# ply -T
WARN: Unable to verify kernel config
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK

Did you have a hacked OpenWrt Makefile

I modified my prior Makefile, with COMMIT-ID and release date in generated package (i.e., ply_2022-12-09-1d12ea77-1_mipsel_24kc.ipk), you might need to modify it to include PLY version instead (placed in feeds/packages/devel/ply directory):

#
# Copyright (C) 2022 Ye Jiaqiang
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk

PKG_NAME:=ply
PKG_RELEASE:=1

PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/iovisor/ply.git
PKG_MIRROR_HASH:=022491103c4c280d3e68a3e65cae780dc24e2fdd40001ac6a4befa801f0273d0
PKG_SOURCE_DATE:=2022-12-09
PKG_SOURCE_VERSION:=1d12ea776d07ecc3a215458b28cbdb4a9e461227

PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=COPYING
PKG_MAINTAINER:=Ye Jiaqiang <yejq.jiaqiang@gmail.com>

include $(INCLUDE_DIR)/package.mk

define Package/ply
  SECTION:=devel
  CATEGORY:=Development
  TITLE:=Light-weight dynamic tracer for Linux
  URL:=https://github.com/iovisor/ply.git
endef

define Package/ply/description
  A light-weight dynamic tracer for Linux that leverages the kernel's
  BPF VM in concert with kprobes and tracepoints to attach probes to
  arbitrary points in the kernel.
endef

CONFIGURE_ARGS += --enable-shared=yes --enable-static=no

define Build/Prepare
	$(call Build/Prepare/Default)
	cd $(PKG_BUILD_DIR) && exec ./autogen.sh
endef

define Package/ply/install
	$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/lib
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/ply/.libs/ply $(1)/usr/sbin/
	$(CP) $(PKG_BUILD_DIR)/src/libply/.libs/libply.so* $(1)/usr/lib/
endef

$(eval $(call BuildPackage,ply))

After some test, the above Makefile also builds for arm targets.

or any "gotchas" to be aware of from your prior work?

No, not really, I didn't find any "gotchas" ^_^. However, the latest PLY does not run on older kernels, (while prior version of PLY works) @wkz , which I think is due to the evolution of BPF architecture in the kernel (am I right?):

root@Megsine:~# uname -a
Linux Megsine 4.14.131 #0 Thu Jun 27 12:18:52 2019 mips GNU/Linux
root@Openwrt:/tmp# ply -T
WARN: Unable to verify kernel config
Ensuring that debugfs is mounted... OK
Verifying kprobe... ERR:-22
ERROR
Verifying tracepoint... OK
Verifying special... ERR:-22
ERROR
Verifying interval... OK

@guidosarducci
Copy link

I modified my prior Makefile, with COMMIT-ID and release date in generated package (i.e., ply_2022-12-09-1d12ea77-1_mipsel_24kc.ipk), you might need to modify it to include PLY version instead (placed in feeds/packages/devel/ply directory):

@jaqchen Thanks, that's wonderful to have and I'll be using that Makefile shortly. I noticed it's fully fleshed out, with MAINTAINER and all; are you also planning on upstreaming this to OpenWrt?

@jaqchen
Copy link
Author

jaqchen commented Dec 15, 2022

are you also planning on upstreaming this to OpenWrt?

@guidosarducci No, I think I will be too busy to do that, please remove me from MAINTAINER if upstreaming has been planned.

@guidosarducci
Copy link

are you also planning on upstreaming this to OpenWrt?

@guidosarducci No, I think I will be too busy to do that, please remove me from MAINTAINER if upstreaming has been planned.

Alright, I'll do some testing myself first and then submit an upstream PR, including you in the commit but removing from MAINTAINER. Thanks again, this saves a lot of time.

@guidosarducci
Copy link

I added support for mips64 while I was at it, and tried to figure out the proper layout of pt_regs based on different defines set by GCC based on the selected compiler options (ABI, SmartMIPS, etc.).

@guidosarducci Maybe you could also try it out?

@wkz I was able to package and build ply under OpenWrt, then began testing across various MIPS archs and ARM32 by following posted examples from both ply and bpftrace. Most of the basics work, but on MIPS I'm not able to access and print string args. While hunting for the problem, I also came across other issues which I've fixed in my branch https://github.com/guidosarducci/ply/tree/master-mips-openwrt. Please have a look there.

I see the string/arg issue on mips32be, mips32le and mips64le, which seems to discount an endian or word-size bug as I first suspected. None of these problems appear on ARM32 however. The relevant kernel code and some logs illustrating the problem are below.

Kernel Code: (https://elixir.bootlin.com/linux/v5.15.83/source/fs/open.c#L1195)

static long do_sys_openat2(int dfd, const char __user *filename,
			   struct open_how *how)
{
	struct open_flags op;
	int fd = build_open_flags(how, &op);
	struct filename *tmp;

ARMVIRT32: (good)

root@OpenWrt:~# uname -a
Linux OpenWrt 5.15.83 #0 SMP Fri Dec 16 10:01:38 2022 armv7l GNU/Linux

root@OpenWrt:~# ply -T
Verifying kernel config (/proc/config.gz)... OK
  CONFIG_UPROBES is not set
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK

root@OpenWrt:~# ply -k 'kprobe:do_sys_openat2 { printf("%v(%v): fd %v fn %v str %s\n", comm, uid, arg0, arg1, str(arg1)); }'
procd          (   0): fd 0xffffff9c fn 0x4eff1c str /dev
procd          (   0): fd 0x9 fn 0xb6e6b670 str ttyS0
procd          (   0): fd 0xffffff9c fn 0x4eff1c str /dev
procd          (   0): fd 0x9 fn 0xb6e6b670 str ttyS0
procd          (   0): fd 0xffffff9c fn 0x4eff1c str /dev
procd          (   0): fd 0x9 fn 0xb6e6b670 str ttyS0
askfirst       (   0): fd 0xffffff9c fn 0xbea648e0 str /etc/ld-musl-armhf.path
askfirst       (   0): fd 0xffffff9c fn 0xbea64a80 str /lib/libgcc_s.so.1

MIPS32BE: (bad)

root@OpenWrt:~# uname -a
Linux OpenWrt 5.15.83 #0 SMP Fri Dec 16 10:01:38 2022 mips GNU/Linux

root@OpenWrt:~# ply -T
Verifying kernel config (/proc/config.gz)... OK
  CONFIG_UPROBES is not set
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK

root@OpenWrt:~# ply -k 'kprobe:do_sys_openat2 { printf("%v(%v): fd %v fn %v str %s\n", comm, uid, arg0, arg1, str(arg1)); }'
info: creating kallsyms cache
utpl           (   0): fd 0xffffff9c fn 0x77d54bf0 str
utpl           (   0): fd 0xffffff9c fn 0x77d43960 str
utpl           (   0): fd 0xffffff9c fn 0x7fcbc868 str
utpl           (   0): fd 0xffffff9c fn 0x7fcbc868 str
utpl           (   0): fd 0xffffff9c fn 0x77d54bf0 str
utpl           (   0): fd 0xffffff9c fn 0x7fcbc868 str
utpl           (   0): fd 0xffffff9c fn 0x7fcbc868 str

Could you please have a think about these symptoms? I suspect they may ring a bell given your familiarity with internals. I'd also appreciate if you could suggest other useful test cases e.g. printing chars from arrays, dumping the the pt_regs struct, testing the core str() function, etc.

@jaqchen Did this functionality work for you previously? Does it continue to work on your MIPS builds?

A further point I'll note is that I'm running BTF-enabled builds after contributing this to OpenWrt, and the various struct pt_regs look as expected:

MIPS32BE:

struct pt_regs {
        long unsigned int pad0[8];
        long unsigned int regs[32];
        long unsigned int cp0_status;
        long unsigned int hi;
        long unsigned int lo;
        long unsigned int cp0_badvaddr;
        long unsigned int cp0_cause;
        long unsigned int cp0_epc;
        long unsigned int __last[0];
};

MIPS64LE:

struct pt_regs {
        long unsigned int regs[32];
        long unsigned int cp0_status;
        long unsigned int hi;
        long unsigned int lo;
        long unsigned int cp0_badvaddr;
        long unsigned int cp0_cause;
        long unsigned int cp0_epc;
        long unsigned int __last[0];
};

@jaqchen
Copy link
Author

jaqchen commented Dec 20, 2022

Did this functionality work for you previously? Does it continue to work on your MIPS builds?

This is what I got when running ply on my MIPS32LE openwrt:

root@OpenWrt:~# uname -a
Linux OpenWrt 5.10.111 #0 Fri Apr 22 07:23:49 2022 mips GNU/Linux
root@OpenWrt:~# ply -T
WARN: Unable to verify kernel config
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK
root@OpenWrt:~# ply -k 'kprobe:do_sys_openat2 { printf("%v(%v): fd %v fn %v str %s\n", comm, uid, arg0, arg1, str(arg1)); }'
info: creating kallsyms cache
odhcpd         (   0): fd 0xffffff9c fn 0x7fac4174 str /proc/sys/net/ipv6/conf/br-lan/hop_limit
odhcpd         (   0): fd 0xffffff9c fn 0x7fac4174 str /proc/sys/net/ipv6/conf/br-lan/mtu
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feec2f8 str /etc/ld-musl-mipsel-sf.path
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feec320 str /lib/libgcc_s.so.1
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feecf7a str /usr/sbin/ntpd-hotplug
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x77e300a4 str /usr/share/libubox/jshn.sh
env            ( 123): fd 0xffffff9c fn 0x7f851598 str /etc/ld-musl-mipsel-sf.path
env            ( 123): fd 0xffffff9c fn 0x7f8515c0 str /lib/libgcc_s.so.1
jshn           ( 123): fd 0xffffff9c fn 0x7f73da98 str /etc/ld-musl-mipsel-sf.path
jshn           ( 123): fd 0xffffff9c fn 0x7f73dac0 str /lib/libblobmsg_json.so.20211120

The str function works on MIPS32LE.

A further point I'll note is that I'm running BTF-enabled builds after contributing this to OpenWrt, and the various struct pt_regs look as expected...

For MIPS32BE (I only have MIPS32LE devices, which is somewhat identical), you can try to get the size of struct pt_regs via:

~/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-5.10.111$ file vmlinux
vmlinux: ELF 32-bit LSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, BuildID[sha1]=26e6f51d1c2ca5723a12f233d25fc835852e6c99, with debug_info, not stripped
~/openwrt/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux-5.10.111$ ../../../../staging_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/bin/mipsel-openwrt-linux-musl-gdb -q ./vmlinux
Reading symbols from ./vmlinux...
(gdb) print sizeof(struct pt_regs)
$1 = 184

And we know that for MIPS32BE, struct pt_regs should have 46 * 4 = 184 bytes of size, and can be verified by the output from GDB. You can do the same for MIPS64BE vmlinux to verify that. @guidosarducci

@guidosarducci
Copy link

Did this functionality work for you previously? Does it continue to work on your MIPS builds?

This is what I got when running ply on my MIPS32LE openwrt:

root@OpenWrt:~# uname -a
Linux OpenWrt 5.10.111 #0 Fri Apr 22 07:23:49 2022 mips GNU/Linux
root@OpenWrt:~# ply -T
WARN: Unable to verify kernel config
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK
root@OpenWrt:~# ply -k 'kprobe:do_sys_openat2 { printf("%v(%v): fd %v fn %v str %s\n", comm, uid, arg0, arg1, str(arg1)); }'
info: creating kallsyms cache
odhcpd         (   0): fd 0xffffff9c fn 0x7fac4174 str /proc/sys/net/ipv6/conf/br-lan/hop_limit
odhcpd         (   0): fd 0xffffff9c fn 0x7fac4174 str /proc/sys/net/ipv6/conf/br-lan/mtu
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feec2f8 str /etc/ld-musl-mipsel-sf.path
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feec320 str /lib/libgcc_s.so.1
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x7feecf7a str /usr/sbin/ntpd-hotplug
ntpd-hotplug   ( 123): fd 0xffffff9c fn 0x77e300a4 str /usr/share/libubox/jshn.sh
env            ( 123): fd 0xffffff9c fn 0x7f851598 str /etc/ld-musl-mipsel-sf.path
env            ( 123): fd 0xffffff9c fn 0x7f8515c0 str /lib/libgcc_s.so.1
jshn           ( 123): fd 0xffffff9c fn 0x7f73da98 str /etc/ld-musl-mipsel-sf.path
jshn           ( 123): fd 0xffffff9c fn 0x7f73dac0 str /lib/libblobmsg_json.so.20211120

The str function works on MIPS32LE.

@jaqchen Great, thanks! This at least clarifies the functionality should work/has worked before. Unfortunately, as noted I am seeing the same problem across MIPS32BE, MIPS32LE and MIPS64LE.

And we know that for MIPS32BE, struct pt_regs should have 46 * 4 = 184 bytes of size, and can be verified by the output from GDB. You can do the same for MIPS64BE vmlinux to verify that.

To double-check, I used gdb as you suggest and found the expected results:

kodidev:~/openwrt-project$ ./staging_dir/toolchain-mipsel_24kc_gcc-11.3.0_musl/bin/mipsel-openwrt-linux-gdb -q -ex 'print sizeof(struct pt_regs)' build_dir/target-mipsel_24kc_musl/linux-malta_le/linux-5.15.83/vmlinux
Reading symbols from build_dir/target-mipsel_24kc_musl/linux-malta_le/linux-5.15.83/vmlinux...
$1 = 184
(gdb)

kodidev:~/openwrt-project$ ./staging_dir/toolchain-mips_24kc_gcc-11.3.0_musl/bin/mips-openwrt-linux-gdb -q -ex 'print sizeof(struct pt_regs)' build_dir/target-mips_24kc_musl/linux-malta_be/linux-5.15.83/vmlinux
Reading symbols from build_dir/target-mips_24kc_musl/linux-malta_be/linux-5.15.83/vmlinux...
$1 = 184
(gdb)

kodidev:~/openwrt-project$ ./staging_dir/toolchain-mips64el_mips64r2_64_gcc-11.3.0_musl/bin/mips64el-openwrt-linux-gdb -q -ex 'print sizeof(struct pt_regs)' build_dir/target-mips64el_mips64r2_64_musl/linux-malta_le64/linux-5.15.83/vmlinux  Reading symbols from build_dir/target-mips64el_mips64r2_64_musl/linux-malta_le64/linux-5.15.83/vmlinux...
$1 = 304
(gdb)

At this stage the options to investigate are narrowing. One thing I noted is that I'm building on LTS kernel 5.15 while you're using kernel 5.10. I'm going to try building MIPS32BE on kernel 5.10 next.

Could you try building with kernel 5.15 (OpenWrt snapshot) for comparison? Also, were you using the latest ply master branch as I was?

@wkz Anything else you might suggest is appreciated.

Thanks all!

@guidosarducci
Copy link

Just a quick update that things work fine on LTS kernel 5.10 for MIPS32BE, MIPS32LE and MIPS64LE. For example, MIPS32BE:

root@OpenWrt:/# uname -a
Linux OpenWrt 5.10.159 #0 SMP Wed Dec 21 01:39:50 2022 mips GNU/Linux

root@OpenWrt:/# ply -T
Verifying kernel config (/proc/config.gz)... OK
  CONFIG_UPROBES is not set
Ensuring that debugfs is mounted... OK
Verifying kprobe... OK
Verifying tracepoint... OK
Verifying special... OK
Verifying interval... OK

root@OpenWrt:/# ply -k 'kprobe:do_sys_openat2 { printf("%v(%v): fd %v fn %v str %s\n", comm, uid, arg0, arg1, str(arg1)); }'
uhttpd         (   0): fd 0xffffff9c fn 0x77bfce80 str /dev/urandom
uhttpd         (   0): fd 0xffffff9c fn 0x77bfce80 str /dev/urandom
uhttpd         (   0): fd 0xffffff9c fn 0x77bfce80 str /dev/urandom
luci           (   0): fd 0xffffff9c fn 0x7faeff08 str /etc/ld-musl-mips-sf.path
luci           (   0): fd 0xffffff9c fn 0x7faeff30 str /lib/libgcc_s.so.1
ucode          (   0): fd 0xffffff9c fn 0x7f9aaa78 str /etc/ld-musl-mips-sf.path
ucode          (   0): fd 0xffffff9c fn 0x7f9aaaa0 str /lib/libucode.so.20220812
ucode          (   0): fd 0xffffff9c fn 0x7f9aaaa0 str /usr/local/lib/libucode.so.20220812

It's possible something broke in the kernel between 5.10 and 5.15, or something deliberately changed which ply does not accommodate.

@jaqchen
Copy link
Author

jaqchen commented Dec 21, 2022

Could you try building with kernel 5.15 (OpenWrt snapshot) for comparison? Also, were you using the latest ply master branch as I was?

Yes, I built latest ply and it works fine on kernel 5.10.

It's possible something broke in the kernel between 5.10 and 5.15, or something deliberately changed which ply does not accommodate.

I think you are right. @guidosarducci I might try kernel 5.15 on AArch64 device, I don't think the problem is specific to MIPS architecture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants