diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2026-01-14 12:10:33 -0500 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2026-01-14 12:10:33 -0500 |
| commit | 31a440a0e9a26fee109ed753e3493c72b9dc05e9 (patch) | |
| tree | 63aa9a4ba8e606b6e14c0c43c49bbb6f4cd7749f /libexec | |
| parent | 2a5c5b8f7cddf14537707895fceb454cabc1b3bd (diff) | |
rtld: Simplify walking program headers
Store phnum in Obj_Entry instead of phsize and use that to simplify
the terminate expressions when iterating over program headers.
Reviewed by: kib
Obtained from: CheriBSD
Sponsored by: AFRL, DARPA
Differential Revision: https://reviews.freebsd.org/D54710
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/rtld-elf/map_object.c | 2 | ||||
| -rw-r--r-- | libexec/rtld-elf/powerpc/reloc.c | 4 | ||||
| -rw-r--r-- | libexec/rtld-elf/powerpc64/reloc.c | 4 | ||||
| -rw-r--r-- | libexec/rtld-elf/rtld.c | 18 | ||||
| -rw-r--r-- | libexec/rtld-elf/rtld.h | 2 |
5 files changed, 12 insertions, 18 deletions
diff --git a/libexec/rtld-elf/map_object.c b/libexec/rtld-elf/map_object.c index 5e5774c0b017..6c6f0c9289b9 100644 --- a/libexec/rtld-elf/map_object.c +++ b/libexec/rtld-elf/map_object.c @@ -318,7 +318,7 @@ map_object(int fd, const char *path, const struct stat *sb, bool ismain) phsize); obj->phdr_alloc = true; } - obj->phsize = phsize; + obj->phnum = phsize / sizeof(*phdr); if (phinterp != NULL) obj->interp = (const char *)(obj->relocbase + phinterp->p_vaddr); diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c index c160028cea6d..eb6f50c3c841 100644 --- a/libexec/rtld-elf/powerpc/reloc.c +++ b/libexec/rtld-elf/powerpc/reloc.c @@ -366,9 +366,7 @@ done: * 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++) { + for (phdr = obj->phdr; phdr < obj->phdr + obj->phnum; phdr++) { if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) { __syncicache(obj->relocbase + phdr->p_vaddr, phdr->p_memsz); diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c index 4a4107aef861..a107da6b0a6a 100644 --- a/libexec/rtld-elf/powerpc64/reloc.c +++ b/libexec/rtld-elf/powerpc64/reloc.c @@ -364,9 +364,7 @@ done: * 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++) { + for (phdr = obj->phdr; phdr < obj->phdr + obj->phnum; phdr++) { if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X) != 0) { __syncicache(obj->relocbase + phdr->p_vaddr, phdr->p_memsz); diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 39fb6bc5fb31..7b5f31525853 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -1684,7 +1684,7 @@ digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) continue; obj->phdr = phdr; - obj->phsize = ph->p_memsz; + obj->phnum = ph->p_memsz / sizeof(*ph); obj->relocbase = __DECONST(char *, phdr) - ph->p_vaddr; break; } @@ -2423,8 +2423,7 @@ parse_rtld_phdr(Obj_Entry *obj) first_seg = true; obj->stack_flags = PF_X | PF_R | PF_W; - for (ph = obj->phdr; - (const char *)ph < (const char *)obj->phdr + obj->phsize; ph++) { + for (ph = obj->phdr; ph < obj->phdr + obj->phnum; ph++) { switch (ph->p_type) { case PT_LOAD: if (first_seg) { @@ -2486,7 +2485,7 @@ init_rtld(caddr_t mapbase, Elf_Auxinfo **aux_info) ehdr = (Elf_Ehdr *)mapbase; objtmp.phdr = (Elf_Phdr *)((char *)mapbase + ehdr->e_phoff); - objtmp.phsize = ehdr->e_phnum * sizeof(objtmp.phdr[0]); + objtmp.phnum = ehdr->e_phnum; /* Initialize the object list. */ TAILQ_INIT(&obj_list); @@ -2998,7 +2997,7 @@ load_kpreload(const void *addr) obj = obj_new(); phdr = (const Elf_Phdr *)((const char *)addr + ehdr->e_phoff); obj->phdr = phdr; - obj->phsize = ehdr->e_phnum * sizeof(*phdr); + obj->phnum = ehdr->e_phnum; phlimit = phdr + ehdr->e_phnum; seg0 = segn = NULL; @@ -3380,10 +3379,10 @@ reloc_textrel_prot(Obj_Entry *obj, bool before) { const Elf_Phdr *ph; void *base; - size_t l, sz; + size_t sz; int prot; - for (l = obj->phsize / sizeof(*ph), ph = obj->phdr; l > 0; l--, ph++) { + for (ph = obj->phdr; ph < obj->phdr + obj->phnum; ph++) { if (ph->p_type != PT_LOAD || (ph->p_flags & PF_W) != 0) continue; base = obj->relocbase + rtld_trunc_page(ph->p_vaddr); @@ -4331,7 +4330,7 @@ rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info) phdr_info->dlpi_addr = (Elf_Addr)obj->relocbase; phdr_info->dlpi_name = obj->path; phdr_info->dlpi_phdr = obj->phdr; - phdr_info->dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]); + phdr_info->dlpi_phnum = obj->phnum; phdr_info->dlpi_tls_modid = obj->tlsindex; phdr_info->dlpi_tls_data = (char *)tls_get_addr_slow(_tcb_get(), obj->tlsindex, 0, true); @@ -6149,8 +6148,7 @@ obj_remap_relro(Obj_Entry *obj, int prot) caddr_t relro_page; size_t relro_size; - for (ph = obj->phdr; (const char *)ph < (const char *)obj->phdr + - obj->phsize; ph++) { + for (ph = obj->phdr; ph < obj->phdr + obj->phnum; ph++) { if (ph->p_type != PT_GNU_RELRO) continue; relro_page = obj->relocbase + rtld_trunc_page(ph->p_vaddr); diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h index d4829b17cebb..023e9af9a2a8 100644 --- a/libexec/rtld-elf/rtld.h +++ b/libexec/rtld-elf/rtld.h @@ -152,7 +152,7 @@ typedef struct Struct_Obj_Entry { const Elf_Dyn *dynamic; /* Dynamic section */ caddr_t entry; /* Entry point */ const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */ - size_t phsize; /* Size of program header in bytes */ + size_t phnum; /* Number of program headers */ const char *interp; /* Pathname of the interpreter, if any */ Elf_Word stack_flags; |
