Home | History | Annotate | Download | only in libdw
      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