C++ exception of RPi
Daisuke Aoyama
aoyama at peach.ne.jp
Sun Jan 18 06:41:48 UTC 2015
Hi,
It seems SDHCI_QUIRK_NO_HISPD_BIT is commited.
http://svnweb.freebsd.org/base?view=revision&revision=277307
I write other problem in src-r277169-20150114.patch here.
Current /lib/libcxxrt.so.1 can't handle exception table by clang (at leaset 3.5)
clang++ generate EH like this:
----------------------------------------------------------------------
.handlerdata
.align 2
GCC_except_table0:
.Lexception0:
.byte 255 @ @LPStart Encoding = omit
.byte 0 @ @TType Encoding = absptr
.byte 73 @ @TType base offset
.byte 3 @ Call site Encoding = udata4
.byte 65 @ Call site table length
.Lset0 = .Leh_func_begin0-.Leh_func_begin0 @ >> Call Site 1 <<
.long .Lset0
.Lset1 = .Ltmp0-.Leh_func_begin0 @ Call between .Leh_func_begin0 and .Ltmp0
.long .Lset1
.long 0 @ has no landing pad
.byte 0 @ On action: cleanup
.Lset2 = .Ltmp0-.Leh_func_begin0 @ >> Call Site 2 <<
.long .Lset2
.Lset3 = .Ltmp1-.Ltmp0 @ Call between .Ltmp0 and .Ltmp1
.long .Lset3
.Lset4 = .Ltmp2-.Leh_func_begin0 @ jumps to .Ltmp2
.long .Lset4
.byte 1 @ On action: 1
.Lset5 = .Ltmp1-.Leh_func_begin0 @ >> Call Site 3 <<
.long .Lset5
.Lset6 = .Ltmp3-.Ltmp1 @ Call between .Ltmp1 and .Ltmp3
.long .Lset6
.long 0 @ has no landing pad
.byte 0 @ On action: cleanup
.Lset7 = .Ltmp3-.Leh_func_begin0 @ >> Call Site 4 <<
.long .Lset7
----------------------------------------------------------------------
You can see udata4 of .Lset0 is located at offset 5 from .Lexception0.
(.Lset2 is offset 18, .Lset5 is offset 31)
This data is scaned by dwarf_eh_find_callsite() in /usr/src/contrib/libcxxrt/dwarf_eh.h:
418 while (callsite_table <= lsda->action_table)
419 {
420 // Once again, the layout deviates from the spec.
421 uint64_t call_site_start, call_site_size, landing_pad, action;
422 call_site_start = read_value(lsda->callsite_encoding, &callsite_table);
423 call_site_size = read_value(lsda->callsite_encoding, &callsite_table);
Also, read_value is:
218 static uint64_t read_value(char encoding, dw_eh_ptr_t *data)
219 {
220 enum dwarf_data_encoding type = get_encoding(encoding);
221 uint64_t v;
222 switch (type)
223 {
224 // Read fixed-length types
225 #define READ(dwarf, type) \
226 case dwarf:\
227 v = static_cast<uint64_t>(*reinterpret_cast<type*>(*data));\
228 *data += sizeof(type);\
229 break;
230 READ(DW_EH_PE_udata2, uint16_t)
231 READ(DW_EH_PE_udata4, uint32_t)
232 READ(DW_EH_PE_udata8, uint64_t)
233 READ(DW_EH_PE_sdata2, int16_t)
234 READ(DW_EH_PE_sdata4, int32_t)
235 READ(DW_EH_PE_sdata8, int64_t)
236 READ(DW_EH_PE_absptr, intptr_t)
237 #undef READ
238 // Read variable-length types
239 case DW_EH_PE_sleb128:
240 v = read_sleb128(data);
241 break;
242 case DW_EH_PE_uleb128:
243 v = read_uleb128(data);
244 break;
245 default: abort();
246 }
247
248 return v;
249 }
This reinterpret_cast code of data is probably generated like:
ldr r0, [r0]
But r0 is not aligned! As a result, "return v" is not expected value on RPi.
(usually, it shows v = *((*data) & ~0x3))
To avoid unaligned access, I use byte access in contrib/libcxxrt/dwarf_eh.h.
This solve unwind code in RPi.
----------------------------------------------------------------------
I don't know other CPU. Please check your CPU.
Regards,
--
Daisuke Aoyama
More information about the freebsd-arm
mailing list