|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var mod_assert = require('assert'); |
|
|
var ASSERT = mod_assert.ok; |
|
|
|
|
|
var ctf_versions = [ '1.0' ]; |
|
|
var ctf_entries = [ 'integer', 'float', 'typedef', 'struct' ]; |
|
|
var ctf_deftypes = [ 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', |
|
|
'uint32_t', 'float', 'double' ]; |
|
|
|
|
|
function ctfParseInteger(entry, ctype) |
|
|
{ |
|
|
var name, sign, len, type; |
|
|
|
|
|
name = entry['name']; |
|
|
if (!('signed' in entry['integer'])) |
|
|
throw (new Error('Malformed CTF JSON: integer missing ' + |
|
|
'signed value')); |
|
|
|
|
|
|
|
|
if (!('length' in entry['integer'])) |
|
|
throw (new Error('Malformed CTF JSON: integer missing ' + |
|
|
'length value')); |
|
|
|
|
|
sign = entry['integer']['signed']; |
|
|
len = entry['integer']['length']; |
|
|
type = null; |
|
|
|
|
|
if (sign && len == 1) |
|
|
type = 'int8_t'; |
|
|
else if (len == 1) |
|
|
type = 'uint8_t'; |
|
|
else if (sign && len == 2) |
|
|
type = 'int16_t'; |
|
|
else if (len == 2) |
|
|
type = 'uint16_t'; |
|
|
else if (sign && len == 4) |
|
|
type = 'int32_t'; |
|
|
else if (len == 4) |
|
|
type = 'uint32_t'; |
|
|
else if (sign && len == 8) |
|
|
type = 'int64_t'; |
|
|
else if (len == 8) |
|
|
type = 'uint64_t'; |
|
|
|
|
|
if (type === null) |
|
|
throw (new Error('Malformed CTF JSON: integer has ' + |
|
|
'unsupported length and sign - ' + len + '/' + sign)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (name == type) |
|
|
return; |
|
|
|
|
|
if (name == 'char') { |
|
|
ASSERT(type == 'int8_t'); |
|
|
return; |
|
|
} |
|
|
|
|
|
ctype.typedef(name, type); |
|
|
} |
|
|
|
|
|
function ctfParseFloat(entry, ctype) |
|
|
{ |
|
|
var name, len; |
|
|
|
|
|
name = entry['name']; |
|
|
if (!('length' in entry['float'])) |
|
|
throw (new Error('Malformed CTF JSON: float missing ' + |
|
|
'length value')); |
|
|
|
|
|
len = entry['float']['length']; |
|
|
if (len != 4 && len != 8) |
|
|
throw (new Error('Malformed CTF JSON: float has invalid ' + |
|
|
'length value')); |
|
|
|
|
|
if (len == 4) { |
|
|
if (name == 'float') |
|
|
return; |
|
|
ctype.typedef(name, 'float'); |
|
|
} else if (len == 8) { |
|
|
if (name == 'double') |
|
|
return; |
|
|
ctype.typedef(name, 'double'); |
|
|
} |
|
|
} |
|
|
|
|
|
function ctfParseTypedef(entry, ctype) |
|
|
{ |
|
|
var name, type, ii; |
|
|
|
|
|
name = entry['name']; |
|
|
if (typeof (entry['typedef']) != 'string') |
|
|
throw (new Error('Malformed CTF JSON: typedef value in not ' + |
|
|
'a string')); |
|
|
|
|
|
type = entry['typedef']; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (ii = 0; ii < ctf_deftypes.length; ii++) { |
|
|
if (name == ctf_deftypes[ii]) |
|
|
return; |
|
|
} |
|
|
|
|
|
ctype.typedef(name, type); |
|
|
} |
|
|
|
|
|
function ctfParseStruct(entry, ctype) |
|
|
{ |
|
|
var name, type, ii, val, index, member, push; |
|
|
|
|
|
member = []; |
|
|
if (!Array.isArray(entry['struct'])) |
|
|
throw (new Error('Malformed CTF JSON: struct value is not ' + |
|
|
'an array')); |
|
|
|
|
|
for (ii = 0; ii < entry['struct'].length; ii++) { |
|
|
val = entry['struct'][ii]; |
|
|
if (!('name' in val)) |
|
|
throw (new Error('Malformed CTF JSON: struct member ' + |
|
|
'missing name')); |
|
|
|
|
|
if (!('type' in val)) |
|
|
throw (new Error('Malformed CTF JSON: struct member ' + |
|
|
'missing type')); |
|
|
|
|
|
if (typeof (val['name']) != 'string') |
|
|
throw (new Error('Malformed CTF JSON: struct member ' + |
|
|
'name isn\'t a string')); |
|
|
|
|
|
if (typeof (val['type']) != 'string') |
|
|
throw (new Error('Malformed CTF JSON: struct member ' + |
|
|
'type isn\'t a string')); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
name = val['name']; |
|
|
type = val['type']; |
|
|
index = type.indexOf(' ['); |
|
|
if (index != -1) { |
|
|
type = type.substring(0, index) + |
|
|
type.substring(index + 1, type.length); |
|
|
} |
|
|
push = {}; |
|
|
push[name] = { 'type': type }; |
|
|
member.push(push); |
|
|
} |
|
|
|
|
|
name = entry['name']; |
|
|
ctype.typedef(name, member); |
|
|
} |
|
|
|
|
|
function ctfParseEntry(entry, ctype) |
|
|
{ |
|
|
var ii, found; |
|
|
|
|
|
if (!('name' in entry)) |
|
|
throw (new Error('Malformed CTF JSON: entry missing "name" ' + |
|
|
'section')); |
|
|
|
|
|
for (ii = 0; ii < ctf_entries.length; ii++) { |
|
|
if (ctf_entries[ii] in entry) |
|
|
found++; |
|
|
} |
|
|
|
|
|
if (found === 0) |
|
|
throw (new Error('Malformed CTF JSON: found no entries')); |
|
|
|
|
|
if (found >= 2) |
|
|
throw (new Error('Malformed CTF JSON: found more than one ' + |
|
|
'entry')); |
|
|
|
|
|
if ('integer' in entry) { |
|
|
ctfParseInteger(entry, ctype); |
|
|
return; |
|
|
} |
|
|
|
|
|
if ('float' in entry) { |
|
|
ctfParseFloat(entry, ctype); |
|
|
return; |
|
|
} |
|
|
|
|
|
if ('typedef' in entry) { |
|
|
ctfParseTypedef(entry, ctype); |
|
|
return; |
|
|
} |
|
|
|
|
|
if ('struct' in entry) { |
|
|
ctfParseStruct(entry, ctype); |
|
|
return; |
|
|
} |
|
|
|
|
|
ASSERT(false, 'shouldn\'t reach here'); |
|
|
} |
|
|
|
|
|
function ctfParseJson(json, ctype) |
|
|
{ |
|
|
var version, ii; |
|
|
|
|
|
ASSERT(json); |
|
|
ASSERT(ctype); |
|
|
if (!('metadata' in json)) |
|
|
throw (new Error('Invalid CTF JSON: missing metadata section')); |
|
|
|
|
|
if (!('ctf2json_version' in json['metadata'])) |
|
|
throw (new Error('Invalid CTF JSON: missing ctf2json_version')); |
|
|
|
|
|
version = json['metadata']['ctf2json_version']; |
|
|
for (ii = 0; ii < ctf_versions.length; ii++) { |
|
|
if (ctf_versions[ii] == version) |
|
|
break; |
|
|
} |
|
|
|
|
|
if (ii == ctf_versions.length) |
|
|
throw (new Error('Unsuported ctf2json_version: ' + version)); |
|
|
|
|
|
if (!('data' in json)) |
|
|
throw (new Error('Invalid CTF JSON: missing data section')); |
|
|
|
|
|
if (!Array.isArray(json['data'])) |
|
|
throw (new Error('Malformed CTF JSON: data section is not ' + |
|
|
'an array')); |
|
|
|
|
|
for (ii = 0; ii < json['data'].length; ii++) |
|
|
ctfParseEntry(json['data'][ii], ctype); |
|
|
} |
|
|
|
|
|
exports.ctfParseJson = ctfParseJson; |
|
|
|