|
From: Jeremy F. <je...@go...> - 2003-12-16 22:27:18
|
CVS commit by fitzhardinge:
Auto-generate stage2.lds so that the linker script matches the local
linker.
M +1 -1 Makefile.am 1.62
M +1 -3 stage1.c 1.2 [POSSIBLY UNSAFE: printf]
M +6 -4 stage2.c 1.2
M +5 -0 ume.c 1.2 [POSSIBLY UNSAFE: printf]
M +2 -0 vg_errcontext.c 1.47
M +6 -2 vg_include.h 1.159
M +1 -1 vg_intercept.c 1.27
M +11 -6 vg_main.c 1.129
M +1 -1 vg_syscalls.c 1.68
M +10 -1 x86/Makefile.am 1.2
R x86/stage2.lds 1.1
--- valgrind/coregrind/Makefile.am #1.61:1.62
@@ -1,4 +1,4 @@
-SUBDIRS = demangle . docs x86
+SUBDIRS = x86 demangle . docs
add_includes = -I$(srcdir)/demangle -I$(top_srcdir)/include -I$(srcdir)/x86
--- valgrind/coregrind/stage1.c #1.1:1.2
@@ -136,7 +136,5 @@ static void hoops(void)
info.argv = NULL;
- strcpy(buf, valgrind_lib);
- strcat(buf, "/");
- strcat(buf, stage2);
+ snprintf(buf, sizeof(buf), "%s/%s", valgrind_lib, stage2);
err = do_exec(buf, &info);
--- valgrind/coregrind/stage2.c #1.1:1.2
@@ -66,5 +66,5 @@ static int scan_auxv(void)
case AT_UME_EXECFD:
- kp.execfd = auxv->a_val;
+ kp.vgexecfd = auxv->a_val;
found |= 2;
break;
@@ -594,5 +594,5 @@ int main(int argc, char **argv)
if (!scan_auxv()) {
fprintf(stderr, "stage2 must be launched by stage1\n");
- exit(1);
+ exit(127);
}
@@ -868,5 +868,5 @@ int main(int argc, char **argv)
fprintf(stderr, "Aborting: couldn't initialize valgrind\n");
list_tools();
- exit(1);
+ exit(127);
}
@@ -901,9 +901,11 @@ int main(int argc, char **argv)
info.argv = cl_argv;
+ kp.clexecfd = open(exec, O_RDONLY);
+
{
int ret = do_exec(exec, &info);
if (ret != 0) {
fprintf(stderr, "do_exec(%s) failed: %s\n", exec, strerror(ret));
- exit(1);
+ exit(127);
}
}
--- valgrind/coregrind/ume.c #1.1:1.2
@@ -609,4 +609,9 @@ static int do_exec_inner(const char *exe
int ngrp = getgroups(32, groups);
+ if (st.st_mode & (S_ISUID | S_ISGID)) {
+ fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe);
+ return EACCES;
+ }
+
if (uid == st.st_uid && !(st.st_mode & S_IXUSR))
return EACCES;
--- valgrind/coregrind/vg_errcontext.c #1.46:1.47
@@ -266,4 +266,6 @@ void do_actions_on_error(Error* err, Boo
m_ebp = tst->m_ebp;
}
+ VG_(printf)("starting gdb with eip=%p esp=%p ebp=%p\n",
+ m_eip, m_esp, m_ebp);
VG_(swizzle_esp_then_start_GDB)( m_eip, m_esp, m_ebp );
}
--- valgrind/coregrind/vg_include.h #1.158:1.159
@@ -1336,5 +1336,6 @@ typedef struct {
const Char *libdir; /* library directory */
- Int execfd; /* fd of our own (stage1) executable */
+ Int vgexecfd; /* fd of our own (stage1) executable */
+ Int clexecfd; /* fd of the client executable */
Addr client_base; /* start of client address space */
@@ -1385,5 +1386,8 @@ extern Addr VG_(valgrind_end);
/* stage1 executable file descriptor */
-extern Int VG_(execfd);
+extern Int VG_(vgexecfd);
+
+/* client executable file descriptor */
+extern Int VG_(clexecfd);
/* Path to all our library/aux files */
--- valgrind/coregrind/vg_intercept.c #1.26:1.27
@@ -63,5 +63,5 @@ int __GI_raise(int) __attribute__((alias
int gsignal(int sig)
{
- raise(sig);
+ return raise(sig);
}
--- valgrind/coregrind/vg_main.c #1.128:1.129
@@ -136,5 +136,8 @@ Addr VG_(valgrind_end);
/* stage1 (main) executable */
-Int VG_(execfd) = -1;
+Int VG_(vgexecfd) = -1;
+
+/* client executable */
+Int VG_(clexecfd) = -1;
/* Path to library directory */
@@ -1390,6 +1393,8 @@ void VG_(main) ( const KickstartParams *
vg_assert(VG_(clstk_end) == VG_(client_end));
- if (kp->execfd != -1)
- VG_(execfd) = VG_(safe_fd)(kp->execfd);
+ if (kp->vgexecfd != -1)
+ VG_(vgexecfd) = VG_(safe_fd)(kp->vgexecfd);
+ if (kp->clexecfd != -1)
+ VG_(clexecfd) = VG_(safe_fd)(kp->clexecfd);
if (0) {
@@ -1710,11 +1715,11 @@ void VG_(mash_colon_env)(Char *varp, con
look at parameters, memory, etc. You can't meaningfully get GDB to
continue the program, though; to continue, quit GDB. */
-extern void VG_(start_GDB_whilst_on_client_stack) ( void )
+void VG_(start_GDB_whilst_on_client_stack) ( void )
{
Int res;
UChar buf[100];
- VG_(sprintf)(buf, "%s -nw /proc/%d/exe %d",
- VG_(clo_GDB_path), VG_(getpid)(), VG_(getpid)());
+ VG_(sprintf)(buf, "%s -nw /proc/%d/fd/%d %d",
+ VG_(clo_GDB_path), VG_(getpid)(), VG_(clexecfd), VG_(getpid)());
VG_(message)(Vg_UserMsg, "starting GDB with cmd: %s", buf);
res = VG_(system)(buf);
--- valgrind/coregrind/vg_syscalls.c #1.67:1.68
@@ -1717,5 +1717,5 @@ PRE(execve)
VG_(sprintf)(exec, "--exec=%s", (Char *)arg1);
- VG_(sprintf)(exename, "/proc/self/fd/%d", VG_(execfd));
+ VG_(sprintf)(exename, "/proc/self/fd/%d", VG_(vgexecfd));
optlen += VG_(strlen)(exec)+1;
--- valgrind/coregrind/x86/Makefile.am #1.1:1.2
@@ -4,5 +4,4 @@
EXTRA_DIST = \
Make.inc \
- stage2.lds \
ume_archdefs.c \
ume_archdefs.h \
@@ -10,2 +9,12 @@
ume_go.c
+BUILT_SOURCES = stage2.lds
+CLEANFILES = stage2.lds
+
+# Extract ld's default linker script and hack it to our needs
+stage2.lds: Makefile
+ ld --verbose | sed \
+ -e '1,/^=====\+$$/d' \
+ -e '/^=====\+$$/d' \
+ -e 's/ENTRY(_start)/ENTRY(_ume_entry)/' \
+ -e 's/0x08048000/kickstart_base/' > $@ || rm -f $@
|
|
From: Dirk M. <mu...@kd...> - 2004-01-06 16:03:10
|
CVS commit by mueller:
remove anonymous unions - not supported by older versions of gcc.
M +8 -8 stage1.c 1.5 [POSSIBLY UNSAFE: printf]
M +12 -12 stage2.c 1.6
M +0 -2 ume.c 1.7
M +1 -1 ume.h 1.3
M +5 -5 vg_stabs.c 1.5
M +6 -6 vg_symtab2.c 1.73
M +1 -1 vg_symtab2.h 1.6
M +44 -44 vg_symtypes.c 1.4
--- valgrind/coregrind/stage1.c #1.4:1.5
@@ -91,5 +91,5 @@ static void *fix_auxv(void *v_init_esp,
place when we start it */
auxv[0].a_type = AT_UME_PADFD;
- auxv[0].a_val = as_getpadfd();
+ auxv[0].u.a_val = as_getpadfd();
/* This will be needed by valgrind itself so that it can
@@ -97,10 +97,10 @@ static void *fix_auxv(void *v_init_esp,
because /proc/self/exe will go away once we unmap stage1. */
auxv[1].a_type = AT_UME_EXECFD;
- auxv[1].a_val = open("/proc/self/exe", O_RDONLY);
+ auxv[1].u.a_val = open("/proc/self/exe", O_RDONLY);
/* make sure the rest are sane */
for(i = new_entries; i < delta/sizeof(*auxv); i++) {
auxv[i].a_type = AT_IGNORE;
- auxv[i].a_val = 0;
+ auxv[i].u.a_val = 0;
}
@@ -110,25 +110,25 @@ static void *fix_auxv(void *v_init_esp,
for(; auxv->a_type != AT_NULL; auxv++) {
if (0)
- printf("doing auxv %p %4x: %d %p\n", auxv, auxv->a_type, auxv->a_val, auxv->a_ptr);
+ printf("doing auxv %p %4x: %d %p\n", auxv, auxv->a_type, auxv->u.a_val, auxv->u.a_ptr);
switch(auxv->a_type) {
case AT_PHDR:
seen |= 1;
- auxv->a_val = info->phdr;
+ auxv->u.a_val = info->phdr;
break;
case AT_PHNUM:
seen |= 2;
- auxv->a_val = info->phnum;
+ auxv->u.a_val = info->phnum;
break;
case AT_BASE:
seen |= 4;
- auxv->a_val = info->interp_base;
+ auxv->u.a_val = info->interp_base;
break;
case AT_ENTRY:
seen |= 8;
- auxv->a_val = info->entry;
+ auxv->u.a_val = info->entry;
break;
}
--- valgrind/coregrind/stage2.c #1.5:1.6
@@ -91,10 +91,10 @@ static int scan_auxv(void)
switch(auxv->a_type) {
case AT_UME_PADFD:
- as_setpadfd(auxv->a_val);
+ as_setpadfd(auxv->u.a_val);
found |= 1;
break;
case AT_UME_EXECFD:
- kp.vgexecfd = auxv->a_val;
+ kp.vgexecfd = auxv->u.a_val;
found |= 2;
break;
@@ -237,5 +237,5 @@ static Addr setup_client_stack(char **or
for(cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) {
if (cauxv->a_type == AT_PLATFORM)
- stringsize += strlen(cauxv->a_ptr) + 1;
+ stringsize += strlen(cauxv->u.a_ptr) + 1;
auxsize += sizeof(*cauxv);
}
@@ -278,5 +278,5 @@ static Addr setup_client_stack(char **or
client_end - PGROUNDDN(cl_esp),
PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
@@ -322,5 +322,5 @@ static Addr setup_client_stack(char **or
auxv->a_type = AT_IGNORE;
else
- auxv->a_val = info->phdr;
+ auxv->u.a_val = info->phdr;
break;
@@ -329,5 +329,5 @@ static Addr setup_client_stack(char **or
auxv->a_type = AT_IGNORE;
else
- auxv->a_val = info->phnum;
+ auxv->u.a_val = info->phnum;
break;
@@ -336,13 +336,13 @@ static Addr setup_client_stack(char **or
auxv->a_type = AT_IGNORE;
else
- auxv->a_val = info->interp_base;
+ auxv->u.a_val = info->interp_base;
break;
case AT_PLATFORM: /* points to a platform description string */
- auxv->a_ptr = copy_str(&strtab, orig_auxv->a_ptr);
+ auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr);
break;
case AT_ENTRY:
- auxv->a_val = info->entry;
+ auxv->u.a_val = info->entry;
break;
@@ -374,5 +374,5 @@ static Addr setup_client_stack(char **or
need LD_PRELOAD/LD_LIBRARY_PATH to work for the client, we
set AT_SECURE to 0. */
- auxv->a_val = 0;
+ auxv->u.a_val = 0;
break;
@@ -925,5 +925,5 @@ int main(int argc, char **argv)
/* make the redzone inaccessible */
mmap((void *)client_end, REDZONE_SIZE, PROT_NONE,
- MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0);
munmap(CLIENT_BASE, client_size); /* make client hole */
@@ -952,5 +952,5 @@ int main(int argc, char **argv)
if (shadow_size != 0)
mmap((char *)shadow_base, shadow_size, PROT_NONE,
- MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+ MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0);
/* unpad us */
--- valgrind/coregrind/ume.c #1.6:1.7
@@ -86,7 +86,5 @@
#include <stdlib.h>
#include <unistd.h>
-#include <asm/unistd.h>
#include <sys/stat.h>
-#include <sys/sysmacros.h>
#include <dlfcn.h>
#include <assert.h>
--- valgrind/coregrind/ume.h #1.2:1.3
@@ -92,5 +92,5 @@ struct ume_auxv
int a_val;
void (*a_fcn)(void);
- };
+ } u;
};
--- valgrind/coregrind/vg_stabs.c #1.4:1.5
@@ -1013,10 +1013,10 @@ static Bool initSym(SegInfo *si, Sym *sy
case N_LCSYM:
sym->kind = SyStatic;
- sym->addr = si->offset + (Addr)val;
+ sym->u.addr = si->offset + (Addr)val;
break;
case N_PSYM:
sym->kind = SyEBPrel; /* +ve offset off EBP (erk, or ESP if no frame pointer) */
- sym->offset = val;
+ sym->u.offset = val;
break;
@@ -1026,15 +1026,15 @@ static Bool initSym(SegInfo *si, Sym *sy
else
sym->kind = SyESPrel; /* +ve off ESP when there's no frame pointer */
- sym->offset = val;
+ sym->u.offset = val;
break;
case N_RSYM:
sym->kind = SyReg;
- sym->regno = val;
+ sym->u.regno = val;
break;
case N_GSYM:
sym->kind = SyGlobal;
- sym->addr = 0; /* XXX should really look up global address */
+ sym->u.addr = 0; /* XXX should really look up global address */
break;
--- valgrind/coregrind/vg_symtab2.c #1.72:1.73
@@ -1778,5 +1778,5 @@ Variable *VG_(get_scope_variables)(Threa
if (debug && 0)
- VG_(printf)("sym->name=%s sym->kind=%d offset=%d\n", sym->name, sym->kind, sym->offset);
+ VG_(printf)("sym->name=%s sym->kind=%d offset=%d\n", sym->name, sym->kind, sym->u.offset);
switch(sym->kind) {
UInt reg;
@@ -1784,12 +1784,12 @@ Variable *VG_(get_scope_variables)(Threa
case SyGlobal:
case SyStatic:
- if (sym->addr == 0) {
+ if (sym->u.addr == 0) {
/* XXX lookup value */
}
- v->valuep = sym->addr;
+ v->valuep = sym->u.addr;
break;
case SyReg:
- v->valuep = (Addr)regaddr(tid, sym->regno);
+ v->valuep = (Addr)regaddr(tid, sym->u.regno);
break;
@@ -1798,6 +1798,6 @@ Variable *VG_(get_scope_variables)(Threa
reg = *regaddr(tid, sym->kind == SyESPrel ? R_ESP : R_EBP);
if (debug)
- VG_(printf)("reg=%p+%d=%p\n", reg, sym->offset, reg+sym->offset);
- v->valuep = (Addr)(reg + sym->offset);
+ VG_(printf)("reg=%p+%d=%p\n", reg, sym->u.offset, reg+sym->u.offset);
+ v->valuep = (Addr)(reg + sym->u.offset);
break;
--- valgrind/coregrind/vg_symtab2.h #1.5:1.6
@@ -98,5 +98,5 @@ struct _Sym {
Int regno; /* register number */
Addr addr; /* static or global address */
- };
+ } u;
};
--- valgrind/coregrind/vg_symtypes.c #1.3:1.4
@@ -152,5 +152,5 @@ struct _SymType {
void *data; /* data for resolver */
} t_unresolved;
- };
+ } u;
};
@@ -187,5 +187,5 @@ static void resolve(SymType *st)
return;
- (*st->t_unresolved.resolver)(st, st->t_unresolved.data);
+ (*st->u.t_unresolved.resolver)(st, st->u.t_unresolved.data);
if (st->kind == TyUnresolved)
@@ -201,6 +201,6 @@ SymType *VG_(st_mkunresolved)(SymType *s
st->kind = TyUnresolved;
st->size = 0;
- st->t_unresolved.resolver = resolver;
- st->t_unresolved.data = data;
+ st->u.t_unresolved.resolver = resolver;
+ st->u.t_unresolved.data = data;
return st;
@@ -212,6 +212,6 @@ void VG_(st_unresolved_setdata)(SymType
return;
- st->t_unresolved.resolver = resolver;
- st->t_unresolved.data = data;
+ st->u.t_unresolved.resolver = resolver;
+ st->u.t_unresolved.data = data;
}
@@ -247,5 +247,5 @@ SymType *VG_(st_mkint)(SymType *st, UInt
st->kind = TyInt;
st->size = size;
- st->t_scalar.issigned = isSigned;
+ st->u.t_scalar.issigned = isSigned;
return st;
@@ -260,5 +260,5 @@ SymType *VG_(st_mkfloat)(SymType *st, UI
st->kind = TyFloat;
st->size = size;
- st->t_scalar.issigned = True;
+ st->u.t_scalar.issigned = True;
return st;
@@ -286,5 +286,5 @@ SymType *VG_(st_mkpointer)(SymType *st,
st->kind = TyPointer;
st->size = sizeof(void *);
- st->t_pointer.type = ptr;
+ st->u.t_pointer.type = ptr;
return st;
@@ -299,7 +299,7 @@ SymType *VG_(st_mkrange)(SymType *st, Sy
st->kind = TyRange;
st->size = 0; /* ? */
- st->t_range.type = ty;
- st->t_range.min = min;
- st->t_range.max = max;
+ st->u.t_range.type = ty;
+ st->u.t_range.min = min;
+ st->u.t_range.max = max;
return st;
@@ -312,14 +312,14 @@ SymType *VG_(st_mkstruct)(SymType *st, U
vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || st->kind == TyStruct);
- vg_assert(st->kind != TyStruct || st->t_struct.nfield == 0);
+ vg_assert(st->kind != TyStruct || st->u.t_struct.nfield == 0);
st->kind = TyStruct;
st->size = size;
- st->t_struct.nfield = 0;
- st->t_struct.nfieldalloc = nfields;
+ st->u.t_struct.nfield = 0;
+ st->u.t_struct.nfieldalloc = nfields;
if (nfields != 0)
- st->t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields);
+ st->u.t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields);
else
- st->t_struct.fields = NULL;
+ st->u.t_struct.fields = NULL;
return st;
@@ -332,14 +332,14 @@ SymType *VG_(st_mkunion)(SymType *st, UI
vg_assert(st->kind == TyUnresolved || st->kind == TyUnknown || st->kind == TyUnion);
- vg_assert(st->kind != TyUnion || st->t_struct.nfield == 0);
+ vg_assert(st->kind != TyUnion || st->u.t_struct.nfield == 0);
st->kind = TyUnion;
st->size = size;
- st->t_struct.nfield = 0;
- st->t_struct.nfieldalloc = nfields;
+ st->u.t_struct.nfield = 0;
+ st->u.t_struct.nfieldalloc = nfields;
if (nfields != 0)
- st->t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields);
+ st->u.t_struct.fields = VG_(arena_malloc)(VG_AR_SYMTAB, sizeof(StField) * nfields);
else
- st->t_struct.fields = NULL;
+ st->u.t_struct.fields = NULL;
return st;
@@ -352,15 +352,15 @@ void VG_(st_addfield)(SymType *st, Char
vg_assert(st->kind == TyStruct || st->kind == TyUnion);
- if (st->t_struct.nfieldalloc == st->t_struct.nfield) {
+ if (st->u.t_struct.nfieldalloc == st->u.t_struct.nfield) {
StField *n = VG_(arena_malloc)(VG_AR_SYMTAB,
- sizeof(StField) * (st->t_struct.nfieldalloc + 2));
- VG_(memcpy)(n, st->t_struct.fields, sizeof(*n) * st->t_struct.nfield);
- if (st->t_struct.fields != NULL)
- VG_(arena_free)(VG_AR_SYMTAB, st->t_struct.fields);
- st->t_struct.nfieldalloc++;
- st->t_struct.fields = n;
+ sizeof(StField) * (st->u.t_struct.nfieldalloc + 2));
+ VG_(memcpy)(n, st->u.t_struct.fields, sizeof(*n) * st->u.t_struct.nfield);
+ if (st->u.t_struct.fields != NULL)
+ VG_(arena_free)(VG_AR_SYMTAB, st->u.t_struct.fields);
+ st->u.t_struct.nfieldalloc++;
+ st->u.t_struct.fields = n;
}
- f = &st->t_struct.fields[st->t_struct.nfield++];
+ f = &st->u.t_struct.fields[st->u.t_struct.nfield++];
f->name = name;
f->type = type;
@@ -377,6 +377,6 @@ SymType *VG_(st_mkenum)(SymType *st, UIn
st->kind = TyEnum;
- st->t_enum.ntag = 0;
- st->t_enum.tags = NULL;
+ st->u.t_enum.ntag = 0;
+ st->u.t_enum.tags = NULL;
return st;
@@ -390,6 +390,6 @@ SymType *VG_(st_mkarray)(SymType *st, Sy
st->kind = TyArray;
- st->t_array.type = type;
- st->t_array.idxtype = idxtype;
+ st->u.t_array.type = type;
+ st->u.t_array.idxtype = idxtype;
return st;
@@ -406,5 +406,5 @@ SymType *VG_(st_mktypedef)(SymType *st,
st->kind = TyTypedef;
st->name = name;
- st->t_typedef.type = type;
+ st->u.t_typedef.type = type;
return st;
@@ -419,5 +419,5 @@ SymType *VG_(st_basetype)(SymType *type,
if (type->kind == TyTypedef)
- type = type->t_typedef.type;
+ type = type->u.t_typedef.type;
}
@@ -826,7 +826,7 @@ Char *VG_(describe_addr)(ThreadId tid, A
if (debug)
- VG_(printf)(" %d fields\n", type->t_struct.nfield);
- for(i = 0; i < type->t_struct.nfield; i++) {
- StField *f = &type->t_struct.fields[i];
+ VG_(printf)(" %d fields\n", type->u.t_struct.nfield);
+ for(i = 0; i < type->u.t_struct.nfield; i++) {
+ StField *f = &type->u.t_struct.fields[i];
newvar(f->name, f->type, var->valuep + (f->offset / 8), (f->size + 7) / 8);
}
@@ -838,10 +838,10 @@ Char *VG_(describe_addr)(ThreadId tid, A
Int offset; /* offset of index for non-0-based arrays */
Int min, max; /* range of indicies we care about (0 based) */
- SymType *ty = type->t_array.type;
- vg_assert(type->t_array.idxtype->kind == TyRange);
+ SymType *ty = type->u.t_array.type;
+ vg_assert(type->u.t_array.idxtype->kind == TyRange);
- offset = type->t_array.idxtype->t_range.min;
+ offset = type->u.t_array.idxtype->u.t_range.min;
min = 0;
- max = type->t_array.idxtype->t_range.max - offset;
+ max = type->u.t_array.idxtype->u.t_range.max - offset;
if ((max-min+1) == 0) {
@@ -894,5 +894,5 @@ Char *VG_(describe_addr)(ThreadId tid, A
actually a decayed array, and treat it accordingly */
if (is_valid_addr(var->valuep))
- newvar(NULL, type->t_pointer.type, *(Addr *)var->valuep, -1);
+ newvar(NULL, type->u.t_pointer.type, *(Addr *)var->valuep, -1);
break;
|
|
From: Nicholas N. <nj...@ca...> - 2004-06-22 14:00:20
|
CVS commit by nethercote:
Slightly disentangle main().
M +15 -13 vg_main.c 1.159 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/vg_main.c #1.158:1.159
@@ -1046,9 +1046,4 @@ static Addr setup_client_stack(char **or
cl_esp = ROUNDDN(cl_esp, 16); /* make stack 16 byte aligned */
- if (0)
- printf("stringsize=%d auxsize=%d stacksize=%d\n",
- stringsize, auxsize, stacksize);
-
-
/* base of the string table (aligned) */
stringbase = strtab = (char *)(VG_(client_trampoline_code) - ROUNDUP(stringsize, sizeof(int)));
@@ -1057,4 +1052,11 @@ static Addr setup_client_stack(char **or
VG_(clstk_end) = VG_(client_end);
+ if (0)
+ printf("stringsize=%d auxsize=%d stacksize=%d\n"
+ "clstk_base %x\n"
+ "clstk_end %x\n",
+ stringsize, auxsize, stacksize, VG_(clstk_base), VG_(clstk_end));
+
+
/* ==================== allocate space ==================== */
@@ -1186,4 +1188,8 @@ static Addr setup_client_stack(char **or
vg_assert((strtab-stringbase) == stringsize);
+ /* We know the initial ESP is pointing at argc/argv */
+ VG_(client_argc) = *(Int*)cl_esp;
+ VG_(client_argv) = (Char**)(cl_esp + sizeof(Int));
+
return cl_esp;
}
@@ -1634,6 +1640,5 @@ static void pre_process_cmd_line_options
}
-static void process_cmd_line_options
- ( UInt* client_auxv, Addr esp_at_startup, const char* toolname )
+static void process_cmd_line_options( UInt* client_auxv, const char* toolname )
{
Int i, eventually_log_fd;
@@ -1659,8 +1664,4 @@ static void process_cmd_line_options
}
- /* We know the initial ESP is pointing at argc/argv */
- VG_(client_argc) = *(Int *)esp_at_startup;
- VG_(client_argv) = (Char **)(esp_at_startup + sizeof(Int));
-
for (i = 1; i < VG_(vg_argc); i++) {
@@ -2750,5 +2751,5 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Setup client stack and eip
+ // Setup client stack, eip, and VG_(client_arg[cv])
// p: load_client() [for 'info']
// p: fix_environment() [for 'env']
@@ -2792,4 +2793,5 @@ int main(int argc, char **argv)
// XXX: alternatively, if sk_pre_clo_init does use VG_(malloc)(), is it
// wrong to ignore any segments that might add in parse_procselfmaps?
+ // p: setup_client_stack() [for 'VG_(client_arg[cv]']
//--------------------------------------------------------------
(*toolinfo->sk_pre_clo_init)();
@@ -2812,5 +2814,5 @@ int main(int argc, char **argv)
// p: sk_pre_clo_init [to set 'command_line_options' need]
//--------------------------------------------------------------
- process_cmd_line_options(client_auxv, esp_at_startup, tool);
+ process_cmd_line_options(client_auxv, tool);
//--------------------------------------------------------------
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-15 14:58:54
|
CVS commit by nethercote:
This commit fixes things so that the client stack can be easily placed
anywhere, even below the client executable, just by changing a single
assignment to VG_(clstk_end). I haven't actually moved the stack, though.
M +14 -10 vg_main.c 1.170 [POSSIBLY UNSAFE: printf]
M +3 -1 vg_signals.c 1.72
--- valgrind/coregrind/vg_main.c #1.169:1.170
@@ -511,5 +511,4 @@ static void layout_remaining_space(float
/* where !FIXED mmap goes */
VG_(client_mapbase) = PGROUNDDN((addr_t)(client_size * CLIENT_HEAP_PROPORTION));
- VG_(client_trampoline_code) = VG_(client_end) - VKI_BYTES_PER_PAGE;
VG_(shadow_base) = VG_(client_end) + REDZONE_SIZE;
@@ -941,6 +940,5 @@ static char *copy_str(char **tab, const
if (0)
- printf("copied %p \"%s\" len %d\n",
- orig, orig, cp-orig);
+ printf("copied %p \"%s\" len %d\n", orig, orig, cp-orig);
*tab = cp;
@@ -1050,6 +1048,11 @@ static Addr setup_client_stack(char **or
VKI_BYTES_PER_PAGE; /* page for trampoline code */
+ // decide where stack goes!
+ VG_(clstk_end) = VG_(client_end);
+
+ VG_(client_trampoline_code) = VG_(clstk_end) - VKI_BYTES_PER_PAGE;
+
/* cl_esp is the client's stack pointer */
- cl_esp = VG_(client_end) - stacksize;
+ cl_esp = VG_(clstk_end) - stacksize;
cl_esp = ROUNDDN(cl_esp, 16); /* make stack 16 byte aligned */
@@ -1058,5 +1061,4 @@ static Addr setup_client_stack(char **or
VG_(clstk_base) = PGROUNDDN(cl_esp);
- VG_(clstk_end) = VG_(client_end);
if (0)
@@ -1070,5 +1072,5 @@ static Addr setup_client_stack(char **or
/* allocate a stack - mmap enough space for the stack */
- res = mmap((void *)PGROUNDDN(cl_esp), VG_(client_end) - PGROUNDDN(cl_esp),
+ res = mmap((void *)PGROUNDDN(cl_esp), VG_(clstk_end) - PGROUNDDN(cl_esp),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
@@ -1193,4 +1195,8 @@ static Addr setup_client_stack(char **or
vg_assert(auxv->a_type == AT_NULL);
+ /* --- trampoline page --- */
+ VG_(memcpy)( (void *)VG_(client_trampoline_code),
+ &VG_(trampoline_code_start), VG_(trampoline_code_length) );
+
vg_assert((strtab-stringbase) == stringsize);
@@ -2886,9 +2892,7 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Initialize our trampoline page (which is also sysinfo stuff)
- // p: setup_client_stack() [for 'esp_at_startup']
+ // Protect client trampoline page (which is also sysinfo stuff)
+ // p: segment stuff [otherwise get seg faults...]
//--------------------------------------------------------------
- VG_(memcpy)( (void *)VG_(client_trampoline_code),
- &VG_(trampoline_code_start), VG_(trampoline_code_length) );
VG_(mprotect)( (void *)VG_(client_trampoline_code),
VG_(trampoline_code_length), VKI_PROT_READ|VKI_PROT_EXEC );
--- valgrind/coregrind/vg_signals.c #1.71:1.72
@@ -2117,4 +2117,6 @@ void vg_sync_signalhandler ( Int sigNo,
if (seg != NULL)
seg = VG_(next_segment)(seg);
+ else
+ seg = VG_(first_segment)();
if (VG_(clo_trace_signals)) {
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-17 12:57:50
|
CVS commit by nethercote:
Check mmap() and munmap() results at startup; they can fail if a hard memory
limit is set. This fixes bug #82722.
CCMAIL: 827...@bu...
M +42 -16 ume.c 1.12 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/ume.c #1.11:1.12
@@ -56,4 +56,14 @@ static struct stat padstat;
extern int kickstart_base; /* linker created */
+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);
+ exit(1);
+ }
+}
+
void foreach_map(int (*fn)(void *start, void *end,
const char *perm, off_t offset,
@@ -111,7 +121,9 @@ static int fillgap(void *segstart, void
return 0;
- if ((char *)segstart > fillgap_addr)
- mmap(fillgap_addr, (char *)segstart-fillgap_addr, PROT_NONE,
+ if ((char *)segstart > fillgap_addr) {
+ void* res = mmap(fillgap_addr, (char *)segstart-fillgap_addr, PROT_NONE,
MAP_FIXED|MAP_PRIVATE, padfile, 0);
+ check_mmap(res, fillgap_addr, (char*)segstart - fillgap_addr);
+ }
fillgap_addr = segend;
@@ -142,7 +154,9 @@ void as_pad(void *start, void *end)
foreach_map(fillgap);
- if (fillgap_addr < fillgap_end)
- mmap(fillgap_addr, fillgap_end-fillgap_addr, PROT_NONE,
+ if (fillgap_addr < fillgap_end) {
+ void* res = mmap(fillgap_addr, fillgap_end-fillgap_addr, PROT_NONE,
MAP_FIXED|MAP_PRIVATE, padfile, 0);
+ check_mmap(res, fillgap_addr, fillgap_end - fillgap_addr);
+ }
}
@@ -151,6 +165,8 @@ static void *killpad_end;
static int killpad(void *segstart, void *segend, const char *perm, off_t off,
- int maj, int min, int ino) {
+ int maj, int min, int ino)
+{
void *b, *e;
+ int res;
if (padstat.st_dev != makedev(maj, min) || padstat.st_ino != ino)
@@ -170,5 +186,6 @@ static int killpad(void *segstart, void
e = segend;
- munmap(b, (char *)e-(char *)b);
+ res = munmap(b, (char *)e-(char *)b);
+ assert(0 == res);
return 1;
@@ -281,4 +298,5 @@ ESZ(Addr) mapelf(struct elfinfo *e, ESZ(
{
int i;
+ void* res;
ESZ(Addr) elfbrk = 0;
@@ -327,6 +345,9 @@ ESZ(Addr) mapelf(struct elfinfo *e, ESZ(
brkaddr = addr+memsz;
- mmap((char *)ROUNDDN(addr, align), ROUNDUP(bss, align)-ROUNDDN(addr, align),
+ res = mmap((char *)ROUNDDN(addr, align),
+ ROUNDUP(bss, align)-ROUNDDN(addr, align),
prot, MAP_FIXED|MAP_PRIVATE, e->fd, ROUNDDN(off, align));
+ check_mmap(res, (char*)ROUNDDN(addr,align),
+ ROUNDUP(bss, align)-ROUNDDN(addr, align));
/* if memsz > filesz, then we need to fill the remainder with zeroed pages */
@@ -335,7 +356,9 @@ ESZ(Addr) mapelf(struct elfinfo *e, ESZ(
bytes = ROUNDUP(brkaddr, align)-ROUNDUP(bss, align);
- if (bytes > 0)
- mmap((char *)ROUNDUP(bss, align), bytes,
+ if (bytes > 0) {
+ res = mmap((char *)ROUNDUP(bss, align), bytes,
prot, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ check_mmap(res, (char*)ROUNDUP(bss,align), bytes);
+ }
bytes = bss & (VKI_BYTES_PER_PAGE - 1);
@@ -457,6 +480,7 @@ static int load_ELF(char *hdr, int len,
if (interp != NULL) {
/* reserve a chunk of address space for interpreter */
- char *base = (char *)info->exe_base;
- char *baseoff;
+ void* res;
+ char* base = (char *)info->exe_base;
+ char* baseoff;
int flags = MAP_PRIVATE|MAP_ANONYMOUS;
@@ -466,5 +490,7 @@ static int load_ELF(char *hdr, int len,
}
- base = mmap(base, interp_size, PROT_NONE, flags, -1, 0);
+ res = mmap(base, interp_size, PROT_NONE, flags, -1, 0);
+ check_mmap(res, base, interp_size);
+ base = res;
baseoff = base - interp_addr;
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-22 12:41:27
|
CVS commit by nethercote:
Clarify error msgs
M +8 -9 ume.c 1.14 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/ume.c #1.13:1.14
@@ -249,5 +249,5 @@ struct elfinfo *readelf(int fd, const ch
if (pread(fd, &e->e, sizeof(e->e), 0) != sizeof(e->e)) {
- fprintf(stderr, "%s: can't read elf header: %s\n",
+ fprintf(stderr, "valgrind: %s: can't read elf header: %s\n",
filename, strerror(errno));
return NULL;
@@ -255,28 +255,27 @@ struct elfinfo *readelf(int fd, const ch
if (memcmp(&e->e.e_ident[0], ELFMAG, SELFMAG) != 0) {
- fprintf(stderr, "%s: bad ELF magic\n",
- filename);
+ fprintf(stderr, "valgrind: %s: bad ELF magic\n", filename);
return NULL;
}
if (e->e.e_ident[EI_CLASS] != ELFCLASS32) {
- fprintf(stderr, "Can only handle 32-bit executables\n");
+ fprintf(stderr, "valgrind: Can only handle 32-bit executables\n");
return NULL;
}
if (e->e.e_ident[EI_DATA] != ELFDATA2LSB) {
- fprintf(stderr, "Expecting little-endian\n");
+ fprintf(stderr, "valgrind: Expecting little-endian\n");
return NULL;
}
if (!(e->e.e_type == ET_EXEC || e->e.e_type == ET_DYN)) {
- fprintf(stderr, "need executable\n");
+ fprintf(stderr, "valgrind: need executable\n");
return NULL;
}
if (e->e.e_machine != EM_386) {
- fprintf(stderr, "need x86\n");
+ fprintf(stderr, "valgrind: need x86\n");
return NULL;
}
if (e->e.e_phentsize != sizeof(ESZ(Phdr))) {
- fprintf(stderr, "sizeof Phdr wrong\n");
+ fprintf(stderr, "valgrind: sizeof Phdr wrong\n");
return NULL;
}
@@ -287,5 +286,5 @@ struct elfinfo *readelf(int fd, const ch
if (pread(fd, e->p, phsz, e->e.e_phoff) != phsz) {
- fprintf(stderr, "can't read phdr: %s\n", strerror(errno));
+ fprintf(stderr, "valgrind: can't read phdr: %s\n", strerror(errno));
return NULL;
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-26 11:12:07
|
CVS commit by nethercote:
Er, actually make this test meaningful. It now aborts correctly if you try to
launch stage2 directly, rather than giving an obscure error about the tool
later on.
M +2 -2 vg_main.c 1.174 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/vg_main.c #1.173:1.174
@@ -474,6 +474,6 @@ static void scan_auxv(void)
}
- if ( ! (1|2) ) {
- fprintf(stderr, "stage2 must be launched by stage1\n");
+ if ( found != (1|2) ) {
+ fprintf(stderr, "valgrind: stage2 must be launched by stage1\n");
exit(127);
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-26 15:41:08
|
CVS commit by nethercote:
Rename 'argv0' and 'argv1' to the more meaningful 'interp_name' and
'interp_args'.
M +8 -8 ume.c 1.17 [POSSIBLY UNSAFE: printf]
M +2 -2 ume.h 1.7
M +13 -13 vg_main.c 1.176
--- valgrind/coregrind/ume.c #1.16:1.17
@@ -566,9 +566,9 @@ static int load_script(char *hdr, int le
}
- info->argv0 = strdup(interp);
- assert(NULL != info->argv0);
+ info->interp_name = strdup(interp);
+ assert(NULL != info->interp_name);
if (arg != NULL && *arg != '\0') {
- info->argv1 = strdup(arg);
- assert(NULL != info->argv1);
+ info->interp_args = strdup(arg);
+ assert(NULL != info->interp_args);
}
@@ -577,6 +577,6 @@ static int load_script(char *hdr, int le
if (0)
- printf("#! script: argv0=\"%s\" argv1=\"%s\"\n",
- info->argv0, info->argv1);
+ printf("#! script: interp_name=\"%s\" interp_args=\"%s\"\n",
+ info->interp_name, info->interp_args);
return do_exec_inner(interp, info);
@@ -670,6 +670,6 @@ static int do_exec_inner(const char *exe
int do_exec(const char *exe, struct exeinfo *info)
{
- info->argv0 = NULL;
- info->argv1 = NULL;
+ info->interp_name = NULL;
+ info->interp_args = NULL;
return do_exec_inner(exe, info);
--- valgrind/coregrind/ume.h #1.6:1.7
@@ -71,6 +71,6 @@ struct exeinfo
// These are the extra args added by #! scripts
- char* argv0; // INPUT: the interpreter name
- char* argv1; // INPUT: the args for the interpreter
+ char* interp_name; // INPUT: the interpreter name
+ char* interp_args; // INPUT: the args for the interpreter
};
--- valgrind/coregrind/vg_main.c #1.175:1.176
@@ -1014,11 +1014,11 @@ static Addr setup_client_stack(char **or
interpreter and its argument) */
argc = 0;
- if (info->argv0 != NULL) {
+ if (info->interp_name != NULL) {
argc++;
- stringsize += strlen(info->argv0) + 1;
+ stringsize += strlen(info->interp_name) + 1;
}
- if (info->argv1 != NULL) {
+ if (info->interp_args != NULL) {
argc++;
- stringsize += strlen(info->argv1) + 1;
+ stringsize += strlen(info->interp_args) + 1;
}
@@ -1092,11 +1092,11 @@ static Addr setup_client_stack(char **or
/* --- argv --- */
- if (info->argv0) {
- *ptr++ = (addr_t)copy_str(&strtab, info->argv0);
- free(info->argv0);
+ if (info->interp_name) {
+ *ptr++ = (addr_t)copy_str(&strtab, info->interp_name);
+ free(info->interp_name);
}
- if (info->argv1) {
- *ptr++ = (addr_t)copy_str(&strtab, info->argv1);
- free(info->argv1);
+ if (info->interp_args) {
+ *ptr++ = (addr_t)copy_str(&strtab, info->interp_args);
+ free(info->interp_args);
}
for (cpp = orig_argv; *cpp; ptr++, cpp++) {
@@ -1453,6 +1453,6 @@ static void load_client(char* cl_argv[],
if (need_help) {
VG_(clexecfd) = -1;
- info->argv0 = NULL;
- info->argv1 = NULL;
+ info->interp_name = NULL;
+ info->interp_args = NULL;
} else {
Int ret;
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-26 16:21:42
|
CVS commit by nethercote:
Added some comments.
M +2 -0 ume.c 1.18
M +17 -10 ume.h 1.8
M +3 -2 vg_main.c 1.177 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/ume.c #1.17:1.18
@@ -668,4 +668,6 @@ static int do_exec_inner(const char *exe
}
+// See ume.h for an indication of which entries of 'info' are inputs, which
+// are outputs, and which are both.
int do_exec(const char *exe, struct exeinfo *info)
{
--- valgrind/coregrind/ume.h #1.7:1.8
@@ -55,24 +55,30 @@ typedef ESZ(Addr) addr_t;
/*------------------------------------------------------------*/
+// Info needed to load and run a program. IN/INOUT/OUT refers to the
+// inputs/outputs of do_exec().
struct exeinfo
{
- addr_t map_base; // INPUT: if non-zero, base address of mappings
- char** argv; // INPUT: the original argv
+ addr_t map_base; // IN: if non-zero, base address of mappings
+ char** argv; // IN: the original argv
addr_t exe_base; // INOUT: lowest (allowed) address of exe
addr_t exe_end; // INOUT: highest (allowed) address
- addr_t phdr; // address phdr was mapped at
- int phnum; // number of phdrs
- addr_t interp_base; // where interpreter (ld.so) was mapped
- addr_t entry; // entrypoint in main executable
- addr_t init_eip; // initial eip
- addr_t brkbase; // base address of brk segment
+ addr_t phdr; // OUT: address phdr was mapped at
+ int phnum; // OUT: number of phdrs
+ addr_t interp_base; // OUT: where interpreter (ld.so) was mapped
+ addr_t entry; // OUT: entrypoint in main executable
+ addr_t init_eip; // OUT: initial eip
+ addr_t brkbase; // OUT: base address of brk segment
// These are the extra args added by #! scripts
- char* interp_name; // INPUT: the interpreter name
- char* interp_args; // INPUT: the args for the interpreter
+ char* interp_name; // OUT: the interpreter name
+ char* interp_args; // OUT: the args for the interpreter
};
+// Does everything short of actually running 'exe': finds the file,
+// checks execute permissions, sets up interpreter if program is a script,
+// reads headers, maps file into memory, and returns important info about
+// the program.
int do_exec(const char *exe, struct exeinfo *info);
@@ -85,4 +91,5 @@ void foreach_map(int (*fn)(void *start,
int maj, int min, int ino));
+// Padding functions used at startup to force things where we want them.
void as_pad(void *start, void *end);
void as_unpad(void *start, void *end);
--- valgrind/coregrind/vg_main.c #1.176:1.177
@@ -1453,4 +1452,5 @@ static void load_client(char* cl_argv[],
if (need_help) {
VG_(clexecfd) = -1;
+ // Set the minimal number of entries in 'info' to continue.
info->interp_name = NULL;
info->interp_args = NULL;
@@ -1460,5 +1460,6 @@ static void load_client(char* cl_argv[],
ret = do_exec(exec, info);
if (ret != 0) {
- fprintf(stderr, "valgrind: do_exec(%s) failed: %s\n", exec, strerror(ret));
+ fprintf(stderr, "valgrind: do_exec(%s) failed: %s\n",
+ exec, strerror(ret));
exit(127);
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-07-30 21:50:39
|
CVS commit by nethercote:
Restructured the as_*() functions so they are simpler and there is no implicit
global state -- the state is threaded explicitly through via function arguments
and return values. ume.c now has no global variables, which is nice.
Also removed a redundant as_pad() call in stage2's main() which meant
layout_client_space() could be merged with layout_remaining_space().
Also removed a couple of no-longer-used variables and #defines.
M +10 -7 stage1.c 1.15
M +107 -93 ume.c 1.19 [POSSIBLY UNSAFE: printf]
M +9 -9 ume.h 1.9
M +29 -40 vg_main.c 1.178
--- valgrind/coregrind/stage1.c #1.14:1.15
@@ -62,5 +62,6 @@ static const char stage2[] = "stage2";
padding file, so it can identiry and remove the padding later).
*/
-static void *fix_auxv(void *v_init_esp, const struct exeinfo *info)
+static void *fix_auxv(void *v_init_esp, const struct exeinfo *info,
+ int padfile)
{
struct ume_auxv *auxv;
@@ -91,5 +92,5 @@ static void *fix_auxv(void *v_init_esp,
place when we start it */
auxv[0].a_type = AT_UME_PADFD;
- auxv[0].u.a_val = as_getpadfd();
+ auxv[0].u.a_val = padfile;
/* This will be needed by valgrind itself so that it can
@@ -156,5 +157,6 @@ static void *fix_auxv(void *v_init_esp,
}
-static int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
+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",
start, end, perm, maj, min, ino);
@@ -164,5 +166,5 @@ static int prmap(void *start, void *end,
static void hoops(void)
{
- int err;
+ int err, padfile;
struct exeinfo info;
extern char _end;
@@ -194,12 +196,13 @@ static void hoops(void)
/* Make sure stage2's dynamic linker can't tromp on the lower part
of the address space. */
- as_pad(0, (void *)info.map_base);
+ padfile = as_openpadfile();
+ as_pad(0, (void *)info.map_base, padfile);
- esp = fix_auxv(ume_exec_esp, &info);
+ esp = fix_auxv(ume_exec_esp, &info, padfile);
if (0) {
printf("---------- launch stage 2 ----------\n");
printf("eip=%p esp=%p\n", (void *)info.init_eip, esp);
- foreach_map(prmap);
+ foreach_map(prmap, /*dummy*/NULL);
}
--- valgrind/coregrind/ume.c #1.18:1.19
@@ -58,9 +58,4 @@ struct elfinfo
};
-static int padfile = -1;
-static struct stat padstat;
-
-extern int kickstart_base; /* linker created */
-
static void check_mmap(void* res, void* base, int len)
{
@@ -73,7 +68,10 @@ static void check_mmap(void* res, void*
}
-void foreach_map(int (*fn)(void *start, void *end,
+// 'extra' allows the caller to pass in extra args to 'fn', like free
+// variables to a closure.
+void foreach_map(int (*fn)(char *start, char *end,
const char *perm, off_t offset,
- int maj, int min, int ino))
+ int maj, int min, int ino, void* extra),
+ void* extra)
{
static char buf[10240];
@@ -115,79 +113,101 @@ void foreach_map(int (*fn)(void *start,
bufptr++; /* skip \n */
- if (!(*fn)(segstart, segend, perm, offset, maj, min, ino))
+ if (!(*fn)(segstart, segend, perm, offset, maj, min, ino, extra))
break;
}
}
-static char *fillgap_addr;
-static char *fillgap_end;
+typedef struct {
+ char* fillgap_start;
+ char* fillgap_end;
+ int fillgap_padfile;
+} fillgap_extra;
-static int fillgap(void *segstart, void *segend, const char *perm, off_t off,
- int maj, int min, int ino) {
- if ((char *)segstart >= fillgap_end)
+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 ((char *)segstart > fillgap_addr) {
- void* res = mmap(fillgap_addr, (char *)segstart-fillgap_addr, PROT_NONE,
- MAP_FIXED|MAP_PRIVATE, padfile, 0);
- check_mmap(res, fillgap_addr, (char*)segstart - fillgap_addr);
+ 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);
}
- fillgap_addr = segend;
+ extra->fillgap_start = segend;
return 1;
}
-/* pad all the empty spaces in a range of address space to stop
- interlopers */
-void as_pad(void *start, void *end)
+// Choose a name for the padfile, open it.
+int as_openpadfile(void)
{
- char buf[1024];
-
- if (padfile == -1) {
+ char buf[256];
+ int padfile;
int seq = 1;
do {
- sprintf(buf, "/tmp/.pad.%d.%d", getpid(), seq++);
+ 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)
+ if (padfile == -1 && errno != EEXIST) {
+ fprintf(stderr, "valgrind: couldn't open padfile\n");
exit(44);
- } while(padfile == -1);
- fstat(padfile, &padstat);
}
+ } while(padfile == -1);
- fillgap_addr = start;
- fillgap_end = end;
+ return padfile;
+}
- foreach_map(fillgap);
+// 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;
- if (fillgap_addr < fillgap_end) {
- void* res = mmap(fillgap_addr, fillgap_end-fillgap_addr, PROT_NONE,
- MAP_FIXED|MAP_PRIVATE, padfile, 0);
- check_mmap(res, fillgap_addr, fillgap_end - fillgap_addr);
+ 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);
}
}
-static void *killpad_start;
-static void *killpad_end;
+typedef struct {
+ char* killpad_start;
+ char* killpad_end;
+ struct stat* killpad_padstat;
+} killpad_extra;
-static int killpad(void *segstart, void *segend, const char *perm, off_t off,
- int maj, int min, int ino)
+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;
- if (padstat.st_dev != makedev(maj, min) || padstat.st_ino != ino)
+ assert(NULL != extra->killpad_padstat);
+
+ if (extra->killpad_padstat->st_dev != makedev(maj, min) ||
+ extra->killpad_padstat->st_ino != ino)
return 1;
- if (segend <= killpad_start || segstart >= killpad_end)
+ if (segend <= extra->killpad_start || segstart >= extra->killpad_end)
return 1;
- if (segstart <= killpad_start)
- b = killpad_start;
+ if (segstart <= extra->killpad_start)
+ b = extra->killpad_start;
else
b = segstart;
- if (segend >= killpad_end)
- e = killpad_end;
+ if (segend >= extra->killpad_end)
+ e = extra->killpad_end;
else
e = segend;
@@ -199,35 +219,30 @@ static int killpad(void *segstart, void
}
-/* remove padding from a range of address space - padding is always a
- mapping of padfile*/
-void as_unpad(void *start, void *end)
+// Remove padding of 'padfile' from a range of address space.
+void as_unpad(void *start, void *end, int padfile)
{
- if (padfile == -1) /* no padfile, no padding */
- return;
-
- killpad_start = start;
- killpad_end = end;
+ static struct stat padstat;
+ killpad_extra extra;
+ int res;
- foreach_map(killpad);
-}
+ assert(padfile > 0);
-void as_closepadfile(void)
-{
- /* don't unpad */
- close(padfile);
- padfile = -1;
+ res = fstat(padfile, &padstat);
+ assert(0 == res);
+ extra.killpad_padstat = &padstat;
+ extra.killpad_start = start;
+ extra.killpad_end = end;
+ foreach_map(killpad, &extra);
}
-int as_getpadfd(void)
+void as_closepadfile(int padfile)
{
- return padfile;
+ int res = close(padfile);
+ assert(0 == res);
}
-void as_setpadfd(int fd)
-{
- as_closepadfile();
- padfile = fd;
- fstat(padfile, &padstat);
-}
+/*------------------------------------------------------------*/
+/*--- Finding auxv on the stack ---*/
+/*------------------------------------------------------------*/
struct ume_auxv *find_auxv(int *esp)
@@ -246,4 +261,7 @@ struct ume_auxv *find_auxv(int *esp)
}
+/*------------------------------------------------------------*/
+/*--- Loading ELF files ---*/
+/*------------------------------------------------------------*/
struct elfinfo *readelf(int fd, const char *filename)
@@ -300,6 +318,4 @@ struct elfinfo *readelf(int fd, const ch
}
-#define REMAINS(x, a) ((x) & ((a)-1))
-
/* Map an ELF file. Returns the brk address. */
ESZ(Addr) mapelf(struct elfinfo *e, ESZ(Addr) base)
@@ -381,5 +397,5 @@ ESZ(Addr) mapelf(struct elfinfo *e, ESZ(
}
-
+// Forward declaration.
static int do_exec_inner(const char *exe, struct exeinfo *info);
@@ -391,5 +406,6 @@ static int match_ELF(const char *hdr, in
}
-static int load_ELF(char *hdr, int len, int fd, const char *name, struct exeinfo *info)
+static int load_ELF(char *hdr, int len, int fd, const char *name,
+ struct exeinfo *info)
{
struct elfinfo *e;
@@ -531,5 +547,6 @@ static int match_script(const char *hdr,
}
-static int load_script(char *hdr, int len, int fd, const char *name, struct exeinfo *info)
+static int load_script(char *hdr, int len, int fd, const char *name,
+ struct exeinfo *info)
{
char *interp;
@@ -583,15 +600,4 @@ static int load_script(char *hdr, int le
}
-struct binfmt {
- int (*match)(const char *hdr, int len);
- int (*load) ( char *hdr, int len, int fd, const char *name, struct exeinfo *);
-};
-
-static const struct binfmt formats[] = {
- { match_ELF, load_ELF },
- { match_script, load_script },
-};
-
-
static int do_exec_inner(const char *exe, struct exeinfo *info)
{
@@ -602,4 +608,12 @@ static int do_exec_inner(const char *exe
int ret;
struct stat st;
+ static const struct {
+ int (*match)(const char *hdr, int len);
+ int (*load) ( char *hdr, int len, int fd2, const char *name,
+ struct exeinfo *);
+ } formats[] = {
+ { match_ELF, load_ELF },
+ { match_script, load_script },
+ };
fd = open(exe, O_RDONLY);
--- valgrind/coregrind/ume.h #1.8:1.9
@@ -51,4 +51,9 @@
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 ---*/
@@ -87,14 +92,9 @@ int do_exec(const char *exe, struct exei
/*------------------------------------------------------------*/
-void foreach_map(int (*fn)(void *start, void *end,
- const char *perm, off_t offset,
- int maj, int min, int ino));
-
// Padding functions used at startup to force things where we want them.
-void as_pad(void *start, void *end);
-void as_unpad(void *start, void *end);
-void as_closepadfile(void);
-int as_getpadfd(void);
-void as_setpadfd(int);
+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);
/*------------------------------------------------------------*/
--- valgrind/coregrind/vg_main.c #1.177:1.178
@@ -456,13 +456,13 @@ static void newpid(ThreadId unused)
/* Look for our AUXV table */
-static void scan_auxv(void)
+int scan_auxv(void)
{
const struct ume_auxv *auxv = find_auxv((int *)ume_exec_esp);
- int found = 0;
+ int padfile = -1, found = 0;
for (; auxv->a_type != AT_NULL; auxv++)
switch(auxv->a_type) {
case AT_UME_PADFD:
- as_setpadfd(auxv->u.a_val);
+ padfile = auxv->u.a_val;
found |= 1;
break;
@@ -478,4 +478,6 @@ static void scan_auxv(void)
exit(127);
}
+ vg_assert(padfile >= 0);
+ return padfile;
}
@@ -485,25 +487,18 @@ static void scan_auxv(void)
/*====================================================================*/
-/* Pad client space so it doesn't get filled in before the right time */
-static void layout_client_space(Addr argc_addr)
-{
- VG_(client_base) = CLIENT_BASE;
- VG_(valgrind_base) = (addr_t)&kickstart_base;
- VG_(valgrind_end) = ROUNDUP(argc_addr, 0x10000); /* stack */
-
- as_pad((void *)VG_(client_base), (void *)VG_(valgrind_base));
-}
-
-static void layout_remaining_space(float ratio)
+static void layout_remaining_space(Addr argc_addr, float ratio)
{
Int ires;
void* vres;
+ addr_t client_size, shadow_size;
- /* This tries to give the client as large as possible address space while
- * taking into account the tool's shadow needs. */
- addr_t client_size = ROUNDDN((VG_(valgrind_base) - REDZONE_SIZE) / (1. + ratio),
- CLIENT_SIZE_MULTIPLE);
- addr_t shadow_size = PGROUNDUP(client_size * ratio);
+ VG_(valgrind_base) = (addr_t)&kickstart_base;
+ VG_(valgrind_end) = ROUNDUP(argc_addr, 0x10000); // stack
+ // This gives the client the largest possible address space while
+ // taking into account the tool's shadow needs.
+ client_size = ROUNDDN((VG_(valgrind_base)-REDZONE_SIZE) / (1.+ratio),
+ CLIENT_SIZE_MULTIPLE);
+ VG_(client_base) = CLIENT_BASE;
VG_(client_end) = VG_(client_base) + client_size;
/* where !FIXED mmap goes */
@@ -511,4 +506,5 @@ static void layout_remaining_space(float
PGROUNDDN((addr_t)(client_size * CLIENT_HEAP_PROPORTION));
+ shadow_size = PGROUNDUP(client_size * ratio);
VG_(shadow_base) = VG_(client_end) + REDZONE_SIZE;
VG_(shadow_end) = VG_(shadow_base) + shadow_size;
@@ -2697,6 +2693,6 @@ void VG_(do_sanity_checks) ( Bool force_
*/
-static int prmap(void *start, void *end, const char *perm, off_t off,
- int maj, int min, int ino) {
+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",
start, end, perm, maj, min, ino);
@@ -2721,4 +2717,5 @@ int main(int argc, char **argv)
Int exitcode = 0;
vki_rlimit zero = { 0, 0 };
+ Int padfile;
//============================================================
@@ -2749,9 +2746,9 @@ int main(int argc, char **argv)
// p: n/a
//--------------------------------------------------------------
- scan_auxv();
+ padfile = scan_auxv();
if (0) {
printf("========== main() ==========\n");
- foreach_map(prmap);
+ foreach_map(prmap, /*dummy*/NULL);
}
@@ -2766,10 +2763,4 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // Begin working out address space layout
- // p: n/a
- //--------------------------------------------------------------
- layout_client_space( (Addr) & argc );
-
- //--------------------------------------------------------------
// Get valgrind args + client args (inc. from VALGRIND_OPTS/.valgrindrc).
// Pre-process the command line.
@@ -2786,5 +2777,4 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
// With client padded out, map in tool
- // p: layout_client_space() [for padding]
// p: set-libdir [for VG_(libdir)]
// p: pre_process_cmd_line_options() [for 'tool']
@@ -2799,11 +2789,10 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
// Finalise address space layout
- // p: layout_client_space(), load_tool() [for 'toolinfo']
+ // p: load_tool() [for 'toolinfo']
//--------------------------------------------------------------
- layout_remaining_space( toolinfo->shadow_ratio );
+ layout_remaining_space( (Addr) & argc, toolinfo->shadow_ratio );
//--------------------------------------------------------------
// Load client executable, finding in $PATH if necessary
- // p: layout_client_space() [so there's space]
// p: pre_process_cmd_line_options() [for 'exec', 'need_help']
// p: layout_remaining_space [so there's space]
@@ -2816,6 +2805,6 @@ int main(int argc, char **argv)
// p: load_client() [ditto]
//--------------------------------------------------------------
- as_unpad((void *)VG_(shadow_end), (void *)~0);
- as_closepadfile(); /* no more padding */
+ as_unpad((void *)VG_(shadow_end), (void *)~0, padfile);
+ as_closepadfile(padfile); // no more padding
//--------------------------------------------------------------
|
|
From: Nicholas N. <nj...@ca...> - 2004-08-05 12:16:23
|
CVS commit by nethercote:
Make error messages more informative.
M +2 -2 stage1.c 1.16 [POSSIBLY UNSAFE: printf]
M +3 -1 ume.c 1.20 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/stage1.c #1.15:1.16
@@ -150,5 +150,5 @@ static void *fix_auxv(void *v_init_esp,
can't make the new executable viable. */
if (seen != 0xf) {
- fprintf(stderr, "fix_auxv: we didn't see enough auxv entries (seen=%x)\n", seen);
+ fprintf(stderr, "valgrind: we didn't see enough auxv entries (seen=%x)\n", seen);
exit(1);
}
@@ -189,5 +189,5 @@ static void hoops(void)
if (err != 0) {
- fprintf(stderr, "failed to load %s: %s\n",
+ fprintf(stderr, "valgrind: failed to load %s: %s\n",
buf, strerror(err));
exit(1);
--- valgrind/coregrind/ume.c #1.19:1.20
@@ -492,5 +492,7 @@ static int load_ELF(char *hdr, int len,
(minaddr < info->exe_base ||
maxaddr > info->exe_end)) {
- fprintf(stderr, "Executable is mapped outside of range %p-%p\n",
+ fprintf(stderr, "Executable range %p-%p is outside the\n"
+ "acceptable range %p-%p\n",
+ (void *)minaddr, (void *)maxaddr,
(void *)info->exe_base, (void *)info->exe_end);
return ENOMEM;
|
|
From: Nicholas N. <nj...@ca...> - 2004-08-30 19:36:54
|
CVS commit by nethercote:
Print a message if shadow memory cannot be allocated, rather than just
asserting.
M +7 -1 vg_main.c 1.198 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/vg_main.c #1.197:1.198
@@ -495,5 +495,11 @@ static void layout_remaining_space(Addr
vres = mmap((char *)VG_(shadow_base), shadow_size, PROT_NONE,
MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0);
- vg_assert((void*)-1 != vres);
+ if ((void*)-1 == vres) {
+ fprintf(stderr,
+ "valgrind: Couldn't allocate address space for shadow memory\n"
+ "valgrind: Are you using a kernel with a small user address space,\n"
+ "valgrind: or do you have your virtual memory size limited?\n");
+ exit(1);
+ }
}
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-08-30 19:42:22
|
On Mon, 30 Aug 2004, Nicholas Nethercote wrote: > CVS commit by nethercote: > > Print a message if shadow memory cannot be allocated, rather than just > asserting. That's my last change before the release; I won't touch anything else. N |
|
From: Julian S. <js...@ac...> - 2004-08-31 00:23:11
|
> That's my last change before the release; I won't touch anything else. Good. I think I too am done committing. Please, nobody commit anything for the time being. Now I wait for the nightly builds. J |
|
From: Jeremy F. <je...@go...> - 2004-09-08 20:05:36
|
CVS commit by fitzhardinge:
Pull permissions checking out into a separate function to clean
things up a bit.
M +57 -35 ume.c 1.26 [POSSIBLY UNSAFE: printf]
--- valgrind/coregrind/ume.c #1.25:1.26
@@ -612,43 +612,28 @@ static int load_script(char *hdr, int le
}
-static int do_exec_inner(const char *exe, struct exeinfo *info)
+/*
+ Emulate the normal Unix permissions checking algorithm.
+
+ If owner matches, then use the owner permissions, else
+ if group matches, then use the group permissions, else
+ use other permissions.
+
+ Note that we can't deal with SUID/SGID, so we refuse to run them
+ (otherwise the executable may misbehave if it doesn't have the
+ permissions it thinks it does).
+*/
+static int check_perms(int fd)
{
- int fd;
- char buf[VKI_BYTES_PER_PAGE];
- int bufsz;
- int i;
- int ret;
struct stat st;
- static const struct {
- int (*match)(const char *hdr, int len);
- int (*load) ( char *hdr, int len, int fd2, const char *name,
- struct exeinfo *);
- } formats[] = {
- { match_ELF, load_ELF },
- { match_script, load_script },
- };
-
- fd = open(exe, O_RDONLY);
- if (fd == -1) {
- if (0)
- fprintf(stderr, "Can't open executable %s: %s\n",
- exe, strerror(errno));
- return errno;
- }
if (fstat(fd, &st) == -1)
return errno;
- else {
- uid_t uid = geteuid();
- gid_t gid = getegid();
- gid_t groups[32];
- int ngrp = getgroups(32, groups);
if (st.st_mode & (S_ISUID | S_ISGID)) {
- fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe);
+ //fprintf(stderr, "Can't execute suid/sgid executable %s\n", exe);
return EACCES;
}
- if (uid == st.st_uid) {
+ if (geteuid() == st.st_uid) {
if (!(st.st_mode & S_IXUSR))
return EACCES;
@@ -656,7 +641,11 @@ static int do_exec_inner(const char *exe
int grpmatch = 0;
- if (gid == st.st_gid)
+ if (getegid() == st.st_gid)
grpmatch = 1;
- else
+ else {
+ gid_t groups[32];
+ int ngrp = getgroups(32, groups);
+ int i;
+
for(i = 0; i < ngrp; i++)
if (groups[i] == st.st_gid) {
@@ -664,4 +653,5 @@ static int do_exec_inner(const char *exe
break;
}
+ }
if (grpmatch) {
@@ -671,4 +661,36 @@ static int do_exec_inner(const char *exe
return EACCES;
}
+
+ return 0;
+}
+
+static int do_exec_inner(const char *exe, struct exeinfo *info)
+{
+ int fd;
+ char buf[VKI_BYTES_PER_PAGE];
+ int bufsz;
+ int i;
+ int ret;
+ static const struct {
+ int (*match)(const char *hdr, int len);
+ int (*load) ( char *hdr, int len, int fd2, const char *name,
+ struct exeinfo *);
+ } formats[] = {
+ { match_ELF, load_ELF },
+ { match_script, load_script },
+ };
+
+ fd = open(exe, O_RDONLY);
+ if (fd == -1) {
+ if (0)
+ fprintf(stderr, "Can't open executable %s: %s\n",
+ exe, strerror(errno));
+ return errno;
+ }
+
+ int err = check_perms(fd);
+ if (err != 0) {
+ close(fd);
+ return err;
}
|
|
From: Nicholas N. <nj...@ca...> - 2004-10-09 19:08:11
|
CVS commit by nethercote:
Arch-abstraction:
- abstract out three ELF constants
M +7 -6 ume.c 1.29 [POSSIBLY UNSAFE: printf]
M +3 -3 vg_signals.c 1.90
M +3 -3 vg_symtab2.c 1.90
M +9 -0 x86/core_arch.h 1.9
--- valgrind/coregrind/ume.c #1.28:1.29
@@ -278,10 +278,11 @@ struct elfinfo *readelf(int fd, const ch
return NULL;
}
- if (e->e.e_ident[EI_CLASS] != ELFCLASS32) {
- fprintf(stderr, "valgrind: Can only handle 32-bit executables\n");
+ if (e->e.e_ident[EI_CLASS] != VG_ELF_CLASS) {
+ fprintf(stderr, "valgrind: wrong executable class (eg. 32-bit instead\n"
+ "valgrind: of 64-bit)\n");
return NULL;
}
- if (e->e.e_ident[EI_DATA] != ELFDATA2LSB) {
- fprintf(stderr, "valgrind: Expecting little-endian\n");
+ if (e->e.e_ident[EI_DATA] != VG_ELF_ENDIANNESS) {
+ fprintf(stderr, "valgrind: wrong endian-ness\n");
return NULL;
}
@@ -291,6 +292,6 @@ struct elfinfo *readelf(int fd, const ch
}
- if (e->e.e_machine != EM_386) {
- fprintf(stderr, "valgrind: need x86\n");
+ if (e->e.e_machine != VG_ELF_MACHINE) {
+ fprintf(stderr, "valgrind: wrong architecture\n");
return NULL;
}
--- valgrind/coregrind/vg_signals.c #1.89:1.90
@@ -1015,10 +1015,10 @@ static void fill_ehdr(Elf32_Ehdr *ehdr,
VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG);
- ehdr->e_ident[EI_CLASS] = ELFCLASS32;
- ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
+ ehdr->e_ident[EI_CLASS] = VG_ELF_CLASS;
+ ehdr->e_ident[EI_DATA] = VG_ELF_ENDIANNESS;
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
ehdr->e_type = ET_CORE;
- ehdr->e_machine = EM_386;
+ ehdr->e_machine = VG_ELF_MACHINE;
ehdr->e_version = EV_CURRENT;
ehdr->e_entry = 0;
--- valgrind/coregrind/vg_symtab2.c #1.89:1.90
@@ -759,9 +759,9 @@ Bool VG_(is_object_file)(const void *buf
&& ehdr->e_ident[EI_MAG2] == 'L'
&& ehdr->e_ident[EI_MAG3] == 'F');
- ok &= (ehdr->e_ident[EI_CLASS] == ELFCLASS32
- && ehdr->e_ident[EI_DATA] == ELFDATA2LSB
+ ok &= (ehdr->e_ident[EI_CLASS] == VG_ELF_CLASS
+ && ehdr->e_ident[EI_DATA] == VG_ELF_ENDIANNESS
&& ehdr->e_ident[EI_VERSION] == EV_CURRENT);
ok &= (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN);
- ok &= (ehdr->e_machine == EM_386);
+ ok &= (ehdr->e_machine == VG_ELF_MACHINE);
ok &= (ehdr->e_version == EV_CURRENT);
ok &= (ehdr->e_shstrndx != SHN_UNDEF);
--- valgrind/coregrind/x86/core_arch.h #1.8:1.9
@@ -130,4 +130,13 @@ extern Int VGOFF_(helper_undefined_instr
/* ---------------------------------------------------------------------
+ Elf stuff
+ ------------------------------------------------------------------ */
+
+#define VG_ELF_ENDIANNESS ELFDATA2LSB
+#define VG_ELF_MACHINE EM_386
+#define VG_ELF_CLASS ELFCLASS32
+
+
+/* ---------------------------------------------------------------------
Exports of vg_helpers.S
------------------------------------------------------------------ */
|
|
From: Nicholas N. <nj...@ca...> - 2004-10-13 17:29:07
|
CVS commit by nethercote:
Cleaned up ume.h by moving some functions around.
M +90 -0 stage1.c 1.21 [POSSIBLY UNSAFE: printf]
M +1 -127 ume.c 1.30 [POSSIBLY UNSAFE: printf]
M +9 -19 ume.h 1.10
M +66 -1 vg_main.c 1.214
--- valgrind/coregrind/stage1.c #1.20:1.21
@@ -31,4 +31,5 @@
#define _FILE_OFFSET_BITS 64
+#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -37,5 +38,7 @@
#include <signal.h>
#include <fcntl.h>
+#include <sys/mman.h>
#include <sys/resource.h>
+#include <unistd.h>
#include "core.h"
@@ -52,4 +55,8 @@ static const char *valgrind_lib = VG_LIB
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.
@@ -154,4 +161,87 @@ static void *fix_auxv(void *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) {
--- valgrind/coregrind/ume.c #1.29:1.30
@@ -56,7 +56,5 @@ static void check_mmap(void* res, void*
{
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);
}
@@ -113,128 +111,4 @@ void foreach_map(int (*fn)(char *start,
}
-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 ---*/
--- valgrind/coregrind/ume.h #1.9:1.10
@@ -40,4 +40,13 @@
/*------------------------------------------------------------*/
+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
@@ -51,13 +60,4 @@
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().
@@ -89,14 +89,4 @@ int do_exec(const char *exe, struct exei
/*------------------------------------------------------------*/
-/*--- 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 ---*/
/*------------------------------------------------------------*/
--- valgrind/coregrind/vg_main.c #1.213:1.214
@@ -1401,4 +1401,69 @@ static void load_client(char* cl_argv[],
}
+/*====================================================================*/
+/*=== 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);
+}
+
/*====================================================================*/
@@ -2571,5 +2636,5 @@ int main(int argc, char **argv)
//--------------------------------------------------------------
- // 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]
|
|
From: Nicholas N. <nj...@ca...> - 2004-11-01 16:52:50
|
CVS commit by nethercote:
64-bit cleanness tweaks.
M +2 -1 stage1.c 1.29 [POSSIBLY UNSAFE: printf]
M +1 -1 ume.c 1.35 [POSSIBLY UNSAFE: scanf]
M +3 -3 vg_main.c 1.224 [POSSIBLY UNSAFE: printf]
M +2 -2 vg_proxylwp.c 1.28
--- valgrind/coregrind/stage1.c #1.28:1.29
@@ -116,5 +116,6 @@ static void *fix_auxv(void *v_init_esp,
for(; auxv->a_type != AT_NULL; auxv++) {
if (0)
- printf("doing auxv %p %4x: %d %p\n", auxv, auxv->a_type, auxv->u.a_val, auxv->u.a_ptr);
+ printf("doing auxv %p %4lld: %lld %p\n",
+ auxv, (ULong)auxv->a_type, (ULong)auxv->u.a_val, auxv->u.a_ptr);
switch(auxv->a_type) {
--- valgrind/coregrind/ume.c #1.34:1.35
@@ -101,5 +101,5 @@ void foreach_map(int (*fn)(char *start,
void *segstart, *segend;
- sscanf(bufptr, "%p-%p %s %Lx %x:%x %d",
+ sscanf(bufptr, "%p-%p %s %llx %x:%x %d",
&segstart, &segend, perm, &offset, &maj, &min, &ino);
bufptr = strchr(bufptr, '\n');
--- valgrind/coregrind/vg_main.c #1.223:1.224
@@ -881,5 +881,5 @@ static char *copy_str(char **tab, const
if (0)
- printf("copied %p \"%s\" len %d\n", orig, orig, cp-orig);
+ printf("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig));
*tab = cp;
@@ -1129,5 +1129,5 @@ static Addr setup_client_stack(void* ini
/* stomp out anything we don't know about */
if (0)
- printf("stomping auxv entry %d\n", auxv->a_type);
+ printf("stomping auxv entry %lld\n", (ULong)auxv->a_type);
auxv->a_type = AT_IGNORE;
break;
@@ -1285,5 +1285,5 @@ static void load_tool( const char *tooln
VG_CORE_INTERFACE_MAJOR_VERSION,
VG_CORE_INTERFACE_MINOR_VERSION,
- sizeof(*toolinfo),
+ (Int)sizeof(*toolinfo),
toolinfo->interface_major_version,
toolinfo->interface_minor_version,
--- valgrind/coregrind/vg_proxylwp.c #1.27:1.28
@@ -1020,7 +1020,7 @@ static void sys_wait_results(Bool block,
case PX_RunSyscall:
if (VG_(clo_trace_syscalls))
- VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_RunSyscall for TID %d: syscall %d result %d",
+ VG_(message)(Vg_DebugMsg, "sys_wait_results: got PX_RunSyscall for TID %d: syscall %d result %lld",
res.tid, tst->syscallno,
- PLATFORM_SYSCALL_RET(tst->arch));
+ (UWord)PLATFORM_SYSCALL_RET(tst->arch));
if (tst->status != VgTs_WaitSys)
|
|
From: Jeremy F. <je...@go...> - 2003-12-16 22:42:41
|
On Tue, 2003-12-16 at 14:26, Jeremy Fitzhardinge wrote: > CVS commit by fitzhardinge: > > Auto-generate stage2.lds so that the linker script matches the local > linker. > > > M +1 -1 Makefile.am 1.62 > M +1 -3 stage1.c 1.2 [POSSIBLY UNSAFE: printf] > M +6 -4 stage2.c 1.2 > M +5 -0 ume.c 1.2 [POSSIBLY UNSAFE: printf] > M +2 -0 vg_errcontext.c 1.47 > M +6 -2 vg_include.h 1.159 > M +1 -1 vg_intercept.c 1.27 > M +11 -6 vg_main.c 1.129 > M +1 -1 vg_syscalls.c 1.68 > M +10 -1 x86/Makefile.am 1.2 > R x86/stage2.lds 1.1 Oops. I thought editing the file list in the commit message would actually have an effect. Oh well, there's other fixes here too, which I'd intended to check in separately. |