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