FreeBSD/libexec/rtld-elf/rtld.c
/*
 * Prepare for, or clean after, relocating an object marked with
 * DT_TEXTREL or DF_TEXTREL.  Before relocating, all read-only
 * segments are remapped read-write.  After relocations are done, the
 * segment's permissions are returned back to the modes specified in
 * the phdrs.  If any relocation happened, or always for wired
 * program, COW is triggered.
 */
Prepare for, or clean after, relocating an object marked with
DT_TEXTREL or DF_TEXTREL.  Before relocating, all read-only
segments are remapped read-write.  After relocations are done, the
segment's permissions are returned back to the modes specified in
the phdrs.  If any relocation happened, or always for wired
program, COW is triggered.
Prepare for or clean after relocating an object marked with DT_TEXTREL or DF_TEXTREL . Before relocating all read - only segments are remapped read - write . After relocations are done the segment ' s permissions are returned back to the modes specified in the phdrs . If any relocation happened or always for wired program COW is triggered .
static int
reloc_textrel_prot(Obj_Entry *obj, bool before)
{
	const Elf_Phdr *ph;
	void *base;
	size_t l, sz;
	int prot;
	for (l = obj->phsize / sizeof(*ph), ph = obj->phdr; l > 0;
	    l--, ph++) {
		if (ph->p_type != PT_LOAD || (ph->p_flags & PF_W) != 0)
			continue;
		base = obj->relocbase + trunc_page(ph->p_vaddr);
		sz = round_page(ph->p_vaddr + ph->p_filesz) -
		    trunc_page(ph->p_vaddr);
		prot = convert_prot(ph->p_flags) | (before ? PROT_WRITE : 0);
		if (mprotect(base, sz, prot) == -1) {
			_rtld_error("%s: Cannot write-%sable text segment: %s",
			    obj->path, before ? "en" : "dis",
			    rtld_strerror(errno));
			return (-1);
		}
	}
	return (0);
}
static int reloc_textrel_prot ( Obj_Entry * obj , bool before ) { const Elf_Phdr * ph ; void * base ; size_t l , sz ; int prot ; for ( l = obj -> phsize / sizeof ( * ph ) , ph = obj -> phdr ; l > 0 ; l -- , ph ++ ) { if ( ph -> p_type != PT_LOAD || ( ph -> p_flags & PF_W ) != 0 ) continue ; base = obj -> relocbase + trunc_page ( ph -> p_vaddr ) ; sz = round_page ( ph -> p_vaddr + ph -> p_filesz ) - trunc_page ( ph -> p_vaddr ) ; prot = convert_prot ( ph -> p_flags ) | ( before ? PROT_WRITE : 0 ) ; if ( mprotect ( base , sz , prot ) == -1 ) { _rtld_error ( " " , obj -> path , before ? " " : " " , rtld_strerror ( errno ) ) ; return ( -1 ) ; } } return ( 0 ) ; }
Prepare for, or clean after, relocating an object marked with
 DT_TEXTREL or DF_TEXTREL.
Prepare for or clean after relocating an object marked with DT_TEXTREL or DF_TEXTREL .