5 ms·
It's quite widely used for dynamic library jump tables. When calling a function in a dynamically linked library, it calls a stub, which is initially a call to t
by tlb 7y ago
It's quite widely used for dynamic library jump tables. When calling a function in a dynamically linked library, it calls a stub, which is initially a call to the lazy linker, but gets replaced with a call to the resolved function.
You may be remembering early x86 chips that didn't properly invalidate the instruction cache after a write. Modern chips are fully cache-coherent.
- saagarjha 7y agoThat’s not self modifying code, though; it’s just an indirect jump through a pointer.
- sigjuice 7y agoI don't know much about x86, but on other cpus/architectures (PowerPC, MIPS, and possibly others) one might still need to fiddle with the instruction cache.
- chrisseaton 7y agoOn modern IA32 and AMD64 architectures it involves the instruction cache in the cache protocol, so it's all done for you.
- Taniwha 7y agoYes but it still needs to: a) empty the write buffers into the cache, then b) flush the current instruction stream (in case the CPU has already fetched and decoded instructions from the modified memory) Doing this on every write (especially considering multiple possible virtual to physical mappings) is very expensive in terms of hardware - it's why some architectures (RISC-V for example) have explicit instructions to trigger these things
- matheusmoreira 7y agoThis is interesting. I've read documentation about dynamic linking and it describes this replacement process but I never truly understood the fact it was self-modifying code. Doesn't this imply the program's code is writable? I know that JIT compilers also emit code into writable and executable pages. Aren't there security implications?
- saagarjha 7y agoThere are. That’s why dynamic linking typically doesn’t use self-modifying code and JIT compilers take a number of precautions to prevent attackers from being able to execute arbitrary code.