xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_section.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2   Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2019 David Anderson. All Rights Reserved.
4   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6 
7   This program is free software; you can redistribute it
8   and/or modify it under the terms of version 2.1 of the
9   GNU Lesser General Public License as published by the Free
10   Software Foundation.
11 
12   This program is distributed in the hope that it would be
13   useful, but WITHOUT ANY WARRANTY; without even the implied
14   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15   PURPOSE.
16 
17   Further, this software is distributed without any warranty
18   that it is free of the rightful claim of any third person
19   regarding infringement or the like.  Any license provided
20   herein, whether implied or otherwise, applies only to this
21   software file.  Patent licenses, if any, provided herein
22   do not apply to combinations of this program with other
23   software, or any other product whatsoever.
24 
25   You should have received a copy of the GNU Lesser General
26   Public License along with this program; if not, write the
27   Free Software Foundation, Inc., 51 Franklin Street - Fifth
28   Floor, Boston MA 02110-1301, USA.
29 
30 */
31 
32 #include "config.h"
33 #include "libdwarfdefs.h"
34 #include <stdio.h>
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif /* HAVE_STRING_H */
38 #ifdef   HAVE_ELFACCESS_H
39 #include <elfaccess.h>
40 #endif
41 #ifdef HAVE_STDLIB_H
42 #include <stdlib.h>
43 #endif
44 #ifdef HAVE_MALLOC_H
45 /* Useful include for some Windows compilers. */
46 #include <malloc.h>
47 #endif /* HAVE_MALLOC_H */
48 #ifdef HAVE_STDDEF_H
49 #include <stddef.h>
50 #endif /* HAVE_STDDEF_H */
51 #include "pro_incl.h"
52 #include "dwarf.h"
53 #include "libdwarf.h"
54 #include "pro_opaque.h"
55 #include "pro_error.h"
56 #include "pro_util.h"
57 #include "pro_encode_nm.h"
58 #include "pro_alloc.h"
59 #include "pro_section.h"
60 #include "pro_line.h"
61 #include "pro_frame.h"
62 #include "pro_die.h"
63 #include "pro_macinfo.h"
64 #include "pro_types.h"
65 #include "pro_dnames.h"
66 
67 
68 #ifndef SHN_UNDEF
69 #define SHN_UNDEF 0
70 #endif /* SHN_UNDEF */
71 
72 #ifndef SHF_MIPS_NOSTRIP
73 /* if this is not defined, we probably don't need it: just use 0 */
74 #define SHF_MIPS_NOSTRIP 0
75 #endif
76 #ifndef R_MIPS_NONE
77 #define R_MIPS_NONE 0
78 #endif
79 
80 #ifndef TRUE
81 #define TRUE 1
82 #endif
83 #ifndef FALSE
84 #define FALSE 0
85 #endif
86 
87 #ifdef WORDS_BIGENDIAN
88 #define ASNOUT(t,s,l)                       \
89     do {                                    \
90         unsigned sbyte = 0;                 \
91         const char *p = 0;                  \
92         if (l > sizeof(s)) {                \
93             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
94             return DW_DLV_ERROR;            \
95         }                                   \
96         sbyte = sizeof(s) - l;              \
97         p = (const char *)(&s);             \
98         dbg->de_copy_word(t,(const void *)(p+sbyte),l);\
99     } while (0)
100 #else /* LITTLEENDIAN */
101 #define ASNOUT(t,s,l)                       \
102     do {                                    \
103         const char *p = 0;                  \
104         if (l > sizeof(s)) {                \
105             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
106             return DW_DLV_ERROR;            \
107         }                                   \
108         p = (const char *)(&s);             \
109         dbg->de_copy_word(t,(const void *)p,l); \
110     } while (0)
111 #endif /* ENDIANNESS */
112 
113 
114 #define SIZEOFT32 4
115 
116 struct Dwarf_Sort_Abbrev_s {
117     Dwarf_Unsigned dsa_attr;
118     Dwarf_Unsigned dsa_form;
119     Dwarf_Signed dsa_implicitvalue;
120     Dwarf_P_Attribute dsa_attrp;
121 };
122 
123 
124 /* Must match up with pro_section.h defines of DEBUG_INFO etc
125 and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
126 see pro_incl.h
127 */
128 const char *_dwarf_rel_section_names[] = {
129     REL_SEC_PREFIX ".debug_info",
130     REL_SEC_PREFIX ".debug_line",
131     REL_SEC_PREFIX ".debug_abbrev",     /* Nothing here refers to anything. */
132     REL_SEC_PREFIX ".debug_frame",
133     REL_SEC_PREFIX ".debug_aranges",
134     REL_SEC_PREFIX ".debug_pubnames",
135     REL_SEC_PREFIX ".debug_funcnames",  /* sgi extension */
136     REL_SEC_PREFIX ".debug_typenames",  /* sgi extension */
137     REL_SEC_PREFIX ".debug_varnames",   /* sgi extension */
138     REL_SEC_PREFIX ".debug_weaknames",  /* sgi extension */
139     REL_SEC_PREFIX ".debug_macinfo",
140     REL_SEC_PREFIX ".debug_loc",
141     REL_SEC_PREFIX ".debug_ranges",
142     REL_SEC_PREFIX ".debug_types",      /* new in DWARF4 */
143     REL_SEC_PREFIX ".debug_pubtypes",   /* new in DWARF3 */
144     REL_SEC_PREFIX ".debug_names",      /* DWARF5 aka dnames */
145     REL_SEC_PREFIX ".debug_str",        /* Nothing here refers to anything.*/
146     REL_SEC_PREFIX ".debug_rnglists",   /* DWARF5. */
147     REL_SEC_PREFIX ".debug_line_str",   /* DWARF5. Nothing referselsewhere */
148     REL_SEC_PREFIX ".debug_macro",      /* DWARF5. */
149     REL_SEC_PREFIX ".debug_loclists",   /* DWARF5. */
150     REL_SEC_PREFIX ".debug_rnglists",   /* DWARF5. */
151 };
152 
153 /*  names of sections. Ensure that it matches the defines
154     in pro_section.h, in the same order
155     Must match also _dwarf_rel_section_names above
156 */
157 const char *_dwarf_sectnames[] = {
158     ".debug_info",
159     ".debug_line",
160     ".debug_abbrev",
161     ".debug_frame",
162     ".debug_aranges",
163     ".debug_pubnames",
164     ".debug_funcnames",         /* sgi extension */
165     ".debug_typenames",         /* sgi extension */
166     ".debug_varnames",          /* sgi extension */
167     ".debug_weaknames",         /* sgi extension */
168     ".debug_macinfo",
169     ".debug_loc",
170     ".debug_ranges",
171     ".debug_types",             /* new in DWARF4 */
172     ".debug_pubtypes",          /* new in DWARF3 */
173     ".debug_names",             /* new in DWARF5. aka dnames */
174     ".debug_str",
175     ".debug_line_str",          /* new in DWARF5 */
176     ".debug_macro",             /* new in DWARF5 */
177     ".debug_loclists",          /* new in DWARF5 */
178     ".debug_rnglists",          /* new in DWARF5 */
179 };
180 
181 
182 
183 
184 static const Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */
185     1,                          /* DW_LNS_advance_pc */
186     1,                          /* DW_LNS_advance_line */
187     1,                          /* DW_LNS_set_file */
188     1,                          /* DW_LNS_set_column */
189     0,                          /* DW_LNS_negate_stmt */
190     0,                          /* DW_LNS_set_basic_block */
191     0,                          /* DW_LNS_const_add_pc */
192     1,                          /* DW_LNS_fixed_advance_pc */
193     /*  The following for DWARF3 and DWARF4, though GNU
194         uses these in DWARF2 as well. */
195     0,                          /* DW_LNS_set_prologue_end */
196     0,                          /* DW_LNS_set_epilogue_begin */
197     1,                          /* DW_LNS_set_isa */
198 };
199 
200 /*  struct to hold relocation entries. Its mantained as a linked
201     list of relocation structs, and will then be written at as a
202     whole into the relocation section. Whether its 32 bit or
203     64 bit will be obtained from Dwarf_Debug pointer.
204 */
205 
206 typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
207 struct Dwarf_P_Rel_s {
208     Dwarf_P_Rel dr_next;
209     void *dr_rel_datap;
210 };
211 typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
212 struct Dwarf_P_Rel_Head_s {
213     struct Dwarf_P_Rel_s *drh_head;
214     struct Dwarf_P_Rel_s *drh_tail;
215 };
216 
217 static int
218 _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,
219     Dwarf_Signed *nbufs, Dwarf_Error * error);
220 static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,
221     Dwarf_Signed *nbufs, Dwarf_Error * error);
222 static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,
223     Dwarf_Signed *nbufs, Dwarf_Error * error);
224 static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
225     Dwarf_Signed *nbufs, Dwarf_Error * error);
226 static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
227     Dwarf_Signed *nbufs, Dwarf_Error * error);
228 static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
229     Dwarf_Signed *nbufs, Dwarf_Error * error);
230 
231 #if 0
232 static void
233 dump_bytes(char * msg,Dwarf_Small * start, long len)
234 {
235     Dwarf_Small *end = start + len;
236     Dwarf_Small *cur = start;
237 
238     printf("%s len %ld ",msg,len);
239     for (; cur < end; cur++) {
240         printf("%02x ", *cur);
241     }
242     printf("\n");
243 }
244 #endif
245 
246 #if 0
247 static void
248 print_single_abbrev(Dwarf_P_Abbrev c, unsigned idx)
249 {
250     unsigned j = 0;
251 
252     printf(" %2u idx %2u tag 0x%x attrct %2u\n",idx,
253         (unsigned)c->abb_idx,
254         (unsigned)c->abb_tag,
255         (unsigned)c->abb_n_attr);
256 
257     for ( ; j < (unsigned)c->abb_n_attr; ++j) {
258         printf("  %2u attr 0x%2x  form 0x%2x impl val %" DW_PR_DSd "\n",
259             j,
260             (unsigned)c->abb_attrs[j],
261             (unsigned)c->abb_forms[j]);
262             (unsigned)c->abb_implicits[j]);
263     }
264 }
265 static void
266 print_curabbrev(const char *where,
267     Dwarf_P_Abbrev curabbrev)
268 {
269     Dwarf_P_Abbrev ca = 0;
270     unsigned i = 0;
271     for(ca = curabbrev; ca ; ca = ca->abb_next,++i) {
272         printf("ABBREV %u from %s\n",i,where);
273         print_single_abbrev(ca,i);
274     }
275 }
276 #endif
277 
278 
279 /* These macros used as return value for _dwarf_pro_get_opc. */
280 #define         OPC_INCS_ZERO           -1
281 #define         OPC_OUT_OF_RANGE        -2
282 #define         LINE_OUT_OF_RANGE       -3
283 /*  Given address advance and line advance, it gives
284     either special opcode, or a number < 0
285 
286     FIXME: Check all three negative values.
287     Are any negatives really hard errors?
288 */
289 static int
_dwarf_pro_get_opc(struct Dwarf_P_Line_Inits_s * inits,Dwarf_Unsigned addr_adv,int line_adv)290 _dwarf_pro_get_opc(
291     struct Dwarf_P_Line_Inits_s *inits,
292     Dwarf_Unsigned addr_adv,
293     int line_adv)
294 {
295     int line_base = inits->pi_line_base;
296     int line_range =inits->pi_line_range;
297     Dwarf_Unsigned factored_adv = 0;
298 
299     factored_adv = addr_adv / inits->pi_minimum_instruction_length;
300     if (line_adv == 0 && factored_adv == 0) {
301         return OPC_INCS_ZERO;
302     }
303     if (line_adv >= line_base && line_adv < line_base + line_range) {
304         int opc = 0;
305 
306         opc = (line_adv - line_base) +
307             (factored_adv * line_range) +
308             inits->pi_opcode_base;
309         if (opc > 255) {
310             return OPC_OUT_OF_RANGE;
311         }
312         return opc;
313     }
314     return LINE_OUT_OF_RANGE;
315 }
316 
317 
318 
319 /*  OFFSET_PLUS_EXTENSION_SIZE is the size of the 'length' field in total.
320     Which may be 4,8, or 12 bytes!
321     4 is standard DWARF2.
322     8 is non-standard MIPS-IRIX 64-bit.
323     12 is standard DWARF3 for 64 bit offsets.
324     Used in various routines: local variable names
325     must match the names here.
326 */
327 #define OFFSET_PLUS_EXTENSION_SIZE (offset_size + extension_size)
328 
329 /*  Return TRUE if we need the section, FALSE otherwise
330 
331     If any of the 'line-data-related' calls were made
332     including file or directory entries,
333     produce .debug_line .
334 
335 */
336 static int
dwarf_need_debug_line_section(Dwarf_P_Debug dbg)337 dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
338 {
339     if (dbg->de_output_version > 4) {
340         return FALSE;
341     }
342     if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
343         && dbg->de_inc_dirs == NULL) {
344         return FALSE;
345     }
346     return TRUE;
347 }
348 
349 /*  DWARF5 only. */
350 static int
dwarf_need_debug_names_section(Dwarf_P_Debug dbg)351 dwarf_need_debug_names_section(Dwarf_P_Debug dbg)
352 {
353     if (dbg->de_output_version <  5) {
354         return FALSE;
355     }
356     if (!dbg->de_dnames) {
357         return FALSE;
358     }
359     if (!dbg->de_dnames->dn_create_section) {
360         return FALSE;
361     }
362     return TRUE;
363 }
364 
365 /*  Convert debug information to  a format such that
366     it can be written on disk.
367     Called exactly once per execution.
368     This is the traditional interface. Bad interface design.
369 */
370 Dwarf_Signed
dwarf_transform_to_disk_form(Dwarf_P_Debug dbg,Dwarf_Error * error)371 dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
372 {
373     Dwarf_Signed count = 0;
374     int res = 0;
375 
376     res = dwarf_transform_to_disk_form_a(dbg, &count,error);
377     if (res == DW_DLV_ERROR) {
378         return DW_DLV_NOCOUNT;
379     }
380     return count;
381 }
382 /*  Convert debug information to  a format such that
383     it can be written on disk.
384     Called exactly once per execution.
385     This is the interface design used with the consumer
386     interface, so easier for callers to work with.
387 */
388 int
dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg,Dwarf_Signed * count,Dwarf_Error * error)389 dwarf_transform_to_disk_form_a(Dwarf_P_Debug dbg, Dwarf_Signed *count,
390     Dwarf_Error * error)
391 {
392     /*  Section data in written out in a number of buffers. Each
393         _generate_*() function returns a cumulative count of buffers for
394         all the sections.
395         dwarf_get_section_bytes() returns pointers to these
396         buffers one at a time. */
397     Dwarf_Signed nbufs = 0;
398     int sect = 0;
399     int err = 0;
400     Dwarf_Unsigned du = 0;
401 
402     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
403         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
404     }
405 
406     /* Create dwarf section headers */
407     for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
408         long flags = 0;
409 
410         switch (sect) {
411 
412         case DEBUG_INFO:
413             if (dbg->de_dies == NULL) {
414                 continue;
415             }
416             break;
417 
418         case DEBUG_LINE:
419             if (dwarf_need_debug_line_section(dbg) == FALSE) {
420                 continue;
421             }
422             break;
423 
424         case DEBUG_ABBREV:
425             if (dbg->de_dies == NULL) {
426                 continue;
427             }
428             break;
429 
430         case DEBUG_FRAME:
431             if (dbg->de_frame_cies == NULL) {
432                 continue;
433             }
434             flags = SHF_MIPS_NOSTRIP;
435             break;
436 
437         case DEBUG_ARANGES:
438             if (dbg->de_arange == NULL) {
439                 continue;
440             }
441             break;
442 
443         case DEBUG_PUBNAMES:
444             if (dbg->de_simple_name_headers[dwarf_snk_pubname].
445                 sn_head == NULL) {
446                 continue;
447             }
448             break;
449         case DEBUG_PUBTYPES:
450             if (dbg->de_simple_name_headers[dwarf_snk_pubtype].
451                 sn_head == NULL) {
452                 continue;
453             }
454             break;
455 
456         case DEBUG_STR:
457             if (dbg->de_debug_str->ds_data == NULL) {
458                 continue;
459             }
460             break;
461 
462         case DEBUG_FUNCNAMES:
463             if (dbg->de_simple_name_headers[dwarf_snk_funcname].
464                 sn_head == NULL) {
465                 continue;
466             }
467             break;
468 
469         case DEBUG_TYPENAMES:
470             if (dbg->de_simple_name_headers[dwarf_snk_typename].
471                 sn_head == NULL) {
472                 continue;
473             }
474             break;
475 
476         case DEBUG_VARNAMES:
477             if (dbg->de_simple_name_headers[dwarf_snk_varname].
478                 sn_head == NULL) {
479                 continue;
480             }
481             break;
482 
483         case DEBUG_WEAKNAMES:
484             if (dbg->de_simple_name_headers[dwarf_snk_weakname].
485                 sn_head == NULL) {
486                 continue;
487             }
488             break;
489 
490         case DEBUG_MACINFO:
491             if (dbg->de_first_macinfo == NULL) {
492                 continue;
493             }
494             break;
495         case DEBUG_NAMES: /* DWARF5 */
496             if (dwarf_need_debug_names_section(dbg) == FALSE) {
497                 continue;
498             }
499             break;
500         case DEBUG_LOC:
501             /* Not handled yet. */
502             continue;
503         case DEBUG_RANGES:
504             /* Not handled yet. */
505             continue;
506         case DEBUG_TYPES:
507             /* Not handled yet. */
508             continue;
509         case DEBUG_MACRO:
510             /* Not handled yet. */
511             continue;
512         case DEBUG_LOCLISTS:
513             /* Not handled yet. */
514             continue;
515         case DEBUG_RNGLISTS:
516             /* Not handled yet. */
517             continue;
518         case DEBUG_LINE_STR:
519             if (dwarf_need_debug_line_section(dbg) == FALSE) {
520                 continue;
521             }
522             /* Not handled yet. */
523             continue;
524         default:
525             /* logic error: missing a case */
526             DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_ERROR);
527         }
528         {
529             int new_base_elf_sect = 0;
530 
531             if (dbg->de_callback_func) {
532                 new_base_elf_sect =
533                     dbg->de_callback_func(_dwarf_sectnames[sect],
534                         /* rec size */ 1,
535                         SECTION_TYPE,
536                         flags, SHN_UNDEF, 0, &du,
537                         dbg->de_user_data, &err);
538             }
539             if (new_base_elf_sect == -1) {
540                 DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
541                     DW_DLV_ERROR);
542             }
543             dbg->de_elf_sects[sect] = new_base_elf_sect;
544             dbg->de_sect_name_idx[sect] = du;
545         }
546     }
547 
548     nbufs = 0;
549 
550     /*  Changing the order in which the sections are generated may cause
551         problems because of relocations. */
552 
553     if (dwarf_need_debug_line_section(dbg) == TRUE) {
554         int res = _dwarf_pro_generate_debugline(dbg,&nbufs, error);
555         if (res == DW_DLV_ERROR) {
556             return res;
557         }
558     }
559 
560     if (dbg->de_frame_cies) {
561         int res = _dwarf_pro_generate_debugframe(dbg,&nbufs,error);
562         if (res == DW_DLV_ERROR) {
563             return res;
564         }
565     }
566     if (dbg->de_first_macinfo) {
567         /* For DWARF 2,3,4 only */
568         /* Need new code for DWARF5 macro info. FIXME*/
569         int res  = _dwarf_pro_transform_macro_info_to_disk(dbg,
570             &nbufs,error);
571         if (res == DW_DLV_ERROR) {
572             return res;
573         }
574     }
575 
576     if (dbg->de_dies) {
577         int res= _dwarf_pro_generate_debuginfo(dbg, &nbufs, error);
578         if (res == DW_DLV_ERROR) {
579             return res;
580         }
581     }
582 
583     if (dbg->de_debug_str->ds_data) {
584         int res = _dwarf_pro_generate_debug_str(dbg,&nbufs, error);
585         if (res == DW_DLV_ERROR) {
586             return res;
587         }
588     }
589     if (dbg->de_debug_line_str->ds_data) {
590         int res = _dwarf_pro_generate_debug_line_str(dbg,&nbufs, error);
591         if (res == DW_DLV_ERROR) {
592             return res;
593         }
594     }
595 
596 
597 
598     if (dbg->de_arange) {
599         int res = _dwarf_transform_arange_to_disk(dbg,&nbufs, error);
600         if (res == DW_DLV_ERROR) {
601             return res;
602         }
603     }
604     if (dbg->de_output_version < 5) {
605         if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
606             int res = _dwarf_transform_simplename_to_disk(dbg,
607                 dwarf_snk_pubname,
608                 DEBUG_PUBNAMES,
609                 &nbufs,
610                 error);
611             if (res == DW_DLV_ERROR) {
612                 return res;
613             }
614         }
615         if (dbg->de_simple_name_headers[dwarf_snk_pubtype].sn_head) {
616             int res = _dwarf_transform_simplename_to_disk(dbg,
617                 dwarf_snk_pubtype,
618                 DEBUG_PUBTYPES,
619                 &nbufs,
620                 error);
621             if (res == DW_DLV_ERROR) {
622                 return res;
623             }
624         }
625 
626         if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
627             int res = _dwarf_transform_simplename_to_disk(dbg,
628                 dwarf_snk_funcname,
629                 DEBUG_FUNCNAMES,
630                 &nbufs,
631                 error);
632             if (res == DW_DLV_ERROR) {
633                 return res;
634             }
635         }
636 
637         if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
638             int res = _dwarf_transform_simplename_to_disk(dbg,
639                 dwarf_snk_typename,
640                 DEBUG_TYPENAMES,
641                 &nbufs,
642                 error);
643             if (res == DW_DLV_ERROR) {
644                 return res;
645             }
646         }
647 
648         if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
649             int res = _dwarf_transform_simplename_to_disk(dbg,
650                 dwarf_snk_varname,
651                 DEBUG_VARNAMES,
652                 &nbufs,
653                 error);
654             if (res == DW_DLV_ERROR) {
655                 return res;
656             }
657         }
658 
659         if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
660             int res = _dwarf_transform_simplename_to_disk(dbg,
661                 dwarf_snk_weakname, DEBUG_WEAKNAMES,
662                 &nbufs,
663                 error);
664             if (res == DW_DLV_ERROR) {
665                 return res;
666             }
667         }
668     }
669     if (dwarf_need_debug_names_section(dbg) == TRUE) {
670         int res = _dwarf_pro_generate_debug_names(dbg,&nbufs, error);
671         if (res == DW_DLV_ERROR) {
672             return res;
673         }
674     }
675 #if 0  /* FIXME: TODO new sections */
676     if (dwarf_need_debug_macro_section(dbg) == TRUE) {
677         int res = _dwarf_pro_generate_debug_macro(dbg,&nbufs, error);
678         if (res == DW_DLV_ERROR) {
679             return res;
680         }
681     }
682     if (dwarf_need_debug_loclists_section(dbg) == TRUE) {
683         int res = _dwarf_pro_generate_debug_loclists(dbg,&nbufs, error);
684         if (res == DW_DLV_ERROR) {
685             return res;
686         }
687     }
688     if (dwarf_need_debug_rnglists_section(dbg) == TRUE) {
689         int res = _dwarf_pro_generate_debug_rnglists(dbg,&nbufs, error);
690         if (res == DW_DLV_ERROR) {
691             return res;
692         }
693     }
694 #endif
695 
696     {
697         Dwarf_Signed new_chunks = 0;
698         int res = 0;
699 
700         res = dbg->de_transform_relocs_to_disk(dbg, &new_chunks);
701         if (res != DW_DLV_OK) {
702             DWARF_P_DBG_ERROR(dbg, DW_DLE_RELOCS_ERROR,
703                 DW_DLV_ERROR);
704         }
705         nbufs += new_chunks;
706     }
707     *count = nbufs;
708     return DW_DLV_OK;
709 }
710 
711 static int
write_fixed_size(Dwarf_Unsigned val,Dwarf_P_Debug dbg,int elfsectno,Dwarf_Unsigned size,unsigned * size_out,Dwarf_Error * error)712 write_fixed_size(Dwarf_Unsigned val,
713     Dwarf_P_Debug dbg,
714     int elfsectno,
715     Dwarf_Unsigned size,
716     unsigned * size_out,
717     Dwarf_Error* error)
718 {
719     unsigned char *data = 0;
720     GET_CHUNK_ERR(dbg, elfsectno, data, size, error);
721     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &val,
722         sizeof(val), size);
723     *size_out = size;
724     return DW_DLV_OK;
725 }
726 
727 static int
write_ubyte(unsigned val,Dwarf_P_Debug dbg,int elfsectno,unsigned * len_out,Dwarf_Error * error)728 write_ubyte(unsigned val,
729     Dwarf_P_Debug dbg,
730     int elfsectno,
731     unsigned *len_out,
732     Dwarf_Error* error)
733 {
734     Dwarf_Ubyte db = val;
735     unsigned char *data = 0;
736     unsigned len = sizeof(Dwarf_Ubyte);
737     GET_CHUNK_ERR(dbg, elfsectno, data,
738         len, error);
739     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
740         sizeof(db), len);
741     *len_out = 1;
742     return DW_DLV_OK;;
743 }
744 static int
pretend_write_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,unsigned * uval_len_out,Dwarf_Error * error)745 pretend_write_uval(Dwarf_Unsigned val,
746     Dwarf_P_Debug dbg,
747     unsigned *uval_len_out,
748     Dwarf_Error* error)
749 {
750     char buff1[ENCODE_SPACE_NEEDED];
751     int nbytes = 0;
752     int res = 0;
753 
754     res = _dwarf_pro_encode_leb128_nm(val,
755         &nbytes, buff1,
756         sizeof(buff1));
757     if (res != DW_DLV_OK) {
758         DWARF_P_DBG_ERROR(dbg,DW_DLE_LEB_OUT_ERROR , DW_DLV_ERROR);
759     }
760     *uval_len_out = nbytes;
761     return DW_DLV_OK;
762 }
763 
764 static int
write_sval(Dwarf_Signed val,Dwarf_P_Debug dbg,int elfsectno,unsigned * sval_len_out,Dwarf_Error * error)765 write_sval(Dwarf_Signed val,
766     Dwarf_P_Debug dbg,
767     int elfsectno,
768     unsigned *sval_len_out,
769     Dwarf_Error* error)
770 {
771     char buff1[ENCODE_SPACE_NEEDED];
772     unsigned char *data = 0;
773     int nbytes = 0;
774     int res =  _dwarf_pro_encode_signed_leb128_nm(val,
775         &nbytes, buff1,
776         sizeof(buff1));
777     if (res != DW_DLV_OK) {
778         DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
779     }
780     GET_CHUNK(dbg, elfsectno, data, nbytes, error);
781     memcpy((void *) data, (const void *) buff1, nbytes);
782     *sval_len_out = nbytes;
783     return DW_DLV_OK;
784 }
785 
786 /*  This one does not allocate a chunk, uses
787     an already existing chunk.
788     data points into that existing chunk. */
789 static int
append_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,unsigned char * data,unsigned * uval_len_out,Dwarf_Error * error)790 append_uval(Dwarf_Unsigned val,
791     Dwarf_P_Debug dbg,
792     unsigned char *data,
793     unsigned * uval_len_out,
794     Dwarf_Error* error)
795 {
796     char buff1[ENCODE_SPACE_NEEDED];
797     int nbytes = 0;
798     int res =  _dwarf_pro_encode_leb128_nm(val,
799         &nbytes, buff1,
800         sizeof(buff1));
801     if (res != DW_DLV_OK) {
802         DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
803     }
804     memcpy((void *) data, (const void *) buff1, nbytes);
805     *uval_len_out = nbytes;
806     return DW_DLV_OK;
807 }
808 
809 
810 static int
write_uval(Dwarf_Unsigned val,Dwarf_P_Debug dbg,int elfsectno,unsigned * uval_len_out,Dwarf_Error * error)811 write_uval(Dwarf_Unsigned val,
812     Dwarf_P_Debug dbg,
813     int elfsectno,
814     unsigned * uval_len_out,
815     Dwarf_Error* error)
816 {
817     char buff1[ENCODE_SPACE_NEEDED];
818     unsigned char *data = 0;
819     int nbytes = 0;
820     int res =  _dwarf_pro_encode_leb128_nm(val,
821         &nbytes, buff1,
822         sizeof(buff1));
823     if (res != DW_DLV_OK) {
824         DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
825     }
826     GET_CHUNK_ERR(dbg, elfsectno, data, nbytes, error);
827     memcpy((void *) data, (const void *) buff1, nbytes);
828     *uval_len_out = nbytes;
829     return DW_DLV_OK;
830 }
831 
832 
833 static unsigned
write_opcode_uval(int opcode,Dwarf_P_Debug dbg,int elfsectno,Dwarf_Unsigned val,unsigned * len_out,Dwarf_Error * error)834 write_opcode_uval(int opcode,
835     Dwarf_P_Debug dbg,
836     int elfsectno,
837     Dwarf_Unsigned val,
838     unsigned *len_out,
839     Dwarf_Error* error)
840 {
841     unsigned ublen = 0;
842     int res = 0;
843     unsigned uvlen = 0;
844     res  = write_ubyte(opcode,dbg,elfsectno,&ublen,error);
845     if (res != DW_DLV_OK) {
846         DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
847     }
848     res = write_uval(val,dbg,elfsectno,&uvlen,error);
849     if (res != DW_DLV_OK) {
850         DWARF_P_DBG_ERROR(dbg, DW_DLE_LEB_OUT_ERROR, DW_DLV_ERROR);
851     }
852     *len_out = ublen +uvlen;
853     return DW_DLV_OK;
854 }
855 
856 static int
determine_form_size(Dwarf_P_Debug dbg,unsigned format_count,struct Dwarf_P_Line_format_s * format,unsigned * size_out,Dwarf_Bool write_out,unsigned char * data,Dwarf_Error * error)857 determine_form_size(Dwarf_P_Debug dbg,
858     unsigned format_count,
859     struct Dwarf_P_Line_format_s *format,
860     unsigned *size_out,
861     Dwarf_Bool write_out,
862     unsigned char *data,
863     Dwarf_Error *error)
864 {
865     unsigned calculated_size = 0;
866     unsigned n = 0;
867     int res = 0;
868 
869     /*  entry format itself */
870     calculated_size += sizeof_ubyte(dbg);
871 
872     /*  Space for the format details. */
873     for(n = 0; n < format_count; ++n) {
874         struct Dwarf_P_Line_format_s *lf = format+n;
875         unsigned val_len = 0;
876         unsigned val_len2 = 0;
877 
878         if (write_out) {
879             res = append_uval(lf->def_content_type, dbg,
880                 data,
881                 &val_len,error);
882         } else {
883             res = pretend_write_uval(lf->def_content_type, dbg,
884                 &val_len,error);
885         }
886         data += val_len;
887         if(res != DW_DLV_OK) {
888             return res;
889         }
890         if (write_out) {
891             res = append_uval(lf->def_form_code, dbg,
892                 data,
893                 &val_len2,error);
894         } else {
895             res = pretend_write_uval(lf->def_form_code, dbg,
896                 &val_len2,error);
897         }
898         if(res != DW_DLV_OK) {
899             return res;
900         }
901         data += val_len2;
902         calculated_size += val_len + val_len2;
903     }
904     *size_out = calculated_size;
905     return DW_DLV_OK;
906 }
907 
908 static int
determine_file_content_size(Dwarf_P_Debug dbg,Dwarf_P_F_Entry entry_list,Dwarf_Unsigned format_count,struct Dwarf_P_Line_format_s * format,unsigned * size_out,Dwarf_Bool write_out,unsigned char * data,Dwarf_Error * error)909 determine_file_content_size(Dwarf_P_Debug dbg,
910     Dwarf_P_F_Entry entry_list,
911     Dwarf_Unsigned format_count,
912     struct Dwarf_P_Line_format_s *format,
913     unsigned *size_out,
914     Dwarf_Bool write_out,
915     unsigned char *data,
916     Dwarf_Error *error)
917 {
918     unsigned calculated_size = 0;
919     unsigned count_len   = 0;
920     Dwarf_P_F_Entry  cur = 0;
921     Dwarf_P_F_Entry  nxt = 0;
922     unsigned n           = 0;
923     int res              = 0;
924     Dwarf_Unsigned offset_size = 0;
925 
926     offset_size = dbg->de_dwarf_offset_size;
927     res = pretend_write_uval(format_count,dbg,
928         &count_len,error);
929     if(res != DW_DLV_OK) {
930         return res;
931     }
932     calculated_size += count_len;
933 
934     cur =  entry_list;
935     for(n = 0; cur; n++,cur = nxt) {
936         unsigned f = 0;
937         nxt = cur->dfe_next;
938 
939         for( ; f < format_count; f++) {
940             struct Dwarf_P_Line_format_s *lf = format+f;
941             unsigned ctype = lf->def_content_type;
942             unsigned cform = lf->def_form_code;
943 
944             switch (ctype) {
945             case DW_LNCT_path: {
946                 switch(cform) {
947                 case DW_FORM_string: {
948                     unsigned slen = strlen(cur->dfe_name) +1;
949                     calculated_size += slen;
950                     if (write_out) {
951                         strcpy((char *)data, cur->dfe_name);
952                         data += slen;
953                     }
954                     }
955                     break;
956                 case DW_FORM_strp: {
957                     unsigned slen = strlen(cur->dfe_name) +1;
958                     if (write_out) {
959                         Dwarf_Unsigned stroffset = 0;
960                         res = _dwarf_insert_or_find_in_debug_str(
961                             dbg,
962                             cur->dfe_name,
963                             _dwarf_hash_debug_str,
964                             slen,
965                             &stroffset,error);
966                         if (res != DW_DLV_OK) {
967                             return res;
968                         }
969                         WRITE_UNALIGNED(dbg, (void *) data,
970                             (const void *) &stroffset,
971                             sizeof(stroffset), offset_size);
972                         data += offset_size;
973                     }
974                     calculated_size += offset_size;
975                     }
976                     break;
977                 case DW_FORM_line_strp: {
978                     unsigned slen = strlen(cur->dfe_name) +1;
979                     if (write_out) {
980                         Dwarf_Unsigned stroffset = 0;
981                         res = _dwarf_insert_or_find_in_debug_str(
982                             dbg,
983                             cur->dfe_name,
984                             _dwarf_hash_debug_line_str,
985                             slen,
986                             &stroffset,error);
987                         if (res != DW_DLV_OK) {
988                             return res;
989                         }
990                         WRITE_UNALIGNED(dbg, (void *) data,
991                             (const void *) &stroffset,
992                             sizeof(stroffset), offset_size);
993                         data += offset_size;
994                     }
995                     calculated_size += offset_size;
996                     }
997                     break;
998                 case DW_FORM_strp_sup:
999                 /* Following in dwo only. */
1000                 case DW_FORM_strx:
1001                 case DW_FORM_strx1:
1002                 case DW_FORM_strx2:
1003                 case DW_FORM_strx3:
1004                 case DW_FORM_strx4:
1005                 default:
1006                     DWARF_P_DBG_ERROR(dbg,
1007                         DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1008                     break;
1009                 }
1010                 }
1011                 break;
1012             case DW_LNCT_directory_index: {
1013                 switch(cform) {
1014                 case DW_FORM_data1:
1015                     calculated_size += 1;
1016                     if (write_out) {
1017                         unsigned char ub = cur->dfe_index;
1018                         *data = ub;
1019                         data += 1;
1020                     }
1021                     break;
1022                 case DW_FORM_data2:
1023                     calculated_size += DWARF_HALF_SIZE;
1024                     if (write_out) {
1025                         Dwarf_Half uh = cur->dfe_index;
1026                         memcpy(data,&uh,DWARF_HALF_SIZE);
1027                         data += DWARF_HALF_SIZE;
1028                     }
1029                     break;
1030                 case DW_FORM_udata: {
1031                     unsigned val_len = 0;
1032                     if (write_out) {
1033                         res = append_uval(cur->dfe_index,
1034                             dbg,
1035                             data,
1036                             &val_len,error);
1037                         data += val_len;
1038                     } else {
1039                         res = pretend_write_uval(cur->dfe_index,
1040                             dbg, &val_len,error);
1041                     }
1042                     if (res != DW_DLV_OK) {
1043                         return res;
1044                     }
1045                     calculated_size += val_len;
1046                     }
1047                     break;
1048                 default:
1049                     DWARF_P_DBG_ERROR(dbg,
1050                         DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1051                 }
1052                 }
1053                 break;
1054             case DW_LNCT_timestamp: {
1055                 switch(cform) {
1056                 case DW_FORM_udata: {
1057                     unsigned val_len = 0;
1058                     if (write_out) {
1059                         res = append_uval(cur->dfe_timestamp,
1060                             dbg,
1061                             data,
1062                             &val_len,error);
1063                         data += val_len;
1064                     } else {
1065                         res = pretend_write_uval(cur->dfe_timestamp,
1066                             dbg, &val_len,error);
1067                     }
1068                     if (res != DW_DLV_OK) {
1069                         return res;
1070                     }
1071                     calculated_size += val_len;
1072                     }
1073                     break;
1074                 case DW_FORM_data4: {
1075                     calculated_size += DWARF_32BIT_SIZE;
1076                     if (write_out) {
1077                         ASNOUT(data,cur->dfe_timestamp,
1078                             DWARF_32BIT_SIZE);
1079                         data += DWARF_32BIT_SIZE;
1080                     }
1081                     }
1082                     break;
1083                 case DW_FORM_data8:
1084                     /*  As of 2017 there is no 8 byte timestamp
1085                         defined, though it does have to happen.
1086                         before 2038. */
1087                     calculated_size += DWARF_64BIT_SIZE;
1088                     if (write_out) {
1089                         Dwarf_Unsigned u8 = cur->dfe_index;
1090                         WRITE_UNALIGNED(dbg, (void *) data,
1091                             (const void *) &u8,
1092                             sizeof(u8), DWARF_64BIT_SIZE);
1093                         data += DWARF_64BIT_SIZE;
1094                     }
1095                     break;
1096                 case DW_FORM_block:
1097                 default:
1098                     DWARF_P_DBG_ERROR(dbg,
1099                         DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1100                 }
1101                 }
1102                 break;
1103             case DW_LNCT_size: {
1104                 switch(cform) {
1105                 case DW_FORM_data1:
1106                     calculated_size += 1;
1107                     if (write_out) {
1108                         unsigned char ub = cur->dfe_index;
1109                         *data = ub;
1110                         data += 1;
1111                     }
1112                     break;
1113                 case DW_FORM_data2:
1114                     calculated_size += DWARF_HALF_SIZE;
1115                     if (write_out) {
1116                         Dwarf_Half uh = cur->dfe_index;
1117                         memcpy(data,&uh,DWARF_HALF_SIZE);
1118 
1119                     }
1120                     break;
1121                 case DW_FORM_data4:
1122                     calculated_size += DWARF_32BIT_SIZE;
1123                     if (write_out) {
1124                         ASNOUT(data,cur->dfe_index,
1125                             DWARF_32BIT_SIZE);
1126                         data += DWARF_32BIT_SIZE;
1127                     }
1128                     break;
1129                 case DW_FORM_data8:
1130                     calculated_size += DWARF_64BIT_SIZE;
1131                     if (write_out) {
1132                         Dwarf_Unsigned u8 = cur->dfe_index;
1133                         WRITE_UNALIGNED(dbg, (void *) data,
1134                             (const void *) &u8,
1135                             sizeof(u8), DWARF_64BIT_SIZE);
1136                         data += DWARF_64BIT_SIZE;
1137                     }
1138                     break;
1139                 case DW_FORM_udata: {
1140                     unsigned val_len = 0;
1141                     if (write_out) {
1142                         res = append_uval(cur->dfe_size,
1143                             dbg,
1144                             data,
1145                             &val_len,error);
1146                         data += val_len;
1147                     } else {
1148                         res = pretend_write_uval(cur->dfe_size,
1149                             dbg, &val_len,error);
1150                     }
1151                     if (res != DW_DLV_OK) {
1152                         return res;
1153                     }
1154                     calculated_size += val_len;
1155                     }
1156                     break;
1157                 default:
1158                     DWARF_P_DBG_ERROR(dbg,
1159                         DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1160                 }
1161                 }
1162                 break;
1163             case DW_LNCT_MD5: {
1164                 switch(cform) {
1165                 case DW_FORM_data16:
1166                     if (write_out) {
1167                         memcpy(data,cur->dfe_md5,sizeof(cur->dfe_md5));
1168                         data += 16;
1169                     }
1170                     calculated_size += 16;
1171                     break;
1172                 default:
1173                     DWARF_P_DBG_ERROR(dbg,
1174                         DW_DLE_LNCT_FORM_CODE_NOT_HANDLED, DW_DLV_ERROR);
1175                 }
1176                 }
1177                 break;
1178             default:
1179                 DWARF_P_DBG_ERROR(dbg, DW_DLE_LNCT_CODE_UNKNOWN, DW_DLV_ERROR);
1180             }
1181         }
1182     }
1183     *size_out = calculated_size;
1184     return DW_DLV_OK;
1185 }
1186 
1187 static int
calculate_size_of_line_header5(Dwarf_P_Debug dbg,struct Dwarf_P_Line_Inits_s * inits,unsigned * prolog_size_out,Dwarf_Error * error)1188 calculate_size_of_line_header5(Dwarf_P_Debug dbg,
1189     struct Dwarf_P_Line_Inits_s *inits,
1190     unsigned *prolog_size_out,
1191     Dwarf_Error *error)
1192 {
1193     unsigned prolog_size = 0;
1194     int offset_size = dbg->de_dwarf_offset_size;
1195     int extension_size = dbg->de_64bit_extension ? 4 : 0;
1196     int res = 0;
1197 
1198     prolog_size += OFFSET_PLUS_EXTENSION_SIZE +
1199         sizeof_uhalf(dbg) + /* version # */
1200         sizeof_ubyte(dbg) +     /* address_size */
1201         sizeof_ubyte(dbg) +     /* segment_selector_size */
1202         offset_size       +     /* header length */
1203         sizeof_ubyte(dbg) +     /* min_instr length */
1204         sizeof_ubyte(dbg) +     /* maximum_operations_per_instruction */
1205         sizeof_ubyte(dbg) +     /* default is_stmt */
1206         sizeof_ubyte(dbg) +     /* linebase */
1207         sizeof_ubyte(dbg) +     /* linerange */
1208         sizeof_ubyte(dbg);      /* opcode base */
1209         /* For maximum_operations_per_instruction. */
1210         prolog_size += sizeof_ubyte(dbg);
1211 
1212     /* standard_opcode_lengths table len */
1213     prolog_size += inits->pi_opcode_base-1;
1214 
1215     {
1216         unsigned fsize = 0;
1217         res = determine_form_size(dbg,
1218             inits->pi_directory_entry_format_count,
1219             inits->pi_incformats,
1220             &fsize,FALSE,0,error);
1221         if (res != DW_DLV_OK) {
1222             return res;
1223         }
1224         prolog_size += fsize;
1225     }
1226     {
1227         unsigned dir_count_len = 0;
1228         res = determine_file_content_size(dbg,
1229             dbg->de_inc_dirs,
1230             dbg->de_line_inits.pi_directory_entry_format_count,
1231             dbg->de_line_inits.pi_incformats,
1232             &dir_count_len,
1233             FALSE,0,
1234             error);
1235         if (res != DW_DLV_OK) {
1236             return res;
1237         }
1238         prolog_size += dir_count_len;
1239     }
1240     {
1241         unsigned fsize = 0;
1242         res = determine_form_size(dbg,
1243             inits->pi_file_entry_format_count,
1244             inits->pi_fileformats,
1245             &fsize,
1246             FALSE,0,
1247             error);
1248         if (res != DW_DLV_OK) {
1249             return res;
1250         }
1251         prolog_size += fsize;
1252     }
1253     {
1254         unsigned file_count_len = 0;
1255         res = determine_file_content_size(dbg,
1256             dbg->de_file_entries,
1257             dbg->de_line_inits.pi_file_entry_format_count,
1258             dbg->de_line_inits.pi_fileformats,
1259             &file_count_len,
1260             FALSE,0,
1261             error);
1262         if (res != DW_DLV_OK) {
1263             return res;
1264         }
1265         prolog_size += file_count_len;
1266     }
1267     *prolog_size_out = prolog_size;
1268     return DW_DLV_OK;
1269 }
1270 
1271 /* For DWARF 2,3,4 */
1272 static int
calculate_size_of_line_header4(Dwarf_P_Debug dbg,struct Dwarf_P_Line_Inits_s * inits,unsigned * prolog_size_out,UNUSEDARG Dwarf_Error * error)1273 calculate_size_of_line_header4(Dwarf_P_Debug dbg,
1274     struct Dwarf_P_Line_Inits_s *inits,
1275     unsigned *prolog_size_out,
1276     UNUSEDARG Dwarf_Error *error)
1277 {
1278     Dwarf_P_F_Entry curdir = 0;
1279     Dwarf_P_F_Entry curentry = 0;
1280     unsigned prolog_size = 0;
1281     int offset_size = dbg->de_dwarf_offset_size;
1282     int extension_size = dbg->de_64bit_extension ? 4 : 0;
1283 
1284     prolog_size += OFFSET_PLUS_EXTENSION_SIZE +
1285         sizeof_uhalf(dbg) +  /* version # */
1286         offset_size       +  /* header length */
1287         sizeof_ubyte(dbg) +  /* min_instr length */
1288         sizeof_ubyte(dbg) +  /* default is_stmt */
1289         sizeof_ubyte(dbg) +  /* linebase */
1290         sizeof_ubyte(dbg) +  /* linerange */
1291         sizeof_ubyte(dbg);   /* opcode base */
1292     if (inits->pi_linetable_version == DW_LINE_VERSION4) {
1293         /* For maximum_operations_per_instruction. */
1294         prolog_size += sizeof_ubyte(dbg);
1295     }
1296     /* standard_opcode_lengths table len */
1297     prolog_size += inits->pi_opcode_base-1;
1298 
1299     /* include directories */
1300     curdir = dbg->de_inc_dirs;
1301     while (curdir) {
1302         prolog_size += strlen(curdir->dfe_name) + 1;
1303         curdir = curdir->dfe_next;
1304     }
1305     prolog_size++; /* last null following last directory
1306         entry. */
1307 
1308     /* file entries */
1309     curentry = dbg->de_file_entries;
1310     while (curentry) {
1311         prolog_size +=
1312             strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
1313         curentry = curentry->dfe_next;
1314     }
1315     prolog_size++; /* last null byte */
1316     *prolog_size_out = prolog_size;
1317     return DW_DLV_OK;
1318 }
1319 
1320 
1321 /* Generate debug_line section
1322    Dwarf2, dwarf3 headers are the same (DW3 acknowledges 64bit).
1323    DWARF4 adds the maximum_operations_per_instruction field.
1324    DWARF5 adds address size and address selector size
1325    and replaces the entire directories/files list with
1326    very different stuff.
1327 */
1328 static int
_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)1329 _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
1330     Dwarf_Signed * nbufs,
1331     Dwarf_Error * error)
1332 {
1333     Dwarf_P_F_Entry curdir = 0;
1334     Dwarf_P_F_Entry curentry = 0;
1335     Dwarf_P_Line curline = 0;
1336     Dwarf_P_Line prevline = 0;
1337     struct Dwarf_P_Line_Inits_s *inits = 0;
1338 
1339     /* all data named cur* are used to loop thru linked lists */
1340 
1341     int sum_bytes = 0;
1342     unsigned prolog_size = 0;
1343     unsigned char *data = 0;    /* holds disk form data */
1344     int elfsectno = 0;
1345     unsigned char *start_line_sec = 0;  /* pointer to the buffer at
1346         section start */
1347     /* temps for memcpy */
1348     Dwarf_Unsigned du = 0;
1349     Dwarf_Ubyte db = 0;
1350     Dwarf_Half dh = 0;
1351     int res = 0;
1352     Dwarf_Half version = dbg->de_output_version;
1353     int offset_size = dbg->de_dwarf_offset_size;
1354     Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0;
1355     Dwarf_Ubyte address_size = dbg->de_pointer_size;
1356 
1357     sum_bytes = 0;
1358 
1359     elfsectno = dbg->de_elf_sects[DEBUG_LINE];
1360 
1361     inits = &dbg->de_line_inits;
1362     if (version < 5) {
1363         res  = calculate_size_of_line_header4(dbg,inits,&prolog_size,
1364             error);
1365     } else if (version == 5) {
1366         res  = calculate_size_of_line_header5(dbg,inits,&prolog_size,
1367             error);
1368     } else {
1369         _dwarf_p_error(dbg, error,DW_DLE_VERSION_STAMP_ERROR );
1370         return DW_DLV_ERROR;
1371     }
1372     if (res != DW_DLV_OK) {
1373         return res;
1374     }
1375     /* Allocate a chunk, put address in 'data' */
1376     GET_CHUNK_ERR(dbg, elfsectno, data, prolog_size, error);
1377 
1378     start_line_sec = data;
1379 
1380     /* Copy the prologue data into 'data' */
1381     /* total_length */
1382     du = 0;
1383     if (extension_size) {
1384         DISTINGUISHED_VALUE_ARRAY(v4);
1385 
1386         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &v4[0],
1387         SIZEOFT32, extension_size);
1388         data += extension_size;
1389     }
1390 
1391     /*  We will adjust this later, we do not know the full length
1392         of the line_section content for this cu  yet. */
1393     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1394         sizeof(du), offset_size);
1395     data += offset_size;
1396 
1397     dh =  inits->pi_linetable_version;
1398     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
1399         sizeof(dh), DWARF_HALF_SIZE);
1400     data +=  DWARF_HALF_SIZE;
1401     if (version == 5 ) {
1402         /* address size, seg sel size now */
1403         db = inits->pi_address_size;
1404         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1405             sizeof(db), sizeof(db));
1406         data += sizeof(db);
1407         db = inits->pi_segment_size; /* segment selector size */
1408         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1409             sizeof(db), sizeof(db));
1410         data += sizeof(db);
1411     }
1412 
1413     {
1414         /*  header length (called prolog length in DWARF2)
1415             This we do know, we calculated the prolog length
1416             already and it is prolog_size so just
1417             */
1418         Dwarf_Unsigned sofar = data  - start_line_sec;
1419 
1420         du = prolog_size - sofar - offset_size;
1421         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
1422             sizeof(du), offset_size);
1423         data += offset_size;
1424     }
1425     db =  inits->pi_minimum_instruction_length;
1426     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1427         sizeof(db), sizeof(Dwarf_Ubyte));
1428     data += sizeof(Dwarf_Ubyte);
1429 
1430     if (inits->pi_linetable_version == 4 ||
1431         inits->pi_linetable_version == 5) {
1432         db =  inits->pi_maximum_operations_per_instruction;
1433         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1434             sizeof(db), sizeof(Dwarf_Ubyte));
1435         data += sizeof(Dwarf_Ubyte);
1436     }
1437 
1438     db =  inits->pi_default_is_stmt;
1439     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1440         sizeof(db), sizeof(Dwarf_Ubyte));
1441     data += sizeof(Dwarf_Ubyte);
1442     db =  inits->pi_line_base;
1443     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1444         sizeof(db), sizeof(Dwarf_Ubyte));
1445     data += sizeof(Dwarf_Ubyte);
1446     db =  inits->pi_line_range;
1447     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1448         sizeof(db), sizeof(Dwarf_Ubyte));
1449     data += sizeof(Dwarf_Ubyte);
1450     db =  inits->pi_opcode_base;
1451     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
1452         sizeof(db), sizeof(Dwarf_Ubyte));
1453     data += sizeof(Dwarf_Ubyte);
1454     WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
1455         inits->pi_opcode_base-1,
1456         inits->pi_opcode_base-1);
1457     data += inits->pi_opcode_base-1;
1458 
1459     if (version < 5) {
1460         /* copy over include directories */
1461         curdir = dbg->de_inc_dirs;
1462         while (curdir) {
1463             strcpy((char *) data, curdir->dfe_name);
1464             data += strlen(curdir->dfe_name) + 1;
1465             curdir = curdir->dfe_next;
1466         }
1467         *data = '\0';               /* last null */
1468         data++;
1469 
1470         /* copy file entries */
1471         curentry = dbg->de_file_entries;
1472         while (curentry) {
1473             strcpy((char *) data, curentry->dfe_name);
1474             data += strlen(curentry->dfe_name) + 1;
1475             /* copies of leb numbers, no endian issues */
1476             memcpy((void *) data,
1477                 (const void *) curentry->dfe_args, curentry->dfe_nbytes);
1478             data += curentry->dfe_nbytes;
1479             curentry = curentry->dfe_next;
1480         }
1481         *data = '\0';
1482         data++;
1483     } else if (version == 5) {
1484         {
1485             unsigned fsize = 0;
1486             res = determine_form_size(dbg,
1487                 inits->pi_directory_entry_format_count,
1488                 inits->pi_incformats,
1489                 &fsize,
1490                 TRUE,data,
1491                 error);
1492             if (res != DW_DLV_OK) {
1493                 return res;
1494             }
1495             data += fsize;
1496         }
1497         {
1498             unsigned dir_count_len = 0;
1499             res = determine_file_content_size(dbg,
1500                 dbg->de_inc_dirs,
1501                 inits->pi_directory_entry_format_count,
1502                 inits->pi_incformats,
1503                 &dir_count_len,
1504                 TRUE,data,
1505                 error);
1506             if (res != DW_DLV_OK) {
1507                 return res;
1508             }
1509             data += dir_count_len;
1510         }
1511         {
1512             unsigned fsize = 0;
1513             res = determine_form_size(dbg,
1514                 inits->pi_file_entry_format_count,
1515                 inits->pi_fileformats,
1516                 &fsize,
1517                 TRUE,data,
1518                 error);
1519             if (res != DW_DLV_OK) {
1520                 return res;
1521             }
1522             data += fsize;
1523         }
1524         {
1525             unsigned file_count_len = 0;
1526             res = determine_file_content_size(dbg,
1527                 dbg->de_file_entries,
1528                 dbg->de_line_inits.pi_file_entry_format_count,
1529                 dbg->de_line_inits.pi_fileformats,
1530                 &file_count_len,
1531                 TRUE,data,
1532                 error);
1533             if (res != DW_DLV_OK) {
1534                 return res;
1535             }
1536             data += file_count_len;
1537         }
1538     }
1539 
1540     {
1541         Dwarf_Unsigned sofar = data - start_line_sec;
1542         if (sofar != prolog_size) {
1543             /* We miscalculated something. */
1544             _dwarf_p_error(dbg, error,
1545                 DW_DLE_LINE_HEADER_LENGTH_BOTCH);
1546             return DW_DLV_ERROR;
1547         }
1548         sum_bytes += prolog_size;
1549     }
1550 
1551     curline = dbg->de_lines;
1552     prevline = (Dwarf_P_Line)
1553         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
1554     if (prevline == NULL) {
1555         DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_ERROR);
1556     }
1557     _dwarf_pro_reg_init(dbg,prevline);
1558     /* generate opcodes for line numbers */
1559     while (curline) {
1560         int opc = 0;
1561         int no_lns_copy = 0; /* if lns copy opcode does not need to be
1562             generated, if special opcode or end
1563             sequence */
1564         Dwarf_Unsigned addr_adv = 0;
1565         int line_adv = 0;           /* supposed to be a reasonably small
1566             number, so the size should not be a
1567             problem. ? */
1568 
1569         no_lns_copy = 0;
1570         if (curline->dpl_opc != 0) {
1571             int inst_bytes = 0;     /* no of bytes in extended opcode */
1572             unsigned writelen = 0;
1573 
1574             switch (curline->dpl_opc) {
1575             case DW_LNE_end_sequence:
1576                 /* Advance pc to end of text section. */
1577                 addr_adv = curline->dpl_address - prevline->dpl_address;
1578                 if (addr_adv > 0) {
1579                     res = write_opcode_uval(DW_LNS_advance_pc,dbg,
1580                         elfsectno,
1581                         addr_adv/inits->pi_minimum_instruction_length,
1582                         &writelen,
1583                         error);
1584                     if (res != DW_DLV_OK) {
1585                         return res;
1586                     }
1587                     sum_bytes += writelen;
1588                     prevline->dpl_address = curline->dpl_address;
1589                 }
1590 
1591                 /* first null byte */
1592                 db = 0;
1593                 res = write_ubyte(db,dbg,elfsectno,
1594                     &writelen,error);
1595                 if (res != DW_DLV_OK) {
1596                     return res;
1597                 }
1598                 sum_bytes += writelen;
1599 
1600                 /* write length of extended opcode */
1601                 inst_bytes = sizeof(Dwarf_Ubyte);
1602                 res = write_uval(inst_bytes,dbg,elfsectno,
1603                     &writelen,error);
1604                 if (res != DW_DLV_OK) {
1605                     return res;
1606                 }
1607                 sum_bytes += writelen;
1608 
1609                 /* write extended opcode */
1610                 res = write_ubyte(DW_LNE_end_sequence,dbg,elfsectno,
1611                     &writelen,error);
1612                 if (res != DW_DLV_OK) {
1613                     return res;
1614                 }
1615                 sum_bytes += writelen;
1616 
1617                 /* reset value to original values */
1618                 _dwarf_pro_reg_init(dbg,prevline);
1619                 no_lns_copy = 1;
1620                 /*  this is set only for end_sequence, so that a
1621                     dw_lns_copy is not generated */
1622                 break;
1623 
1624             case DW_LNE_set_address:
1625 
1626                 /* first null byte */
1627                 db = 0;
1628                 res = write_ubyte(db,dbg,elfsectno,
1629                     &writelen,error);
1630                 if (res != DW_DLV_OK) {
1631                     return res;
1632                 }
1633                 sum_bytes += writelen;
1634 
1635                 /* write length of extended opcode */
1636                 inst_bytes = sizeof(Dwarf_Ubyte) + address_size;
1637                 res = write_uval(inst_bytes,dbg,elfsectno,
1638                     &writelen,error);
1639                 if (res != DW_DLV_OK) {
1640                     return res;
1641                 }
1642                 sum_bytes += writelen;
1643 
1644                 /* write extended opcode */
1645                 res = write_ubyte(DW_LNE_set_address,dbg,elfsectno,
1646                     &writelen,error);
1647                 if (res != DW_DLV_OK) {
1648                     return res;
1649                 }
1650                 sum_bytes += writelen;
1651 
1652                 /* reloc for address */
1653                 res = dbg->de_relocate_by_name_symbol(dbg,
1654                     DEBUG_LINE,
1655                     sum_bytes,  /* r_offset  */
1656                     curline->dpl_r_symidx,
1657                     dwarf_drt_data_reloc,
1658                     offset_size);
1659                 if (res != DW_DLV_OK) {
1660                     DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, DW_DLV_ERROR);
1661                 }
1662 
1663                 /* write offset (address) */
1664                 du = curline->dpl_address;
1665                 res = write_fixed_size(du,dbg,elfsectno,
1666                     address_size,&writelen,error);
1667                 if (res != DW_DLV_OK) {
1668                     return res;
1669                 }
1670                 sum_bytes += writelen;
1671                 prevline->dpl_address = curline->dpl_address;
1672                 no_lns_copy = 1;
1673                 break;
1674             case DW_LNE_define_file:
1675                 /*  Not supported, all add-file entries
1676                     are added via dbg  -> de_file_entries,
1677                     which adds to the line table header.  */
1678                 no_lns_copy = 1;
1679                 break;
1680             case DW_LNE_set_discriminator: {/* DWARF4 */
1681                 unsigned val_len = 0;
1682                 /* first null byte */
1683                 db = 0;
1684                 res = write_ubyte(db,dbg,elfsectno,&writelen,error);
1685                 if (res != DW_DLV_OK) {
1686                     return res;
1687                 }
1688                 sum_bytes += writelen;
1689 
1690                 /* Write len of opcode + value here. */
1691                 res = pretend_write_uval(curline->dpl_discriminator,
1692                     dbg, &val_len,error);
1693                 if (res != DW_DLV_OK) {
1694                     return res;
1695                 }
1696                 val_len++;
1697 
1698                 res = write_uval(val_len +1,dbg,elfsectno,
1699                     &writelen,error);
1700                 if (res != DW_DLV_OK) {
1701                     return res;
1702                 }
1703                 sum_bytes += writelen;
1704 
1705                 /* Write opcode */
1706                 res = write_ubyte(DW_LNE_set_discriminator,
1707                     dbg,elfsectno,
1708                     &writelen,error);
1709                 if (res != DW_DLV_OK) {
1710                     return res;
1711                 }
1712                 sum_bytes += writelen;
1713 
1714                 /* Write the value itself. */
1715                 res = write_uval(curline->dpl_discriminator,
1716                     dbg,elfsectno,&writelen,error);
1717                 if (res != DW_DLV_OK) {
1718                     return res;
1719                 }
1720                 sum_bytes += writelen;
1721                 no_lns_copy = 1;
1722                 }
1723                 break;
1724             }
1725         } else {
1726             unsigned writelen = 0;
1727             if (inits->pi_opcode_base >12) {
1728                 /*  We have the newer standard opcodes
1729                     DW_LNS_set_prologue_end, DW_LNS_set_epilogue_end,
1730                     DW_LNS_set_isa, we do not write them if not
1731                     in the table. DWARF3 and DWARF4 */
1732                 /*  Should we check if a change? These reset automatically
1733                     in the line processing/reading engine,
1734                     so I think no check of prevline is wanted. */
1735                 if (curline->dpl_epilogue_begin) {
1736                     res = write_ubyte(DW_LNS_set_epilogue_begin,dbg,
1737                         elfsectno,&writelen, error);
1738                     if (res != DW_DLV_OK) {
1739                         return res;
1740                     }
1741                     sum_bytes += writelen;
1742                 }
1743                 if (curline->dpl_prologue_end) {
1744                     res = write_ubyte(DW_LNS_set_prologue_end,dbg,
1745                         elfsectno, &writelen,error);
1746                     if (res != DW_DLV_OK) {
1747                         return res;
1748                     }
1749                     sum_bytes += writelen;
1750                 }
1751                 if (curline->dpl_isa != prevline->dpl_isa) {
1752                     res = write_opcode_uval(DW_LNS_set_isa,dbg,
1753                         elfsectno, curline->dpl_isa,
1754                         &writelen ,error);
1755                     if (res != DW_DLV_OK) {
1756                         return res;
1757                     }
1758                     sum_bytes += writelen;
1759                 }
1760             }
1761             if (curline->dpl_file != prevline->dpl_file) {
1762                 db = DW_LNS_set_file;
1763                 res = write_opcode_uval(db,dbg,
1764                     elfsectno,
1765                         curline->dpl_file,&writelen ,error);
1766                 if (res != DW_DLV_OK) {
1767                     return res;
1768                 }
1769                 sum_bytes += writelen;
1770 
1771                 prevline->dpl_file = curline->dpl_file;
1772             }
1773             if (curline->dpl_column != prevline->dpl_column) {
1774                 db = DW_LNS_set_column;
1775                 res = write_opcode_uval(db,dbg,
1776                     elfsectno, curline->dpl_column , &writelen,error);
1777                 if (res != DW_DLV_OK) {
1778                     return res;
1779                 }
1780                 sum_bytes += writelen;
1781                 prevline->dpl_column = curline->dpl_column;
1782             }
1783             if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
1784                 res = write_ubyte(DW_LNS_negate_stmt,dbg,elfsectno,
1785                     &writelen,error);
1786                 if (res != DW_DLV_OK) {
1787                     return res;
1788                 }
1789                 sum_bytes += writelen;
1790                 prevline->dpl_is_stmt = curline->dpl_is_stmt;
1791             }
1792             if (curline->dpl_basic_block == true &&
1793                 prevline->dpl_basic_block == false) {
1794                 res = write_ubyte(DW_LNS_set_basic_block,dbg,
1795                     elfsectno,&writelen,error);
1796                 if (res != DW_DLV_OK) {
1797                     return res;
1798                 }
1799                 sum_bytes += writelen;
1800                 prevline->dpl_basic_block = curline->dpl_basic_block;
1801             }
1802             if (curline->dpl_discriminator) {
1803                 /*  This is dwarf4, but because it is an extended op
1804                     not a standard op,
1805                     we allow it without testing version.
1806                     GNU seems to set this from time to time. */
1807                 unsigned val_len = 0;
1808                 /* first null byte */
1809                 db = 0;
1810                 res = write_ubyte(db,dbg,elfsectno,&writelen,error);
1811                 if (res != DW_DLV_OK) {
1812                     return res;
1813                 }
1814                 sum_bytes += writelen;
1815 
1816                 /* Write len of opcode + value here. */
1817                 res = pretend_write_uval(curline->dpl_discriminator,
1818                     dbg, &val_len,error);
1819                 if (res != DW_DLV_OK) {
1820                     return res;
1821                 }
1822                 val_len ++;
1823                 res = write_uval(val_len +1,dbg,elfsectno,
1824                     &writelen,error);
1825                 if (res != DW_DLV_OK) {
1826                     return res;
1827                 }
1828                 sum_bytes += writelen;
1829 
1830                 /* Write opcode */
1831                 res = write_ubyte(DW_LNE_set_discriminator,
1832                     dbg,elfsectno,&writelen,error);
1833                 if (res != DW_DLV_OK) {
1834                     return res;
1835                 }
1836                 sum_bytes += writelen;
1837 
1838                 /* Write the value itself. */
1839                 res = write_uval(curline->dpl_discriminator,
1840                     dbg,elfsectno,&writelen,error);
1841                 if (res != DW_DLV_OK) {
1842                     return res;
1843                 }
1844                 sum_bytes += writelen;
1845             }
1846 
1847             addr_adv = curline->dpl_address - prevline->dpl_address;
1848 
1849             line_adv = (int) (curline->dpl_line - prevline->dpl_line);
1850             if ((addr_adv % MIN_INST_LENGTH) != 0) {
1851                 DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, DW_DLV_ERROR);
1852             }
1853             opc = _dwarf_pro_get_opc(inits,addr_adv, line_adv);
1854             if (opc > 0) {
1855                 /* Use special opcode. */
1856                 no_lns_copy = 1;
1857                 res = write_ubyte(opc,dbg,elfsectno,&writelen,error);
1858                 if (res != DW_DLV_OK) {
1859                     return res;
1860                 }
1861                 sum_bytes += writelen;
1862                 prevline->dpl_basic_block = false;
1863                 prevline->dpl_address = curline->dpl_address;
1864                 prevline->dpl_line = curline->dpl_line;
1865             } else {
1866                 /*  opc says use standard opcodes. */
1867                 if (addr_adv > 0) {
1868                     db = DW_LNS_advance_pc;
1869                     res = write_opcode_uval(db,dbg,
1870                         elfsectno,
1871                         addr_adv/inits->pi_minimum_instruction_length,
1872                         &writelen,
1873                         error);
1874                     if (res != DW_DLV_OK) {
1875                         return res;
1876                     }
1877                     sum_bytes += writelen;
1878                     prevline->dpl_basic_block = false;
1879                     prevline->dpl_address = curline->dpl_address;
1880                 }
1881                 if (line_adv != 0) {
1882                     db = DW_LNS_advance_line;
1883                     res = write_ubyte(db,dbg,
1884                         elfsectno,
1885                         &writelen,
1886                         error);
1887                     if (res != DW_DLV_OK) {
1888                         return res;
1889                     }
1890                     sum_bytes += writelen;
1891                     res = write_sval(line_adv,dbg,
1892                         elfsectno,
1893                         &writelen,
1894                         error);
1895                     if (res != DW_DLV_OK) {
1896                         return res;
1897                     }
1898                     sum_bytes += writelen;
1899                     prevline->dpl_basic_block = false;
1900                     prevline->dpl_line = curline->dpl_line;
1901                 }
1902             }
1903         }   /* ends else for opc <= 0 */
1904         if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq
1905             generate a matrix line */
1906             unsigned writelen = 0;
1907             res = write_ubyte(DW_LNS_copy,dbg,elfsectno,&writelen,error);
1908             if (res != DW_DLV_OK) {
1909                 return res;
1910             }
1911             sum_bytes += writelen;
1912             prevline->dpl_basic_block = false;
1913         }
1914         curline = curline->dpl_next;
1915     }
1916 
1917     /* write total length field */
1918     du = sum_bytes - OFFSET_PLUS_EXTENSION_SIZE;
1919     {
1920         start_line_sec += extension_size;
1921         WRITE_UNALIGNED(dbg, (void *) start_line_sec,
1922             (const void *) &du, sizeof(du), offset_size);
1923     }
1924 
1925     *nbufs = dbg->de_n_debug_sect;
1926     return DW_DLV_OK;
1927 }
1928 
1929 /*
1930     Generate debug_frame section  */
1931 static int
_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)1932 _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
1933     Dwarf_Signed *nbufs,
1934     Dwarf_Error * error)
1935 {
1936     int elfsectno = 0;
1937     int i = 0;
1938     int firsttime = 1;
1939     Dwarf_P_Cie curcie = 0;
1940     Dwarf_P_Fde curfde = 0;
1941     unsigned char *data = 0;
1942     Dwarf_Unsigned du = 0;
1943     Dwarf_Ubyte db = 0;
1944     long *cie_offs = 0;   /* Holds byte offsets for links to fde's */
1945     unsigned long cie_length = 0;
1946     int cie_no = 0;
1947     Dwarf_Ubyte offset_size = dbg->de_dwarf_offset_size;
1948     Dwarf_Ubyte extension_size = dbg->de_64bit_extension ? 4 : 0;
1949     Dwarf_Ubyte address_size = dbg->de_pointer_size;
1950     Dwarf_Unsigned cur_off = 0; /* current offset of written data, held
1951         for relocation info */
1952 
1953     elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
1954 
1955     curcie = dbg->de_frame_cies;
1956     cie_length = 0;
1957     cie_offs = (long *)
1958         _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
1959     if (cie_offs == NULL) {
1960         DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
1961     }
1962     /*  Generate cie number as we go along.  This writes
1963         all CIEs first before any FDEs, which is rather
1964         different from the order a compiler might like (which
1965         might be each CIE followed by its FDEs then the next CIE, and
1966         so on). */
1967     cie_no = 1;
1968     while (curcie) {
1969         char *code_al = 0;
1970         int codeal_bytes = 0;
1971         char *data_al = 0;
1972         int data_align_bytes = 0;
1973         int pad = 0;     /* Pad for padding to align cies and fdes */
1974         int res = 0;
1975         char buff1[ENCODE_SPACE_NEEDED];
1976         char buff2[ENCODE_SPACE_NEEDED];
1977         char buff3[ENCODE_SPACE_NEEDED];
1978         char *augmentation = 0;
1979         char *augmented_al = 0;
1980         long augmented_fields_length = 0;
1981         int irix_auglen_v0 = 0;
1982         Dwarf_Half version = curcie->cie_version;
1983 
1984         res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
1985             &codeal_bytes,
1986             buff1, sizeof(buff1));
1987         if (res != DW_DLV_OK) {
1988             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
1989         }
1990         /*  Before April 1999, the following was using an unsigned
1991             encode. That worked ok even though the decoder used the
1992             correct signed leb read, but doing the encode correctly
1993             (according to the dwarf spec) saves space in the output file
1994             and is completely compatible.
1995 
1996             Note the actual stored amount on MIPS was 10 bytes (!) to
1997             store the value -4. (hex)fc ffffffff ffffffff 01 The
1998             libdwarf consumer consumed all 10 bytes too!
1999 
2000             old version res =
2001             _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
2002 
2003             below is corrected signed version. */
2004         res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
2005             &data_align_bytes,
2006             buff2, sizeof(buff2));
2007         if (res != DW_DLV_OK) {
2008             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, DW_DLV_ERROR);
2009         }
2010         code_al = buff1;
2011         data_al = buff2;
2012 
2013         /* get the correct offset */
2014         if (firsttime) {
2015             cie_offs[cie_no - 1] = 0;
2016             firsttime = 0;
2017         } else {
2018             cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
2019                 (long) cie_length + OFFSET_PLUS_EXTENSION_SIZE;
2020         }
2021         cie_no++;
2022         augmentation = curcie->cie_aug;
2023         cie_length = offset_size +  /* cie_id */
2024             sizeof(Dwarf_Ubyte) +   /* cie version */
2025             strlen(curcie->cie_aug) + 1 +   /* augmentation */
2026             codeal_bytes +       /* code alignment factor */
2027             data_align_bytes +       /* data alignment factor */
2028             sizeof(Dwarf_Ubyte) +   /* return reg address */
2029             curcie->cie_inst_bytes;
2030         if (dbg->de_irix_exc_augmentation &&
2031             (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0)) {
2032 
2033             /* IRIX specific. */
2034             augmented_fields_length = 0;
2035             res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
2036                 &irix_auglen_v0, buff3,
2037                 sizeof(buff3));
2038             augmented_al = buff3;
2039             if (res != DW_DLV_OK) {
2040                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2041                     DW_DLV_ERROR);
2042             }
2043             cie_length += irix_auglen_v0 ;       /* augmentation length */
2044         }
2045         if (version >= 4) {
2046             /* address size, segment selector size */
2047             cie_length += 1 +1;
2048         }
2049 
2050         pad = (int) PADDING(cie_length, address_size);
2051         cie_length += pad;
2052 
2053         /* Now we have the cie length with padding,
2054             allocate a buffer for that plus the header
2055             length. */
2056         GET_CHUNK_ERR(dbg, elfsectno, data, cie_length +
2057             OFFSET_PLUS_EXTENSION_SIZE,
2058             error);
2059         if (extension_size) {
2060             DISTINGUISHED_VALUE_ARRAY(v4);
2061 
2062             WRITE_UNALIGNED(dbg, (void *) data,
2063                 (const void *) &v4[0],
2064                 SIZEOFT32, extension_size);
2065             data += extension_size;
2066 
2067         }
2068         du = cie_length;
2069         /* total length of cie */
2070         WRITE_UNALIGNED(dbg, (void *) data,
2071             (const void *) &du, sizeof(du), offset_size);
2072         data += offset_size;
2073 
2074         /* cie-id is a special value. */
2075         du = DW_CIE_ID;
2076         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
2077             sizeof(du), offset_size);
2078         data += offset_size;
2079 
2080         db = curcie->cie_version;
2081         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2082             sizeof(db), sizeof(Dwarf_Ubyte));
2083         data += sizeof(Dwarf_Ubyte);
2084 
2085         strcpy((char *) data, curcie->cie_aug);
2086         data += strlen(curcie->cie_aug) + 1;
2087 
2088         if (curcie->cie_version >= 4) {
2089             /* emit address-size, segment selector size */
2090             db = dbg->de_pointer_size;
2091             WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2092                 sizeof(db), sizeof(Dwarf_Ubyte));
2093             data += sizeof(Dwarf_Ubyte);
2094 
2095             db = dbg->de_segment_selector_size;
2096             WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2097                 sizeof(db), sizeof(Dwarf_Ubyte));
2098             data += sizeof(Dwarf_Ubyte);
2099         }
2100 
2101 
2102         memcpy((void *) data, (const void *) code_al, codeal_bytes);
2103         data += codeal_bytes;
2104 
2105         memcpy((void *) data, (const void *) data_al, data_align_bytes);
2106         data += data_align_bytes;
2107 
2108         db = curcie->cie_ret_reg;
2109         WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2110             sizeof(db), sizeof(Dwarf_Ubyte));
2111         data += sizeof(Dwarf_Ubyte);
2112 
2113         if (dbg->de_irix_exc_augmentation &&
2114             strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
2115 
2116             /* IRIX only */
2117             memcpy((void *) data, (const void *) augmented_al,
2118                 irix_auglen_v0);
2119             data += irix_auglen_v0;
2120         }
2121         memcpy((void *) data, (const void *) curcie->cie_inst,
2122             curcie->cie_inst_bytes);
2123         data += curcie->cie_inst_bytes;
2124 
2125         for (i = 0; i < pad; i++) {
2126             *data = DW_CFA_nop;
2127             data++;
2128         }
2129         curcie = curcie->cie_next;
2130     }
2131     /* calculate current offset */
2132     cur_off = cie_offs[cie_no - 2] + cie_length +
2133         OFFSET_PLUS_EXTENSION_SIZE;
2134 
2135     /* write out fde's */
2136     curfde = dbg->de_frame_fdes;
2137     while (curfde) {
2138         Dwarf_P_Frame_Pgm curinst = 0;
2139         long fde_length = 0;
2140         int pad2 = 0;
2141         Dwarf_P_Cie cie_ptr = 0;
2142         Dwarf_Unsigned cie_index = 0;
2143         /* index is a global in string.h, so don't name anything index. */
2144         Dwarf_Unsigned indx = 0;
2145         int oet_length = 0;
2146         int afl_length = 0;
2147         int res = 0;
2148         int v0_augmentation = 0;
2149         char afl_buff[ENCODE_SPACE_NEEDED];
2150 
2151         /* Find the CIE associated with this fde. */
2152         cie_ptr = dbg->de_frame_cies;
2153         cie_index = curfde->fde_cie;
2154         indx = 1; /* The cie_index of the first cie is 1, not 0. */
2155         while (cie_ptr && indx < cie_index) {
2156             cie_ptr = cie_ptr->cie_next;
2157             indx++;
2158         }
2159         if (cie_ptr == NULL) {
2160             DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, DW_DLV_ERROR);
2161         }
2162 
2163         fde_length = curfde->fde_n_bytes +
2164             OFFSET_PLUS_EXTENSION_SIZE +
2165             /* cie pointer */
2166             address_size + /* initial loc */
2167             address_size;  /* address range */
2168         if (dbg->de_irix_exc_augmentation &&
2169             strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
2170 
2171             v0_augmentation = 1;
2172             oet_length = DWARF_32BIT_SIZE;
2173             /* encode the length of augmented fields. */
2174             res = _dwarf_pro_encode_leb128_nm(oet_length,
2175                 &afl_length, afl_buff,
2176                 sizeof(afl_buff));
2177             if (res != DW_DLV_OK) {
2178                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC,
2179                     DW_DLV_ERROR);
2180             }
2181 
2182             fde_length +=
2183                 afl_length +    /* augmented field length */
2184                 oet_length;     /* exception_table offset */
2185         }
2186 
2187         if (curfde->fde_die) {
2188             /*  IRIX/MIPS extension:
2189                 Using fde offset, generate DW_AT_MIPS_fde
2190                 attribute for the
2191                 die corresponding to this fde.  */
2192             res = _dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off,
2193                 error);
2194             if (res != DW_DLV_OK) {
2195                 return res;
2196             }
2197         }
2198 
2199         /* store relocation for cie pointer */
2200 
2201         res = dbg->de_relocate_by_name_symbol(dbg,
2202             DEBUG_FRAME, cur_off +
2203             OFFSET_PLUS_EXTENSION_SIZE /* r_offset */,
2204             dbg->de_sect_name_idx[DEBUG_FRAME],
2205             dwarf_drt_data_reloc, offset_size);
2206         if (res != DW_DLV_OK) {
2207             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res );
2208         }
2209 
2210         /* store relocation information for initial location */
2211         res = dbg->de_relocate_by_name_symbol(dbg,
2212             DEBUG_FRAME,
2213             cur_off + OFFSET_PLUS_EXTENSION_SIZE +
2214                 address_size /* r_offset */,
2215             curfde->fde_r_symidx,
2216             dwarf_drt_data_reloc, address_size);
2217         if (res != DW_DLV_OK) {
2218             DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
2219         }
2220         /*  Store the relocation information for the
2221             offset_into_exception_info field, if the offset is valid (0
2222             is a valid offset). */
2223         if (v0_augmentation &&
2224             curfde->fde_offset_into_exception_tables >= 0) {
2225 
2226             res = dbg->de_relocate_by_name_symbol(dbg,
2227                 DEBUG_FRAME,
2228                 /* r_offset, where in cie this field starts */
2229                 cur_off + OFFSET_PLUS_EXTENSION_SIZE +
2230                     offset_size + 2 * address_size +
2231                     afl_length,
2232                 curfde->fde_exception_table_symbol,
2233                 dwarf_drt_segment_rel,
2234                 DWARF_32BIT_SIZE);
2235             if (res != DW_DLV_OK) {
2236                 DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, res);
2237             }
2238         }
2239 
2240         /* adjust for padding */
2241         pad2 = (int) PADDING(fde_length, address_size);
2242         fde_length += pad2;
2243 
2244 
2245         /* write out fde */
2246         GET_CHUNK(dbg, elfsectno, data, fde_length +
2247             OFFSET_PLUS_EXTENSION_SIZE,
2248             error);
2249         du = fde_length;
2250         {
2251             if (extension_size) {
2252                 DISTINGUISHED_VALUE_ARRAY(v4);
2253 
2254                 WRITE_UNALIGNED(dbg, (void *) data,
2255                     (const void *) &v4[0],
2256                     SIZEOFT32, extension_size);
2257                 data += extension_size;
2258             }
2259             /* length */
2260             WRITE_UNALIGNED(dbg, (void *) data,
2261                 (const void *) &du,
2262                 sizeof(du), offset_size);
2263             data += offset_size;
2264 
2265             /* offset to cie */
2266             du = cie_offs[curfde->fde_cie - 1];
2267             WRITE_UNALIGNED(dbg, (void *) data,
2268                 (const void *) &du,
2269                 sizeof(du), offset_size);
2270             data += offset_size;
2271 
2272             du = curfde->fde_initloc;
2273             WRITE_UNALIGNED(dbg, (void *) data,
2274                 (const void *) &du,
2275                 sizeof(du), address_size);
2276             data += address_size;
2277 
2278             if (dbg->de_relocate_pair_by_symbol &&
2279                 curfde->fde_end_symbol != 0 &&
2280                 curfde->fde_addr_range == 0) {
2281                 /*  symbolic reloc, need reloc for length What if we
2282                     really know the length? If so, should use the other
2283                     part of 'if'. */
2284                 Dwarf_Unsigned val;
2285 
2286                 res = dbg->de_relocate_pair_by_symbol(dbg,
2287                     DEBUG_FRAME,
2288                     cur_off + 2 * offset_size + address_size,
2289                     /* r_offset */ curfde->fde_r_symidx,
2290                     curfde->fde_end_symbol,
2291                     dwarf_drt_first_of_length_pair,
2292                     address_size);
2293                 if (res != DW_DLV_OK) {
2294                     {
2295                         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
2296                         return DW_DLV_ERROR;
2297                     }
2298                 }
2299 
2300                 /*  arrange pre-calc so assem text can do .word end -
2301                     begin + val (gets val from stream) */
2302                 val = curfde->fde_end_symbol_offset -
2303                     curfde->fde_initloc;
2304                 WRITE_UNALIGNED(dbg, data,
2305                     (const void *) &val,
2306                     sizeof(val), address_size);
2307                 data += address_size;
2308             } else {
2309                 du = curfde->fde_addr_range;
2310                 WRITE_UNALIGNED(dbg, (void *) data,
2311                     (const void *) &du,
2312                     sizeof(du), address_size);
2313                 data += address_size;
2314             }
2315         }
2316 
2317         if (v0_augmentation) {
2318             /* IRIX only. */
2319             /* write the encoded augmented field length. */
2320             Dwarf_Signed dsw = 0;
2321 
2322             memcpy((void *) data, (const void *) afl_buff, afl_length);
2323             data += afl_length;
2324             /* write the offset_into_exception_tables field. */
2325             dsw = (Dwarf_Signed)curfde->fde_offset_into_exception_tables;
2326             WRITE_UNALIGNED(dbg, (void *) data,
2327                 (const void *) &dsw,
2328                 sizeof(dsw), DWARF_32BIT_SIZE);
2329             data += DWARF_32BIT_SIZE;
2330         }
2331 
2332         curinst = curfde->fde_inst;
2333         if (curfde->fde_block) {
2334             unsigned long size = curfde->fde_inst_block_size;
2335             memcpy((void *) data, (const void *) curfde->fde_block, size);
2336             data += size;
2337         } else {
2338             while (curinst) {
2339                 db = curinst->dfp_opcode;
2340                 WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
2341                     sizeof(db), sizeof(Dwarf_Ubyte));
2342                 data += sizeof(Dwarf_Ubyte);
2343                 memcpy((void *) data,
2344                     (const void *) curinst->dfp_args,
2345                     curinst->dfp_nbytes);
2346                 data += curinst->dfp_nbytes;
2347                 curinst = curinst->dfp_next;
2348             }
2349         }
2350         /* padding */
2351         for (i = 0; i < pad2; i++) {
2352             *data = DW_CFA_nop;
2353             data++;
2354         }
2355         cur_off += fde_length + offset_size;
2356         curfde = curfde->fde_next;
2357     }
2358 
2359 
2360     *nbufs =  dbg->de_n_debug_sect;
2361     return DW_DLV_OK;
2362 }
2363 
2364 /*
2365   These functions remember all the markers we see along
2366   with the right offset in the .debug_info section so that
2367   we can dump them all back to the user with the section info.
2368 */
2369 
2370 static int
marker_init(Dwarf_P_Debug dbg,unsigned count)2371 marker_init(Dwarf_P_Debug dbg,
2372     unsigned count)
2373 {
2374     dbg->de_marker_n_alloc = count;
2375     dbg->de_markers = NULL;
2376     if (count > 0) {
2377         dbg->de_markers = _dwarf_p_get_alloc(dbg,
2378             sizeof(struct Dwarf_P_Marker_s) * dbg->de_marker_n_alloc);
2379         if (dbg->de_markers == NULL) {
2380             dbg->de_marker_n_alloc = 0;
2381             return DW_DLV_ERROR;
2382         }
2383     }
2384     return DW_DLV_OK;
2385 }
2386 
2387 static int
marker_add(Dwarf_P_Debug dbg,Dwarf_Unsigned offset,Dwarf_Unsigned marker)2388 marker_add(Dwarf_P_Debug dbg,
2389     Dwarf_Unsigned offset,
2390     Dwarf_Unsigned marker)
2391 {
2392     if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
2393         unsigned n = dbg->de_marker_n_used++;
2394         dbg->de_markers[n].ma_offset = offset;
2395         dbg->de_markers[n].ma_marker = marker;
2396         return DW_DLV_OK;
2397     }
2398     return DW_DLV_ERROR;
2399 }
2400 
2401 Dwarf_Signed
dwarf_get_die_markers(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)2402 dwarf_get_die_markers(Dwarf_P_Debug dbg,
2403     Dwarf_P_Marker * marker_list, /* pointer to a pointer */
2404     Dwarf_Unsigned * marker_count,
2405     Dwarf_Error * error)
2406 {
2407     int res = 0;
2408 
2409     res = dwarf_get_die_markers_a(dbg,marker_list,marker_count,
2410         error);
2411     if (res == DW_DLV_ERROR) {
2412         return DW_DLV_BADADDR;
2413     }
2414     return 0;
2415 }
2416 
2417 int
dwarf_get_die_markers_a(Dwarf_P_Debug dbg,Dwarf_P_Marker * marker_list,Dwarf_Unsigned * marker_count,Dwarf_Error * error)2418 dwarf_get_die_markers_a(Dwarf_P_Debug dbg,
2419     Dwarf_P_Marker * marker_list, /* pointer to a pointer */
2420     Dwarf_Unsigned * marker_count,
2421     Dwarf_Error * error)
2422 {
2423     if (marker_list == NULL || marker_count == NULL) {
2424         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
2425     }
2426     if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
2427         DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR);
2428     }
2429 
2430     *marker_list = dbg->de_markers;
2431     *marker_count = dbg->de_marker_n_used;
2432     return DW_DLV_OK;
2433 }
2434 
2435 /*  These functions provide the offsets of DW_FORM_string
2436     attributes in the section section_index. These information
2437     will enable a producer app that is generating assembly
2438     text output to easily emit those attributes in ascii form
2439     without having to decode the byte stream.  */
2440 static int
string_attr_init(Dwarf_P_Debug dbg,Dwarf_Signed section_index,unsigned count)2441 string_attr_init (Dwarf_P_Debug dbg,
2442     Dwarf_Signed section_index,
2443     unsigned count)
2444 {
2445     Dwarf_P_Per_Sect_String_Attrs sect_sa =
2446         &dbg->de_sect_string_attr[section_index];
2447 
2448     sect_sa->sect_sa_n_alloc = count;
2449     sect_sa->sect_sa_list = NULL;
2450     if (count > 0) {
2451         sect_sa->sect_sa_section_number = section_index;
2452         sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
2453             sizeof(struct Dwarf_P_String_Attr_s) * sect_sa->sect_sa_n_alloc);
2454         if (sect_sa->sect_sa_list == NULL) {
2455             sect_sa->sect_sa_n_alloc = 0;
2456             return DW_DLV_ERROR;
2457         }
2458     }
2459     return DW_DLV_OK;
2460 }
2461 
2462 static int
string_attr_add(Dwarf_P_Debug dbg,Dwarf_Signed section_index,Dwarf_Unsigned offset,Dwarf_P_Attribute attr)2463 string_attr_add (Dwarf_P_Debug dbg,
2464     Dwarf_Signed section_index,
2465     Dwarf_Unsigned offset,
2466     Dwarf_P_Attribute attr)
2467 {
2468     Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
2469     if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
2470         unsigned n = sect_sa->sect_sa_n_used++;
2471         sect_sa->sect_sa_list[n].sa_offset = offset;
2472         sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
2473         return DW_DLV_OK;
2474     }
2475 
2476     return DW_DLV_ERROR;
2477 }
2478 
2479 int
dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_sa_sections,int * drd_buffer_version,UNUSEDARG Dwarf_Error * error)2480 dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
2481     Dwarf_Unsigned *
2482     count_of_sa_sections,
2483     int *drd_buffer_version,
2484     UNUSEDARG Dwarf_Error *error)
2485 {
2486     int i = 0;
2487     unsigned int count = 0;
2488 
2489     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
2490         if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
2491             ++count;
2492         }
2493     }
2494     *count_of_sa_sections = (Dwarf_Unsigned) count;
2495     *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
2496 
2497     return DW_DLV_OK;
2498 }
2499 
2500 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,UNUSEDARG Dwarf_Error * error)2501 dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
2502     Dwarf_Signed *elf_section_index,
2503     Dwarf_Unsigned *sect_sa_buffer_count,
2504     Dwarf_P_String_Attr *sect_sa_buffer,
2505     UNUSEDARG Dwarf_Error *error)
2506 {
2507     int i = 0;
2508     int next = dbg->de_sect_sa_next_to_return;
2509 
2510     for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
2511         Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];
2512         if (sect_sa->sect_sa_n_used > 0) {
2513             dbg->de_sect_sa_next_to_return = i + 1;
2514             *elf_section_index = sect_sa->sect_sa_section_number;
2515             *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
2516             *sect_sa_buffer = sect_sa->sect_sa_list;
2517             return DW_DLV_OK;
2518         }
2519     }
2520     return DW_DLV_NO_ENTRY;
2521 }
2522 
2523 
2524 static int
has_sibling_die_already(Dwarf_P_Die d)2525 has_sibling_die_already(Dwarf_P_Die d)
2526 {
2527     Dwarf_P_Attribute a = 0;
2528     for(a = d->di_attrs; a ; a = a->ar_next) {
2529         if(a->ar_attribute == DW_AT_sibling) {
2530             return TRUE;
2531         }
2532     }
2533     return FALSE;
2534 }
2535 
2536 /*  For DW_FORM_strp we need to set the symindex so we need
2537     to check that such applies.  */
2538 static int
if_relocatable_string_form(Dwarf_P_Debug dbg,Dwarf_P_Attribute curattr,int * debug_str_reloc,Dwarf_Error * error)2539 if_relocatable_string_form(Dwarf_P_Debug dbg, Dwarf_P_Attribute curattr,
2540     int *debug_str_reloc,
2541     Dwarf_Error *error)
2542 {
2543     if (curattr->ar_rel_type == R_MIPS_NONE) {
2544         *debug_str_reloc = 0;
2545         return DW_DLV_OK;
2546     }
2547     if (curattr->ar_attribute_form != DW_FORM_strp) {
2548         _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL);
2549         return DW_DLV_ERROR;
2550     }
2551     if (curattr->ar_rel_type != dbg->de_offset_reloc) {
2552         _dwarf_p_error(dbg, error,DW_DLE_DEBUGSTR_UNEXPECTED_REL);
2553         return DW_DLV_ERROR;
2554     }
2555     *debug_str_reloc = 1;
2556     return DW_DLV_OK;
2557 }
2558 
2559 /*  Tries to see if given attribute and form combination
2560     of the attr exists in the given abbreviation.
2561     abbrevs and attrs are sorted in attrnum order. */
2562 static int
_dwarf_pro_match_attr(Dwarf_P_Attribute attr,Dwarf_P_Abbrev abbrev,int no_attr)2563 _dwarf_pro_match_attr(Dwarf_P_Attribute attr,
2564     Dwarf_P_Abbrev abbrev, int no_attr)
2565 {
2566     int i = 0;
2567     Dwarf_P_Attribute curatp = attr;
2568 
2569     for (i = 0; i < no_attr && curatp; i++,curatp = curatp->ar_next ) {
2570         if (curatp->ar_attribute != abbrev->abb_attrs[i] ||
2571             curatp->ar_attribute_form != abbrev->abb_forms[i]) {
2572             return 0;
2573         }
2574         /*  If either is implicit_const need special
2575             check for matching val. */
2576         if (curatp->ar_attribute_form == DW_FORM_implicit_const) {
2577             if (abbrev->abb_forms[i] == DW_FORM_implicit_const) {
2578                 if (curatp->ar_implicit_const !=
2579                     abbrev->abb_implicits[i]) {
2580                     return 0;
2581                 }
2582             } else {
2583                 return 0;
2584             }
2585         } else {
2586             if (abbrev->abb_forms[i] == DW_FORM_implicit_const) {
2587                 return 0;
2588             }
2589         }
2590     }
2591     return 1;
2592 }
2593 
2594 static int
verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s * sortab,int attrcount)2595 verify_ab_no_dups(struct Dwarf_Sort_Abbrev_s *sortab,
2596     int attrcount)
2597 {
2598     int k = 0;
2599     unsigned preva = 0;
2600     struct Dwarf_Sort_Abbrev_s *ab = sortab;
2601 
2602     if (attrcount < 2) {
2603         return DW_DLV_OK;
2604     }
2605     for(k = 0; k < attrcount; ++k,++ab) {
2606         if (k) {
2607             if (preva >= ab->dsa_attr) {
2608                 return DW_DLV_ERROR;
2609             }
2610         }
2611         preva = ab->dsa_attr;
2612     }
2613     return DW_DLV_OK;
2614 }
2615 
2616 static int
abcompare(const void * l_in,const void * r_in)2617 abcompare(const void *l_in, const void *r_in)
2618 {
2619     struct Dwarf_Sort_Abbrev_s *l =
2620         (struct Dwarf_Sort_Abbrev_s *)l_in;
2621     struct Dwarf_Sort_Abbrev_s *r =
2622         (struct Dwarf_Sort_Abbrev_s *)r_in;
2623     if (l->dsa_attr < r->dsa_attr) {
2624         return -1;
2625     }
2626     if (l->dsa_attr > r->dsa_attr) {
2627         return +1;
2628     }
2629     /* ASSERT: This never happens in correct dwarf. */
2630     return 0;
2631 }
2632 
2633 /*  Handles abbreviations. It takes a die, searches through
2634     current list of abbreviations for a matching one. If it
2635     finds one, it returns a pointer to the abbrev through
2636     the ab_out pointer, and if it does not,
2637     it returns a new abbrev through the ab_out pointer.
2638 
2639     The die->die_attrs are sorted by attribute and the curabbrev
2640     attrs are too.
2641 
2642     It is up to the user of this function to
2643     link it up to the abbreviation head. If it is a new abbrev
2644     abb_idx has 0. */
2645 static int
_dwarf_pro_getabbrev(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_P_Abbrev head,Dwarf_P_Abbrev * ab_out,Dwarf_Error * error)2646 _dwarf_pro_getabbrev(Dwarf_P_Debug dbg,
2647     Dwarf_P_Die die, Dwarf_P_Abbrev head,
2648     Dwarf_P_Abbrev*ab_out,Dwarf_Error *error)
2649 {
2650     Dwarf_P_Abbrev curabbrev = 0;
2651     Dwarf_P_Attribute curattr = 0;
2652     int match = 0;
2653     Dwarf_Unsigned *forms = 0;
2654     Dwarf_Unsigned *attrs = 0;
2655     Dwarf_Signed *implicits = 0;
2656     int attrcount = die->di_n_attr;
2657 
2658     curabbrev = head;
2659     /*  Loop thru the currently known abbreviations needed
2660         to see if we can share an existing abbrev.  */
2661     while (curabbrev) {
2662         if ((die->di_tag == curabbrev->abb_tag) &&
2663             ((die->di_child != NULL &&
2664             curabbrev->abb_children == DW_CHILDREN_yes) ||
2665             (die->di_child == NULL &&
2666             curabbrev->abb_children == DW_CHILDREN_no)) &&
2667             (attrcount == curabbrev->abb_n_attr)) {
2668 
2669             /*  There is a chance of a match, basic
2670                 characterists match. Now Check the attrs and
2671                 forms. */
2672             curattr = die->di_attrs;
2673             match = _dwarf_pro_match_attr(curattr,
2674                 curabbrev,
2675                 (int) curabbrev->abb_n_attr);
2676             if (match == 1) {
2677                 /*  This tag/children/abbrev-list matches
2678                     the incoming die needs exactly. Reuse
2679                     this abbreviation. */
2680                 *ab_out = curabbrev;
2681                 return DW_DLV_OK;
2682             }
2683         }
2684         curabbrev = curabbrev->abb_next;
2685     }
2686     /* no match, create new abbreviation */
2687     if (attrcount) {
2688         forms = (Dwarf_Unsigned *)
2689             _dwarf_p_get_alloc(die->di_dbg,
2690                 sizeof(Dwarf_Unsigned) * attrcount);
2691         if (forms == NULL) {
2692             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2693         }
2694         attrs = (Dwarf_Unsigned *)
2695             _dwarf_p_get_alloc(die->di_dbg,
2696                 sizeof(Dwarf_Unsigned) * attrcount);
2697         if (attrs == NULL) {
2698             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2699         }
2700         implicits = (Dwarf_Signed *)
2701             _dwarf_p_get_alloc(die->di_dbg,
2702                 sizeof(Dwarf_Signed) * attrcount);
2703         if (implicits == NULL) {
2704             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2705         }
2706     }
2707     curattr = die->di_attrs;
2708     if (forms && attrs && attrcount) {
2709         struct Dwarf_Sort_Abbrev_s *sortab = 0;
2710         struct Dwarf_Sort_Abbrev_s *ap = 0;
2711         int k = 0;
2712         int res = 0;
2713 
2714         sortab = (struct Dwarf_Sort_Abbrev_s *)
2715             malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount);
2716         if(!sortab) {
2717             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2718         }
2719         /*  ASSERT curattr->ar_next chain length == attrcount  */
2720         ap = sortab;
2721         for(; curattr; ++ap, curattr = curattr->ar_next) {
2722             ap->dsa_attr = curattr->ar_attribute;
2723             ap->dsa_form = curattr->ar_attribute_form;
2724             ap->dsa_implicitvalue = curattr->ar_implicit_const;
2725             ap->dsa_attrp = 0;
2726         }
2727 
2728         qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s),
2729             abcompare);
2730         ap = sortab;
2731         k = 0;
2732         res = verify_ab_no_dups(sortab,attrcount);
2733         if (res != DW_DLV_OK) {
2734             DWARF_P_DBG_ERROR(dbg,DW_DLE_DUP_ATTR_ON_DIE,DW_DLV_ERROR);
2735         }
2736         for( ; k < attrcount; ++k,++ap) {
2737             attrs[k] = ap->dsa_attr;
2738             forms[k] = ap->dsa_form;
2739             implicits[k] = ap->dsa_implicitvalue;
2740         }
2741         free(sortab);
2742     }
2743 
2744     curabbrev = (Dwarf_P_Abbrev)
2745         _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
2746     if (curabbrev == NULL) {
2747         DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
2748     }
2749 
2750     if (die->di_child == NULL) {
2751         curabbrev->abb_children = DW_CHILDREN_no;
2752     } else {
2753         curabbrev->abb_children = DW_CHILDREN_yes;
2754     }
2755     curabbrev->abb_tag = die->di_tag;
2756     curabbrev->abb_attrs = attrs;
2757     curabbrev->abb_forms = forms;
2758     curabbrev->abb_implicits = implicits;
2759     curabbrev->abb_n_attr = attrcount;
2760     curabbrev->abb_idx = 0;
2761     curabbrev->abb_next = NULL;
2762     *ab_out = curabbrev;
2763     return DW_DLV_OK;
2764 }
2765 
2766 /* Generate debug_info and debug_abbrev sections */
2767 
2768 
2769 /*  DWARF 2,3,4  */
2770 static int
generate_debuginfo_header_2(Dwarf_P_Debug dbg,unsigned * abbrev_offset_io,unsigned char ** data_io,int * cu_header_size_out,Dwarf_Small ** abbr_off_ptr_out,Dwarf_Half version,int extension_size,Dwarf_Ubyte address_size,Dwarf_Error * error)2771 generate_debuginfo_header_2(Dwarf_P_Debug dbg,
2772     unsigned *abbrev_offset_io,
2773     unsigned char **data_io,
2774     int     *cu_header_size_out,
2775     Dwarf_Small **abbr_off_ptr_out,
2776     Dwarf_Half version,
2777     int extension_size,
2778     Dwarf_Ubyte address_size,
2779     Dwarf_Error * error)
2780 {
2781     unsigned abbrev_offset = 0;
2782     unsigned char * data = 0;
2783     int offset_size = dbg->de_dwarf_offset_size;
2784     int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
2785     int cu_header_size = 0;
2786     Dwarf_Unsigned du = 0;
2787     Dwarf_Small *abbr_off_ptr = 0;
2788 
2789     /* write cu header. abbrev_offset used to
2790         generate relocation record below */
2791     abbrev_offset =  OFFSET_PLUS_EXTENSION_SIZE +
2792         DWARF_HALF_SIZE  ;
2793 
2794     cu_header_size = abbrev_offset +
2795         offset_size + sizeof(Dwarf_Ubyte);
2796 
2797     GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size,
2798         error);
2799     if (extension_size) {
2800         /* This for a dwarf-standard 64bit offset. */
2801         DISTINGUISHED_VALUE_ARRAY(v4);
2802 
2803         WRITE_UNALIGNED(dbg, (void *) data,
2804             (const void *) &v4[0], SIZEOFT32, extension_size);
2805         data += extension_size;
2806     }
2807     abbr_off_ptr = data;
2808     du = 0; /* length of debug_info, not counting
2809         this field itself (unknown at this point). */
2810     WRITE_UNALIGNED(dbg, (void *) data,
2811         (const void *) &du, sizeof(du), offset_size);
2812     data += offset_size;
2813 
2814     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
2815         sizeof(version), DWARF_HALF_SIZE);
2816     data += DWARF_HALF_SIZE;
2817 
2818     du = 0;/* offset into abbrev table, not yet known. */
2819     WRITE_UNALIGNED(dbg, (void *) data,
2820         (const void *) &du, sizeof(du), offset_size);
2821     data += offset_size;
2822 
2823     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size,
2824         sizeof(address_size), sizeof(Dwarf_Ubyte));
2825     data += sizeof(Dwarf_Ubyte);
2826 
2827     /*  We have filled the chunk we got with GET_CHUNK.
2828         At this point we
2829         no longer dare use "data"  as a
2830         pointer any longer except to refer to that first
2831         small chunk for the cu header to update
2832         the section length. */
2833     *abbrev_offset_io = abbrev_offset;
2834     *data_io = data;
2835     *cu_header_size_out = cu_header_size;
2836     *abbr_off_ptr_out = abbr_off_ptr;
2837     return DW_DLV_OK;
2838 }
2839 
2840 /*  DWARF 5 */
2841 static int
generate_debuginfo_header_5(Dwarf_P_Debug dbg,unsigned * abbrev_offset_io,unsigned char ** data_io,int * cu_header_size_out,Dwarf_Small ** abbr_off_ptr_out,Dwarf_Half version,Dwarf_Ubyte unit_type,int extension_size,Dwarf_Ubyte address_size,Dwarf_Error * error)2842 generate_debuginfo_header_5(Dwarf_P_Debug dbg,
2843     unsigned       *abbrev_offset_io,
2844     unsigned char **data_io,
2845     int            *cu_header_size_out,
2846     Dwarf_Small   **abbr_off_ptr_out,
2847     Dwarf_Half      version,
2848     Dwarf_Ubyte     unit_type,
2849     int             extension_size,
2850     Dwarf_Ubyte     address_size,
2851     Dwarf_Error    *error)
2852 {
2853     int offset_size = dbg->de_dwarf_offset_size;
2854     unsigned abbrev_offset = 0;
2855     unsigned char * data = 0;
2856     int elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
2857     int cu_header_size = 0;
2858     Dwarf_Unsigned du = 0;
2859     Dwarf_Small *abbr_off_ptr = 0;
2860 
2861 
2862     /*  write cu header. abbrev_offset used to
2863         generate relocation record below */
2864     abbrev_offset =  OFFSET_PLUS_EXTENSION_SIZE +
2865         DWARF_HALF_SIZE + /* version stamp */
2866         sizeof(unit_type) +
2867         sizeof(Dwarf_Ubyte);
2868     cu_header_size = abbrev_offset + offset_size;
2869 
2870     GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, cu_header_size,
2871         error);
2872     if (extension_size) {
2873         /* Impossible in DW5, really, is for IRIX64. But we allow it. */
2874         DISTINGUISHED_VALUE_ARRAY(v4);
2875 
2876         WRITE_UNALIGNED(dbg, (void *) data,
2877             (const void *) &v4[0], SIZEOFT32, extension_size);
2878         data += extension_size;
2879     }
2880     abbr_off_ptr = data;
2881     du = 0; /* length of debug_info, not counting
2882         this field itself (unknown at this point). */
2883     WRITE_UNALIGNED(dbg, (void *) data,
2884         (const void *) &du, sizeof(du), offset_size);
2885     data += offset_size;
2886 
2887     WRITE_UNALIGNED(dbg, (void *) data,
2888         (const void *) &version,
2889         sizeof(version), DWARF_HALF_SIZE);
2890     data += DWARF_HALF_SIZE;
2891 
2892     WRITE_UNALIGNED(dbg, (void *) data,
2893         (const void *) &unit_type,
2894         sizeof(unit_type), sizeof(Dwarf_Ubyte));
2895     data += sizeof(Dwarf_Ubyte);
2896 
2897     WRITE_UNALIGNED(dbg, (void *) data, (const void *) &address_size,
2898         sizeof(address_size), sizeof(Dwarf_Ubyte));
2899     data += sizeof(Dwarf_Ubyte);
2900 
2901     du = 0;/* offset into abbrev table, not yet known. */
2902     WRITE_UNALIGNED(dbg, (void *) data,
2903         (const void *) &du, sizeof(du), offset_size);
2904     data += offset_size;
2905 
2906     /*  We have filled the chunk we got with GET_CHUNK.
2907         At this point we
2908         no longer dare use "data" as a pointer any
2909         longer except to refer to that first small chunk for the cu
2910         header to update the section length. */
2911 
2912     *abbrev_offset_io = abbrev_offset;
2913     *data_io = data;
2914     *cu_header_size_out = cu_header_size;
2915     *abbr_off_ptr_out = abbr_off_ptr;
2916     return DW_DLV_OK;
2917 }
2918 
2919 /* Write out debug_abbrev section */
2920 static int
write_out_debug_abbrev(Dwarf_P_Debug dbg,Dwarf_P_Abbrev abbrev_head,Dwarf_Error * error)2921 write_out_debug_abbrev(Dwarf_P_Debug dbg,
2922     Dwarf_P_Abbrev abbrev_head,
2923     Dwarf_Error * error)
2924 {
2925     Dwarf_P_Abbrev curabbrev = abbrev_head;
2926     unsigned char *data = 0;
2927     int res = 0;
2928     int abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
2929 
2930     while (curabbrev) {
2931         int idx = 0;
2932         unsigned lebcount = 0;
2933         Dwarf_Ubyte db = 0;
2934 
2935         res  = write_uval(curabbrev->abb_idx,dbg,abbrevsectno,
2936             &lebcount,error);
2937         if (res != DW_DLV_OK) {
2938             return res;
2939         }
2940 
2941         res  = write_uval(curabbrev->abb_tag,dbg,abbrevsectno,
2942             &lebcount,error);
2943         if (res != DW_DLV_OK) {
2944             return res;
2945         }
2946 
2947         db = curabbrev->abb_children;
2948         res = write_ubyte(db,dbg,abbrevsectno,&lebcount,error);
2949         if (res != DW_DLV_OK) {
2950             return res;
2951         }
2952 
2953         /* add attributes and forms */
2954         for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
2955             res =write_uval(curabbrev->abb_attrs[idx],
2956                 dbg,abbrevsectno,
2957                 &lebcount,error);
2958             if (res != DW_DLV_OK) {
2959                 return res;
2960             }
2961             res =write_uval(curabbrev->abb_forms[idx],
2962                 dbg,abbrevsectno,
2963                 &lebcount,error);
2964             if (res != DW_DLV_OK) {
2965                 return res;
2966             }
2967             if (curabbrev->abb_forms[idx] == DW_FORM_implicit_const){
2968                 res =write_sval(curabbrev->abb_implicits[idx],
2969                     dbg,abbrevsectno,
2970                     &lebcount,error);
2971                 if (res != DW_DLV_OK) {
2972                     return res;
2973                 }
2974             }
2975         }
2976         /* Two zeros, for last entry, see dwarf2 sec 7.5.3 */
2977         GET_CHUNK_ERR(dbg, abbrevsectno, data, 2, error);
2978         *data = 0;
2979         data++;
2980         *data = 0;
2981 
2982         curabbrev = curabbrev->abb_next;
2983     }
2984     /* one zero, for end of cu, see dwarf2 sec 7.5.3 */
2985     GET_CHUNK_ERR(dbg, abbrevsectno, data, 1, error);
2986     *data = 0;
2987     return DW_DLV_OK;
2988 }
2989 
2990 static int
sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die,Dwarf_Error * error)2991 sort_die_attrs(Dwarf_P_Debug dbg,Dwarf_P_Die die,
2992     Dwarf_Error *error)
2993 {
2994     struct Dwarf_Sort_Abbrev_s *sortab = 0;
2995     struct Dwarf_Sort_Abbrev_s *ap = 0;
2996     Dwarf_P_Attribute at = 0;
2997     Dwarf_P_Attribute sorted_attrlist = 0;
2998     Dwarf_P_Attribute sorted_tail = 0;
2999     int attrcount = die->di_n_attr;
3000     int res = 0;
3001     unsigned ct = 0;
3002 
3003     int k = 0;
3004 
3005     if (attrcount < 2) {
3006         return DW_DLV_OK;
3007     }
3008 
3009     sortab = (struct Dwarf_Sort_Abbrev_s *)
3010         malloc(sizeof(struct Dwarf_Sort_Abbrev_s)*attrcount);
3011     if(!sortab) {
3012         DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3013     }
3014     /*  ASSERT at->ar_next chain length == attrcount  */
3015     ap = sortab;
3016     at = die->di_attrs;
3017     for(; at; ++ap, at = at->ar_next) {
3018         ap->dsa_attr = at->ar_attribute;
3019         ap->dsa_form = at->ar_attribute_form;
3020         ap->dsa_attrp = at;
3021         ++ct;
3022     }
3023     qsort(sortab,attrcount,sizeof(struct Dwarf_Sort_Abbrev_s),
3024         abcompare);
3025     res = verify_ab_no_dups(sortab,attrcount);
3026     if (res != DW_DLV_OK) {
3027         DWARF_P_DBG_ERROR(dbg, DW_DLE_DUP_ATTR_ON_DIE, DW_DLV_ERROR);
3028     }
3029     ap = sortab;
3030     k = 0;
3031     for( ; k < attrcount; ++k,++ap) {
3032         Dwarf_P_Attribute localptr = ap->dsa_attrp;
3033         if (!sorted_attrlist) {
3034             sorted_attrlist = localptr;
3035             sorted_tail = sorted_attrlist;
3036             localptr->ar_next = 0;
3037             continue;
3038         }
3039         sorted_tail->ar_next  = localptr;
3040         sorted_tail = localptr;
3041         localptr->ar_next = 0;
3042     }
3043     /*  Now replace the list with the same pointers
3044         but in order sorted by attribute. */
3045     die->di_attrs = sorted_attrlist;
3046     free(sortab);
3047     return DW_DLV_OK;
3048 }
3049 
3050 
3051 
3052 static int
_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3053 _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
3054     Dwarf_Signed *nbufs,
3055     Dwarf_Error * error)
3056 {
3057     int elfsectno_of_debug_info = 0;
3058     unsigned char *data = 0;
3059     int cu_header_size = 0;
3060     Dwarf_P_Abbrev curabbrev = 0;
3061     Dwarf_P_Abbrev abbrev_head = 0;
3062     Dwarf_P_Abbrev abbrev_tail = 0;
3063     Dwarf_P_Die curdie = 0;
3064     Dwarf_P_Die first_child = 0;
3065     Dwarf_Unsigned dw = 0;
3066     Dwarf_Unsigned du = 0;
3067     Dwarf_Half dh = 0;
3068     Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */
3069     int n_abbrevs = 0;
3070     unsigned  abbrev_offset = 0;
3071     int res = 0;
3072     unsigned marker_count = 0;
3073     unsigned string_attr_count = 0;
3074     unsigned string_attr_offset = 0;
3075     Dwarf_Small *abbr_off_ptr = 0;
3076 
3077     int offset_size = dbg->de_dwarf_offset_size;
3078     /*  extension_size is oddly names. The standard calls
3079         for a 64bit offset to have a 4 byte 0xffff
3080         while original IRIX64 did not.
3081         So if dbg->de_64bit_extension set this is a standard
3082         DWARF 64bit offset and if de_64bit_extension not set
3083         this is non-standard IRIX64 64 bit offset. */
3084     Dwarf_Half version = dbg->de_output_version;
3085     int extension_size = dbg->de_64bit_extension ? 4 : 0;
3086 
3087     /* For now just assume DW_UT_compile FIXME */
3088     Dwarf_Ubyte unit_type = DW_UT_compile;
3089     Dwarf_Ubyte address_size = 0;
3090 
3091     elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
3092     address_size = dbg->de_pointer_size;
3093     if (version  < 5) {
3094         res = generate_debuginfo_header_2(dbg,
3095             &abbrev_offset,
3096             &data,
3097             &cu_header_size,
3098             &abbr_off_ptr,
3099             version,  extension_size, address_size,
3100             error);
3101         if (res != DW_DLV_OK) {
3102             return res;
3103         }
3104     } else if (version == 5) {
3105         res = generate_debuginfo_header_5(dbg,
3106             &abbrev_offset,
3107             &data,
3108             &cu_header_size,
3109             &abbr_off_ptr,
3110             version, unit_type, extension_size, address_size,
3111             error);
3112         if (res != DW_DLV_OK) {
3113             return res;
3114         }
3115     } else {
3116         DWARF_P_DBG_ERROR(dbg, DW_DLE_VERSION_STAMP_ERROR,
3117             DW_DLV_ERROR);
3118     }
3119 
3120     curdie = dbg->de_dies;
3121 
3122     /*  Create AT_macro_info if appropriate */
3123     if( version < 5) {
3124         if (dbg->de_first_macinfo != NULL) {
3125             res = _dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error);
3126             if (res != DW_DLV_OK) {
3127                 return res;
3128             }
3129         }
3130     } else {
3131         /* FIXME need to add code to emit DWARF5 macro data. */
3132 #if 0
3133             res = _dwarf_pro_add_AT_macro5_info(dbg, curdie, 0, error);
3134 #endif
3135     }
3136 
3137     /* Create AT_stmt_list attribute if necessary */
3138     if (dwarf_need_debug_line_section(dbg) == TRUE) {
3139         res =_dwarf_pro_add_AT_stmt_list(dbg, curdie, error);
3140         if (res != DW_DLV_OK) {
3141             return res;
3142         }
3143     }
3144     die_off = cu_header_size;
3145 
3146     /*  Relocation for abbrev offset in cu header store relocation
3147         record in linked list */
3148     res = dbg->de_relocate_by_name_symbol(dbg,
3149         DEBUG_INFO,
3150         abbrev_offset /* r_offset */,
3151         dbg->de_sect_name_idx[DEBUG_ABBREV],
3152         dwarf_drt_data_reloc, offset_size);
3153     if (res != DW_DLV_OK) {
3154         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3155     }
3156 
3157     /*  Pass 0: only top level dies, add at_sibling attribute to those
3158         dies with children, but if and only if
3159         there is no sibling attribute already. */
3160     first_child = curdie->di_child;
3161     while (first_child && first_child->di_right) {
3162         if (first_child->di_child) {
3163             if (!has_sibling_die_already(first_child)) {
3164                 dwarf_add_AT_reference(dbg,
3165                     first_child,
3166                     DW_AT_sibling,
3167                     first_child->di_right, error);
3168             }
3169         }
3170         first_child = first_child->di_right;
3171     }
3172 
3173     /* Pass 1: create abbrev info, get die offsets, calc relocations */
3174     abbrev_head = abbrev_tail = NULL;
3175     marker_count = 0;
3176     string_attr_count = 0;
3177     while (curdie != NULL) {
3178         int nbytes = 0;
3179         Dwarf_P_Attribute curattr = 0;
3180         char *space = 0;
3181         int cres = 0;
3182         char buff1[ENCODE_SPACE_NEEDED];
3183 
3184         curdie->di_offset = die_off;
3185 
3186         if (curdie->di_marker != 0) {
3187             marker_count++;
3188         }
3189         cres  =sort_die_attrs(dbg,curdie,error);
3190         if (cres != DW_DLV_OK) {
3191             /* DW_DLV_NO_ENTRY is impossible. */
3192             return cres;
3193         }
3194         /*  Find or create a final abbrev record for the
3195             debug_abbrev section we will write (below). */
3196         cres  = _dwarf_pro_getabbrev(dbg,curdie, abbrev_head,&curabbrev,
3197             error);
3198         if (cres != DW_DLV_OK) {
3199             return cres;
3200         }
3201         if (abbrev_head == NULL) {
3202             n_abbrevs = 1;
3203             curabbrev->abb_idx = n_abbrevs;
3204             abbrev_tail = abbrev_head = curabbrev;
3205         } else {
3206             /* Check if it is a new abbreviation, if yes, add to tail */
3207             if (curabbrev->abb_idx == 0) {
3208                 n_abbrevs++;
3209                 curabbrev->abb_idx = n_abbrevs;
3210                 abbrev_tail->abb_next = curabbrev;
3211                 abbrev_tail = curabbrev;
3212             }
3213         }
3214         /*  We know the abbrev number to use now.
3215             So create the bytes of the leb with the
3216             value and save those bytes in di_abbrev,
3217             we will emit in Pass 2 (below). */
3218         cres = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
3219             &nbytes,
3220             buff1, sizeof(buff1));
3221         if (cres != DW_DLV_OK) {
3222             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3223         }
3224         space = _dwarf_p_get_alloc(dbg, nbytes);
3225         if (space == NULL) {
3226             DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, DW_DLV_ERROR);
3227         }
3228         memcpy(space, buff1, nbytes);
3229         curdie->di_abbrev = space;
3230         curdie->di_abbrev_nbytes = nbytes;
3231         die_off += nbytes;
3232 
3233         /*  The abbrev and DIE attr lists match, so the die
3234             abbrevs are in the correct order,
3235             curdie->di_attrs.  */
3236 
3237         /*  Now we attach the attributes list to the die. */
3238         curattr = curdie->di_attrs;
3239 
3240         while (curattr) {
3241             if (curattr->ar_rel_type != R_MIPS_NONE) {
3242                 int rres=0;
3243                 switch (curattr->ar_attribute) {
3244                 case DW_AT_stmt_list:
3245                     curattr->ar_rel_symidx =
3246                         dbg->de_sect_name_idx[DEBUG_LINE];
3247                     break;
3248                 case DW_AT_MIPS_fde:
3249                     curattr->ar_rel_symidx =
3250                         dbg->de_sect_name_idx[DEBUG_FRAME];
3251                     break;
3252                 case DW_AT_macro_info:
3253                     curattr->ar_rel_symidx =
3254                         dbg->de_sect_name_idx[DEBUG_MACINFO];
3255                     break;
3256                 /* See also: pro_forms.c for same strings attribute list. */
3257                 case DW_AT_comp_dir:
3258                 case DW_AT_const_value:
3259                 case DW_AT_linkage_name: /* DWARF5 */
3260                 case DW_AT_MIPS_abstract_name:
3261                 case DW_AT_MIPS_linkage_name:
3262                 case DW_AT_name:
3263                 case DW_AT_producer: {
3264                     int is_debug_str = 0;
3265                     int nres = if_relocatable_string_form(dbg,curattr,
3266                         &is_debug_str,error);
3267                     if (nres != DW_DLV_OK) {
3268                         return res;
3269                     }
3270                     if (is_debug_str) {
3271                         curattr->ar_rel_symidx =
3272                             dbg->de_sect_name_idx[DEBUG_STR];
3273                     }
3274                     }
3275                     break;
3276                 default:
3277                     break;
3278                 }
3279                 rres = dbg->de_relocate_by_name_symbol(dbg,
3280                     DEBUG_INFO,
3281                     die_off + curattr->ar_rel_offset,/* r_offset */
3282                     curattr->ar_rel_symidx,
3283                     dwarf_drt_data_reloc,
3284                     curattr->ar_reloc_len);
3285 
3286                 if (rres != DW_DLV_OK) {
3287                     DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3288                 }
3289             }
3290             if (curattr->ar_attribute_form == DW_FORM_string) {
3291                 string_attr_count++;
3292             }
3293             die_off += curattr->ar_nbytes;
3294             curattr = curattr->ar_next;
3295         }
3296         /* Depth first access to all the DIEs. */
3297         if (curdie->di_child) {
3298             curdie = curdie->di_child;
3299         } else {
3300             while (curdie != NULL && curdie->di_right == NULL) {
3301                 curdie = curdie->di_parent;
3302                 /* See -nonrootsibling- below */
3303                 if (curdie != NULL) {
3304                     die_off++;
3305                 }
3306             }
3307             if (curdie != NULL) {
3308                 curdie = curdie->di_right;
3309             }
3310         }
3311 
3312     } /* end while (curdie != NULL), the per-die loop */
3313 
3314     res = marker_init(dbg, marker_count);
3315     if (res == DW_DLV_ERROR) {
3316         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3317     }
3318     res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
3319     if (res != DW_DLV_OK) {
3320         DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3321     }
3322 
3323     /*  Pass 2: Write out the die information Here 'data' is a
3324         temporary, one block for each GET_CHUNK.  'data' is overused. */
3325     curdie = dbg->de_dies;
3326     while (curdie != NULL) {
3327         Dwarf_P_Attribute curattr;
3328 
3329         if (curdie->di_marker != 0) {
3330             res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
3331             if (res == DW_DLV_ERROR) {
3332                 DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
3333             }
3334         }
3335 
3336         /* Index to abbreviation table */
3337         GET_CHUNK_ERR(dbg, elfsectno_of_debug_info,
3338             data, curdie->di_abbrev_nbytes, error);
3339         memcpy((void *) data,
3340             (const void *) curdie->di_abbrev,
3341             curdie->di_abbrev_nbytes);
3342 
3343         /* Attribute values - need to fill in all form attributes */
3344         curattr = curdie->di_attrs;
3345         string_attr_offset = curdie->di_offset +
3346             curdie->di_abbrev_nbytes;
3347         while (curattr) {
3348             GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data,
3349                 (unsigned long) curattr->ar_nbytes, error);
3350             switch (curattr->ar_attribute_form) {
3351             case DW_FORM_ref1:
3352                 {
3353                     Dwarf_Ubyte db = 0;
3354                     if (curattr->ar_ref_die->di_offset >
3355                         (unsigned) 0xff) {
3356                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
3357                     }
3358                     db = curattr->ar_ref_die->di_offset;
3359                     WRITE_UNALIGNED(dbg, (void *) data,
3360                         (const void *) &db,
3361                         sizeof(db), sizeof(Dwarf_Ubyte));
3362                     break;
3363                 }
3364             case DW_FORM_ref2:
3365                 {
3366                     if (curattr->ar_ref_die->di_offset >
3367                         (unsigned) 0xffff) {
3368                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, DW_DLV_ERROR);
3369                     }
3370                     dh = curattr->ar_ref_die->di_offset;
3371                     WRITE_UNALIGNED(dbg, (void *) data,
3372                         (const void *) &dh,
3373                         sizeof(dh), DWARF_HALF_SIZE);
3374                     break;
3375                 }
3376             case DW_FORM_ref_addr:
3377                 {
3378                     /*  curattr->ar_ref_die == NULL!
3379 
3380                         DW_FORM_ref_addr doesn't take a CU-offset.
3381                         This is different than other refs.
3382                         This value will be set by the user of the
3383                         producer library using a relocation.
3384                         No need to set a value here.  */
3385                     break;
3386 
3387                 }
3388             case DW_FORM_ref4:
3389                 {
3390                     if (curattr->ar_ref_die->di_offset >
3391                         (unsigned) 0xffffffff) {
3392                         DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW,
3393                             DW_DLV_ERROR);
3394                     }
3395                     dw = (Dwarf_Unsigned) curattr->ar_ref_die->di_offset;
3396                     WRITE_UNALIGNED(dbg, (void *) data,
3397                         (const void *) &dw,
3398                         sizeof(dw), DWARF_32BIT_SIZE);
3399                     break;
3400                 }
3401             case DW_FORM_ref8:
3402                 du = curattr->ar_ref_die->di_offset;
3403                 WRITE_UNALIGNED(dbg, (void *) data,
3404                     (const void *) &du,
3405                     sizeof(du), DWARF_64BIT_SIZE);
3406                 break;
3407             case DW_FORM_ref_udata:
3408                 {   /* unsigned leb128 offset */
3409 
3410                     int nbytesx;
3411                     char buff1[ENCODE_SPACE_NEEDED];
3412 
3413                     res =
3414                         _dwarf_pro_encode_leb128_nm(curattr->
3415                             ar_ref_die->
3416                             di_offset, &nbytesx,
3417                             buff1,
3418                             sizeof(buff1));
3419                     if (res != DW_DLV_OK) {
3420                         DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC,
3421                             DW_DLV_ERROR);
3422                     }
3423                     memcpy(data, buff1, nbytesx);
3424                     break;
3425                 }
3426             default:
3427                 if(curattr->ar_nbytes) {
3428                     memcpy((void *) data,
3429                         (const void *) curattr->ar_data,
3430                         curattr->ar_nbytes);
3431                 }
3432                 break;
3433             }
3434             if (curattr->ar_attribute_form == DW_FORM_string) {
3435                 string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
3436             }
3437             string_attr_offset += curattr->ar_nbytes;
3438             curattr = curattr->ar_next;
3439         }
3440 
3441         /* depth first search */
3442         if (curdie->di_child) {
3443             curdie = curdie->di_child;
3444         } else {
3445             while (curdie != NULL && curdie->di_right == NULL) {
3446                 /*  -nonrootsibling-
3447                     A null die should only be written for terminating
3448                     siblings, not the root.  Adding a terminating die
3449                     for the root will cause, after object files are
3450                     linked, warnings to be generated with newer
3451                     versions of readelf. */
3452                 if (!curdie->di_parent) {
3453                     /*  The parent is not a DIE so ending a sibling
3454                         chain makes no sense (wastes a byte). */
3455                     break;
3456                 }
3457                 GET_CHUNK_ERR(dbg, elfsectno_of_debug_info, data, 1, error);
3458                 *data = '\0';
3459                 curdie = curdie->di_parent;
3460             }
3461             if (curdie != NULL)
3462                 curdie = curdie->di_right;
3463         }
3464     } /* end while (curdir != NULL) */
3465 
3466     /*  Write out debug_info size, now that we know it
3467         This is back-patching the CU header we created
3468         above. */
3469     du = die_off - OFFSET_PLUS_EXTENSION_SIZE;
3470     WRITE_UNALIGNED(dbg, (void *) abbr_off_ptr,
3471         (const void *) &du, sizeof(du), offset_size);
3472 
3473 
3474     data = 0;                   /* Emphasise not usable now */
3475 
3476     res = write_out_debug_abbrev(dbg,
3477         abbrev_head, error);
3478     if (res != DW_DLV_OK) {
3479         return res;
3480     }
3481 
3482     *nbufs =  dbg->de_n_debug_sect;
3483     return DW_DLV_OK;
3484 }
3485 
3486 static int
_dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed * nbufs,Dwarf_Error * error UNUSEDARG)3487 _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,
3488     UNUSEDARG Dwarf_Signed *nbufs,
3489     Dwarf_Error * error UNUSEDARG)
3490 {
3491 #if 0
3492     int elfsectno_of_debug_names =  dbg->de_elf_sects[DEBUG_NAMES];
3493     FIXME: Needs implementation
3494     unsigned char *data = 0;
3495 
3496     GET_CHUNK(dbg, elfsectno_of_debug_names, data,
3497         dbg->de_debug_names->ds_nbytes,
3498         error);
3499     memcpy(data,dbg->de_debug_names->ds_data,dbg->de_debug_names->ds_nbytes);
3500 #endif
3501     *nbufs = dbg->de_n_debug_sect;
3502     return DW_DLV_OK;
3503 }
3504 
3505 static int
_dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3506 _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,
3507     Dwarf_Signed *nbufs,
3508     Dwarf_Error * error)
3509 {
3510     int elfsectno_of_debug_str = 0;
3511     unsigned char *data = 0;
3512 
3513     elfsectno_of_debug_str = dbg->de_elf_sects[DEBUG_STR];
3514     GET_CHUNK(dbg, elfsectno_of_debug_str, data, dbg->de_debug_str->ds_nbytes,
3515         error);
3516     memcpy(data,dbg->de_debug_str->ds_data,dbg->de_debug_str->ds_nbytes);
3517     *nbufs = dbg->de_n_debug_sect;
3518     return DW_DLV_OK;
3519 }
3520 static int
_dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)3521 _dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,
3522     Dwarf_Signed *nbufs,
3523     Dwarf_Error * error)
3524 {
3525     int elfsectno_of_debug_line_str = 0;
3526     unsigned char *data = 0;
3527 
3528     elfsectno_of_debug_line_str = dbg->de_elf_sects[DEBUG_LINE_STR];
3529     GET_CHUNK(dbg, elfsectno_of_debug_line_str, data,
3530         dbg->de_debug_line_str->ds_nbytes,
3531         error);
3532     memcpy(data,dbg->de_debug_line_str->ds_data,
3533         dbg->de_debug_line_str->ds_nbytes);
3534     *nbufs = dbg->de_n_debug_sect;
3535     return DW_DLV_OK;
3536 }
3537 
3538 
3539 /*  Get a buffer of section data.
3540     section_idx is the elf-section number that this data applies to.
3541     length shows length of returned data
3542     This is the original format. Hard to check for error. */
3543 
3544 /*ARGSUSED*/                   /* pretend all args used */
3545 Dwarf_Ptr
dwarf_get_section_bytes(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Error * error)3546 dwarf_get_section_bytes(Dwarf_P_Debug dbg,
3547     UNUSEDARG Dwarf_Signed dwarf_section,
3548     Dwarf_Signed * section_idx,
3549     Dwarf_Unsigned * length, Dwarf_Error * error)
3550 {
3551     Dwarf_Ptr s_bytes = 0;
3552     int res = 0;
3553 
3554     res = dwarf_get_section_bytes_a(dbg,
3555         dwarf_section,
3556         section_idx,
3557         length,
3558         &s_bytes,
3559         error);
3560     if (res == DW_DLV_ERROR) {
3561         return (Dwarf_Ptr)DW_DLV_BADADDR;
3562     }
3563     if (res == DW_DLV_NO_ENTRY) {
3564         return NULL;
3565     }
3566     return s_bytes;
3567 }
3568 
3569 /*  Get a buffer of section data.
3570     section_idx is the elf-section number that this data applies to.
3571     length shows length of returned data
3572     This is the September 2016 format. Preferred. */
3573 int
dwarf_get_section_bytes_a(Dwarf_P_Debug dbg,UNUSEDARG Dwarf_Signed dwarf_section,Dwarf_Signed * section_idx,Dwarf_Unsigned * length,Dwarf_Ptr * section_bytes,Dwarf_Error * error)3574 dwarf_get_section_bytes_a(Dwarf_P_Debug dbg,
3575     UNUSEDARG Dwarf_Signed dwarf_section,
3576     Dwarf_Signed   * section_idx,
3577     Dwarf_Unsigned * length,
3578     Dwarf_Ptr      * section_bytes,
3579     Dwarf_Error * error)
3580 {
3581     Dwarf_Ptr buf = 0;
3582 
3583     if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
3584         DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_ERROR);
3585     }
3586     *section_bytes = 0;
3587     *length = 0;
3588     if (dbg->de_debug_sects == 0) {
3589         /* no more data !! */
3590         return DW_DLV_NO_ENTRY;
3591     }
3592     if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
3593         /* no data ever entered !! */
3594         return DW_DLV_NO_ENTRY;
3595     }
3596     *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
3597     *length = dbg->de_debug_sects->ds_nbytes;
3598 
3599     buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
3600 
3601     /*  Here is the iterator so the next call gets
3602         the next section. */
3603     dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
3604 
3605     /*  We may want to call the section stuff more than once: see
3606         dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
3607 
3608     *section_bytes = buf;
3609     return DW_DLV_OK;
3610 }
3611 
3612 /* No errors possible.  */
3613 void
dwarf_reset_section_bytes(Dwarf_P_Debug dbg)3614 dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
3615 {
3616     dbg->de_debug_sects = dbg->de_first_debug_sect;
3617     /*  No need to reset; commented out decrement. dbg->de_n_debug_sect
3618         = ???; */
3619     dbg->de_reloc_next_to_return = 0;
3620     dbg->de_sect_sa_next_to_return = 0;
3621 }
3622 
3623 /*  Storage handler. Gets either a new chunk of memory, or
3624     a pointer in existing memory, from the linked list attached
3625     to dbg at de_debug_sects, depending on size of nbytes
3626 
3627     Assume dbg not null, checked in top level routine
3628 
3629     Returns a pointer to the allocated buffer space for the
3630     lib to fill in,  predincrements next-to-use count so the
3631     space requested is already counted 'used'
3632     when this returns (ie, reserved).
3633 
3634 */
3635 Dwarf_Small *
_dwarf_pro_buffer(Dwarf_P_Debug dbg,int elfsectno,unsigned long nbytes)3636 _dwarf_pro_buffer(Dwarf_P_Debug dbg,
3637     int elfsectno, unsigned long nbytes)
3638 {
3639     Dwarf_P_Section_Data cursect = 0;
3640 
3641     cursect = dbg->de_current_active_section;
3642     /*  By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must
3643         not match any legit section number. test to have just two
3644         clauses (no NULL pointer test) See dwarf_producer_init(). */
3645     if ((cursect->ds_elf_sect_no != elfsectno) ||
3646         ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
3647         ) {
3648 
3649         /*  Either the elf section has changed or there is not enough
3650             space in the current section.
3651 
3652             Create a new Dwarf_P_Section_Data_s for the chunk. and have
3653             space 'on the end' for the buffer itself so we just do one
3654             malloc (not two).  */
3655         unsigned long space = nbytes;
3656 
3657         if (nbytes < CHUNK_SIZE)
3658             space = CHUNK_SIZE;
3659 
3660         cursect = (Dwarf_P_Section_Data)
3661             _dwarf_p_get_alloc(dbg,
3662                 sizeof(struct Dwarf_P_Section_Data_s)
3663                 + space);
3664         if (cursect == NULL) {
3665             return (NULL);
3666         }
3667 
3668         /* _dwarf_p_get_alloc zeroes the space... */
3669 
3670         cursect->ds_data = (char *) cursect +
3671             sizeof(struct Dwarf_P_Section_Data_s);
3672         cursect->ds_orig_alloc = space;
3673         cursect->ds_elf_sect_no = elfsectno;
3674         cursect->ds_nbytes = nbytes;    /* reserve this number of bytes
3675             of space for caller to fill in */
3676         /*  Now link on the end of the list, and mark this one as the
3677             current one */
3678 
3679         if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
3680             /*  The only entry is the special one for 'no entry' so
3681                 delete that phony one while adding this initial real
3682                 one. */
3683             dbg->de_debug_sects = cursect;
3684             dbg->de_current_active_section = cursect;
3685             dbg->de_first_debug_sect = cursect;
3686         } else {
3687             dbg->de_current_active_section->ds_next = cursect;
3688             dbg->de_current_active_section = cursect;
3689         }
3690         dbg->de_n_debug_sect++;
3691 
3692         return ((Dwarf_Small *) cursect->ds_data);
3693     }
3694 
3695     /* There is enough space in the current buffer */
3696     {
3697         Dwarf_Small *space_for_caller = (Dwarf_Small *)
3698             (cursect->ds_data + cursect->ds_nbytes);
3699 
3700         cursect->ds_nbytes += nbytes;
3701         return space_for_caller;
3702     }
3703 }
3704