aboutsummaryrefslogtreecommitdiff
path: root/coregrind
diff options
context:
space:
mode:
authornjn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-06-30 06:06:14 +0000
committernjn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-06-30 06:06:14 +0000
commit58899e8e2af51859289d0badea881b7b72c3fb13 (patch)
tree006dade0827b7a07b4e10f70bf99b5e7423909e9 /coregrind
parent018916e835a3f21a278a16ac012b021778d1b070 (diff)
downloadvalgrind-58899e8e2af51859289d0badea881b7b72c3fb13.tar.gz
Fix a problem with r10384: it was failing to read the ELF header if the
executable was less than 4096 bytes. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10387 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'coregrind')
-rw-r--r--coregrind/launcher-linux.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c
index 34754d02a..7b89969ae 100644
--- a/coregrind/launcher-linux.c
+++ b/coregrind/launcher-linux.c
@@ -113,9 +113,8 @@ static const char *select_platform(const char *clientname)
{
int fd;
uint8_t header[4096];
- ssize_t bytes;
+ ssize_t n_bytes;
const char *platform = NULL;
- long pagesize = sysconf(_SC_PAGESIZE);
if (strchr(clientname, '/') == NULL)
clientname = find_client(clientname);
@@ -124,28 +123,38 @@ static const char *select_platform(const char *clientname)
return NULL;
// barf("open(%s): %s", clientname, strerror(errno));
- bytes = read(fd, header, sizeof(header));
+ n_bytes = read(fd, header, sizeof(header));
close(fd);
- if (bytes != sizeof(header)) {
+ if (n_bytes < 2) {
return NULL;
}
if (header[0] == '#' && header[1] == '!') {
+ int i = 2;
char *interp = (char *)header + 2;
- char *interpend;
- while (*interp == ' ' || *interp == '\t')
- interp++;
-
- for (interpend = interp; !isspace(*interpend); interpend++)
- ;
+ // Skip whitespace.
+ while (1) {
+ if (i == n_bytes) return NULL;
+ if (' ' != header[i] && '\t' == header[i]) break;
+ i++;
+ }
- *interpend = '\0';
+ // Get the interpreter name.
+ interp = &header[i];
+ while (1) {
+ if (i == n_bytes) break;
+ if (isspace(header[i])) break;
+ i++;
+ }
+ if (i == n_bytes) return NULL;
+ header[i] = '\0';
platform = select_platform(interp);
- } else if (memcmp(header, ELFMAG, SELFMAG) == 0) {
- if (header[EI_CLASS] == ELFCLASS32) {
+ } else if (n_bytes >= SELFMAG && memcmp(header, ELFMAG, SELFMAG) == 0) {
+
+ if (n_bytes >= sizeof(Elf32_Ehdr) && header[EI_CLASS] == ELFCLASS32) {
const Elf32_Ehdr *ehdr = (Elf32_Ehdr *)header;
if (header[EI_DATA] == ELFDATA2LSB) {
@@ -160,7 +169,7 @@ static const char *select_platform(const char *clientname)
platform = "ppc32-linux";
}
}
- } else if (header[EI_CLASS] == ELFCLASS64) {
+ } else if (n_bytes >= sizeof(Elf64_Ehdr) && header[EI_CLASS] == ELFCLASS64) {
const Elf64_Ehdr *ehdr = (Elf64_Ehdr *)header;
if (header[EI_DATA] == ELFDATA2LSB) {
@@ -177,8 +186,6 @@ static const char *select_platform(const char *clientname)
}
}
- munmap(header, pagesize);
-
return platform;
}
@@ -266,7 +273,7 @@ int main(int argc, char** argv, char** envp)
/* Figure out the name of this executable (viz, the launcher), so
we can tell stage2. stage2 will use the name for recursive
- invokations of valgrind on child processes. */
+ invocations of valgrind on child processes. */
memset(launcher_name, 0, PATH_MAX+1);
r = readlink("/proc/self/exe", launcher_name, PATH_MAX);
if (r == -1) {
@@ -306,7 +313,7 @@ int main(int argc, char** argv, char** envp)
if (cp != NULL)
valgrind_lib = cp;
- /* Build the stage2 invokation, and execve it. Bye! */
+ /* Build the stage2 invocation, and execve it. Bye! */
toolfile = malloc(strlen(valgrind_lib) + strlen(toolname) + strlen(platform) + 3);
if (toolfile == NULL)
barf("malloc of toolfile failed.");