commit 70a93a144c1654a677a069db51c437e2659a544b Author: Mark Johnston Date: Mon Jan 30 10:43:19 2023 -0500 libdwarf: Some very partial DWARF 5 support diff --git a/contrib/elftoolchain/libdwarf/_libdwarf.h b/contrib/elftoolchain/libdwarf/_libdwarf.h index 68a4c61522fa..f68f90831a32 100644 --- a/contrib/elftoolchain/libdwarf/_libdwarf.h +++ b/contrib/elftoolchain/libdwarf/_libdwarf.h @@ -95,6 +95,7 @@ struct _Dwarf_AttrDef { Dwarf_Half ad_attrib; /* DW_AT_XXX */ Dwarf_Half ad_form; /* DW_FORM_XXX */ uint64_t ad_offset; /* Offset in abbrev section. */ + int64_t ad_value; /* XXX-MJ */ STAILQ_ENTRY(_Dwarf_AttrDef) ad_next; /* Next attribute define. */ }; @@ -330,6 +331,7 @@ struct _Dwarf_CU { uint8_t cu_pointer_size;/* Number of bytes in pointer. */ uint8_t cu_dwarf_size; /* CU section dwarf size. */ Dwarf_Sig8 cu_type_sig; /* Type unit's signature. */ + uint8_t cu_unit_type; /* CU type, see DW_UT_* constants. */ uint64_t cu_type_offset; /* Type unit's type offset. */ Dwarf_Off cu_next_offset; /* Offset to the next CU. */ uint64_t cu_1st_offset; /* First DIE offset. */ @@ -428,6 +430,8 @@ struct _Dwarf_Debug { char *dbg_strtab; /* Dwarf string table. */ Dwarf_Unsigned dbg_strtab_cap; /* Dwarf string table capacity. */ Dwarf_Unsigned dbg_strtab_size; /* Dwarf string table size. */ + char *dbg_line_strtab; /* XXX-MJ */ + Dwarf_Unsigned dbg_line_strtab_size; STAILQ_HEAD(, _Dwarf_MacroSet) dbg_mslist; /* List of macro set. */ STAILQ_HEAD(, _Dwarf_Rangelist) dbg_rllist; /* List of rangelist. */ uint64_t (*read)(uint8_t *, uint64_t *, int); @@ -507,7 +511,8 @@ int _dwarf_attr_init(Dwarf_Debug, Dwarf_Section *, uint64_t *, int, Dwarf_CU, Dwarf_Die, Dwarf_AttrDef, uint64_t, int, Dwarf_Error *); int _dwarf_attrdef_add(Dwarf_Debug, Dwarf_Abbrev, uint64_t, - uint64_t, uint64_t, Dwarf_AttrDef *, Dwarf_Error *); + uint64_t, uint64_t, int64_t, Dwarf_AttrDef *, + Dwarf_Error *); uint64_t _dwarf_decode_lsb(uint8_t **, int); uint64_t _dwarf_decode_msb(uint8_t **, int); int64_t _dwarf_decode_sleb128(uint8_t **); @@ -640,6 +645,7 @@ int _dwarf_strtab_add(Dwarf_Debug, char *, uint64_t *, void _dwarf_strtab_cleanup(Dwarf_Debug); int _dwarf_strtab_gen(Dwarf_P_Debug, Dwarf_Error *); char *_dwarf_strtab_get_table(Dwarf_Debug); +char *_dwarf_strtab_get_line_str_table(Dwarf_Debug); int _dwarf_strtab_init(Dwarf_Debug, Dwarf_Error *); void _dwarf_type_unit_cleanup(Dwarf_Debug); void _dwarf_write_block(void *, uint64_t *, uint8_t *, uint64_t); diff --git a/contrib/elftoolchain/libdwarf/dwarf_attrval.c b/contrib/elftoolchain/libdwarf/dwarf_attrval.c index 9a2f791b2b40..49e603209426 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_attrval.c +++ b/contrib/elftoolchain/libdwarf/dwarf_attrval.c @@ -206,6 +206,7 @@ dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwa case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: + case DW_FORM_implicit_const: *valp = at->u[0].u64; break; default: diff --git a/contrib/elftoolchain/libdwarf/dwarf_form.c b/contrib/elftoolchain/libdwarf/dwarf_form.c index a9a22cbe4e2f..55559a5a9d65 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_form.c +++ b/contrib/elftoolchain/libdwarf/dwarf_form.c @@ -390,6 +390,10 @@ dwarf_formstring(Dwarf_Attribute at, char **return_string, *return_string = (char *) at->u[1].s; ret = DW_DLV_OK; break; + case DW_FORM_line_strp: + *return_string = (char *) at->u[1].s; + ret = DW_DLV_OK; + break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); ret = DW_DLV_ERROR; @@ -403,6 +407,7 @@ dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr, Dwarf_Half offset_size, Dwarf_Half form) { + /* XXX-MJ need updates for other new forms */ switch (form) { case DW_FORM_addr: return (DW_FORM_CLASS_ADDRESS); @@ -413,6 +418,7 @@ dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr, return (DW_FORM_CLASS_BLOCK); case DW_FORM_string: case DW_FORM_strp: + case DW_FORM_line_strp: return (DW_FORM_CLASS_STRING); case DW_FORM_flag: case DW_FORM_flag_present: diff --git a/contrib/elftoolchain/libdwarf/libdwarf.h b/contrib/elftoolchain/libdwarf/libdwarf.h index b1f9e0c8abc7..1f07482c5d75 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf.h +++ b/contrib/elftoolchain/libdwarf/libdwarf.h @@ -336,6 +336,7 @@ enum { DW_DLE_DEBUG_MACRO_INCONSISTENT,/* Invalid macinfo data. */ DW_DLE_ELF_SECT_ERR, /* Application callback failed. */ DW_DLE_COMPRESSION, /* Section decompression error. */ + DW_DLE_UNKNOWN_CU_TYPE, /* Unknown compilation unit type. */ DW_DLE_NUM /* Max error number. */ }; @@ -600,6 +601,7 @@ int dwarf_get_MACINFO_name(unsigned, const char **); int dwarf_get_OP_name(unsigned, const char **); int dwarf_get_ORD_name(unsigned, const char **); int dwarf_get_TAG_name(unsigned, const char **); +int dwarf_get_UT_name(unsigned, const char **); int dwarf_get_VIRTUALITY_name(unsigned, const char **); int dwarf_get_VIS_name(unsigned, const char **); int dwarf_get_abbrev(Dwarf_Debug, Dwarf_Unsigned, Dwarf_Abbrev *, diff --git a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c index ff3a385f197f..d8d7ca1b2901 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c @@ -65,7 +65,8 @@ _dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, int _dwarf_attrdef_add(Dwarf_Debug dbg, Dwarf_Abbrev ab, uint64_t attr, - uint64_t form, uint64_t adoff, Dwarf_AttrDef *adp, Dwarf_Error *error) + uint64_t form, uint64_t adoff, int64_t value, Dwarf_AttrDef *adp, + Dwarf_Error *error) { Dwarf_AttrDef ad; @@ -83,6 +84,7 @@ _dwarf_attrdef_add(Dwarf_Debug dbg, Dwarf_Abbrev ab, uint64_t attr, ad->ad_attrib = attr; ad->ad_form = form; ad->ad_offset = adoff; + ad->ad_value = value; /* Add the attribute definition to the list in the abbrev. */ STAILQ_INSERT_TAIL(&ab->ab_attrdef, ad, ad_next); @@ -107,6 +109,7 @@ _dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, uint64_t aboff; uint64_t adoff; uint64_t tag; + int64_t value; uint8_t children; int ret; @@ -140,9 +143,11 @@ _dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, adoff = *offset; attr = _dwarf_read_uleb128(ds->ds_data, offset); form = _dwarf_read_uleb128(ds->ds_data, offset); + value = form == DW_FORM_implicit_const ? + _dwarf_read_sleb128(ds->ds_data, offset) : 0; if (attr != 0) if ((ret = _dwarf_attrdef_add(dbg, *abp, attr, - form, adoff, NULL, error)) != DW_DLE_NONE) + form, adoff, value, NULL, error)) != DW_DLE_NONE) return (ret); } while (attr != 0); diff --git a/contrib/elftoolchain/libdwarf/libdwarf_attr.c b/contrib/elftoolchain/libdwarf/libdwarf_attr.c index a25deedaa5b1..83bca805399e 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_attr.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_attr.c @@ -193,6 +193,14 @@ _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, /* This form has no value encoded in the DIE. */ atref.u[0].u64 = 1; break; + case DW_FORM_line_strp: + atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); + atref.u[1].s = _dwarf_strtab_get_line_str_table(dbg) + + atref.u[0].u64; + break; + case DW_FORM_implicit_const: + atref.u[0].s64 = ad->ad_value; + break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); ret = DW_DLE_ATTR_FORM_BAD; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_die.c b/contrib/elftoolchain/libdwarf/libdwarf_die.c index 928a74fc2e6b..c96182e16712 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_die.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_die.c @@ -342,7 +342,7 @@ _dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, return (ret); STAILQ_FOREACH(at, &die->die_attr, at_next) { ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib, - at->at_form, 0, NULL, error); + at->at_form, 0, 0, NULL, error); if (ret != DW_DLE_NONE) return (ret); } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c index 68062ee3209f..cb266c44e52a 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c @@ -40,6 +40,7 @@ static const char *debug_name[] = { ".eh_frame", ".debug_macinfo", ".debug_str", + ".debug_line_str", ".debug_loc", ".debug_pubtypes", ".debug_ranges", diff --git a/contrib/elftoolchain/libdwarf/libdwarf_info.c b/contrib/elftoolchain/libdwarf/libdwarf_info.c index 74765930aaed..d519227d4d8f 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_info.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_info.c @@ -201,14 +201,29 @@ _dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, dbg->dbg_types_off = next_offset; /* Initialise the compilation unit. */ - cu->cu_length = length; - cu->cu_length_size = (dwarf_size == 4 ? 4 : 12); - cu->cu_version = dbg->read(ds->ds_data, &offset, 2); - cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, - dwarf_size); + cu->cu_length = length; + cu->cu_length_size = (dwarf_size == 4 ? 4 : 12); + cu->cu_version = dbg->read(ds->ds_data, &offset, 2); + if (cu->cu_version == 5) { + cu->cu_unit_type = dbg->read(ds->ds_data, &offset, 1); + if (cu->cu_unit_type != DW_UT_compile) { + DWARF_SET_ERROR(dbg, error, + DW_DLE_UNKNOWN_CU_TYPE); + ret = DW_DLE_UNKNOWN_CU_TYPE; + break; + } + cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, + 1); + cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + } else { + cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, + dwarf_size); + cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, + 1); + } cu->cu_abbrev_offset_cur = cu->cu_abbrev_offset; - cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1); - cu->cu_next_offset = next_offset; + cu->cu_next_offset = next_offset; /* .debug_types extra fields. */ if (!is_info) { @@ -225,7 +240,7 @@ _dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, else STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next); - if (cu->cu_version < 2 || cu->cu_version > 4) { + if (cu->cu_version < 2 || cu->cu_version > 5) { DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); ret = DW_DLE_VERSION_STAMP_ERROR; break; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c index 9dddbea6c459..dc745ba39170 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_lineno.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_lineno.c @@ -298,6 +298,9 @@ _dwarf_lineno_init(Dwarf_Die die, uint64_t offset, Dwarf_Error *error) case DW_FORM_string: compdir = at->u[0].s; break; + case DW_FORM_line_strp: + compdir = at->u[1].s; + break; default: break; } diff --git a/contrib/elftoolchain/libdwarf/libdwarf_str.c b/contrib/elftoolchain/libdwarf/libdwarf_str.c index 0c1ccac5ae97..e89a7da375b5 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_str.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_str.c @@ -68,6 +68,13 @@ _dwarf_strtab_get_table(Dwarf_Debug dbg) return (dbg->dbg_strtab); } +char * +_dwarf_strtab_get_line_str_table(Dwarf_Debug dbg) +{ + + return (dbg->dbg_line_strtab); +} + int _dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error) { @@ -76,6 +83,15 @@ _dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error) assert(dbg != NULL); if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) { + ds = _dwarf_find_section(dbg, ".debug_line_str"); + if (ds != NULL) { + dbg->dbg_line_strtab = ds->ds_data; + dbg->dbg_line_strtab_size = ds->ds_size; + } else { + dbg->dbg_line_strtab = NULL; + dbg->dbg_line_strtab_size = 0; + } + ds = _dwarf_find_section(dbg, ".debug_str"); if (ds == NULL) { dbg->dbg_strtab = NULL;