* Jakub Jelinek:

>> +#undef C
>> +
>> +      /* Validate the augmentation length, and return the enconding after
>> +     it.  No check for the return address column because it is
>> +     byte-encoded with CIE version 1.  */
>> +      if (__builtin_expect ((value & mask) == expected
>> +                        && (cie->augmentation[8] & 0x80) == 0, 1))
>> +      return cie->augmentation[9];
>
> And the above line is indented too much, should be just tab.
>
> But more importantly, I don't see how it can work at all correctly.
> For the "zR" case:
>   Version:               1
>   Augmentation:          "zR"
>   Code alignment factor: 1
>   Data alignment factor: -8
>   Return address column: 16
>   Augmentation data:     1b
> I believe the function wants to return 0x1b, we have
> 1 z R 0 c d r l X
> and we want to return the X, which is indeed at &cie->version + 8
> aka cie->augmentation[7].
> But with "zPLR"
>   Version:               1
>   Augmentation:          "zPLR"
>   Code alignment factor: 1
>   Data alignment factor: -8
>   Return address column: 16
>   Augmentation data:     03 00 00 00 00 03 1b
> we have
> 1 z P L R 0 c d r l M N N N N O X 
> and still want to return the X, while you return the M in there.
> How large the N is depends on the M value.  The "P" data
> is <encoding byte> + <encoded value>, "L" takes just <encoding byte>
> and so does "R".
> So, you'd need in addition to your (cie->augmentation[8] & 0x80) == 0
> check (that augmentation data length is single byte uleb128) verify
> that cie->augmentation[9] is DW_EH_PE_udata4, then you can skip
> the 4 bytes after it and the one byte for "L" and return
> cie->augmentation[15];  But you'd need to verify what different
> DW_EH_PE_* values are used in the wild.

Meh, right.  I think what I'm doing is pretty pointless.  We call
extract_cie_info immediately after calling _Unwind_Find_FDE in
uw_frame_state_for.  That already gives us the FDE encoding.  So it
seems to make more sense to do the PC range check in uw_frame_state_for,
and _Unwind_Find_FDE won't need the FDE encoding anymore.

My testing doesn't catch this problem unfortunately.

> BTW, version 1 is there just because binutils emit those,
> if one uses -fno-dwarf2-cfi-asm, there is:
>   Version:               3
>   Augmentation:          "zR"
>   Code alignment factor: 1
>   Data alignment factor: -8
>   Return address column: 16
>   Augmentation data:     03
> and
>   Version:               3
>   Augmentation:          "zPLR"
>   Code alignment factor: 1
>   Data alignment factor: -8
>   Return address column: 16
>   Augmentation data:     03 00 00 00 00 03 03
> instead (so 3 instead of 1, and leb128 RA instead of byte;
> 1 vs. 3 can be handled by mask and checking if top byte of the
> RA isn't set could work too).  One should trie what one gets
> with -fpic/-fpie/-fno-pie on various arches though.
> E.g. doesn't aarch64 use augmentations with B in it?

I haven't seen those, and I also can't find the GCC code to emit it.  I
think it's now handled via aarch64_frob_update_context, not an
augmentation flag.  Perhaps we should remove the 'B' cases.

Reply via email to