Clean up header files
[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 char * P_cplus_demangle( const char * symbol, bool nativeCompiler,
173                                 bool includeTypes ) 
174 {
175    int opts = 0;
176    opts |= includeTypes ? DMGL_PARAMS | DMGL_ANSI : 0;
177    //   [ pgcc/CC are the "native" compilers on Linux. Go figure. ]
178    // pgCC's mangling scheme most closely resembles that of the Annotated
179    // C++ Reference Manual, only with "some exceptions" (to quote the PGI
180    // documentation). I guess we'll demangle names with "some exceptions".
181    opts |= nativeCompiler ? DMGL_ARM : 0;
182
183    char * demangled = cplus_demangle( const_cast< char *>(symbol), opts);
184    if( demangled == NULL ) { return NULL; }
185
186    if( ! includeTypes ) {
187         /* de-demangling never increases the length */   
188         char * dedemangled = strdup( demangled );   
189         assert( dedemangled != NULL );
190         dedemangle( demangled, dedemangled );
191         assert( dedemangled != NULL );
192
193         free( demangled );
194         return dedemangled;
195         }
196
197    return demangled;
198    } /* end P_cplus_demangle() */
199
200 bool PtraceBulkRead(Address inTraced, unsigned size, const void *inSelf, int pid)
201 {
202    const unsigned char *ap = (const unsigned char*) inTraced; 
203    unsigned char *dp = (unsigned char *) const_cast<void *>(inSelf);
204    Address w = 0x0;               /* ptrace I/O buffer */
205    int len = sizeof(void *);
206    unsigned cnt;
207    
208    if (0 == size) {
209       return true;
210    }
211    
212    if ((cnt = ((Address)ap) % len)) {
213       /* Start of request is not aligned. */
214       unsigned char *p = (unsigned char*) &w;
215       
216       /* Read the segment containing the unaligned portion, and
217          copy what was requested to DP. */
218       errno = 0;
219       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) (ap-cnt), w, len);
220       if (errno) {
221          return false;
222       }
223       for (unsigned i = 0; i < len-cnt && i < size; i++)
224          dp[i] = p[cnt+i];
225       
226       if (len-cnt >= size) {
227          return true; /* done */
228       }
229       
230       dp += len-cnt;
231       ap += len-cnt;
232       size -= len-cnt;
233    }
234    /* Copy aligned portion */
235    while (size >= (u_int)len) {
236       errno = 0;
237       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0, len);
238       if (errno) {
239          return false;
240       }
241       memcpy(dp, &w, len);
242       dp += len;
243       ap += len;
244       size -= len;
245    }
246    
247    if (size > 0) {
248       /* Some unaligned data remains */
249       unsigned char *p = (unsigned char *) &w;
250       
251       /* Read the segment containing the unaligned portion, and
252          copy what was requested to DP. */
253       errno = 0;
254       w = P_ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0, len);
255       if (errno) {
256          return false;
257       }
258       for (unsigned i = 0; i < size; i++)
259          dp[i] = p[i];
260    }
261    return true;
262
263 }
264
265 // These constants are not defined in all versions of elf.h
266 #ifndef AT_BASE
267 #define AT_BASE 7
268 #endif
269 #ifndef AT_NULL
270 #define AT_NULL 0
271 #endif
272 #ifndef AT_SYSINFO
273 #define AT_SYSINFO 32
274 #endif
275 #ifndef AT_SYSINFO_EHDR
276 #define AT_SYSINFO_EHDR 33
277 #endif
278
279 static bool couldBeVsyscallPage(map_entries *entry, bool strict, Address) {
280    if (strict) {
281        if (entry->prems != PREMS_PRIVATE)
282          return false;
283       if (entry->path[0] != '\0')
284          return false;
285    }
286    if (entry->offset != 0)
287       return false;
288    if (entry->dev_major != 0 || entry->dev_minor != 0)
289       return false;
290    if (entry->inode != 0)
291       return false;
292
293    return true;
294 }
295
296 bool AuxvParser::readAuxvInfo()
297 {
298   /**
299    * The location of the vsyscall is stored in /proc/PID/auxv in Linux 2.6.
300    * auxv consists of a list of name/value pairs, ending with the AT_NULL
301    * name.  There isn't a direct way to get the vsyscall info on Linux 2.4
302    **/
303   uint32_t *buffer32 = NULL;
304   uint64_t *buffer64 = NULL;
305   unsigned pos = 0;
306   Address dso_start = 0x0, text_start = 0x0;
307   unsigned page_size = 0x0;
308
309   struct {
310     unsigned long type;
311     unsigned long value;
312   } auxv_entry;
313
314   /**
315    * Try to read from /proc/%d/auxv.  On Linux 2.4 systems auxv
316    * doesn't exist, which is okay because vsyscall isn't used.
317    * On latter 2.6 kernels the AT_SYSINFO field isn't present,
318    * so we have to resort to more "extreme" measures.
319    **/
320   buffer64 = (uint64_t *) readAuxvFromProc();
321   if (!buffer64) 
322      buffer64 = (uint64_t *) readAuxvFromStack();
323   if (!buffer64)
324      return false;
325   buffer32 = (uint32_t *) buffer64;
326   do {
327      /**Fill in the auxv_entry structure.  We may have to do different
328       * size reads depending on the address space.  No matter which
329       * size we read, we'll fill the data in to auxv_entry, which may
330       * involve a size shift up.
331       **/
332      if (addr_size == 4) {
333         auxv_entry.type = (unsigned long) buffer32[pos];
334         pos++;
335         auxv_entry.value = (unsigned long) buffer32[pos];
336         pos++;
337      }
338      else {
339         auxv_entry.type = (unsigned long) buffer64[pos];
340         pos++;
341         auxv_entry.value = (unsigned long) buffer64[pos];
342         pos++;
343      }
344      
345      if (auxv_entry.type == AT_SYSINFO)
346         text_start = auxv_entry.value;
347      else if (auxv_entry.type == AT_SYSINFO_EHDR)
348         dso_start = auxv_entry.value;
349      else if (auxv_entry.type == AT_PAGESZ)
350         page_size = auxv_entry.value;
351      else if (auxv_entry.type == AT_BASE)
352         interpreter_base = auxv_entry.value;
353   } while (auxv_entry.type != AT_NULL);
354
355   if (buffer64)
356      free(buffer64);
357   if (!page_size)
358      page_size = getpagesize();
359   /**
360    * Even if we found dso_start in /proc/pid/auxv, the vsyscall 'page'
361    * can be larger than a single page.  Thus we look through /proc/pid/maps
362    * for known, default, or guessed start address(es).
363    **/
364   std::vector<Address> guessed_addrs;
365   
366   /* The first thing to check is the auxvinfo, if we have any. */
367   if( dso_start != 0x0 ) 
368      guessed_addrs.push_back( dso_start );
369     
370   /**
371    * We'll make several educated attempts at guessing an address
372    * for the vsyscall page.  After deciding on a guess, we'll try to
373    * verify that using /proc/pid/maps.
374    **/
375   
376   // Guess some constants that we've seen before.
377 #if defined(arch_x86) 
378   guessed_addrs.push_back(0xffffe000); //Many early 2.6 systems
379   guessed_addrs.push_back(0xffffd000); //RHEL4
380 #elif defined(arch_ia64)
381   guessed_addrs.push_back(0xa000000000000000); 
382   guessed_addrs.push_back(0xa000000000010000); 
383   guessed_addrs.push_back(0xa000000000020000); //Juniper & Hogan
384 #endif
385 #if defined(arch_x86_64)
386   guessed_addrs.push_back(0xffffffffff600000);
387 #endif
388
389   /**
390    * Look through every entry in /proc/maps, and compare it to every 
391    * entry in guessed_addrs.  If a guessed_addr looks like the right
392    * thing, then we'll go ahead and call it the vsyscall page.
393    **/
394   unsigned num_maps;
395   map_entries *secondary_match = NULL;
396   map_entries *maps = getLinuxMaps(pid, num_maps);
397   for (unsigned i=0; i<guessed_addrs.size(); i++) {
398      Address addr = guessed_addrs[i];
399      for (unsigned j=0; j<num_maps; j++) {
400         map_entries *entry = &(maps[j]);
401         if (addr < entry->start || addr >= entry->end)
402            continue;
403
404         if (dso_start == entry->start ||
405             couldBeVsyscallPage(entry, true, page_size)) {
406            //We found a possible page using a strict check. 
407            // This is really likely to be it.
408            vsyscall_base = entry->start;
409            vsyscall_end = entry->end;
410            vsyscall_text = text_start;
411            found_vsyscall = true;
412            free(maps);
413            return true;
414         }
415
416         if (couldBeVsyscallPage(entry, false, page_size)) {
417            //We found an entry that loosely looks like the
418            // vsyscall page.  Let's hang onto this and return 
419            // it if we find nothing else.
420            secondary_match = entry;
421         }
422      }  
423   }
424
425   /**
426    * There were no hits using our guessed_addrs scheme.  Let's
427    * try to look at every entry in the maps table (not just the 
428    * guessed addresses), and see if any of those look like a vsyscall page.
429    **/
430   for (unsigned i=0; i<num_maps; i++) {
431      if (couldBeVsyscallPage(&(maps[i]), true, page_size)) {
432         vsyscall_base = maps[i].start;
433         vsyscall_end = maps[i].end;
434         vsyscall_text = text_start;
435         found_vsyscall = true;
436         free(maps);
437         return true;
438      }
439   }
440
441   /**
442    * Return any secondary possiblitiy pages we found in our earlier search.
443    **/
444   if (secondary_match) {
445      vsyscall_base = secondary_match->start;
446      vsyscall_end = secondary_match->end;
447      vsyscall_text = text_start;
448      found_vsyscall = true;
449      free(maps);
450      return true;
451   }
452
453   /**
454    * Time to give up.  Sigh.
455    **/
456   found_vsyscall = false;
457   free(maps);
458   return false;
459 }
460
461 #if 0
462 /**
463  * get_word_at is a helper function for readAuxvFromStack.  It reads
464  * a word out of the mutatee's stack via the debugger interface, and
465  * it keeps the word cached for future reads.
466  * The gwa_* global variables are basically parameters to get_word_at
467  * and should be reset before every call
468  *
469  * gwa_buffer is a cache of data we've read before.  It's backwards 
470  * for convience, higher addresses are cached towards the base of gwa_buffer
471  * and lower addresses are cached at the top.  This is because we read from
472  * high addresses to low ones, but we want to start caching at the start of
473  * gwa_buffer.
474  **/
475 static unsigned long *gwa_buffer = NULL;
476 static unsigned gwa_size = 0; 
477 static unsigned gwa_pos = 0;
478 static unsigned long gwa_base_addr = 0;
479
480 static unsigned long get_word_at(process *p, unsigned long addr, bool &err) {
481    bool result;
482    unsigned word_size = p->getAddressWidth();
483    unsigned long word;
484
485    /**
486     * On AMD64 controlling 32-bit mutatee words are 32 bits long.
487     * We don't want to deal with this now, so treat as a 64 bit read
488     * (from aligned_addr) and then pick the correct 32 bits to return
489     * at the end of this function.
490     **/
491    unsigned long aligned_addr = addr;
492    if (word_size == 4 && sizeof(long) == 8 && addr % 8 == 4)
493       aligned_addr -= 4;
494
495    /**
496     * Allocate gwa_buffer on first call
497     **/
498    if (gwa_buffer == NULL) {
499       gwa_buffer = (unsigned long *) malloc(gwa_size);
500    }
501
502    /**
503     * If gwa_buffer isn't big enough, grow it.
504     **/
505    if (gwa_base_addr - gwa_size >= aligned_addr) {
506       while (gwa_base_addr - gwa_size >= aligned_addr)
507          gwa_size = gwa_size * 2;
508       gwa_buffer = (unsigned long *) realloc(gwa_buffer, gwa_size);
509    }
510
511    /**
512     * Keep adding words to the cache (gwa_buffer) until we've cached
513     * the word the user is interested in.
514     **/
515    while (gwa_base_addr - (gwa_pos * sizeof(long)) >= aligned_addr) {
516       result = p->readDataSpace((void *) aligned_addr, sizeof(long), &word, false);
517       if (!result) {
518          err = true;
519          return 0x0;
520       }
521       gwa_buffer[gwa_pos] = word;
522       gwa_pos++;
523    }
524
525    /**
526     * Return the word the user wants out of the cache.  'word' is the
527     * long value we want to return.  On 64-bit mutator/32-bit mutatees
528     * we may need to return a specific 32-bits of word.
529     **/
530    word = gwa_buffer[(gwa_base_addr - aligned_addr) / sizeof(long)];
531
532    if (word_size == 4 && sizeof(long) == 8 && addr % 8 == 4) {
533       //64-bit mutator, 32 bit mutatee, looking for unaligned word
534       uint32_t *words = (uint32_t *) &word;
535       return (long) words[1];
536    }
537    else if (word_size == 4 && sizeof(long) == 8)
538    {
539       //64-bit mutator, 32 bit mutatee, looking for aligned word
540       uint32_t *words = (uint32_t *) &word;
541       return (long) words[0];
542    }
543    else
544    {
545       //mutator and mutatee are same size
546       return word;
547    }
548 }
549
550
551 /**
552  * Another helper function for readAuxvInfoFromStack.  We want to know
553  * the top byte of the stack.  Unfortunately, if we're running this it's
554  * probably because /proc/PID/ isn't reliable, so we can't use maps.  
555  * Check the machine's stack pointer, page align it, and start walking
556  * back looking for an unaccessible page.
557  **/
558 static Address getStackTop(AddrSpaceReader *proc, bool &err) {
559    Address stack_pointer;
560    Address pagesize = getpagesize();
561    bool result;
562    long word;
563    err = false;
564
565
566    stack_pointer = proc->readRegContents(PTRACE_REG_SP);
567    dyn_lwp *init_lwp = proc->getInitialLwp();
568    if (!init_lwp) {
569       err = true;
570       return 0x0;
571    }
572
573    Frame frame = init_lwp->getActiveFrame();
574    stack_pointer = frame.getSP();
575    if (!stack_pointer) {
576       err = true;
577       return 0x0;
578    }
579    
580    //Align sp to pagesize
581    stack_pointer = (stack_pointer & ~(pagesize - 1)) + pagesize;
582    
583    //Read pages until we get to an unmapped page
584    for (;;) {
585       result = proc->readDataSpace((void *) stack_pointer, sizeof(long), &word, 
586                                    false);
587       if (!result) {
588          break;
589       }
590       stack_pointer += pagesize;
591    }
592
593    //The vsyscall page sometimes hangs out above the stack.  Test if this
594    // page is it, then move back down one if it is.
595    char pagestart[4];
596    result = proc->readDataSpace((void *) (stack_pointer - pagesize), 4, pagestart, 
597                                 false);
598    if (result) {
599       if (pagestart[0] == 0x7F && pagestart[1] == 'E' && 
600           pagestart[2] == 'L' &&  pagestart[3] == 'F') 
601       {
602          stack_pointer -= pagesize;
603       }
604    }
605
606    return stack_pointer;
607 }
608
609 /**
610  * We can't read /proc/PID/auxv for some reason (BProc is a likely candidate).
611  * We'll instead pull this data from the mutatee's stack.  On Linux the top of
612  * the stack at process startup is arranged like the following:
613  *          -------------------------------------
614  * esp ->   |                argc               |
615  *          |               argv[0]             |
616  *          |                ...                |
617  *          |               argv[n]             |
618  *          |                                   |
619  *          |               envp[0]             |
620  *          |                ...                |
621  *          |               envp[n]             |
622  *          |                NULL               |
623  *          |                                   |
624  *          |  { auxv[0].type, auxv[0].value }  |   
625  *          |                ...                |
626  *          |  { auxv[n].type, auxv[n].value }  | 
627  *          |  {      NULL   ,     NULL      }  |
628  *          |                                   |
629  *          |      Some number of NULL words    |
630  *          |        Strings for argv[]         |
631  *          |        Strings for envp[]         |
632  *          |                NULL               |
633  *          -------------------------------------
634  *
635  * We want to get at the name/value pairs of auxv.  Unfortunately,
636  * if we're attaching the stack pointer has probably moved.  Instead
637  * we'll try to read the from the bottom up, which is more difficult.
638  * argv[] and envp[] are pointers to the strings at the bottom of
639  * the stack.  We'll search backwards for these pointers, then move back
640  * down until we think we have the auxv array.  Yea us.
641  **/
642 void *AuxvParser::readAuxvFromStack(process *proc) {
643    gwa_buffer = NULL;
644    gwa_size = 1024 * 1024; //One megabyte default
645    gwa_pos = 0;
646    unsigned word_size = proc->getAddressWidth();
647    bool err = false;
648
649    // Get the base address of the mutatee's stack.  For example,
650    //  on many standard linux/x86 machines this will return 
651    //  0xc0000000
652    gwa_base_addr = getStackTop(proc, err);
653    if (err) 
654       return NULL;
655    gwa_base_addr -= word_size;
656    
657    unsigned long current = gwa_base_addr;
658    unsigned long strings_start, strings_end;
659    unsigned long l1, l2, auxv_start, word;
660    unsigned char *buffer = NULL;
661    unsigned bytes_to_read;
662
663    // Go through initial NULL word
664    while (get_word_at(proc, current, err) == 0x0) {
665       if (err) goto done_err;
666       current -= word_size;
667    }
668
669    // Go through the auxv[] and envp[] strings
670    strings_end = current;
671    while (get_word_at(proc, current, err) != 0x0) {
672       if (err) goto done_err;
673       current -= word_size;
674    }
675    strings_start = current + word_size;
676    
677    //Read until we find a pair of pointers into the strings 
678    // section, this should mean we're now above the auxv vector
679    // and in envp or argv
680    for (;;) {
681       l1 = get_word_at(proc, current, err);
682       if (err) goto done_err;
683       l2 = get_word_at(proc, current - word_size, err);
684       if (err) goto done_err;
685       if (l1 >= strings_start && l1 < strings_end && 
686           l2 >= strings_start && l2 < strings_end)
687          break;
688       current -= word_size;
689    }
690
691    //Read back down until we get to the end of envp[]
692    while (get_word_at(proc, current, err) != 0x0) {
693       if (err) goto done_err;
694       current += word_size;
695    }
696    //Through the NULL byte before auxv..
697    while (get_word_at(proc, current, err) == 0x0) {
698       if (err) goto done_err;
699       current += word_size;
700    }
701
702    //Success. Found the start of auxv.
703    auxv_start = current;
704
705    //Read auxv into buffer
706    bytes_to_read = strings_start - auxv_start;
707    buffer = (unsigned char *) malloc(bytes_to_read + word_size*2);
708    if (!buffer)
709       goto done_err;   
710    for (unsigned pos = 0; pos < bytes_to_read; pos += word_size) {
711       word = get_word_at(proc, auxv_start + pos, err);
712       if (err) goto done_err;
713       if (word_size == 4)
714          *((uint32_t *) (buffer + pos)) = (uint32_t) word;
715       else
716          *((unsigned long *) (buffer + pos)) = word;
717    }
718
719    goto done;
720
721  done_err:
722    if (buffer)
723       free(buffer);
724    buffer = NULL;
725  done:
726    if (gwa_buffer)
727       free(gwa_buffer);
728    return (void *) buffer;
729 }
730
731 #else
732
733 void *AuxvParser::readAuxvFromStack() {
734    /**
735     * Disabled, for now.  Re-enable if /proc/pid/auxv doesn't exist.
736     **/
737    return NULL;
738 }
739
740 #endif
741
742 #define READ_BLOCK_SIZE (1024 * 5)
743 void *AuxvParser::readAuxvFromProc() {
744    char filename[64];
745    unsigned char *buffer = NULL;
746    unsigned char *temp;
747    unsigned buffer_size = READ_BLOCK_SIZE;
748    unsigned pos = 0;
749    ssize_t result = 0;
750    int fd = -1;
751
752    sprintf(filename, "/proc/%d/auxv", pid);
753    fd = open(filename, O_RDONLY, 0);
754    if (fd == -1)
755       goto done_err;
756
757    buffer = (unsigned char *) malloc(buffer_size);
758    if (!buffer) {
759       goto done_err;
760    }
761
762    for (;;) {
763       result = read(fd, buffer + pos, READ_BLOCK_SIZE);
764       if (result == -1) {
765          perror("Couldn't read auxv entry");
766          goto done_err;
767       }
768       else if (!result && !pos) {
769          //Didn't find any data to read
770          perror("Could read auxv entry");
771          goto done_err;
772       }
773       else if (result < READ_BLOCK_SIZE) {
774          //Success
775          goto done;
776       }
777       else if (result == READ_BLOCK_SIZE) {
778          //WTF... 5k wasn't enough for auxv?
779          buffer_size *= 2;
780          temp = (unsigned char *) realloc(buffer, buffer_size);
781          if (!temp)
782             goto done_err;
783          buffer = temp;
784          pos += READ_BLOCK_SIZE;
785       }
786       else {
787          fprintf(stderr, "[%s:%u] - Unknown error reading auxv\n",
788                  __FILE__, __LINE__);
789          goto done_err;
790       }
791    }
792       
793    done_err:
794       if (buffer)
795          free(buffer);
796       buffer = NULL;
797    done:
798       if (fd != -1)
799          close(fd);
800       return buffer;
801 }
802
803
804 #define LINE_LEN 1024
805 map_entries *getLinuxMaps(int pid, unsigned &maps_size) {
806    char line[LINE_LEN], prems[16], *s;
807    int result;
808    FILE *f;
809    map_entries *maps = NULL;
810    unsigned i, no_lines = 0;
811    
812   
813    sprintf(line, "/proc/%d/maps", pid);
814    f = fopen(line, "r");
815    if (!f)
816       return NULL;
817    
818    //Calc num of entries needed and allocate the buffer.  Assume the 
819    //process is stopped.
820    while (!feof(f)) {
821       fgets(line, LINE_LEN, f);
822       no_lines++;
823    }
824    maps = (map_entries *) malloc(sizeof(map_entries) * (no_lines+1));
825    if (!maps)
826       goto done_err;
827    result = fseek(f, 0, SEEK_SET);
828    if (result == -1)
829       goto done_err;
830
831    //Read all of the maps entries
832    for (i = 0; i < no_lines; i++) {
833       if (!fgets(line, LINE_LEN, f))
834          break;
835       line[LINE_LEN - 1] = '\0';
836       maps[i].path[0] = '\0';
837       sscanf(line, "%lx-%lx %16s %lx %x:%x %u %512s\n", 
838              (Address *) &maps[i].start, (Address *) &maps[i].end, prems, 
839              (Address *) &maps[i].offset, &maps[i].dev_major,
840              &maps[i].dev_minor, &maps[i].inode, maps[i].path);
841       maps[i].prems = 0;
842       for (s = prems; *s != '\0'; s++) {
843          switch (*s) {
844             case 'r':
845                maps[i].prems |= PREMS_READ;
846                break;
847             case 'w':
848                maps[i].prems |= PREMS_WRITE;
849                break;
850             case 'x':
851                maps[i].prems |= PREMS_EXEC;
852                break;
853             case 'p':
854                maps[i].prems |= PREMS_PRIVATE;
855                break;
856             case 's':
857                maps[i].prems |= PREMS_EXEC;
858                break;
859          }
860       }
861    }
862    //Zero out the last entry
863    memset(&(maps[i]), 0, sizeof(map_entries));
864    maps_size = i;
865    fclose(f);
866    return maps;
867
868  done_err:
869    if (f)
870       fclose(f);
871    if (maps)
872       free(maps);
873    return NULL;
874 }
875