Skip to content

Commit

Permalink
Update BPF lexer (#2004)
Browse files Browse the repository at this point in the history
* bpf: highlight signed type keywords

Signed type keywords such as s16 have always been supported by BPF but
recently became more frequent. They were missing in the original lexer
so this commit adds them, with an example.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

* bpf: highlight simpler call syntax

The lexer already supports the following syntax for call instructions:

    call bpf_skb_load_bytes#1234

but a simpler syntax without the number at the end is now also possible.
This commit adds support for it, with an example.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

* bpf: highlight all byte-swapping instructions

The original lexer was missing support for the little-endian
byte-swapping instructions le{16,32,64}. This commit adds them, together
with the new bswap{16,32,64} instructions. The later are unconditional
byte-swapping instructions, meaning they don't depend on the
architecture.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

* bpf: fix highlight of negative hexadecimal numbers

Hexadecimal literals can also have a sign in BPF. This commit fixes this
error in the lexer and adds a corresponding example.

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

* bpf: highlight hexadecimal jump offsets

The offset of BPF jump instructions is now sometimes displayed in
hexadecimal format. This commit adds support for that, together with an
example. It also adds an example to cover the syntax where the jump has
both an offset literal and an offset label (ex. "+1 <LBB0_2>").

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

* bpf: highlight long jumps

Jump instructions with a 32-bit offset are displayed as "gotol" instead
of "goto".

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>

---------

Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
  • Loading branch information
pchaigno authored Oct 24, 2023
1 parent 90ca46e commit fdfcbd4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
20 changes: 10 additions & 10 deletions lib/rouge/lexers/bpf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ class BPF < RegexLexer
tag 'bpf'

TYPE_KEYWORDS = %w(
u8 u16 u32 u64 ll
u8 u16 u32 u64 s8 s16 s32 s64 ll
).join('|')

MISC_KEYWORDS = %w(
be16 be32 be64 exit lock map
be16 be32 be64 le16 le32 le64 bswap16 bswap32 bswap64 exit lock map
).join('|')

state :root do
Expand All @@ -32,21 +32,21 @@ class BPF < RegexLexer
rule %r/(call)(\s+)(\d+)/i do
groups Keyword, Text::Whitespace, Literal::Number::Integer
end
rule %r/(call)(\s+)(\w+)(#)(\d+)/i do
rule %r/(call)(\s+)(\w+)(?:(#)(\d+))?/i do
groups Keyword, Text::Whitespace, Name::Builtin, Punctuation, Literal::Number::Integer
end

# Unconditional jumps
rule %r/(goto)(\s*)(\+\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label
rule %r/(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label
end

# Conditional jumps
rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)(0x\h+|[-]?\d+)(\s*)(goto)(\s*)(\+\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label
rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)(0x\h+|[-]?\d+)(\s*)(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Literal::Number, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label
end
rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)([rw]\d+)(\s*)(goto)(\s*)(\+\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Name, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Integer, Text::Whitespace, Name::Label
rule %r/(if)(\s+)([rw]\d+)(\s*)([s!=<>]+)(\s*)([rw]\d+)(\s*)(gotol?)(\s*)([-+]0x\w+)?([-+]\d+)?(\s*)(<?\w+>?)/i do
groups Keyword, Text::Whitespace, Name, Text::Whitespace, Operator, Text::Whitespace, Name, Text::Whitespace, Keyword, Text::Whitespace, Literal::Number::Hex, Literal::Number::Integer, Text::Whitespace, Name::Label
end

# Dereferences
Expand All @@ -70,7 +70,7 @@ class BPF < RegexLexer
rule %r/#{MISC_KEYWORDS}/i, Keyword

# Literals and global objects (maps) refered by name
rule %r/(0x\h+|[-]?\d+)(\s*)(ll)?/i do
rule %r/([-]?0x\h+|[-]?\d+)(\s*)(ll)?/i do
groups Literal::Number, Text::Whitespace, Keyword::Type
end
rule %r/(\w+)(\s*)(ll)/i do
Expand Down
16 changes: 13 additions & 3 deletions spec/visual/samples/bpf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ LBB0_4:
r6 = *(u16 *)(r1 + 8) // BPF_LDX | BPF_H
r7 = *(u32 *)(r2 + 16) // BPF_LDX | BPF_W
r8 = *(u64 *)(r3 - 30) // BPF_LDX | BPF_DW
r1 = *(s32 *)(r6 +0) // BPF_SMEM | BPF_LDX | BPF_W

// ======== BPF_STX Class ========
*(u8 *)(r0 + 0) = r7 // BPF_STX | BPF_B
Expand All @@ -54,6 +55,7 @@ LBB0_4:
// ======== BPF_JMP Class ========
goto Llabel0 // BPF_JA
call 1 // BPF_CALL
call bpf_skb_load_bytes // BPF_CALL
exit // BPF_EXIT

if r0 == r1 goto Llabel0 // BPF_JEQ | BPF_X
Expand All @@ -69,6 +71,8 @@ LBB0_4:
if r8 s< r9 goto Llabel0 // BPF_JSLT | BPF_X
if r9 s<= r10 goto Llabel0 // BPF_JSLE | BPF_X

if r9 < r1 goto -0x5 <Llabel0> // BPF_JLT | BPF_X

if r0 == 0 goto Llabel0 // BPF_JEQ | BPF_K
if r3 != -1 goto Llabel0 // BPF_JNE | BPF_K

Expand All @@ -82,11 +86,15 @@ LBB0_4:
if r8 s< 0 goto Llabel0 // BPF_JSLT | BPF_K
if r9 s<= -1 goto Llabel0 // BPF_JSLE | BPF_K

goto +1 <LBB0_2> // BPF_JMP | BPF_JA
gotol +0x7fffffff <LBB0_2> // BPF_JMP32 | BPF_JA

// ======== BPF_ALU64 Class ========
r0 += r1 // BPF_ADD | BPF_X
r1 -= r2 // BPF_SUB | BPF_X
r2 *= r3 // BPF_MUL | BPF_X
r3 /= r4 // BPF_DIV | BPF_X
r1 s/= -0x5 // BPF_SDIV | BPF_X

Llabel0 :
r2 = -r2 // BPF_NEG
Expand All @@ -98,9 +106,11 @@ Llabel0 :
r9 = r10 // BPF_MOV | BPF_X
r10 s>>= r0 // BPF_ARSH | BPF_X

r1 = be16 r1 // BPF_END | BPF_TO_BE
r2 = be32 r2 // BPF_END | BPF_TO_BE
r3 = be64 r3 // BPF_END | BPF_TO_BE
r1 = be16 r1 // BPF_END | BPF_TO_BE
r2 = be32 r2 // BPF_END | BPF_TO_BE
r3 = be64 r3 // BPF_END | BPF_TO_BE
r1 = le16 r1 // BPF_END | BPF_TO_LE
r1 = bswap32 r1 // BPF_ALU64 | BPF_END | BPF_TO_BE

r0 += 1 // BPF_ADD | BPF_K
r1 -= 0x1 // BPF_SUB | BPF_K
Expand Down

0 comments on commit fdfcbd4

Please sign in to comment.