This is a fascinating topic that I hope to follow up with a more technical blog post. The short summary is that there is room for functions to grow, and if they still exceed the padding, they get moved around to a new location in both virtual memory and in the file. Because of indirect function calls this means callsites remain the same; only the GOT entry has to get updated. The actual function body is moved with the copy_file_range syscall, where available.