diff options
| author | mycroft <mycroft@NetBSD.org> | 2002-10-04 18:50:43 +0000 |
|---|---|---|
| committer | mycroft <mycroft@NetBSD.org> | 2002-10-04 18:50:43 +0000 |
| commit | 6f56cdc91f6f2fa3401a4432102b606b05e1a9be (patch) | |
| tree | f8b048c414c8fcfb585d42e700fec6408d39ef65 /libexec | |
| parent | 7d7701ff68f508648d505f2fc0a6dbc4e08aa204 (diff) | |
Rearrange _rtld_map_object() a little, so that we don't have to have the first
page of the object double-mapped. Not that it matters much, but someone was
whinging about it.
While I'm at it, nuke obj->phdr and obj->phsize; they're unused.
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/headers.c | 4 | ||||
| -rw-r--r-- | libexec/ld.elf_so/map_object.c | 114 | ||||
| -rw-r--r-- | libexec/ld.elf_so/rtld.c | 5 | ||||
| -rw-r--r-- | libexec/ld.elf_so/rtld.h | 6 |
4 files changed, 59 insertions, 70 deletions
diff --git a/libexec/ld.elf_so/headers.c b/libexec/ld.elf_so/headers.c index f58358070ec..c6b004214ce 100644 --- a/libexec/ld.elf_so/headers.c +++ b/libexec/ld.elf_so/headers.c @@ -1,4 +1,4 @@ -/* $NetBSD: headers.c,v 1.15 2002/09/26 20:27:50 mycroft Exp $ */ +/* $NetBSD: headers.c,v 1.16 2002/10/04 18:50:43 mycroft Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -285,8 +285,6 @@ _rtld_digest_phdr(phdr, phnum, entry) case PT_PHDR: assert((const Elf_Phdr *) ph->p_vaddr == phdr); - obj->phdr = (const Elf_Phdr *) ph->p_vaddr; - obj->phsize = ph->p_memsz; break; case PT_INTERP: diff --git a/libexec/ld.elf_so/map_object.c b/libexec/ld.elf_so/map_object.c index a1a55e3a5f0..f7bfc7737db 100644 --- a/libexec/ld.elf_so/map_object.c +++ b/libexec/ld.elf_so/map_object.c @@ -1,4 +1,4 @@ -/* $NetBSD: map_object.c,v 1.21 2002/09/27 19:48:24 mycroft Exp $ */ +/* $NetBSD: map_object.c,v 1.22 2002/10/04 18:50:43 mycroft Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -63,19 +63,18 @@ _rtld_map_object(path, fd, sb) Elf_Phdr *phlimit; Elf_Phdr *segs[2]; int nsegs; - Elf_Phdr *phdyn; - Elf_Phdr *phphdr; - Elf_Phdr *phinterp; - caddr_t mapbase; + caddr_t mapbase = MAP_FAILED; size_t mapsize; Elf_Off base_offset; Elf_Addr base_vaddr; Elf_Addr base_vlimit; Elf_Addr text_vlimit; + int text_flags; caddr_t base_addr; Elf_Off data_offset; Elf_Addr data_vaddr; Elf_Addr data_vlimit; + int data_flags; caddr_t data_addr; caddr_t gap_addr; size_t gap_size; @@ -85,11 +84,18 @@ _rtld_map_object(path, fd, sb) size_t nclear; #endif + obj = _rtld_obj_new(); + obj->path = path; + if (sb != NULL) { + obj->dev = sb->st_dev; + obj->ino = sb->st_ino; + } + ehdr = mmap(NULL, _rtld_pagesz, PROT_READ, MAP_FILE | MAP_SHARED, fd, (off_t)0); if (ehdr == MAP_FAILED) { _rtld_error("%s: read error: %s", path, xstrerror(errno)); - return NULL; + goto bad; } /* Make sure the file is valid */ if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 || @@ -133,11 +139,10 @@ _rtld_map_object(path, fd, sb) phdr = (Elf_Phdr *) ((caddr_t)ehdr + ehdr->e_phoff); phlimit = phdr + ehdr->e_phnum; nsegs = 0; - phdyn = phphdr = phinterp = NULL; while (phdr < phlimit) { switch (phdr->p_type) { case PT_INTERP: - phinterp = phdr; + obj->interp = (void *)phdr->p_vaddr; break; case PT_LOAD: @@ -146,18 +151,15 @@ _rtld_map_object(path, fd, sb) ++nsegs; break; - case PT_PHDR: - phphdr = phdr; - break; - case PT_DYNAMIC: - phdyn = phdr; + obj->dynamic = (void *)phdr->p_vaddr; break; } ++phdr; } - if (phdyn == NULL) { + obj->entry = (void *)ehdr->e_entry; + if (!obj->dynamic) { _rtld_error("%s: not dynamically linked", path); goto bad; } @@ -183,58 +185,62 @@ _rtld_map_object(path, fd, sb) base_vaddr = round_down(segs[0]->p_vaddr); base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz); text_vlimit = round_up(segs[0]->p_vaddr + segs[0]->p_memsz); - mapsize = base_vlimit - base_vaddr; + text_flags = protflags(segs[0]->p_flags); + data_offset = round_down(segs[1]->p_offset); + data_vaddr = round_down(segs[1]->p_vaddr); + data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz); + data_flags = protflags(segs[1]->p_flags); + clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz; + + obj->textsize = text_vlimit - base_vaddr; + obj->vaddrbase = base_vaddr; + obj->isdynamic = ehdr->e_type == ET_DYN; + + munmap(ehdr, _rtld_pagesz); + ehdr = MAP_FAILED; #ifdef RTLD_LOADER - base_addr = ehdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; + base_addr = obj->isdynamic ? NULL : (caddr_t)base_vaddr; #else base_addr = NULL; #endif - - mapbase = mmap(base_addr, mapsize, protflags(segs[0]->p_flags), - MAP_FILE | MAP_PRIVATE, fd, base_offset); + mapsize = base_vlimit - base_vaddr; + mapbase = mmap(base_addr, mapsize, text_flags, MAP_FILE | MAP_PRIVATE, + fd, base_offset); if (mapbase == MAP_FAILED) { _rtld_error("mmap of entire address space failed: %s", xstrerror(errno)); goto bad; } - base_addr = mapbase; - /* Overlay the data segment onto the proper region. */ - data_offset = round_down(segs[1]->p_offset); - data_vaddr = round_down(segs[1]->p_vaddr); - data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz); data_addr = mapbase + (data_vaddr - base_vaddr); - if (mmap(data_addr, data_vlimit - data_vaddr, - protflags(segs[1]->p_flags), - MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, data_offset) - == MAP_FAILED) { + if (mmap(data_addr, data_vlimit - data_vaddr, data_flags, + MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, data_offset) == + MAP_FAILED) { _rtld_error("mmap of data failed: %s", xstrerror(errno)); - goto bad2; + goto bad; } /* Overlay the bss segment onto the proper region. */ if (mmap(mapbase + data_vlimit - base_vaddr, base_vlimit - data_vlimit, - protflags(segs[1]->p_flags), - MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) - == MAP_FAILED) { + data_flags, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) == + MAP_FAILED) { _rtld_error("mmap of bss failed: %s", xstrerror(errno)); - goto bad2; + goto bad; } /* Unmap the gap between the text and data. */ - gap_addr = base_addr + round_up(text_vlimit - base_vaddr); + gap_addr = mapbase + round_up(text_vlimit - base_vaddr); gap_size = data_addr - gap_addr; if (gap_size != 0 && mprotect(gap_addr, gap_size, PROT_NONE) == -1) { _rtld_error("mprotect of text -> data gap failed: %s", xstrerror(errno)); - goto bad2; + goto bad; } #ifdef RTLD_LOADER /* Clear any BSS in the last page of the data segment. */ - clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz; clear_addr = mapbase + (clear_vaddr - base_vaddr); if ((nclear = data_vlimit - clear_vaddr) > 0) memset(clear_addr, 0, nclear); @@ -242,37 +248,25 @@ _rtld_map_object(path, fd, sb) /* Non-file portion of BSS mapped above. */ #endif - obj = _rtld_obj_new(); - obj->path = path; - if (sb != NULL) { - obj->dev = sb->st_dev; - obj->ino = sb->st_ino; - } obj->mapbase = mapbase; obj->mapsize = mapsize; - obj->textsize = round_up(segs[0]->p_vaddr + segs[0]->p_memsz) - - base_vaddr; - obj->vaddrbase = base_vaddr; obj->relocbase = mapbase - base_vaddr; - obj->dynamic = (Elf_Dyn *)(obj->relocbase + phdyn->p_vaddr); - if (ehdr->e_entry != 0) - obj->entry = (caddr_t)(obj->relocbase + ehdr->e_entry); - if (phphdr != NULL) { - obj->phdr = (const Elf_Phdr *) - (obj->relocbase + phphdr->p_vaddr); - obj->phsize = phphdr->p_memsz; - } - if (phinterp != NULL) - obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr); - obj->isdynamic = ehdr->e_type == ET_DYN; - munmap(ehdr, _rtld_pagesz); + if (obj->dynamic) + obj->dynamic = (void *)(obj->relocbase + (Elf_Addr)obj->dynamic); + if (obj->entry) + obj->entry = (void *)(obj->relocbase + (Elf_Addr)obj->entry); + if (obj->interp) + obj->interp = (void *)(obj->relocbase + (Elf_Addr)obj->interp); + return obj; -bad2: - munmap(mapbase, mapsize); bad: - munmap(ehdr, _rtld_pagesz); + if (ehdr != MAP_FAILED) + munmap(ehdr, _rtld_pagesz); + if (mapbase != MAP_FAILED) + munmap(mapbase, mapsize); + _rtld_obj_free(obj); return NULL; } diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index b369929065a..8cf89b6a7dc 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.85 2002/10/04 03:59:41 mycroft Exp $ */ +/* $NetBSD: rtld.c,v 1.86 2002/10/04 18:50:43 mycroft Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -138,14 +138,11 @@ static void _rtld_init(mapbase, relocbase) caddr_t mapbase, relocbase; { - const Elf_Ehdr *hdr = (Elf_Ehdr *) mapbase; - /* Conjure up an Obj_Entry structure for the dynamic linker. */ _rtld_objself.path = _rtld_path; _rtld_objself.rtld = true; _rtld_objself.mapbase = mapbase; _rtld_objself.relocbase = relocbase; - _rtld_objself.phdr = (Elf_Phdr *) (mapbase + hdr->e_phoff); _rtld_objself.dynamic = (Elf_Dyn *) &_DYNAMIC; #ifdef RTLD_RELOCATE_SELF diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h index 5c5928b0f35..d74d993b399 100644 --- a/libexec/ld.elf_so/rtld.h +++ b/libexec/ld.elf_so/rtld.h @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.62 2002/10/03 20:35:20 mycroft Exp $ */ +/* $NetBSD: rtld.h,v 1.63 2002/10/04 18:50:44 mycroft Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -134,8 +134,8 @@ typedef struct Struct_Obj_Entry { caddr_t relocbase; /* Reloc const = mapbase - *vaddrbase */ Elf_Dyn *dynamic; /* Dynamic section */ caddr_t entry; /* Entry point */ - const Elf_Phdr *phdr; /* Program header if mapped, ow NULL */ - size_t phsize; /* Size of program header in bytes */ + const Elf_Phdr *__junk001; + size_t __junk002; /* Items from the dynamic section. */ Elf_Addr *pltgot; /* PLTGOT table */ |
