python/xrelfo: cross-platform xrefstructs.json

Just get names, types and order from pahole; ditch offset & size since
they're different on 32/64 bit.  None of the structs has padding
currently;  if we really need that it can be implemented in the future.

(Padding will raise an exception, so it won't break silently.)

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2021-02-14 01:36:09 +01:00
parent 5e085e529d
commit a971f0718d
2 changed files with 19 additions and 67 deletions

View File

@ -52,12 +52,14 @@ def extract(filename='lib/.libs/libfrr.so'):
pastructs = struct_re.findall(pahole) pastructs = struct_re.findall(pahole)
out = {} out = {}
for name, data in pastructs: for sname, data in pastructs:
this = out.setdefault(name, {}) this = out.setdefault(sname, {})
fields = this.setdefault('fields', []) fields = this.setdefault('fields', [])
lines = data.strip().splitlines() lines = data.strip().splitlines()
next_offs = 0
for line in lines: for line in lines:
if line.strip() == '': if line.strip() == '':
continue continue
@ -81,13 +83,16 @@ def extract(filename='lib/.libs/libfrr.so'):
data = { data = {
'name': name, 'name': name,
'type': typ_, 'type': typ_,
'offset': offs, # 'offset': offs,
'size': size, # 'size': size,
} }
if m.group('array'): if m.group('array'):
data['array'] = int(m.group('array')) data['array'] = int(m.group('array'))
fields.append(data) fields.append(data)
if offs != next_offs:
raise ValueError('%d padding bytes before struct %s.%s' % (offs - next_offs, sname, name))
next_offs = offs + size
continue continue
raise ValueError('cannot process line: %s' % line) raise ValueError('cannot process line: %s' % line)
@ -122,7 +127,7 @@ class FieldApplicator(object):
def resolve(self, cls): def resolve(self, cls):
out = [] out = []
offset = 0 #offset = 0
fieldrename = getattr(cls, 'fieldrename', {}) fieldrename = getattr(cls, 'fieldrename', {})
def mkname(n): def mkname(n):
@ -132,9 +137,12 @@ class FieldApplicator(object):
typs = field['type'].split() typs = field['type'].split()
typs = [i for i in typs if i not in ['const']] typs = [i for i in typs if i not in ['const']]
if field['offset'] != offset: # this will break reuse of xrefstructs.json across 32bit & 64bit
assert offset < field['offset'] # platforms
out.append(('_pad', '%ds' % (field['offset'] - offset,)))
#if field['offset'] != offset:
# assert offset < field['offset']
# out.append(('_pad', '%ds' % (field['offset'] - offset,)))
# pretty hacky C types handling, but covers what we need # pretty hacky C types handling, but covers what we need
@ -158,7 +166,7 @@ class FieldApplicator(object):
if typs[1] in self.clsmap: if typs[1] in self.clsmap:
packtype = (self.clsmap[typs[1]],) packtype = (self.clsmap[typs[1]],)
else: else:
packtype = ('%ds' % field['size'],) raise ValueError('embedded struct %s not in extracted data' % (typs[1],))
else: else:
raise ValueError('cannot decode field %s in struct %s (%s)' % ( raise ValueError('cannot decode field %s in struct %s (%s)' % (
cls.struct, field['name'], field['type'])) cls.struct, field['name'], field['type']))
@ -172,7 +180,7 @@ class FieldApplicator(object):
else: else:
out.append(mkname(field['name']) + packtype) out.append(mkname(field['name']) + packtype)
offset = field['offset'] + field['size'] #offset = field['offset'] + field['size']
cls.fields = out cls.fields = out

View File

@ -3,44 +3,30 @@
"fields": [ "fields": [
{ {
"name": "string", "name": "string",
"offset": 0,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "doc", "name": "doc",
"offset": 8,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "daemon", "name": "daemon",
"offset": 16,
"size": 4,
"type": "int" "type": "int"
}, },
{ {
"name": "attr", "name": "attr",
"offset": 20, "type": "uint32_t"
"size": 1,
"type": "uint8_t"
}, },
{ {
"name": "func", "name": "func",
"offset": 24,
"size": 8,
"type": "int *" "type": "int *"
}, },
{ {
"name": "name", "name": "name",
"offset": 32,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "xref", "name": "xref",
"offset": 40,
"size": 32,
"type": "struct xref" "type": "struct xref"
} }
] ]
@ -49,32 +35,22 @@
"fields": [ "fields": [
{ {
"name": "xrefdata", "name": "xrefdata",
"offset": 0,
"size": 8,
"type": "struct xrefdata *" "type": "struct xrefdata *"
}, },
{ {
"name": "type", "name": "type",
"offset": 8,
"size": 4,
"type": "enum xref_type" "type": "enum xref_type"
}, },
{ {
"name": "line", "name": "line",
"offset": 12,
"size": 4,
"type": "int" "type": "int"
}, },
{ {
"name": "file", "name": "file",
"offset": 16,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "func", "name": "func",
"offset": 24,
"size": 8,
"type": "const char *" "type": "const char *"
} }
] ]
@ -83,20 +59,14 @@
"fields": [ "fields": [
{ {
"name": "xref", "name": "xref",
"offset": 0,
"size": 32,
"type": "struct xref" "type": "struct xref"
}, },
{ {
"name": "cmd_element", "name": "cmd_element",
"offset": 32,
"size": 8,
"type": "const struct cmd_element *" "type": "const struct cmd_element *"
}, },
{ {
"name": "node_type", "name": "node_type",
"offset": 40,
"size": 4,
"type": "enum node_type" "type": "enum node_type"
} }
] ]
@ -105,32 +75,22 @@
"fields": [ "fields": [
{ {
"name": "xref", "name": "xref",
"offset": 0,
"size": 32,
"type": "struct xref" "type": "struct xref"
}, },
{ {
"name": "fmtstring", "name": "fmtstring",
"offset": 32,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "priority", "name": "priority",
"offset": 40,
"size": 4,
"type": "uint32_t" "type": "uint32_t"
}, },
{ {
"name": "ec", "name": "ec",
"offset": 44,
"size": 4,
"type": "uint32_t" "type": "uint32_t"
}, },
{ {
"name": "args", "name": "args",
"offset": 48,
"size": 8,
"type": "const char *" "type": "const char *"
} }
] ]
@ -139,26 +99,18 @@
"fields": [ "fields": [
{ {
"name": "xref", "name": "xref",
"offset": 0,
"size": 32,
"type": "struct xref" "type": "struct xref"
}, },
{ {
"name": "funcname", "name": "funcname",
"offset": 32,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "dest", "name": "dest",
"offset": 40,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"name": "thread_type", "name": "thread_type",
"offset": 48,
"size": 4,
"type": "uint32_t" "type": "uint32_t"
} }
] ]
@ -167,28 +119,20 @@
"fields": [ "fields": [
{ {
"name": "xref", "name": "xref",
"offset": 0,
"size": 8,
"type": "const struct xref *" "type": "const struct xref *"
}, },
{ {
"array": 16, "array": 16,
"name": "uid", "name": "uid",
"offset": 8,
"size": 16,
"type": "char" "type": "char"
}, },
{ {
"name": "hashstr", "name": "hashstr",
"offset": 24,
"size": 8,
"type": "const char *" "type": "const char *"
}, },
{ {
"array": 2, "array": 2,
"name": "hashu32", "name": "hashu32",
"offset": 32,
"size": 8,
"type": "uint32_t" "type": "uint32_t"
} }
] ]