Cleaned up the page alignment macros, incorporated NewOS fix #2022
(but with the correct semantics). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8934 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
04a280790e
commit
82b76be31e
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "rld_priv.h"
|
#include "rld_priv.h"
|
||||||
|
|
||||||
#define TRACE_RLD
|
//#define TRACE_RLD
|
||||||
#ifdef TRACE_RLD
|
#ifdef TRACE_RLD
|
||||||
# define TRACE(x) dprintf x
|
# define TRACE(x) dprintf x
|
||||||
#else
|
#else
|
||||||
@ -42,12 +42,10 @@
|
|||||||
// ToDo: implement lazy binding
|
// ToDo: implement lazy binding
|
||||||
|
|
||||||
#define PAGE_MASK (B_PAGE_SIZE - 1)
|
#define PAGE_MASK (B_PAGE_SIZE - 1)
|
||||||
#define PAGE_OFFS(y) ((y) & (PAGE_MASK))
|
|
||||||
#define PAGE_BASE(y) ((y) & ~(PAGE_MASK))
|
|
||||||
|
|
||||||
/* david - added '_' to avoid macro's in kernel.h */
|
#define PAGE_OFFSET(x) ((x) & (PAGE_MASK))
|
||||||
#define _ROUNDOWN(x,y) ((x)&~((y)-1))
|
#define PAGE_BASE(x) ((x) & ~(PAGE_MASK))
|
||||||
#define _ROUNDUP(x,y) ROUNDOWN(x+y-1,y)
|
#define TO_PAGE_SIZE(x) ((x + (PAGE_MASK)) & ~(PAGE_MASK))
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -311,12 +309,9 @@ count_regions(char const *buff, int phnum, int phentsize)
|
|||||||
break;
|
break;
|
||||||
case PT_LOAD:
|
case PT_LOAD:
|
||||||
retval += 1;
|
retval += 1;
|
||||||
if (pheaders->p_memsz!= pheaders->p_filesz) {
|
if (pheaders->p_memsz != pheaders->p_filesz) {
|
||||||
unsigned A = pheaders->p_vaddr + pheaders->p_memsz;
|
addr_t A = TO_PAGE_SIZE(pheaders->p_vaddr + pheaders->p_memsz);
|
||||||
unsigned B = pheaders->p_vaddr + pheaders->p_filesz - 1;
|
addr_t B = TO_PAGE_SIZE(pheaders->p_vaddr + pheaders->p_filesz);
|
||||||
|
|
||||||
A = PAGE_BASE(A);
|
|
||||||
B = PAGE_BASE(B);
|
|
||||||
|
|
||||||
if (A != B)
|
if (A != B)
|
||||||
retval += 1;
|
retval += 1;
|
||||||
@ -411,9 +406,9 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
*/
|
*/
|
||||||
image->regions[regcount].start = pheader->p_vaddr;
|
image->regions[regcount].start = pheader->p_vaddr;
|
||||||
image->regions[regcount].size = pheader->p_memsz;
|
image->regions[regcount].size = pheader->p_memsz;
|
||||||
image->regions[regcount].vmstart = _ROUNDOWN(pheader->p_vaddr, B_PAGE_SIZE);
|
image->regions[regcount].vmstart = PAGE_BASE(pheader->p_vaddr);
|
||||||
image->regions[regcount].vmsize = _ROUNDUP(pheader->p_memsz +
|
image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_memsz
|
||||||
(pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
|
+ PAGE_OFFSET(pheader->p_vaddr));
|
||||||
image->regions[regcount].fdstart = pheader->p_offset;
|
image->regions[regcount].fdstart = pheader->p_offset;
|
||||||
image->regions[regcount].fdsize = pheader->p_filesz;
|
image->regions[regcount].fdsize = pheader->p_filesz;
|
||||||
image->regions[regcount].delta = 0;
|
image->regions[regcount].delta = 0;
|
||||||
@ -426,17 +421,14 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
/*
|
/*
|
||||||
* may require splitting
|
* may require splitting
|
||||||
*/
|
*/
|
||||||
unsigned A = pheader->p_vaddr + pheader->p_memsz;
|
addr_t A = TO_PAGE_SIZE(pheader->p_vaddr + pheader->p_memsz);
|
||||||
unsigned B = pheader->p_vaddr + pheader->p_filesz - 1;
|
addr_t B = TO_PAGE_SIZE(pheader->p_vaddr + pheader->p_filesz);
|
||||||
|
|
||||||
A = PAGE_BASE(A);
|
|
||||||
B = PAGE_BASE(B);
|
|
||||||
|
|
||||||
image->regions[regcount].start = pheader->p_vaddr;
|
image->regions[regcount].start = pheader->p_vaddr;
|
||||||
image->regions[regcount].size = pheader->p_filesz;
|
image->regions[regcount].size = pheader->p_filesz;
|
||||||
image->regions[regcount].vmstart = _ROUNDOWN(pheader->p_vaddr, B_PAGE_SIZE);
|
image->regions[regcount].vmstart = PAGE_BASE(pheader->p_vaddr);
|
||||||
image->regions[regcount].vmsize = _ROUNDUP (pheader->p_filesz +
|
image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_filesz
|
||||||
(pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE);
|
+ PAGE_OFFSET(pheader->p_vaddr));
|
||||||
image->regions[regcount].fdstart = pheader->p_offset;
|
image->regions[regcount].fdstart = pheader->p_offset;
|
||||||
image->regions[regcount].fdsize = pheader->p_filesz;
|
image->regions[regcount].fdsize = pheader->p_filesz;
|
||||||
image->regions[regcount].delta = 0;
|
image->regions[regcount].delta = 0;
|
||||||
@ -454,8 +446,7 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
image->regions[regcount].start = pheader->p_vaddr;
|
image->regions[regcount].start = pheader->p_vaddr;
|
||||||
image->regions[regcount].size = pheader->p_memsz - pheader->p_filesz;
|
image->regions[regcount].size = pheader->p_memsz - pheader->p_filesz;
|
||||||
image->regions[regcount].vmstart = image->regions[regcount-1].vmstart + image->regions[regcount-1].vmsize;
|
image->regions[regcount].vmstart = image->regions[regcount-1].vmstart + image->regions[regcount-1].vmsize;
|
||||||
image->regions[regcount].vmsize = _ROUNDUP(pheader->p_memsz
|
image->regions[regcount].vmsize = TO_PAGE_SIZE(pheader->p_memsz + PAGE_OFFSET(pheader->p_vaddr))
|
||||||
+ (pheader->p_vaddr % B_PAGE_SIZE), B_PAGE_SIZE)
|
|
||||||
- image->regions[regcount-1].vmsize;
|
- image->regions[regcount-1].vmsize;
|
||||||
image->regions[regcount].fdstart = 0;
|
image->regions[regcount].fdstart = 0;
|
||||||
image->regions[regcount].fdsize = 0;
|
image->regions[regcount].fdsize = 0;
|
||||||
@ -495,7 +486,7 @@ parse_program_headers(image_t *image, char *buff, int phnum, int phentsize)
|
|||||||
static bool
|
static bool
|
||||||
assert_dynamic_loadable(image_t *image)
|
assert_dynamic_loadable(image_t *image)
|
||||||
{
|
{
|
||||||
unsigned i;
|
uint32 i;
|
||||||
|
|
||||||
if (!image->dynamic_ptr)
|
if (!image->dynamic_ptr)
|
||||||
return true;
|
return true;
|
||||||
@ -513,14 +504,14 @@ assert_dynamic_loadable(image_t *image)
|
|||||||
static bool
|
static bool
|
||||||
map_image(int fd, char const *path, image_t *image, bool fixed)
|
map_image(int fd, char const *path, image_t *image, bool fixed)
|
||||||
{
|
{
|
||||||
unsigned i;
|
uint32 i;
|
||||||
|
|
||||||
(void)(fd);
|
(void)(fd);
|
||||||
|
|
||||||
for (i = 0; i < image->num_regions; i++) {
|
for (i = 0; i < image->num_regions; i++) {
|
||||||
char regionName[B_OS_NAME_LENGTH];
|
char regionName[B_OS_NAME_LENGTH];
|
||||||
addr_t load_address;
|
addr_t loadAddress;
|
||||||
unsigned addr_specifier;
|
uint32 addressSpecifier;
|
||||||
|
|
||||||
// for BeOS compatibility: if we load an old BeOS executable, we
|
// for BeOS compatibility: if we load an old BeOS executable, we
|
||||||
// have to relocate it, if possible - we recognize it because the
|
// have to relocate it, if possible - we recognize it because the
|
||||||
@ -528,7 +519,7 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
if (fixed && image->regions[i].vmstart == 0)
|
if (fixed && image->regions[i].vmstart == 0)
|
||||||
fixed = false;
|
fixed = false;
|
||||||
|
|
||||||
snprintf(regionName, sizeof(regionName), "%s_seg%d%s",
|
snprintf(regionName, sizeof(regionName), "%s_seg%lu%s",
|
||||||
path, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
|
path, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
|
||||||
|
|
||||||
if (image->dynamic_ptr && !fixed) {
|
if (image->dynamic_ptr && !fixed) {
|
||||||
@ -539,59 +530,58 @@ map_image(int fd, char const *path, image_t *image, bool fixed)
|
|||||||
/*
|
/*
|
||||||
* but only the first segment gets a free ride
|
* but only the first segment gets a free ride
|
||||||
*/
|
*/
|
||||||
load_address = 0;
|
loadAddress = 0;
|
||||||
addr_specifier = B_ANY_ADDRESS;
|
addressSpecifier = B_ANY_ADDRESS;
|
||||||
} else {
|
} else {
|
||||||
load_address = image->regions[i].vmstart + image->regions[i-1].delta;
|
loadAddress = image->regions[i].vmstart + image->regions[i-1].delta;
|
||||||
addr_specifier = B_EXACT_ADDRESS;
|
addressSpecifier = B_EXACT_ADDRESS;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* not relocatable, put it where it asks or die trying
|
* not relocatable, put it where it asks or die trying
|
||||||
*/
|
*/
|
||||||
load_address = image->regions[i].vmstart;
|
loadAddress = image->regions[i].vmstart;
|
||||||
addr_specifier = B_EXACT_ADDRESS;
|
addressSpecifier = B_EXACT_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->regions[i].flags & RFLAG_ANON) {
|
if (image->regions[i].flags & RFLAG_ANON) {
|
||||||
image->regions[i].id = _kern_create_area(regionName, (void **)&load_address,
|
image->regions[i].id = _kern_create_area(regionName, (void **)&loadAddress,
|
||||||
addr_specifier, image->regions[i].vmsize, B_NO_LOCK,
|
addressSpecifier, image->regions[i].vmsize, B_NO_LOCK,
|
||||||
B_READ_AREA | B_WRITE_AREA);
|
B_READ_AREA | B_WRITE_AREA);
|
||||||
|
|
||||||
if (image->regions[i].id < 0)
|
if (image->regions[i].id < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
image->regions[i].delta = loadAddress - image->regions[i].vmstart;
|
||||||
image->regions[i].vmstart = load_address;
|
image->regions[i].vmstart = loadAddress;
|
||||||
} else {
|
} else {
|
||||||
image->regions[i].id = sys_vm_map_file(regionName, (void **)&load_address,
|
image->regions[i].id = sys_vm_map_file(regionName, (void **)&loadAddress,
|
||||||
addr_specifier, image->regions[i].vmsize, B_READ_AREA | B_WRITE_AREA,
|
addressSpecifier, image->regions[i].vmsize, B_READ_AREA | B_WRITE_AREA,
|
||||||
REGION_PRIVATE_MAP, path,
|
REGION_PRIVATE_MAP, path, PAGE_BASE(image->regions[i].fdstart));
|
||||||
_ROUNDOWN(image->regions[i].fdstart, B_PAGE_SIZE));
|
|
||||||
|
|
||||||
if (image->regions[i].id < 0)
|
if (image->regions[i].id < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
TRACE(("\"%s\" at %p (%s)\n", path, (void *)load_address,
|
TRACE(("\"%s\" at %p (%s)\n", path, (void *)loadAddress,
|
||||||
image->regions[i].flags & RFLAG_RW ? "rw" : "read-only"));
|
image->regions[i].flags & RFLAG_RW ? "rw" : "read-only"));
|
||||||
|
|
||||||
image->regions[i].delta = load_address - image->regions[i].vmstart;
|
image->regions[i].delta = loadAddress - image->regions[i].vmstart;
|
||||||
image->regions[i].vmstart = load_address;
|
image->regions[i].vmstart = loadAddress;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle trailer bits in data segment
|
* handle trailer bits in data segment
|
||||||
*/
|
*/
|
||||||
if (image->regions[i].flags & RFLAG_RW) {
|
if (image->regions[i].flags & RFLAG_RW) {
|
||||||
unsigned start_clearing;
|
addr_t startClearing;
|
||||||
unsigned to_clear;
|
addr_t toClear;
|
||||||
|
|
||||||
start_clearing = image->regions[i].vmstart
|
startClearing = image->regions[i].vmstart
|
||||||
+ PAGE_OFFS(image->regions[i].start)
|
+ PAGE_OFFSET(image->regions[i].start)
|
||||||
+ image->regions[i].size;
|
+ image->regions[i].size;
|
||||||
to_clear = image->regions[i].vmsize
|
toClear = image->regions[i].vmsize
|
||||||
- PAGE_OFFS(image->regions[i].start)
|
- PAGE_OFFSET(image->regions[i].start)
|
||||||
- image->regions[i].size;
|
- image->regions[i].size;
|
||||||
memset((void*)start_clearing, 0, to_clear);
|
memset((void *)startClearing, 0, toClear);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,7 +599,7 @@ error:
|
|||||||
static void
|
static void
|
||||||
unmap_image(image_t *image)
|
unmap_image(image_t *image)
|
||||||
{
|
{
|
||||||
unsigned i;
|
uint32 i;
|
||||||
|
|
||||||
for (i = 0; i < image->num_regions; i++) {
|
for (i = 0; i < image->num_regions; i++) {
|
||||||
_kern_delete_area(image->regions[i].id);
|
_kern_delete_area(image->regions[i].id);
|
||||||
|
Loading…
Reference in New Issue
Block a user