aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax99x <max99x@gmail.com>2011-07-20 00:05:17 +0300
committermax99x <max99x@gmail.com>2011-07-20 01:02:26 +0300
commitb27e8bfffe20c043ca2ea100cac99c0a2ba3497d (patch)
tree96685d6f6a776276ff3d0e08e9d4724822042371
parent51df7dfe82125f8772b1c998121fbbf6e3cdab80 (diff)
Added support for extracting struct member names and layout from Dwarf info.
-rw-r--r--src/modules.js54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/modules.js b/src/modules.js
index 89684411..81280988 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -19,6 +19,12 @@ var Debugging = {
var metadataToParentMetadata = {};
var metadataToFilename = {};
+ var structToMemberMeta = {};
+ var memberMetaToStruct = {};
+ var structToSize = {};
+ var memberMetaToMembers = {};
+ var metadataToMember = {};
+
var form1 = new RegExp(/^ .*, !dbg !(\d+) *$/);
var form2 = new RegExp(/^ .*, !dbg !(\d+) *; .*$/);
var form3 = new RegExp(/^!(\d+) = metadata !{i32 (\d+), i32 \d+, metadata !(\d+), .*}$/);
@@ -30,6 +36,9 @@ var Debugging = {
var form4 = new RegExp(/^!llvm.dbg.[\w\.]+ = .*$/);
var form5 = new RegExp(/^!(\d+) = metadata !{.*$/);
var form6 = new RegExp(/^ (tail )?call void \@llvm.dbg.\w+\(metadata .*$/);
+ var formStruct = /^!(\d+) = metadata !\{i32 \d+, metadata !\d+, metadata !"([^"]+)", metadata !\d+, i32 \d+, i64 (\d+), .+?, metadata !(\d+),[^,]*,[^,]*} ; \[ DW_TAG_structure_type \]$/;
+ var formStructMembers = /^!(\d+) = metadata !\{(metadata !\d+(?:, metadata !\d+)*)\}$/;
+ var formMember = /^!(\d+) = metadata !\{i32 \d+, metadata !\d+, metadata !"([^"]+)", metadata !\d+, i32 \d+, i64 (\d+), i64 \d+, i64 (\d+), .+?, metadata !(\d+)} ; \[ DW_TAG_member \]$/;
var debugComment = new RegExp(/; +\[debug line = \d+:\d+\]/);
@@ -43,6 +52,23 @@ var Debugging = {
llvmLineToMetadata[i+1] = calc[1];
return line.replace(', !dbg !' + calc[1], '');
}
+ calc = formStruct.exec(line);
+ if (calc) {
+ memberMetaToStruct[calc[1]] = calc[2];
+ structToSize[calc[2]] = calc[3];
+ structToMemberMeta[calc[2]] = calc[4];
+ return ';';
+ }
+ calc = formStructMembers.exec(line);
+ if (calc) {
+ memberMetaToMembers[calc[1]] = calc[2].match(/\d+/g);
+ return ';';
+ }
+ calc = formMember.exec(line);
+ if (calc) {
+ metadataToMember[calc[1]] = calc.slice(2);
+ return ';';
+ }
calc = form3.exec(line);
if (calc) {
metadataToSourceLine[calc[1]] = calc[2];
@@ -85,6 +111,34 @@ var Debugging = {
this.llvmLineToSourceFile[l] = metadataToFilename[m];
}
+ // Create base struct definitions.
+ Types.structDefinitions = {};
+ for (var structName in structToMemberMeta) {
+ // TODO: Account for bitfields.
+ Types.structDefinitions[structName] = {
+ size: parseInt(structToSize[structName]) / 8,
+ members: {}
+ }
+ }
+ // Fill struct members.
+ for (var structName in structToMemberMeta) {
+ var struct = Types.structDefinitions[structName];
+ var memberIds = memberMetaToMembers[structToMemberMeta[structName]];
+ for (var i = 0; i < memberIds.length; i++) {
+ var member = metadataToMember[memberIds[i]];
+ var memberObj = {
+ size: parseInt(member[1]) / 8,
+ offset: parseInt(member[2]) / 8
+ }
+ dprint(member[3] + " in " + keys(memberMetaToStruct));
+ if (member[3] in memberMetaToStruct) {
+ var subStruct = Types.structDefinitions[memberMetaToStruct[member[3]]];
+ memberObj.members = subStruct.members;
+ }
+ struct.members[member[0]] = memberObj;
+ }
+ }
+
this.on = true;
return ret;