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