diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:28 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:29:28 -0800 |
commit | 441f72d43a9b550baa779fc82f70816da5f74f0e (patch) | |
tree | 477ac2b54c1ef5b8e25e4255b27bca9469ed3911 /libdw/dwarf_getmacros.c | |
parent | 7a80622f69812ca3262d2027c07a4ed0c0242945 (diff) | |
download | android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.tar.gz android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.tar.bz2 android_external_elfutils-441f72d43a9b550baa779fc82f70816da5f74f0e.zip |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libdw/dwarf_getmacros.c')
-rw-r--r-- | libdw/dwarf_getmacros.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c new file mode 100644 index 00000000..f6f933aa --- /dev/null +++ b/libdw/dwarf_getmacros.c @@ -0,0 +1,114 @@ +/* Get public symbol information. + Copyright (C) 2002, 2003, 2004 Red Hat, Inc. + Written by Ulrich Drepper <drepper@redhat.com>, 2002. + + This program is Open Source software; you can redistribute it and/or + modify it under the terms of the Open Software License version 1.0 as + published by the Open Source Initiative. + + You should have received a copy of the Open Software License along + with this program; if not, you may obtain a copy of the Open Software + License version 1.0 from http://www.opensource.org/licenses/osl.php or + by writing the Open Source Initiative c/o Lawrence Rosen, Esq., + 3001 King Ranch Road, Ukiah, CA 95482. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <dwarf.h> +#include <string.h> + +#include <libdwP.h> + + +ptrdiff_t +dwarf_getmacros (die, callback, arg, offset) + Dwarf_Die *die; + int (*callback) (Dwarf_Macro *, void *); + void *arg; + ptrdiff_t offset; +{ + /* Get the appropriate attribute. */ + Dwarf_Attribute attr; + if (dwarf_attr (die, DW_AT_macro_info, &attr) == NULL) + return -1; + + /* Offset into the .debug_macinfo section. */ + Dwarf_Word macoff; + if (dwarf_formudata (&attr, &macoff) != 0) + return -1; + + const unsigned char *readp + = die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + offset; + const unsigned char *readendp + = readp + die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_size; + + if (readp == readendp) + return 0; + + if (*readp != DW_MACINFO_start_file) + goto invalid; + + while (readp < readendp) + { + unsigned int opcode = *readp++; + unsigned int u128; + unsigned int u128_2 = 0; + const char *str = NULL; + const unsigned char *endp; + + switch (opcode) + { + case DW_MACINFO_define: + case DW_MACINFO_undef: + case DW_MACINFO_vendor_ext: + /* For the first two opcodes the parameters are + line, string + For the latter + number, string. + We can treat these cases together. */ + get_uleb128 (u128, readp); + + endp = memchr (readp, '\0', readendp - readp); + if (endp == NULL) + goto invalid; + + str = (char *) readp; + readp = endp + 1; + break; + + case DW_MACINFO_start_file: + /* The two parameters are line and file index. */ + get_uleb128 (u128, readp); + get_uleb128 (u128_2, readp); + break; + + case DW_MACINFO_end_file: + /* Nothing more to do. */ + return 0; + + default: + goto invalid; + } + + Dwarf_Macro mac; + mac.opcode = opcode; + mac.param1 = u128; + if (str == NULL) + mac.param2.u = u128_2; + else + mac.param2.s = str; + + if (callback (&mac, arg) != DWARF_CB_OK) + return (readp + - ((unsigned char *) die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + + offset)); + } + + /* If we come here the termination of the data for the CU is not + present. */ + invalid: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; +} |