Build fixes for static linked Dyninst components (compute node linux), when linking...
[dyninst.git] / common / h / dwarfExpr.h
1 /*
2  * Copyright (c) 1996-2011 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 <stack>
33 #include "dynutil/h/dyn_regs.h"
34 #if !defined(DWARF_EXPR_H)
35 #define DWARF_EXPR_H
36
37 using namespace std;
38 using namespace Dyninst;
39
40 #if defined(arch_x86_64)
41 // We can only safely map the general purpose registers (0-7 on ia-32,
42 // 0-15 on amd-64)
43 #define IA32_MAX_MAP 7
44 #define AMD64_MAX_MAP 15
45 static int const amd64_register_map[] =
46   {
47     0,  // RAX
48     2,  // RDX
49     1,  // RCX
50     3,  // RBX
51     6,  // RSI
52     7,  // RDI
53     5,  // RBP
54     4,  // RSP
55     8, 9, 10, 11, 12, 13, 14, 15    // gp 8 - 15
56     /* This is incomplete. The x86_64 ABI specifies a mapping from
57        dwarf numbers (0-66) to ("architecture number"). Without a
58        corresponding mapping for the SVR4 dwarf-machine encoding for
59        IA-32, however, it is not meaningful to provide this mapping. */
60   };
61
62 static int Register_DWARFtoMachineEnc32(int n)
63 {
64   if (n > IA32_MAX_MAP) {
65     dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
66                  __FILE__,__LINE__,n);
67   }
68   return n;
69 }
70
71
72 static int Register_DWARFtoMachineEnc64(int n)
73 {
74   if (n <= AMD64_MAX_MAP)
75     return amd64_register_map[n];
76   else {
77     dwarf_printf("%s[%d]: unexpected map lookup for DWARF register %d\n",
78                  __FILE__,__LINE__,n);
79     return n;
80   }
81 }
82
83 #define DWARF_TO_MACHINE_ENC(n, proc)                                   \
84   ((proc->getAddressWidth() == 4) ? Register_DWARFtoMachineEnc32((int) n) : Register_DWARFtoMachineEnc64((int) n))
85 #define DWARF_TO_MACHINE_ENC_W(n, w) \
86   (w == 4) ? Register_DWARFtoMachineEnc32((int) n) : Register_DWARFtoMachineEnc64((int) n)
87 #define DWARF_TO_MACHINEREG_ENC_W(n, w) \
88    (w == 4) ? MachRegister::DwarfEncToReg(n, Dyninst::Arch_x86) : MachRegister::DwarfEncToReg(n, Dyninst::Arch_x86_64);
89 #else
90 #define DWARF_TO_MACHINE_ENC(n, proc) (n)
91 #define DWARF_TO_MACHINE_ENC_W(n, w) (n)
92 #define DWARF_TO_MACHINEREG_ENC_W(n, w) MachRegister::DwarfEncToReg(n, Dyninst::Arch_x86);
93 #endif
94
95 #define DWARF_FALSE_IF(condition,...)           \
96   if ( condition ) { return false; }
97 #define DWARF_RETURN_IF(condition,...)          \
98   if ( condition ) { return; }
99 #define DWARF_NULL_IF(condition,...)            \
100   if ( condition ) { return NULL; }
101 #define DWARF_NEXT_IF(condition, ...)                                   \
102   if (condition) { if (depth != 1) { return false; } else {walk_error = true; break; } }
103
104
105 static Dyninst::MachRegister DwarfToDynReg(Dwarf_Signed reg, Dyninst::Architecture arch)
106 {
107    return MachRegister::DwarfEncToReg(reg, arch);
108 }
109
110 static Dwarf_Signed DynToDwarfReg(Dyninst::MachRegister reg)
111 {
112    return reg.getDwarfEnc();
113 }
114
115 static bool decodeDwarfExpression(Dwarf_Locdesc *dwlocs,
116                                   long int *initialStackValue,
117                                   VariableLocation *loc, bool &isLocSet,
118                                   ProcessReader *reader,
119                                   Dyninst::Architecture arch,
120                                   long int &end_result)
121 {
122    /* Initialize the stack. */
123    int addr_width = getArchAddressWidth(arch);
124    std::stack< long int > opStack = std::stack<long int>();
125    if ( initialStackValue != NULL ) { opStack.push( * initialStackValue ); }
126
127    Dwarf_Loc *locations = dwlocs->ld_s;
128    unsigned count = dwlocs->ld_cents;
129    for ( unsigned int i = 0; i < count; i++ ) 
130    {
131       /* Handle the literals w/o 32 case statements. */
132       if ( DW_OP_lit0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_lit31 ) 
133       {
134          dwarf_printf( "pushing named constant: %d\n", locations[i].lr_atom - DW_OP_lit0 );
135          opStack.push( locations[i].lr_atom - DW_OP_lit0 );
136          continue;
137       }
138
139       /* Haandle registers w/o 32 case statements. */
140       if ( DW_OP_reg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_reg31 ) 
141       {
142          /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
143          dwarf_printf( "location is named register %d\n", 
144                        DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width) );
145          //loc->stClass = storageRegOffset;
146          if (loc) 
147          {
148             loc->stClass = storageReg;
149             loc->refClass = storageNoRef;
150             loc->frameOffset = 0;
151             loc->reg = DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width);
152             loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_atom - DW_OP_reg0, addr_width);
153             //loc->frameOffset = 0;
154             isLocSet = true;
155          }
156          continue;
157       } 
158
159       /* Haandle registers w/o 32 case statements. */
160       if ( DW_OP_breg0 <= locations[i].lr_atom && locations[i].lr_atom <= DW_OP_breg31 ) 
161       {
162          dwarf_printf( "setting storage class to named register, regNum to %d, offset %d\n", DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width), locations[i].lr_number );
163          long int to_push;
164          if (loc) {
165             loc->stClass = storageRegOffset;
166             loc->refClass = storageNoRef;
167             loc->frameOffset = locations[i].lr_number ;
168             loc->reg = DWARF_TO_MACHINE_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width);
169             loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_atom - DW_OP_breg0, addr_width);
170             to_push = static_cast<long int>(locations[i].lr_number);
171          }
172          else if (reader) {
173             Dyninst::MachRegister r = DwarfToDynReg(locations[i].lr_atom - DW_OP_breg0,
174                                                     arch);
175             Dyninst::MachRegisterVal v;
176             bool result = reader->GetReg(r, v);
177             if (!result) {
178                return false;
179             }
180             to_push = (long int) v + locations[i].lr_number;
181          }
182             
183          opStack.push(to_push); 
184          continue;
185       }
186
187       switch( locations[i].lr_atom ) 
188       {
189          case DW_OP_addr:
190          case DW_OP_const1u:
191          case DW_OP_const2u:
192          case DW_OP_const4u:
193          case DW_OP_const8u:
194          case DW_OP_constu:
195             dwarf_printf( "pushing unsigned constant %lu\n", 
196                           (unsigned long)locations[i].lr_number );
197             opStack.push(static_cast<long int>(locations[i].lr_number));
198             break;
199
200          case DW_OP_const1s:
201          case DW_OP_const2s:
202          case DW_OP_const4s:
203          case DW_OP_const8s:
204          case DW_OP_consts:
205             dwarf_printf( "pushing signed constant %ld\n", 
206                           (signed long)(locations[i].lr_number) );
207             opStack.push(static_cast<long int>(locations[i].lr_number));
208             break;
209
210          case DW_OP_regx:
211             /* storageReg is unimplemented, so do an offset of 0 from the named register instead. */
212             dwarf_printf( "location is register %d\n", 
213                           DWARF_TO_MACHINE_ENC_W(locations[i].lr_number, addr_width) );
214             if (loc) {
215                loc->stClass = storageReg;
216                loc->refClass = storageNoRef;
217                loc->reg = (int) DWARF_TO_MACHINE_ENC_W(locations[i].lr_number, addr_width); 
218                loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W(locations[i].lr_number, addr_width); 
219                loc->frameOffset = 0;
220                isLocSet = true;
221             }
222             break;
223
224          case DW_OP_fbreg:
225          {
226             dwarf_printf( "setting storage class to frame base\n" );
227             //if ( storageClass != NULL ) { * storageClass = storageFrameOffset; }
228             long int to_push = 0;
229             if (loc) {
230                loc->stClass = storageRegOffset;
231                loc->refClass = storageNoRef;
232                loc->frameOffset = 0;
233                to_push = static_cast<long int>(locations[i].lr_number);
234             }
235             else if (reader) {
236                Dyninst::MachRegister r = Dyninst::FrameBase;
237                Dyninst::MachRegisterVal v;
238                bool result = reader->GetReg(r, v);
239                if (!result) {
240                   return false;
241                }
242                to_push = (long int) v + locations[i].lr_number;               
243             }
244             opStack.push(to_push);
245          } break;          
246          case DW_OP_bregx: 
247          {
248             dwarf_printf( "setting storage class to register, regNum to %d\n", 
249                           locations[i].lr_number );
250             long int to_push = 0;
251             if (loc) {
252                loc->stClass = storageRegOffset;
253                loc->refClass = storageNoRef;
254                loc->reg = (int) DWARF_TO_MACHINE_ENC_W( locations[i].lr_number, addr_width );
255                loc->mr_reg = DWARF_TO_MACHINEREG_ENC_W( locations[i].lr_number, addr_width );
256                loc->frameOffset = 0;
257                to_push = static_cast<long int>(locations[i].lr_number2);
258             }
259             else if (reader) {
260                Dyninst::MachRegister r = DwarfToDynReg(locations[i].lr_number, arch);
261                Dyninst::MachRegisterVal v;
262                bool result = reader->GetReg(r, v);
263                if (!result) {
264                   return false;
265                }
266                to_push = (long int) v + locations[i].lr_number2;
267             }
268             opStack.push(to_push);
269          } break;
270          case DW_OP_dup:
271             DWARF_FALSE_IF( opStack.size() < 1, 
272                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
273             opStack.push( opStack.top() );
274             break;
275
276          case DW_OP_drop:
277             DWARF_FALSE_IF( opStack.size() < 1, 
278                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
279             opStack.pop();
280             break;
281
282          case DW_OP_pick: 
283          {
284             /* Duplicate the entry at index locations[i].lr_number. */
285             std::stack< long int > temp = std::stack< long int >();
286             
287             for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
288             {
289                temp.push( opStack.top() ); opStack.pop();
290             }
291             
292             long int dup = opStack.top();
293             
294             for ( unsigned int j = 0; j < locations[i].lr_number; j++ ) 
295             {
296                opStack.push( temp.top() ); temp.pop();
297             }
298             
299             opStack.push( dup );
300          } break;
301
302          case DW_OP_over: 
303          {
304             DWARF_FALSE_IF( opStack.size() < 2, 
305                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
306             long int first = opStack.top(); opStack.pop();
307             long int second = opStack.top(); opStack.pop();
308             opStack.push( second ); opStack.push( first ); opStack.push( second );
309          } break;
310          
311          case DW_OP_swap: 
312          {
313             DWARF_FALSE_IF( opStack.size() < 2, 
314                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
315             long int first = opStack.top(); opStack.pop();
316             long int second = opStack.top(); opStack.pop();
317             opStack.push( first ); opStack.push( second );
318          } break;
319          
320          case DW_OP_deref:
321          {
322             if (!reader)
323                break;
324             long int addr = opStack.top(); opStack.pop();
325             unsigned long to_push = 0;
326             bool bresult = false;
327             if (addr_width == 4) {
328                uint32_t v;
329                bresult = reader->ReadMem(addr, &v, sizeof(v));
330                to_push = (unsigned long) v;
331             }
332             else if (addr_width == 8) {
333                uint64_t v;
334                bresult = reader->ReadMem(addr, &v, sizeof(v));
335                to_push = (unsigned long) v;
336             }
337             DWARF_FALSE_IF(!bresult,
338                            "%s[%d]: Could not read from %lx\n", addr);
339             opStack.push(to_push);
340             break;
341          }
342          case DW_OP_deref_size:
343          {
344             if (!reader)
345                break;
346             long int addr = opStack.top(); opStack.pop();
347             int width = locations[i].lr_number;
348             unsigned long to_push = 0;
349             bool bresult = false;
350             if (width == 1) {
351                uint8_t v;
352                bresult = reader->ReadMem(addr, &v, sizeof(v));
353                to_push = (unsigned long) v;
354             }
355             if (width == 2) {
356                uint16_t v;
357                bresult = reader->ReadMem(addr, &v, sizeof(v));
358                to_push = (unsigned long) v;
359             }
360             if (width == 4) {
361                uint32_t v;
362                bresult = reader->ReadMem(addr, &v, sizeof(v));
363                to_push = (unsigned long) v;
364             }
365             else if (width == 8) {
366                uint64_t v;
367                bresult = reader->ReadMem(addr, &v, sizeof(v));
368                to_push = (long int) v;
369             }
370             DWARF_FALSE_IF(!bresult,
371                            "%s[%d]: Could not read from %lx\n", addr);
372             opStack.push(to_push);
373             break;
374          }
375          case DW_OP_rot: 
376          {
377             DWARF_FALSE_IF( opStack.size() < 3, 
378                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
379             long int first = opStack.top(); opStack.pop();
380             long int second = opStack.top(); opStack.pop();
381             long int third = opStack.top(); opStack.pop();
382             opStack.push( first ); opStack.push( third ); opStack.push( second );
383          } break;
384
385          case DW_OP_abs: 
386          {
387             DWARF_FALSE_IF( opStack.size() < 1, 
388                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
389             long int top = opStack.top(); opStack.pop();
390             opStack.push( abs( top ) );
391          } break;
392          
393          case DW_OP_and: 
394          {
395             DWARF_FALSE_IF( opStack.size() < 2, 
396                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
397             long int first = opStack.top(); opStack.pop();
398             long int second = opStack.top(); opStack.pop();
399             opStack.push( second & first );
400          } break;
401
402          case DW_OP_div: 
403          {
404             DWARF_FALSE_IF( opStack.size() < 2, 
405                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
406             long int first = opStack.top(); opStack.pop();
407             long int second = opStack.top(); opStack.pop();
408             opStack.push( second / first );
409          } break;
410
411          case DW_OP_minus: 
412          {
413             DWARF_FALSE_IF( opStack.size() < 2, 
414                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
415             long int first = opStack.top(); opStack.pop();
416             long int second = opStack.top(); opStack.pop();
417             opStack.push( second - first );
418          } break;
419
420          case DW_OP_mod: 
421          {
422             DWARF_FALSE_IF( opStack.size() < 2, 
423                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
424             long int first = opStack.top(); opStack.pop();
425             long int second = opStack.top(); opStack.pop();
426             opStack.push( second % first );
427          } break;
428
429          case DW_OP_mul: 
430          {
431             DWARF_FALSE_IF( opStack.size() < 2, 
432                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
433             long int first = opStack.top(); opStack.pop();
434             long int second = opStack.top(); opStack.pop();
435             opStack.push( second * first );
436          } break;
437
438          case DW_OP_neg: 
439          {
440             DWARF_FALSE_IF( opStack.size() < 1, 
441                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
442             long int first = opStack.top(); opStack.pop();
443             opStack.push( first * (-1) );
444          } break;
445          
446          case DW_OP_not: 
447          {
448             DWARF_FALSE_IF( opStack.size() < 1, 
449                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
450             long int first = opStack.top(); opStack.pop();
451             opStack.push( ~ first );
452          } break;
453
454          case DW_OP_or: 
455          {
456             DWARF_FALSE_IF( opStack.size() < 2, 
457                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
458             long int first = opStack.top(); opStack.pop();
459             long int second = opStack.top(); opStack.pop();
460             opStack.push( second | first );
461          } break;
462
463          case DW_OP_plus: 
464          {
465             DWARF_FALSE_IF( opStack.size() < 2, 
466                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
467             long int first = opStack.top(); opStack.pop();
468             long int second = opStack.top(); opStack.pop();
469             opStack.push( second + first );
470          } break;
471
472          case DW_OP_plus_uconst: 
473          {
474             DWARF_FALSE_IF( opStack.size() < 1, 
475                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
476             long int first = opStack.top(); opStack.pop();
477             opStack.push(static_cast<long int>(first + locations[i].lr_number));
478          } break;
479          
480          case DW_OP_shl: 
481          {
482             DWARF_FALSE_IF( opStack.size() < 2, 
483                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
484             long int first = opStack.top(); opStack.pop();
485             long int second = opStack.top(); opStack.pop();
486             opStack.push( second << first );
487          } break;
488
489          case DW_OP_shr: 
490          {
491             DWARF_FALSE_IF( opStack.size() < 2, 
492                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
493             long int first = opStack.top(); opStack.pop();
494             long int second = opStack.top(); opStack.pop();
495             
496             opStack.push( (long int)((unsigned long)second >> (unsigned long)first) );
497          } break;
498          
499          case DW_OP_shra: 
500          {
501             DWARF_FALSE_IF( opStack.size() < 2, 
502                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
503             long int first = opStack.top(); opStack.pop();
504             long int second = opStack.top(); opStack.pop();
505             opStack.push( second >> first );
506          } break;
507
508          case DW_OP_xor: 
509          {
510             DWARF_FALSE_IF( opStack.size() < 2, 
511                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
512             long int first = opStack.top(); opStack.pop();
513             long int second = opStack.top(); opStack.pop();
514             opStack.push( second ^ first );
515          } break;
516
517          case DW_OP_le: 
518          {
519             DWARF_FALSE_IF( opStack.size() < 2, 
520                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
521             long int first = opStack.top(); opStack.pop();
522             long int second = opStack.top(); opStack.pop();
523             opStack.push( first <= second ? 1 : 0 );
524          } break;
525
526          case DW_OP_ge: 
527          {
528             DWARF_FALSE_IF( opStack.size() < 2, 
529                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
530             long int first = opStack.top(); opStack.pop();
531             long int second = opStack.top(); opStack.pop();
532             opStack.push( first >= second ? 1 : 0 );
533          } break;
534
535          case DW_OP_eq: 
536          {
537             DWARF_FALSE_IF( opStack.size() < 2, 
538                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
539             long int first = opStack.top(); opStack.pop();
540             long int second = opStack.top(); opStack.pop();
541             opStack.push( first == second ? 1 : 0 );
542          } break;
543
544          case DW_OP_lt: 
545          {
546             DWARF_FALSE_IF( opStack.size() < 2, 
547                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
548             long int first = opStack.top(); opStack.pop();
549             long int second = opStack.top(); opStack.pop();
550             opStack.push( first < second ? 1 : 0 );
551          } break;
552
553          case DW_OP_gt: 
554          {
555             DWARF_FALSE_IF( opStack.size() < 2, 
556                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
557             long int first = opStack.top(); opStack.pop();
558             long int second = opStack.top(); opStack.pop();
559             opStack.push( first > second ? 1 : 0 );
560          } break;
561
562          case DW_OP_ne: 
563          {
564             DWARF_FALSE_IF( opStack.size() < 2, 
565                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
566             long int first = opStack.top(); opStack.pop();
567             long int second = opStack.top(); opStack.pop();
568             opStack.push( first != second ? 1 : 0 );
569          } break;
570
571          case DW_OP_bra:
572          {
573             DWARF_FALSE_IF( opStack.size() < 1, 
574                             "%s[%d]: invalid stack, returning false.\n", __FILE__, __LINE__ );
575             if ( opStack.top() == 0 ) { break; }
576             opStack.pop();
577          }
578          case DW_OP_skip: 
579          {
580             int bytes = (int)(Dwarf_Signed)locations[i].lr_number;
581             unsigned int target = (unsigned int) locations[i].lr_offset + bytes;
582             
583             int j = i;
584             if ( bytes < 0 ) {
585                for ( j = i - 1; j >= 0; j-- ) {
586                   if ( locations[j].lr_offset == target ) { break; }
587                } /* end search backward */
588             } else {
589                for ( j = i + 1; j < dwlocs->ld_cents; j ++ ) {
590                   if ( locations[j].lr_offset == target ) { break; }
591                } /* end search forward */
592             } /* end if positive offset */
593             
594             /* Because i will be incremented the next time around the loop. */
595             i = j - 1;
596          } break;
597
598          case DW_OP_piece:
599             /* For multi-part variables, which we don't handle. */
600             //bperr ( "Warning: dyninst does not handle multi-part variables.\n" );
601             break;
602
603          case DW_OP_nop:
604             break;
605
606          default:
607             dwarf_printf( "Unrecognized or non-static location opcode 0x%x, aborting.\n", locations[i].lr_atom );
608             return false;
609             break;
610       } /* end operand switch */
611    } /* end iteration over Dwarf_Loc entries. */
612    
613    if (opStack.empty()) {
614       dwarf_printf( "ignoring malformed location list (stack empty at end of list).\n" );
615       return isLocSet;
616    }
617    dwarf_printf( "Dwarf expression returning %d\n", opStack.top() );
618    end_result = opStack.top();
619    return true;
620 }
621
622 #endif