xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_forms.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1 /*
2   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
4   Portions Copyright 2007-2013 David Anderson. All rights reserved.
5   Portions Copyright 2012 SN Systems Ltd. All rights reserved.
6 
7   This program is free software; you can redistribute it and/or modify it
8   under the terms of version 2.1 of the GNU Lesser General Public License
9   as published by the Free Software Foundation.
10 
11   This program is distributed in the hope that it would be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15   Further, this software is distributed without any warranty that it is
16   free of the rightful claim of any third person regarding infringement
17   or the like.  Any license provided herein, whether implied or
18   otherwise, applies only to this software file.  Patent licenses, if
19   any, provided herein do not apply to combinations of this program with
20   other software, or any other product whatsoever.
21 
22   You should have received a copy of the GNU Lesser General Public
23   License along with this program; if not, write the Free Software
24   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25   USA.
26 
27 */
28 
29 #include "config.h"
30 #include "libdwarfdefs.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include <limits.h>
34 #include "pro_incl.h"
35 #include <stddef.h>
36 #include "dwarf.h"
37 #include "libdwarf.h"
38 #include "pro_opaque.h"
39 #include "pro_error.h"
40 #include "pro_encode_nm.h"
41 #include "pro_alloc.h"
42 #include "pro_die.h"
43 #include "pro_expr.h"
44 
45 #ifndef R_MIPS_NONE
46 #define R_MIPS_NONE 0
47 #endif
48 
49 
50 /* Indicates no relocation needed. */
51 #define NO_ELF_SYM_INDEX        0
52 
53 
54 #ifdef WORDS_BIGENDIAN
55 #define ASNAR(t,s,l)                   \
56     do {                                    \
57         unsigned tbyte = sizeof(t) - l;     \
58         t = 0;                              \
59         dbg->de_copy_word(((char *)&t)+tbyte ,&s[0],l);\
60     } while (0)
61 #else /* LITTLE ENDIAN */
62 #define ASNAR(t,s,l)                 \
63     do {                                \
64         t = 0;                          \
65         dbg->de_copy_word(&t,&s[0],l);             \
66     } while (0)
67 #endif /* end LITTLE- BIG-ENDIAN */
68 
69 
70 #ifdef WORDS_BIGENDIAN
71 #define ASNOUT(t,s,l)                       \
72     do {                                    \
73         unsigned sbyte = 0;                 \
74         char *p = 0;                        \
75         if (l > sizeof(s)) {                \
76             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
77             return DW_DLV_ERROR;            \
78         }                                   \
79         sbyte = sizeof(s) - l;              \
80         p = (const char *)(&s);             \
81         dbg->de_copy_word(t,(const void *)(p+sbyte),l);\
82     } while (0)
83 #else /* LITTLEENDIAN */
84 #define ASNOUT(t,s,l)                       \
85     do {                                    \
86         const char *p = 0;                  \
87         if (l > sizeof(s)) {                \
88             _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\
89             return DW_DLV_ERROR;            \
90         }                                   \
91         p = (const char *)(&s);             \
92         memcpy(t,(const void *)p,l);        \
93         dbg->de_copy_word(t,(const void *)p,l); \
94     } while (0)
95 #endif /* ENDIANNESS */
96 
97 #ifdef WORDS_BIGENDIAN
98 #define SIGN_EXTEND(dest, length)                                 \
99     do {                                                          \
100         if (*(Dwarf_Sbyte *)((char *)&dest +                      \
101             sizeof(dest) - length) < 0) {                         \
102             memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff",\
103                 sizeof(dest) - length);                           \
104         }                                                         \
105     } while (0)
106 #else /* LITTLE ENDIAN */
107 #define SIGN_EXTEND(dest, length)                               \
108     do {                                                        \
109         if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) { \
110             memcpy((char *)&dest+length,                        \
111                 "\xff\xff\xff\xff\xff\xff\xff\xff",             \
112                 sizeof(dest) - length);                         \
113         }                                                       \
114     } while (0)
115 
116 #endif /* ! LITTLE_ENDIAN */
117 
118 
119 /*  This function adds an attribute whose value is
120     a target address to the given die.  The attribute
121     is given the name provided by attr.  The address
122     is given in pc_value.  */
123 
124 static int
125 local_add_AT_address_a(Dwarf_P_Debug dbg,
126     Dwarf_P_Die ownerdie,
127     Dwarf_Half attr,
128     Dwarf_Signed form,
129     Dwarf_Unsigned pc_value,
130     Dwarf_Unsigned sym_index,
131     Dwarf_P_Attribute *attr_out,
132     Dwarf_Error * error);
133 
134 /* old interface */
135 Dwarf_P_Attribute
dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Signed sym_index,Dwarf_Error * error)136 dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
137     Dwarf_P_Die ownerdie,
138     Dwarf_Half attr,
139     Dwarf_Unsigned pc_value,
140     Dwarf_Signed sym_index, Dwarf_Error * error)
141 {
142     Dwarf_P_Attribute a = 0;
143     int res = 0;
144 
145     if (sym_index < 0) {
146         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
147     }
148     res =   dwarf_add_AT_targ_address_c(dbg,
149         ownerdie, attr, pc_value,
150         (Dwarf_Unsigned) sym_index,
151         &a,
152         error);
153     if (res != DW_DLV_OK) {
154         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
155     }
156     return a;
157 
158 }
159 
160 /*  New interface, replacing dwarf_add_AT_targ_address.
161     Essentially just makes sym_index a Dwarf_Unsigned
162     so for symbolic relocations it can be a full address.  */
163 Dwarf_P_Attribute
dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)164 dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
165     Dwarf_P_Die ownerdie,
166     Dwarf_Half attr,
167     Dwarf_Unsigned pc_value,
168     Dwarf_Unsigned sym_index,
169     Dwarf_Error * error)
170 {
171     Dwarf_P_Attribute a = 0;
172     int res = 0;
173 
174     res = dwarf_add_AT_targ_address_c(dbg,
175         ownerdie,attr,pc_value,sym_index,
176         &a, error);
177     if (res != DW_DLV_OK) {
178         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
179     }
180     return a;
181 
182 }
183 int
dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)184 dwarf_add_AT_targ_address_c(Dwarf_P_Debug dbg,
185     Dwarf_P_Die ownerdie,
186     Dwarf_Half attr,
187     Dwarf_Unsigned pc_value,
188     Dwarf_Unsigned sym_index,
189     Dwarf_P_Attribute *attr_out,
190     Dwarf_Error * error)
191 {
192     int res = 0;
193 
194     switch (attr) {
195     case DW_AT_low_pc:
196     case DW_AT_high_pc:
197 
198     /* added to support location lists */
199     /* no way to check that this is a loclist-style address though */
200     case DW_AT_location:
201     case DW_AT_string_length:
202     case DW_AT_return_addr:
203     case DW_AT_frame_base:
204     case DW_AT_segment:
205     case DW_AT_static_link:
206     case DW_AT_use_location:
207     case DW_AT_vtable_elem_location:
208     case DW_AT_const_value: /* Gcc can generate this as address. */
209     case DW_AT_entry_pc:
210         break;
211     default:
212         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
213             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
214             return DW_DLV_ERROR;
215         }
216         break;
217     }
218 
219     res = local_add_AT_address_a(dbg, ownerdie, attr, DW_FORM_addr,
220         pc_value, sym_index,attr_out, error);
221     return res;
222 }
223 
224 Dwarf_P_Attribute
dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)225 dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
226     Dwarf_P_Die ownerdie,
227     Dwarf_Half attr,
228     Dwarf_Unsigned pc_value,
229     Dwarf_Unsigned sym_index,
230     Dwarf_Error * error)
231 {
232     Dwarf_P_Attribute a = 0;
233     int res = 0;
234 
235     res = dwarf_add_AT_ref_address_a(dbg,ownerdie,
236         attr,pc_value,sym_index,&a,error);
237     if (res != DW_DLV_OK) {
238         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
239     }
240     return a;
241 }
242 
243 int
dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)244 dwarf_add_AT_ref_address_a(Dwarf_P_Debug dbg,
245     Dwarf_P_Die ownerdie,
246     Dwarf_Half attr,
247     Dwarf_Unsigned pc_value,
248     Dwarf_Unsigned sym_index,
249     Dwarf_P_Attribute *attr_out,
250     Dwarf_Error * error)
251 {
252     int res = 0;
253 
254     switch (attr) {
255     case DW_AT_type:
256     case DW_AT_import:
257         break;
258 
259     default:
260         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
261             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
262             return DW_DLV_ERROR;
263         }
264         break;
265     }
266 
267     /*  FIXME: For DWARF3 and later this call is problematic as
268         DW_FORM_ref_addr is really an offset in
269         .debug_info , not an address.  */
270     res = local_add_AT_address_a(dbg, ownerdie,
271         attr, DW_FORM_ref_addr,
272         pc_value, sym_index,attr_out, error);
273     return res;
274 }
275 
276 
277 /* Make sure attribute types are checked before entering here. */
278 static int
local_add_AT_address_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed form,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)279 local_add_AT_address_a(Dwarf_P_Debug dbg,
280     Dwarf_P_Die ownerdie,
281     Dwarf_Half attr,
282     Dwarf_Signed form,
283     Dwarf_Unsigned pc_value,
284     Dwarf_Unsigned sym_index,
285     Dwarf_P_Attribute *attr_out,
286     Dwarf_Error * error)
287 {
288     Dwarf_P_Attribute new_attr;
289     int upointer_size = 0;
290 
291     if (dbg == NULL) {
292         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
293         return DW_DLV_ERROR;
294     }
295     upointer_size = dbg->de_pointer_size;
296 
297     if (ownerdie == NULL) {
298         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
299         return DW_DLV_ERROR;
300     }
301 
302     /* attribute types have already been checked */
303     /* switch (attr) { ... } */
304 
305     new_attr = (Dwarf_P_Attribute)
306         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
307     if (new_attr == NULL) {
308         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
309         return DW_DLV_ERROR;
310     }
311 
312     new_attr->ar_attribute = attr;
313     new_attr->ar_attribute_form = form;
314     new_attr->ar_nbytes = upointer_size;
315     new_attr->ar_rel_symidx = sym_index;
316     new_attr->ar_reloc_len = upointer_size;
317     new_attr->ar_next = 0;
318     if (sym_index != NO_ELF_SYM_INDEX) {
319         new_attr->ar_rel_type = dbg->de_ptr_reloc;
320     } else {
321         new_attr->ar_rel_type = R_MIPS_NONE;
322     }
323 
324     new_attr->ar_data = (char *)
325         _dwarf_p_get_alloc(dbg, upointer_size);
326     if (new_attr->ar_data == NULL) {
327         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
328         return DW_DLV_ERROR;
329     }
330     WRITE_UNALIGNED(dbg, new_attr->ar_data,
331         (const void *) &pc_value,
332         sizeof(pc_value), upointer_size);
333 
334     /* add attribute to the die */
335     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
336     *attr_out = new_attr;
337     return DW_DLV_OK;
338 }
339 
340 /*  Pass in array (ie a pointer to) of Dwarf_Signed
341     with input_array_length elements.
342 
343     A block of bytes is created
344     with the sleb data in it.
345 
346     A pointer to the glob of bytes is returned
347     through the output_block pointer and its length
348     through output_block_len pointer. */
349 int
dwarf_compress_integer_block_a(Dwarf_P_Debug dbg,Dwarf_Unsigned input_array_length,Dwarf_Signed * input_array,Dwarf_Unsigned * output_block_len,void ** output_block_returned,Dwarf_Error * error)350 dwarf_compress_integer_block_a(
351     Dwarf_P_Debug    dbg,
352     Dwarf_Unsigned  input_array_length,
353     Dwarf_Signed *  input_array,
354     Dwarf_Unsigned *output_block_len,
355     void         ** output_block_returned,
356     Dwarf_Error*     error
357 )
358 {
359     Dwarf_Unsigned output_length_in_bytes = 0;
360     char * output_block = 0;
361     char encode_buffer[ENCODE_SPACE_NEEDED];
362     unsigned u = 0;
363     char * ptr = 0;
364     int remain = 0;
365     int result = 0;
366 
367     if (dbg == NULL) {
368         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
369         return DW_DLV_ERROR;
370     }
371     /* First compress everything to find the total size. */
372 
373     output_length_in_bytes = 0;
374     for (u=0; u<input_array_length; u++) {
375         int unit_encoded_size;
376         Dwarf_Signed unit = 0;
377 
378         unit = input_array[u];
379         result = _dwarf_pro_encode_signed_leb128_nm(
380             unit, &unit_encoded_size,
381             encode_buffer,sizeof(encode_buffer));
382         if (result !=  DW_DLV_OK) {
383             _dwarf_p_error(NULL, error, DW_DLE_LEB_IMPROPER);
384             return DW_DLV_ERROR;
385         }
386         output_length_in_bytes += unit_encoded_size;
387     }
388     output_block = (void *)
389         _dwarf_p_get_alloc(dbg, output_length_in_bytes);
390     if (output_block == NULL) {
391         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
392         return DW_DLV_ERROR;
393     }
394 
395     /* Then compress again and copy into new buffer */
396     ptr = output_block;
397     remain = output_length_in_bytes;
398     for (u=0; u<input_array_length; u++) {
399         int unit_encoded_size;
400         Dwarf_Signed unit = 0;
401 
402         unit = input_array[u];
403         result = _dwarf_pro_encode_signed_leb128_nm(unit,
404             &unit_encoded_size,
405             ptr, remain);
406         if (result !=  DW_DLV_OK) {
407             _dwarf_p_error(NULL, error, DW_DLE_LEB_IMPROPER);
408             return DW_DLV_ERROR;
409         }
410         remain -= unit_encoded_size;
411         ptr += unit_encoded_size;
412     }
413 
414     *output_block_len = output_length_in_bytes;
415     *output_block_returned = output_block;
416     return DW_DLV_OK;
417 }
418 /*  Functions to compress and uncompress data from normal
419     arrays of integral types into arrays of LEB128 numbers.
420     Extend these functions as needed to handle wider input
421     variety.  Return values should be freed with _dwarf_p_dealloc
422     after they aren't needed any more.
423 
424     It is not clear there is any use to this function
425     as it was contributed by SUN but may not have ever
426     been needed in any released SUN compiler. */
427 
428 /* return value points to an array of LEB numbers */
429 
430 void *
dwarf_compress_integer_block(Dwarf_P_Debug dbg,Dwarf_Bool unit_is_signed,Dwarf_Small unit_length_in_bits,void * input_block,Dwarf_Unsigned input_length_in_units,Dwarf_Unsigned * output_length_in_bytes_ptr,Dwarf_Error * error)431 dwarf_compress_integer_block(
432     Dwarf_P_Debug    dbg,
433     Dwarf_Bool       unit_is_signed,
434     Dwarf_Small      unit_length_in_bits,
435     void*            input_block,
436     Dwarf_Unsigned   input_length_in_units,
437     Dwarf_Unsigned*  output_length_in_bytes_ptr,
438     Dwarf_Error*     error
439 )
440 {
441     Dwarf_Unsigned output_length_in_bytes = 0;
442     char * output_block = 0;
443     char encode_buffer[ENCODE_SPACE_NEEDED];
444     unsigned u = 0;
445     char * ptr = 0;
446     int remain = 0;
447     int result = 0;
448     char *inptr = 0;
449 
450     if (dbg == NULL) {
451         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
452         return((void *)DW_DLV_BADADDR);
453     }
454 
455     if (unit_is_signed == false ||
456         unit_length_in_bits != 32 ||
457         input_block == NULL ||
458         input_length_in_units == 0 ||
459         output_length_in_bytes_ptr == NULL) {
460         _dwarf_p_error(NULL, error, DW_DLE_BADBITC);
461         return ((void *) DW_DLV_BADADDR);
462     }
463 
464     /* At this point we assume the format is: signed 32 bit */
465 
466     /* First compress everything to find the total size. */
467 
468     output_length_in_bytes = 0;
469     inptr = input_block;
470     for (u=0; u<input_length_in_units; u++) {
471         int unit_encoded_size;
472         Dwarf_Signed unit = 0;
473 
474         ASNAR(unit,inptr,DWARF_32BIT_SIZE);
475         SIGN_EXTEND(unit,DWARF_32BIT_SIZE);
476         result = _dwarf_pro_encode_signed_leb128_nm(
477             unit, &unit_encoded_size,
478             encode_buffer,sizeof(encode_buffer));
479         if (result !=  DW_DLV_OK) {
480             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
481             return((Dwarf_P_Attribute)DW_DLV_BADADDR);
482         }
483         output_length_in_bytes += unit_encoded_size;
484         inptr += DWARF_32BIT_SIZE;
485     }
486 
487     /* Then alloc */
488     output_block = (void *)
489         _dwarf_p_get_alloc(dbg, output_length_in_bytes);
490     if (output_block == NULL) {
491         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
492         return((void*)DW_DLV_BADADDR);
493     }
494 
495     /* Then compress again and copy into new buffer */
496     ptr = output_block;
497     inptr = input_block;
498     remain = output_length_in_bytes;
499     for (u=0; u<input_length_in_units; u++) {
500         int unit_encoded_size;
501         Dwarf_Signed unit = 0;
502 
503         ASNAR(unit,inptr,DWARF_32BIT_SIZE);
504         SIGN_EXTEND(unit,DWARF_32BIT_SIZE);
505         result = _dwarf_pro_encode_signed_leb128_nm(unit,
506             &unit_encoded_size,
507             ptr, remain);
508         if (result !=  DW_DLV_OK) {
509             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
510             return((Dwarf_P_Attribute)DW_DLV_BADADDR);
511         }
512         remain -= unit_encoded_size;
513         ptr += unit_encoded_size;
514         inptr += DWARF_32BIT_SIZE;
515     }
516 
517     if (remain != 0) {
518         _dwarf_p_dealloc(dbg, (unsigned char *)output_block);
519         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
520         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
521     }
522 
523     *output_length_in_bytes_ptr = output_length_in_bytes;
524     return (void*) output_block;
525 }
526 
527 void
dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg,void * space)528 dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
529 {
530     _dwarf_p_dealloc(dbg, space);
531 }
532 
533 /*  This is very similar to targ_address but results in a different FORM */
534 /*  dbg->de_ar_data_attribute_form is data4 or data8
535     and dwarf4 changes the definition for such on DW_AT_high_pc.
536     DWARF 3: the FORM here has no defined meaning for dwarf3.
537     DWARF 4: the FORM here means that for DW_AT_high_pc the value
538         is not a high address but is instead an offset
539         from a (separate) DW_AT_low_pc.
540     The intent for DWARF4 is that this is not a relocated
541     address at all.  Instead a simple offset.
542     But this should NOT be called for a simple non-relocated offset.
543     So do not call this with an attr of DW_AT_high_pc.
544     Use dwarf_add_AT_unsigned_const() (for example) instead of
545     dwarf_add_AT_dataref when the value is a simple offset .  */
546 
547 int
dwarf_add_AT_dataref_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)548 dwarf_add_AT_dataref_a(
549     Dwarf_P_Debug dbg,
550     Dwarf_P_Die ownerdie,
551     Dwarf_Half attr,
552     Dwarf_Unsigned pc_value,
553     Dwarf_Unsigned sym_index,
554     Dwarf_P_Attribute *attr_out,
555     Dwarf_Error * error)
556 {
557     int res = 0;
558 
559     /* TODO: Add checking here */
560     res = local_add_AT_address_a(dbg, ownerdie, attr,
561         dbg->de_ar_data_attribute_form,
562         pc_value,
563         sym_index,
564         attr_out,
565         error);
566     return res;
567 }
568 
569 
570 Dwarf_P_Attribute
dwarf_add_AT_dataref(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned pc_value,Dwarf_Unsigned sym_index,Dwarf_Error * error)571 dwarf_add_AT_dataref(
572     Dwarf_P_Debug dbg,
573     Dwarf_P_Die ownerdie,
574     Dwarf_Half attr,
575     Dwarf_Unsigned pc_value,
576     Dwarf_Unsigned sym_index,
577     Dwarf_Error * error)
578 {
579     Dwarf_P_Attribute a = 0;
580     int res = 0;
581 
582     /* TODO: Add checking here */
583     res = local_add_AT_address_a(dbg, ownerdie, attr,
584         dbg->de_ar_data_attribute_form,
585         pc_value,
586         sym_index,
587         &a,
588         error);
589     if (res != DW_DLV_OK) {
590         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
591     }
592     return a;
593 }
594 
595 Dwarf_P_Attribute
dwarf_add_AT_block(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small * block_data,Dwarf_Unsigned block_size,Dwarf_Error * error)596 dwarf_add_AT_block(
597     Dwarf_P_Debug       dbg,
598     Dwarf_P_Die         ownerdie,
599     Dwarf_Half          attr,
600     Dwarf_Small         *block_data,
601     Dwarf_Unsigned      block_size,
602     Dwarf_Error         *error)
603 {
604     int res = 0;
605     Dwarf_P_Attribute   new_attr = 0;
606 
607     res = dwarf_add_AT_block_a(dbg,ownerdie,attr,
608         block_data,block_size,&new_attr,error);
609     if (res != DW_DLV_OK) {
610         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
611     }
612     return new_attr;
613 }
614 int
dwarf_add_AT_block_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small * block_data,Dwarf_Unsigned block_size,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)615 dwarf_add_AT_block_a(
616     Dwarf_P_Debug       dbg,
617     Dwarf_P_Die         ownerdie,
618     Dwarf_Half          attr,
619     Dwarf_Small         *block_data,
620     Dwarf_Unsigned      block_size,
621     Dwarf_P_Attribute*  attr_out,
622     Dwarf_Error         *error)
623 {
624     Dwarf_P_Attribute   new_attr = 0;
625     int result = 0;
626     char encode_buffer[ENCODE_SPACE_NEEDED];
627     int len_size = 0;
628     char * attrdata = 0;
629 
630     if (dbg == NULL) {
631         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
632         return DW_DLV_ERROR;
633     }
634 
635     if (ownerdie == NULL) {
636         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
637         return DW_DLV_ERROR;
638     }
639 
640     /* I don't mess with block1, block2, block4, not worth the effort */
641 
642     /* So, encode the length into LEB128 */
643     result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
644         encode_buffer,sizeof(encode_buffer));
645     if (result !=  DW_DLV_OK) {
646         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
647         return DW_DLV_ERROR;
648     }
649 
650     /* Allocate the new attribute */
651     new_attr = (Dwarf_P_Attribute)
652         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
653     if (new_attr == NULL) {
654         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
655         return DW_DLV_ERROR;
656     }
657 
658     /* Fill in the attribute */
659     new_attr->ar_attribute = attr;
660     new_attr->ar_attribute_form = DW_FORM_block;
661     new_attr->ar_nbytes = len_size + block_size;
662     new_attr->ar_next = 0;
663 
664     new_attr->ar_data = attrdata = (char *)
665         _dwarf_p_get_alloc(dbg, len_size + block_size);
666     if (new_attr->ar_data == NULL) {
667         /* free the block we got earlier */
668         _dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
669         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
670         return DW_DLV_ERROR;
671     }
672 
673     /* write length and data to attribute data buffer */
674     memcpy(attrdata, encode_buffer, len_size);
675     attrdata += len_size;
676     memcpy(attrdata, block_data, block_size);
677 
678     /* add attribute to the die */
679     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
680     *attr_out = new_attr;
681     return DW_DLV_OK;
682 }
683 
684 
685 /*
686     This function adds attributes whose value
687     is an unsigned constant.  It determines the
688     size of the value field from the value of
689     the constant.
690 */
691 Dwarf_P_Attribute
dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned value,Dwarf_Error * error)692 dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
693    Dwarf_P_Die ownerdie,
694    Dwarf_Half attr,
695    Dwarf_Unsigned value, Dwarf_Error * error)
696 {
697     Dwarf_P_Attribute a = 0;
698     int res = 0;
699 
700     res = dwarf_add_AT_unsigned_const_a(dbg,
701         ownerdie,attr,value,
702         &a,error);
703     if (res != DW_DLV_OK) {
704         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
705     }
706     return a;
707 }
708 
709 
710 int
dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Unsigned value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)711 dwarf_add_AT_unsigned_const_a(Dwarf_P_Debug dbg,
712    Dwarf_P_Die ownerdie,
713    Dwarf_Half attr,
714    Dwarf_Unsigned value,
715    Dwarf_P_Attribute *attr_out,
716    Dwarf_Error * error)
717 {
718     Dwarf_P_Attribute new_attr = 0;
719     Dwarf_Half attr_form = 0;
720     Dwarf_Small size = 0;
721 
722     if (dbg == NULL) {
723         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
724         return DW_DLV_ERROR;
725     }
726 
727     if (ownerdie == NULL) {
728         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
729         return DW_DLV_ERROR;
730     }
731 
732     switch (attr) {
733     case DW_AT_ordering:
734     case DW_AT_byte_size:
735     case DW_AT_bit_offset:
736     case DW_AT_bit_size:
737     case DW_AT_inline:
738     case DW_AT_language:
739     case DW_AT_visibility:
740     case DW_AT_virtuality:
741     case DW_AT_accessibility:
742     case DW_AT_address_class:
743     case DW_AT_calling_convention:
744     case DW_AT_encoding:
745     case DW_AT_identifier_case:
746     case DW_AT_MIPS_loop_unroll_factor:
747     case DW_AT_MIPS_software_pipeline_depth:
748         break;
749 
750     case DW_AT_decl_column:
751     case DW_AT_decl_file:
752     case DW_AT_decl_line:
753     case DW_AT_const_value:
754     case DW_AT_start_scope:
755     case DW_AT_stride_size: /* DW_AT_bit_stride  is DWARF3 name */
756     case DW_AT_count:
757     case DW_AT_high_pc:     /* DWARF5: allowing const udata high_pc */
758     case DW_AT_associated:
759     case DW_AT_allocated:
760     case DW_AT_upper_bound:
761     case DW_AT_lower_bound:
762     case DW_AT_call_file:
763     case DW_AT_call_line:
764     case DW_AT_data_member_location:
765     case DW_AT_trampoline:
766         break;
767 
768     default:
769         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
770             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
771             return DW_DLV_ERROR;
772         }
773         break;
774     }
775 
776     /* Compute the number of bytes needed to hold constant. */
777     if (value <= UCHAR_MAX) {
778         attr_form = DW_FORM_data1;
779         size = 1;
780     } else if (value <= USHRT_MAX) {
781         attr_form = DW_FORM_data2;
782         size = 2;
783     } else if (value <= UINT_MAX) {
784         attr_form = DW_FORM_data4;
785         size = 4;
786     } else {
787         attr_form = DW_FORM_data8;
788         size = 8;
789     }
790 
791     new_attr = (Dwarf_P_Attribute)
792         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
793     if (new_attr == NULL) {
794         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
795         return DW_DLV_ERROR;
796     }
797 
798     new_attr->ar_attribute = attr;
799     new_attr->ar_attribute_form = attr_form;
800     new_attr->ar_rel_type = R_MIPS_NONE;
801     new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
802     new_attr->ar_nbytes = size;
803     new_attr->ar_next = 0;
804 
805     new_attr->ar_data = (char *)
806         _dwarf_p_get_alloc(dbg, size);
807     if (new_attr->ar_data == NULL) {
808         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
809         return DW_DLV_ERROR;
810     }
811     WRITE_UNALIGNED(dbg, new_attr->ar_data,
812         (const void *) &value, sizeof(value), size);
813 
814     /* add attribute to the die */
815     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
816     *attr_out = new_attr;
817     return DW_DLV_OK;
818 }
819 
820 
821 /*  This function adds attributes whose value
822     is an signed constant.  It determines the
823     size of the value field from the value of
824     the constant.  */
825 Dwarf_P_Attribute
dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed value,Dwarf_Error * error)826 dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
827     Dwarf_P_Die ownerdie,
828     Dwarf_Half attr,
829     Dwarf_Signed value,
830     Dwarf_Error * error)
831 {
832     Dwarf_P_Attribute a = 0;
833     int res = 0;
834 
835     res = dwarf_add_AT_signed_const_a(dbg,
836         ownerdie,attr,value,&a,error);
837     if(res != DW_DLV_OK) {
838         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
839     }
840     return a;
841 }
842 
843 int
dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Signed value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)844 dwarf_add_AT_signed_const_a(Dwarf_P_Debug dbg,
845     Dwarf_P_Die ownerdie,
846     Dwarf_Half attr,
847     Dwarf_Signed value,
848     Dwarf_P_Attribute *attr_out,
849     Dwarf_Error * error)
850 {
851     Dwarf_P_Attribute new_attr = 0;
852     Dwarf_Half attr_form = 0;
853     Dwarf_Small size = 0;
854 
855     if (dbg == NULL) {
856         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
857         return DW_DLV_ERROR;
858     }
859 
860     if (ownerdie == NULL) {
861         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
862         return DW_DLV_ERROR;
863     }
864 
865     switch (attr) {
866     case DW_AT_lower_bound:
867     case DW_AT_upper_bound:
868     case DW_AT_const_value:
869     case DW_AT_bit_offset:
870     case DW_AT_bit_size:
871     case DW_AT_byte_size:
872     case DW_AT_count:
873     case DW_AT_byte_stride:
874     case DW_AT_bit_stride:
875     case DW_AT_allocated:
876     case DW_AT_associated:
877         break;
878 
879     default:
880         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
881             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
882             return DW_DLV_ERROR;
883         }
884         break;
885     }
886 
887     /* Compute the number of bytes needed to hold constant. */
888     if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
889         attr_form = DW_FORM_data1;
890         size = 1;
891     } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
892         attr_form = DW_FORM_data2;
893         size = 2;
894     } else if (value >= INT_MIN && value <= INT_MAX) {
895         attr_form = DW_FORM_data4;
896         size = 4;
897     } else {
898         attr_form = DW_FORM_data8;
899         size = 8;
900     }
901 
902     new_attr = (Dwarf_P_Attribute)
903         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
904     if (new_attr == NULL) {
905         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
906         return DW_DLV_ERROR;
907     }
908 
909     new_attr->ar_attribute = attr;
910     new_attr->ar_attribute_form = attr_form;
911     new_attr->ar_rel_type = R_MIPS_NONE;
912     new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */
913     new_attr->ar_nbytes = size;
914     new_attr->ar_next = 0;
915 
916     new_attr->ar_data = (char *)
917         _dwarf_p_get_alloc(dbg, size);
918     if (new_attr->ar_data == NULL) {
919         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
920         return DW_DLV_ERROR;
921     }
922     WRITE_UNALIGNED(dbg, new_attr->ar_data,
923         (const void *) &value, sizeof(value), size);
924 
925     /* add attribute to the die */
926     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
927     *attr_out = new_attr;
928     return DW_DLV_OK;
929 }
930 
931 
932 /*  This function adds attributes whose value
933     is a location expression.  */
934 Dwarf_P_Attribute
dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Expr loc_expr,Dwarf_Error * error)935 dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
936     Dwarf_P_Die ownerdie,
937     Dwarf_Half attr,
938     Dwarf_P_Expr loc_expr, Dwarf_Error * error)
939 {
940     int res = 0;
941     Dwarf_P_Attribute a = 0;
942 
943     res = dwarf_add_AT_location_expr_a(dbg,ownerdie,attr,
944         loc_expr,&a,error);
945     if (res != DW_DLV_OK) {
946         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
947     }
948     return a;
949 }
950 
951 /* Preferred interface as of December 2018 */
952 int
dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Expr loc_expr,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)953 dwarf_add_AT_location_expr_a(Dwarf_P_Debug dbg,
954     Dwarf_P_Die ownerdie,
955     Dwarf_Half attr,
956     Dwarf_P_Expr loc_expr,
957     Dwarf_P_Attribute *attr_out,
958     Dwarf_Error * error)
959 {
960     char encode_buffer[ENCODE_SPACE_NEEDED];
961     int res = 0;
962     Dwarf_P_Attribute new_attr = 0;
963     Dwarf_Half attr_form = 0;
964     char *len_str = 0;
965     int len_size = 0;
966     Dwarf_Unsigned block_size = 0;
967     char *block_dest_ptr = 0;
968     int do_len_as_int = 0;
969 
970     if (dbg == NULL) {
971         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
972         return DW_DLV_ERROR;
973     }
974 
975     if (ownerdie == NULL) {
976         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
977         return DW_DLV_ERROR;
978     }
979 
980     if (loc_expr == NULL) {
981         _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
982         return DW_DLV_ERROR;
983     }
984 
985     if (loc_expr->ex_dbg != dbg) {
986         _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
987         return DW_DLV_ERROR;
988     }
989     block_size = loc_expr->ex_next_byte_offset;
990 
991     switch (attr) {
992     case DW_AT_location:
993     case DW_AT_string_length:
994     case DW_AT_const_value:
995     case DW_AT_use_location:
996     case DW_AT_return_addr:
997     case DW_AT_data_member_location:
998     case DW_AT_frame_base:
999     case DW_AT_static_link:
1000     case DW_AT_vtable_elem_location:
1001     case DW_AT_lower_bound:
1002     case DW_AT_upper_bound:
1003     case DW_AT_count:
1004     case DW_AT_associated:
1005     case DW_AT_allocated:
1006     case DW_AT_data_location:
1007     case DW_AT_byte_stride:
1008     case DW_AT_bit_stride:
1009     case DW_AT_byte_size:
1010     case DW_AT_bit_size:
1011     break;
1012 
1013     default:
1014         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
1015             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
1016             return DW_DLV_ERROR;
1017         }
1018     break;
1019     }
1020 
1021     /*  Compute the number of bytes needed to hold constant.
1022         This is a bit fake in that the size will never
1023         be particularly large and always < UINT_MAX. */
1024     if (block_size <= UCHAR_MAX) {
1025         attr_form = DW_FORM_block1;
1026         len_size = 1;
1027         do_len_as_int = 1;
1028     } else if (block_size <= USHRT_MAX) {
1029         attr_form = DW_FORM_block2;
1030         len_size = 2;
1031         do_len_as_int = 1;
1032     } else if (block_size <= UINT_MAX) {
1033         attr_form = DW_FORM_block4;
1034         len_size = 4;
1035         do_len_as_int = 1;
1036     } else {
1037         attr_form = DW_FORM_block;
1038         res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
1039             encode_buffer,
1040             sizeof(encode_buffer));
1041         if (res != DW_DLV_OK) {
1042             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1043             return DW_DLV_ERROR;
1044         }
1045         len_str = (char *) encode_buffer;
1046     }
1047 
1048     new_attr = (Dwarf_P_Attribute)
1049         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1050     if (new_attr == NULL) {
1051         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1052         return DW_DLV_ERROR;
1053     }
1054 
1055     new_attr->ar_attribute = attr;
1056     new_attr->ar_attribute_form = attr_form;
1057     new_attr->ar_reloc_len = dbg->de_pointer_size;
1058     if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
1059         new_attr->ar_rel_type = dbg->de_ptr_reloc;
1060     } else {
1061         new_attr->ar_rel_type = R_MIPS_NONE;
1062     }
1063     new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
1064     new_attr->ar_rel_offset =
1065         loc_expr->ex_reloc_offset + len_size;
1066 
1067     new_attr->ar_nbytes = block_size + len_size;
1068 
1069     new_attr->ar_next = 0;
1070     new_attr->ar_data = block_dest_ptr =
1071         (char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
1072     if (new_attr->ar_data == NULL) {
1073         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1074         return DW_DLV_ERROR;
1075     }
1076 
1077     if (do_len_as_int) {
1078         WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
1079             sizeof(block_size), len_size);
1080     } else {
1081         /* Is uleb number form, DW_FORM_block. See above. */
1082         memcpy(block_dest_ptr, len_str, len_size);
1083     }
1084     block_dest_ptr += len_size;
1085     if (block_size > sizeof(loc_expr->ex_byte_stream)) {
1086         /* ex_byte_stream has a fixed max value. */
1087         _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
1088         return DW_DLV_ERROR;
1089     }
1090     memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
1091 
1092     /* add attribute to the die */
1093     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1094     *attr_out = new_attr;
1095     return DW_DLV_OK;
1096 }
1097 
1098 
1099 /*  This function adds attributes of reference class.
1100     The references here are local CU references,
1101     not DW_FORM_ref_addr.
1102     The offset field is 4 bytes for 32-bit objects,
1103     and 8-bytes for 64-bit objects.  Otherdie is the
1104     that is referenced by ownerdie.
1105 
1106     For reference attributes, the ar_data and ar_nbytes
1107     are not needed.  Instead, the ar_ref_die points to
1108     the other die, and its di_offset value is used as
1109     the reference value.  */
1110 
1111 static int
_dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,int check_otherdie,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1112 _dwarf_add_AT_reference_internal_a(Dwarf_P_Debug dbg,
1113     Dwarf_P_Die ownerdie,
1114     Dwarf_Half attr,
1115     Dwarf_P_Die otherdie,
1116     int check_otherdie,
1117     Dwarf_P_Attribute *attr_out,
1118     Dwarf_Error * error)
1119 {
1120     Dwarf_P_Attribute new_attr = 0;
1121 
1122     if (dbg == NULL) {
1123         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
1124         return DW_DLV_ERROR;
1125     }
1126 
1127     if (ownerdie == NULL) {
1128         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1129         return DW_DLV_ERROR;
1130     }
1131 
1132     if (check_otherdie && (otherdie == NULL)) {
1133         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1134         return DW_DLV_ERROR;
1135     }
1136 
1137     switch (attr) {
1138     case DW_AT_count:
1139     case DW_AT_sibling:
1140     case DW_AT_byte_size:
1141     case DW_AT_bit_offset:
1142     case DW_AT_bit_size:
1143     case DW_AT_discr:
1144     case DW_AT_import:
1145     case DW_AT_common_reference:
1146     case DW_AT_containing_type:
1147     case DW_AT_default_value:
1148     case DW_AT_lower_bound:
1149     case DW_AT_bit_stride: /* Early name is DW_AT_stride_size */
1150     case DW_AT_upper_bound:
1151     case DW_AT_abstract_origin:
1152     case DW_AT_base_types:
1153     case DW_AT_friend:
1154     case DW_AT_namelist_item:
1155     case DW_AT_priority:
1156     case DW_AT_specification:
1157     case DW_AT_type:
1158     case DW_AT_allocated:
1159     case DW_AT_associated:
1160     case DW_AT_byte_stride:
1161     case DW_AT_extension:
1162     case DW_AT_trampoline:
1163     case DW_AT_small:
1164     case DW_AT_object_pointer:
1165     case DW_AT_signature:
1166         break;
1167 
1168     default:
1169         if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
1170             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
1171             return DW_DLV_ERROR;
1172         }
1173         break;
1174     }
1175 
1176     new_attr = (Dwarf_P_Attribute)
1177         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1178     if (new_attr == NULL) {
1179         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1180         return DW_DLV_ERROR;
1181     }
1182 
1183     new_attr->ar_attribute = attr;
1184     new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
1185     new_attr->ar_nbytes = dbg->de_dwarf_offset_size;
1186     new_attr->ar_reloc_len = dbg->de_dwarf_offset_size;
1187     new_attr->ar_ref_die = otherdie;
1188     new_attr->ar_rel_type = R_MIPS_NONE;
1189     new_attr->ar_next = 0;
1190 
1191     /* Add attribute to the die */
1192     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1193     *attr_out = new_attr;
1194     return DW_DLV_OK;
1195 }
1196 
1197 /*  Allowing the target die to be identified later.
1198     */
1199 int
dwarf_add_AT_reference_c(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1200 dwarf_add_AT_reference_c(Dwarf_P_Debug dbg,
1201     Dwarf_P_Die ownerdie,
1202     Dwarf_Half attr,
1203     Dwarf_P_Die otherdie,
1204     Dwarf_P_Attribute *attr_out,
1205     Dwarf_Error * error)
1206 {
1207     int res = 0;
1208 
1209     res = _dwarf_add_AT_reference_internal_a(dbg,
1210         ownerdie,
1211         attr,
1212         otherdie,
1213         /* check otherdie */ 0,
1214         attr_out,
1215         error);
1216     return res;
1217 }
1218 
1219 
1220 
1221 Dwarf_P_Attribute
dwarf_add_AT_reference(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,Dwarf_Error * error)1222 dwarf_add_AT_reference(Dwarf_P_Debug dbg,
1223     Dwarf_P_Die ownerdie,
1224     Dwarf_Half attr,
1225     Dwarf_P_Die otherdie, Dwarf_Error * error)
1226 {
1227     Dwarf_P_Attribute a = 0;
1228     int res = 0;
1229 
1230     res = _dwarf_add_AT_reference_internal_a(dbg,
1231         ownerdie,
1232         attr,
1233         otherdie,
1234         /* check otherdie */ 1,
1235         &a,
1236         error);
1237     if (res != DW_DLV_OK) {
1238         return (Dwarf_P_Attribute)DW_DLV_BADADDR;
1239     }
1240     return a;
1241 }
1242 
1243 /*  Allowing the target die to be identified later.
1244     */
1245 Dwarf_P_Attribute
dwarf_add_AT_reference_b(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_P_Die otherdie,Dwarf_Error * error)1246 dwarf_add_AT_reference_b(Dwarf_P_Debug dbg,
1247     Dwarf_P_Die ownerdie,
1248     Dwarf_Half attr,
1249     Dwarf_P_Die otherdie,
1250     Dwarf_Error * error)
1251 {
1252     Dwarf_P_Attribute a = 0;
1253     int res = 0;
1254 
1255     res = _dwarf_add_AT_reference_internal_a(dbg,
1256         ownerdie,
1257         attr,
1258         otherdie,
1259         /* check otherdie */ 0,
1260         &a,
1261         error);
1262     if (res != DW_DLV_OK) {
1263         return (Dwarf_P_Attribute)DW_DLV_BADADDR;
1264     }
1265     return a;
1266 }
1267 
1268 
1269 
1270 
1271 int
dwarf_fixup_AT_reference_die(Dwarf_P_Debug dbg,Dwarf_Half attrnum,Dwarf_P_Die sourcedie,Dwarf_P_Die targetdie,Dwarf_Error * error)1272 dwarf_fixup_AT_reference_die(Dwarf_P_Debug dbg,
1273    Dwarf_Half attrnum,
1274    Dwarf_P_Die sourcedie,
1275    Dwarf_P_Die targetdie,
1276    Dwarf_Error *error)
1277 {
1278     Dwarf_P_Attribute a = 0;
1279     Dwarf_P_Attribute cur = 0;
1280     if (dbg == NULL) {
1281         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
1282         return DW_DLV_ERROR;
1283     }
1284     for(cur = sourcedie->di_attrs; cur; cur = cur->ar_next) {
1285         if (attrnum == cur->ar_attribute) {
1286             a = cur;
1287             break;
1288         }
1289     }
1290     if(!a) {
1291         _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_NULL);
1292         return DW_DLV_ERROR;
1293     }
1294     if(a->ar_ref_die) {
1295         _dwarf_p_error(dbg, error, DW_DLE_AT_FIXUP_DUP);
1296         return DW_DLV_ERROR;
1297     }
1298     a->ar_ref_die = targetdie;
1299     return DW_DLV_OK;
1300 }
1301 
1302 
1303 /* This function adds attributes of the flag class.  */
1304 Dwarf_P_Attribute
dwarf_add_AT_flag(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small flag,Dwarf_Error * error)1305 dwarf_add_AT_flag(Dwarf_P_Debug dbg,
1306     Dwarf_P_Die ownerdie,
1307     Dwarf_Half attr,
1308     Dwarf_Small flag,
1309     Dwarf_Error * error)
1310 {
1311     Dwarf_P_Attribute a = 0;
1312     int res = 0;
1313 
1314     res = dwarf_add_AT_flag_a(dbg,ownerdie,attr,flag,
1315         &a,error);
1316     if (res != DW_DLV_OK) {
1317         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1318     }
1319     return a;
1320 }
1321 int
dwarf_add_AT_flag_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,Dwarf_Small flag,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1322 dwarf_add_AT_flag_a(Dwarf_P_Debug dbg,
1323     Dwarf_P_Die ownerdie,
1324     Dwarf_Half attr,
1325     Dwarf_Small flag,
1326     Dwarf_P_Attribute * attr_out,
1327     Dwarf_Error * error)
1328 {
1329     Dwarf_P_Attribute new_attr = 0;
1330 
1331     if (dbg == NULL) {
1332         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
1333         return DW_DLV_ERROR;
1334     }
1335     if (ownerdie == NULL) {
1336         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1337         return DW_DLV_ERROR;
1338     }
1339 
1340     new_attr = (Dwarf_P_Attribute)
1341         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1342     if (new_attr == NULL) {
1343         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1344         return DW_DLV_ERROR;
1345     }
1346 
1347     new_attr->ar_attribute = attr;
1348     new_attr->ar_attribute_form = DW_FORM_flag;
1349     new_attr->ar_nbytes = 1;
1350     new_attr->ar_reloc_len = 0; /* not used */
1351     new_attr->ar_rel_type = R_MIPS_NONE;
1352     new_attr->ar_next = 0;
1353 
1354     new_attr->ar_data = (char *)
1355         _dwarf_p_get_alloc(dbg, 1);
1356     if (new_attr->ar_data == NULL) {
1357         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1358         return DW_DLV_ERROR;
1359     }
1360     memcpy(new_attr->ar_data, &flag, 1);
1361 
1362     /* Add attribute to the die */
1363     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1364     *attr_out = new_attr;
1365     return DW_DLV_OK;
1366 }
1367 
1368 
1369 /*  This function adds values of attributes
1370     belonging to the string class. */
1371 Dwarf_P_Attribute
dwarf_add_AT_string(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,char * string,Dwarf_Error * error)1372 dwarf_add_AT_string(Dwarf_P_Debug dbg,
1373     Dwarf_P_Die ownerdie,
1374     Dwarf_Half attr, char *string, Dwarf_Error * error)
1375 {
1376     Dwarf_P_Attribute a = 0;
1377     int res = 0;
1378 
1379     res = dwarf_add_AT_string_a(dbg,
1380         ownerdie,attr,string,&a,error);
1381     if (res != DW_DLV_OK) {
1382         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1383     }
1384     return a;
1385 }
1386 
1387 int
dwarf_add_AT_string_a(Dwarf_P_Debug dbg,Dwarf_P_Die ownerdie,Dwarf_Half attr,char * string,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1388 dwarf_add_AT_string_a(Dwarf_P_Debug dbg,
1389     Dwarf_P_Die ownerdie,
1390     Dwarf_Half attr,
1391     char *string,
1392     Dwarf_P_Attribute *attr_out,
1393     Dwarf_Error * error)
1394 {
1395     Dwarf_P_Attribute new_attr = 0;
1396     int res = 0;
1397 
1398     if (dbg == NULL) {
1399         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
1400         return DW_DLV_ERROR;
1401     }
1402 
1403     if (ownerdie == NULL) {
1404         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1405         return DW_DLV_ERROR;
1406     }
1407 
1408     new_attr = (Dwarf_P_Attribute)
1409         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1410     if (new_attr == NULL) {
1411         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1412         return DW_DLV_ERROR;
1413     }
1414 
1415     switch (attr) {
1416     /* See also: pro_section.c for same strings attribute list. */
1417     case DW_AT_comp_dir:
1418     case DW_AT_const_value:
1419     case DW_AT_linkage_name:/* DWARF5, but ok for any version really.*/
1420     case DW_AT_MIPS_abstract_name:
1421     case DW_AT_MIPS_linkage_name:
1422     case DW_AT_name:
1423     case DW_AT_producer:
1424         break;
1425 
1426         default:
1427             if (attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
1428             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
1429             return DW_DLV_ERROR;
1430         }
1431             break;
1432     }
1433     new_attr->ar_attribute = attr;
1434     res = _dwarf_pro_set_string_attr(new_attr,ownerdie->di_dbg,
1435         string,error);
1436     if (res != DW_DLV_OK) {
1437         return res;
1438     }
1439 
1440     /* add attribute to the die */
1441     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1442     *attr_out = new_attr;
1443     return DW_DLV_OK;
1444 }
1445 
1446 Dwarf_P_Attribute
dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,char * string_value,Dwarf_Error * error)1447 dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
1448     char *string_value, Dwarf_Error * error)
1449 {
1450     Dwarf_P_Attribute a = 0;
1451     int res = 0;
1452 
1453     res = dwarf_add_AT_const_value_string_a(ownerdie,
1454         string_value,&a,error);
1455     if (res != DW_DLV_OK) {
1456         return (Dwarf_P_Attribute) DW_DLV_BADADDR;
1457     }
1458     return a;
1459 }
1460 
1461 int
dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie,char * string_value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1462 dwarf_add_AT_const_value_string_a(Dwarf_P_Die ownerdie,
1463     char *string_value,
1464     Dwarf_P_Attribute *attr_out,
1465     Dwarf_Error * error)
1466 {
1467     Dwarf_P_Attribute new_attr = 0;
1468     Dwarf_P_Debug dbg = 0;
1469     int res = 0;
1470 
1471     if (ownerdie == NULL) {
1472         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1473         return DW_DLV_ERROR;
1474     }
1475     dbg = ownerdie->di_dbg;
1476 
1477     new_attr = (Dwarf_P_Attribute)
1478         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1479     if (new_attr == NULL) {
1480         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1481         return DW_DLV_ERROR;
1482     }
1483 
1484     new_attr->ar_attribute = DW_AT_const_value;
1485     res = _dwarf_pro_set_string_attr(new_attr,dbg,
1486         string_value,error);
1487     if (res != DW_DLV_OK) {
1488         return res;
1489     }
1490 
1491     /* add attribute to the die */
1492     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1493     *attr_out = new_attr;
1494     return DW_DLV_OK;
1495 }
1496 
1497 Dwarf_P_Attribute
dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,const Dwarf_Sig8 * sig8_in,Dwarf_Error * error)1498 dwarf_add_AT_with_ref_sig8(Dwarf_P_Die ownerdie,
1499     Dwarf_Half attrnum,
1500     const Dwarf_Sig8 *sig8_in,
1501     Dwarf_Error * error)
1502 {
1503     Dwarf_P_Attribute a = 0;
1504     int res = 0;
1505 
1506     res = dwarf_add_AT_with_ref_sig8_a(ownerdie,
1507         attrnum,sig8_in,&a,error);
1508     if (res != DW_DLV_OK) {
1509         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1510     }
1511     return a;
1512 }
1513 
1514 int
dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,const Dwarf_Sig8 * sig8_in,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1515 dwarf_add_AT_with_ref_sig8_a(Dwarf_P_Die ownerdie,
1516     Dwarf_Half attrnum,
1517     const Dwarf_Sig8 *sig8_in,
1518     Dwarf_P_Attribute * attr_out,
1519     Dwarf_Error * error)
1520 {
1521     Dwarf_P_Attribute new_attr = 0;
1522     Dwarf_P_Debug dbg = 0;
1523 
1524     if (ownerdie == NULL) {
1525         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1526         return DW_DLV_ERROR;
1527     }
1528     dbg = ownerdie->di_dbg;
1529 
1530     new_attr = (Dwarf_P_Attribute)
1531         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1532     if (new_attr == NULL) {
1533         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1534         return DW_DLV_ERROR;
1535     }
1536     new_attr->ar_attribute = attrnum;
1537     new_attr->ar_attribute_form = DW_FORM_ref_sig8;
1538     new_attr->ar_nbytes = sizeof (Dwarf_Sig8);
1539     new_attr->ar_next = 0;
1540 
1541     new_attr->ar_data =
1542         (char *) _dwarf_p_get_alloc(dbg, sizeof(Dwarf_Sig8));
1543     if (new_attr->ar_data == NULL) {
1544         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1545         return DW_DLV_ERROR;
1546     }
1547     memcpy(new_attr->ar_data,sig8_in,sizeof(Dwarf_Sig8));
1548     new_attr->ar_rel_type = R_MIPS_NONE;
1549     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1550     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1551     *attr_out = new_attr;
1552     return DW_DLV_OK;
1553 }
1554 
1555 
1556 
1557 Dwarf_P_Attribute
dwarf_add_AT_producer(Dwarf_P_Die ownerdie,char * producer_string,Dwarf_Error * error)1558 dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
1559     char *producer_string, Dwarf_Error * error)
1560 {
1561     Dwarf_P_Attribute a = 0;
1562     int res = 0;
1563 
1564     res = dwarf_add_AT_producer_a(ownerdie,
1565         producer_string,&a,error);
1566     if (res != DW_DLV_OK) {
1567         return ((Dwarf_P_Attribute)DW_DLV_BADADDR);
1568     }
1569     return a;
1570 }
1571 
1572 int
dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie,char * producer_string,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1573 dwarf_add_AT_producer_a(Dwarf_P_Die ownerdie,
1574     char *producer_string,
1575     Dwarf_P_Attribute *attr_out,
1576     Dwarf_Error * error)
1577 {
1578     Dwarf_P_Attribute new_attr = 0;
1579     Dwarf_P_Debug dbg = 0;
1580     int res = 0;
1581 
1582     if (ownerdie == NULL) {
1583         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1584         return DW_DLV_ERROR;
1585     }
1586     dbg = ownerdie->di_dbg;
1587     new_attr = (Dwarf_P_Attribute)
1588         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1589     if (new_attr == NULL) {
1590         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1591         return DW_DLV_ERROR;
1592     }
1593 
1594     new_attr->ar_attribute = DW_AT_producer;
1595     res = _dwarf_pro_set_string_attr(new_attr,dbg,
1596         producer_string,error);
1597     if (res != DW_DLV_OK) {
1598         return res;
1599     }
1600 
1601     /* add attribute to the die */
1602     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1603     *attr_out = new_attr;
1604     return DW_DLV_OK;
1605 }
1606 
1607 int
dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie,Dwarf_Signed signed_value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1608 dwarf_add_AT_const_value_signedint_a(Dwarf_P_Die ownerdie,
1609     Dwarf_Signed signed_value,
1610     Dwarf_P_Attribute *attr_out,
1611     Dwarf_Error * error)
1612 {
1613     int res = 0;
1614 
1615     res = dwarf_add_AT_any_value_sleb_a(
1616         ownerdie,DW_AT_const_value,
1617         signed_value,
1618         attr_out, error);
1619     return res;
1620 }
1621 
1622 Dwarf_P_Attribute
dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,Dwarf_Signed signed_value,Dwarf_Error * error)1623 dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
1624     Dwarf_Signed signed_value,
1625     Dwarf_Error * error)
1626 {
1627     Dwarf_P_Attribute a = 0;
1628     int res = 0;
1629 
1630     res = dwarf_add_AT_any_value_sleb_a(
1631         ownerdie,DW_AT_const_value,
1632         signed_value,
1633         &a, error);
1634     if (res != DW_DLV_OK) {
1635         return (Dwarf_P_Attribute)DW_DLV_BADADDR;
1636     }
1637     return a;
1638 }
1639 
1640 int
dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Signed signed_value,Dwarf_P_Attribute * outattr,Dwarf_Error * error)1641 dwarf_add_AT_implicit_const(Dwarf_P_Die ownerdie,
1642     Dwarf_Half attrnum,
1643     Dwarf_Signed signed_value,
1644     Dwarf_P_Attribute *outattr,
1645     Dwarf_Error * error)
1646 {
1647     Dwarf_P_Attribute new_attr = 0;
1648     Dwarf_P_Debug dbg = 0;
1649 
1650     if (ownerdie == NULL) {
1651         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1652         return DW_DLV_ERROR;
1653     }
1654     dbg = ownerdie->di_dbg;
1655 
1656     new_attr = (Dwarf_P_Attribute)
1657         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1658     if (new_attr == NULL) {
1659         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1660         return DW_DLV_ERROR;
1661     }
1662 
1663     new_attr->ar_attribute = attrnum;
1664     new_attr->ar_attribute_form = DW_FORM_implicit_const;
1665     new_attr->ar_rel_type = R_MIPS_NONE;
1666     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1667     new_attr->ar_next = 0;
1668 
1669     /*  The value will go in the abbrev section.
1670         Not the DIE. Encoding done with abbrev generation. */
1671     new_attr->ar_data = 0;
1672     new_attr->ar_nbytes = 0;
1673     new_attr->ar_implicit_const = signed_value;
1674 
1675     /* add attribute to the die */
1676     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1677     *outattr = new_attr;
1678     return DW_DLV_OK;
1679 }
1680 
1681 Dwarf_P_Attribute
dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Signed signed_value,Dwarf_Error * error)1682 dwarf_add_AT_any_value_sleb(Dwarf_P_Die ownerdie,
1683     Dwarf_Half attrnum,
1684     Dwarf_Signed signed_value,
1685     Dwarf_Error * error)
1686 {
1687     int res = 0;
1688     Dwarf_P_Attribute a = 0;
1689 
1690     res = dwarf_add_AT_any_value_sleb_a(ownerdie,
1691         attrnum,
1692         signed_value,
1693         &a, error);
1694     if (res != DW_DLV_OK) {
1695         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1696     }
1697     return a;
1698 }
1699 
1700 int
dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Signed signed_value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1701 dwarf_add_AT_any_value_sleb_a(Dwarf_P_Die ownerdie,
1702     Dwarf_Half attrnum,
1703     Dwarf_Signed signed_value,
1704     Dwarf_P_Attribute *attr_out,
1705     Dwarf_Error * error)
1706 {
1707     Dwarf_P_Attribute new_attr = 0;
1708     int leb_size = 0;
1709     Dwarf_P_Debug dbg = 0;
1710     char encode_buffer[ENCODE_SPACE_NEEDED];
1711     int res = 0;
1712 
1713     if (ownerdie == NULL) {
1714         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1715         return DW_DLV_ERROR;
1716     }
1717     dbg = ownerdie->di_dbg;
1718 
1719     new_attr = (Dwarf_P_Attribute)
1720         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1721     if (new_attr == NULL) {
1722         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1723         return DW_DLV_ERROR;
1724     }
1725 
1726     new_attr->ar_attribute = attrnum;
1727     new_attr->ar_attribute_form = DW_FORM_sdata;
1728     new_attr->ar_rel_type = R_MIPS_NONE;
1729     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1730     new_attr->ar_next = 0;
1731 
1732     res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
1733         encode_buffer,
1734         sizeof(encode_buffer));
1735     if (res != DW_DLV_OK) {
1736         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1737         return DW_DLV_ERROR;
1738     }
1739     new_attr->ar_data = (char *)
1740         _dwarf_p_get_alloc(dbg, leb_size);
1741     if (new_attr->ar_data == NULL) {
1742         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1743         return DW_DLV_ERROR;
1744     }
1745     memcpy(new_attr->ar_data, encode_buffer, leb_size);
1746     new_attr->ar_nbytes = leb_size;
1747 
1748     /* add attribute to the die */
1749     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1750     *attr_out = new_attr;
1751     return DW_DLV_OK;
1752 }
1753 
1754 /* AT_const_value, uleb */
1755 Dwarf_P_Attribute
dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,Dwarf_Unsigned unsigned_value,Dwarf_Error * error)1756 dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
1757     Dwarf_Unsigned unsigned_value,
1758     Dwarf_Error * error)
1759 {
1760     Dwarf_P_Attribute a =0;
1761     int res = 0;
1762 
1763     res = dwarf_add_AT_any_value_uleb_a(
1764         ownerdie,DW_AT_const_value,
1765         unsigned_value,
1766         &a,
1767         error);
1768     if (res != DW_DLV_OK) {
1769         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1770     }
1771     return a;
1772 }
1773 
1774 int
dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie,Dwarf_Unsigned unsigned_value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1775 dwarf_add_AT_const_value_unsignedint_a(Dwarf_P_Die ownerdie,
1776     Dwarf_Unsigned unsigned_value,
1777     Dwarf_P_Attribute *attr_out,
1778     Dwarf_Error * error)
1779 {
1780 
1781     return dwarf_add_AT_any_value_uleb_a(
1782         ownerdie,DW_AT_const_value,
1783         unsigned_value,
1784         attr_out,
1785         error);
1786 }
1787 
1788 int
dwarf_add_AT_data16(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Form_Data16 * ptr_to_val,Dwarf_P_Attribute * attr_return,Dwarf_Error * error)1789 dwarf_add_AT_data16(Dwarf_P_Die ownerdie,
1790     Dwarf_Half attrnum,
1791     Dwarf_Form_Data16 * ptr_to_val,
1792     Dwarf_P_Attribute * attr_return,
1793     Dwarf_Error * error)
1794 {
1795     Dwarf_P_Attribute new_attr;
1796     int val_size = sizeof(Dwarf_Form_Data16);
1797     Dwarf_P_Debug dbg = 0;
1798 
1799     if (ownerdie == NULL) {
1800         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1801         return DW_DLV_ERROR;
1802     }
1803     dbg = ownerdie->di_dbg;
1804     new_attr = (Dwarf_P_Attribute)
1805         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1806     if (new_attr == NULL) {
1807         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1808         return DW_DLV_ERROR;
1809     }
1810     new_attr->ar_attribute = attrnum;
1811     new_attr->ar_attribute_form = DW_FORM_data16;
1812     new_attr->ar_rel_type = R_MIPS_NONE;
1813     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1814     new_attr->ar_next = 0;
1815     new_attr->ar_data = (char *)
1816         _dwarf_p_get_alloc(dbg, val_size);
1817     if (new_attr->ar_data == NULL) {
1818         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1819         return DW_DLV_ERROR;
1820     }
1821     memcpy(new_attr->ar_data, ptr_to_val->fd_data, val_size);
1822     new_attr->ar_nbytes = val_size;
1823     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1824     *attr_return = new_attr;
1825     return DW_DLV_OK;
1826 }
1827 
1828 Dwarf_P_Attribute
dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Unsigned unsigned_value,Dwarf_Error * error)1829 dwarf_add_AT_any_value_uleb(Dwarf_P_Die ownerdie,
1830     Dwarf_Half attrnum,
1831     Dwarf_Unsigned unsigned_value,
1832     Dwarf_Error * error)
1833 {
1834     Dwarf_P_Attribute a = 0;
1835     int res = 0;
1836 
1837     res = dwarf_add_AT_any_value_uleb_a(ownerdie,
1838         attrnum,unsigned_value,&a,error);
1839     if (res != DW_DLV_OK) {
1840         return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
1841     }
1842     return a;
1843 }
1844 int
dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie,Dwarf_Half attrnum,Dwarf_Unsigned unsigned_value,Dwarf_P_Attribute * attr_out,Dwarf_Error * error)1845 dwarf_add_AT_any_value_uleb_a(Dwarf_P_Die ownerdie,
1846     Dwarf_Half attrnum,
1847     Dwarf_Unsigned unsigned_value,
1848     Dwarf_P_Attribute * attr_out,
1849     Dwarf_Error * error)
1850 {
1851     Dwarf_P_Attribute new_attr;
1852     int leb_size;
1853     Dwarf_P_Debug dbg = 0;
1854     char encode_buffer[ENCODE_SPACE_NEEDED];
1855     int res;
1856 
1857     if (ownerdie == NULL) {
1858         _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
1859         return DW_DLV_ERROR;
1860     }
1861     dbg = ownerdie->di_dbg;
1862     new_attr = (Dwarf_P_Attribute)
1863         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
1864     if (new_attr == NULL) {
1865         _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
1866         return DW_DLV_ERROR;
1867     }
1868 
1869     new_attr->ar_attribute = attrnum;
1870     new_attr->ar_attribute_form = DW_FORM_udata;
1871     new_attr->ar_rel_type = R_MIPS_NONE;
1872     new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */
1873     new_attr->ar_next = 0;
1874 
1875     res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
1876         encode_buffer,
1877         sizeof(encode_buffer));
1878     if (res != DW_DLV_OK) {
1879         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1880         return DW_DLV_ERROR;
1881     }
1882     new_attr->ar_data = (char *)
1883         _dwarf_p_get_alloc(dbg, leb_size);
1884     if (new_attr->ar_data == NULL) {
1885         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
1886         return DW_DLV_ERROR;
1887     }
1888     memcpy(new_attr->ar_data, encode_buffer, leb_size);
1889     new_attr->ar_nbytes = leb_size;
1890 
1891     /* add attribute to the die */
1892     _dwarf_pro_add_at_to_die(ownerdie, new_attr);
1893     *attr_out = new_attr;
1894     return DW_DLV_OK;
1895 }
1896