This patch addresses the current limitation that entry values can only
be emitted for registers that can be encoded in one byte
(DW_OP_reg0..DW_OP_reg31). For larger register numbers, which are
emitted as multi-byte DW_OP_regx expressions, we would incorrectly emit
a DW_OP_entry_value with the size operand 1.
This patch modifies the semantics of the DW_OP_LLVM_entry_value
operation so that its operand now specifies the number of operations in
the DIExpression that the entry value covers, rather than the byte size.
The number of operands also include the DBG_VALUE's value operand.
To keep the scope of these changes acceptable this patch keeps the
limitation that the entry value can only cover simple register
locations, so the size operand in the DIExpression world can still only
be one. To support entry values covering multiple operations there needs
to be more finalizeEntryValue() logic added to DwarfExpression.
When implementing this I initially thought about running through
DwarfExpression's emission two times; first with a temporary buffer to
emit the operations that the entry value cover, in order to being able
to calculate the size of that emitted data. However, DwarfExpression is
a quite complex state machine, so I decided against that, as it seemed
like the two runs could get out of sync, resulting in incorrect size
operands. Therefore I have implemented this in a way that we only have
to run DwarfExpression once. When DwarfExpression starts emitting an
entry value operation, the output for the DWARF block that is covered by
the entry values is written to a temporary buffer. The size of that
temporary buffer is then used when emitting the entry value's size
operand, and after that the data in the temporary buffer is written to
the real output buffer.
In the case of DIEDwarfExpression, a temporary DIE is used. The values are all
allocated using the same BumpPtrAllocator as for all other DIEs, and the values
are then transferred to the real value list. In the case of
DebugLocDwarfExpression, the temporary buffer is implemented using a
BufferByteStreamer which emits to a buffer in the DwarfExpression object.