Flush data cache for executable loadable segments explicitly.

Do not use textsize and do not flush everything between map base and
base + textsize, because unmapped areas cannot be flushed.

This makes Obj_Entry textsize only use go away, and I will remove it
later.

Reported by:	tuexen
Tested by:	Mark Millard <marklmi26-fbsd@yahoo.com>
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
kib 2018-11-03 20:39:16 +00:00
parent c23eecbf56
commit 5b944b1c03
2 changed files with 26 additions and 4 deletions

View File

@ -294,6 +294,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
const Elf_Phdr *phdr;
SymCache *cache;
int r = -1;
@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
if (cache != NULL)
free(cache);
/* Synchronize icache for text seg in case we made any changes */
__syncicache(obj->mapbase, obj->textsize);
/*
* Synchronize icache for executable segments in case we made
* any changes.
*/
for (phdr = obj->phdr;
(const char *)phdr < (const char *)obj->phdr + obj->phsize;
phdr++) {
if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) {
__syncicache(obj->relocbase + phdr->p_vaddr,
phdr->p_memsz);
}
}
return (r);
}

View File

@ -291,6 +291,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
const Elf_Phdr *phdr;
SymCache *cache;
int bytes = obj->dynsymcount * sizeof(SymCache);
int r = -1;
@ -327,8 +328,18 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
if (cache)
munmap(cache, bytes);
/* Synchronize icache for text seg in case we made any changes */
__syncicache(obj->mapbase, obj->textsize);
/*
* Synchronize icache for executable segments in case we made
* any changes.
*/
for (phdr = obj->phdr;
(const char *)phdr < (const char *)obj->phdr + obj->phsize;
phdr++) {
if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) {
__syncicache(obj->relocbase + phdr->p_vaddr,
phdr->p_memsz);
}
}
return (r);
}