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