1 /* Copyright (C) 2007-2010 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 
13 /*
14  * Contains implementation of a class DwarfCU, that encapsulates a compilation
15  * unit in the .debug_info section of the mapped ELF file.
16  */
17 
18 #include "string.h"
19 #include "stdio.h"
20 #include "elf_file.h"
21 #include "dwarf_cu.h"
22 #include "dwarf_utils.h"
23 
DwarfCU(ElfFile * elf)24 DwarfCU::DwarfCU(ElfFile* elf)
25     : elf_file_(elf),
26       cu_die_(NULL),
27       prev_cu_(NULL) {
28 }
29 
~DwarfCU()30 DwarfCU::~DwarfCU() {
31   if (cu_die_ != NULL) {
32     delete cu_die_;
33   }
34   abbrs_.empty();
35 }
36 
create_instance(ElfFile * elf,const void * hdr)37 DwarfCU* DwarfCU::create_instance(ElfFile* elf, const void* hdr) {
38   DwarfCU* ret;
39 
40   /* 64-bit DWARF CU has first 4 bytes in its header set to 0xFFFFFFFF. */
41   if (*reinterpret_cast<const Elf_Word*>(hdr) == 0xFFFFFFFF) {
42     ret = new(elf) DwarfCUImpl<Dwarf64_CUHdr, Dwarf64_Off>
43                       (elf, reinterpret_cast<const Dwarf64_CUHdr*>(hdr));
44   } else {
45     ret = new(elf) DwarfCUImpl<Dwarf32_CUHdr, Dwarf32_Off>
46                       (elf, reinterpret_cast<const Dwarf32_CUHdr*>(hdr));
47   }
48   assert(ret != NULL);
49   if (ret == NULL) {
50     _set_errno(ENOMEM);
51   }
52   return ret;
53 }
54 
process_attrib(const Elf_Byte * prop,Dwarf_Form form,Dwarf_Value * attr_value) const55 const Elf_Byte* DwarfCU::process_attrib(const Elf_Byte* prop,
56                                         Dwarf_Form form,
57                                         Dwarf_Value* attr_value) const {
58   assert(form != 0);
59   Dwarf_Value tmp_val;
60   Dwarf_Value leb128;
61 
62   attr_value->type = DWARF_VALUE_UNKNOWN;
63   attr_value->encoded_size = 0;
64   attr_value->u64 = 0;
65 
66   switch (form) {
67     /* Property is a block of data, contained in .debug_info section. Block
68      * size is encoded with 1 byte value, and block data immediately follows
69      * block size. */
70     case DW_FORM_block1:
71       attr_value->type = DWARF_VALUE_BLOCK;
72       attr_value->block.block_size = *prop;
73       attr_value->block.block_ptr = prop + 1;
74       attr_value->encoded_size =
75           static_cast<Elf_Word>(attr_value->block.block_size + 1);
76       break;
77 
78     /* Property is a block of data, contained in .debug_info section. Block
79      * size is encoded with 2 bytes value, and block data immediately follows
80      * block size. */
81     case DW_FORM_block2:
82       attr_value->type = DWARF_VALUE_BLOCK;
83       attr_value->block.block_size =
84           elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop));
85       attr_value->block.block_ptr = prop + 2;
86       attr_value->encoded_size =
87           static_cast<Elf_Word>(attr_value->block.block_size + 2);
88       break;
89 
90     /* Property is a block of data, contained in .debug_info section. Block
91      * size is encoded with 4 bytes value, and block data immediately follows
92      * block size. */
93     case DW_FORM_block4:
94       attr_value->type = DWARF_VALUE_BLOCK;
95       attr_value->block.block_size =
96           elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
97       attr_value->block.block_ptr = prop + 4;
98       attr_value->encoded_size =
99           static_cast<Elf_Word>(attr_value->block.block_size + 4);
100       break;
101 
102     /* Property is a block of data, contained in .debug_info section. Block
103      * size is encoded with unsigned LEB128 value, and block data immediately
104      * follows block size. */
105     case DW_FORM_block:
106       reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(&leb128);
107       attr_value->type = DWARF_VALUE_BLOCK;
108       attr_value->block.block_size = leb128.u32;
109       attr_value->block.block_ptr = prop + leb128.encoded_size;
110       attr_value->encoded_size =
111           static_cast<Elf_Word>(attr_value->block.block_size +
112                                 leb128.encoded_size);
113       break;
114 
115     /* Property is unsigned 1 byte value. */
116     case DW_FORM_flag:
117     case DW_FORM_data1:
118     case DW_FORM_ref1:
119       attr_value->type = DWARF_VALUE_U8;
120       attr_value->u8 = *prop;
121       attr_value->encoded_size = 1;
122       break;
123 
124     /* Property is unsigned 2 bytes value. */
125     case DW_FORM_data2:
126     case DW_FORM_ref2:
127       attr_value->type = DWARF_VALUE_U16;
128       attr_value->u16 =
129           elf_file_->pull_val(reinterpret_cast<const Elf_Half*>(prop));
130       attr_value->encoded_size = 2;
131       break;
132 
133     /* Property is unsigned 4 bytes value. */
134     case DW_FORM_data4:
135     case DW_FORM_ref4:
136       attr_value->type = DWARF_VALUE_U32;
137       attr_value->u32 =
138           elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
139       attr_value->encoded_size = 4;
140       break;
141 
142     /* Property is unsigned 8 bytes value. */
143     case DW_FORM_data8:
144     case DW_FORM_ref8:
145     case DW_FORM_ref_sig8:
146       attr_value->type = DWARF_VALUE_U64;
147       attr_value->u64 =
148           elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
149       attr_value->encoded_size = 8;
150       break;
151 
152     /* Property is signed LEB128 value. */
153     case DW_FORM_sdata:
154       reinterpret_cast<const Dwarf_Leb128*>(prop)->process_signed(attr_value);
155       break;
156 
157     /* Property is unsigned LEB128 value. */
158     case DW_FORM_ref_udata:
159     case DW_FORM_udata:
160       reinterpret_cast<const Dwarf_Leb128*>(prop)->process_unsigned(attr_value);
161       break;
162 
163     /* Property is a string contained directly in .debug_info section. */
164     case DW_FORM_string:
165       attr_value->type = DWARF_VALUE_STR;
166       attr_value->str = reinterpret_cast<const char*>(prop);
167       attr_value->encoded_size = strlen(attr_value->str) + 1;
168       break;
169 
170     /* Property is an offset of a string contained in .debug_str section.
171      * We will process the reference here, converting it into the actual
172      * string value. */
173     case DW_FORM_strp:
174       attr_value->type = DWARF_VALUE_STR;
175       if (elf_file_->is_DWARF_64()) {
176         Elf_Xword str_offset =
177             elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
178         attr_value->str = elf_file_->get_debug_str(str_offset);
179         attr_value->encoded_size = 8;
180       } else {
181         Elf_Word str_offset =
182             elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
183         attr_value->str = elf_file_->get_debug_str(str_offset);
184         attr_value->encoded_size = 4;
185       }
186       break;
187 
188     /* Property is an address. */
189     case DW_FORM_addr:
190       if (addr_sizeof_ == 4) {
191         attr_value->type = DWARF_VALUE_PTR32;
192         attr_value->u32 =
193             elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
194       } else {
195         attr_value->type = DWARF_VALUE_PTR64;
196         attr_value->u64 =
197             elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
198       }
199       attr_value->encoded_size = addr_sizeof_;
200       break;
201 
202     /* Reference from the beginning of .debug_info section. */
203     case DW_FORM_ref_addr:
204       /* DWARF3+ requires that encoding size of this property must be 4 bytes
205        * in 32-bit DWARF, and 8 bytes in 64-bit DWARF, while DWARF2- requires
206        * encoding size to be equal to CU's pointer size. */
207       if (is_DWARF3_or_higher()) {
208         if (elf_file_->is_DWARF_64()) {
209           attr_value->type = DWARF_VALUE_U64;
210           attr_value->u64 =
211               elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
212           attr_value->encoded_size = 4;
213         } else {
214           attr_value->type = DWARF_VALUE_U32;
215           attr_value->u32 =
216               elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
217           attr_value->encoded_size = 8;
218         }
219       } else {
220         if (addr_sizeof_ == 4) {
221           attr_value->type = DWARF_VALUE_U32;
222           attr_value->u32 =
223               elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
224         } else {
225           attr_value->type = DWARF_VALUE_U64;
226           attr_value->u64 =
227               elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
228         }
229         attr_value->encoded_size = addr_sizeof_;
230       }
231       break;
232 
233     /* Reference to a section, other than .debug_info, or .debug_str */
234     case DW_FORM_sec_offset:
235       if (elf_file_->is_DWARF_64()) {
236         attr_value->type = DWARF_VALUE_U64;
237         attr_value->u64 =
238             elf_file_->pull_val(reinterpret_cast<const Elf_Xword*>(prop));
239         attr_value->encoded_size = 4;
240       } else {
241         attr_value->type = DWARF_VALUE_U32;
242         attr_value->u32 =
243             elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
244         attr_value->encoded_size = 8;
245       }
246       break;
247 
248     /* This is a replacement for DW_FORM_flag, which doesn't consume memory
249      * in .debug_info section, and only by the fact of its existence it is
250      * equal to DW_FORM_flag with value set to 1. */
251     case DW_FORM_flag_present:
252       attr_value->type = DWARF_VALUE_U8;
253       attr_value->u8 = 1;
254       attr_value->encoded_size = 0;
255       break;
256 
257     /* Encodes the actual form to be used. */
258     case DW_FORM_indirect:
259       // Starts with ULEB128
260       prop = reinterpret_cast<const Elf_Byte*>
261                 (reinterpret_cast<const Dwarf_Leb128*>
262                     (prop)->process_unsigned(&tmp_val));
263       /* ULEB128 encodes the actual form to be used to process this entry. */
264       process_attrib(prop, tmp_val.u16, attr_value);
265       attr_value->encoded_size += tmp_val.encoded_size;
266       break;
267 
268     /* This form is defined for DWARF4, and has no documentation whatsoever. */
269     case DW_FORM_exprloc:
270     default:
271       attr_value->type = DWARF_VALUE_U32;
272       attr_value->u32 =
273           elf_file_->pull_val(reinterpret_cast<const Elf_Word*>(prop));
274       attr_value->encoded_size = 4;
275       break;
276   }
277 
278   return prop + attr_value->encoded_size;
279 }
280 
dump() const281 void DwarfCU::dump() const {
282   printf("\n\n>>>>>>>>>>>>>>> CU %p (version %u, address size %u)\n",
283          cu_die_->die(), static_cast<Elf_Word>(version_),
284          static_cast<Elf_Word>(addr_sizeof_));
285   printf(">>>>> Build dir path:  %s\n", comp_dir_path());
286   printf(">>>>> Build file path: %s\n", rel_cu_path());
287   if (cu_die_ != NULL) {
288     cu_die_->dump(false);
289   }
290 }
291 
292 //=============================================================================
293 // DwarfCUImpl implementation
294 //=============================================================================
295 
296 template <typename Dwarf_CUHdr, typename Dwarf_Off>
DwarfCUImpl(ElfFile * elf,const Dwarf_CUHdr * hdr)297 DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::DwarfCUImpl(ElfFile* elf,
298                                                  const Dwarf_CUHdr* hdr)
299     : DwarfCU(elf),
300       cu_header_(hdr) {
301   /* Cache CU's DIE abbreviation descriptor in the array. This MUST be done
302    * BEFORE first call to array's cache_to() method. */
303   const Dwarf_Abbr_DIE* cu_abbr_die = reinterpret_cast<const Dwarf_Abbr_DIE*>
304                                  (INC_CPTR(elf->get_debug_abbrev_data(),
305                                            elf->pull_val(hdr->abbrev_offset)));
306   abbrs_.add(cu_abbr_die);
307 
308   cu_size_ = elf->pull_val(hdr->size_hdr.size);
309   version_ = elf->pull_val(hdr->version);
310   addr_sizeof_ = hdr->address_size;
311   memset(&stmtl_header_, 0, sizeof(stmtl_header_));
312 }
313 
314 template <typename Dwarf_CUHdr, typename Dwarf_Off>
parse(const DwarfParseContext * parse_context,const void ** next_cu_die)315 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::parse(
316     const DwarfParseContext* parse_context,
317     const void** next_cu_die) {
318   /* Start parsing with the DIE for this CU. */
319   if (process_DIE(parse_context, get_DIE(), NULL) == NULL) {
320     return false;
321   }
322 
323   /* CU area size (thus, next CU header offset) in .debug_info section equals
324    * to CU size, plus number of bytes, required to encode CU size in CU header
325    * (4 for 32-bit CU, and 12 for 64-bit CU. */
326   *next_cu_die =
327       INC_CPTR(cu_header_, cu_size_ + ELFF_FIELD_OFFSET(Dwarf_CUHdr, version));
328 
329   return true;
330 }
331 
332 template <typename Dwarf_CUHdr, typename Dwarf_Off>
process_DIE(const DwarfParseContext * parse_context,const Dwarf_DIE * die,DIEObject * parent_obj)333 const Elf_Byte* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::process_DIE(
334     const DwarfParseContext* parse_context,
335     const Dwarf_DIE* die,
336     DIEObject* parent_obj) {
337   while (is_attrib_ptr_valid(die) && !die->is_separator()) {
338     Dwarf_AbbrNum abbr_num;
339     Dwarf_Tag     die_tag;
340     Elf_Word      sibling_off = 0;
341 
342     /* Get DIE's abbreviation number, and advance to DIE's properties. */
343     const Elf_Byte* die_attr = die->process(&abbr_num);
344 
345     /* Get abbreviation for the current DIE. */
346     const Dwarf_Abbr_DIE* die_abbr = abbrs_.cache_to(abbr_num);
347     if (die_abbr == NULL) {
348       return NULL;
349     }
350 
351     /* Get base DIE properties, and advance to the DIE's
352      * attribute descriptors. */
353     const Dwarf_Abbr_AT* at_abbr = die_abbr->process(NULL, &die_tag);
354 
355     /* Instantiate DIE object for this DIE, and get list of properties,
356      * that should be collected while processing that DIE. */
357     DIEObject* die_obj =
358       create_die_object(parse_context, die, parent_obj, die_tag);
359     if (die_obj == NULL && errno != 0) {
360       return NULL;
361     }
362 
363     if (die_obj != NULL) {
364       if (parent_obj != NULL) {
365         /* Update list of parent's children. */
366         die_obj->link_sibling(parent_obj->last_child());
367         parent_obj->link_child(die_obj);
368       } else {
369         /* NULL parent object is allowed only for CU DIE itself. */
370         assert(cu_die_ == NULL && die_tag == DW_TAG_compile_unit);
371         if (cu_die_ == NULL && die_tag != DW_TAG_compile_unit) {
372           _set_errno(EINVAL);
373           return NULL;
374         }
375         cu_die_ = die_obj;
376         /* This CU DIE object will be used as a parent for all DIE
377          * objects, created in this method. */
378         parent_obj = cu_die_;
379       }
380     }
381 
382     // Loop through all DIE properties.
383     while (elf_file_->is_valid_abbr_ptr(at_abbr, sizeof(Dwarf_Abbr_AT)) &&
384            !at_abbr->is_separator()) {
385       Dwarf_At    at_value;
386       Dwarf_Form  at_form;
387       Dwarf_Value attr_value;
388 
389       // Obtain next property value.
390       at_abbr = at_abbr->process(&at_value, &at_form);
391       die_attr = process_attrib(die_attr, at_form, &attr_value);
392 
393       if (at_value == DW_AT_sibling) {
394         /* DW_AT_sibling means that next DIE is a child of the one that's
395          * being currently processed. We need to cache value of this property
396          * in order to correctly calculate next sibling of this DIE after
397          * child's DIE has been processed. */
398         assert(sibling_off == 0);
399         sibling_off = attr_value.u32;
400       }
401     }
402 
403     /* Next DIE immediately follows last property for the current DIE. */
404     die = reinterpret_cast<const Dwarf_DIE*>(die_attr);
405     if (sibling_off != 0) {
406       // Process child DIE.
407       process_DIE(parse_context, die, die_obj != NULL ? die_obj : parent_obj);
408       // Next sibling DIE offset is relative to this CU's header beginning.
409       die = INC_CPTR_T(Dwarf_DIE, cu_header_, sibling_off);
410     }
411   }
412 
413   return INC_CPTR_T(Elf_Byte, die, 1);
414 }
415 
416 template <typename Dwarf_CUHdr, typename Dwarf_Off>
create_die_object(const DwarfParseContext * parse_context,const Dwarf_DIE * die,DIEObject * parent,Dwarf_Tag tag)417 DIEObject* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::create_die_object(
418     const DwarfParseContext* parse_context,
419     const Dwarf_DIE* die,
420     DIEObject* parent,
421     Dwarf_Tag tag) {
422   DIEObject* ret = NULL;
423 
424   /* We will always create a DIE object for CU DIE. */
425   if (tag == DW_TAG_compile_unit || collect_die(parse_context, tag)) {
426     ret = new(elf_file_) DIEObject(die, this, parent);
427     assert(ret != NULL);
428     if (ret == NULL) {
429       _set_errno(ENOMEM);
430     }
431   } else {
432     _set_errno(0);
433   }
434   return ret;
435 }
436 
437 template <typename Dwarf_CUHdr, typename Dwarf_Off>
init_stmtl()438 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::init_stmtl() {
439   if (stmtl_header_.unit_length != 0) {
440     return true;
441   }
442 
443   assert(cu_die_ != NULL);
444   if (cu_die_ == NULL) {
445     _set_errno(EINVAL);
446     return false;
447   }
448 
449   DIEAttrib stmtl;
450   if (!cu_die()->get_attrib(DW_AT_stmt_list, &stmtl)) {
451     _set_errno(EINVAL);
452     return false;
453   }
454 
455   const void* stmtl_start =
456       INC_CPTR(elf_file()->get_debug_line_data(), stmtl.value()->u32);
457   if (*reinterpret_cast<const Elf_Word*>(stmtl_start) == 0xFFFFFFFF) {
458     cache_stmtl<Dwarf64_STMTLHdr>(reinterpret_cast<const Dwarf64_STMTLHdr*>(stmtl_start));
459   } else {
460     cache_stmtl<Dwarf32_STMTLHdr>(reinterpret_cast<const Dwarf32_STMTLHdr*>(stmtl_start));
461   }
462 
463   return true;
464 }
465 
466 template <typename Dwarf_CUHdr, typename Dwarf_Off>
get_pc_address_file_info(Elf_Xword address,Dwarf_AddressInfo * info)467 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_pc_address_file_info(
468     Elf_Xword address,
469     Dwarf_AddressInfo* info) {
470   /* Make sure STMTL header is cached. */
471   if (!init_stmtl()) {
472     return false;
473   }
474   /* Flags address match, that should trigger return next time
475    * source line gets adjusted. */
476   bool found = false;
477   /* Create new state machine. */
478   DwarfStateMachine state(stmtl_header_.default_is_stmt != 0);
479 
480   /* Start the "Line Number Program" */
481   const Elf_Byte* go = stmtl_header_.start;
482   while (go < stmtl_header_.end) {
483     const Elf_Byte op = *go;
484     go++;
485 
486     if (op == 0) {
487       /* This is an extended opcode. */
488       Dwarf_Value op_size;
489 
490       /* First ULEB128 contains opcode size, (excluding ULEB128 itself). */
491       go = reinterpret_cast<const Elf_Byte*>
492              (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&op_size));
493       /* Next is the extended opcode. */
494       const Elf_Byte* ex_op_ptr = go;
495       switch (*ex_op_ptr) {
496         case DW_LNE_end_sequence:
497           state.end_sequence_ = true;
498           state.reset(stmtl_header_.default_is_stmt != 0);
499           found = false;
500           break;
501 
502         case DW_LNE_set_address: {
503           Elf_Xword prev_address = state.address_;
504           if (is_CU_address_64()) {
505             state.address_ =
506               elf_file()->pull_val(reinterpret_cast<const Elf_Xword*>(ex_op_ptr + 1));
507           } else {
508             state.address_ =
509               elf_file()->pull_val(reinterpret_cast<const Elf_Word*>(ex_op_ptr + 1));
510           }
511           if (prev_address != 0 &&
512               address >= prev_address && address < state.address_) {
513             return set_source_info(&state, info);
514           } else if (address == state.address_) {
515             found = true;
516           }
517           break;
518         }
519 
520         case DW_LNE_define_file: {
521           /* Parameters start with the directly encoded zero-terminated
522            * file name. */
523           state.set_file_info_ = INC_CPTR_T(Dwarf_STMTL_FileDesc, ex_op_ptr, 1);
524           assert(state.set_file_info_ != NULL);
525           if (state.set_file_info_ != NULL) {
526             ex_op_ptr = reinterpret_cast<const Elf_Byte*>(state.set_file_info_->process(NULL));
527           }
528           break;
529         }
530 
531         case DW_LNE_set_discriminator: {
532           Dwarf_Value discr_val;
533           /* One parameter: discriminator's ULEB128 value. */
534           reinterpret_cast<const Dwarf_Leb128*>(ex_op_ptr + 1)->process_unsigned(&discr_val);
535           state.discriminator_ = discr_val.u32;
536           break;
537         }
538 
539         default:
540           assert(0);
541           return false;
542       }
543       go += op_size.u32;
544     } else if (op < stmtl_header_.opcode_base) {
545       /* This is a standard opcode. */
546       switch (op) {
547         case DW_LNS_copy:
548           /* No parameters. */
549           state.basic_block_ = false;
550           state.prologue_end_ = false;
551           state.epilogue_begin_ = false;
552           break;
553 
554         case DW_LNS_advance_pc: {
555           /* One parameter: ULEB128 value to add to the current address value
556            * in the state machine. */
557           Dwarf_Value addr_add;
558           go = reinterpret_cast<const Elf_Byte*>
559               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&addr_add));
560           Elf_Xword prev_address = state.address_;
561           state.address_ += addr_add.u64;
562           if (prev_address != 0 &&
563               address >= prev_address && address < state.address_) {
564             return set_source_info(&state, info);
565           } else if (address == state.address_) {
566             found = true;
567           }
568           break;
569         }
570 
571         case DW_LNS_advance_line: {
572           /* One parameter: signed LEB128 value to add to the current line
573            * number in the state machine. */
574           Dwarf_Value line_add;
575           go = reinterpret_cast<const Elf_Byte*>
576               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_signed(&line_add));
577           state.line_ += line_add.s32;
578           if (found) {
579             return set_source_info(&state, info);
580           }
581           break;
582         }
583 
584         case DW_LNS_set_file: {
585           /* One parameter: ULEB128 value encoding current file number. */
586           Dwarf_Value file_num;
587           go = reinterpret_cast<const Elf_Byte*>
588               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&file_num));
589           state.file_ = file_num.u32;
590           /* This operation should discard previously saved file information. */
591           state.set_file_info_ = NULL;
592           break;
593         }
594 
595         case DW_LNS_set_column: {
596           /* One parameter: ULEB128 value encoding current column number. */
597           Dwarf_Value column_num;
598           go = reinterpret_cast<const Elf_Byte*>
599               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&column_num));
600           state.column_ = column_num.u32;
601           break;
602         }
603 
604         case DW_LNS_negate_stmt:
605           /* No parameters. */
606           state.is_stmt_ = !state.is_stmt_;
607           break;
608 
609         case DW_LNS_set_basic_block:
610           /* No parameters. */
611           state.basic_block_ = true;
612           break;
613 
614         case DW_LNS_const_add_pc: {
615           Elf_Xword prev_address = state.address_;
616           /* No parameters. This operation does the same thing, as special
617            * opcode 255 would do to the current address. */
618           Elf_Word adjusted =
619               static_cast<Elf_Word>(255) - stmtl_header_.opcode_base;
620           state.address_ += (adjusted / stmtl_header_.line_range) *
621                             stmtl_header_.min_instruction_len;
622           if (prev_address != 0 &&
623               address >= prev_address && address < state.address_) {
624             return set_source_info(&state, info);
625           } else if (address == state.address_) {
626             found = true;
627           }
628           break;
629         }
630 
631         case DW_LNS_fixed_advance_pc: {
632           Elf_Xword prev_address = state.address_;
633           /* One parameter: directly encoded 16-bit value to add to the
634            * current address. */
635           state.address_ +=
636               elf_file()->pull_val(reinterpret_cast<const Elf_Half*>(go));
637           if (prev_address != 0 &&
638               address >= prev_address && address < state.address_) {
639             return set_source_info(&state, info);
640           } else if (address == state.address_) {
641             found = true;
642           }
643           go += sizeof(Elf_Half);
644           break;
645         }
646 
647         case DW_LNS_set_prologue_end:
648           /* No parameters. */
649           state.prologue_end_ = true;
650           break;
651 
652         case DW_LNS_set_epilogue_begin:
653           /* No parameters. */
654           state.epilogue_begin_ = true;
655           break;
656 
657         case DW_LNS_set_isa: {
658           /* One parameter: ISA value encoded as ULEB128. */
659           Dwarf_Value isa_val;
660           go = reinterpret_cast<const Elf_Byte*>
661               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&isa_val));
662           state.isa_ = isa_val.u32;
663           break;
664         }
665 
666         default:
667           /* Unknown opcode. Just skip it. */
668           for (Elf_Byte uleb = 0;
669                uleb < stmtl_header_.standard_opcode_lengths[op - 1]; uleb++) {
670             Dwarf_Value tmp;
671             go = reinterpret_cast<const Elf_Byte*>
672               (reinterpret_cast<const Dwarf_Leb128*>(go)->process_unsigned(&tmp));
673           }
674           break;
675       }
676     } else {
677       Elf_Xword prev_address = state.address_;
678       /* This is a special opcode. */
679       const Elf_Word adjusted = op - stmtl_header_.opcode_base;
680       /* Advance address. */
681       state.address_ += (adjusted / stmtl_header_.line_range) *
682                         stmtl_header_.min_instruction_len;
683       if (prev_address != 0 &&
684           address >= prev_address && address < state.address_) {
685         return set_source_info(&state, info);
686       }
687       /* Advance line. */
688       state.line_ += stmtl_header_.line_base +
689                      (adjusted % stmtl_header_.line_range);
690       if (state.address_ == address) {
691         return set_source_info(&state, info);
692       }
693       /* Do the woodoo. */
694       state.basic_block_ = false;
695       state.prologue_end_ = false;
696       state.epilogue_begin_ = false;
697     }
698   }
699 
700   return false;
701 }
702 
703 template <typename Dwarf_CUHdr, typename Dwarf_Off>
get_stmt_file_info(Elf_Word index)704 const Dwarf_STMTL_FileDesc* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_file_info(
705     Elf_Word index) {
706   /* Index must be 1-based. */
707   if (index == 0) {
708     return NULL;
709   }
710 
711   const Dwarf_STMTL_FileDesc* cur_desc = stmtl_header_.file_infos;
712   while (index != 1 && !cur_desc->is_last_entry()) {
713     cur_desc = cur_desc->process(NULL);
714     index--;
715   }
716   assert(!cur_desc->is_last_entry());
717   return cur_desc->is_last_entry() ? NULL : cur_desc;
718 }
719 
720 template <typename Dwarf_CUHdr, typename Dwarf_Off>
get_stmt_dir_name(Elf_Word dir_index)721 const char* DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::get_stmt_dir_name(
722     Elf_Word dir_index) {
723   if (dir_index == 0) {
724     /* Requested is current compilation directory. */
725     return comp_dir_path();
726   }
727   if (dir_index > stmtl_header_.inc_dir_num) {
728     return NULL;
729   }
730 
731   const char* cur_dir = stmtl_header_.include_directories;
732   while (dir_index != 1) {
733     cur_dir += strlen(cur_dir) + 1;
734     dir_index--;
735   }
736   return cur_dir;
737 }
738 
739 template <typename Dwarf_CUHdr, typename Dwarf_Off>
set_source_info(const DwarfStateMachine * state,Dwarf_AddressInfo * info)740 bool DwarfCUImpl<Dwarf_CUHdr, Dwarf_Off>::set_source_info(
741     const DwarfStateMachine* state,
742     Dwarf_AddressInfo* info) {
743   info->line_number = state->line_;
744   const Dwarf_STMTL_FileDesc* file_info = state->set_file_info_;
745   if (file_info == NULL) {
746     file_info = get_stmt_file_info(state->file_);
747     if (file_info == NULL) {
748       info->file_name = rel_cu_path();
749       info->dir_name = comp_dir_path();
750       return true;
751     }
752   }
753   info->file_name = file_info->get_file_name();
754   const Elf_Word dir_index = file_info->get_dir_index();
755   info->dir_name = get_stmt_dir_name(dir_index);
756   return true;
757 }
758 
759