Friday, January 12, 2007

Dumbing it down - the threaded fixup UnOptimizer

A while ago I wrote about my threaded fixup optimizer.

No sooner had it been out of the gates when another issue surfaced. It seems Borland's TLINK linker is somewhat profoundly retarded when it comes to threaded fixups. Big splats, blood/gore all over the place and disfunctional EXE's result when TLINK tried to link something with threaded fixups.

Apparently Borland never cared much about this because their own language products don't generate threaded fixups, and they generally disavowed support for anyone trying to mix-n-match modules from different vendors. Case closed. Tough luck. You lose. End of story.

Of course, this situation comes up ALL THE TIME when people try to recycle legacy code into new projects. As a practical matter, few organizations can afford to throw away millions of dollars worth of code and bought libraries of functions just because its "old". In the real world, maintenance programmers have to "deal with it" and make the old stuff work. The shiny new stuff someone is working on today will become "legacy code" next year ;->

This leaves people trying to integrate bits of code from other languages and products having to use the Microsoft LINK or some other 3rd party linker that does handle threaded fixups correctly. This was/is not always a satisfactory choice if your main blob of code was Borland and you want to use Turbo Debugger, which is/was a pretty damn good debugger. Other vendor's linkers aren't going to always support the TD debug format and you're likely be left trying to debug stuff at the assembler level because the foreign linker didn't create the TD symbolic debug infos. Very very unsatisfactory.

The solution to TLINK's ill mannered threaded fixup handling?

A threaded fixup UnOptimizer that eliminates threaded fixups and replaces them with their explicit equivalents. Sure, the OBJ porks up some, but now TLINK will be able to handle it and keep the symbolic debug info intact for Borland stuff.


It seems Microsoft compilers aren't very smart about choosing what to generate threaded fixups for when they do it. I've observed that UnOptimizing a Microsoft compiled OBJ and then ReOptimizing it with my stuff makes the OBJ smaller. It looks like Microsoft just picked a "standard" set of segment/group names to generate threaded fixups for and didn't bother actually performing an instance count to see which combination of things would provide the best payoff.


In fact its even worse with the Microsoft compilers. I've just proven they're wasting space on fixup thread definition records even when a particular OBJ doesn't even have any fixups in it that use'em.

My tool removes those superfluous definition records too ;->

No comments: