xref: /aosp_15_r20/external/bcc/src/lua/bpf/ljbytecode.lua (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker--[[
2*387f9dfdSAndroid Build Coastguard WorkerCopyright 2016 Marek Vavrusa <[email protected]>
3*387f9dfdSAndroid Build Coastguard Worker
4*387f9dfdSAndroid Build Coastguard WorkerLicensed under the Apache License, Version 2.0 (the "License");
5*387f9dfdSAndroid Build Coastguard Workeryou may not use this file except in compliance with the License.
6*387f9dfdSAndroid Build Coastguard WorkerYou may obtain a copy of the License at
7*387f9dfdSAndroid Build Coastguard Worker
8*387f9dfdSAndroid Build Coastguard Workerhttp://www.apache.org/licenses/LICENSE-2.0
9*387f9dfdSAndroid Build Coastguard Worker
10*387f9dfdSAndroid Build Coastguard WorkerUnless required by applicable law or agreed to in writing, software
11*387f9dfdSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS,
12*387f9dfdSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*387f9dfdSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and
14*387f9dfdSAndroid Build Coastguard Workerlimitations under the License.
15*387f9dfdSAndroid Build Coastguard Worker]]
16*387f9dfdSAndroid Build Coastguard Workerlocal jutil = require("jit.util")
17*387f9dfdSAndroid Build Coastguard Workerlocal vmdef = require("jit.vmdef")
18*387f9dfdSAndroid Build Coastguard Workerlocal bit = require('bit')
19*387f9dfdSAndroid Build Coastguard Workerlocal shr, band = bit.rshift, bit.band
20*387f9dfdSAndroid Build Coastguard Worker
21*387f9dfdSAndroid Build Coastguard Worker-- Decode LuaJIT 2.0 Byte Format
22*387f9dfdSAndroid Build Coastguard Worker-- Reference: http://wiki.luajit.org/Bytecode-2.0
23*387f9dfdSAndroid Build Coastguard Worker-- Thanks to LJ, we get code in portable bytecode with constants folded, basic
24*387f9dfdSAndroid Build Coastguard Worker-- virtual registers allocated etc.
25*387f9dfdSAndroid Build Coastguard Worker-- No SSA IR, type inference or advanced optimizations because the code wasn't traced yet.
26*387f9dfdSAndroid Build Coastguard Workerlocal function decode_ins(func, pc)
27*387f9dfdSAndroid Build Coastguard Worker	local ins, m = jutil.funcbc(func, pc)
28*387f9dfdSAndroid Build Coastguard Worker	if not ins then return nil end
29*387f9dfdSAndroid Build Coastguard Worker	local op, ma, mb, mc = band(ins, 0xff), band(m, 7), band(m, 15*8), band(m, 15*128)
30*387f9dfdSAndroid Build Coastguard Worker	local a, b, c, d = band(shr(ins, 8), 0xff), nil, nil, shr(ins, 16)
31*387f9dfdSAndroid Build Coastguard Worker	if mb ~= 0 then
32*387f9dfdSAndroid Build Coastguard Worker		d = band(d, 0xff)
33*387f9dfdSAndroid Build Coastguard Worker		b = shr(ins, 24)
34*387f9dfdSAndroid Build Coastguard Worker	end
35*387f9dfdSAndroid Build Coastguard Worker	if ma == 5 then          -- BCMuv
36*387f9dfdSAndroid Build Coastguard Worker	    a = jutil.funcuvname(func, a)
37*387f9dfdSAndroid Build Coastguard Worker	end
38*387f9dfdSAndroid Build Coastguard Worker	if mc == 13*128 then     -- BCMjump
39*387f9dfdSAndroid Build Coastguard Worker		c = pc+d-0x7fff
40*387f9dfdSAndroid Build Coastguard Worker	elseif mc == 14*128 then -- BCMcdata
41*387f9dfdSAndroid Build Coastguard Worker		c = jutil.funck(func, -d-1)
42*387f9dfdSAndroid Build Coastguard Worker	elseif mc == 9*128 then  -- BCMint
43*387f9dfdSAndroid Build Coastguard Worker		c = jutil.funck(func, d)
44*387f9dfdSAndroid Build Coastguard Worker	elseif mc == 10*128 then -- BCMstr
45*387f9dfdSAndroid Build Coastguard Worker		c = jutil.funck(func, -d-1)
46*387f9dfdSAndroid Build Coastguard Worker	elseif mc == 5*128 then  -- BCMuv
47*387f9dfdSAndroid Build Coastguard Worker	    c = jutil.funcuvname(func, d)
48*387f9dfdSAndroid Build Coastguard Worker	end
49*387f9dfdSAndroid Build Coastguard Worker	-- Convert version-specific opcode to string
50*387f9dfdSAndroid Build Coastguard Worker	op = 6*op
51*387f9dfdSAndroid Build Coastguard Worker	op = string.sub(vmdef.bcnames, op+1, op+6):match('[^%s]+')
52*387f9dfdSAndroid Build Coastguard Worker	return pc, op, a, b, c, d
53*387f9dfdSAndroid Build Coastguard Workerend
54*387f9dfdSAndroid Build Coastguard Worker
55*387f9dfdSAndroid Build Coastguard Worker-- Decoder closure
56*387f9dfdSAndroid Build Coastguard Workerlocal function decoder(func)
57*387f9dfdSAndroid Build Coastguard Worker	local pc = 0
58*387f9dfdSAndroid Build Coastguard Worker	return function ()
59*387f9dfdSAndroid Build Coastguard Worker		pc = pc + 1
60*387f9dfdSAndroid Build Coastguard Worker		return decode_ins(func, pc)
61*387f9dfdSAndroid Build Coastguard Worker	end
62*387f9dfdSAndroid Build Coastguard Workerend
63*387f9dfdSAndroid Build Coastguard Worker
64*387f9dfdSAndroid Build Coastguard Worker-- Hexdump generated code
65*387f9dfdSAndroid Build Coastguard Workerlocal function dump(func)
66*387f9dfdSAndroid Build Coastguard Worker	return require('jit.bc').dump(func)
67*387f9dfdSAndroid Build Coastguard Workerend
68*387f9dfdSAndroid Build Coastguard Worker
69*387f9dfdSAndroid Build Coastguard Workerreturn {
70*387f9dfdSAndroid Build Coastguard Worker	decode = decode_ins,
71*387f9dfdSAndroid Build Coastguard Worker	decoder = decoder,
72*387f9dfdSAndroid Build Coastguard Worker	dump = dump,
73*387f9dfdSAndroid Build Coastguard Worker	funcinfo = function (...) return jutil.funcinfo(...) end,
74*387f9dfdSAndroid Build Coastguard Worker}