diff --git a/web/explorer/src/components/FunctionCapabilities.vue b/web/explorer/src/components/FunctionCapabilities.vue
index c3e9e463a6..bfa170b6e2 100644
--- a/web/explorer/src/components/FunctionCapabilities.vue
+++ b/web/explorer/src/components/FunctionCapabilities.vue
@@ -26,7 +26,7 @@
:showClearButton="false"
>
-
+
{{ data.address }}
@@ -36,9 +36,9 @@
-
+
-
+
{{ data.rule }}
@@ -46,9 +46,9 @@
-
+
-
+
diff --git a/web/explorer/src/components/columns/RuleColumn.vue b/web/explorer/src/components/columns/RuleColumn.vue
index 6c4b1ca2e0..bafad25c38 100644
--- a/web/explorer/src/components/columns/RuleColumn.vue
+++ b/web/explorer/src/components/columns/RuleColumn.vue
@@ -31,7 +31,15 @@
- {{ node.data.typeValue }}:
-
+
{{ node.data.name }}
@@ -63,4 +71,12 @@ defineProps({
required: true
}
});
+
+const getTooltipContent = (data) => {
+ if (data.typeValue === "number" || data.typeValue === "offset") {
+ const decimalValue = parseInt(data.name, 16);
+ return `Decimal: ${decimalValue}`;
+ }
+ return null;
+};
diff --git a/web/explorer/src/utils/rdocParser.js b/web/explorer/src/utils/rdocParser.js
index 8484d25434..46a11e36b0 100644
--- a/web/explorer/src/utils/rdocParser.js
+++ b/web/explorer/src/utils/rdocParser.js
@@ -108,6 +108,9 @@ export function parseFunctionCapabilities(doc) {
// Map to store capabilities matched to each function
const matchesByFunction = new Map();
+ // Add a special entry for file-level matches
+ matchesByFunction.set("file", new Set());
+
// Iterate through all rules in the document
for (const [, rule] of Object.entries(doc.rules)) {
if (rule.meta.scopes.static === "function") {
@@ -133,12 +136,26 @@ export function parseFunctionCapabilities(doc) {
.add({ name: rule.meta.name, namespace: rule.meta.namespace, lib: rule.meta.lib });
}
}
+ } else if (rule.meta.scopes.static === "file") {
+ // Add file-level matches to the special 'file' entry
+ matchesByFunction.get("file").add({
+ name: rule.meta.name,
+ namespace: rule.meta.namespace,
+ lib: rule.meta.lib
+ });
}
- // (else) Ignoring file scope rules
}
const result = [];
+ // Add file-level matches if there are any
+ if (matchesByFunction.get("file").size > 0) {
+ result.push({
+ address: "file",
+ capabilities: Array.from(matchesByFunction.get("file"))
+ });
+ }
+
// Iterate through all functions in the document
for (const f of doc.meta.analysis.feature_counts.functions) {
const addr = formatAddress(f.address);