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
24DwarfCU::DwarfCU(ElfFile* elf)
25    : elf_file_(elf),
26      cu_die_(NULL),
27      prev_cu_(NULL) {
28}
29
30DwarfCU::~DwarfCU() {
31  if (cu_die_ != NULL) {
32    delete cu_die_;
33  }
34  abbrs_.empty();
35}
36
37DwarfCU* 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
55const 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
281void 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
296template <typename Dwarf_CUHdr, typename Dwarf_Off>
297DwarfCUImpl<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
314template <typename Dwarf_CUHdr, typename Dwarf_Off>
315bool 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
332template <typename Dwarf_CUHdr, typename Dwarf_Off>
333const 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
416template <typename Dwarf_CUHdr, typename Dwarf_Off>
417DIEObject* 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
437template <typename Dwarf_CUHdr, typename Dwarf_Off>
438bool 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
466template <typename Dwarf_CUHdr, typename Dwarf_Off>
467bool 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
703template <typename Dwarf_CUHdr, typename Dwarf_Off>
704const 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
720template <typename Dwarf_CUHdr, typename Dwarf_Off>
721const 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
739template <typename Dwarf_CUHdr, typename Dwarf_Off>
740bool 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