map_object.c (232856) | map_object.c (232974) |
---|---|
1/*- 2 * Copyright 1996-1998 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * | 1/*- 2 * Copyright 1996-1998 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 8 unchanged lines hidden (view full) --- 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * |
25 * $FreeBSD: head/libexec/rtld-elf/map_object.c 232856 2012-03-12 10:36:03Z kib $ | 25 * $FreeBSD: head/libexec/rtld-elf/map_object.c 232974 2012-03-14 15:39:59Z kib $ |
26 */ 27 28#include <sys/param.h> 29#include <sys/mman.h> 30#include <sys/stat.h> 31 32#include <errno.h> 33#include <stddef.h> --- 145 unchanged lines hidden (view full) --- 179 base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); 180 mapsize = base_vlimit - base_vaddr; 181 base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; 182 183 mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | 184 MAP_NOCORE, -1, 0); 185 if (mapbase == (caddr_t) -1) { 186 _rtld_error("%s: mmap of entire address space failed: %s", | 26 */ 27 28#include <sys/param.h> 29#include <sys/mman.h> 30#include <sys/stat.h> 31 32#include <errno.h> 33#include <stddef.h> --- 145 unchanged lines hidden (view full) --- 179 base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); 180 mapsize = base_vlimit - base_vaddr; 181 base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; 182 183 mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | 184 MAP_NOCORE, -1, 0); 185 if (mapbase == (caddr_t) -1) { 186 _rtld_error("%s: mmap of entire address space failed: %s", |
187 path, strerror(errno)); | 187 path, rtld_strerror(errno)); |
188 return NULL; 189 } 190 if (base_addr != NULL && mapbase != base_addr) { 191 _rtld_error("%s: mmap returned wrong address: wanted %p, got %p", 192 path, base_addr, mapbase); 193 munmap(mapbase, mapsize); 194 return NULL; 195 } 196 197 for (i = 0; i <= nsegs; i++) { 198 /* Overlay the segment onto the proper region. */ 199 data_offset = trunc_page(segs[i]->p_offset); 200 data_vaddr = trunc_page(segs[i]->p_vaddr); 201 data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz); 202 data_addr = mapbase + (data_vaddr - base_vaddr); 203 data_prot = convert_prot(segs[i]->p_flags); 204 data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; 205 if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, 206 data_flags, fd, data_offset) == (caddr_t) -1) { | 188 return NULL; 189 } 190 if (base_addr != NULL && mapbase != base_addr) { 191 _rtld_error("%s: mmap returned wrong address: wanted %p, got %p", 192 path, base_addr, mapbase); 193 munmap(mapbase, mapsize); 194 return NULL; 195 } 196 197 for (i = 0; i <= nsegs; i++) { 198 /* Overlay the segment onto the proper region. */ 199 data_offset = trunc_page(segs[i]->p_offset); 200 data_vaddr = trunc_page(segs[i]->p_vaddr); 201 data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz); 202 data_addr = mapbase + (data_vaddr - base_vaddr); 203 data_prot = convert_prot(segs[i]->p_flags); 204 data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; 205 if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, 206 data_flags, fd, data_offset) == (caddr_t) -1) { |
207 _rtld_error("%s: mmap of data failed: %s", path, strerror(errno)); | 207 _rtld_error("%s: mmap of data failed: %s", path, 208 rtld_strerror(errno)); |
208 return NULL; 209 } 210 211 /* Do BSS setup */ 212 if (segs[i]->p_filesz != segs[i]->p_memsz) { 213 214 /* Clear any BSS in the last page of the segment. */ 215 clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; 216 clear_addr = mapbase + (clear_vaddr - base_vaddr); 217 clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); 218 219 if ((nclear = data_vlimit - clear_vaddr) > 0) { 220 /* Make sure the end of the segment is writable */ 221 if ((data_prot & PROT_WRITE) == 0 && -1 == 222 mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { 223 _rtld_error("%s: mprotect failed: %s", path, | 209 return NULL; 210 } 211 212 /* Do BSS setup */ 213 if (segs[i]->p_filesz != segs[i]->p_memsz) { 214 215 /* Clear any BSS in the last page of the segment. */ 216 clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; 217 clear_addr = mapbase + (clear_vaddr - base_vaddr); 218 clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); 219 220 if ((nclear = data_vlimit - clear_vaddr) > 0) { 221 /* Make sure the end of the segment is writable */ 222 if ((data_prot & PROT_WRITE) == 0 && -1 == 223 mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { 224 _rtld_error("%s: mprotect failed: %s", path, |
224 strerror(errno)); | 225 rtld_strerror(errno)); |
225 return NULL; 226 } 227 228 memset(clear_addr, 0, nclear); 229 230 /* Reset the data protection back */ 231 if ((data_prot & PROT_WRITE) == 0) 232 mprotect(clear_page, PAGE_SIZE, data_prot); 233 } 234 235 /* Overlay the BSS segment onto the proper region. */ 236 bss_vaddr = data_vlimit; 237 bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); 238 bss_addr = mapbase + (bss_vaddr - base_vaddr); 239 if (bss_vlimit > bss_vaddr) { /* There is something to do */ 240 if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot, 241 data_flags | MAP_ANON, -1, 0) == (caddr_t)-1) { 242 _rtld_error("%s: mmap of bss failed: %s", path, | 226 return NULL; 227 } 228 229 memset(clear_addr, 0, nclear); 230 231 /* Reset the data protection back */ 232 if ((data_prot & PROT_WRITE) == 0) 233 mprotect(clear_page, PAGE_SIZE, data_prot); 234 } 235 236 /* Overlay the BSS segment onto the proper region. */ 237 bss_vaddr = data_vlimit; 238 bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); 239 bss_addr = mapbase + (bss_vaddr - base_vaddr); 240 if (bss_vlimit > bss_vaddr) { /* There is something to do */ 241 if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot, 242 data_flags | MAP_ANON, -1, 0) == (caddr_t)-1) { 243 _rtld_error("%s: mmap of bss failed: %s", path, |
243 strerror(errno)); | 244 rtld_strerror(errno)); |
244 return NULL; 245 } 246 } 247 } 248 249 if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && 250 (data_vlimit - data_vaddr + data_offset) >= 251 (hdr->e_phoff + hdr->e_phnum * sizeof (Elf_Phdr))) { --- 50 unchanged lines hidden (view full) --- 302{ 303 static union { 304 Elf_Ehdr hdr; 305 char buf[PAGE_SIZE]; 306 } u; 307 ssize_t nbytes; 308 309 if ((nbytes = pread(fd, u.buf, PAGE_SIZE, 0)) == -1) { | 245 return NULL; 246 } 247 } 248 } 249 250 if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && 251 (data_vlimit - data_vaddr + data_offset) >= 252 (hdr->e_phoff + hdr->e_phnum * sizeof (Elf_Phdr))) { --- 50 unchanged lines hidden (view full) --- 303{ 304 static union { 305 Elf_Ehdr hdr; 306 char buf[PAGE_SIZE]; 307 } u; 308 ssize_t nbytes; 309 310 if ((nbytes = pread(fd, u.buf, PAGE_SIZE, 0)) == -1) { |
310 _rtld_error("%s: read error: %s", path, strerror(errno)); | 311 _rtld_error("%s: read error: %s", path, rtld_strerror(errno)); |
311 return NULL; 312 } 313 314 /* Make sure the file is valid */ 315 if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) { 316 _rtld_error("%s: invalid file format", path); 317 return NULL; 318 } --- 121 unchanged lines hidden --- | 312 return NULL; 313 } 314 315 /* Make sure the file is valid */ 316 if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) { 317 _rtld_error("%s: invalid file format", path); 318 return NULL; 319 } --- 121 unchanged lines hidden --- |