The other day i was faced with an issue, working with generating A2L files to be used by XCP. Where XCP is a diagnostics protocol used to read/write to High Integrity machines in the automotive industry. A2l is a format of the memory to be available for read/write. Its generated from .cpp and .elf files.

In the .cpp files comments are placed on each of the variables that the user would like to read/write to.

Now the issue I was facing is that a fault shown upon generating, which resulted in a seg-fault.

Now, the tool would only work with C-code, however I am using C++ code. Which is a problem, but it was the only tool around.

I tripple checked, the comments were according to the guidelines of the tool that was used to generate the a2l files.

The only option I was left with was to debug the actual tool I was using.

So I fired up GDB, and stepped through the tool and found where it was breaking.

I could also mention that the tool started acting up when I added cpp arrays into the mix of generated signals. So I was pretty sure that was the issue, but I was not at all sure of why the tool broke.

Anyway, it turned out that the tool was expecting a DW_AT_upper_bound within the array definition, and only DW_AT_count was available.

DW_AT tags are apart of DWARF, which is a debugging format that reside inside .elf files. I know, I will tell you about gandalf in a second.

I made a test program to see how arrays look inside the .elf object file.

Here is my test program:

/* main.c */
int main(int argc, char** argv)
{
    volatile int test_ar[500];
    test_ar[0] = 0;
    return test_ar[0];
}

Compiling this with gcc main.c -g -Wall -o main.elf and running objdump -W main.elf Using: gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

In the objdump I can see the array like this:

 <2><6f>: Abbrev Number: 4 (DW_TAG_variable)
    <70>   DW_AT_name        : (indirect string, offset: 0x12): test_ar
    <74>   DW_AT_decl_file   : 1
    <75>   DW_AT_decl_line   : 3
    <76>   DW_AT_decl_column : 18
    <77>   DW_AT_type        : <0xd0>
    <7b>   DW_AT_location    : 3 byte block: 91 90 70   (DW_OP_fbreg: -2032)
...
 <1><bf>: Abbrev Number: 11 (DW_TAG_array_type)
    <c0>   DW_AT_type        : <0xa7>
    <c4>   DW_AT_sibling     : <0xd0>
 <2><c8>: Abbrev Number: 12 (DW_TAG_subrange_type)
    <c9>   DW_AT_type        : <0xd5>
    <cd>   DW_AT_upper_bound : 499

So compiling with gcc results in a DW_AT_upper_bound tag as the array size.

But when I compile the same code with clang, clang main.c -g -Wall -o main.elf i get the following elf output. Using: clang version 10.0.0-4ubuntu1

 <2><5f>: Abbrev Number: 4 (DW_TAG_variable)
    <60>   DW_AT_location    : 3 byte block: 91 a0 70   (DW_OP_fbreg: -2016)
    <64>   DW_AT_name        : (indirect string, offset: 0x6c): test_ar
    <68>   DW_AT_decl_file   : 1
    <69>   DW_AT_decl_line   : 3
    <6a>   DW_AT_type        : <0xa4>
...
 <1><a4>: Abbrev Number: 8 (DW_TAG_array_type)
    <a5>   DW_AT_type        : <0xb1>
 <2><a9>: Abbrev Number: 9 (DW_TAG_subrange_type)
    <aa>   DW_AT_type        : <0xb6>
    <ae>   DW_AT_count       : 500

And there it is, the problem, compilers generate different elf output. Where the array size tag is DW_AT_upper_bound with GCC and DW_AT_count with clang.