A common mistake many developers do is to leave names of local symbols inside applications built on OS X. Using the strip utility combined with the compiler visibility flags is, unfortunately, not enough.
So I wrote a small script for Profiler to be run from the command line and I integrated it in the build process.
The syntax to execute the script is:
cerpro -c -r path/to/strip.py:stripMachO source destination
Here’s the whole code:
# name: strip.py
from Pro.Core import *
from Pro.MachO import *
def stripMachO(srcname, dstname):
oldc = createContainerFromFile(srcname)
if oldc.isNull():
print("error: couldn't open '%s'" % (srcname,))
return
obj = MachObject()
if not obj.Load(oldc):
print("error: could't load Mach-o")
return
obj.ProcessLoadCommands()
newc = oldc.copyToNewContainer()
symlc = obj.SymTableLC()
stroffs = symlc.Num("stroff")
it = obj.SymbolNList(symlc).iterator()
while it.hasNext():
syms = it.next()
# only local symbols
if syms.Num("sect") == 0:
continue
nameoffs = obj.AddressToOffset(syms.Num("strx") + stroffs)
name, ret = obj.ReadUInt8String(nameoffs, 0x10000)
newc.fill(nameoffs, 0, len(name))
if newc.save(dstname):
print("successfully stripped all local symbols!")
else:
print("error: couldn't save stripped binary to '%s'" % (dstname,))
The code zeroes names of symbols which are not associated to any section in the binary.
Easy. 🙂