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