The really cool TL;DR here is that courgette "disassembles" the binary before diffing. Basically turning internal references into symbolic references. This way adding an extra instruction to a function won't affect all of the relative addresses in surrounding code.
https://blog.chromium.org/2009/07/smaller-is-faster-and-safe...
The explanation here is pretty fascinating
https://www.chromium.org/developers/design-documents/softwar...