diff options
author | Chih-hung Hsieh <chh@google.com> | 2015-09-25 14:51:48 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-09-25 14:51:48 +0000 |
commit | b0121c5547604527aaeea297b54047cd14b234df (patch) | |
tree | 7d9031ee3d5796de4a1825892fc6e04ba6e36ae2 /libdw/libdw_form.c | |
parent | d03895cf5f8b77c6a85abcd84ea0d80ff56be846 (diff) | |
parent | 5eafdf0f9bfd9a3c5f93414ac16bb399b6da0b7f (diff) | |
download | android_external_elfutils-b0121c5547604527aaeea297b54047cd14b234df.tar.gz android_external_elfutils-b0121c5547604527aaeea297b54047cd14b234df.tar.bz2 android_external_elfutils-b0121c5547604527aaeea297b54047cd14b234df.zip |
Merge "Move files up to match upstream source structure."
Diffstat (limited to 'libdw/libdw_form.c')
-rw-r--r-- | libdw/libdw_form.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/libdw/libdw_form.c b/libdw/libdw_form.c new file mode 100644 index 00000000..72e2390c --- /dev/null +++ b/libdw/libdw_form.c @@ -0,0 +1,132 @@ +/* Helper functions for form handling. + Copyright (C) 2003-2009, 2014 Red Hat, Inc. + This file is part of elfutils. + Written by Ulrich Drepper <drepper@redhat.com>, 2003. + + This file is free software; you can redistribute it and/or modify + it under the terms of either + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at + your option) any later version + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at + your option) any later version + + or both in parallel, as here. + + elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <dwarf.h> +#include <string.h> + +#include "libdwP.h" + + +size_t +internal_function +__libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form, + const unsigned char *valp) +{ + const unsigned char *startp = valp; + const unsigned char *endp = cu->endp; + Dwarf_Word u128; + size_t result; + + /* NB: This doesn't cover constant form lengths, which are + already handled by the inlined __libdw_form_val_len. */ + switch (form) + { + case DW_FORM_addr: + result = cu->address_size; + break; + + case DW_FORM_ref_addr: + result = cu->version == 2 ? cu->address_size : cu->offset_size; + break; + + case DW_FORM_strp: + case DW_FORM_sec_offset: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: + result = cu->offset_size; + break; + + case DW_FORM_block1: + if (unlikely ((size_t) (endp - startp) < 1)) + goto invalid; + result = *valp + 1; + break; + + case DW_FORM_block2: + if (unlikely ((size_t) (endp - startp) < 2)) + goto invalid; + result = read_2ubyte_unaligned (cu->dbg, valp) + 2; + break; + + case DW_FORM_block4: + if (unlikely ((size_t) (endp - startp) < 4)) + goto invalid; + result = read_4ubyte_unaligned (cu->dbg, valp) + 4; + break; + + case DW_FORM_block: + case DW_FORM_exprloc: + get_uleb128 (u128, valp, endp); + result = u128 + (valp - startp); + break; + + case DW_FORM_string: + { + const unsigned char *endstrp = memchr (valp, '\0', + (size_t) (endp - startp)); + if (unlikely (endstrp == NULL)) + goto invalid; + result = (size_t) (endstrp - startp) + 1; + break; + } + + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + get_uleb128 (u128, valp, endp); + result = valp - startp; + break; + + case DW_FORM_indirect: + get_uleb128 (u128, valp, endp); + // XXX Is this really correct? + result = __libdw_form_val_len (cu, u128, valp); + if (result != (size_t) -1) + result += valp - startp; + else + return (size_t) -1; + break; + + default: + goto invalid; + } + + if (unlikely (result > (size_t) (endp - startp))) + { + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + result = (size_t) -1; + } + + return result; +} |