Clean up gcc compiler warnings
[dyninst.git] / common / src / linuxKludges.C
1 /*
2  * Copyright (c) 1996-2007 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "common/h/headers.h"
33 #include "common/h/parseauxv.h"
34
35 #include <elf.h>
36
37 #include <vector>
38
39 typedef int (*intKludge)();
40
41 int P_getopt(int argc, char *argv[], const char *optstring)
42 {
43   /* On linux we prepend a + character */
44   char newopt[strlen(optstring)+5];
45   strcpy(newopt, "+");
46   strcat(newopt, optstring);
47   return getopt(argc, argv, newopt);
48 }
49
50 int P_copy(const char *from, const char *to) {
51     int from_fd = P_open(from, O_RDONLY, 0);
52     if (from_fd == -1)  {
53         perror("Opening from file in copy"); 
54         return -1;
55     }
56     int to_fd = P_open(to, O_WRONLY | O_APPEND | O_CREAT | O_TRUNC, 0);
57     if (to_fd == -1) {
58         perror("Opening to file in copy");
59         close(from_fd);
60         return -1;
61     }
62
63     char buffer[1048576];
64     while(true) {
65         int amount = read(from_fd, buffer, 1048576);
66         if (amount == -1) {
67             perror("Reading in file copy");
68             return -1;
69         }
70         write(to_fd, buffer, amount);
71         if (amount < 1048576) break;
72     }
73     close(to_fd);
74     close(from_fd);
75     return 0;
76 }
77
78
79 unsigned long long PDYN_div1000(unsigned long long in) {
80    /* Divides by 1000 without an integer division instruction or library call, both of
81     * which are slow.
82     * We do only shifts, adds, and subtracts.
83     *
84     * We divide by 1000 in this way:
85     * multiply by 1/1000, or multiply by (1/1000)*2^30 and then right-shift by 30.
86     * So what is 1/1000 * 2^30?
87     * It is 1,073,742.   (actually this is rounded)
88     * So we can multiply by 1,073,742 and then right-shift by 30 (neat, eh?)
89     *
90     * Now for multiplying by 1,073,742...
91     * 1,073,742 = (1,048,576 + 16384 + 8192 + 512 + 64 + 8 + 4 + 2)
92     * or, slightly optimized:
93     * = (1,048,576 + 16384 + 8192 + 512 + 64 + 16 - 2)
94     * for a total of 8 shifts and 6 add/subs, or 14 operations.
95     *
96     */
97
98    unsigned long long temp = in << 20; // multiply by 1,048,576
99       // beware of overflow; left shift by 20 is quite a lot.
100       // If you know that the input fits in 32 bits (4 billion) then
101       // no problem.  But if it's much bigger then start worrying...
102
103    temp += in << 14; // 16384
104    temp += in << 13; // 8192
105    temp += in << 9;  // 512
106    temp += in << 6;  // 64
107    temp += in << 4;  // 16
108    temp -= in >> 2;  // 2
109
110    return (temp >> 30); // divide by 2^30
111 }
112
113 unsigned long long PDYN_divMillion(unsigned long long in) {
114    /* Divides by 1,000,000 without an integer division instruction or library call,
115     * both of which are slow.
116     * We do only shifts, adds, and subtracts.
117     *
118     * We divide by 1,000,000 in this way:
119     * multiply by 1/1,000,000, or multiply by (1/1,000,000)*2^30 and then right-shift
120     * by 30.  So what is 1/1,000,000 * 2^30?
121     * It is 1,074.   (actually this is rounded)
122     * So we can multiply by 1,074 and then right-shift by 30 (neat, eh?)
123     *
124     * Now for multiplying by 1,074
125     * 1,074 = (1024 + 32 + 16 + 2)
126     * for a total of 4 shifts and 4 add/subs, or 8 operations.
127     *
128     * Note: compare with div1000 -- it's cheaper to divide by a million than
129     *       by a thousand (!)
130     *
131     */
132
133    unsigned long long temp = in << 10; // multiply by 1024
134       // beware of overflow...if the input arg uses more than 52 bits
135       // than start worrying about whether (in << 10) plus the smaller additions
136       // we're gonna do next will fit in 64...
137
138    temp += in << 5; // 32
139    temp += in << 4; // 16
140    temp += in << 1; // 2
141
142    return (temp >> 30); // divide by 2^30
143 }
144
145 unsigned long long PDYN_mulMillion(unsigned long long in) {
146    unsigned long long result = in;
147
148    /* multiply by 125 by multiplying by 128 and subtracting 3x */
149    result = (result << 7) - result - result - result;
150
151    /* multiply by 125 again, for a total of 15625x */
152    result = (result << 7) - result - result - result;
153
154    /* multiply by 64, for a total of 1,000,000x */
155    result <<= 6;
156
157    /* cost was: 3 shifts and 6 subtracts
158     * cost of calling mul1000(mul1000()) would be: 6 shifts and 4 subtracts
159     *
160     * Another algorithm is to multiply by 2^6 and then 5^6.
161     * The former is super-cheap (one shift); the latter is more expensive.
162     * 5^6 = 15625 = 16384 - 512 - 256 + 8 + 1
163     * so multiplying by 5^6 means 4 shift operations and 4 add/sub ops
164     * so multiplying by 1000000 means 5 shift operations and 4 add/sub ops.
165     * That may or may not be cheaper than what we're doing (3 shifts; 6 subtracts);
166     * I'm not sure.  --ari
167     */
168
169    return result;
170 }
171
172 bool PtraceBulkRead(Address inTraced, unsigned size, const void *inSelf, int pid)
173 {
174    const unsigned char *ap = (const unsigned char*) inTraced; 
175    unsigned char *dp = (unsigned char *) const_cast<void *>(inSelf);
176    Address w = 0x0;               /* ptrace I/O buffer */
177    int len = sizeof(void *);
178    unsigned cnt;
179    
180    if (0 == size) {
181       return true;
182    }
183    
184    if ((cnt = ((Address)ap) % len)) {
185       /* Start of request is not aligned. */
186       unsigned char *p = (unsigned char*) &w;
187       
188       /* Read the segment containing the unaligned portion, and
189          copy what was requested to DP. */
190       errno = 0;
191       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) (ap-cnt), w, len);
192       if (errno) {
193          return false;
194       }
195       for (unsigned i = 0; i < len-cnt && i < size; i++)
196          dp[i] = p[cnt+i];
197       
198       if (len-cnt >= size) {
199          return true; /* done */
200       }
201       
202       dp += len-cnt;
203       ap += len-cnt;
204       size -= len-cnt;
205    }
206    /* Copy aligned portion */
207    while (size >= (u_int)len) {
208       errno = 0;
209       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0, len);
210       if (errno) {
211          return false;
212       }
213       memcpy(dp, &w, len);
214       dp += len;
215       ap += len;
216       size -= len;
217    }
218    
219    if (size > 0) {
220       /* Some unaligned data remains */
221       unsigned char *p = (unsigned char *) &w;
222       
223       /* Read the segment containing the unaligned portion, and
224          copy what was requested to DP. */
225       errno = 0;
226       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0, len);
227       if (errno) {
228          return false;
229       }
230       for (unsigned i = 0; i < size; i++)
231          dp[i] = p[i];
232    }
233    return true;
234
235 }
236
237 // These constants are not defined in all versions of elf.h
238 #ifndef AT_BASE
239 #define AT_BASE 7
240 #endif
241 #ifndef AT_NULL
242 #define AT_NULL 0
243 #endif
244 #ifndef AT_SYSINFO
245 #define AT_SYSINFO 32
246 #endif
247 #ifndef AT_SYSINFO_EHDR
248 #define AT_SYSINFO_EHDR 33
249 #endif
250
251 static bool couldBeVsyscallPage(map_entries *entry, bool strict, Address) {
252    if (strict) {
253        if (entry->prems != PREMS_PRIVATE)
254          return false;
255       if (entry->path[0] != '\0')
256          return false;
257    }
258    if (entry->offset != 0)
259       return false;
260    if (entry->dev_major != 0 || entry->dev_minor != 0)
261       return false;
262    if (entry->inode != 0)
263       return false;
264
265    return true;
266 }
267
268 bool AuxvParser::readAuxvInfo()
269 {
270   /**
271    * The location of the vsyscall is stored in /proc/PID/auxv in Linux 2.6.
272    * auxv consists of a list of name/value pairs, ending with the AT_NULL
273    * name.  There isn't a direct way to get the vsyscall info on Linux 2.4
274    **/
275   uint32_t *buffer32 = NULL;
276   uint64_t *buffer64 = NULL;
277   unsigned pos = 0;
278   Address dso_start = 0x0, text_start = 0x0;
279   unsigned page_size = 0x0;
280
281   struct {
282     unsigned long type;
283     unsigned long value;
284   } auxv_entry;
285
286   /**
287    * Try to read from /proc/%d/auxv.  On Linux 2.4 systems auxv
288    * doesn't exist, which is okay because vsyscall isn't used.
289    * On latter 2.6 kernels the AT_SYSINFO field isn't present,
290    * so we have to resort to more "extreme" measures.
291    **/
292   buffer64 = (uint64_t *) readAuxvFromProc();
293   if (!buffer64) 
294      buffer64 = (uint64_t *) readAuxvFromStack();
295   if (!buffer64)
296      return false;
297   buffer32 = (uint32_t *) buffer64;
298   do {
299      /**Fill in the auxv_entry structure.  We may have to do different
300       * size reads depending on the address space.  No matter which
301       * size we read, we'll fill the data in to auxv_entry, which may
302       * involve a size shift up.
303       **/
304      if (addr_size == 4) {
305         auxv_entry.type = (unsigned long) buffer32[pos];
306         pos++;
307         auxv_entry.value = (unsigned long) buffer32[pos];
308         pos++;
309      }
310      else {
311         auxv_entry.type = (unsigned long) buffer64[pos];
312         pos++;
313         auxv_entry.value = (unsigned long) buffer64[pos];
314         pos++;
315      }
316      
317      if (auxv_entry.type == AT_SYSINFO)
318         text_start = auxv_entry.value;
319      else if (auxv_entry.type == AT_SYSINFO_EHDR)
320         dso_start = auxv_entry.value;
321      else if (auxv_entry.type == AT_PAGESZ)
322         page_size = auxv_entry.value;
323      else if (auxv_entry.type == AT_BASE)
324         interpreter_base = auxv_entry.value;
325   } while (auxv_entry.type != AT_NULL);
326
327   if (buffer64)
328      free(buffer64);
329   if (!page_size)
330      page_size = getpagesize();
331   /**
332    * Even if we found dso_start in /proc/pid/auxv, the vsyscall 'page'
333    * can be larger than a single page.  Thus we look through /proc/pid/maps
334    * for known, default, or guessed start address(es).
335    **/
336   std::vector<Address> guessed_addrs;
337   
338   /* The first thing to check is the auxvinfo, if we have any. */
339   if( dso_start != 0x0 ) 
340      guessed_addrs.push_back( dso_start );
341     
342   /**
343    * We'll make several educated attempts at guessing an address
344    * for the vsyscall page.  After deciding on a guess, we'll try to
345    * verify that using /proc/pid/maps.
346    **/
347   
348   // Guess some constants that we've seen before.
349 #if defined(arch_x86) 
350   guessed_addrs.push_back(0xffffe000); //Many early 2.6 systems
351   guessed_addrs.push_back(0xffffd000); //RHEL4
352 #elif defined(arch_ia64)
353   guessed_addrs.push_back(0xa000000000000000); 
354   guessed_addrs.push_back(0xa000000000010000); 
355   guessed_addrs.push_back(0xa000000000020000); //Juniper & Hogan
356 #endif
357 #if defined(arch_x86_64)
358   guessed_addrs.push_back(0xffffffffff600000);
359 #endif
360
361   /**
362    * Look through every entry in /proc/maps, and compare it to every 
363    * entry in guessed_addrs.  If a guessed_addr looks like the right
364    * thing, then we'll go ahead and call it the vsyscall page.
365    **/
366   unsigned num_maps;
367   map_entries *secondary_match = NULL;
368   map_entries *maps = getLinuxMaps(pid, num_maps);
369   for (unsigned i=0; i<guessed_addrs.size(); i++) {
370      Address addr = guessed_addrs[i];
371      for (unsigned j=0; j<num_maps; j++) {
372         map_entries *entry = &(maps[j]);
373         if (addr < entry->start || addr >= entry->end)
374            continue;
375
376         if (dso_start == entry->start ||
377             couldBeVsyscallPage(entry, true, page_size)) {
378            //We found a possible page using a strict check. 
379            // This is really likely to be it.
380            vsyscall_base = entry->start;
381            vsyscall_end = entry->end;
382            vsyscall_text = text_start;
383            found_vsyscall = true;
384            free(maps);
385            return true;
386         }
387
388         if (couldBeVsyscallPage(entry, false, page_size)) {
389            //We found an entry that loosely looks like the
390            // vsyscall page.  Let's hang onto this and return 
391            // it if we find nothing else.
392            secondary_match = entry;
393         }
394      }  
395   }
396
397   /**
398    * There were no hits using our guessed_addrs scheme.  Let's
399    * try to look at every entry in the maps table (not just the 
400    * guessed addresses), and see if any of those look like a vsyscall page.
401    **/
402   for (unsigned i=0; i<num_maps; i++) {
403      if (couldBeVsyscallPage(&(maps[i]), true, page_size)) {
404         vsyscall_base = maps[i].start;
405         vsyscall_end = maps[i].end;
406         vsyscall_text = text_start;
407         found_vsyscall = true;
408         free(maps);
409         return true;
410      }
411   }
412
413   /**
414    * Return any secondary possiblitiy pages we found in our earlier search.
415    **/
416   if (secondary_match) {
417      vsyscall_base = secondary_match->start;
418      vsyscall_end = secondary_match->end;
419      vsyscall_text = text_start;
420      found_vsyscall = true;
421      free(maps);
422      return true;
423   }
424
425   /**
426    * Time to give up.  Sigh.
427    **/
428   found_vsyscall = false;
429   free(maps);
430   return false;
431 }
432
433 #if 0
434 /**
435  * get_word_at is a helper function for readAuxvFromStack.  It reads
436  * a word out of the mutatee's stack via the debugger interface, and
437  * it keeps the word cached for future reads.
438  * The gwa_* global variables are basically parameters to get_word_at
439  * and should be reset before every call
440  *
441  * gwa_buffer is a cache of data we've read before.  It's backwards 
442  * for convience, higher addresses are cached towards the base of gwa_buffer
443  * and lower addresses are cached at the top.  This is because we read from
444  * high addresses to low ones, but we want to start caching at the start of
445  * gwa_buffer.
446  **/
447 static unsigned long *gwa_buffer = NULL;
448 static unsigned gwa_size = 0; 
449 static unsigned gwa_pos = 0;
450 static unsigned long gwa_base_addr = 0;
451
452 static unsigned long get_word_at(process *p, unsigned long addr, bool &err) {
453    bool result;
454    unsigned word_size = p->getAddressWidth();
455    unsigned long word;
456
457    /**
458     * On AMD64 controlling 32-bit mutatee words are 32 bits long.
459     * We don't want to deal with this now, so treat as a 64 bit read
460     * (from aligned_addr) and then pick the correct 32 bits to return
461     * at the end of this function.
462     **/
463    unsigned long aligned_addr = addr;
464    if (word_size == 4 && sizeof(long) == 8 && addr % 8 == 4)
465       aligned_addr -= 4;
466
467    /**
468     * Allocate gwa_buffer on first call
469     **/
470    if (gwa_buffer == NULL) {
471       gwa_buffer = (unsigned long *) malloc(gwa_size);
472    }
473
474    /**
475     * If gwa_buffer isn't big enough, grow it.
476     **/
477    if (gwa_base_addr - gwa_size >= aligned_addr) {
478       while (gwa_base_addr - gwa_size >= aligned_addr)
479          gwa_size = gwa_size * 2;
480       gwa_buffer = (unsigned long *) realloc(gwa_buffer, gwa_size);
481    }
482
483    /**
484     * Keep adding words to the cache (gwa_buffer) until we've cached
485     * the word the user is interested in.
486     **/
487    while (gwa_base_addr - (gwa_pos * sizeof(long)) >= aligned_addr) {
488       result = p->readDataSpace((void *) aligned_addr, sizeof(long), &word, false);
489       if (!result) {
490          err = true;
491          return 0x0;
492       }
493       gwa_buffer[gwa_pos] = word;
494       gwa_pos++;
495    }
496
497    /**
498     * Return the word the user wants out of the cache.  'word' is the
499     * long value we want to return.  On 64-bit mutator/32-bit mutatees
500     * we may need to return a specific 32-bits of word.
501     **/
502    word = gwa_buffer[(gwa_base_addr - aligned_addr) / sizeof(long)];
503
504    if (word_size == 4 && sizeof(long) == 8 && addr % 8 == 4) {
505       //64-bit mutator, 32 bit mutatee, looking for unaligned word
506       uint32_t *words = (uint32_t *) &word;
507       return (long) words[1];
508    }
509    else if (word_size == 4 && sizeof(long) == 8)
510    {
511       //64-bit mutator, 32 bit mutatee, looking for aligned word
512       uint32_t *words = (uint32_t *) &word;
513       return (long) words[0];
514    }
515    else
516    {
517       //mutator and mutatee are same size
518       return word;
519    }
520 }
521
522
523 /**
524  * Another helper function for readAuxvInfoFromStack.  We want to know
525  * the top byte of the stack.  Unfortunately, if we're running this it's
526  * probably because /proc/PID/ isn't reliable, so we can't use maps.  
527  * Check the machine's stack pointer, page align it, and start walking
528  * back looking for an unaccessible page.
529  **/
530 static Address getStackTop(AddrSpaceReader *proc, bool &err) {
531    Address stack_pointer;
532    Address pagesize = getpagesize();
533    bool result;
534    long word;
535    err = false;
536
537
538    stack_pointer = proc->readRegContents(PTRACE_REG_SP);
539    dyn_lwp *init_lwp = proc->getInitialLwp();
540    if (!init_lwp) {
541       err = true;
542       return 0x0;
543    }
544
545    Frame frame = init_lwp->getActiveFrame();
546    stack_pointer = frame.getSP();
547    if (!stack_pointer) {
548       err = true;
549       return 0x0;
550    }
551    
552    //Align sp to pagesize
553    stack_pointer = (stack_pointer & ~(pagesize - 1)) + pagesize;
554    
555    //Read pages until we get to an unmapped page
556    for (;;) {
557       result = proc->readDataSpace((void *) stack_pointer, sizeof(long), &word, 
558                                    false);
559       if (!result) {
560          break;
561       }
562       stack_pointer += pagesize;
563    }
564
565    //The vsyscall page sometimes hangs out above the stack.  Test if this
566    // page is it, then move back down one if it is.
567    char pagestart[4];
568    result = proc->readDataSpace((void *) (stack_pointer - pagesize), 4, pagestart, 
569                                 false);
570    if (result) {
571       if (pagestart[0] == 0x7F && pagestart[1] == 'E' && 
572           pagestart[2] == 'L' &&  pagestart[3] == 'F') 
573       {
574          stack_pointer -= pagesize;
575       }
576    }
577
578    return stack_pointer;
579 }
580
581 /**
582  * We can't read /proc/PID/auxv for some reason (BProc is a likely candidate).
583  * We'll instead pull this data from the mutatee's stack.  On Linux the top of
584  * the stack at process startup is arranged like the following:
585  *          -------------------------------------
586  * esp ->   |                argc               |
587  *          |               argv[0]             |
588  *          |                ...                |
589  *          |               argv[n]             |
590  *          |                                   |
591  *          |               envp[0]             |
592  *          |                ...                |
593  *          |               envp[n]             |
594  *          |                NULL               |
595  *          |                                   |
596  *          |  { auxv[0].type, auxv[0].value }  |   
597  *          |                ...                |
598  *          |  { auxv[n].type, auxv[n].value }  | 
599  *          |  {      NULL   ,     NULL      }  |
600  *          |                                   |
601  *          |      Some number of NULL words    |
602  *          |        Strings for argv[]         |
603  *          |        Strings for envp[]         |
604  *          |                NULL               |
605  *          -------------------------------------
606  *
607  * We want to get at the name/value pairs of auxv.  Unfortunately,
608  * if we're attaching the stack pointer has probably moved.  Instead
609  * we'll try to read the from the bottom up, which is more difficult.
610  * argv[] and envp[] are pointers to the strings at the bottom of
611  * the stack.  We'll search backwards for these pointers, then move back
612  * down until we think we have the auxv array.  Yea us.
613  **/
614 void *AuxvParser::readAuxvFromStack(process *proc) {
615    gwa_buffer = NULL;
616    gwa_size = 1024 * 1024; //One megabyte default
617    gwa_pos = 0;
618    unsigned word_size = proc->getAddressWidth();
619    bool err = false;
620
621    // Get the base address of the mutatee's stack.  For example,
622    //  on many standard linux/x86 machines this will return 
623    //  0xc0000000
624    gwa_base_addr = getStackTop(proc, err);
625    if (err) 
626       return NULL;
627    gwa_base_addr -= word_size;
628    
629    unsigned long current = gwa_base_addr;
630    unsigned long strings_start, strings_end;
631    unsigned long l1, l2, auxv_start, word;
632    unsigned char *buffer = NULL;
633    unsigned bytes_to_read;
634
635    // Go through initial NULL word
636    while (get_word_at(proc, current, err) == 0x0) {
637       if (err) goto done_err;
638       current -= word_size;
639    }
640
641    // Go through the auxv[] and envp[] strings
642    strings_end = current;
643    while (get_word_at(proc, current, err) != 0x0) {
644       if (err) goto done_err;
645       current -= word_size;
646    }
647    strings_start = current + word_size;
648    
649    //Read until we find a pair of pointers into the strings 
650    // section, this should mean we're now above the auxv vector
651    // and in envp or argv
652    for (;;) {
653       l1 = get_word_at(proc, current, err);
654       if (err) goto done_err;
655       l2 = get_word_at(proc, current - word_size, err);
656       if (err) goto done_err;
657       if (l1 >= strings_start && l1 < strings_end && 
658           l2 >= strings_start && l2 < strings_end)
659          break;
660       current -= word_size;
661    }
662
663    //Read back down until we get to the end of envp[]
664    while (get_word_at(proc, current, err) != 0x0) {
665       if (err) goto done_err;
666       current += word_size;
667    }
668    //Through the NULL byte before auxv..
669    while (get_word_at(proc, current, err) == 0x0) {
670       if (err) goto done_err;
671       current += word_size;
672    }
673
674    //Success. Found the start of auxv.
675    auxv_start = current;
676
677    //Read auxv into buffer
678    bytes_to_read = strings_start - auxv_start;
679    buffer = (unsigned char *) malloc(bytes_to_read + word_size*2);
680    if (!buffer)
681       goto done_err;   
682    for (unsigned pos = 0; pos < bytes_to_read; pos += word_size) {
683       word = get_word_at(proc, auxv_start + pos, err);
684       if (err) goto done_err;
685       if (word_size == 4)
686          *((uint32_t *) (buffer + pos)) = (uint32_t) word;
687       else
688          *((unsigned long *) (buffer + pos)) = word;
689    }
690
691    goto done;
692
693  done_err:
694    if (buffer)
695       free(buffer);
696    buffer = NULL;
697  done:
698    if (gwa_buffer)
699       free(gwa_buffer);
700    return (void *) buffer;
701 }
702
703 #else
704
705 void *AuxvParser::readAuxvFromStack() {
706    /**
707     * Disabled, for now.  Re-enable if /proc/pid/auxv doesn't exist.
708     **/
709    return NULL;
710 }
711
712 #endif
713
714 #define READ_BLOCK_SIZE (1024 * 5)
715 void *AuxvParser::readAuxvFromProc() {
716    char filename[64];
717    unsigned char *buffer = NULL;
718    unsigned char *temp;
719    unsigned buffer_size = READ_BLOCK_SIZE;
720    unsigned pos = 0;
721    ssize_t result = 0;
722    int fd = -1;
723
724    sprintf(filename, "/proc/%d/auxv", pid);
725    fd = open(filename, O_RDONLY, 0);
726    if (fd == -1)
727       goto done_err;
728
729    buffer = (unsigned char *) malloc(buffer_size);
730    if (!buffer) {
731       goto done_err;
732    }
733
734    for (;;) {
735       result = read(fd, buffer + pos, READ_BLOCK_SIZE);
736       if (result == -1) {
737          perror("Couldn't read auxv entry");
738          goto done_err;
739       }
740       else if (!result && !pos) {
741          //Didn't find any data to read
742          perror("Could read auxv entry");
743          goto done_err;
744       }
745       else if (result < READ_BLOCK_SIZE) {
746          //Success
747          goto done;
748       }
749       else if (result == READ_BLOCK_SIZE) {
750          //WTF... 5k wasn't enough for auxv?
751          buffer_size *= 2;
752          temp = (unsigned char *) realloc(buffer, buffer_size);
753          if (!temp)
754             goto done_err;
755          buffer = temp;
756          pos += READ_BLOCK_SIZE;
757       }
758       else {
759          fprintf(stderr, "[%s:%u] - Unknown error reading auxv\n",
760                  __FILE__, __LINE__);
761          goto done_err;
762       }
763    }
764       
765    done_err:
766       if (buffer)
767          free(buffer);
768       buffer = NULL;
769    done:
770       if (fd != -1)
771          close(fd);
772       return buffer;
773 }
774
775
776 #define LINE_LEN 1024
777 map_entries *getLinuxMaps(int pid, unsigned &maps_size) {
778    char line[LINE_LEN], prems[16], *s;
779    int result;
780    FILE *f;
781    map_entries *maps = NULL;
782    unsigned i, no_lines = 0;
783    
784   
785    sprintf(line, "/proc/%d/maps", pid);
786    f = fopen(line, "r");
787    if (!f)
788       return NULL;
789    
790    //Calc num of entries needed and allocate the buffer.  Assume the 
791    //process is stopped.
792    while (!feof(f)) {
793       fgets(line, LINE_LEN, f);
794       no_lines++;
795    }
796    maps = (map_entries *) malloc(sizeof(map_entries) * (no_lines+1));
797    if (!maps)
798       goto done_err;
799    result = fseek(f, 0, SEEK_SET);
800    if (result == -1)
801       goto done_err;
802
803    //Read all of the maps entries
804    for (i = 0; i < no_lines; i++) {
805       if (!fgets(line, LINE_LEN, f))
806          break;
807       line[LINE_LEN - 1] = '\0';
808       maps[i].path[0] = '\0';
809       sscanf(line, "%lx-%lx %16s %lx %x:%x %u %512s\n", 
810              (Address *) &maps[i].start, (Address *) &maps[i].end, prems, 
811              (Address *) &maps[i].offset, &maps[i].dev_major,
812              &maps[i].dev_minor, &maps[i].inode, maps[i].path);
813       maps[i].prems = 0;
814       for (s = prems; *s != '\0'; s++) {
815          switch (*s) {
816             case 'r':
817                maps[i].prems |= PREMS_READ;
818                break;
819             case 'w':
820                maps[i].prems |= PREMS_WRITE;
821                break;
822             case 'x':
823                maps[i].prems |= PREMS_EXEC;
824                break;
825             case 'p':
826                maps[i].prems |= PREMS_PRIVATE;
827                break;
828             case 's':
829                maps[i].prems |= PREMS_EXEC;
830                break;
831          }
832       }
833    }
834    //Zero out the last entry
835    memset(&(maps[i]), 0, sizeof(map_entries));
836    maps_size = i;
837    fclose(f);
838    return maps;
839
840  done_err:
841    if (f)
842       fclose(f);
843    if (maps)
844       free(maps);
845    return NULL;
846 }
847