Cleaned up ume.h by moving some functions around.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2756
This commit is contained in:
Nicholas Nethercote
2004-10-13 17:29:01 +00:00
parent 98b5592107
commit 7440f4def2
4 changed files with 166 additions and 147 deletions

View File

@@ -30,13 +30,16 @@
#define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <unistd.h>
#include "core.h"
@@ -51,6 +54,10 @@ static const char *valgrind_lib = VG_LIBDIR;
/* stage2's name */
static const char stage2[] = "stage2";
/*------------------------------------------------------------*/
/*--- Auxv modification ---*/
/*------------------------------------------------------------*/
/* Modify the auxv the kernel gave us to make it look like we were
execed as the shared object.
@@ -153,6 +160,89 @@ static void *fix_auxv(void *v_init_esp, const struct exeinfo *info,
return v_init_esp;
}
/*------------------------------------------------------------*/
/*--- Address space padding ---*/
/*------------------------------------------------------------*/
static void check_mmap(void* res, void* base, int len)
{
if ((void*)-1 == res) {
fprintf(stderr, "valgrind: padding mmap(%p, %d) failed during startup.\n"
"valgrind: is there a hard virtual memory limit set?\n",
base, len);
exit(1);
}
}
typedef struct {
char* fillgap_start;
char* fillgap_end;
int fillgap_padfile;
} fillgap_extra;
static int fillgap(char *segstart, char *segend, const char *perm, off_t off,
int maj, int min, int ino, void* e)
{
fillgap_extra* extra = e;
if (segstart >= extra->fillgap_end)
return 0;
if (segstart > extra->fillgap_start) {
void* res = mmap(extra->fillgap_start, segstart - extra->fillgap_start,
PROT_NONE, MAP_FIXED|MAP_PRIVATE,
extra->fillgap_padfile, 0);
check_mmap(res, extra->fillgap_start, segstart - extra->fillgap_start);
}
extra->fillgap_start = segend;
return 1;
}
// Choose a name for the padfile, open it.
int as_openpadfile(void)
{
char buf[256];
int padfile;
int seq = 1;
do {
snprintf(buf, 256, "/tmp/.pad.%d.%d", getpid(), seq++);
padfile = open(buf, O_RDWR|O_CREAT|O_EXCL, 0);
unlink(buf);
if (padfile == -1 && errno != EEXIST) {
fprintf(stderr, "valgrind: couldn't open padfile\n");
exit(44);
}
} while(padfile == -1);
return padfile;
}
// Pad all the empty spaces in a range of address space to stop interlopers.
void as_pad(void *start, void *end, int padfile)
{
fillgap_extra extra;
extra.fillgap_start = start;
extra.fillgap_end = end;
extra.fillgap_padfile = padfile;
foreach_map(fillgap, &extra);
if (extra.fillgap_start < extra.fillgap_end) {
void* res = mmap(extra.fillgap_start,
extra.fillgap_end - extra.fillgap_start,
PROT_NONE, MAP_FIXED|MAP_PRIVATE, padfile, 0);
check_mmap(res, extra.fillgap_start,
extra.fillgap_end - extra.fillgap_start);
}
}
/*------------------------------------------------------------*/
/*--- main() and related pieces ---*/
/*------------------------------------------------------------*/
static int prmap(char *start, char *end, const char *perm, off_t off, int maj,
int min, int ino, void* dummy) {
printf("mapping %10p-%10p %s %02x:%02x %d\n",

View File

@@ -55,9 +55,7 @@ struct elfinfo
static void check_mmap(void* res, void* base, int len)
{
if ((void*)-1 == res) {
fprintf(stderr, "valgrind: mmap(%p, %d) failed during startup.\n"
"valgrind: is there a hard virtual memory limit set?\n",
base, len);
fprintf(stderr, "valgrind: mmap(%p, %d) failed in UME.\n", base, len);
exit(1);
}
}
@@ -112,130 +110,6 @@ void foreach_map(int (*fn)(char *start, char *end,
}
}
typedef struct {
char* fillgap_start;
char* fillgap_end;
int fillgap_padfile;
} fillgap_extra;
static int fillgap(char *segstart, char *segend, const char *perm, off_t off,
int maj, int min, int ino, void* e)
{
fillgap_extra* extra = e;
if (segstart >= extra->fillgap_end)
return 0;
if (segstart > extra->fillgap_start) {
void* res = mmap(extra->fillgap_start, segstart - extra->fillgap_start,
PROT_NONE, MAP_FIXED|MAP_PRIVATE|MAP_NORESERVE,
extra->fillgap_padfile, 0);
check_mmap(res, extra->fillgap_start, segstart - extra->fillgap_start);
}
extra->fillgap_start = segend;
return 1;
}
// Choose a name for the padfile, open it.
int as_openpadfile(void)
{
char buf[256];
int padfile;
int seq = 1;
do {
snprintf(buf, 256, "/tmp/.pad.%d.%d", getpid(), seq++);
padfile = open(buf, O_RDWR|O_CREAT|O_EXCL, 0);
unlink(buf);
if (padfile == -1 && errno != EEXIST) {
fprintf(stderr, "valgrind: couldn't open padfile\n");
exit(44);
}
} while(padfile == -1);
return padfile;
}
// Pad all the empty spaces in a range of address space to stop interlopers.
void as_pad(void *start, void *end, int padfile)
{
fillgap_extra extra;
extra.fillgap_start = start;
extra.fillgap_end = end;
extra.fillgap_padfile = padfile;
foreach_map(fillgap, &extra);
if (extra.fillgap_start < extra.fillgap_end) {
void* res = mmap(extra.fillgap_start,
extra.fillgap_end - extra.fillgap_start,
PROT_NONE, MAP_FIXED|MAP_PRIVATE|MAP_NORESERVE, padfile, 0);
check_mmap(res, extra.fillgap_start,
extra.fillgap_end - extra.fillgap_start);
}
}
typedef struct {
char* killpad_start;
char* killpad_end;
struct stat* killpad_padstat;
} killpad_extra;
static int killpad(char *segstart, char *segend, const char *perm, off_t off,
int maj, int min, int ino, void* ex)
{
killpad_extra* extra = ex;
void *b, *e;
int res;
assert(NULL != extra->killpad_padstat);
if (extra->killpad_padstat->st_dev != makedev(maj, min) ||
extra->killpad_padstat->st_ino != ino)
return 1;
if (segend <= extra->killpad_start || segstart >= extra->killpad_end)
return 1;
if (segstart <= extra->killpad_start)
b = extra->killpad_start;
else
b = segstart;
if (segend >= extra->killpad_end)
e = extra->killpad_end;
else
e = segend;
res = munmap(b, (char *)e-(char *)b);
assert(0 == res);
return 1;
}
// Remove padding of 'padfile' from a range of address space.
void as_unpad(void *start, void *end, int padfile)
{
static struct stat padstat;
killpad_extra extra;
int res;
assert(padfile > 0);
res = fstat(padfile, &padstat);
assert(0 == res);
extra.killpad_padstat = &padstat;
extra.killpad_start = start;
extra.killpad_end = end;
foreach_map(killpad, &extra);
}
void as_closepadfile(int padfile)
{
int res = close(padfile);
assert(0 == res);
}
/*------------------------------------------------------------*/
/*--- Finding auxv on the stack ---*/
/*------------------------------------------------------------*/

View File

@@ -39,6 +39,15 @@
/*--- General stuff ---*/
/*------------------------------------------------------------*/
void foreach_map(int (*fn)(char *start, char *end,
const char *perm, off_t offset,
int maj, int min, int ino, void* extra),
void* extra);
/*------------------------------------------------------------*/
/*--- Loading ELF files ---*/
/*------------------------------------------------------------*/
#if ELFSZ == 64
#define ESZ(x) Elf64_##x
#elif ELFSZ == 32
@@ -50,15 +59,6 @@
/* Integer type the same size as a pointer */
typedef ESZ(Addr) addr_t;
void foreach_map(int (*fn)(char *start, char *end,
const char *perm, off_t offset,
int maj, int min, int ino, void* extra),
void* extra);
/*------------------------------------------------------------*/
/*--- Loading ELF files ---*/
/*------------------------------------------------------------*/
// Info needed to load and run a program. IN/INOUT/OUT refers to the
// inputs/outputs of do_exec().
struct exeinfo
@@ -87,16 +87,6 @@ struct exeinfo
// the program.
int do_exec(const char *exe, struct exeinfo *info);
/*------------------------------------------------------------*/
/*--- Address space padding ---*/
/*------------------------------------------------------------*/
// Padding functions used at startup to force things where we want them.
int as_openpadfile (void);
void as_pad (void *start, void *end, int padfile);
void as_unpad (void *start, void *end, int padfile);
void as_closepadfile(int padfile);
/*------------------------------------------------------------*/
/*--- Finding and dealing with auxv ---*/
/*------------------------------------------------------------*/

View File

@@ -1400,6 +1400,71 @@ static void load_client(char* cl_argv[], const char* exec, Int need_help,
VG_(brk_base) = VG_(brk_limit) = info->brkbase;
}
/*====================================================================*/
/*=== Address space unpadding ===*/
/*====================================================================*/
typedef struct {
char* killpad_start;
char* killpad_end;
struct stat* killpad_padstat;
} killpad_extra;
static int killpad(char *segstart, char *segend, const char *perm, off_t off,
int maj, int min, int ino, void* ex)
{
killpad_extra* extra = ex;
void *b, *e;
int res;
vg_assert(NULL != extra->killpad_padstat);
if (extra->killpad_padstat->st_dev != makedev(maj, min) ||
extra->killpad_padstat->st_ino != ino)
return 1;
if (segend <= extra->killpad_start || segstart >= extra->killpad_end)
return 1;
if (segstart <= extra->killpad_start)
b = extra->killpad_start;
else
b = segstart;
if (segend >= extra->killpad_end)
e = extra->killpad_end;
else
e = segend;
res = munmap(b, (char *)e-(char *)b);
vg_assert(0 == res);
return 1;
}
// Remove padding of 'padfile' from a range of address space.
void as_unpad(void *start, void *end, int padfile)
{
static struct stat padstat;
killpad_extra extra;
int res;
vg_assert(padfile > 0);
res = fstat(padfile, &padstat);
vg_assert(0 == res);
extra.killpad_padstat = &padstat;
extra.killpad_start = start;
extra.killpad_end = end;
foreach_map(killpad, &extra);
}
void as_closepadfile(int padfile)
{
int res = close(padfile);
vg_assert(0 == res);
}
/*====================================================================*/
/*=== Command-line: variables, processing, etc ===*/
@@ -2570,7 +2635,7 @@ int main(int argc, char **argv)
load_client(cl_argv, exec, need_help, &info, &client_eip);
//--------------------------------------------------------------
// Everything in place, unpad us
// Everything in place, remove padding done by stage1
// p: layout_remaining_space() [everything must be mapped in before now]
// p: load_client() [ditto]
//--------------------------------------------------------------