50 lines
1.3 KiB
JavaScript
Executable file
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));
|
|
}
|