Full Code of Nalen98/eBPF-for-Ghidra for AI

master 69f6ea89fecd cached
20 files
117.8 KB
31.6k tokens
17 symbols
1 requests
Download .txt
Repository: Nalen98/eBPF-for-Ghidra
Branch: master
Commit: 69f6ea89fecd
Files: 20
Total size: 117.8 KB

Directory structure:
gitextract_aren7096/

├── .gitignore
├── LICENSE
├── Module.manifest
├── README.md
├── build.gradle
├── data/
│   ├── build.xml
│   ├── languages/
│   │   ├── eBPF.cspec
│   │   ├── eBPF.dwarf
│   │   ├── eBPF.ldefs
│   │   ├── eBPF.opinion
│   │   ├── eBPF.pspec
│   │   ├── eBPF.sinc
│   │   └── eBPF.slaspec
│   └── sleighArgs.txt
├── extension.properties
└── src/
    └── main/
        └── java/
            └── ghidra/
                └── app/
                    ├── plugin/
                    │   └── core/
                    │       └── analysis/
                    │           └── eBPFAnalyzer.java
                    └── util/
                        └── bin/
                            └── format/
                                └── elf/
                                    ├── extend/
                                    │   └── eBPF_ElfExtension.java
                                    └── relocation/
                                        ├── ElfeBPFRelocationFixupHandler.java
                                        ├── eBPF_ElfRelocationConstants.java
                                        └── eBPF_ElfRelocationHandler.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.gradle
build
dist


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2019 Nalen98

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Module.manifest
================================================
 


================================================
FILE: README.md
================================================
# eBPF processor for Ghidra

The extension implements eBPF architecture support for Ghidra and allows for disassembly and decompilation of eBPF programs.

# Warning: eBPF is included in Ghidra since Ghidra 10.3

**Since May 2023, [eBPF-for-Ghidra](https://github.com/Nalen98/eBPF-for-Ghidra) has been included in the official [NationalSecurityAgency/Ghidra](https://github.com/NationalSecurityAgency/ghidra) repository**.  
You can get the latest updates and fixes for the [eBPF module](https://github.com/NationalSecurityAgency/ghidra/tree/70405b07b0b857d433dfec77ae5c343997f589eb/Ghidra/Processors/eBPF) directly in Ghidra.

This repo may be archived in the future.

# Examples

Example of eBPF program you can get
[here](https://github.com/vbpf/ebpf-samples).

![eBPF Extension](./images/eBPF.gif)

Example of disassembling and decompiling of eBPF:

![Example of decompiling](./images/Main.png)

# Installation

- Download Release version of extension and install it in Ghidra `File → Install Extensions...`
- Use gradle to build extension: `GHIDRA_INSTALL_DIR=${GHIDRA_HOME} gradle` and use Ghidra to install it: `File → Install Extensions...`
- Clone this repository to `\Ghidra\Extensions` directory.

# Updates

03.09.2019 — eBPF maps implementation, custom relocation handler was implemented

![](./images/eBPFMaps.png)


19.09.2019 — problem with stack [is resolved](https://github.com/Nalen98/eBPF-for-Ghidra/issues/2#issuecomment-533263382)

20.09.2019 — eBPF call-helpers are implemented as syscalls, added helper's signature through custom eBPFAnalyzer

![](./images/eBPFSyscalls.png)


23.09.2019 — bad bookmarks fixed

![](./images/GoodBookmarks.png)

01.12.2020 — new eBPF-helpers added

23.06.2022 — added support for relative calls (`R_BPF_64_32` relocation type). Thanks [@cnwangjihe](https://github.com/cnwangjihe) for this [idea](https://github.com/Nalen98/eBPF-for-Ghidra/pull/10). `imm` of call instruction where `bpf_call->src_reg == BPF_PSEUDO_CALL` now contains the relative offset to target function.

Before:

![image](https://user-images.githubusercontent.com/52778977/175531695-bb059f0c-9f6e-4346-87fa-eaa9c0e6a45a.png)

After:

![](./images/RelativeCalls.png)


24.06.2022 — making the [Pull Request](https://github.com/NationalSecurityAgency/ghidra/pull/4378) to official [Ghidra](https://github.com/NationalSecurityAgency/ghidra) repository as the main supplier of the eBPF processor

19.12.2022 — added support for BPF_ATOMIC operations, ALU32 instructions added, BPF_JMP32 instructions added, JSET instruction fixed

03.05.2023 — eBPF processor support added to the Ghidra official repository in the commit [506ca1e](https://github.com/NationalSecurityAgency/ghidra/commit/79102c13c48b56e8173a0754d2804f4fe25adf22)

Starting from Ghidra 10.3, the eBPF module is included by default in Ghidra. There's no need to build this project and add it as a Ghidra extension anymore. For users of older versions of Ghidra, the eBPF module can still be accessed through existing [Releases](https://github.com/Nalen98/eBPF-for-Ghidra/releases/tag/v0.2).

# Useful links

* [Official kernel documentation](https://www.kernel.org/doc/Documentation/networking/filter.txt)

* [Official kernel documentation - questions](https://www.kernel.org/doc/html/latest/bpf/bpf_design_QA.html)

* [eBPF programs to test in Ghidra](https://github.com/vbpf/ebpf-samples)

* [Simple eBPF disassembler in Rust](https://github.com/badboy/ebpf-disasm)

* [Rust virtual machine and JIT compiler for eBPF programs](https://github.com/qmonnet/rbpf)

* [eBPF helpers (all)](https://github.com/torvalds/linux/blob/v5.17/include/uapi/linux/bpf.h#L2619)

* [eBPF overview](https://www.collabora.com/news-and-blog/blog/2019/04/05/an-ebpf-overview-part-1-introduction/)




================================================
FILE: build.gradle
================================================
// Builds a Ghidra Extension for a given Ghidra installation.
//
// An absolute path to the Ghidra installation directory must be supplied either by setting the
// GHIDRA_INSTALL_DIR environment variable or Gradle project property:
//
//     > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
//     > gradle
//
//         or
//
//     > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
//
// Gradle should be invoked from the directory of the project to build.  Please see the
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
// for the correction version of Gradle to use for the Ghidra installation you specify.

//----------------------START "DO NOT MODIFY" SECTION------------------------------
def ghidraInstallDir

if (System.env.GHIDRA_INSTALL_DIR) {
  ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
}
else if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
  ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
}

if (ghidraInstallDir) {
  apply from: new File(ghidraInstallDir).getCanonicalPath() + "/support/buildExtension.gradle"
}
else {
  throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
}
//----------------------END "DO NOT MODIFY" SECTION-------------------------------


================================================
FILE: data/build.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
                               
<project name="privateBuildDistribution" default="sleigh-compile">
    
    <property name="sleigh.compile.class" value="ghidra.pcodeCPort.slgh_compile.SleighCompile"/>
    
    <target name="sleigh-compile">
        
        <property name="framework.path" value="../../../Framework"/>
        
        <path id="sleigh.class.path">
            <fileset dir="${framework.path}/SoftwareModeling/lib">
                <include name="*.jar"/>
            </fileset>
            <fileset dir="${framework.path}/Generic/lib">
                <include name="*.jar"/>
            </fileset>
            <fileset dir="${framework.path}/Utility/lib">
                <include name="*.jar"/>
            </fileset>
        </path>
        
        <available classname="${sleigh.compile.class}" classpathref="sleigh.class.path" property="sleigh.compile.exists"/>
            
        <fail unless="sleigh.compile.exists" />
        
        <java classname="${sleigh.compile.class}"
            classpathref="sleigh.class.path"
            fork="true"
            failonerror="true">
            <jvmarg value="-Xmx2048M"/>
            <arg value="-i"/>
            <arg value="sleighArgs.txt"/>
            <arg value="-a"/>
            <arg value="./languages"/>
        </java>
        
    </target>

</project>


================================================
FILE: data/languages/eBPF.cspec
================================================
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
  <data_organization> 
     <absolute_max_alignment value="0" />
     <machine_alignment value="2" />
     <default_alignment value="1" />
     <default_pointer_alignment value="8" />
     <pointer_size value="8" />
     <wchar_size value="2" />
     <short_size value="2" />
     <integer_size value="4" />
     <long_size value="4" />
     <long_long_size value="8" />
     <float_size value="4" />
     <double_size value="8" />
     <long_double_size value="8" />
     <size_alignment_map>
          <entry size="1" alignment="1" />
          <entry size="2" alignment="2" />
          <entry size="4" alignment="4" />
          <entry size="8" alignment="8" />
     </size_alignment_map>
  </data_organization>
   <global> 
   	  <range space="ram"/>
   	  <range space="syscall"/>
   </global> 
  <stackpointer register="R10" space="ram"/>
   <default_proto>
    <prototype name="__fastcall" extrapop="0" stackshift="0">
      <input>
        <pentry minsize="1" maxsize="8">
          <register name="R1"/>
        </pentry>
        <pentry minsize="1" maxsize="8">
          <register name="R2"/>
        </pentry>
        <pentry minsize="1" maxsize="8">
          <register name="R3"/>
        </pentry>      
         <pentry minsize="1" maxsize="8">
          <register name="R4"/>
        </pentry>
         <pentry minsize="1" maxsize="8">
          <register name="R5"/>
        </pentry>
      </input>
      <output killedbycall="true">
        <pentry minsize="1" maxsize="8">
          <register name="R0"/>
        </pentry>
       </output>
      <unaffected>
        <varnode space="ram" offset="8" size="8"/>
        <register name="R6"/>       
	    <register name="R7"/>
        <register name="R8"/>
        <register name="R9"/>       
		<register name="R10"/> 	
      </unaffected> 
    </prototype>
  </default_proto>
 </compiler_spec>


================================================
FILE: data/languages/eBPF.dwarf
================================================
<dwarf>
    <register_mappings>								
        <register_mapping dwarf="0" ghidra="R0"/>
        <register_mapping dwarf="1" ghidra="R1"/>
        <register_mapping dwarf="2" ghidra="R2"/>
        <register_mapping dwarf="3" ghidra="R3"/>
        <register_mapping dwarf="4" ghidra="R4"/>
        <register_mapping dwarf="5" ghidra="R5"/>
        <register_mapping dwarf="6" ghidra="R6"/>
        <register_mapping dwarf="7" ghidra="R7"/>
        <register_mapping dwarf="8" ghidra="R8"/>
        <register_mapping dwarf="9" ghidra="R9"/>
        <register_mapping dwarf="10" ghidra="R10" stackpointer="true"/>
    </register_mappings>
    <call_frame_cfa value="8"/>
</dwarf>


================================================
FILE: data/languages/eBPF.ldefs
================================================
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
   <language processor="eBPF"
            endian="little"
            size="64"
            variant="default"
            version="1.0"
            slafile="eBPF_le.sla"
            processorspec="eBPF.pspec"
            id="eBPF:LE:64:default">
    <description>eBPF processor 64-bit little-endian</description>
    <compiler name="default" spec="eBPF.cspec" id="default"/>
	<external_name tool="DWARF.register.mapping.file" name="eBPF.dwarf"/>
  </language>
</language_definitions>


================================================
FILE: data/languages/eBPF.opinion
================================================
<opinions>
    <constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
        <constraint primary="247" processor="eBPF" endian="little" size="64" />
    </constraint>  
</opinions>


================================================
FILE: data/languages/eBPF.pspec
================================================
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
    <programcounter register="PC"/>	 
    <default_symbols>
            <symbol name="bpf_unspec" address="syscall:0x0"/>
            <symbol name="bpf_map_lookup_elem" address="syscall:0x1"/>
            <symbol name="bpf_map_update_elem" address="syscall:0x2"/>
            <symbol name="bpf_map_delete_elem" address="syscall:0x3"/>
            <symbol name="bpf_probe_read" address="syscall:0x4"/>
            <symbol name="bpf_ktime_get_ns" address="syscall:0x5"/>
            <symbol name="bpf_trace_printk" address="syscall:0x6"/>
            <symbol name="bpf_get_prandom_u32" address="syscall:0x7"/>
            <symbol name="bpf_get_smp_processor_id" address="syscall:0x8"/>
            <symbol name="bpf_skb_store_bytes" address="syscall:0x9"/>
            <symbol name="bpf_l3_csum_replace" address="syscall:0xa"/>
            <symbol name="bpf_l4_csum_replace" address="syscall:0xb"/>
            <symbol name="bpf_tail_call" address="syscall:0xc"/>
            <symbol name="bpf_clone_redirect" address="syscall:0xd"/>
            <symbol name="bpf_get_current_pid_tgid" address="syscall:0xe"/>
            <symbol name="bpf_get_current_uid_gid" address="syscall:0xf"/>
            <symbol name="bpf_get_current_comm" address="syscall:0x10"/>
            <symbol name="bpf_get_cgroup_classid" address="syscall:0x11"/>
            <symbol name="bpf_skb_vlan_push" address="syscall:0x12"/>
            <symbol name="bpf_skb_vlan_pop" address="syscall:0x13"/>
            <symbol name="bpf_skb_get_tunnel_key" address="syscall:0x14"/>
            <symbol name="bpf_skb_set_tunnel_key" address="syscall:0x15"/>
            <symbol name="bpf_perf_event_read" address="syscall:0x16"/>
            <symbol name="bpf_redirect" address="syscall:0x17"/>
            <symbol name="bpf_get_route_realm" address="syscall:0x18"/>
            <symbol name="bpf_perf_event_output" address="syscall:0x19"/>
            <symbol name="bpf_skb_load_bytes" address="syscall:0x1a"/>
            <symbol name="bpf_get_stackid" address="syscall:0x1b"/>	
            <symbol name="bpf_csum_diff" address="syscall:0x1c"/>
            <symbol name="bpf_skb_get_tunnel_opt" address="syscall:0x1d"/>
            <symbol name="bpf_skb_set_tunnel_opt" address="syscall:0x1e"/>
            <symbol name="bpf_skb_change_proto" address="syscall:0x1f"/>
            <symbol name="bpf_skb_change_type" address="syscall:0x20"/>
            <symbol name="bpf_skb_under_cgroup" address="syscall:0x21"/>
            <symbol name="bpf_get_hash_recalc" address="syscall:0x22"/>
            <symbol name="bpf_get_current_task" address="syscall:0x23"/>
            <symbol name="bpf_probe_write_user" address="syscall:0x24"/>
            <symbol name="bpf_current_task_under_cgroup" address="syscall:0x25"/>
            <symbol name="bpf_skb_change_tail" address="syscall:0x26"/>
            <symbol name="bpf_skb_pull_data" address="syscall:0x27"/>
            <symbol name="bpf_csum_update" address="syscall:0x28"/>
            <symbol name="bpf_set_hash_invalid" address="syscall:0x29"/>
            <symbol name="bpf_get_numa_node_id" address="syscall:0x2a"/>
            <symbol name="bpf_skb_change_head" address="syscall:0x2b"/>
            <symbol name="bpf_xdp_adjust_head" address="syscall:0x2c"/>
            <symbol name="bpf_probe_read_str" address="syscall:0x2d"/>
            <symbol name="bpf_get_socket_cookie" address="syscall:0x2e"/>
            <symbol name="bpf_get_socket_cookie" address="syscall:0x2f"/>
            <symbol name="bpf_get_socket_cookie" address="syscall:0x30"/>
            <symbol name="bpf_get_socket_uid" address="syscall:0x31"/>
            <symbol name="bpf_set_hash" address="syscall:0x32"/>
            <symbol name="bpf_setsockopt" address="syscall:0x33"/>
            <symbol name="bpf_skb_adjust_room" address="syscall:0x34"/>
            <symbol name="bpf_redirect_map" address="syscall:0x35"/>
            <symbol name="bpf_sk_redirect_map" address="syscall:0x36"/>
            <symbol name="bpf_sock_map_update" address="syscall:0x37"/>
            <symbol name="bpf_xdp_adjust_meta" address="syscall:0x38"/>
            <symbol name="bpf_perf_event_read_value" address="syscall:0x39"/>
            <symbol name="bpf_perf_prog_read_value" address="syscall:0x3a"/>
            <symbol name="bpf_getsockopt" address="syscall:0x3b"/>
            <symbol name="bpf_override_return" address="syscall:0x3c"/>
            <symbol name="bpf_sock_ops_cb_flags_set" address="syscall:0x3d"/>
            <symbol name="bpf_msg_redirect_map" address="syscall:0x3e"/>
            <symbol name="bpf_msg_apply_bytes" address="syscall:0x3f"/>	
    </default_symbols>
    <default_memory_blocks>
        <memory_block name="eBPFHelper_functions" start_address="syscall:0" length="0x400" initialized="true"/>    
    </default_memory_blocks>
</processor_spec>


================================================
FILE: data/languages/eBPF.sinc
================================================
###############################################################################
# eBPF Processor Specification for Ghidra
###############################################################################

#eBPF is a RISC register machine with a total of 11 64-bit registers, a program counter and a 512 byte fixed-size stack. 
#9 registers are general purpouse read-write, one is a read-only stack pointer and the program counter is implicit,
#i.e. we can only jump to a certain offset from it. The eBPF registers are always 64-bit wide.

define space ram type=ram_space size=8 default;
define space register type=register_space size=4;
define space syscall type=ram_space size=4;

define register offset=0 size=8 [ R0  R1  R2  R3  R4  R5  R6  R7  R8  R9  R10  PC ];

# Instruction encoding: Insop:8, dst_reg:4, src_reg:4, off:16, imm:32 - from lsb to msb
define token instr(64)
    imm=(32, 63) signed
    off=(16, 31) signed
    src=(12, 15)
    dst=(8, 11)
    op_alu_jmp_opcode=(4, 7)
    op_alu_jmp_source=(3, 3)
    op_ld_st_mode=(5, 7)
    op_ld_st_size=(3, 4)
    op_insn_class=(0, 2)
;

#We'll need this token to operate with LDDW instruction, which has 64 bit imm value
define token immtoken(64)
    imm2=(32, 63)		
;

#To operate with registers
attach variables [ src dst ] [  R0  R1  R2  R3  R4  R5  R6  R7  R8  R9  R10  _  _  _  _  _  ];

#Arithmetic instructions
#BPF_ALU64
###############################################################################

:MOV dst, src  is src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = src; }
:MOV dst, imm  is imm & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = imm; }

:ADD dst, src  is src & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst + src; }
:ADD dst, imm  is imm & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst + imm; }

:SUB dst, src  is src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst - src; }
:SUB dst, imm  is imm & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst - imm; }

:MUL dst, src  is src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst * src; }
:MUL dst, imm  is imm & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst * imm; }

:DIV dst, src  is src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst / src; }
:DIV dst, imm  is imm & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst / imm; }

:OR dst, src  is src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst | src; }
:OR dst, imm  is imm & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst | imm; }

:AND dst, src  is src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst & src; }
:AND dst, imm  is imm & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst & imm; }

:LSH dst, src  is src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst << src; }
:LSH dst, imm  is imm & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst << imm; }

:RSH dst, src  is src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst >> src; }
:RSH dst, imm  is imm & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst >> imm; }

:NEG dst  is dst & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = -dst; }

:MOD dst, src  is src & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst % src; }
:MOD dst, imm  is imm & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst % imm; }

:XOR dst, src  is src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst ^ src; }
:XOR dst, imm  is imm & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst ^ imm; }

:ARSH dst, src  is src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x7 { dst = dst s>> src; }
:ARSH dst, imm  is imm & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x7 { dst = dst s>> imm; }

#BPF_ALU
###############################################################################

:MOV dst, src  is src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(src:4); }
:MOV dst, imm  is imm & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = imm; }

:ADD dst, src  is src & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 + src:4); }
:ADD dst, imm  is imm & dst & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 + imm); }

:SUB dst, src  is src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 - src:4); }
:SUB dst, imm  is imm & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 - imm); }

:MUL dst, src  is src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 * src:4); }
:MUL dst, imm  is imm & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 * imm); }

:DIV dst, src  is src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 / src:4); }
:DIV dst, imm  is imm & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 / imm); }

:OR dst, src  is src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 | src:4); }
:OR dst, imm  is imm & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 | imm); }

:AND dst, src  is src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 & src:4); }
:AND dst, imm  is imm & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 & imm); }

:LSH dst, src  is src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 << src:4); }
:LSH dst, imm  is imm & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 << imm); }

:RSH dst, src  is src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 >> src:4); }
:RSH dst, imm  is imm & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 >> imm); }

:NEG dst  is dst & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(-dst:4); }

:MOD dst, src  is src & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 % src:4); }
:MOD dst, imm  is imm & dst & op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 % imm); }

:XOR dst, src  is src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 ^ src:4); }
:XOR dst, imm  is imm & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 ^ imm); }

:ARSH dst, src  is src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x4 { dst = zext(dst:4 s>> src:4); }
:ARSH dst, imm  is imm & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x4 { dst = zext(dst:4 s>> imm); }

#Bytewasp instructions
###############################################################################
# BPF_ALU   | BPF_K   | BPF_END
:LE16 dst  is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst=((dst) >> 8) | ((dst) << 8); }
:LE32 dst  is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 { dst=((dst) >> 24) | (((dst) & 0x00FF0000) >> 8)  | (((dst) & 0x0000FF00) << 8) | ((dst) << 24); }
:LE64 dst  is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x4 {
    dst=( (dst << 56) & 0xff00000000000000 ) |
    ( (dst << 40) & 0x00ff000000000000 ) |
    ( (dst << 24) & 0x0000ff0000000000 ) |
    ( (dst <<  8) & 0x000000ff00000000 ) |
    ( (dst >>  8) & 0x00000000ff000000 ) |
    ( (dst >> 24) & 0x0000000000ff0000 ) |
    ( (dst >> 40) & 0x000000000000ff00 ) |
    ( (dst >> 56) & 0x00000000000000ff );
}

# BPF_ALU   | BPF_X   | BPF_END
:BE16 dst  is imm=0x10 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst=((dst) >> 8) | ((dst) << 8); }
:BE32 dst  is imm=0x20 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 { dst=((dst) >> 24) | (((dst) & 0x00FF0000) >> 8)  | (((dst) & 0x0000FF00) << 8) | ((dst) << 24); }
:BE64 dst  is imm=0x40 & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x4 {
    dst=( (dst << 56) & 0xff00000000000000 ) |
    ( (dst << 40) & 0x00ff000000000000 ) |
    ( (dst << 24) & 0x0000ff0000000000 ) |
    ( (dst <<  8) & 0x000000ff00000000 ) |
    ( (dst >>  8) & 0x00000000ff000000 ) |
    ( (dst >> 24) & 0x0000000000ff0000 ) |
    ( (dst >> 40) & 0x000000000000ff00 ) |
    ( (dst >> 56) & 0x00000000000000ff );
}
    
#Memory instructions - Load and Store
###############################################################################

#LDDW is the only 16-byte eBPF instruction which consists of two consecutive 8-byte blocks ('struct bpf_insn') 
#and interpreted as single instruction which loads 64-bit imm value into dst. Encoding of LDDW:
#LSR                                                                                                MSR
#           opcode      src     dst     offset      Low 8-byte imm      zero-block      High 8-byte imm
#bits          8         4       4        16               32               32                 32
# So, imm64 consists of concatination of high 8-byte imm and low 8-byte imm.

:LDDW dst, concat  is imm & dst &  op_ld_st_mode=0x0 & op_ld_st_size=0x3 & op_insn_class=0x0; imm2 [ concat= (imm2 << 32) | ((imm) & 0xFFFFFFFF); ] { dst = concat; }

#BPF_LD_MAP_FD(DST, MAP_FD) -> second LDDW = pseudo LDDW insn used to refer to process-local map_fd 
#For each instruction which needs relocation, it inject corresponding file descriptor to imm field. 
#As a part of protocol, src_reg is set to BPF_PSEUDO_MAP_FD (which defined as 1) to notify kernel this is a map loading instruction.

:LDDW dst, imm  is imm & src=1 & dst & op_ld_st_mode=0x0 & op_ld_st_size=0x3 & op_insn_class=0x0; imm2 { dst = *:8 imm:8; }

:LDABSW dst, imm  is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x0 & op_insn_class=0x0 { dst=*:4 imm:8; }

:LDABSH dst, imm  is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x1 & op_insn_class=0x0 { dst=*:2 imm:8; }

:LDABSB dst, imm  is imm & dst &  op_ld_st_mode=0x1 & op_ld_st_size=0x2 & op_insn_class=0x0 { dst=*:1 imm:8; }

:LDABSDW dst, imm  is imm & dst & op_ld_st_mode=0x1 & op_ld_st_size=0x3 & op_insn_class=0x0 { dst=*:8 imm:8; }

:LDINDW src, dst, imm  is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x0 & op_insn_class=0x0  { dst=*:4 (src + imm); }

:LDINDH src, dst, imm  is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x1 & op_insn_class=0x0 { dst=*:2 (src + imm); }

:LDINDB src, dst, imm  is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x2 & op_insn_class=0x0 { dst=*:1 (src + imm); }

:LDINDDW src, dst, imm  is imm & src & dst & op_ld_st_mode=0x2 & op_ld_st_size=0x3 & op_insn_class=0x0 { dst=*:8 (src + imm); }

:LDXW dst, [src + off]  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x1 { dst=*:4 (src + off); }

:LDXH dst, [src + off]  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x1 { dst=*:2 (src + off); }

:LDXB dst, [src + off]  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x1 { dst=*:1 (src + off); }

:LDXDW dst, [src + off]  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x1 { dst=*:8 (src + off); }

:STW [dst + off], imm  is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x2 { *:4 (dst + off)=imm:4; }

:STH [dst + off], imm  is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x2 { *:2 (dst + off)=imm:2; }

:STB [dst + off], imm  is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x2 { *:1 (dst + off)=imm:1; }

:STDW [dst + off], imm  is imm & off & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x2 { *:8 (dst + off)=imm:8; }

:STXW [dst + off], src  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off)=src:4; }

:STXH [dst + off], src  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x1 & op_insn_class=0x3 { *:2 (dst + off)=src:2; }

:STXB [dst + off], src  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x2 & op_insn_class=0x3 { *:1 (dst + off)=src:1; }

:STXDW [dst + off], src  is off & src & dst & op_ld_st_mode=0x3 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off)=src:8; }

# BPF_ATOMIC
# BPF_ADD:

# BPF_STX  | BPF_ATOMIC | BPF_W
:STXXADDW [dst + off], src  is imm=0x0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) + src:4; }

# BPF_STX  | BPF_ATOMIC | BPF_DW
:STXXADDDW [dst + off], src  is imm=0x0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) + src; }

# BPF_OR:

:STXXADDW [dst + off], src  is imm=0x40 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) | src:4; }

:STXXADDDW [dst + off], src  is imm=0x40 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) | src; }

# BPF_AND:

:STXXADDW [dst + off], src  is imm=0x50 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) & src:4; }

:STXXADDDW [dst + off], src  is imm=0x50 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) & src; }

# BPF_XOR:

:STXXADDW [dst + off], src  is imm=0xa0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { *:4 (dst + off) = *:4 (dst + off) ^ src:4; }

:STXXADDDW [dst + off], src  is imm=0xa0 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { *:8 (dst + off) = *:8 (dst + off) ^ src; }

# BPF_ADD | BPF_FETCH -> src = atomic_fetch_add(dst + off, src):

:STXXADDW [dst + off], src  is imm=0x1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    *:4 (dst + off) = *:4 (dst + off) + src:4;
    src = zext(tmp);
}

:STXXADDDW [dst + off], src  is imm=0x1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    *:8 (dst + off) = *:8 (dst + off) + src; 
    src = tmp;
}

# BPF_OR | BPF_FETCH -> src = atomic_fetch_or(dst + off, src):

:STXXADDW [dst + off], src  is imm=0x41 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    *:4 (dst + off) = *:4 (dst + off) | src:4;
    src = zext(tmp);
}

:STXXADDDW [dst + off], src  is imm=0x41 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    *:8 (dst + off) = *:8 (dst + off) | src; 
    src = tmp;
}

# BPF_AND | BPF_FETCH -> src = atomic_fetch_and(dst + off, src):

:STXXADDW [dst + off], src  is imm=0x51 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    *:4 (dst + off) = *:4 (dst + off) & src:4;
    src = zext(tmp);
}

:STXXADDDW [dst + off], src  is imm=0x51 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    *:8 (dst + off) = *:8 (dst + off) & src; 
    src = tmp;
}

# BPF_XOR | BPF_FETCH -> src = atomic_fetch_xor(dst + off, src):

:STXXADDW [dst + off], src  is imm=0xa1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    *:4 (dst + off) = *:4 (dst + off) ^ src:4;
    src = zext(tmp);
}

:STXXADDDW [dst + off], src  is imm=0xa1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    *:8 (dst + off) = *:8 (dst + off) ^ src; 
    src = tmp;
}

# BPF_XCHG -> src_reg = atomic_xchg(dst + off, src):

:STXXADDW [dst + off], src  is imm=0xe1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    *:4 (dst + off) = src:4;
    src = zext(tmp);
}

:STXXADDDW [dst + off], src  is imm=0xe1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    *:8 (dst + off) = src;
    src = tmp;
}

# BPF_CMPXCHG -> R0 = atomic_cmpxchg(dst + off, R0, src):

:STXXADDW [dst + off], src  is imm=0xf1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x0 & op_insn_class=0x3 { 
    local tmp:4 = *:4 (dst + off);
    if (R0:4 == tmp) goto <equal>;
    R0 = zext(tmp);    
<equal>
    *:4 (dst + off) = src:4;
}

:STXXADDDW [dst + off], src  is imm=0xf1 & off & src & dst & op_ld_st_mode=0x6 & op_ld_st_size=0x3 & op_insn_class=0x3 { 
    local tmp:8 = *:8 (dst + off);
    if (R0 == tmp) goto <equal>;
    R0 = tmp;    
<equal>
    *:8 (dst + off) = src; 
}

#Jump instructions (BPF_JMP, BPF_JMP32)
###############################################################################

joff: reloc  is off [ reloc = inst_next + off * 8; ] { export *:8 reloc; }

:JA joff  is joff & op_alu_jmp_opcode=0x0 & op_alu_jmp_source=0 & op_insn_class=0x5 {	
    goto joff;
}

:JEQ dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x5 {	
    if (dst == imm) goto joff;
}

:JEQ dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst == src) goto joff;
}

:JEQ dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=0 & op_insn_class=0x6 {	
    if (dst:4 == imm:4) goto joff;
}

:JEQ dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x1 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 == src:4) goto joff;
}

:JGT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst > imm) goto joff;	
}

:JGT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst > src) goto joff;
}

:JGT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 > imm:4) goto joff;	
}

:JGT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x2 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 > src:4) goto joff;
}

:JGE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst >= imm) goto joff;
}

:JGE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst >= src) goto joff;
}

:JGE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 >= imm:4) goto joff;
}

:JGE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x3 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 >= src:4) goto joff;
}

:JLT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst < imm) goto joff;
}

:JLT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst < src) goto joff;
}

:JLT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 < imm:4) goto joff;
}

:JLT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xa & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 < src:4) goto joff;
}

:JLE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst <= imm) goto joff;
}

:JLE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst <= src) goto joff;
}

:JLE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 <= imm:4) goto joff;
}

:JLE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xb & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 <= src:4) goto joff;
}

:JNE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst != imm) goto joff;
}

:JNE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst != src) goto joff;	
}

:JNE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 != imm:4) goto joff;
}

:JNE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x5 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 != src:4) goto joff;	
}

:JSET dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x5 {    	  
    if ((dst & imm) != 0) goto joff;
}

:JSET dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x5 {     
    if ((dst & src) != 0) goto joff;
}

:JSET dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=0 & op_insn_class=0x6 {     
    if ((dst:4 & imm:4) != 0) goto joff;
}

:JSET dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x4 & op_alu_jmp_source=1 & op_insn_class=0x6 {   	  
    if ((dst:4 & src:4) != 0) goto joff;
}

:JSGT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst s> imm) goto joff;
}

:JSGT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst s> src) goto joff;
}

:JSGT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 s> imm:4) goto joff;
}

:JSGT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x6 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 s> src:4) goto joff;
}

:JSGE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst s>= imm) goto joff;
}

:JSGE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst s>= src) goto joff;
}

:JSGE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 s>= imm:4) goto joff;
}

:JSGE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0x7 & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 s>= src:4) goto joff;
}

:JSLT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst s< imm) goto joff;
}

:JSLT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst s< src) goto joff;
}

:JSLT dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 s< imm:4) goto joff;
}

:JSLT dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xc & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 s< src:4) goto joff;
}

:JSLE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x5 {	  
    if (dst s<= imm) goto joff;
}

:JSLE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x5 {	  
    if (dst s<= src) goto joff;
}

:JSLE dst, imm, joff  is imm & joff & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=0 & op_insn_class=0x6 {	  
    if (dst:4 s<= imm:4) goto joff;
}

:JSLE dst, src, joff  is joff & src & dst & op_alu_jmp_opcode=0xd & op_alu_jmp_source=1 & op_insn_class=0x6 {	  
    if (dst:4 s<= src:4) goto joff;
}

SysCall:  imm is imm { export *[syscall]:1 imm; }

:CALL SysCall  is imm & src=0 & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x5 & SysCall {
    call SysCall;
}

disp32: reloc is imm [ reloc = inst_next + imm; ] { export *:4 reloc; }

:CALL disp32 is imm & src=1 & op_alu_jmp_opcode=0x8 & op_alu_jmp_source=0 & op_insn_class=0x5 & disp32 {
    call disp32;
}

:EXIT is op_alu_jmp_opcode=0x9 & op_alu_jmp_source=0 & op_insn_class=0x5 { return [*:8 R10]; }


================================================
FILE: data/languages/eBPF.slaspec
================================================
define endian=little;

@include "eBPF.sinc"

================================================
FILE: data/sleighArgs.txt
================================================
# Add sleigh compiler options to this file (one per line) which will
# be used when compiling each language within this module.
# All options should start with a '-' character.
#
# IMPORTANT: The -a option should NOT be specified
#

================================================
FILE: extension.properties
================================================
name=eBPF
description=eBPF Processor for Ghidra
author=Nalen98
createdOn=
version=@extversion@


================================================
FILE: src/main/java/ghidra/app/plugin/core/analysis/eBPFAnalyzer.java
================================================
package ghidra.app.plugin.core.analysis;

import ghidra.app.cmd.function.SetFunctionNameCmd;
import ghidra.app.cmd.function.SetFunctionVarArgsCommand;
import ghidra.app.cmd.function.SetReturnDataTypeCmd;
import ghidra.app.plugin.core.analysis.ConstantPropagationAnalyzer;
import ghidra.app.plugin.core.analysis.ConstantPropagationContextEvaluator;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import ghidra.program.model.address.*;
import ghidra.program.model.data.CharDataType;
import ghidra.program.model.data.DataType;
import ghidra.program.model.lang.Processor;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.SourceType;
import ghidra.program.model.symbol.SymbolIterator;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.program.util.*;
import ghidra.program.model.data.IntegerDataType;
import ghidra.program.model.data.PointerDataType;
import ghidra.program.model.data.SignedQWordDataType;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.data.UnsignedCharDataType;
import ghidra.program.model.data.UnsignedIntegerDataType;
import ghidra.program.model.data.UnsignedLongDataType;
import ghidra.program.model.data.UnsignedShortDataType;
import ghidra.program.model.data.VoidDataType;
import ghidra.program.model.listing.BookmarkManager;
import ghidra.program.model.listing.CodeUnit;
import ghidra.program.model.listing.Function;
import ghidra.app.cmd.function.AddMemoryParameterCommand;

public class eBPFAnalyzer extends ConstantPropagationAnalyzer {
    private final static String PROCESSOR_NAME = "eBPF";

    public eBPFAnalyzer() {
        super(PROCESSOR_NAME);
    }

    @Override
    public boolean canAnalyze(Program program) {
        return program.getLanguage().getProcessor().equals(
            Processor.findOrPossiblyCreateProcessor(PROCESSOR_NAME));
    }

    @Override
    public AddressSet flowConstants(final Program program, Address flowStart, AddressSetView flowSet, final SymbolicPropogator symEval, final TaskMonitor monitor)
    throws CancelledException {
        // https://github.com/NationalSecurityAgency/ghidra/commit/70405b07b0b857d433dfec77ae5c343997f589eb
        ContextEvaluator eval = new ConstantPropagationContextEvaluator(monitor, trustWriteMemOption);
        AddressSet resultSet = symEval.flowConstants(flowStart, flowSet, eval, true, monitor);

        BookmarkManager bmmanager = program.getBookmarkManager();
        bmmanager.removeBookmarks("Error", "Bad Instruction", monitor);

        SymbolTable table = program.getSymbolTable();
        boolean includeDynamicSymbols = true;
        SymbolIterator symbols = table.getAllSymbols(includeDynamicSymbols);

        for (ghidra.program.model.symbol.Symbol s: symbols) {
            if (s.getName().contains("syscall")) {
                Function func = program.getFunctionManager().getFunctionAt(s.getAddress());

                //Definitions for datatypes
                DataType dstruct = null;
                DataType dvoid = new VoidDataType();
                DataType dint = new IntegerDataType();
                DataType dchar = new CharDataType();
                DataType duint = new UnsignedIntegerDataType();
                DataType dulong = new UnsignedLongDataType();
                DataType dushort = new UnsignedShortDataType();
                DataType dslong = new SignedQWordDataType();
                DataType duchar = new UnsignedCharDataType();
                DataType dvp = new PointerDataType(dvoid, 0);
                DataType dcp = new PointerDataType(dchar, 0);
                DataType dsp; //DataType for struct-pointer
                //Command-vars
                SetFunctionNameCmd cmdName;
                SetReturnDataTypeCmd cmdRet;
                AddMemoryParameterCommand cmdArg1;
                AddMemoryParameterCommand cmdArg2;
                AddMemoryParameterCommand cmdArg3;
                AddMemoryParameterCommand cmdArg4;
                AddMemoryParameterCommand cmdArg5;
                SetFunctionVarArgsCommand cmdVar = new SetFunctionVarArgsCommand(func, true);

                String location = s.getName().substring(14); //Getting address of helper
                int helper_id = Integer.parseInt(location, 16);
                switch (helper_id) {
                    case(0x0):
                        //void bpf_unspec()
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_unspec", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1):
                        //void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_lookup_elem", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvp, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2):
                        //int bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_update_elem", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "value", dvp, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3):
                        //int bpf_map_delete_elem(struct bpf_map *map, const void *key)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_map_delete_elem", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x4):
                        //int bpf_probe_read(void *dst, u32 size, const void *src)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_read", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "src", dvp, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x5):
                        //u64 bpf_ktime_get_ns(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_ktime_get_ns", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x6):
                        //int bpf_trace_printk(const char *fmt, u32 fmt_size, ...)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_trace_printk", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "fmt", dcp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "fmt_size", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x7):
                        //u32 bpf_get_prandom_u32(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_prandom_u32", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x8):
                        //u32 bpf_get_smp_processor_id(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_smp_processor_id", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x9):
                        //int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_store_bytes", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdVar.applyTo(program);
                        //If we'll set all arguments for this func (as always), it will give rise nasty errors such "Removing unreachable block at (address)"
                        //int bpf_skb_store_bytes(struct sk_buff *skb, u32 offset, const void *from, u32 len, u64 flags)
                        program.flushEvents();
                        break;
                    case (0xa):
                        //int bpf_l3_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_l3_csum_replace", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "from", dulong, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dulong, 3, SourceType.ANALYSIS);
                        cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "size", dulong, 4, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        cmdArg5.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0xb):
                        //int bpf_l4_csum_replace(struct sk_buff *skb, u32 offset, u64 from, u64 to, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_l4_csum_replace", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "from", dulong, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dulong, 3, SourceType.ANALYSIS);
                        cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 4, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        cmdArg5.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0xc):
                        //int bpf_tail_call(void *ctx, struct bpf_map *prog_array_map, u32 index)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_tail_call", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dvp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "prog_array_map", dsp, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0xd):
                        //int bpf_clone_redirect(struct sk_buff *skb, u32 ifindex, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_clone_redirect", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "ifindex", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0xe):
                        //u64 bpf_get_current_pid_tgid(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_pid_tgid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0xf):
                        //u64 bpf_get_current_uid_gid(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_uid_gid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x10):
                        //int bpf_get_current_comm(char *buf, u32 size_of_buf)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_comm", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", dcp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size_of_buf", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x11):
                        //u32 bpf_get_cgroup_classid(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_cgroup_classid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x12):
                        //int bpf_skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci)
                        //In ghidra Api conditions we must equate__be16 with unsigned short type.
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_vlan_push", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "vlan_proto", dushort, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "vlan_tci", dushort, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x13):
                        //int bpf_skb_vlan_pop(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_vlan_pop", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x14):
                        //int bpf_skb_get_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_get_tunnel_key", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        DataType dstruct2 = new StructureDataType("struct bpf_tunnel_key", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x15):
                        //int bpf_skb_set_tunnel_key(struct sk_buff *skb, struct bpf_tunnel_key *key, u32 size, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_set_tunnel_key", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_tunnel_key", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x16):
                        //u64 bpf_perf_event_read(struct bpf_map *map, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_read", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x17):
                        //int bpf_redirect(u32 ifindex, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_redirect", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ifindex", duint, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x18):
                        //u32 bpf_get_route_realm(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_route_realm", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x19):
                        //int bpf_perf_event_output(struct pt_reg *ctx, struct bpf_map *map, u64 flags, void *data, u64 size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_output", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct pt_reg", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "data", dvp, 3, SourceType.ANALYSIS);
                        cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "size", dulong, 4, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        cmdArg5.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1a):
                        //int bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset, void *to, u32 len)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_load_bytes", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "offset", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "to", dvp, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1b):
                        //int bpf_get_stackid(struct pt_reg *ctx, struct bpf_map *map, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_stackid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct pt_reg", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1c):
                        //s64 bpf_csum_diff(__be32 *from, u32 from_size, __be32 *to, u32 to_size, __wsum seed)
                        //In ghidra Api conditions we must equate __be32 and __wsum with u32 (knowing typedef).
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_csum_diff", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dslong, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "from", new PointerDataType(duint, 0), 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "from_size", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "to", new PointerDataType(duint, 0), 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "to_size", duint, 3, SourceType.ANALYSIS);
                        cmdArg5 = new AddMemoryParameterCommand(func, s.getAddress(), "seed", duint, 4, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        cmdArg5.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1d):
                        //int bpf_skb_get_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_get_tunnel_opt", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "opt", new PointerDataType(duchar, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1e):
                        //int bpf_skb_set_tunnel_opt(struct sk_buff *skb, u8 *opt, u32 size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_set_tunnel_opt", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "opt", new PointerDataType(duchar, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x1f):
                        //int bpf_skb_change_proto(struct sk_buff *skb, __be16 proto, u64 flags)
                        //__be16 equals u16 for big-endian
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_proto", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "proto", dushort, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x20):
                        //int bpf_skb_change_type(struct sk_buff *skb, u32 type)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_type", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "type", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x21):
                        //int bpf_skb_under_cgroup(struct sk_buff *skb, struct bpf_map *map, u32 index)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_under_cgroup", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x22):
                        //u32 bpf_get_hash_recalc(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_hash_recalc", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x23):
                        //u64 bpf_get_current_task(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_current_task", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x24):
                        //int bpf_probe_write_user(void *dst, const void *src, u32 len)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_write_user", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "src", dvp, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x25):
                        //int bpf_current_task_under_cgroup(struct bpf_map *map, u32 index)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_current_task_under_cgroup", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "index", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x26):
                        //int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_tail", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x27):
                        //int bpf_skb_pull_data(struct sk_buff *skb, u32 len)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_pull_data", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x28):
                        //s64 bpf_csum_update(struct sk_buff *skb, __wsum csum)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_csum_update", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dslong, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "csum", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x29):
                        //void bpf_set_hash_invalid(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_set_hash_invalid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2a):
                        //int bpf_get_numa_node_id(void)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_numa_node_id", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2b):
                        //int bpf_skb_change_head(struct sk_buff *skb, u32 len, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_change_head", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2c):
                        //int bpf_xdp_adjust_head(struct xdp_buff *xdp_md, int delta)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_xdp_adjust_head", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct xdp_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "xdp_md", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "delta", dint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2d):
                        //int bpf_probe_read_str(void *dst, u32 size, const void *unsafe_ptr)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_probe_read_str", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);

                        dstruct = new StructureDataType("struct xdp_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "dst", dvp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "size", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "unsafe_ptr", dvp, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2e):
                        //u64 bpf_get_socket_cookie(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x2f):
                        //u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_sock_addr", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x30):
                        //u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_cookie", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dulong, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_sock_ops", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x31):
                        //u32 bpf_get_socket_uid(struct sk_buff *skb)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_get_socket_uid", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), duint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x32):
                        //int bpf_set_hash(struct sk_buff *skb, u32 hash)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_set_hash", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "hash", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x33):
                        //int bpf_setsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_setsockopt", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdVar.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x34):
                        //int bpf_skb_adjust_room(struct sk_buff *skb, s32 len_diff, u32 mode, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_skb_adjust_room", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "len_diff", dint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "mode", duint, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x35):
                        //int bpf_redirect_map(struct bpf_map *map, u32 key, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_redirect_map", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x36):
                        //int bpf_sk_redirect_map(struct sk_buff *skb, struct bpf_map *map, u32 key, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sk_redirect_map", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skb", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x37):
                        //int bpf_sock_map_update(struct bpf_sock_ops *skops, struct bpf_map *map, void *key, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sock_map_update", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_sock_ops", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "skops", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", dvp, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x38):
                        //int bpf_xdp_adjust_meta(struct xdp_buff *xdp_md, int delta)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_xdp_adjust_meta", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct xdp_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "xdp_md", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "delta", dint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x39):
                        //int bpf_perf_event_read_value(struct bpf_map *map, u64 flags, struct bpf_perf_event_value *buf, u32 buf_size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_event_read_value", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_map", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_perf_event_value", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "map", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", new PointerDataType(dstruct2, 0), 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "buf_size", duint, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3a):
                        //int bpf_perf_prog_read_value(struct bpf_perf_event_data *ctx, struct bpf_perf_event_value *buf, u32 buf_size)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_perf_prog_read_value", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_perf_event_data", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_perf_event_value", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "ctx", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "buf", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "buf_size", duint, 2, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3b):
                        //int bpf_getsockopt(void *bpf_socket, int level, int optname, void *optval, int optlen)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_getsockopt", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdVar.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3c):
                        //int bpf_override_return(struct pt_regs *regs, u64 rc)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_override_return", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct pt_regs", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "regs", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "rc", dulong, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3d):
                        //int bpf_sock_ops_cb_flags_set(struct bpf_sock_ops *bpf_sock, int argval)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_sock_ops_cb_flags_set", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct bpf_sock_ops", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "bpf_sock", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "argval", dint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3e):
                        //int bpf_msg_redirect_map(struct sk_msg_buff *msg, struct bpf_map *map, u32 key, u64 flags)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_msg_redirect_map", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_msg_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);
                        dstruct2 = new StructureDataType("struct bpf_map", 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "msg", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "map", new PointerDataType(dstruct2, 0), 1, SourceType.ANALYSIS);
                        cmdArg3 = new AddMemoryParameterCommand(func, s.getAddress(), "key", duint, 2, SourceType.ANALYSIS);
                        cmdArg4 = new AddMemoryParameterCommand(func, s.getAddress(), "flags", dulong, 3, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        cmdArg3.applyTo(program);
                        cmdArg4.applyTo(program);
                        program.flushEvents();
                        break;
                    case (0x3f):
                        //int bpf_msg_apply_bytes(struct sk_msg_buff *msg, u32 bytes)
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_msg_apply_bytes", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dint, SourceType.ANALYSIS);
                        dstruct = new StructureDataType("struct sk_msg_buff", 0);
                        dsp = new PointerDataType(dstruct, 0);

                        cmdArg1 = new AddMemoryParameterCommand(func, s.getAddress(), "msg", dsp, 0, SourceType.ANALYSIS);
                        cmdArg2 = new AddMemoryParameterCommand(func, s.getAddress(), "bytes", duint, 1, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        cmdArg1.applyTo(program);
                        cmdArg2.applyTo(program);
                        program.flushEvents();
                        break;
                    default:
                        //void bpf_undef()
                        cmdName = new SetFunctionNameCmd(s.getAddress(), "bpf_undef", SourceType.ANALYSIS);
                        cmdRet = new SetReturnDataTypeCmd(s.getAddress(), dvoid, SourceType.ANALYSIS);

                        cmdName.applyTo(program);
                        cmdRet.applyTo(program);
                        program.flushEvents();
                        break;
                }
                bmmanager.setBookmark(s.getAddress(), "Analysis", "eBPF-helpers", "eBPF-helper Identified");
            }
        }
        return resultSet;
    }
}


================================================
FILE: src/main/java/ghidra/app/util/bin/format/elf/extend/eBPF_ElfExtension.java
================================================
package ghidra.app.util.bin.format.elf.extend;

import ghidra.app.util.bin.format.elf.*;
import ghidra.program.model.lang.*;
import ghidra.util.exception.*;
import ghidra.util.task.TaskMonitor;

public class eBPF_ElfExtension extends ElfExtension {
    @Override
    public boolean canHandle(ElfHeader elf) {
        return elf.e_machine() == ElfConstants.EM_BPF && elf.is64Bit();
    }

    @Override
    public boolean canHandle(ElfLoadHelper elfLoadHelper) {
        Language language = elfLoadHelper.getProgram().getLanguage();
        return canHandle(elfLoadHelper.getElfHeader()) && "eBPF".equals(language.getProcessor().toString()) &&
            language.getLanguageDescription().getSize() == 64;
    }

    @Override
    public String getDataTypeSuffix() {
        return "eBPF";
    }

    @Override
    public void processGotPlt(ElfLoadHelper elfLoadHelper, TaskMonitor monitor) throws CancelledException {
        if (!canHandle(elfLoadHelper)) {
            return;
        }
        super.processGotPlt(elfLoadHelper, monitor);
    }
}


================================================
FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java
================================================
package ghidra.app.util.bin.format.elf.relocation;

import ghidra.app.plugin.core.reloc.RelocationFixupHandler;
import ghidra.app.util.opinion.ElfLoader;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Processor;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.Relocation;
import ghidra.program.model.util.CodeUnitInsertionException;

public class ElfeBPFRelocationFixupHandler extends RelocationFixupHandler {
    @Override
    public boolean processRelocation(Program program, Relocation relocation, Address oldImageBase,
            Address newImageBase) throws MemoryAccessException, CodeUnitInsertionException {
                return process64BitRelocation(program, relocation, oldImageBase, newImageBase);
    }

    @Override
    public boolean handlesProgram(Program program) {
        if (!ElfLoader.ELF_NAME.equals(program.getExecutableFormat())) {
            return false;
        }
        Language language = program.getLanguage();
        if (language.getLanguageDescription().getSize() != 64) {
            return false;
        }
        Processor processor = language.getProcessor();
        return (processor.equals(Processor.findOrPossiblyCreateProcessor("eBPF")));
    }
}


================================================
FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java
================================================
package ghidra.app.util.bin.format.elf.relocation;

public class eBPF_ElfRelocationConstants {

    /** No operation needed */
    public static final int R_BPF_NONE = 0;
    /** S + A */
    public static final int R_BPF_64_64 = 1;
    /** S + A */
    public static final int R_BPF_64_ABS64 = 2;
    /** S + A */
    public static final int R_BPF_64_ABS32 = 3;
    /** S + A */
    public static final int R_BPF_64_NODYLD32 = 4;
    /** (S + A) / 8 - 1 */
    public static final int R_BPF_64_32 = 10;

    private eBPF_ElfRelocationConstants() {
        // no construct
    }
}


================================================
FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java
================================================
package ghidra.app.util.bin.format.elf.relocation;

import ghidra.app.util.bin.format.elf.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.program.model.reloc.RelocationResult;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.symbol.SymbolTable;
import ghidra.util.exception.NotFoundException;

public class eBPF_ElfRelocationHandler extends ElfRelocationHandler {
    @Override
    public boolean canRelocate(ElfHeader elf) {
        return elf.e_machine() == ElfConstants.EM_BPF;
    }

    @Override
    public RelocationResult relocate(ElfRelocationContext elfRelocationContext, ElfRelocation relocation,
                    Address relocationAddress) throws MemoryAccessException, NotFoundException {

        ElfHeader elf = elfRelocationContext.getElfHeader();
        if (elf.e_machine() != ElfConstants.EM_BPF) {
            return RelocationResult.FAILURE;
        }

        Program program = elfRelocationContext.getProgram();
        Memory memory = program.getMemory();

        int type = relocation.getType();
        if (type == eBPF_ElfRelocationConstants.R_BPF_NONE) {
            return RelocationResult.SKIPPED;
        }

        String section_name = elfRelocationContext.relocationTable.getSectionToBeRelocated().getNameAsString();
        if (section_name.toString().contains("debug")) {
            return RelocationResult.SKIPPED;
        }

        SymbolTable table = program.getSymbolTable();
        int symbolIndex = relocation.getSymbolIndex();
        ElfSymbol symbol = elfRelocationContext.getSymbol(symbolIndex);
        String symbolName = symbol.getNameAsString();
        Address symbolAddr = table.getSymbols(symbolName).next().getAddress();

        long new_value = 0;
        int byteLength = 4; // most relocations affect 4-bytes

        try {
            switch (type){
                case eBPF_ElfRelocationConstants.R_BPF_64_64: {
                    new_value = symbolAddr.getAddressableWordOffset();
                    Byte dst = memory.getByte(relocationAddress.add(0x1));
                    memory.setLong(relocationAddress.add(0x4), new_value);
                    memory.setByte(relocationAddress.add(0x1), (byte)(dst + 0x10));
                    break;
                }
                case eBPF_ElfRelocationConstants.R_BPF_64_32: {

                    // if we have, e.g, non-static function, it will be marked in the relocation table
                    // and indexed in the symbol table and it's easy to calculate the pc-relative offset
                    long instr_next = relocationAddress.add(0x8).getAddressableWordOffset();
                    if (symbol.isFunction()) {
                        new_value = symbolAddr.getAddressableWordOffset();
                        int offset = (int)(new_value - instr_next);
                        memory.setInt(relocationAddress.add(0x4), offset);
                    } else if (symbol.isSection()) {
                        if (memory.getInt(relocationAddress) == 0x1085) {
                            ElfSectionHeader sectionHeader = elfRelocationContext.getElfHeader().getSection(symbolName);
                            long section_start = program.getImageBase().getOffset() + sectionHeader.getAddress();

                            // getting call instruction offset (current imm)
                            int current_imm = memory.getInt(relocationAddress.add(0x4));

                            // calculate the call target section offset
                            // according to formula in "kernel.org" docs: https://www.kernel.org/doc/html/latest/bpf/llvm_reloc.html
                            int func_sec_offset = (current_imm + 1) * 8;
                            long func_addr = section_start + func_sec_offset;
                            int offset = (int)(func_addr - instr_next);
                            memory.setInt(relocationAddress.add(0x4), offset);
                        }
                    }
                    break;
                }
                default: {
                    if (symbolIndex == 0) {
                        markAsWarning(program, relocationAddress,
                                Long.toString(type), "applied relocation with symbol-index of 0", elfRelocationContext.getLog());
                    }
                    return RelocationResult.UNSUPPORTED;
                }
            }
        } catch (NullPointerException e) {  }
        return new RelocationResult(Status.APPLIED, byteLength);
    }
}
Download .txt
gitextract_aren7096/

├── .gitignore
├── LICENSE
├── Module.manifest
├── README.md
├── build.gradle
├── data/
│   ├── build.xml
│   ├── languages/
│   │   ├── eBPF.cspec
│   │   ├── eBPF.dwarf
│   │   ├── eBPF.ldefs
│   │   ├── eBPF.opinion
│   │   ├── eBPF.pspec
│   │   ├── eBPF.sinc
│   │   └── eBPF.slaspec
│   └── sleighArgs.txt
├── extension.properties
└── src/
    └── main/
        └── java/
            └── ghidra/
                └── app/
                    ├── plugin/
                    │   └── core/
                    │       └── analysis/
                    │           └── eBPFAnalyzer.java
                    └── util/
                        └── bin/
                            └── format/
                                └── elf/
                                    ├── extend/
                                    │   └── eBPF_ElfExtension.java
                                    └── relocation/
                                        ├── ElfeBPFRelocationFixupHandler.java
                                        ├── eBPF_ElfRelocationConstants.java
                                        └── eBPF_ElfRelocationHandler.java
Download .txt
SYMBOL INDEX (17 symbols across 5 files)

FILE: src/main/java/ghidra/app/plugin/core/analysis/eBPFAnalyzer.java
  class eBPFAnalyzer (line 33) | public class eBPFAnalyzer extends ConstantPropagationAnalyzer {
    method eBPFAnalyzer (line 36) | public eBPFAnalyzer() {
    method canAnalyze (line 40) | @Override
    method flowConstants (line 46) | @Override

FILE: src/main/java/ghidra/app/util/bin/format/elf/extend/eBPF_ElfExtension.java
  class eBPF_ElfExtension (line 8) | public class eBPF_ElfExtension extends ElfExtension {
    method canHandle (line 9) | @Override
    method canHandle (line 14) | @Override
    method getDataTypeSuffix (line 21) | @Override
    method processGotPlt (line 26) | @Override

FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java
  class ElfeBPFRelocationFixupHandler (line 13) | public class ElfeBPFRelocationFixupHandler extends RelocationFixupHandler {
    method processRelocation (line 14) | @Override
    method handlesProgram (line 20) | @Override

FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java
  class eBPF_ElfRelocationConstants (line 3) | public class eBPF_ElfRelocationConstants {
    method eBPF_ElfRelocationConstants (line 18) | private eBPF_ElfRelocationConstants() {

FILE: src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java
  class eBPF_ElfRelocationHandler (line 12) | public class eBPF_ElfRelocationHandler extends ElfRelocationHandler {
    method canRelocate (line 13) | @Override
    method relocate (line 18) | @Override
Condensed preview — 20 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (125K chars).
[
  {
    "path": ".gitignore",
    "chars": 19,
    "preview": ".gradle\nbuild\ndist\n"
  },
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2019 Nalen98\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "Module.manifest",
    "chars": 2,
    "preview": " \n"
  },
  {
    "path": "README.md",
    "chars": 3764,
    "preview": "# eBPF processor for Ghidra\n\nThe extension implements eBPF architecture support for Ghidra and allows for disassembly an"
  },
  {
    "path": "build.gradle",
    "chars": 1263,
    "preview": "// Builds a Ghidra Extension for a given Ghidra installation.\n//\n// An absolute path to the Ghidra installation director"
  },
  {
    "path": "data/build.xml",
    "chars": 1378,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n                               \n<project name=\"privateBuildDistribution\" default="
  },
  {
    "path": "data/languages/eBPF.cspec",
    "chars": 1920,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<compiler_spec>\n  <data_organization> \n     <absolute_max_alignment value=\"0\" />\n"
  },
  {
    "path": "data/languages/eBPF.dwarf",
    "chars": 678,
    "preview": "<dwarf>\n    <register_mappings>\t\t\t\t\t\t\t\t\n        <register_mapping dwarf=\"0\" ghidra=\"R0\"/>\n        <register_mapping dwar"
  },
  {
    "path": "data/languages/eBPF.ldefs",
    "chars": 546,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<language_definitions>\n   <language processor=\"eBPF\"\n            endian=\"little\"\n"
  },
  {
    "path": "data/languages/eBPF.opinion",
    "chars": 210,
    "preview": "<opinions>\n    <constraint loader=\"Executable and Linking Format (ELF)\" compilerSpecID=\"default\">\n        <constraint pr"
  },
  {
    "path": "data/languages/eBPF.pspec",
    "chars": 4918,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<processor_spec>\n    <programcounter register=\"PC\"/>\t \n    <default_symbols>\n    "
  },
  {
    "path": "data/languages/eBPF.sinc",
    "chars": 24955,
    "preview": "###############################################################################\n# eBPF Processor Specification for Ghidr"
  },
  {
    "path": "data/languages/eBPF.slaspec",
    "chars": 45,
    "preview": "define endian=little;\r\n\r\n@include \"eBPF.sinc\""
  },
  {
    "path": "data/sleighArgs.txt",
    "chars": 231,
    "preview": "# Add sleigh compiler options to this file (one per line) which will\n# be used when compiling each language within this "
  },
  {
    "path": "extension.properties",
    "chars": 95,
    "preview": "name=eBPF\ndescription=eBPF Processor for Ghidra\nauthor=Nalen98\ncreatedOn=\nversion=@extversion@\n"
  },
  {
    "path": "src/main/java/ghidra/app/plugin/core/analysis/eBPFAnalyzer.java",
    "chars": 71976,
    "preview": "package ghidra.app.plugin.core.analysis;\n\nimport ghidra.app.cmd.function.SetFunctionNameCmd;\nimport ghidra.app.cmd.funct"
  },
  {
    "path": "src/main/java/ghidra/app/util/bin/format/elf/extend/eBPF_ElfExtension.java",
    "chars": 1051,
    "preview": "package ghidra.app.util.bin.format.elf.extend;\n\nimport ghidra.app.util.bin.format.elf.*;\nimport ghidra.program.model.lan"
  },
  {
    "path": "src/main/java/ghidra/app/util/bin/format/elf/relocation/ElfeBPFRelocationFixupHandler.java",
    "chars": 1354,
    "preview": "package ghidra.app.util.bin.format.elf.relocation;\n\nimport ghidra.app.plugin.core.reloc.RelocationFixupHandler;\nimport g"
  },
  {
    "path": "src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationConstants.java",
    "chars": 581,
    "preview": "package ghidra.app.util.bin.format.elf.relocation;\n\npublic class eBPF_ElfRelocationConstants {\n\n    /** No operation nee"
  },
  {
    "path": "src/main/java/ghidra/app/util/bin/format/elf/relocation/eBPF_ElfRelocationHandler.java",
    "chars": 4614,
    "preview": "package ghidra.app.util.bin.format.elf.relocation;\n\nimport ghidra.app.util.bin.format.elf.*;\nimport ghidra.program.model"
  }
]

About this extraction

This page contains the full source code of the Nalen98/eBPF-for-Ghidra GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 20 files (117.8 KB), approximately 31.6k tokens, and a symbol index with 17 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!