* [committed] Handle DW_AT_language not encoded using DW_FORM_data{1,2}
@ 2020-01-01 0:00 Tom de Vries
0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2020-01-01 0:00 UTC (permalink / raw)
To: dwz, jakub
Hi,
Currently we handle DW_AT_language attributes encoded using
DW_FORM_data1 and DW_FORM_data2.
However, dwarf assembly test cases from the gdb testsuite typically use
something like this:
...
{DW_AT_language @DW_LANG_C}
...
where the '@' prefix forces encoding using DW_FORM_sdata.
The DW_FORM_sdata encoding will cause the DW_AT_language attribute to be
ignored.
Fix this by handling the DW_AT_language attribute encoded using any constant
class encoding.
Committed to trunk.
Thanks,
- Tom
Handle DW_AT_language not encoded using DW_FORM_data{1,2}
2020-02-17 Tom de Vries <tdevries@suse.de>
* dwz.c (read_u16): New macro.
(read_lang): New function.
(read_debug_info): Read DW_AT_language encoded using DW_FORM_data{4,8}
and DW_FORM_{s,u}data.
---
dwz.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 92 insertions(+), 3 deletions(-)
diff --git a/dwz.c b/dwz.c
index 5748f6f..bfc320e 100644
--- a/dwz.c
+++ b/dwz.c
@@ -397,6 +397,63 @@ typedef struct
} \
while (0)
+/* Macro to parse a uint16_t value represented using form, return it and
+ update ptr to the end of the value at the same time. If the value doesn't
+ fit, assign true to error_p. */
+#define read_u16(ptr, form, error_p) \
+ ({ \
+ uint16_t ret = 0; \
+ switch (form) \
+ { \
+ case DW_FORM_data1: \
+ ret = read_8 (ptr); \
+ break; \
+ case DW_FORM_data2: \
+ ret = read_16 (ptr); \
+ break; \
+ case DW_FORM_data4: \
+ { \
+ uint32_t res = read_32 (ptr); \
+ ret = (uint16_t)res; \
+ if ((uint32_t)ret != res) \
+ error_p = true; \
+ break; \
+ } \
+ case DW_FORM_data8: \
+ { \
+ uint64_t res = read_64 (ptr); \
+ ret = (uint16_t)res; \
+ if ((uint64_t)ret != res) \
+ error_p = true; \
+ break; \
+ } \
+ case DW_FORM_udata: \
+ { \
+ uint64_t res = read_uleb128 (ptr); \
+ ret = (uint16_t)res; \
+ if ((uint64_t)ret != res) \
+ error_p = true; \
+ break; \
+ } \
+ case DW_FORM_sdata: \
+ { \
+ union { \
+ uint64_t u; \
+ int64_t i; \
+ } res; \
+ res.u = read_sleb128 (ptr); \
+ ret = (uint16_t)res.u; \
+ if (res.i < 0 || (uint64_t)ret != res.u) \
+ error_p = true; \
+ break; \
+ } \
+ default: \
+ error_p = true; \
+ break; \
+ } \
+ ret; \
+ })
+
/* Pointer size in the debug info, in bytes. Only debug info
with a single pointer size are handled. */
static int ptr_size;
@@ -5592,6 +5649,23 @@ try_debug_info (DSO *dso)
return ret;
}
+/* Read language attribute encoded using FORM from location PTR, return
+ pointer to location after the attribute. Assign the attribute value
+ to *LANG. */
+static unsigned char *
+read_lang (unsigned char *ptr, enum dwarf_form form,
+ enum dwarf_source_language *lang)
+{
+ bool error_p = false;
+ *lang = read_u16 (ptr, form, error_p);
+ if (unlikely (error_p))
+ {
+ *lang = 0;
+ error (0, 0, "Invalid DW_AT_language attribute, ignoring");
+ }
+ return ptr;
+}
+
/* First phase of the DWARF compression. Parse .debug_info section
(for kind == DEBUG_INFO) or .debug_types section (for kind == DEBUG_TYPES)
for each CU in it construct internal representation for the CU
@@ -6007,19 +6081,34 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
case DW_FORM_ref2:
ptr += 2;
break;
- case DW_FORM_ref4:
case DW_FORM_data4:
+ if (odr && die->die_tag == DW_TAG_compile_unit
+ && t->attr[i].attr == DW_AT_language)
+ read_lang (ptr, form, &cu->lang);
+ /* FALLTHRU */
+ case DW_FORM_ref4:
case DW_FORM_sec_offset:
ptr += 4;
break;
- case DW_FORM_ref8:
case DW_FORM_data8:
+ if (odr && die->die_tag == DW_TAG_compile_unit
+ && t->attr[i].attr == DW_AT_language)
+ read_lang (ptr, form, &cu->lang);
+ /* FALLTHRU */
+ case DW_FORM_ref8:
case DW_FORM_ref_sig8:
ptr += 8;
break;
case DW_FORM_sdata:
- case DW_FORM_ref_udata:
case DW_FORM_udata:
+ if (odr && die->die_tag == DW_TAG_compile_unit
+ && t->attr[i].attr == DW_AT_language)
+ {
+ ptr = read_lang (ptr, form, &cu->lang);
+ break;
+ }
+ /* FALLTHRU */
+ case DW_FORM_ref_udata:
read_uleb128 (ptr);
break;
case DW_FORM_strp:
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-02-17 11:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-01 0:00 [committed] Handle DW_AT_language not encoded using DW_FORM_data{1,2} Tom de Vries
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).