From 77c57a8ad70e4052a986d3dc76f30de7c3f03393 Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Tue, 4 Jul 2017 01:09:01 +0100 Subject: [PATCH] ctf: handle the bit_offset in members with a DW_FORM_block data_member_location When building a SPARC kernel with GCC 6, the following failure is observed at CTF generation time: Internal error: within file arch/sparc/built-in.o, module vmlinux, type at DIE offset 3fe447 with ID ////unsigned int:23:0 was not already noted by detect_duplicates(). This is because the bit-field in question (include/math-emu/single.h:_FP_UNION_S.frac) is at offset 1, not 0: the type ID being emitted should be ////unsigned int:23:1. We are not correctly handling the case where a bit-field at nonzero offset has its data_member_location represented by a DW_FORM_block: we were erroneously only considering the bit offset when the form was DW_FORM_*data* (i.e. a simple constant), because I assumed that in this situation the DW_AT_data_member_location would track the location at bit granularity. This is obviously wrong: no matter what form it's in, the data_member_location is a count of bytes. It can't suddenly turn into a count of bits just because it's not being represented as a simple constant! So promote the bit-offset handling to apply to all data_member_locations, regardless of form. Signed-off-by: Nick Alcock Reviewed-by: Tomas Jedlicka Orabug: 26387109 --- scripts/dwarf2ctf/dwarf2ctf.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index 96272364067d..59f3ad02c88f 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -3888,16 +3888,6 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name, dwarf_formudata(&location_attr, &location); offset = location * 8; } - - if (private_dwarf_hasattr(die, DW_AT_bit_offset)) { - Dwarf_Attribute bit_attr; - Dwarf_Word bit; - - private_dwarf_attr(die, DW_AT_bit_offset, - &bit_attr); - dwarf_formudata(&bit_attr, &bit); - bit_offset = bit; - } break; } case DW_FORM_block1: @@ -3958,7 +3948,20 @@ static ctf_id_t assemble_ctf_su_member(const char *module_name, exit(1); } } - /* Fall through. */ + + /* + * Handle the bit offset. + */ + if (private_dwarf_hasattr(die, DW_AT_bit_offset)) { + Dwarf_Attribute bit_attr; + Dwarf_Word bit; + + private_dwarf_attr(die, DW_AT_bit_offset, + &bit_attr); + dwarf_formudata(&bit_attr, &bit); + bit_offset = bit; + } + } else { /* No offset beyond any override. */ die_override_t *o; -- 2.50.1