1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021, 2024, Oracle and/or its affiliates.
*/
#include <bpf_asm_helpers.h>
/*
* void dt_basename(const dt_dctx_t *dctx, char *src, char *dst);
*/
.text
.align 4
.global dt_basename
.type dt_basename, @function
dt_basename :
#define SRC %r6
#define DST %r7
#define BGN %r8
#define LEN %r9
/* store copies of input arguments */
mov SRC, %r2
mov DST, %r3
/*
* Copy src to dst for two reasons:
* - to get the string length
* - to have a copy that we can access directly
*/
/* r0 = bpf_probe_read_str(dst, STRSZ + 1, src) */
mov %r1, DST
lddw %r2, STRSZ
add %r2, 1
mov %r3, SRC
call BPF_FUNC_probe_read_str
/* if (r0 s<= 1) goto Ldot */
jsle %r0, 1, .Ldot
/* len = r0 - 1 */
mov LEN, %r0
sub LEN, 1
/*
* Loop over len, backing it up to find a non-'/' char.
*/
.Lend:
/* len-- */
sub LEN, 1
/* if (len s< 0) goto Lslash */
jslt LEN, 0, .Lslash
/* if (dst[len] == '/') goto Lend */
mov %r1, DST
add %r1, LEN
ldxb %r1, [%r1+0]
and %r1, 0xff
jeq %r1, '/', .Lend
/*
* Loop over bgn, backing it up to find a '/' char.
*/
/* bgn = len */
mov BGN, LEN
.Lbgn:
/* bgn-- */
sub BGN, 1
/* if (bgn s< 0) goto Lcopy */
jslt BGN, 0, .Lcopy
/* if (dst[bgn] != '/') goto Lbgn */
mov %r1, DST
add %r1, BGN
ldxb %r1, [%r1+0]
and %r1, 0xff
jne %r1, '/', .Lbgn
.Lcopy:
/*
* The output string is a copy of the designated substring.
*/
/* len -= bgn (and help the BPF verifier) */
sub LEN, BGN
jsge LEN, 0, 1
mov LEN, 0
/* bgn++ */
add BGN, 1
/* bpf_probe_read_str(dst, len + 1, &src[bgn]) */
mov %r1, DST
mov %r2, LEN
add %r2, 1
mov %r3, SRC
add %r3, BGN
call BPF_FUNC_probe_read_str
/* return */
exit
.Ldot:
/*
* The output string is simply ".\0".
*/
mov LEN, 1
stb [DST+0], '.'
stb [DST+1], 0
exit
.Lslash:
/*
* The output string is simply "/\0".
*/
mov LEN, 1
stb [DST+0], '/'
stb [DST+1], 0
exit
#undef SRC
#undef DST
#undef BGN
#undef LEN
.size dt_basename, .-dt_basename
|