* 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.