svn commit: r339876 - head/libexec/rtld-elf
Konstantin Belousov
kostikbel at gmail.com
Fri Nov 2 15:52:45 UTC 2018
On Fri, Nov 02, 2018 at 08:30:17AM -0700, Mark Millard wrote:
> Breakpoint 4, reloc_non_plt (obj=0x41041000, obj_rtld=0x1801cc7, flags=4, lockstate=0x0) at /usr/src/libexec/rtld-elf/powerpc/reloc.c:338
> 338 __syncicache(obj->mapbase + phdr->p_vaddr,
> 1: x/i $pc
> => 0x1012b90 <reloc_non_plt+276>: lwz r0,36(r29)
> (gdb) print/x obj->mapbase+phdr->p_vaddr
> $17 = 0x3000000
> (gdb) print/x obj->mapbase
> $18 = 0x1800000
> (gdb) print/x phdr->p_vaddr
> $19 = 0x1800000
> (gdb) c
> Continuing.
>
> Program received signal SIGSEGV, Segmentation fault.
> __syncicache (from=0x3000000, len=34112) at /usr/src/lib/libc/powerpc/gen/syncicache.c:94
> 94 __asm __volatile ("dcbst 0,%0" :: "r"(p));
> 1: x/i $pc
> => 0x10228b8 <__syncicache+96>: dcbst 0,r11
>
>
>
> It looks to me like the 0x1800000 component of the
> overall figure was double counted. ( phdr->p_vaddr
> would vary but obj->mapbase would not. )
>
> Omit "obj->mapbase + "?
I used the wrong addend. Try this fix.
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index e921a4dc7d1..fae28dd9224 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -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);
}
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index c2d6dac13b1..15f31738ab7 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -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);
}
More information about the svn-src-head
mailing list