libbacktrace: pass -1 to error callback for unrecognized DWARF

PR libbacktrace/98818
	* dwarf.c (dwarf_buf_error): Add errnum parameter.  Change all
	callers.
	* backtrace.h: Update backtrace_error_callback comment.
This commit is contained in:
Ian Lance Taylor
2021-03-02 13:45:56 -08:00
parent 7854b0bc25
commit 59473f7906
2 changed files with 43 additions and 30 deletions

View File

@@ -54,13 +54,14 @@ struct backtrace_state;
invalid after this function returns. invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, but the function debug info can be found for the executable, or if the debug info
requires debug info (e.g., backtrace_full, backtrace_pcinfo). The exists but has an unsupported version, but the function requires
MSG in this case will be something along the lines of "no debug debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
info". Similarly, ERRNUM will be passed as -1 if there is no this case will be something along the lines of "no debug info".
symbol table, but the function requires a symbol table (e.g., Similarly, ERRNUM will be passed as -1 if there is no symbol table,
backtrace_syminfo). This may be used as a signal that some other but the function requires a symbol table (e.g., backtrace_syminfo).
approach should be tried. */ This may be used as a signal that some other approach should be
tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg, typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum); int errnum);

58
dwarf.c
View File

@@ -743,13 +743,13 @@ struct dwarf_data
/* Report an error for a DWARF buffer. */ /* Report an error for a DWARF buffer. */
static void static void
dwarf_buf_error (struct dwarf_buf *buf, const char *msg) dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
{ {
char b[200]; char b[200];
snprintf (b, sizeof b, "%s in %s at %d", snprintf (b, sizeof b, "%s in %s at %d",
msg, buf->name, (int) (buf->buf - buf->start)); msg, buf->name, (int) (buf->buf - buf->start));
buf->error_callback (buf->data, b, 0); buf->error_callback (buf->data, b, errnum);
} }
/* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on /* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
@@ -763,7 +763,7 @@ require (struct dwarf_buf *buf, size_t count)
if (!buf->reported_underflow) if (!buf->reported_underflow)
{ {
dwarf_buf_error (buf, "DWARF underflow"); dwarf_buf_error (buf, "DWARF underflow", 0);
buf->reported_underflow = 1; buf->reported_underflow = 1;
} }
@@ -925,7 +925,7 @@ read_address (struct dwarf_buf *buf, int addrsize)
case 8: case 8:
return read_uint64 (buf); return read_uint64 (buf);
default: default:
dwarf_buf_error (buf, "unrecognized address size"); dwarf_buf_error (buf, "unrecognized address size", 0);
return 0; return 0;
} }
} }
@@ -976,7 +976,7 @@ read_uleb128 (struct dwarf_buf *buf)
ret |= ((uint64_t) (b & 0x7f)) << shift; ret |= ((uint64_t) (b & 0x7f)) << shift;
else if (!overflow) else if (!overflow)
{ {
dwarf_buf_error (buf, "LEB128 overflows uint64_t"); dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
overflow = 1; overflow = 1;
} }
shift += 7; shift += 7;
@@ -1011,7 +1011,7 @@ read_sleb128 (struct dwarf_buf *buf)
val |= ((uint64_t) (b & 0x7f)) << shift; val |= ((uint64_t) (b & 0x7f)) << shift;
else if (!overflow) else if (!overflow)
{ {
dwarf_buf_error (buf, "signed LEB128 overflows uint64_t"); dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
overflow = 1; overflow = 1;
} }
shift += 7; shift += 7;
@@ -1151,7 +1151,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64); offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_STR]) if (offset >= dwarf_sections->size[DEBUG_STR])
{ {
dwarf_buf_error (buf, "DW_FORM_strp out of range"); dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
return 0; return 0;
} }
val->encoding = ATTR_VAL_STRING; val->encoding = ATTR_VAL_STRING;
@@ -1166,7 +1166,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64); offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_LINE_STR]) if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
{ {
dwarf_buf_error (buf, "DW_FORM_line_strp out of range"); dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
return 0; return 0;
} }
val->encoding = ATTR_VAL_STRING; val->encoding = ATTR_VAL_STRING;
@@ -1213,7 +1213,8 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
if (form == DW_FORM_implicit_const) if (form == DW_FORM_implicit_const)
{ {
dwarf_buf_error (buf, dwarf_buf_error (buf,
"DW_FORM_indirect to DW_FORM_implicit_const"); "DW_FORM_indirect to DW_FORM_implicit_const",
0);
return 0; return 0;
} }
return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64, return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
@@ -1346,7 +1347,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
} }
if (offset >= altlink->dwarf_sections.size[DEBUG_STR]) if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
{ {
dwarf_buf_error (buf, "DW_FORM_strp_sup out of range"); dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
return 0; return 0;
} }
val->encoding = ATTR_VAL_STRING; val->encoding = ATTR_VAL_STRING;
@@ -1355,7 +1356,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
return 1; return 1;
} }
default: default:
dwarf_buf_error (buf, "unrecognized DWARF form"); dwarf_buf_error (buf, "unrecognized DWARF form", -1);
return 0; return 0;
} }
} }
@@ -1404,7 +1405,9 @@ resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
offset = read_offset (&offset_buf, is_dwarf64); offset = read_offset (&offset_buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_STR]) if (offset >= dwarf_sections->size[DEBUG_STR])
{ {
dwarf_buf_error (&offset_buf, "DW_FORM_strx offset out of range"); dwarf_buf_error (&offset_buf,
"DW_FORM_strx offset out of range",
0);
return 0; return 0;
} }
*string = (const char *) dwarf_sections->data[DEBUG_STR] + offset; *string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
@@ -2212,7 +2215,7 @@ add_ranges_from_rnglists (
break; break;
default: default:
dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value"); dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
return 0; return 0;
} }
} }
@@ -2479,7 +2482,7 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
version = read_uint16 (&unit_buf); version = read_uint16 (&unit_buf);
if (version < 2 || version > 5) if (version < 2 || version > 5)
{ {
dwarf_buf_error (&unit_buf, "unrecognized DWARF version"); dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
goto fail; goto fail;
} }
@@ -2758,7 +2761,8 @@ read_v2_paths (struct backtrace_state *state, struct unit *u,
{ {
dwarf_buf_error (hdr_buf, dwarf_buf_error (hdr_buf,
("invalid directory index in " ("invalid directory index in "
"line number program header")); "line number program header"),
0);
return 0; return 0;
} }
dir_len = strlen (dir); dir_len = strlen (dir);
@@ -2827,7 +2831,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
{ {
dwarf_buf_error (hdr_buf, dwarf_buf_error (hdr_buf,
("invalid directory index in " ("invalid directory index in "
"line number program header")); "line number program header"),
0);
return 0; return 0;
} }
dir = hdr->dirs[val.u.uint]; dir = hdr->dirs[val.u.uint];
@@ -2842,7 +2847,8 @@ read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
if (path == NULL) if (path == NULL)
{ {
dwarf_buf_error (hdr_buf, dwarf_buf_error (hdr_buf,
"missing file name in line number program header"); "missing file name in line number program header",
0);
return 0; return 0;
} }
@@ -2969,7 +2975,7 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
hdr->version = read_uint16 (line_buf); hdr->version = read_uint16 (line_buf);
if (hdr->version < 2 || hdr->version > 5) if (hdr->version < 2 || hdr->version > 5)
{ {
dwarf_buf_error (line_buf, "unsupported line number version"); dwarf_buf_error (line_buf, "unsupported line number version", -1);
return 0; return 0;
} }
@@ -2983,7 +2989,8 @@ read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
if (read_byte (line_buf) != 0) if (read_byte (line_buf) != 0)
{ {
dwarf_buf_error (line_buf, dwarf_buf_error (line_buf,
"non-zero segment_selector_size not supported"); "non-zero segment_selector_size not supported",
-1);
return 0; return 0;
} }
} }
@@ -3124,7 +3131,8 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
{ {
dwarf_buf_error (line_buf, dwarf_buf_error (line_buf,
("invalid directory index " ("invalid directory index "
"in line number program")); "in line number program"),
0);
return 0; return 0;
} }
dir_len = strlen (dir); dir_len = strlen (dir);
@@ -3190,7 +3198,8 @@ read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
{ {
dwarf_buf_error (line_buf, dwarf_buf_error (line_buf,
("invalid file number in " ("invalid file number in "
"line number program")); "line number program"),
0);
return 0; return 0;
} }
filename = hdr->filenames[fileno]; filename = hdr->filenames[fileno];
@@ -3425,7 +3434,9 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u,
code = read_uleb128 (&unit_buf); code = read_uleb128 (&unit_buf);
if (code == 0) if (code == 0)
{ {
dwarf_buf_error (&unit_buf, "invalid abstract origin or specification"); dwarf_buf_error (&unit_buf,
"invalid abstract origin or specification",
0);
return NULL; return NULL;
} }
@@ -3628,7 +3639,8 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
{ {
dwarf_buf_error (unit_buf, dwarf_buf_error (unit_buf,
("invalid file number in " ("invalid file number in "
"DW_AT_call_file attribute")); "DW_AT_call_file attribute"),
0);
return 0; return 0;
} }
function->caller_filename = function->caller_filename =