Page MenuHomeFreeBSD

D34765.id104559.diff
No OneTemporary

D34765.id104559.diff

Index: libexec/rtld-elf/map_object.c
===================================================================
--- libexec/rtld-elf/map_object.c
+++ libexec/rtld-elf/map_object.c
@@ -50,7 +50,7 @@
phdr_in_zero_page(const Elf_Ehdr *hdr)
{
return (hdr->e_phoff + hdr->e_phnum * sizeof(Elf_Phdr) <=
- (size_t)PAGE_SIZE);
+ (size_t)getpagesize());
}
/*
@@ -102,11 +102,14 @@
char *note_map;
size_t note_map_len;
Elf_Addr text_end;
+ size_t pagesz;
hdr = get_elf_header(fd, path, sb, &phdr);
if (hdr == NULL)
return (NULL);
+ pagesz = getpagesize();
+
/*
* Scan the program header entries, and save key information.
* We expect that the loadable segments are ordered by load address.
@@ -134,14 +137,15 @@
case PT_LOAD:
segs[++nsegs] = phdr;
- if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) {
+ if ((segs[nsegs]->p_align & (pagesz - 1)) != 0) {
_rtld_error("%s: PT_LOAD segment %d not page-aligned",
path, nsegs);
goto error;
}
if ((segs[nsegs]->p_flags & PF_X) == PF_X) {
text_end = MAX(text_end,
- round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz));
+ rtld_round_page(segs[nsegs]->p_vaddr +
+ segs[nsegs]->p_memsz));
}
break;
@@ -168,18 +172,18 @@
break;
case PT_NOTE:
- if (phdr->p_offset > PAGE_SIZE ||
- phdr->p_offset + phdr->p_filesz > PAGE_SIZE) {
- note_map_len = round_page(phdr->p_offset +
- phdr->p_filesz) - trunc_page(phdr->p_offset);
+ if (phdr->p_offset > pagesz ||
+ phdr->p_offset + phdr->p_filesz > pagesz) {
+ note_map_len = rtld_round_page(phdr->p_offset +
+ phdr->p_filesz) - rtld_trunc_page(phdr->p_offset);
note_map = mmap(NULL, note_map_len, PROT_READ,
- MAP_PRIVATE, fd, trunc_page(phdr->p_offset));
+ MAP_PRIVATE, fd, rtld_trunc_page(phdr->p_offset));
if (note_map == MAP_FAILED) {
_rtld_error("%s: error mapping PT_NOTE (%d)", path, errno);
goto error;
}
note_start = (Elf_Addr)(note_map + phdr->p_offset -
- trunc_page(phdr->p_offset));
+ rtld_trunc_page(phdr->p_offset));
} else {
note_start = (Elf_Addr)(char *)hdr + phdr->p_offset;
}
@@ -203,13 +207,13 @@
* Map the entire address space of the object, to stake out our
* contiguous region, and to establish the base address for relocation.
*/
- base_vaddr = trunc_page(segs[0]->p_vaddr);
- base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
+ base_vaddr = rtld_trunc_page(segs[0]->p_vaddr);
+ base_vlimit = rtld_round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
mapsize = base_vlimit - base_vaddr;
base_addr = (caddr_t) base_vaddr;
base_flags = __getosreldate() >= P_OSREL_MAP_GUARD ? MAP_GUARD :
MAP_PRIVATE | MAP_ANON | MAP_NOCORE;
- if (npagesizes > 1 && round_page(segs[0]->p_filesz) >= pagesizes[1])
+ if (npagesizes > 1 && rtld_round_page(segs[0]->p_filesz) >= pagesizes[1])
base_flags |= MAP_ALIGNED_SUPER;
if (base_vaddr != 0)
base_flags |= MAP_FIXED | MAP_EXCL;
@@ -228,9 +232,9 @@
for (i = 0; i <= nsegs; i++) {
/* Overlay the segment onto the proper region. */
- data_offset = trunc_page(segs[i]->p_offset);
- data_vaddr = trunc_page(segs[i]->p_vaddr);
- data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz);
+ data_offset = rtld_trunc_page(segs[i]->p_offset);
+ data_vaddr = rtld_trunc_page(segs[i]->p_vaddr);
+ data_vlimit = rtld_round_page(segs[i]->p_vaddr + segs[i]->p_filesz);
data_addr = mapbase + (data_vaddr - base_vaddr);
data_prot = convert_prot(segs[i]->p_flags);
data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED;
@@ -248,12 +252,12 @@
/* Clear any BSS in the last page of the segment. */
clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz;
clear_addr = mapbase + (clear_vaddr - base_vaddr);
- clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr);
+ clear_page = mapbase + (rtld_trunc_page(clear_vaddr) - base_vaddr);
if ((nclear = data_vlimit - clear_vaddr) > 0) {
/* Make sure the end of the segment is writable */
if ((data_prot & PROT_WRITE) == 0 && -1 ==
- mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) {
+ mprotect(clear_page, pagesz, data_prot|PROT_WRITE)) {
_rtld_error("%s: mprotect failed: %s", path,
rtld_strerror(errno));
goto error1;
@@ -263,12 +267,12 @@
/* Reset the data protection back */
if ((data_prot & PROT_WRITE) == 0)
- mprotect(clear_page, PAGE_SIZE, data_prot);
+ mprotect(clear_page, pagesz, data_prot);
}
/* Overlay the BSS segment onto the proper region. */
bss_vaddr = data_vlimit;
- bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz);
+ bss_vlimit = rtld_round_page(segs[i]->p_vaddr + segs[i]->p_memsz);
bss_addr = mapbase + (bss_vaddr - base_vaddr);
if (bss_vlimit > bss_vaddr) { /* There is something to do */
if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot,
@@ -324,14 +328,14 @@
obj->tlsinit = mapbase + phtls->p_vaddr;
}
obj->stack_flags = stack_flags;
- obj->relro_page = obj->relocbase + trunc_page(relro_page);
- obj->relro_size = trunc_page(relro_page + relro_size) -
- trunc_page(relro_page);
+ obj->relro_page = obj->relocbase + rtld_trunc_page(relro_page);
+ obj->relro_size = rtld_trunc_page(relro_page + relro_size) -
+ rtld_trunc_page(relro_page);
if (note_start < note_end)
digest_notes(obj, note_start, note_end);
if (note_map != NULL)
munmap(note_map, note_map_len);
- munmap(hdr, PAGE_SIZE);
+ munmap(hdr, pagesz);
return (obj);
error1:
@@ -341,7 +345,7 @@
munmap(note_map, note_map_len);
if (!phdr_in_zero_page(hdr))
munmap(phdr, hdr->e_phnum * sizeof(phdr[0]));
- munmap(hdr, PAGE_SIZE);
+ munmap(hdr, pagesz);
return (NULL);
}
@@ -384,6 +388,7 @@
{
Elf_Ehdr *hdr;
Elf_Phdr *phdr;
+ size_t pagesz;
/* Make sure file has enough data for the ELF header */
if (sbp != NULL && sbp->st_size < (off_t)sizeof(Elf_Ehdr)) {
@@ -391,7 +396,8 @@
return (NULL);
}
- hdr = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ,
+ pagesz = getpagesize();
+ hdr = mmap(NULL, pagesz, PROT_READ, MAP_PRIVATE | MAP_PREFAULT_READ,
fd, 0);
if (hdr == MAP_FAILED) {
_rtld_error("%s: read error: %s", path, rtld_strerror(errno));
@@ -423,7 +429,7 @@
return (hdr);
error:
- munmap(hdr, PAGE_SIZE);
+ munmap(hdr, pagesz);
return (NULL);
}
Index: libexec/rtld-elf/rtld-libc/rtld_libc.c
===================================================================
--- libexec/rtld-elf/rtld-libc/rtld_libc.c
+++ libexec/rtld-elf/rtld-libc/rtld_libc.c
@@ -116,9 +116,10 @@
mib[0] = CTL_HW;
mib[1] = HW_PAGESIZE;
size = sizeof(value);
- if (sysctl(mib, nitems(mib), &value, &size, NULL, 0) == -1)
- pagesize = PAGE_SIZE;
- else
+ if (sysctl(mib, nitems(mib), &value, &size, NULL, 0) == -1) {
+ _rtld_error("getpagesize: Unknown page size");
+ rtld_die();
+ } else
pagesize = value;
}
Index: libexec/rtld-elf/rtld.h
===================================================================
--- libexec/rtld-elf/rtld.h
+++ libexec/rtld-elf/rtld.h
@@ -376,6 +376,8 @@
/*
* Function declarations.
*/
+uintptr_t rtld_round_page(uintptr_t);
+uintptr_t rtld_trunc_page(uintptr_t);
unsigned long elf_hash(const char *);
const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
const Obj_Entry **, int, SymCache *, struct Struct_RtldLockState *);
Index: libexec/rtld-elf/rtld.c
===================================================================
--- libexec/rtld-elf/rtld.c
+++ libexec/rtld-elf/rtld.c
@@ -477,6 +477,34 @@
ld_elf_hints_path = ld_elf_hints_default;
}
+uintptr_t
+rtld_round_page(uintptr_t x)
+{
+ size_t pagesz;
+
+ pagesz = getpagesize();
+ if (pagesz == 0) {
+ _rtld_error("rtld_round_page: Unknown page size");
+ rtld_die();
+ }
+
+ return (roundup2(x, pagesz));
+}
+
+uintptr_t
+rtld_trunc_page(uintptr_t x)
+{
+ size_t pagesz;
+
+ pagesz = getpagesize();
+ if (pagesz == 0) {
+ _rtld_error("rtld_round_page: Unknown page size");
+ rtld_die();
+ }
+
+ return (rounddown2(x, pagesz));
+}
+
/*
* Main entry point for dynamic linking. The first argument is the
* stack pointer. The stack is expected to be laid out as described
@@ -1647,10 +1675,10 @@
case PT_LOAD:
if (nsegs == 0) { /* First load segment */
- obj->vaddrbase = trunc_page(ph->p_vaddr);
+ obj->vaddrbase = rtld_trunc_page(ph->p_vaddr);
obj->mapbase = obj->vaddrbase + obj->relocbase;
} else { /* Last load segment */
- obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
+ obj->mapsize = rtld_round_page(ph->p_vaddr + ph->p_memsz) -
obj->vaddrbase;
}
nsegs++;
@@ -1674,9 +1702,9 @@
break;
case PT_GNU_RELRO:
- obj->relro_page = obj->relocbase + trunc_page(ph->p_vaddr);
- obj->relro_size = trunc_page(ph->p_vaddr + ph->p_memsz) -
- trunc_page(ph->p_vaddr);
+ obj->relro_page = obj->relocbase + rtld_trunc_page(ph->p_vaddr);
+ obj->relro_size = rtld_trunc_page(ph->p_vaddr + ph->p_memsz) -
+ rtld_trunc_page(ph->p_vaddr);
break;
case PT_NOTE:
@@ -2325,8 +2353,8 @@
break;
case PT_GNU_RELRO:
obj->relro_page = obj->relocbase +
- trunc_page(ph->p_vaddr);
- obj->relro_size = round_page(ph->p_memsz);
+ rtld_trunc_page(ph->p_vaddr);
+ obj->relro_size = rtld_round_page(ph->p_memsz);
break;
case PT_NOTE:
note_start = (Elf_Addr)obj->relocbase + ph->p_vaddr;
@@ -3208,9 +3236,9 @@
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);
+ base = obj->relocbase + rtld_trunc_page(ph->p_vaddr);
+ sz = rtld_round_page(ph->p_vaddr + ph->p_filesz) -
+ rtld_trunc_page(ph->p_vaddr);
prot = before ? (PROT_READ | PROT_WRITE) :
convert_prot(ph->p_flags);
if (mprotect(base, sz, prot) == -1) {

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 10, 11:50 PM (42 m, 13 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38673569
Default Alt Text
D34765.id104559.diff (9 KB)

Event Timeline