tree-sitter/script/show-symbol-sizes

50 lines
1.3 KiB
JavaScript
Executable file

#!/usr/bin/env node
const {statSync} = require('fs');
const {execFileSync} = require('child_process');
const libPath = process.argv[2];
if (!libPath || libPath === '--help') {
console.log(`Usage: ${process.argv[1]} <dylib-path>`);
process.exit(0)
}
// Get total file size
const totalSize = statSync(libPath).size
// Dump symbols with addresses
const output = execFileSync(
'nm',
['-t', 'd', libPath],
{encoding: 'utf8'}
);
// Parse addresses
const addressEntries = [];
for (const line of output.split('\n')) {
const [address, _, name] = line.split(/\s+/);
if (address && name) {
addressEntries.push({name, address: parseInt(address)})
}
}
// Compute sizes by subtracting addresses
addressEntries.sort((a, b) => a.address - b.address);
const sizeEntries = addressEntries.map(({name, address}, i) => {
const next = addressEntries[i + 1] ? addressEntries[i + 1].address : totalSize;
const size = next - address;
return {name, size}
})
function formatSize(sizeInBytes) {
return sizeInBytes > 1024
? `${(sizeInBytes / 1024).toFixed(1)} kb`
: `${sizeInBytes} b`
}
// Display sizes
sizeEntries.sort((a, b) => b.size - a.size);
console.log('total'.padEnd(64, ' '), '\t', formatSize(totalSize));
for (const entry of sizeEntries) {
console.log(entry.name.padEnd(64, ' '), '\t', formatSize(entry.size));
}