Files

227 lines
6.2 KiB
JavaScript

// SPDX-FileCopyrightText: 2018-2023 Giovanni Dante Grazioli <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause
import _call_common from '../db/macros.js';
import Long from '../long.js';
/**
* Types size
* @type {Object}
*/
const _standard_types = {
'void': 0,
'char': 8,
'short': 16,
'long': 32,
'float': 32,
'long long': 64,
'double': 64,
};
const _magic_math_values = {
"0x069c16bd": 'if there is a right shift of 0, then it\'s a division by 665/25756',
"0x10624dd3": 'if there is a right shift of 4, then it\'s a division by 1/250',
"0x2aaaaaab": 'if there is a right shift of 0, then it\'s a division by 1/6',
"0x30c30c31": 'if there is a right shift of 3, then it\'s a division by 1/42',
"0x38e38e39": 'if there is a right shift of 1, then it\'s a division by 1/9',
"0x4ec4ec4f": 'if there is a right shift of 3, then it\'s a division by 1/26',
"0x51eb851f": 'if there is a right shift of 5, then it\'s a division by 1/100',
"0x55555556": 'if there is a right shift of 0, then it\'s a division by 1/3',
"0x66666667": 'if there is a right shift of 1, then it\'s a division by 1/5',
"0x6bca1af3": 'if there is a right shift of 5, then it\'s a division by 1/76',
"0x88888889": 'if there is a right shift of 8, then it\'s a division by 1/480',
"0x92492493": 'if there is a right shift of 3, then it\'s a division by 1/14',
"0xa0a0a0a1": 'if there is a right shift of 7, then it\'s a division by 1/204',
"0xaaaaaaab": 'if there is a right shift of 1, then it\'s a division by 1/3',
"0xae147ae1": 'if there is a right shift of 5, then it\'s a division by 17/800',
"0xb21642c9": 'if there is a right shift of 5, then it\'s a division by 1/46',
"0xb60b60b7": 'if there is a right shift of 5, then it\'s a division by 1/45',
"0xba2e8ba3": 'if there is a right shift of 3, then it\'s a division by 1/11',
"0xea0ea0eb": 'if there is a right shift of 0, then it\'s a division by 32/35',
};
var _align_address = function(x) {
var zeros32 = '00000000';
var c = x.toString(16);
if (c.length > zeros32.length) {
return '0x' + c;
}
return '0x' + zeros32.substr(c.length, zeros32.length) + c;
};
/**
* Is helpers
* @type {Object}
*/
const _is = {
string: function(s) {
return typeof s == 'string';
},
number: function(s) {
return typeof s == 'number';
},
array: function(s) {
return Array.isArray(s);
},
inObject: function(object, value) {
for (var k in object) {
if (object[k] == value) {
return true;
}
}
return false;
},
};
/**
* To helpers
* @type {Object}
*/
const _to = {
type: function(bits, signed) {
if (bits == 0 || !bits) {
return 'void';
}
return (signed ? 'int' : 'uint') + bits + '_t';
},
bits: function(type) {
var bits = Global().evars.archbits;
type = type.replace(/[un]?signed\s?/, '');
if (type.length == 0) {
type = bits < 32 ? 'int16_t' : 'int32_t';
}
if (_standard_types[type]) {
return _standard_types[type];
}
if (type == 'int') {
return bits < 32 ? 16 : 32;
}
return parseInt(type.replace(/[intu_]/g, ''));
},
array: function(object) {
var a = [];
for (var key in object) {
a.push(object[key]);
}
return a;
},
};
/**
* Find helpers
* @type {Object}
*/
const _find = {
arguments_number: function(name) {
name = _replace.call(name);
if (_call_common[name]) {
return _call_common[name].required;
} else if (Global().argdb) {
var db = Global().argdb;
for (var k in db) {
if (_replace.call(db[k].name.replace(/^_+/, '')) == name) {
if (db[k].count) {
return parseInt(db[k].count.toString());
}
return db[k].args.length;
}
}
}
return -1;
},
call_additional: function(name) {
name = _replace.call(name);
if (_call_common[name]) {
return !!_call_common[name].varargs;
}
return false;
}
};
/**
* Replace helpers
* @type {Object}
*/
const _replace = {
call: function(name) {
if (typeof name != 'string' || name.startsWith('0x')) {
return name;
}
if (name.startsWith('sym.imp.')) {
name = name.substring('sym.imp.'.length).replace(/^_+/, '');
} else if (name.startsWith('sym.')) {
name = name.substring('sym.'.length).replace(/^_+/, '');
} else if (name.startsWith('imp.')) {
name = name.substring('imp.'.length).replace(/^_+/, '');
//} else if (name.startsWith('fcn.')) {
// name = name.substring('fcn.'.length);
//} else if (name.startsWith('func.')) {
// name = name.substring('func.'.length);
}
if (name.startsWith('reloc.')) {
name = name.substring('reloc.'.length).replace(/^_+/, '');
}
name = name.replace(/^sub\./, '');
if (name.match(/^[\w]+\.dll_/)) {
name = name.replace(/[\w]+\.dll_/, '');
}
name = name.replace(/[Mm][Ss][Vv][Cc][Rr][Tt]\.[Dd][Ll][Ll]_/, '');
name = name.replace(/\./g, '_');
return name.replace(/(\w|^):(\w|$)/g, '$1_$2').replace(/_+/g, '_');
},
object: function(name) {
if (typeof name != 'string' || name.startsWith('0x')) {
return name;
}
if (name.startsWith('sym.imp.')) {
name = name.substring('sym.imp.'.length);
} else if (name.startsWith('sym.')) {
name = name.substring('sym.'.length);
} else if (name.startsWith('imp.')) {
name = name.substring('imp.'.length);
//} else if (name.startsWith('fcn.')) {
// name = name.substring('fcn.'.length);
//} else if (name.startsWith('func.')) {
// name = name.substring('func.'.length);
} else if (name.startsWith('reloc.')) {
name = name.substring('reloc.'.length);
}
if (name.startsWith('L') || name.startsWith('[L')) {
// java object
name = name.replace(/\.<init>\(.+$|\(.+$|\._init_.+V$|_L.+$/, '');
name = name.substr(name.startsWith('L') ? 1 : 2).replace(/\/|;->/g, '.').replace(/\s.+$|;$/, '');
if (name.indexOf('_L') > 0) {
name = name.substring(0, name.indexOf('_L'));
}
}
return name;
}
};
const _tryas = {
int: function(x) {
try {
return Long.from(x.trim(), false, (x.trim().indexOf('0x') == 0 ? 16 : 10));
} catch (e) {}
return x;
}
};
/**
* Extra object
* @return {Function} - Extra object
*/
export default {
tryas: _tryas,
is: _is,
to: _to,
find: _find,
replace: _replace,
align_address: _align_address,
magic_math: function(address) {
if (typeof address != 'string') {
address = '0x' + address.toString(16);
}
return _magic_math_values[address];
}
};