Relocation processing turns symbol-based references into concrete runtime values. ivss's linker adjusts records while merging objects; the emulator's loader applies their patches. It computes the referenced value as follows:
Elf_Addr value = symb->st_value; value += rela->r_addend; if (symb->st_shndx != SHN_ABS) { Elf_PushSection(elf); Elf_Shdr *sym_shdr = Elf_SetSection(elf, symb->st_shndx); value += sym_shdr->sh_addr; Elf_PopSection(elf); }
A section-defined symbol needs its section's base address added. An absolute symbol already has its final value, so that addition is skipped. The relocation addend applies in both cases.
For R_SS_32, the loader writes the result as a word at the relocation's target offset. Expanded-load relocations instead distribute it through the bytes of an instruction sequence.
This explains why linked serialized bytes can still contain placeholders. The effective memory image differs after loading. A successful check should examine the program's loaded behavior or memory, rather than assume that every reference has already been patched in the linker's output file.
Source: emulator.c.