00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "config.h"
00043 #include "dwarf_incl.h"
00044 #include <stdio.h>
00045 #include "dwarf_abbrev.h"
00046
00047 int
00048 dwarf_get_abbrev(Dwarf_Debug dbg,
00049 Dwarf_Unsigned offset,
00050 Dwarf_Abbrev * returned_abbrev,
00051 Dwarf_Unsigned * length,
00052 Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
00053 {
00054 Dwarf_Small *abbrev_ptr;
00055 Dwarf_Small *abbrev_section_end;
00056 Dwarf_Half attr;
00057 Dwarf_Half attr_form;
00058 Dwarf_Abbrev ret_abbrev;
00059 Dwarf_Unsigned labbr_count = 0;
00060 Dwarf_Unsigned utmp;
00061
00062
00063 if (dbg == NULL) {
00064 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00065 return (DW_DLV_ERROR);
00066 }
00067 if (dbg->de_debug_abbrev == 0) {
00068
00069
00070 int res = _dwarf_load_debug_info(dbg, error);
00071
00072 if (res != DW_DLV_OK) {
00073 return res;
00074 }
00075 }
00076
00077 if (offset >= dbg->de_debug_abbrev_size) {
00078 return (DW_DLV_NO_ENTRY);
00079 }
00080
00081
00082 ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
00083 if (ret_abbrev == NULL) {
00084 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00085 return (DW_DLV_ERROR);
00086 }
00087 ret_abbrev->ab_dbg = dbg;
00088 if (returned_abbrev == 0 || abbr_count == 0) {
00089 _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
00090 return (DW_DLV_ERROR);
00091 }
00092
00093
00094 *abbr_count = 0;
00095 if (length != NULL)
00096 *length = 1;
00097
00098 abbrev_ptr = dbg->de_debug_abbrev + offset;
00099 abbrev_section_end =
00100 dbg->de_debug_abbrev + dbg->de_debug_abbrev_size;
00101
00102 DECODE_LEB128_UWORD(abbrev_ptr, utmp);
00103 ret_abbrev->ab_code = (Dwarf_Word) utmp;
00104 if (ret_abbrev->ab_code == 0) {
00105 *returned_abbrev = ret_abbrev;
00106 *abbr_count = 0;
00107 if (length) {
00108 *length = 1;
00109 }
00110 return (DW_DLV_OK);
00111 }
00112
00113 DECODE_LEB128_UWORD(abbrev_ptr, utmp);
00114 ret_abbrev->ab_tag = utmp;
00115 ret_abbrev->ab_has_child = *(abbrev_ptr++);
00116 ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
00117
00118 do {
00119 Dwarf_Unsigned utmp2;
00120
00121 DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
00122 attr = (Dwarf_Half) utmp2;
00123 DECODE_LEB128_UWORD(abbrev_ptr, utmp2)
00124 attr_form = (Dwarf_Half) utmp2;
00125
00126 if (attr != 0)
00127 (labbr_count)++;
00128
00129 } while (abbrev_ptr < abbrev_section_end &&
00130 (attr != 0 || attr_form != 0));
00131
00132 if (abbrev_ptr > abbrev_section_end) {
00133 _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
00134 return (DW_DLV_ERROR);
00135 }
00136
00137 if (length != NULL)
00138 *length = abbrev_ptr - dbg->de_debug_abbrev - offset;
00139
00140 *returned_abbrev = ret_abbrev;
00141 *abbr_count = labbr_count;
00142 return (DW_DLV_OK);
00143 }
00144
00145 int
00146 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
00147 Dwarf_Unsigned * returned_code,
00148 Dwarf_Error * error)
00149 {
00150 if (abbrev == NULL) {
00151 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
00152 return (DW_DLV_ERROR);
00153 }
00154
00155 *returned_code = abbrev->ab_code;
00156 return (DW_DLV_OK);
00157 }
00158
00159 int
00160 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
00161 Dwarf_Half * returned_tag, Dwarf_Error * error)
00162 {
00163 if (abbrev == NULL) {
00164 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
00165 return (DW_DLV_ERROR);
00166 }
00167
00168 *returned_tag = abbrev->ab_tag;
00169 return (DW_DLV_OK);
00170 }
00171
00172
00173 int
00174 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
00175 Dwarf_Signed * returned_flag,
00176 Dwarf_Error * error)
00177 {
00178 if (abbrev == NULL) {
00179 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
00180 return (DW_DLV_ERROR);
00181 }
00182
00183 *returned_flag = abbrev->ab_has_child;
00184 return (DW_DLV_OK);
00185 }
00186
00187
00188 int
00189 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
00190 Dwarf_Signed index,
00191 Dwarf_Half * returned_attr_num,
00192 Dwarf_Signed * form,
00193 Dwarf_Off * offset, Dwarf_Error * error)
00194 {
00195 Dwarf_Byte_Ptr abbrev_ptr;
00196 Dwarf_Byte_Ptr abbrev_end;
00197 Dwarf_Byte_Ptr mark_abbrev_ptr;
00198 Dwarf_Half attr;
00199 Dwarf_Half attr_form;
00200
00201 if (index < 0)
00202 return (DW_DLV_NO_ENTRY);
00203
00204 if (abbrev == NULL) {
00205 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
00206 return (DW_DLV_ERROR);
00207 }
00208
00209 if (abbrev->ab_code == 0) {
00210 return (DW_DLV_NO_ENTRY);
00211 }
00212
00213 if (abbrev->ab_dbg == NULL) {
00214 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
00215 return (DW_DLV_ERROR);
00216 }
00217
00218 abbrev_ptr = abbrev->ab_abbrev_ptr;
00219 abbrev_end =
00220 abbrev->ab_dbg->de_debug_abbrev +
00221 abbrev->ab_dbg->de_debug_abbrev_size;
00222
00223 for (attr = 1, attr_form = 1;
00224 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
00225 attr_form != 0);
00226 index--) {
00227 Dwarf_Unsigned utmp4;
00228
00229 mark_abbrev_ptr = abbrev_ptr;
00230 DECODE_LEB128_UWORD(abbrev_ptr, utmp4)
00231 attr = (Dwarf_Half) utmp4;
00232 DECODE_LEB128_UWORD(abbrev_ptr, utmp4)
00233 attr_form = (Dwarf_Half) utmp4;
00234 }
00235
00236 if (abbrev_ptr >= abbrev_end) {
00237 _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
00238 return (DW_DLV_ERROR);
00239 }
00240
00241 if (index >= 0) {
00242 return (DW_DLV_NO_ENTRY);
00243 }
00244
00245 if (form != NULL)
00246 *form = attr_form;
00247 if (offset != NULL)
00248 *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev;
00249
00250 *returned_attr_num = (attr);
00251 return DW_DLV_OK;
00252 }