What is the difference between the 386 and 32 bit options in ld -V?
elf32_x86_64elf_i386i386linuxi386pepi386pe
And, where can I find the documentation on these "emulation modes"
The “emulation” selects different linker scripts; you’ll find the scripts themselves in /usr/lib/ldscripts on your system. The emulations you’ve listed correspond to
elf32_x86_64: ELF for x64-32, aka x32 — 32-bit x86-64 binarieself_i386: ELF for i386 — 32-bit i386 binariesi386linux: a.out for i386i386pep: PE+ for x86-64 — Windows-format 64-bit binariesi386pe: PE for i386 — Windows-format 32-bit binariesThe linker scripts define the output format and architecture, the search directories (where ld looks for libraries), the sections in the binary, among other things.
The linker script format is well documented (see above), but the available scripts aren’t; in most cases GCC will specify the right one, so you don’t need to worry about it, and in other cases you effectively end up needing to read the linker scripts themselves to figure out what they do.
elf_x86_64 in the ld -V output. I believe it is the same thing as the elf64-x86-64 in the objdump -i ouput. Both should mean the 64-bit x86-64 binaries. Please correct me if I am wrong. ldscripts/ information, very useful! However it's not the end of the story. If/when you provide your own linker script like I did then ldscripts/ are ignored, you can move them out and everything still works. Yet even with all ldscripts/ gone (for testing ld), I found there was still a difference between -melf_i386 and -melf_x86_64! Alignment. The ELF output of the former was aligned to be mmapped on 4K pages and the latter on 2M pages. This was with ld.bfd 2.32. ldscripts/ on your system, they're probably built in the executable. You can extract them like this: ld --verbose > default.xc, ld --verbose --melf_x86_64 --nmagic > elf_x86_64.xn, etc.