1 /*
2
3 Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5 Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of version 2.1 of the GNU Lesser General Public License
9 as published by the Free Software Foundation.
10
11 This program is distributed in the hope that it would be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 Further, this software is distributed without any warranty that it is
16 free of the rightful claim of any third person regarding infringement
17 or the like. Any license provided herein, whether implied or
18 otherwise, applies only to this software file. Patent licenses, if
19 any, provided herein do not apply to combinations of this program with
20 other software, or any other product whatsoever.
21
22 You should have received a copy of the GNU Lesser General Public
23 License along with this program; if not, write the Free Software
24 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25 USA.
26
27 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
28 Mountain View, CA 94043, or:
29
30 http://www.sgi.com
31
32 For further information regarding this notice, see:
33
34 http://oss.sgi.com/projects/GenInfo/NoticeExplan
35
36 */
37 /*
38 SGI has moved from the Crittenden Lane address.
39 */
40
41
42
43
44
45 #include "config.h"
46 #include "libdwarfdefs.h"
47 #include <stdio.h>
48 #include <string.h>
49 #ifdef HAVE_ELFACCESS_H
50 #include <elfaccess.h>
51 #endif
52 #include "pro_incl.h"
53 #include "pro_section.h"
54 #include "pro_line.h"
55 #include "pro_frame.h"
56 #include "pro_die.h"
57 #include "pro_macinfo.h"
58 #include "pro_types.h"
59
60 #ifndef SHF_MIPS_NOSTRIP
61 /* if this is not defined, we probably don't need it: just use 0 */
62 #define SHF_MIPS_NOSTRIP 0
63 #endif
64 #ifndef R_MIPS_NONE
65 #define R_MIPS_NONE 0
66 #endif
67
68 #ifndef TRUE
69 #define TRUE 1
70 #endif
71 #ifndef FALSE
72 #define FALSE 0
73 #endif
74
75 /* must match up with pro_section.h defines of DEBUG_INFO etc
76 and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela"
77 see pro_incl.h
78 */
79 char *_dwarf_rel_section_names[] = {
80 REL_SEC_PREFIX ".debug_info",
81 REL_SEC_PREFIX ".debug_line",
82 REL_SEC_PREFIX ".debug_abbrev", /* no relocations on this, really */
83 REL_SEC_PREFIX ".debug_frame",
84 REL_SEC_PREFIX ".debug_aranges",
85 REL_SEC_PREFIX ".debug_pubnames",
86 REL_SEC_PREFIX ".debug_str",
87 REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */
88 REL_SEC_PREFIX ".debug_typenames", /* sgi extension */
89 REL_SEC_PREFIX ".debug_varnames", /* sgi extension */
90 REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */
91 REL_SEC_PREFIX ".debug_macinfo",
92 REL_SEC_PREFIX ".debug_loc"
93 };
94
95 /* names of sections. Ensure that it matches the defines
96 in pro_section.h, in the same order
97 Must match also _dwarf_rel_section_names above
98 */
99 char *_dwarf_sectnames[] = {
100 ".debug_info",
101 ".debug_line",
102 ".debug_abbrev",
103 ".debug_frame",
104 ".debug_aranges",
105 ".debug_pubnames",
106 ".debug_str",
107 ".debug_funcnames", /* sgi extension */
108 ".debug_typenames", /* sgi extension */
109 ".debug_varnames", /* sgi extension */
110 ".debug_weaknames", /* sgi extension */
111 ".debug_macinfo",
112 ".debug_loc"
113 };
114
115
116
117
118 static Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */
119 1, /* DW_LNS_advance_pc */
120 1, /* DW_LNS_advance_line */
121 1, /* DW_LNS_set_file */
122 1, /* DW_LNS_set_column */
123 0, /* DW_LNS_negate_stmt */
124 0, /* DW_LNS_set_basic_block */
125 0, /* DW_LNS_const_add_pc */
126 1, /* DW_LNS_fixed_advance_pc */
127 };
128
129 /* struct to hold relocation entries. Its mantained as a linked
130 list of relocation structs, and will then be written at as a
131 whole into the relocation section. Whether its 32 bit or
132 64 bit will be obtained from Dwarf_Debug pointer.
133 */
134
135 typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
136 struct Dwarf_P_Rel_s {
137 Dwarf_P_Rel dr_next;
138 void *dr_rel_datap;
139 };
140 typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
141 struct Dwarf_P_Rel_Head_s {
142 struct Dwarf_P_Rel_s *drh_head;
143 struct Dwarf_P_Rel_s *drh_tail;
144 };
145
146 static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
147 Dwarf_Error * error);
148 static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
149 Dwarf_Error * error);
150 static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
151 Dwarf_Error * error);
152 static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev);
153 static int _dwarf_pro_match_attr
154 (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
155
156 /* these macros used as return value for below functions */
157 #define OPC_INCS_ZERO -1
158 #define OPC_OUT_OF_RANGE -2
159 #define LINE_OUT_OF_RANGE -3
160 static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv);
161
162
163 /* BEGIN_LEN_SIZE is the size of the 'length' field in total.
164 Which may be 4,8, or 12 bytes!
165 4 is standard DWARF2.
166 8 is non-standard MIPS-IRIX 64-bit.
167 12 is standard DWARF3 for 64 bit offsets.
168 Used in various routines: local variable names
169 must match the names here.
170 */
171 #define BEGIN_LEN_SIZE (uwordb_size + extension_size)
172
173 /*
174 Return TRUE if we need the section, FALSE otherwise
175
176 If any of the 'line-data-related' calls were made
177 including file or directory entries,
178 produce .debug_line .
179
180 */
181 static int
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)182 dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
183 {
184 if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
185 && dbg->de_inc_dirs == NULL) {
186 return FALSE;
187 }
188 return TRUE;
189 }
190
191 /*
192 Convert debug information to a format such that
193 it can be written on disk.
194 Called exactly once per execution.
195 */
196 Dwarf_Signed
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)197 dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
198 {
199 /*
200 Section data in written out in a number of buffers. Each
201 _generate_*() function returns a cumulative count of buffers for
202 all the sections. get_section_bytes() returns pointers to these
203 buffers one at a time. */
204 int nbufs = 0;
205 int sect = 0;
206 int err = 0;
207 Dwarf_Unsigned du = 0;
208
209 if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
210 DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
211 }
212
213 /* Create dwarf section headers */
214 for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
215 long flags = 0;
216
217 switch (sect) {
218
219 case DEBUG_INFO:
220 if (dbg->de_dies == NULL)
221 continue;
222 break;
223
224 case DEBUG_LINE:
225 if (dwarf_need_debug_line_section(dbg) == FALSE) {
226 continue;
227 }
228 break;
229
230 case DEBUG_ABBREV:
231 if (dbg->de_dies == NULL)
232 continue;
233 break;
234
235 case DEBUG_FRAME:
236 if (dbg->de_frame_cies == NULL)
237 continue;
238 flags = SHF_MIPS_NOSTRIP;
239 break;
240
241 case DEBUG_ARANGES:
242 if (dbg->de_arange == NULL)
243 continue;
244 break;
245
246 case DEBUG_PUBNAMES:
247 if (dbg->de_simple_name_headers[dwarf_snk_pubname].
248 sn_head == NULL)
249 continue;
250 break;
251
252 case DEBUG_STR:
253 if (dbg->de_strings == NULL)
254 continue;
255 break;
256
257 case DEBUG_FUNCNAMES:
258 if (dbg->de_simple_name_headers[dwarf_snk_funcname].
259 sn_head == NULL)
260 continue;
261 break;
262
263 case DEBUG_TYPENAMES:
264 if (dbg->de_simple_name_headers[dwarf_snk_typename].
265 sn_head == NULL)
266 continue;
267 break;
268
269 case DEBUG_VARNAMES:
270 if (dbg->de_simple_name_headers[dwarf_snk_varname].
271 sn_head == NULL)
272 continue;
273 break;
274
275 case DEBUG_WEAKNAMES:
276 if (dbg->de_simple_name_headers[dwarf_snk_weakname].
277 sn_head == NULL)
278 continue;
279 break;
280
281 case DEBUG_MACINFO:
282 if (dbg->de_first_macinfo == NULL)
283 continue;
284 break;
285 case DEBUG_LOC:
286 /* not handled yet */
287 continue;
288 default:
289 /* logic error: missing a case */
290 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
291 }
292 {
293 int new_base_elf_sect;
294
295 if (dbg->de_callback_func_b) {
296 new_base_elf_sect =
297 dbg->de_callback_func_b(_dwarf_sectnames[sect],
298 /* rec size */ 1,
299 SECTION_TYPE,
300 flags, SHN_UNDEF, 0, &du, &err);
301
302 } else {
303 int name_idx = 0;
304 new_base_elf_sect = dbg->de_callback_func(
305 _dwarf_sectnames[sect],
306 dbg->de_relocation_record_size,
307 SECTION_TYPE, flags,
308 SHN_UNDEF, 0,
309 &name_idx, &err);
310 du = name_idx;
311 }
312 if (new_base_elf_sect == -1) {
313 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
314 DW_DLV_NOCOUNT);
315 }
316 dbg->de_elf_sects[sect] = new_base_elf_sect;
317
318 dbg->de_sect_name_idx[sect] = du;
319 }
320 }
321
322 nbufs = 0;
323
324 /*
325 Changing the order in which the sections are generated may cause
326 problems because of relocations. */
327
328 if (dwarf_need_debug_line_section(dbg) == TRUE) {
329 nbufs = _dwarf_pro_generate_debugline(dbg, error);
330 if (nbufs < 0) {
331 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
332 DW_DLV_NOCOUNT);
333 }
334 }
335
336 if (dbg->de_frame_cies) {
337 nbufs = _dwarf_pro_generate_debugframe(dbg, error);
338 if (nbufs < 0) {
339 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
340 DW_DLV_NOCOUNT);
341 }
342 }
343 if (dbg->de_first_macinfo) {
344 nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
345 if (nbufs < 0) {
346 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
347 DW_DLV_NOCOUNT);
348 }
349 }
350
351 if (dbg->de_dies) {
352 nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
353 if (nbufs < 0) {
354 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
355 DW_DLV_NOCOUNT);
356 }
357 }
358
359 if (dbg->de_arange) {
360 nbufs = _dwarf_transform_arange_to_disk(dbg, error);
361 if (nbufs < 0) {
362 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
363 DW_DLV_NOCOUNT);
364 }
365 }
366
367 if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
368 nbufs = _dwarf_transform_simplename_to_disk(dbg,
369 dwarf_snk_pubname,
370 DEBUG_PUBNAMES,
371 error);
372
373
374 if (nbufs < 0) {
375 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
376 DW_DLV_NOCOUNT);
377 }
378 }
379
380 if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
381 nbufs = _dwarf_transform_simplename_to_disk(dbg,
382 dwarf_snk_funcname,
383 DEBUG_FUNCNAMES,
384 error);
385 if (nbufs < 0) {
386 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
387 DW_DLV_NOCOUNT);
388 }
389 }
390
391 if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
392 nbufs = _dwarf_transform_simplename_to_disk(dbg,
393 dwarf_snk_typename,
394 DEBUG_TYPENAMES,
395 error);
396 if (nbufs < 0) {
397 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
398 DW_DLV_NOCOUNT);
399 }
400 }
401
402 if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
403 nbufs = _dwarf_transform_simplename_to_disk(dbg,
404 dwarf_snk_varname,
405 DEBUG_VARNAMES,
406 error);
407
408 if (nbufs < 0) {
409 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
410 DW_DLV_NOCOUNT);
411 }
412 }
413
414 if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
415 nbufs = _dwarf_transform_simplename_to_disk(dbg,
416 dwarf_snk_weakname, DEBUG_WEAKNAMES, error);
417 if (nbufs < 0) {
418 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
419 DW_DLV_NOCOUNT);
420 }
421 }
422
423 {
424 Dwarf_Signed new_secs = 0;
425 int res = 0;
426
427 res = dbg->de_transform_relocs_to_disk(dbg, &new_secs);
428 if (res != DW_DLV_OK) {
429 DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
430 DW_DLV_NOCOUNT);
431 }
432 nbufs += new_secs;
433 }
434 return nbufs;
435 }
436
437
438 /*---------------------------------------------------------------
439 Generate debug_line section
440 ---------------------------------------------------------------*/
441 static int
_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,Dwarf_Error * error)442 _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error)
443 {
444 Dwarf_P_Inc_Dir curdir = 0;
445 Dwarf_P_F_Entry curentry = 0;
446 Dwarf_P_Line curline = 0;
447 Dwarf_P_Line prevline = 0;
448
449 /* all data named cur* are used to loop thru linked lists */
450
451 int sum_bytes = 0;
452 int prolog_size = 0;
453 unsigned char *data = 0; /* holds disk form data */
454 int elfsectno = 0;
455 unsigned char *start_line_sec = 0; /* pointer to the buffer at
456 section start */
457 /* temps for memcpy */
458 Dwarf_Unsigned du = 0;
459 Dwarf_Ubyte db = 0;
460 Dwarf_Half dh = 0;
461 int res = 0;
462 int uwordb_size = dbg->de_offset_size;
463 int extension_size = dbg->de_64bit_extension ? 4 : 0;
464 int upointer_size = dbg->de_pointer_size;
465 char buff1[ENCODE_SPACE_NEEDED];
466
467
468
469 sum_bytes = 0;
470
471 elfsectno = dbg->de_elf_sects[DEBUG_LINE];
472
473 /* include directories */
474 curdir = dbg->de_inc_dirs;
475 while (curdir) {
476 prolog_size += strlen(curdir->did_name) + 1;
477 curdir = curdir->did_next;
478 }
479 prolog_size++; /* last null following last directory
480 entry. */
481
482 /* file entries */
483 curentry = dbg->de_file_entries;
484 while (curentry) {
485 prolog_size +=
486 strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
487 curentry = curentry->dfe_next;
488 }
489 prolog_size++; /* last null byte */
490
491
492 prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */
493 uwordb_size + /* header length */
494 sizeof_ubyte(dbg) + /* min_instr length */
495 sizeof_ubyte(dbg) + /* default is_stmt */
496 sizeof_ubyte(dbg) + /* linebase */
497 sizeof_ubyte(dbg) + /* linerange */
498 sizeof_ubyte(dbg); /* opcode base */
499
500 /* length of table specifying # of opnds */
501 prolog_size += sizeof(std_opcode_len);
502
503 GET_CHUNK(dbg, elfsectno, data, prolog_size, error);
504 start_line_sec = data;
505
506 /* copy over the data */
507 /* total_length */
508 du = 0;
509 if (extension_size) {
510 Dwarf_Word x = DISTINGUISHED_VALUE;
511
512 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
513 sizeof(x), extension_size);
514 data += extension_size;
515 }
516
517 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
518 sizeof(du), uwordb_size);
519 data += uwordb_size;
520
521 dh = VERSION;
522 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
523 sizeof(dh), sizeof(Dwarf_Half));
524 data += sizeof(Dwarf_Half);
525
526 /* header length */
527 du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +
528 uwordb_size);
529 {
530 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
531 sizeof(du), uwordb_size);
532 data += uwordb_size;
533 }
534 db = MIN_INST_LENGTH;
535 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
536 sizeof(db), sizeof(Dwarf_Ubyte));
537 data += sizeof(Dwarf_Ubyte);
538 db = DEFAULT_IS_STMT;
539 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
540 sizeof(db), sizeof(Dwarf_Ubyte));
541 data += sizeof(Dwarf_Ubyte);
542 db = (Dwarf_Ubyte) LINE_BASE;
543 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
544 sizeof(db), sizeof(Dwarf_Ubyte));
545 data += sizeof(Dwarf_Ubyte);
546 db = LINE_RANGE;
547 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
548 sizeof(db), sizeof(Dwarf_Ubyte));
549 data += sizeof(Dwarf_Ubyte);
550 db = OPCODE_BASE;
551 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
552 sizeof(db), sizeof(Dwarf_Ubyte));
553 data += sizeof(Dwarf_Ubyte);
554 WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
555 sizeof(std_opcode_len), sizeof(std_opcode_len));
556 data += sizeof(std_opcode_len);
557
558 /* copy over include directories */
559 curdir = dbg->de_inc_dirs;
560 while (curdir) {
561 strcpy((char *) data, curdir->did_name);
562 data += strlen(curdir->did_name) + 1;
563 curdir = curdir->did_next;
564 }
565 *data = '\0'; /* last null */
566 data++;
567
568 /* copy file entries */
569 curentry = dbg->de_file_entries;
570 while (curentry) {
571 strcpy((char *) data, curentry->dfe_name);
572 data += strlen(curentry->dfe_name) + 1;
573 /* copies of leb numbers, no endian issues */
574 memcpy((void *) data,
575 (const void *) curentry->dfe_args, curentry->dfe_nbytes);
576 data += curentry->dfe_nbytes;
577 curentry = curentry->dfe_next;
578 }
579 *data = '\0';
580 data++;
581
582 sum_bytes += prolog_size;
583
584 curline = dbg->de_lines;
585 prevline = (Dwarf_P_Line)
586 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
587 if (prevline == NULL) {
588 DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
589 }
590 _dwarf_pro_reg_init(prevline);
591 /* generate opcodes for line numbers */
592 while (curline) {
593 int nbytes;
594 char *arg;
595 int opc;
596 int no_lns_copy; /* if lns copy opcode doesnt need to be
597 generated, if special opcode or end
598 sequence */
599 Dwarf_Unsigned addr_adv;
600 int line_adv; /* supposed to be a reasonably small
601 number, so the size should not be a
602 problem. ? */
603
604 no_lns_copy = 0;
605 if (curline->dpl_opc != 0) {
606 int inst_bytes; /* no of bytes in extended opcode */
607 char *str; /* hold leb encoded inst_bytes */
608 int str_nbytes; /* no of bytes in str */
609
610 switch (curline->dpl_opc) {
611 case DW_LNE_end_sequence:
612
613 /* Advance pc to end of text section. */
614 addr_adv = curline->dpl_address - prevline->dpl_address;
615 if (addr_adv > 0) {
616 db = DW_LNS_advance_pc;
617 res =
618 _dwarf_pro_encode_leb128_nm(addr_adv /
619 MIN_INST_LENGTH,
620 &nbytes, buff1,
621 sizeof(buff1));
622 if (res != DW_DLV_OK) {
623 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
624 }
625 GET_CHUNK(dbg, elfsectno, data,
626 nbytes + sizeof(Dwarf_Ubyte), error);
627 WRITE_UNALIGNED(dbg, (void *) data,
628 (const void *) &db, sizeof(db),
629 sizeof(Dwarf_Ubyte));
630 data += sizeof(Dwarf_Ubyte);
631 /* leb, no endianness issue */
632 memcpy((void *) data, (const void *) buff1, nbytes);
633 data += nbytes + sizeof(Dwarf_Ubyte);
634 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
635 prevline->dpl_address = curline->dpl_address;
636 }
637
638 /* first null byte */
639 db = 0;
640 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
641 error);
642 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
643 sizeof(db), sizeof(Dwarf_Ubyte));
644 data += sizeof(Dwarf_Ubyte);
645 sum_bytes += sizeof(Dwarf_Ubyte);
646
647 /* write length of extended opcode */
648 inst_bytes = sizeof(Dwarf_Ubyte);
649 res =
650 _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
651 buff1, sizeof(buff1));
652 if (res != DW_DLV_OK) {
653 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
654 }
655 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
656 memcpy((void *) data, (const void *) buff1, str_nbytes);
657 data += str_nbytes;
658 sum_bytes += str_nbytes;
659
660 /* write extended opcode */
661 db = DW_LNE_end_sequence;
662 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
663 error);
664 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
665 sizeof(db), sizeof(Dwarf_Ubyte));
666 data += sizeof(Dwarf_Ubyte);
667 sum_bytes += sizeof(Dwarf_Ubyte);
668 /* reset value to original values */
669 _dwarf_pro_reg_init(prevline);
670 no_lns_copy = 1;
671 /* this is set only for end_sequence, so that a
672 dw_lns_copy is not generated */
673 break;
674
675 case DW_LNE_set_address:
676
677 /* first null byte */
678 db = 0;
679 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
680 error);
681 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
682 sizeof(db), sizeof(Dwarf_Ubyte));
683 data += sizeof(Dwarf_Ubyte);
684 sum_bytes += sizeof(Dwarf_Ubyte);
685
686 /* write length of extended opcode */
687 inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
688 res =
689 _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
690 buff1, sizeof(buff1));
691 if (res != DW_DLV_OK) {
692 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
693 }
694 GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
695 str = buff1;
696 /* leb number, no endian issue */
697 memcpy((void *) data, (const void *) str, str_nbytes);
698 data += str_nbytes;
699 sum_bytes += str_nbytes;
700
701 /* write extended opcode */
702 db = DW_LNE_set_address;
703 GET_CHUNK(dbg, elfsectno, data, upointer_size +
704 sizeof(Dwarf_Ubyte), error);
705 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
706 sizeof(db), sizeof(Dwarf_Ubyte));
707 data += sizeof(Dwarf_Ubyte);
708 sum_bytes += sizeof(Dwarf_Ubyte);
709
710 /* reloc for address */
711 res = dbg->de_reloc_name(dbg, DEBUG_LINE,
712 sum_bytes, /* r_offset */
713 curline->dpl_r_symidx,
714 dwarf_drt_data_reloc,
715 uwordb_size);
716 if (res != DW_DLV_OK) {
717 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
718 }
719
720 /* write offset (address) */
721 du = curline->dpl_address;
722 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
723 sizeof(du), upointer_size);
724 data += upointer_size;
725 sum_bytes += upointer_size;
726 prevline->dpl_address = curline->dpl_address;
727 no_lns_copy = 1;
728 break;
729 }
730 } else {
731 if (curline->dpl_file != prevline->dpl_file) {
732 db = DW_LNS_set_file;
733 res =
734 _dwarf_pro_encode_leb128_nm(curline->dpl_file,
735 &nbytes, buff1,
736 sizeof(buff1));
737 if (res != DW_DLV_OK) {
738 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
739 }
740 arg = buff1;
741 GET_CHUNK(dbg, elfsectno, data,
742 nbytes + sizeof(Dwarf_Ubyte), error);
743 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
744 sizeof(db), sizeof(Dwarf_Ubyte));
745 data += sizeof(Dwarf_Ubyte);
746 memcpy((void *) data, (const void *) arg, nbytes);
747 data += nbytes;
748 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
749 prevline->dpl_file = curline->dpl_file;
750 }
751 if (curline->dpl_column != prevline->dpl_column) {
752 db = DW_LNS_set_column;
753 res = _dwarf_pro_encode_leb128_nm(curline->dpl_column,
754 &nbytes,
755 buff1, sizeof(buff1));
756 if (res != DW_DLV_OK) {
757 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
758 }
759
760 arg = buff1;
761 GET_CHUNK(dbg, elfsectno, data,
762 nbytes + sizeof(Dwarf_Ubyte), error);
763 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
764 sizeof(db), sizeof(Dwarf_Ubyte));
765 data += sizeof(Dwarf_Ubyte);
766 memcpy((void *) data, (const void *) arg, nbytes);
767 data += nbytes;
768 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
769 prevline->dpl_column = curline->dpl_column;
770 }
771 if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
772 db = DW_LNS_negate_stmt;
773 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
774 error);
775 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
776 sizeof(db), sizeof(Dwarf_Ubyte));
777 data += sizeof(Dwarf_Ubyte);
778 sum_bytes += sizeof(Dwarf_Ubyte);
779 prevline->dpl_is_stmt = curline->dpl_is_stmt;
780 }
781 if (curline->dpl_basic_block == true &&
782 prevline->dpl_basic_block == false) {
783 db = DW_LNS_set_basic_block;
784 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
785 error);
786 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
787 sizeof(db), sizeof(Dwarf_Ubyte));
788 data += sizeof(Dwarf_Ubyte);
789 sum_bytes += sizeof(Dwarf_Ubyte);
790 prevline->dpl_basic_block = curline->dpl_basic_block;
791 }
792 addr_adv = curline->dpl_address - prevline->dpl_address;
793
794 line_adv = (int) (curline->dpl_line - prevline->dpl_line);
795 if ((addr_adv % MIN_INST_LENGTH) != 0) {
796 DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
797 }
798 if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) {
799 no_lns_copy = 1;
800 db = opc;
801 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
802 error);
803 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
804 sizeof(db), sizeof(Dwarf_Ubyte));
805 data += sizeof(Dwarf_Ubyte);
806 sum_bytes += sizeof(Dwarf_Ubyte);
807 prevline->dpl_basic_block = false;
808 prevline->dpl_address = curline->dpl_address;
809 prevline->dpl_line = curline->dpl_line;
810 } else {
811 if (addr_adv > 0) {
812 db = DW_LNS_advance_pc;
813 res =
814 _dwarf_pro_encode_leb128_nm(addr_adv /
815 MIN_INST_LENGTH,
816 &nbytes, buff1,
817 sizeof(buff1));
818 if (res != DW_DLV_OK) {
819 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
820 }
821
822 arg = buff1;
823 GET_CHUNK(dbg, elfsectno, data,
824 nbytes + sizeof(Dwarf_Ubyte), error);
825 WRITE_UNALIGNED(dbg, (void *) data,
826 (const void *) &db,
827 sizeof(db), sizeof(Dwarf_Ubyte));
828 data += sizeof(Dwarf_Ubyte);
829 memcpy((void *) data, (const void *) arg, nbytes);
830 data += nbytes + sizeof(Dwarf_Ubyte);
831 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
832 prevline->dpl_basic_block = false;
833 prevline->dpl_address = curline->dpl_address;
834 }
835 if (line_adv != 0) {
836 db = DW_LNS_advance_line;
837 res = _dwarf_pro_encode_signed_leb128_nm(line_adv,
838 &nbytes,
839 buff1,
840 sizeof
841 (buff1));
842 if (res != DW_DLV_OK) {
843 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
844 }
845
846 arg = buff1;
847 GET_CHUNK(dbg, elfsectno, data,
848 nbytes + sizeof(Dwarf_Ubyte), error);
849 WRITE_UNALIGNED(dbg, (void *) data,
850 (const void *) &db, sizeof(db),
851 sizeof(Dwarf_Ubyte));
852 data += sizeof(Dwarf_Ubyte);
853 memcpy((void *) data, (const void *) arg, nbytes);
854 data += nbytes + sizeof(Dwarf_Ubyte);
855 sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
856 prevline->dpl_basic_block = false;
857 prevline->dpl_line = curline->dpl_line;
858 }
859 }
860 } /* ends else for opc != 0 */
861 if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
862 generate a matrix line */
863 db = DW_LNS_copy;
864 GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error);
865 WRITE_UNALIGNED(dbg, (void *) data,
866 (const void *) &db,
867 sizeof(db), sizeof(Dwarf_Ubyte));
868 data += sizeof(Dwarf_Ubyte);
869 sum_bytes += sizeof(Dwarf_Ubyte);
870 prevline->dpl_basic_block = false;
871 }
872 curline = curline->dpl_next;
873 }
874
875 /* write total length field */
876 du = sum_bytes - BEGIN_LEN_SIZE;
877 {
878 start_line_sec += extension_size;
879 WRITE_UNALIGNED(dbg, (void *) start_line_sec,
880 (const void *) &du, sizeof(du), uwordb_size);
881 }
882
883 return (int) dbg->de_n_debug_sect;
884 }
885
886 /*---------------------------------------------------------------
887 Generate debug_frame section
888 ---------------------------------------------------------------*/
889 static int
_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,Dwarf_Error * error)890 _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error)
891 {
892 int elfsectno = 0;
893 int i = 0;
894 int firsttime = 1;
895 int pad = 0; /* Pad for padding to align cies and fdes */
896 Dwarf_P_Cie curcie = 0;
897 Dwarf_P_Fde curfde = 0;
898 unsigned char *data = 0;
899 Dwarf_sfixed dsw = 0;
900 Dwarf_Unsigned du = 0;
901 Dwarf_Ubyte db = 0;
902 long *cie_offs = 0; /* Holds byte offsets for links to fde's */
903 unsigned long cie_length = 0;
904 int cie_no = 0;
905 int uwordb_size = dbg->de_offset_size;
906 int extension_size = dbg->de_64bit_extension ? 4 : 0;
907 int upointer_size = dbg->de_pointer_size;
908 Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
909 for relocation info */
910
911 elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
912
913 curcie = dbg->de_frame_cies;
914 cie_length = 0;
915 cur_off = 0;
916 cie_offs = (long *)
917 _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
918 if (cie_offs == NULL) {
919 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
920 }
921 /* Generate cie number as we go along. This writes
922 all CIEs first before any FDEs, which is rather
923 different from the order a compiler might like (which
924 might be each CIE followed by its FDEs then the next CIE, and
925 so on). */
926 cie_no = 1;
927 while (curcie) {
928 char *code_al = 0;
929 int c_bytes = 0;
930 char *data_al = 0;
931 int d_bytes = 0;
932 int res = 0;
933 char buff1[ENCODE_SPACE_NEEDED];
934 char buff2[ENCODE_SPACE_NEEDED];
935 char buff3[ENCODE_SPACE_NEEDED];
936 char *augmentation = 0;
937 char *augmented_al = 0;
938 long augmented_fields_length = 0;
939 int a_bytes = 0;
940
941 res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
942 &c_bytes,
943 buff1, sizeof(buff1));
944 if (res != DW_DLV_OK) {
945 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
946 }
947 /* Before April 1999, the following was using an unsigned
948 encode. That worked ok even though the decoder used the
949 correct signed leb read, but doing the encode correctly
950 (according to the dwarf spec) saves space in the output file
951 and is completely compatible.
952
953 Note the actual stored amount on MIPS was 10 bytes (!) to
954 store the value -4. (hex)fc ffffffff ffffffff 01 The
955 libdwarf consumer consumed all 10 bytes too!
956
957 old version res =
958 _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
959
960 below is corrected signed version. */
961 res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
962 &d_bytes,
963 buff2, sizeof(buff2));
964 if (res != DW_DLV_OK) {
965 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
966 }
967 code_al = buff1;
968 data_al = buff2;
969
970 /* get the correct offset */
971 if (firsttime) {
972 cie_offs[cie_no - 1] = 0;
973 firsttime = 0;
974 } else {
975 cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
976 (long) cie_length + BEGIN_LEN_SIZE;
977 }
978 cie_no++;
979 augmentation = curcie->cie_aug;
980 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
981 augmented_fields_length = 0;
982 res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
983 &a_bytes, buff3,
984 sizeof(buff3));
985 augmented_al = buff3;
986 if (res != DW_DLV_OK) {
987 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
988 }
989 cie_length = uwordb_size + /* cie_id */
990 sizeof(Dwarf_Ubyte) + /* cie version */
991 strlen(curcie->cie_aug) + 1 + /* augmentation */
992 c_bytes + /* code alignment factor */
993 d_bytes + /* data alignment factor */
994 sizeof(Dwarf_Ubyte) + /* return reg address */
995 a_bytes + /* augmentation length */
996 curcie->cie_inst_bytes;
997 } else {
998 cie_length = uwordb_size + /* cie_id */
999 sizeof(Dwarf_Ubyte) + /* cie version */
1000 strlen(curcie->cie_aug) + 1 + /* augmentation */
1001 c_bytes + d_bytes + sizeof(Dwarf_Ubyte) + /* return
1002 reg
1003 address
1004 */
1005 curcie->cie_inst_bytes;
1006 }
1007 pad = (int) PADDING(cie_length, upointer_size);
1008 cie_length += pad;
1009 GET_CHUNK(dbg, elfsectno, data, cie_length +
1010 BEGIN_LEN_SIZE, error);
1011 if (extension_size) {
1012 Dwarf_Unsigned x = DISTINGUISHED_VALUE;
1013
1014 WRITE_UNALIGNED(dbg, (void *) data,
1015 (const void *) &x,
1016 sizeof(x), extension_size);
1017 data += extension_size;
1018
1019 }
1020 du = cie_length;
1021 /* total length of cie */
1022 WRITE_UNALIGNED(dbg, (void *) data,
1023 (const void *) &du, sizeof(du), uwordb_size);
1024 data += uwordb_size;
1025
1026 /* cie-id is a special value. */
1027 du = DW_CIE_ID;
1028 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1029 sizeof(du), uwordb_size);
1030 data += uwordb_size;
1031
1032 db = curcie->cie_version;
1033 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1034 sizeof(db), sizeof(Dwarf_Ubyte));
1035 data += sizeof(Dwarf_Ubyte);
1036 strcpy((char *) data, curcie->cie_aug);
1037 data += strlen(curcie->cie_aug) + 1;
1038 memcpy((void *) data, (const void *) code_al, c_bytes);
1039 data += c_bytes;
1040 memcpy((void *) data, (const void *) data_al, d_bytes);
1041 data += d_bytes;
1042 db = curcie->cie_ret_reg;
1043 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1044 sizeof(db), sizeof(Dwarf_Ubyte));
1045 data += sizeof(Dwarf_Ubyte);
1046
1047 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1048 memcpy((void *) data, (const void *) augmented_al, a_bytes);
1049 data += a_bytes;
1050 }
1051 memcpy((void *) data, (const void *) curcie->cie_inst,
1052 curcie->cie_inst_bytes);
1053 data += curcie->cie_inst_bytes;
1054 for (i = 0; i < pad; i++) {
1055 *data = DW_CFA_nop;
1056 data++;
1057 }
1058 curcie = curcie->cie_next;
1059 }
1060 /* calculate current offset */
1061 cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE;
1062
1063 /* write out fde's */
1064 curfde = dbg->de_frame_fdes;
1065 while (curfde) {
1066 Dwarf_P_Frame_Pgm curinst = 0;
1067 long fde_length = 0;
1068 int pad = 0;
1069 Dwarf_P_Cie cie_ptr = 0;
1070 Dwarf_Word cie_index = 0;
1071 Dwarf_Word index = 0;
1072 int oet_length = 0;
1073 int afl_length = 0;
1074 int res = 0;
1075 int v0_augmentation = 0;
1076 #if 0
1077 unsigned char *fde_start_point = 0;
1078 #endif
1079 char afl_buff[ENCODE_SPACE_NEEDED];
1080
1081 /* Find the CIE associated with this fde. */
1082 cie_ptr = dbg->de_frame_cies;
1083 cie_index = curfde->fde_cie;
1084 index = 1; /* The cie_index of the first cie is 1,
1085 not 0. */
1086 while (cie_ptr && index < cie_index) {
1087 cie_ptr = cie_ptr->cie_next;
1088 index++;
1089 }
1090 if (cie_ptr == NULL) {
1091 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
1092 }
1093
1094 if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
1095 v0_augmentation = 1;
1096 oet_length = sizeof(Dwarf_sfixed);
1097 /* encode the length of augmented fields. */
1098 res = _dwarf_pro_encode_leb128_nm(oet_length,
1099 &afl_length, afl_buff,
1100 sizeof(afl_buff));
1101 if (res != DW_DLV_OK) {
1102 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
1103 }
1104
1105 fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
1106 pointer
1107 */
1108 upointer_size + /* initial loc */
1109 upointer_size + /* address range */
1110 afl_length + /* augmented field length */
1111 oet_length; /* exception_table offset */
1112 } else {
1113 fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie
1114 pointer
1115 */
1116 upointer_size + /* initial loc */
1117 upointer_size; /* address range */
1118 }
1119
1120
1121 if (curfde->fde_die) {
1122 /* IRIX/MIPS extension:
1123 Using fde offset, generate DW_AT_MIPS_fde attribute for the
1124 die corresponding to this fde. */
1125 if(_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,
1126 error) < 0) {
1127 return -1;
1128 }
1129 }
1130
1131 /* store relocation for cie pointer */
1132 res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off +
1133 BEGIN_LEN_SIZE /* r_offset */,
1134 dbg->de_sect_name_idx[DEBUG_FRAME],
1135 dwarf_drt_data_reloc, uwordb_size);
1136 if (res != DW_DLV_OK) {
1137 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1138 }
1139
1140 /* store relocation information for initial location */
1141 res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1142 cur_off + BEGIN_LEN_SIZE +
1143 upointer_size /* r_offset */,
1144 curfde->fde_r_symidx,
1145 dwarf_drt_data_reloc, upointer_size);
1146 if (res != DW_DLV_OK) {
1147 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1148 }
1149 /* Store the relocation information for the
1150 offset_into_exception_info field, if the offset is valid (0
1151 is a valid offset). */
1152 if (v0_augmentation &&
1153 curfde->fde_offset_into_exception_tables >= 0) {
1154
1155 res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
1156 /* r_offset, where in cie this
1157 field starts */
1158 cur_off + BEGIN_LEN_SIZE +
1159 uwordb_size + 2 * upointer_size +
1160 afl_length,
1161 curfde->fde_exception_table_symbol,
1162 dwarf_drt_segment_rel,
1163 sizeof(Dwarf_sfixed));
1164 if (res != DW_DLV_OK) {
1165 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
1166 }
1167 }
1168
1169 /* adjust for padding */
1170 pad = (int) PADDING(fde_length, upointer_size);
1171 fde_length += pad;
1172
1173
1174 /* write out fde */
1175 GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE,
1176 error);
1177 #if 0
1178 fde_start_point = data;
1179 #endif
1180 du = fde_length;
1181 {
1182 if (extension_size) {
1183 Dwarf_Word x = DISTINGUISHED_VALUE;
1184
1185 WRITE_UNALIGNED(dbg, (void *) data,
1186 (const void *) &x,
1187 sizeof(x), extension_size);
1188 data += extension_size;
1189 }
1190 /* length */
1191 WRITE_UNALIGNED(dbg, (void *) data,
1192 (const void *) &du,
1193 sizeof(du), uwordb_size);
1194 data += uwordb_size;
1195
1196 /* offset to cie */
1197 du = cie_offs[curfde->fde_cie - 1];
1198 WRITE_UNALIGNED(dbg, (void *) data,
1199 (const void *) &du,
1200 sizeof(du), uwordb_size);
1201 data += uwordb_size;
1202
1203 du = curfde->fde_initloc;
1204 WRITE_UNALIGNED(dbg, (void *) data,
1205 (const void *) &du,
1206 sizeof(du), upointer_size);
1207 data += upointer_size;
1208
1209 if (dbg->de_reloc_pair &&
1210 curfde->fde_end_symbol != 0 &&
1211 curfde->fde_addr_range == 0) {
1212 /* symbolic reloc, need reloc for length What if we
1213 really know the length? If so, should use the other
1214 part of 'if'. */
1215 Dwarf_Unsigned val;
1216
1217 res = dbg->de_reloc_pair(dbg,
1218 /* DEBUG_ARANGES, */
1219 DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size, /* r_offset
1220 */
1221 curfde->fde_r_symidx,
1222 curfde->fde_end_symbol,
1223 dwarf_drt_first_of_length_pair,
1224 upointer_size);
1225 if (res != DW_DLV_OK) {
1226 {
1227 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1228 return (0);
1229 }
1230 }
1231
1232 /* arrange pre-calc so assem text can do .word end -
1233 begin + val (gets val from stream) */
1234 val = curfde->fde_end_symbol_offset -
1235 curfde->fde_initloc;
1236 WRITE_UNALIGNED(dbg, data,
1237 (const void *) &val,
1238 sizeof(val), upointer_size);
1239 data += upointer_size;
1240 } else {
1241
1242 du = curfde->fde_addr_range;
1243 WRITE_UNALIGNED(dbg, (void *) data,
1244 (const void *) &du,
1245 sizeof(du), upointer_size);
1246 data += upointer_size;
1247 }
1248 }
1249
1250 if (v0_augmentation) {
1251 /* write the encoded augmented field length. */
1252 memcpy((void *) data, (const void *) afl_buff, afl_length);
1253 data += afl_length;
1254 /* write the offset_into_exception_tables field. */
1255 dsw =
1256 (Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
1257 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
1258 sizeof(dsw), sizeof(Dwarf_sfixed));
1259 data += sizeof(Dwarf_sfixed);
1260 }
1261
1262 curinst = curfde->fde_inst;
1263 if(curfde->fde_block) {
1264 unsigned long size = curfde->fde_inst_block_size;
1265 memcpy((void *) data, (const void *) curfde->fde_block, size);
1266 data += size;
1267 } else {
1268 while (curinst) {
1269 db = curinst->dfp_opcode;
1270 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1271 sizeof(db), sizeof(Dwarf_Ubyte));
1272 data += sizeof(Dwarf_Ubyte);
1273 #if 0
1274 if (curinst->dfp_sym_index) {
1275 int res = dbg->de_reloc_name(dbg,
1276 DEBUG_FRAME,
1277 /* r_offset = */
1278 (data - fde_start_point) + cur_off + uwordb_size,
1279 curinst->dfp_sym_index,
1280 dwarf_drt_data_reloc,
1281 upointer_size);
1282 if (res != DW_DLV_OK) {
1283 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1284 return (0);
1285 }
1286 }
1287 #endif
1288 memcpy((void *) data,
1289 (const void *) curinst->dfp_args,
1290 curinst->dfp_nbytes);
1291 data += curinst->dfp_nbytes;
1292 curinst = curinst->dfp_next;
1293 }
1294 }
1295 /* padding */
1296 for (i = 0; i < pad; i++) {
1297 *data = DW_CFA_nop;
1298 data++;
1299 }
1300 cur_off += fde_length + uwordb_size;
1301 curfde = curfde->fde_next;
1302 }
1303
1304
1305 return (int) dbg->de_n_debug_sect;
1306 }
1307
1308 /*
1309 These functions remember all the markers we see along
1310 with the right offset in the .debug_info section so that
1311 we can dump them all back to the user with the section info.
1312 */
1313
1314 static int
marker_init(Dwarf_P_Debug dbg,unsigned count)1315 marker_init(Dwarf_P_Debug dbg,
1316 unsigned count)
1317 {
1318 dbg->de_marker_n_alloc = count;
1319 dbg->de_markers = NULL;
1320 if (count > 0) {
1321 dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) *
1322 dbg->de_marker_n_alloc);
1323 if (dbg->de_markers == NULL) {
1324 dbg->de_marker_n_alloc = 0;
1325 return -1;
1326 }
1327 }
1328 return 0;
1329 }
1330
1331 static int
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)1332 marker_add(Dwarf_P_Debug dbg,
1333 Dwarf_Unsigned offset,
1334 Dwarf_Unsigned marker)
1335 {
1336 if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
1337 unsigned n = dbg->de_marker_n_used++;
1338 dbg->de_markers[n].ma_offset = offset;
1339 dbg->de_markers[n].ma_marker = marker;
1340 return 0;
1341 }
1342
1343 return -1;
1344 }
1345
1346 Dwarf_Signed
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)1347 dwarf_get_die_markers(Dwarf_P_Debug dbg,
1348 Dwarf_P_Marker * marker_list, /* pointer to a pointer */
1349 Dwarf_Unsigned * marker_count,
1350 Dwarf_Error * error)
1351 {
1352 if (marker_list == NULL || marker_count == NULL) {
1353 DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR);
1354 }
1355 if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
1356 DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR);
1357 }
1358
1359 *marker_list = dbg->de_markers;
1360 *marker_count = dbg->de_marker_n_used;
1361 return DW_DLV_OK;
1362 }
1363
1364 /* These functions provide the offsets of DW_FORM_string
1365 attributes in the section section_index. These information
1366 will enable a producer app that is generating assembly
1367 text output to easily emit those attributes in ascii form
1368 without having to decode the byte stream.
1369 */
1370 static int
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)1371 string_attr_init (Dwarf_P_Debug dbg,
1372 Dwarf_Signed section_index,
1373 unsigned count)
1374 {
1375 Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
1376
1377 sect_sa->sect_sa_n_alloc = count;
1378 sect_sa->sect_sa_list = NULL;
1379 if (count > 0) {
1380 sect_sa->sect_sa_section_number = section_index;
1381 sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
1382 sizeof(struct Dwarf_P_String_Attr_s)
1383 * sect_sa->sect_sa_n_alloc);
1384 if (sect_sa->sect_sa_list == NULL) {
1385 sect_sa->sect_sa_n_alloc = 0;
1386 return -1;
1387 }
1388 }
1389 return 0;
1390 }
1391
1392 static int
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)1393 string_attr_add (Dwarf_P_Debug dbg,
1394 Dwarf_Signed section_index,
1395 Dwarf_Unsigned offset,
1396 Dwarf_P_Attribute attr)
1397 {
1398 Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
1399 if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
1400 unsigned n = sect_sa->sect_sa_n_used++;
1401 sect_sa->sect_sa_list[n].sa_offset = offset;
1402 sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
1403 return 0;
1404 }
1405
1406 return -1;
1407 }
1408
1409 int
dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_sa_sections,int * drd_buffer_version,Dwarf_Error * error)1410 dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
1411 Dwarf_Unsigned *
1412 count_of_sa_sections,
1413 int *drd_buffer_version,
1414 Dwarf_Error *error)
1415 {
1416 int i;
1417 unsigned int count = 0;
1418
1419 for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
1420 if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
1421 ++count;
1422 }
1423 }
1424 *count_of_sa_sections = (Dwarf_Unsigned) count;
1425 *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
1426
1427 return DW_DLV_OK;
1428 }
1429
1430 int
dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,Dwarf_Signed * elf_section_index,Dwarf_Unsigned * sect_sa_buffer_count,Dwarf_P_String_Attr * sect_sa_buffer,Dwarf_Error * error)1431 dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
1432 Dwarf_Signed *elf_section_index,
1433 Dwarf_Unsigned *sect_sa_buffer_count,
1434 Dwarf_P_String_Attr *sect_sa_buffer,
1435 Dwarf_Error *error)
1436 {
1437 int i;
1438 int next = dbg->de_sect_sa_next_to_return;
1439
1440 for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
1441 Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
1442 if (sect_sa->sect_sa_n_used > 0) {
1443 dbg->de_sect_sa_next_to_return = i + 1;
1444 *elf_section_index = sect_sa->sect_sa_section_number;
1445 *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
1446 *sect_sa_buffer = sect_sa->sect_sa_list;
1447 return DW_DLV_OK;
1448 }
1449 }
1450 return DW_DLV_NO_ENTRY;
1451 }
1452
1453
1454
1455 /*---------------------------------------------------------------
1456 Generate debug_info and debug_abbrev sections
1457 ---------------------------------------------------------------*/
1458 static int
_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Error * error)1459 _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error)
1460 {
1461 int elfsectno_of_debug_info = 0;
1462 int abbrevsectno = 0;
1463 unsigned char *data = 0;
1464 int cu_header_size = 0;
1465 Dwarf_P_Abbrev curabbrev = 0;
1466 Dwarf_P_Abbrev abbrev_head = 0;
1467 Dwarf_P_Abbrev abbrev_tail = 0;
1468 Dwarf_P_Die curdie = 0;
1469 Dwarf_P_Die first_child = 0;
1470 Dwarf_Word dw = 0;
1471 Dwarf_Unsigned du = 0;
1472 Dwarf_Half dh = 0;
1473 Dwarf_Ubyte db = 0;
1474 Dwarf_Half version = 0; /* Need 2 byte quantity. */
1475 Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
1476 int n_abbrevs = 0;
1477 int res = 0;
1478 unsigned marker_count = 0;
1479 unsigned string_attr_count = 0;
1480 unsigned string_attr_offset = 0;
1481
1482 Dwarf_Small *start_info_sec = 0;
1483
1484 int uwordb_size = dbg->de_offset_size;
1485 int extension_size = dbg->de_64bit_extension ? 4 : 0;
1486
1487 abbrev_head = abbrev_tail = NULL;
1488 elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
1489
1490 /* write cu header */
1491 cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + /* version
1492 stamp
1493 */
1494 uwordb_size + /* offset into abbrev table */
1495 sizeof(Dwarf_Ubyte); /* size of target address */
1496 GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size,
1497 error);
1498 start_info_sec = data;
1499 if (extension_size) {
1500 du = DISTINGUISHED_VALUE;
1501 WRITE_UNALIGNED(dbg, (void *) data,
1502 (const void *) &du, sizeof(du), extension_size);
1503 data += extension_size;
1504 }
1505 du = 0; /* length of debug_info, not counting
1506 this field itself (unknown at this
1507 point). */
1508 WRITE_UNALIGNED(dbg, (void *) data,
1509 (const void *) &du, sizeof(du), uwordb_size);
1510 data += uwordb_size;
1511
1512 version = CURRENT_VERSION_STAMP; /* assume this length will not
1513 change */
1514 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
1515 sizeof(version), sizeof(Dwarf_Half));
1516 data += sizeof(Dwarf_Half);
1517
1518 du = 0; /* offset into abbrev table, not yet
1519 known. */
1520 WRITE_UNALIGNED(dbg, (void *) data,
1521 (const void *) &du, sizeof(du), uwordb_size);
1522 data += uwordb_size;
1523
1524
1525 db = dbg->de_pointer_size;
1526
1527 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1528 sizeof(db), 1);
1529
1530 /* We have filled the chunk we got with GET_CHUNK. At this point we
1531 no longer dare use "data" or "start_info_sec" as a pointer any
1532 longer except to refer to that first small chunk for the cu
1533 header. */
1534
1535 curdie = dbg->de_dies;
1536
1537 /* create AT_macro_info if appropriate */
1538 if (dbg->de_first_macinfo != NULL) {
1539 if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
1540 return -1;
1541 }
1542
1543 /* create AT_stmt_list attribute if necessary */
1544 if (dwarf_need_debug_line_section(dbg) == TRUE)
1545 if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
1546 return -1;
1547
1548 die_off = cu_header_size;
1549
1550 /*
1551 Relocation for abbrev offset in cu header store relocation
1552 record in linked list */
1553 res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE +
1554 sizeof(Dwarf_Half),
1555 /* r_offset */
1556 dbg->de_sect_name_idx[DEBUG_ABBREV],
1557 dwarf_drt_data_reloc, uwordb_size);
1558 if (res != DW_DLV_OK) {
1559 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1560 }
1561
1562 /* pass 0: only top level dies, add at_sibling attribute to those
1563 dies with children */
1564 first_child = curdie->di_child;
1565 while (first_child && first_child->di_right) {
1566 if (first_child->di_child)
1567 dwarf_add_AT_reference(dbg,
1568 first_child,
1569 DW_AT_sibling,
1570 first_child->di_right, error);
1571 first_child = first_child->di_right;
1572 }
1573
1574 /* pass 1: create abbrev info, get die offsets, calc relocations */
1575 marker_count = 0;
1576 string_attr_count = 0;
1577 while (curdie != NULL) {
1578 int nbytes = 0;
1579 Dwarf_P_Attribute curattr;
1580 Dwarf_P_Attribute new_first_attr;
1581 Dwarf_P_Attribute new_last_attr;
1582 char *space = 0;
1583 int res = 0;
1584 char buff1[ENCODE_SPACE_NEEDED];
1585 int i = 0;
1586
1587 curdie->di_offset = die_off;
1588
1589 if (curdie->di_marker != 0)
1590 marker_count++;
1591
1592 curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
1593 if (curabbrev == NULL) {
1594 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1595 }
1596 if (abbrev_head == NULL) {
1597 n_abbrevs = 1;
1598 curabbrev->abb_idx = n_abbrevs;
1599 abbrev_tail = abbrev_head = curabbrev;
1600 } else {
1601 /* check if its a new abbreviation, if yes, add to tail */
1602 if (curabbrev->abb_idx == 0) {
1603 n_abbrevs++;
1604 curabbrev->abb_idx = n_abbrevs;
1605 abbrev_tail->abb_next = curabbrev;
1606 abbrev_tail = curabbrev;
1607 }
1608 }
1609 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
1610 &nbytes,
1611 buff1, sizeof(buff1));
1612 if (res != DW_DLV_OK) {
1613 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1614 }
1615 space = _dwarf_p_get_alloc(dbg, nbytes);
1616 if (space == NULL) {
1617 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1618 }
1619 memcpy(space, buff1, nbytes);
1620 curdie->di_abbrev = space;
1621 curdie->di_abbrev_nbytes = nbytes;
1622 die_off += nbytes;
1623
1624 /* Resorting the attributes!! */
1625 new_first_attr = new_last_attr = NULL;
1626 curattr = curdie->di_attrs;
1627 for (i = 0; i < (int)curabbrev->abb_n_attr; i++) {
1628 Dwarf_P_Attribute ca;
1629 Dwarf_P_Attribute cl;
1630
1631 /* The following should always find an attribute! */
1632 for (ca = cl = curattr;
1633 ca && curabbrev->abb_attrs[i] != ca->ar_attribute;
1634 cl = ca, ca = ca->ar_next)
1635 {
1636 }
1637
1638 if (!ca) {
1639 DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
1640 }
1641
1642 /* Remove the attribute from the old list. */
1643 if (ca == curattr) {
1644 curattr = ca->ar_next;
1645 } else {
1646 cl->ar_next = ca->ar_next;
1647 }
1648
1649 ca->ar_next = NULL;
1650
1651 /* Add the attribute to the new list. */
1652 if (new_first_attr == NULL) {
1653 new_first_attr = new_last_attr = ca;
1654 } else {
1655 new_last_attr->ar_next = ca;
1656 new_last_attr = ca;
1657 }
1658 }
1659
1660 curdie->di_attrs = new_first_attr;
1661
1662 curattr = curdie->di_attrs;
1663
1664 while (curattr) {
1665 if (curattr->ar_rel_type != R_MIPS_NONE) {
1666 switch (curattr->ar_attribute) {
1667 case DW_AT_stmt_list:
1668 curattr->ar_rel_symidx =
1669 dbg->de_sect_name_idx[DEBUG_LINE];
1670 break;
1671 case DW_AT_MIPS_fde:
1672 curattr->ar_rel_symidx =
1673 dbg->de_sect_name_idx[DEBUG_FRAME];
1674 break;
1675 case DW_AT_macro_info:
1676 curattr->ar_rel_symidx =
1677 dbg->de_sect_name_idx[DEBUG_MACINFO];
1678 break;
1679 default:
1680 break;
1681 }
1682 res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset, /* r_offset
1683 */
1684 curattr->ar_rel_symidx,
1685 dwarf_drt_data_reloc,
1686 curattr->ar_reloc_len);
1687
1688 if (res != DW_DLV_OK) {
1689 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1690 }
1691
1692 }
1693 if (curattr->ar_attribute_form == DW_FORM_string) {
1694 string_attr_count++;
1695 }
1696 die_off += curattr->ar_nbytes;
1697 curattr = curattr->ar_next;
1698 }
1699
1700 /* depth first search */
1701 if (curdie->di_child)
1702 curdie = curdie->di_child;
1703 else {
1704 while (curdie != NULL && curdie->di_right == NULL) {
1705 curdie = curdie->di_parent;
1706 die_off++; /* since we are writing a null die at
1707 the end of each sibling chain */
1708 }
1709 if (curdie != NULL)
1710 curdie = curdie->di_right;
1711 }
1712
1713 } /* end while (curdie != NULL) */
1714
1715 res = marker_init(dbg, marker_count);
1716 if (res == -1) {
1717 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1718 }
1719 res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
1720 if (res == -1) {
1721 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1722 }
1723
1724 /* Pass 2: Write out the die information Here 'data' is a
1725 temporary, one block for each GET_CHUNK. 'data' is overused. */
1726 curdie = dbg->de_dies;
1727 while (curdie != NULL) {
1728 Dwarf_P_Attribute curattr;
1729
1730 if (curdie->di_marker != 0) {
1731 res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
1732 if (res == -1) {
1733 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
1734 }
1735 }
1736
1737 /* index to abbreviation table */
1738 GET_CHUNK(dbg, elfsectno_of_debug_info,
1739 data, curdie->di_abbrev_nbytes, error);
1740
1741 memcpy((void *) data,
1742 (const void *) curdie->di_abbrev,
1743 curdie->di_abbrev_nbytes);
1744
1745 /* Attribute values - need to fill in all form attributes */
1746 curattr = curdie->di_attrs;
1747 string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes;
1748
1749 while (curattr) {
1750 GET_CHUNK(dbg, elfsectno_of_debug_info, data,
1751 (unsigned long) curattr->ar_nbytes, error);
1752 switch (curattr->ar_attribute_form) {
1753 case DW_FORM_ref1:
1754 {
1755 if (curattr->ar_ref_die->di_offset >
1756 (unsigned) 0xff) {
1757 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1758 }
1759 db = curattr->ar_ref_die->di_offset;
1760 WRITE_UNALIGNED(dbg, (void *) data,
1761 (const void *) &db,
1762 sizeof(db), sizeof(Dwarf_Ubyte));
1763 break;
1764 }
1765 case DW_FORM_ref2:
1766 {
1767 if (curattr->ar_ref_die->di_offset >
1768 (unsigned) 0xffff) {
1769 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1770 }
1771 dh = curattr->ar_ref_die->di_offset;
1772 WRITE_UNALIGNED(dbg, (void *) data,
1773 (const void *) &dh,
1774 sizeof(dh), sizeof(Dwarf_Half));
1775 break;
1776 }
1777 case DW_FORM_ref_addr:
1778 {
1779 /* curattr->ar_ref_die == NULL!
1780 *
1781 * ref_addr doesn't take a CU-offset.
1782 * This is different than other refs.
1783 * This value will be set by the user of the
1784 * producer library using a relocation.
1785 * No need to set a value here.
1786 */
1787 #if 0
1788 du = curattr->ar_ref_die->di_offset;
1789 {
1790 /* ref to offset of die */
1791 WRITE_UNALIGNED(dbg, (void *) data,
1792 (const void *) &du,
1793 sizeof(du), uwordb_size);
1794 }
1795 #endif
1796 break;
1797
1798 }
1799 case DW_FORM_ref4:
1800 {
1801 if (curattr->ar_ref_die->di_offset >
1802 (unsigned) 0xffffffff) {
1803 DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
1804 }
1805 dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
1806 WRITE_UNALIGNED(dbg, (void *) data,
1807 (const void *) &dw,
1808 sizeof(dw), sizeof(Dwarf_ufixed));
1809 break;
1810 }
1811 case DW_FORM_ref8:
1812 du = curattr->ar_ref_die->di_offset;
1813 WRITE_UNALIGNED(dbg, (void *) data,
1814 (const void *) &du,
1815 sizeof(du), sizeof(Dwarf_Unsigned));
1816 break;
1817 case DW_FORM_ref_udata:
1818 { /* unsigned leb128 offset */
1819
1820 int nbytes;
1821 char buff1[ENCODE_SPACE_NEEDED];
1822
1823 res =
1824 _dwarf_pro_encode_leb128_nm(curattr->
1825 ar_ref_die->
1826 di_offset, &nbytes,
1827 buff1,
1828 sizeof(buff1));
1829 if (res != DW_DLV_OK) {
1830 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1831 }
1832
1833 memcpy(data, buff1, nbytes);
1834 break;
1835 }
1836 default:
1837 memcpy((void *) data,
1838 (const void *) curattr->ar_data,
1839 curattr->ar_nbytes);
1840 break;
1841 }
1842 if (curattr->ar_attribute_form == DW_FORM_string) {
1843 string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
1844 }
1845 string_attr_offset += curattr->ar_nbytes;
1846 curattr = curattr->ar_next;
1847 }
1848
1849 /* depth first search */
1850 if (curdie->di_child)
1851 curdie = curdie->di_child;
1852 else {
1853 while (curdie != NULL && curdie->di_right == NULL) {
1854 GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
1855 *data = '\0';
1856 curdie = curdie->di_parent;
1857 }
1858 if (curdie != NULL)
1859 curdie = curdie->di_right;
1860 }
1861 } /* end while (curdir != NULL) */
1862
1863 /* Write out debug_info size */
1864 /* Dont include length field or extension bytes */
1865 du = die_off - BEGIN_LEN_SIZE;
1866 WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size),
1867 (const void *) &du, sizeof(du), uwordb_size);
1868
1869
1870 data = 0; /* Emphasise not usable now */
1871
1872 /* Write out debug_abbrev section */
1873 abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
1874
1875 curabbrev = abbrev_head;
1876 while (curabbrev) {
1877 char *val;
1878 int nbytes;
1879 int idx;
1880 int res;
1881 char buff1[ENCODE_SPACE_NEEDED];
1882
1883 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes,
1884 buff1, sizeof(buff1));
1885 if (res != DW_DLV_OK) {
1886 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1887 }
1888
1889 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1890 val = buff1;
1891 memcpy((void *) data, (const void *) val, nbytes);
1892 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes,
1893 buff1, sizeof(buff1));
1894 if (res != DW_DLV_OK) {
1895 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1896 }
1897 val = buff1;
1898 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1899 memcpy((void *) data, (const void *) val, nbytes);
1900 db = curabbrev->abb_children;
1901 GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error);
1902 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1903 sizeof(db), sizeof(Dwarf_Ubyte));
1904
1905 /* add attributes and forms */
1906 for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
1907 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx],
1908 &nbytes,
1909 buff1, sizeof(buff1));
1910 if (res != DW_DLV_OK) {
1911 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1912 }
1913 val = buff1;
1914 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1915 memcpy((void *) data, (const void *) val, nbytes);
1916 res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx],
1917 &nbytes,
1918 buff1, sizeof(buff1));
1919 if (res != DW_DLV_OK) {
1920 DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
1921 }
1922 val = buff1;
1923 GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
1924 memcpy((void *) data, (const void *) val, nbytes);
1925 }
1926 GET_CHUNK(dbg, abbrevsectno, data, 2, error); /* two zeros,
1927 for last
1928 entry, see
1929 dwarf2 sec
1930 7.5.3 */
1931 *data = 0;
1932 data++;
1933 *data = 0;
1934
1935 curabbrev = curabbrev->abb_next;
1936 }
1937
1938 GET_CHUNK(dbg, abbrevsectno, data, 1, error); /* one zero,
1939 for end of
1940 cu, see
1941 dwarf2 sec
1942 7.5.3 */
1943 *data = 0;
1944
1945
1946 return (int) dbg->de_n_debug_sect;
1947 }
1948
1949
1950 /*---------------------------------------------------------------------
1951 Get a buffer of section data.
1952 section_idx is the elf-section number that this data applies to.
1953 length shows length of returned data
1954 ----------------------------------------------------------------------*/
1955 /*ARGSUSED*/ /* pretend all args used */
1956 Dwarf_Ptr
dwarf_get_section_bytes(Dwarf_P_Debug dbg,Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Error * error)1957 dwarf_get_section_bytes(Dwarf_P_Debug dbg,
1958 Dwarf_Signed dwarf_section,
1959 Dwarf_Signed * section_idx,
1960 Dwarf_Unsigned * length, Dwarf_Error * error)
1961 {
1962 Dwarf_Ptr buf;
1963
1964 if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
1965 DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
1966 }
1967
1968 if (dbg->de_debug_sects == 0) {
1969 /* no more data !! */
1970 return NULL;
1971 }
1972 if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
1973 /* no data ever entered !! */
1974 return NULL;
1975 }
1976 *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
1977 *length = dbg->de_debug_sects->ds_nbytes;
1978
1979 buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
1980
1981 dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
1982
1983 /* We may want to call the section stuff more than once: see
1984 dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
1985
1986 return buf;
1987 }
1988
1989 /*
1990 No errors possible.
1991 */
1992 void
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)1993 dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
1994 {
1995 dbg->de_debug_sects = dbg->de_first_debug_sect;
1996 /* No need to reset; commented out decrement. dbg->de_n_debug_sect
1997 = ???; */
1998 dbg->de_reloc_next_to_return = 0;
1999 dbg->de_sect_sa_next_to_return = 0;
2000 }
2001
2002 /*
2003 Storage handler. Gets either a new chunk of memory, or
2004 a pointer in existing memory, from the linked list attached
2005 to dbg at de_debug_sects, depending on size of nbytes
2006
2007 Assume dbg not null, checked in top level routine
2008
2009 Returns a pointer to the allocated buffer space for the
2010 lib to fill in, predincrements next-to-use count so the
2011 space requested is already counted 'used'
2012 when this returns (ie, reserved).
2013
2014 */
2015 Dwarf_Small *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)2016 _dwarf_pro_buffer(Dwarf_P_Debug dbg,
2017 int elfsectno, unsigned long nbytes)
2018 {
2019 Dwarf_P_Section_Data cursect;
2020
2021
2022 cursect = dbg->de_current_active_section;
2023 /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
2024 not match any legit section number. test to have just two
2025 clauses (no NULL pointer test) See dwarf_producer_init(). */
2026 if ((cursect->ds_elf_sect_no != elfsectno) ||
2027 ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
2028 ) {
2029
2030 /* Either the elf section has changed or there is not enough
2031 space in the current section.
2032
2033 Create a new Dwarf_P_Section_Data_s for the chunk. and have
2034 space 'on the end' for the buffer itself so we just do one
2035 malloc (not two).
2036
2037 */
2038 unsigned long space = nbytes;
2039
2040 if (nbytes < CHUNK_SIZE)
2041 space = CHUNK_SIZE;
2042
2043 cursect = (Dwarf_P_Section_Data)
2044 _dwarf_p_get_alloc(dbg,
2045 sizeof(struct Dwarf_P_Section_Data_s)
2046 + space);
2047
2048
2049 if (cursect == NULL)
2050 return (NULL);
2051
2052 /* _dwarf_p_get_alloc zeroes the space... */
2053
2054 cursect->ds_data = (char *) cursect +
2055 sizeof(struct Dwarf_P_Section_Data_s);
2056 cursect->ds_orig_alloc = space;
2057 cursect->ds_elf_sect_no = elfsectno;
2058 cursect->ds_nbytes = nbytes; /* reserve this number of bytes
2059 of space for caller to fill
2060 in */
2061
2062 /* Now link on the end of the list, and mark this one as the
2063 current one */
2064
2065 if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
2066 /* the only entry is the special one for 'no entry' so
2067 delete that phony one while adding this initial real
2068 one. */
2069 dbg->de_debug_sects = cursect;
2070 dbg->de_current_active_section = cursect;
2071 dbg->de_first_debug_sect = cursect;
2072 } else {
2073 dbg->de_current_active_section->ds_next = cursect;
2074 dbg->de_current_active_section = cursect;
2075 }
2076 dbg->de_n_debug_sect++;
2077
2078 return ((Dwarf_Small *) cursect->ds_data);
2079 }
2080
2081 /* There is enough space in the current buffer */
2082 {
2083 Dwarf_Small *space_for_caller = (Dwarf_Small *)
2084 (cursect->ds_data + cursect->ds_nbytes);
2085
2086 cursect->ds_nbytes += nbytes;
2087 return space_for_caller;
2088 }
2089 }
2090
2091
2092 /*------------------------------------------------------------
2093 Given address advance and line advance, it gives
2094 either special opcode, or a number < 0
2095 ------------------------------------------------------------*/
2096 static int
_dwarf_pro_get_opc(Dwarf_Unsigned addr_adv,int line_adv)2097 _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv)
2098 {
2099 int opc;
2100
2101 addr_adv = addr_adv / MIN_INST_LENGTH;
2102 if (line_adv == 0 && addr_adv == 0)
2103 return OPC_INCS_ZERO;
2104 if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) {
2105 opc =
2106 (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) +
2107 OPCODE_BASE;
2108 if (opc > 255)
2109 return OPC_OUT_OF_RANGE;
2110 return opc;
2111 } else
2112 return LINE_OUT_OF_RANGE;
2113 }
2114
2115 /*-----------------------------------------------------------------------
2116 Handles abbreviations. It takes a die, searches through
2117 current list of abbreviations for matching one. If it
2118 finds one, it returns a pointer to it, and if it doesnt,
2119 it returns a new one. Upto the user of this function to
2120 link it up to the abbreviation head. If its a new one,
2121 abb_idx has 0.
2122 -----------------------------------------------------------------------*/
2123 static Dwarf_P_Abbrev
_dwarf_pro_getabbrev(Dwarf_P_Die die,Dwarf_P_Abbrev head)2124 _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
2125 {
2126 Dwarf_P_Abbrev curabbrev;
2127 Dwarf_P_Attribute curattr;
2128 int res1;
2129 int nattrs;
2130 int match;
2131 Dwarf_ufixed *forms = 0;
2132 Dwarf_ufixed *attrs = 0;
2133
2134 curabbrev = head;
2135 while (curabbrev) {
2136 if ((die->di_tag == curabbrev->abb_tag) &&
2137 ((die->di_child != NULL &&
2138 curabbrev->abb_children == DW_CHILDREN_yes) ||
2139 (die->di_child == NULL &&
2140 curabbrev->abb_children == DW_CHILDREN_no)) &&
2141 (die->di_n_attr == curabbrev->abb_n_attr)) {
2142
2143 /* There is a chance of a match. */
2144 curattr = die->di_attrs;
2145 match = 1; /* Assume match found. */
2146 while (match && curattr) {
2147 res1 = _dwarf_pro_match_attr(curattr,
2148 curabbrev,
2149 (int) curabbrev->
2150 abb_n_attr);
2151 if (res1 == 0)
2152 match = 0;
2153 curattr = curattr->ar_next;
2154 }
2155 if (match == 1)
2156 return curabbrev;
2157 }
2158 curabbrev = curabbrev->abb_next;
2159 }
2160
2161 /* no match, create new abbreviation */
2162 if (die->di_n_attr != 0) {
2163 forms = (Dwarf_ufixed *)
2164 _dwarf_p_get_alloc(die->di_dbg,
2165 sizeof(Dwarf_ufixed) * die->di_n_attr);
2166 if (forms == NULL)
2167 return NULL;
2168 attrs = (Dwarf_ufixed *)
2169 _dwarf_p_get_alloc(die->di_dbg,
2170 sizeof(Dwarf_ufixed) * die->di_n_attr);
2171 if (attrs == NULL)
2172 return NULL;
2173 }
2174 nattrs = 0;
2175 curattr = die->di_attrs;
2176 while (curattr) {
2177 attrs[nattrs] = curattr->ar_attribute;
2178 forms[nattrs] = curattr->ar_attribute_form;
2179 nattrs++;
2180 curattr = curattr->ar_next;
2181 }
2182
2183 curabbrev = (Dwarf_P_Abbrev)
2184 _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
2185 if (curabbrev == NULL)
2186 return NULL;
2187
2188 if (die->di_child == NULL)
2189 curabbrev->abb_children = DW_CHILDREN_no;
2190 else
2191 curabbrev->abb_children = DW_CHILDREN_yes;
2192 curabbrev->abb_tag = die->di_tag;
2193 curabbrev->abb_attrs = attrs;
2194 curabbrev->abb_forms = forms;
2195 curabbrev->abb_n_attr = die->di_n_attr;
2196 curabbrev->abb_idx = 0;
2197 curabbrev->abb_next = NULL;
2198
2199 return curabbrev;
2200 }
2201
2202 /*------------------------------------------------------------------
2203 Tries to see if given attribute and form combination
2204 exists in the given abbreviation
2205 -------------------------------------------------------------------*/
2206 static int
_dwarf_pro_match_attr(Dwarf_P_Attribute attr,Dwarf_P_Abbrev abbrev,int no_attr)2207 _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
2208 Dwarf_P_Abbrev abbrev, int no_attr)
2209 {
2210 int i;
2211 int found = 0;
2212
2213 for (i = 0; i < no_attr; i++) {
2214 if (attr->ar_attribute == abbrev->abb_attrs[i] &&
2215 attr->ar_attribute_form == abbrev->abb_forms[i]) {
2216 found = 1;
2217 break;
2218 }
2219 }
2220 return found;
2221 }
2222