public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
From: "guillermo.e.martinez at oracle dot com" <sourceware-bugzilla@sourceware.org>
To: libabigail@sourceware.org
Subject: [Bug default/29811] extern array declaration following by its definition reports different sizes in DWARF vs CTF
Date: Thu, 22 Dec 2022 15:27:05 +0000	[thread overview]
Message-ID: <bug-29811-9487-Jn4w78IT7e@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-29811-9487@http.sourceware.org/bugzilla/>

https://sourceware.org/bugzilla/show_bug.cgi?id=29811

--- Comment #2 from Guillermo E. Martinez <guillermo.e.martinez at oracle dot com> ---
Hello Dodji,

Thanks for this great explanation!

(In reply to Guillermo E. Martinez from comment #0)
> The following C code generates a infinite subrange length using DWARF
> front-end.
> 
> extern unsigned int is_basic_table[];
> 
> unsigned int is_basic_table [] =
>   {
>     0,
>   };
> 
> <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='infinite'
> alignment-in-bits='32' id='type-id-2'>
>       <subrange length='infinite' type-id='type-id-3' id='type-id-4'/>
>     </array-type-def>
> 
> 
> Using CTF:
> 
>   <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='32'
> id='type-id-2'>
>       <subrange length='1' type-id='type-id-3' id='type-id-4'/>
>     </array-type-def>
> 
> Thus, abidiff abi-ctf.xml abi-dwarf.xml, reports:
> 
> 1 Changed variable:                                                         
> 
>                                                                             
> 
>   [C] 'unsigned int is_basic_table[]' was changed at
> test-extern-array.c:3:1:                                                    
> 
>     type of variable changed:                                               
> 
>       array element type 'unsigned int' changed:                            
> 
>         type size hasn't changed                                            
> 
>         type alignment changed from 32 to 0                                 
> 
>       type size hasn't changed                                              
> 
>       type alignment changed from 32 to 0
> 
> The symbol size showed by objdump:
> 
>   0000000000000000 g     O .bss   0000000000000004 is_basic_table
> 
> Thanks.

(In reply to dodji from comment #1)
> Hello,
> 
> > The following C code generates a infinite subrange length using DWARF
> > front-end.
> >
> > extern unsigned int is_basic_table[];
> >
> > unsigned int is_basic_table [] =
> >   {
> >     0,
> >   };
> 
> So, the declaration unsigned int is_basic_table[] is a declaration of an
> array of "unknown" size.  So, the type of is_basic_table is "array of
> unsigned int, of unknown size".  In this particular case, is_basic_table
> is initialized with an array of one element of type unsigned int.
> 
> So, let's look at what DWARF description of this looks like:
> 
> $ cat test.c
> extern unsigned int is_basic_table[];
> 
> unsigned int is_basic_table [] =
>   {
>     0,
>   };
> $ 
> $ gcc -g -c test.c
> $
> $ eu-readelf --debug-dump=info test.o | cat -n
>      1	
>      2	DWARF section [ 4] '.debug_info' at offset 0x40:
>      3	 [Offset]
>      4	 Compilation unit at offset 0:
>      5	 Version: 5, Abbreviation section offset: 0, Address size: 8, Offset
> size: 4
>      6	 Unit type: compile (1)
>      7	 [     c]  compile_unit         abbrev: 3
>      8	           producer             (strp) "GNU C17 11.3.1 20221121 (Red
> Hat 11.3.1-4) -mtune=generic -march=x86-64-v2 -g"
>      9	           language             (data1) C11 (29)
>     10	           name                 (line_strp) "test.c"
>     11	           comp_dir             (line_strp)
> "/home/dodji/git/libabigail/fixes/prtests/PR29811"
>     12	           stmt_list            (sec_offset) 0
>     13	 [    1e]    array_type           abbrev: 1
>     14	             type                 (ref4) [    29]
>     15	             sibling              (ref4) [    29]
>     16	 [    27]      subrange_type        abbrev: 4
>     17	 [    29]    base_type            abbrev: 2
>     18	             byte_size            (data1) 4
>     19	             encoding             (implicit_const) unsigned (7)
>     20	             name                 (strp) "unsigned int"
>     21	 [    2f]    variable             abbrev: 5
>     22	             name                 (strp) "is_basic_table"
>     23	             decl_file            (data1) test.c (1)
>     24	             decl_line            (data1) 1
>     25	             decl_column          (data1) 21
>     26	             type                 (ref4) [    1e]
>     27	             external             (flag_present) yes
>     28	             declaration          (flag_present) yes
>     29	 [    3b]    array_type           abbrev: 1
>     30	             type                 (ref4) [    29]
>     31	             sibling              (ref4) [    4b]
>     32	 [    44]      subrange_type        abbrev: 6
>     33	               type                 (ref4) [    4b]
>     34	               upper_bound          (data1) 0
>     35	 [    4b]    base_type            abbrev: 2
>     36	             byte_size            (data1) 8
>     37	             encoding             (implicit_const) unsigned (7)
>     38	             name                 (strp) "long unsigned int"
>     39	 [    51]    variable             abbrev: 7
>     40	             specification        (ref4) [    2f]
>     41	             decl_line            (data1) 3
>     42	             decl_column          (data1) 14
>     43	             type                 (ref4) [    3b]
>     44	             location             (exprloc) 
>     45	              [ 0] addr .bss+0 <is_basic_table>
> $ 
> 
> From line 21 to line 26, we see that the Debug Information Entry (a.k.a DIE)
> that describes the variable is_basic_table is the following:
> 
>     21	 [    2f]    variable             abbrev: 5
>     22	             name                 (strp) "is_basic_table"
>     23	             decl_file            (data1) test.c (1)
>     24	             decl_line            (data1) 1
>     25	             decl_column          (data1) 21
>     26	             type                 (ref4) [    1e]
> 
> At line 26, we see that the the value of "type" attribute of the
> variable DIE is 0x1e.  Which means that the DIE describing the type of
> the is_basic_table variable is the DIE which offset is 0x1e.
> 
> That DIE which offset 0x1e is at line 13:
> 
>     13	 [    1e]    array_type           abbrev: 1
>     14	             type                 (ref4) [    29]
>     15	             sibling              (ref4) [    29]
> 
> As you can see there, that DIE has no "size" attribute.  That is in line
> with the type of is_basic_table, as declared in the C source code, which
> is "Array of unknown size".
> 

So, Is it a limitation of DWARF info?


> That is what libabigail expresses by the keyword "infinite".  I probably
> could have chosen a better keyword here ;-)  Anyway, "infinite" really means
> "unknown" here.
> 
> But then, you are right in saying that:
> 
> > The symbol size showed by objdump:
> >   0000000000000000 g     O .bss   0000000000000004 is_basic_table
> 
> That is the symbol view of things.  Note the type description as
> written in the source code.
> 
> In other words, the size "4" there is the size of the ELF symbol
> is_basic_table, which is the ELF symbol for the is_basic_table C
> variable.
> 

Right, just that it is limited to _symbol_information not saying much about of
type symbol, it is most evident when we use abidiff changing the array size,
using CTF and DWARF front-end (e.g I changed the array's elements to two):

$ abidiff test-01.o test-02.o

Functions changes summary: 0 Removed, 0 Changed, 0 Added function               
  Variables changes summary: 0 Removed, 1 Changed, 0 Added variable             

  1 Changed variable:                                                           

    [C] 'unsigned int is_basic_table[]' was changed at test03.c:1:1:            
      size of symbol changed from 4 to 8                                        

$ abidiff --ctf test-01.o test-02.o

Functions changes summary: 0 Removed, 0 Changed, 0 Added function               
  Variables changes summary: 0 Removed, 1 Changed, 0 Added variable             

  1 Changed variable:                                                           

    [C] 'unsigned int is_basic_table[1]' was changed to 'unsigned int
is_basic_table[2]':                                                             
      size of symbol changed from 4 to 8                                        
      type of variable changed:                                                 
        type name changed from 'unsigned int[1]' to 'unsigned int[2]'           
        array type size changed from 32 to 64                                   
        array type subrange 1 changed length from 1 to 2

> The ELF symbol named "is_basic_table" is described by libabigail as can
> been seen by doing:
> 
>     $ /home/dodji/git/libabigail/fixes/build/tools/abidw test.o
>          1	<abi-corpus version='2.1' path='test.o'
> architecture='elf-amd-x86_64'>
>          2	  <elf-variable-symbols>
>          3	    <elf-symbol name='is_basic_table' size='4' type='object-type'
> binding='global-binding' visibility='default-visibility' is-defined='yes'/>
>          4	  </elf-variable-symbols>
>          5	  <abi-instr address-size='64' path='test.c'
> comp-dir-path='/home/dodji/git/libabigail/fixes/prtests/PR29811'
> language='LANG_C11'>
>          6	    <type-decl name='unsigned int' size-in-bits='32'
> id='type-id-1'/>
>          7	    <array-type-def dimensions='1' type-id='type-id-1'
> size-in-bits='32' id='type-id-2'>
>          8	      <subrange length='1' type-id='type-id-3' id='type-id-4'/>
>          9	    </array-type-def>
>         10	    <array-type-def dimensions='1' type-id='type-id-1'
> size-in-bits='infinite' id='type-id-5'>
>         11	      <subrange length='infinite' id='type-id-6'/>
>         12	    </array-type-def>
>         13	    <type-decl name='unsigned long int' size-in-bits='64'
> id='type-id-3'/>
>         14	    <var-decl name='is_basic_table' type-id='type-id-5'
> mangled-name='is_basic_table' visibility='default'
> filepath='/home/dodji/git/libabigail/fixes/prtests/PR29811/test.c' line='1'
> column='1' elf-symbol-id='is_basic_table'/>
>         15	  </abi-instr>
>         16	</abi-corpus>
>     $
> 
> At line 3, we can see:
> 
> <elf-symbol name='is_basic_table' size='4' type='object-type'
> binding='global-binding' visibility='default-visibility' is-defined='yes'/>
> 
> So we see that the symbol is_basic_table has a size of 4.
> 
> So I think that today, all the information is kept in the model: what
> the source code said, and what the actual symbol looks like.
> 
> Let's look at what the comparison & reporting engine are saying when
> comparing the IRs of DWARF against CTF:
> 
> > Thus, abidiff abi-ctf.xml abi-dwarf.xml, reports:
> >
> > 1 Changed variable:                                                             
> >
> >   [C] 'unsigned int is_basic_table[]' was changed at test-extern-array.c:3:1:   
> >     type of variable changed:                                                   
> >       array element type 'unsigned int' changed:                                
> >         type size hasn't changed
> >         type alignment changed from 32 to 0                                     
> >       type size hasn't changed
> 
> You can see the report says that the type hasn't changed.
> 
> >       type alignment changed from 32 to 0
> 
> What has changed is the alignment.  the DWARF front-end considers the
> alignment to be zero for arrays.  This is because there is no specific
> alignment information for that type so we set it to zero.
> 
> Do you know what happens if you set the alignment to zero in the CTF
> front-end?
> 

Yes, I changed the alignment value in CTF front-end in commit: 8b832a9edfa,
and I tested with latest commit until now: 4cf2ef8f9.

$ abidiff abi-ctf.xml abi-dwarf.xml

Functions changes summary: 0 Removed, 0 Changed, 0 Added function               
  Variables changes summary: 0 Removed, 1 Changed, 0 Added variable             

  1 Changed variable:                                                           

    [C] 'unsigned int is_basic_table[1]' was changed to 'unsigned int
is_basic_table[]' at test03.c:1:1:                                              
      type of variable changed:                                                 
        type name changed from 'unsigned int[1]' to 'unsigned int[]'            
        array type size changed from 32 to infinity                             
        array type subrange 1 changed length from 1 to infinity   


> Cheers,


Kind regards,
guillermo

-- 
You are receiving this mail because:
You are on the CC list for the bug.

  parent reply	other threads:[~2022-12-22 15:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-21  4:09 [Bug default/29811] New: " guillermo.e.martinez at oracle dot com
2022-12-21 16:02 ` Dodji Seketeli
2022-12-21 16:02 ` [Bug default/29811] " dodji at seketeli dot org
2022-12-22 10:17 ` dodji at redhat dot com
2022-12-22 15:27 ` guillermo.e.martinez at oracle dot com [this message]
2022-12-23  9:19   ` Dodji Seketeli
2022-12-23  9:19 ` dodji at seketeli dot org
2022-12-23  9:20 ` dodji at redhat dot com
2022-12-24 15:39 ` guillermo.e.martinez at oracle dot com
2023-01-01 17:50   ` Dodji Seketeli
2023-01-01 17:50 ` dodji at seketeli dot org
2023-01-01 17:57 ` dodji at redhat dot com

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-29811-9487-Jn4w78IT7e@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=libabigail@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).