This procedure is, in every possible respect, a bad idea. If it eats your firstborn, please don't come crying to me.
You probably don't need a complete backup of your data to do this safely, but you DO, without question, need boot media that has lots of things on it, like dpkg, for when you fry your system. The expected result of this procedure is a machine on which nothing works, where "nothing" includes "ls".
Seriously; the official documentation specifically declares this procedure to be impossible, which should give you some idea of how bad an idea this is.
Sysadmins that have a 32-bit system that they'd really like to be 64-bit without re-doing all their configuration.
This really is for professional-level sysadmins; I don't suggest that anyone who hasn't seen a Debian box through a few manual broken-apt recoveries with dpkg, and libc upgrades, and kernel upgrades, even consider this.
Smart admins do all the config with cfengine, so this isn't an issue, but I didn't know that when I made this machine. :D
To make this work, you MUST have a 64-bit kernel installed. Seriously; you can't imagine how badly you'll fuck your system if you follow these steps without a 64-bit kernel.
If "uname -a" doesn't end with "x86_64 GNU/Linux", stop RIGHT NOW and fix it.
If you don't know how to upgrade your kernel, stop reading this. It's not for you.
To assist possible recovery issues, I strongly suggest apt-getting busybox and running it as a shell ("/bin/busybox ash") in a separate window. Make sure ls and cp and so on work even with PATH=''
Run dpkg --get-selections and save it to a safe place. You'll want to know what you had installed when apt-get starts trying to make shit up.
Since both apt-get and dpkg think you're on an i386 machine, 64-bit kernel or no, you're going to have to get yourself some packages.
Unless the idea of every binary on your system suddenly ceasing to function sounds like your idea of a good time, you're going to need the 32-bit compatibility libraries for amd64, and you're going to need them before you upgrade libc. Start with the ia32-libs package (i.e. http://packages.debian.org/testing/libs/ia32-libs, but replace "testing" with your actual version) and download the amd64 version of it and ALL its dependencies.
You should now have a directory that looks like this:
ia32-libs_1.19_amd64.deb lib32asound2_1.0.14a-1_amd64.deb lib32gcc1_4.2-20070609-1_amd64.deb lib32ncurses5_5.6-3_amd64.deb lib32stdc++6_4.2-20070609-1_amd64.deb lib32z1_1.2.3-15_amd64.deb libc6-i386_2.5-9_amd64.deb lsb-release_3.1-23.1_all.deb
Grab amd64 versions of dpkg, apt-get, and all their dependencies. You may not end up installing them all manually, but having them around can't hurt. Also grap apt-listchanges and apt-utils.
apt_0.6.46.4-0.1_amd64.deb binutils_2.17cvs20070426-8_amd64.deb bzip2_1.0.3-6_amd64.deb coreutils_5.97-5.3_amd64.deb cpio_2.7-3_amd64.deb debianutils_2.21_amd64.deb dpkg_1.14.4_amd64.deb ed_0.2-20_amd64.deb gcc-4.2-base_4.2-20070609-1_amd64.deb libacl1_2.2.42-1_amd64.deb libasound2_1.0.14a-1_amd64.deb libattr1_2.4.32-1.1_amd64.deb libbz2-1.0_1.0.3-6_amd64.deb libc6_2.5-9_amd64.deb libdb4.4_4.4.20-8_amd64.deb libgcc1_4.2-20070609-1_amd64.deb libgdbm3_1.8.3-3_amd64.deb libgpmg1_1.19.6-25_amd64.deb libncurses5_5.6-3_amd64.deb libreadline5_5.2-3_amd64.deb libselinux1_2.0.15-2_amd64.deb libsepol1_2.0.3-1_amd64.deb libstdc++6_4.2-20070609-1_amd64.deb make_3.81-3_amd64.deb ncurses-bin_5.6-3_amd64.deb patch_2.5.9-4_amd64.deb perl-base_5.8.8-7_amd64.deb perl_5.8.8-7_amd64.deb sed_4.1.5-2_amd64.deb
Please note that order is very important. Read everything before starting. If this order doesn't seem eminently sensible to you, you may want to stop here.
First is the install of the 32-bit compat libc. This is the fun step:
dpkg --force-depends --force-architecture --force-overwrite -i libc6-i386_2.5-9_amd64.deb
Yes, you really do need all those. When you're done, /lib/ld-linux.so.2 should be a symlink into /emul/ia32-linux, like this:
lrwxrwxrwx 1 root root 34 Jun 26 08:57 /lib/ld-linux.so.2 -> /emul/ia32-linux/lib/ld-linux.so.2*
If it's not (it wasn't for me) run:
ln -sf /emul/ia32-linux/lib/ld-linux.so.2 /lib/ld-linux.so.2
Check that it worked; there should be lots of stuff in /emul/ia32-linux, and:
$ ls -l /usr/lib32 /lib32 lrwxrwxrwx 1 root root 20 Jun 26 08:56 /lib32 -> /emul/ia32-linux/lib/ lrwxrwxrwx 1 root root 24 Jun 26 08:56 /usr/lib32 -> /emul/ia32-linux/usr/lib/
Run "dpkg --force-architecture -i" for all of the other 32-bit compat libs until they're all installed. Should be uneventful.
While this should be uneventful, I mention it separately because if you're going to fuck your system, this is where it'll happen. Run:
dpkg --force-architecture -i libc6_2.5-9_amd64.deb
If you can still "ls" and such in a non-static shell, congratulations. Now "dpkg --force-architecture -i" the packages for apt-get, dpkg, apt-listchanges, and apt-utils. Then keep trying to run each of apt-get, dpkg, apt-listchanges and apt-extracttemplates until they actually run without erroring.
For apt-listchanges, I had to install (in this order):
python2.4-minimal python2.4 python-apt zlib1g libdb-4.4
That last isn't necessary for getting it to just run, but it was necessary to stop "apt-get -f install" from barfing.
At this point, "dpkg --print-architecture" should say amd64, as should most of "dpkg-architecture" if you have that installed, and "apt-get update" (which you should run) should download a bunch of files to /var/lib/apt/lists that have "amd64" in the name. That's good.
Run "apt-get update" followed by "apt-get -f install". Keep adding packages until "apt-get -f install" doesn't give you any library or ELFCLASS errors.
Having done so, things will probably still be upset, and you may need to do manual dpkg things. Steps I had to take to make "apt-get -f install" run to completion:
dpkg -i /var/cache/apt/archives/libperl5.8_5.8.8-7_amd64.deb
Note that apt-get will Make Shit Up during this process. For example, it tried to give me exim4-daemon-light, which I never had installed (I use exim4-daemon-heavy). This is what the dpkg selections list is for. Hence:
apt-get -f install exim4 exim4-daemon-heavy apache2-mpm-prefork console-tools libconsole
Then there was funkiness because someone broke tex's dependencies. :P
Here's the fun part: catching all the things that haven't been gotten yet. First, make a list of remaining i386 packages:
for package in $(grep '[^e]install' dpkg_get_selections.out | awk '{ print $1 }') do dpkg -s $package | grep -q 'Architecture: i386' && echo $package done >update
Then open up yourself a copy of the update file (so you can fix the many problems that will occur) and run:
apt-get --reinstall install $(cat update | tr '\012' ' ')
Keep editing and running until it works.
If you thought the last step downloaded a lot of packages, you may be surprised by the results of this step.
After all of that's done, you might want to check your currently installed packages for further badness:
for package in $(dpkg -l | grep '^i' | awk '{ print $2 }') do dpkg -s $package | grep -q 'Architecture: i386' && echo $package done >update2
With this list, though, you almost certainly want to remove most or all of them: if they weren't installed as a dependency of the other stuff, you almost certainly don't care. Trim local stuff out (like kernel packages) and run:
dpkg -r $(cat update2 | tr '\012' ' ')
That should pretty much do it.