Porting WorkspaceHack to different versions of NeXTstep

The installation procedure needs to know several important addresses from your Workspace application. The WorkspaceHack distribution contains several configuration files to allow for installation on systems with different versions of Workspace. There is one of these files for each Workspace version, and the files have the form config.xxx, where xxx is the version number of Workspace.

The first thing to do is to find out exactly what version of Workspace you have. You can find this out by typing the command

    what /usr/lib/NextStep/Workspace.app/Workspace
    
On my NeXTstep 2.0 system, this command reports

    /usr/lib/NextStep/Workspace.app/Workspace
        dbxxx.s 5.2 (Berkeley) 7/12/85
        PROGRAM:Workspace  PROJECT:workspace-217  DEVELOPER:root  BUILT:Wed Nov 14 01:26:50 PST 1990

The last line reported is the one that tells what version of Workspace you have.  The installation program keys on the number after ªPROJECT:workspace-º. You should make a note of the number your system reports here. Technically speaking, the ªnumberº is all characters up to the first space. On my system, the number is 217. On one tester's NeXTstep 2.2 system, the number is 218.4.

Let's take a look at a configuration file. Here's the file config.217, for my 2.0 system:

    print "Configuring for Workspace version 217\n";
    @my_main   = (0x6538, 0x654c4, 0x654c4, "my_main", 0, "bsr");
    @playsound = (0x270dc, 0x270e4, "\\\"jmp 0x270e4\\\"", "playsound", 0, "jmp");

The first line is only for diagnostic purposes during the installation procedure. The next two lines contain addresses where certain key activities take place in Workspace. This document shows you how to make one of these files for your version of Workspace. Don't worry if you don't understand what the whole procedure means, as long as you know how to follow it. Nothing here can change your system in any way, so if you make a mistake, you won't hurt anything. Start by copying config.217 to config.xxx, where xxx is the number of your Workspace, as determined above.

The first thing we're going to do is find out where Workspace makes its call from _start to _main, because I intercept this call. You can find the start address of Workspace by typing ªotool -l Workspace | tailº in a shell window. The last word on the last line shows the start address. My Workspace starts at 0x64d4. Once you know this, you want to disassemble Workspace starting at this address. Run ªgdb Workspace,º on the original Workspace, and when you get the prompt, say ªx/30i 0x64d4,º substituting your start address.  The second instruction below is the jump to _main in my version:

    0x6532: clrl @#0x40105b0 <errno> 
    0x6538: bsr 0x654c4

I've shown the instruction before the branch because the symbol <errno> makes it a clear landmark to help you distinguish the correct jump to main from all the other bsr's. The numbers on the line containing the bsr will go in the second line of your configuration file. Here's mine:

    @my_main        = (0x6538, 0x654c4, 0x654c4, "my_main", 0, "bsr");

The first number should be the address of the bsr, and the second two are the address the bsr goes to (_main).

The other address you need to know is the one for class Workspace, method emptyTrash:. You can find this by typing to gdb ªbreak emptyTrash:º.  Gdb will first tell you that two classes implement emptyTrash:, and you must pick one. You want to choose Workspace.
Gdb will print the address where it set the breakpoint, but the address gdb prints is actually four bytes greater than what you want, because gdb skips past the frame pointer initialization for some reason. Mine sets the breakpoint at 0x270e0, so I subtract four to get 0x270dc. It's important that you do subtract four from what gdb reports. You might also check the three instructions starting there. Here's a paste from mine:

    (gdb) x/3i 0x270dc 
    0x270dc:        linkw fp,#0
    0x270e0:        moveml #8240,-(sp)
    0x270e4:        movel 8(fp),d2

If your instructions are any different, I'll need to know what they are.  The address of this routine, 0x270dc in this case, tells you how to set the final line in your configuration file. Here's mine:

    @playsound = (0x270dc, 0x270e4, "\\\"jmp 0x270e4\\\"", "playsound", 0, "jmp");

The first address is four less than where gdb set the breakpoint (where you started the disassembly), and the next two addresses (don't forget the one in quotes, after the word jmp) are just the first address + 8. That is, the address of the third instruction. What Install is doing is blasting a jmp instruction over the linkw, and the last thing the new code does before jumping back is execute the two instructions it blew away (it's two because jmp is a 6-byte instruction and the linkw is 4).

If you follow this procedure and get WorkspaceHack working on your system, I'd be very interested receiving a copy of your configuration file, and also what Workspace you have as reported by the ªwhat Workspaceº command that we started with. This information will make life easier for other users of future releases.