1 /* Helper functions for form handling. 2 Copyright (C) 2003, 2004 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper (at) redhat.com>, 2003. 4 5 This program is Open Source software; you can redistribute it and/or 6 modify it under the terms of the Open Software License version 1.0 as 7 published by the Open Source Initiative. 8 9 You should have received a copy of the Open Software License along 10 with this program; if not, you may obtain a copy of the Open Software 11 License version 1.0 from http://www.opensource.org/licenses/osl.php or 12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13 3001 King Ranch Road, Ukiah, CA 95482. */ 14 15 #ifdef HAVE_CONFIG_H 16 # include <config.h> 17 #endif 18 19 #include <dwarf.h> 20 #include <string.h> 21 22 #include "libdwP.h" 23 24 25 size_t 26 internal_function_def 27 __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, unsigned int form, 28 unsigned char *valp) 29 { 30 unsigned char *saved; 31 unsigned int u128; 32 size_t result; 33 34 switch (form) 35 { 36 case DW_FORM_addr: 37 result = cu->address_size; 38 break; 39 40 case DW_FORM_strp: 41 case DW_FORM_ref_addr: 42 result = cu->offset_size; 43 break; 44 45 case DW_FORM_block1: 46 result = *valp + 1; 47 break; 48 49 case DW_FORM_block2: 50 result = read_2ubyte_unaligned (dbg, valp) + 2; 51 break; 52 53 case DW_FORM_block4: 54 result = read_4ubyte_unaligned (dbg, valp) + 4; 55 break; 56 57 case DW_FORM_block: 58 saved = valp; 59 get_uleb128 (u128, valp); 60 result = u128 + (valp - saved); 61 break; 62 63 case DW_FORM_ref1: 64 case DW_FORM_data1: 65 case DW_FORM_flag: 66 result = 1; 67 break; 68 69 case DW_FORM_data2: 70 case DW_FORM_ref2: 71 result = 2; 72 break; 73 74 case DW_FORM_data4: 75 case DW_FORM_ref4: 76 result = 4; 77 break; 78 79 case DW_FORM_data8: 80 case DW_FORM_ref8: 81 result = 8; 82 break; 83 84 case DW_FORM_string: 85 result = strlen ((char *) valp) + 1; 86 break; 87 88 case DW_FORM_sdata: 89 case DW_FORM_udata: 90 case DW_FORM_ref_udata: 91 saved = valp; 92 get_uleb128 (u128, valp); 93 result = valp - saved; 94 break; 95 96 case DW_FORM_indirect: 97 saved = valp; 98 get_uleb128 (u128, valp); 99 // XXX Is this really correct? 100 result = __libdw_form_val_len (dbg, cu, u128, valp); 101 if (result != (size_t) -1) 102 result += valp - saved; 103 break; 104 105 default: 106 __libdw_seterrno (DWARF_E_INVALID_DWARF); 107 result = (size_t) -1l; 108 break; 109 } 110 111 return result; 112 } 113