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
116struct 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
125and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
126see pro_incl.h
127*/
128const 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*/
157const 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
184static 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
206typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
207struct Dwarf_P_Rel_s {
208    Dwarf_P_Rel dr_next;
209    void *dr_rel_datap;
210};
211typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
212struct Dwarf_P_Rel_Head_s {
213    struct Dwarf_P_Rel_s *drh_head;
214    struct Dwarf_P_Rel_s *drh_tail;
215};
216
217static int
218_dwarf_pro_generate_debug_line_str(Dwarf_P_Debug dbg,
219    Dwarf_Signed *nbufs, Dwarf_Error * error);
220static int _dwarf_pro_generate_debug_names(Dwarf_P_Debug dbg,
221    Dwarf_Signed *nbufs, Dwarf_Error * error);
222static int _dwarf_pro_generate_debug_str(Dwarf_P_Debug dbg,
223    Dwarf_Signed *nbufs, Dwarf_Error * error);
224static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
225    Dwarf_Signed *nbufs, Dwarf_Error * error);
226static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
227    Dwarf_Signed *nbufs, Dwarf_Error * error);
228static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
229    Dwarf_Signed *nbufs, Dwarf_Error * error);
230
231#if 0
232static void
233dump_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
247static void
248print_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}
265static void
266print_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*/
289static int
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*/
336static int
337dwarf_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. */
350static int
351dwarf_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*/
370Dwarf_Signed
371dwarf_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*/
388int
389dwarf_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
711static int
712write_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
727static int
728write_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}
744static int
745pretend_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
764static int
765write_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. */
789static int
790append_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
810static int
811write_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
833static unsigned
834write_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
856static int
857determine_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
908static int
909determine_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
1187static int
1188calculate_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 */
1272static int
1273calculate_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*/
1328static int
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  */
1931static int
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
2370static int
2371marker_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
2387static int
2388marker_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
2401Dwarf_Signed
2402dwarf_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
2417int
2418dwarf_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.  */
2440static int
2441string_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
2462static int
2463string_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
2479int
2480dwarf_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
2500int
2501dwarf_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
2524static int
2525has_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.  */
2538static int
2539if_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. */
2562static int
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
2594static int
2595verify_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
2616static int
2617abcompare(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. */
2645static int
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  */
2770static int
2771generate_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 */
2841static int
2842generate_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 */
2920static int
2921write_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
2990static int
2991sort_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
3052static int
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
3486static int
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
3505static int
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}
3520static int
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 */
3545Dwarf_Ptr
3546dwarf_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. */
3573int
3574dwarf_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.  */
3613void
3614dwarf_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*/
3635Dwarf_Small *
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