|
From: <sv...@va...> - 2009-06-30 06:07:19
|
Author: njn
Date: 2009-06-30 07:06:14 +0100 (Tue, 30 Jun 2009)
New Revision: 10387
Log:
Fix a problem with r10384: it was failing to read the ELF header if the
executable was less than 4096 bytes.
Modified:
trunk/coregrind/launcher-linux.c
Modified: trunk/coregrind/launcher-linux.c
===================================================================
--- trunk/coregrind/launcher-linux.c 2009-06-29 21:00:33 UTC (rev 10386)
+++ trunk/coregrind/launcher-linux.c 2009-06-30 06:06:14 UTC (rev 10387)
@@ -113,9 +113,8 @@
{
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 @@
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++;
+ // Skip whitespace.
+ while (1) {
+ if (i == n_bytes) return NULL;
+ if (' ' != header[i] && '\t' == header[i]) break;
+ i++;
+ }
- for (interpend = interp; !isspace(*interpend); interpend++)
- ;
+ // 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';
- *interpend = '\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 @@
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 @@
}
}
- munmap(header, pagesize);
-
return platform;
}
@@ -266,7 +273,7 @@
/* 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 @@
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.");
|