Re: [NEWS/RFA] Re: [gdbserver] x86 agent expression bytecode compiler (speed up conditional tracepoints)

Hui Zhu
2010-06-19T17:13:55Z

Hi guys,

I say something about bytecode compiler .

I did some code work like it in skyeye dbct (dynamic binary code
translation) in before (some introduce
http://www.skyeye.org/wiki/SkyeyeDBCTen).

In dbct, I get the binary code like what you do in this patch.
define a functon, get binary code from this function, and use it for
other thing.

But I want say, to maintain is not very easy. At least, we need give up -O2.

Because Gcc's optimization will compile the function that support the
code to some asm code that we don't want it to be.

Any other trouble is , different user will use different version gcc,
different version gcc's optimization is different.
Actually, after gcc4, this issue is very different to handle.

And old version QEMU use this idea too. And it has this issue too.
So a long time, compile qemu need gcc3.
Now, qemu handle this issue because it give up the old way and use TCC
to get the code.

Hope it can help a little better.

Thanks,
Hui

On Sun, Jun 20, 2010 at 00:16, Doug Evans <dje@google.com> wrote:
> Yeah.
> Until it gets fixed a workaround is to compile linux-x86-low.c with -O0.
>
>
> On Sat, Jun 19, 2010 at 9:12 AM, Hui Zhu <teawater@gmail.com> wrote:
>> lubuntu 10.04:
>>
>> make[4]: ?????? `/home/teawater/gdb/bgdball/gdb/gdbserver'
>> rm -f gdbserver
>> gcc -Wall -g -O2    -I. -I../../../src/gdb/gdbserver
>> -I../../../src/gdb/gdbserver/../common
>> -I../../../src/gdb/gdbserver/../regformats
>> -I../../../src/gdb/gdbserver/../../include
>> -Wl,--dynamic-list=../../../src/gdb/gdbserver/proc-service.list -o
>> gdbserver inferiors.o regcache.o remote-utils.o server.o signals.o
>> target.o utils.o version.o mem-break.o hostio.o event-loop.o
>> tracepoint.o xml-builtin.o i386-linux.o i386-avx-linux.o
>> i386-mmx-linux.o linux-low.o linux-x86-low.o i386-low.o i387-fp.o
>> hostio-errno.o thread-db.o proc-service.o  \
>>          -ldl
>> linux-x86-low.o: In function `i386_emit_void_call_2':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2426:
>> undefined reference to `end_i386_void_call_2_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2426:
>> undefined reference to `start_i386_void_call_2_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2426:
>> undefined reference to `start_i386_void_call_2_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2447:
>> undefined reference to `end_i386_void_call_2_b'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2447:
>> undefined reference to `start_i386_void_call_2_b'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2447:
>> undefined reference to `start_i386_void_call_2_b'
>> linux-x86-low.o: In function `i386_emit_int_call_1':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2398:
>> undefined reference to `end_i386_int_call_1_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2398:
>> undefined reference to `start_i386_int_call_1_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2398:
>> undefined reference to `start_i386_int_call_1_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2412:
>> undefined reference to `end_i386_int_call_1_c'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2412:
>> undefined reference to `start_i386_int_call_1_c'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2412:
>> undefined reference to `start_i386_int_call_1_c'
>> linux-x86-low.o: In function `i386_emit_swap':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2364:
>> undefined reference to `end_i386_swap'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2364:
>> undefined reference to `start_i386_swap'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2364:
>> undefined reference to `start_i386_swap'
>> linux-x86-low.o: In function `i386_emit_zero_ext':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2343:
>> undefined reference to `end_i386_zero_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2343:
>> undefined reference to `start_i386_zero_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2343:
>> undefined reference to `start_i386_zero_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2353:
>> undefined reference to `end_i386_zero_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2353:
>> undefined reference to `start_i386_zero_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2353:
>> undefined reference to `start_i386_zero_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2348:
>> undefined reference to `end_i386_zero_ext_16'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2348:
>> undefined reference to `start_i386_zero_ext_16'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2348:
>> undefined reference to `start_i386_zero_ext_16'
>> linux-x86-low.o: In function `i386_emit_stack_flush':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2332:
>> undefined reference to `end_i386_stack_flush'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2332:
>> undefined reference to `start_i386_stack_flush'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2332:
>> undefined reference to `start_i386_stack_flush'
>> linux-x86-low.o: In function `i386_emit_pop':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2324:
>> undefined reference to `end_i386_pop'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2324:
>> undefined reference to `start_i386_pop'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2324:
>> undefined reference to `start_i386_pop'
>> linux-x86-low.o: In function `i386_emit_goto':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2227:
>> undefined reference to `end_i386_goto'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2227:
>> undefined reference to `start_i386_goto'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2227:
>> undefined reference to `start_i386_goto'
>> linux-x86-low.o: In function `i386_emit_if_goto':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2209:
>> undefined reference to `end_i386_if_goto'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2209:
>> undefined reference to `start_i386_if_goto'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2209:
>> undefined reference to `start_i386_if_goto'
>> linux-x86-low.o: In function `i386_emit_ref':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2187:
>> undefined reference to `end_i386_ref1'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2187:
>> undefined reference to `start_i386_ref1'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2187:
>> undefined reference to `start_i386_ref1'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2199:
>> undefined reference to `end_i386_ref8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2199:
>> undefined reference to `start_i386_ref8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2199:
>> undefined reference to `start_i386_ref8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2191:
>> undefined reference to `end_i386_ref2'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2191:
>> undefined reference to `start_i386_ref2'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2191:
>> undefined reference to `start_i386_ref2'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2195:
>> undefined reference to `end_i386_ref4'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2195:
>> undefined reference to `start_i386_ref4'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2195:
>> undefined reference to `start_i386_ref4'
>> linux-x86-low.o: In function `i386_emit_less_unsigned':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2165:
>> undefined reference to `end_i386_less_unsigned'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2165:
>> undefined reference to `start_i386_less_unsigned'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2165:
>> undefined reference to `start_i386_less_unsigned'
>> linux-x86-low.o: In function `i386_emit_less_signed':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2146:
>> undefined reference to `end_i386_less_signed'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2146:
>> undefined reference to `start_i386_less_signed'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2146:
>> undefined reference to `start_i386_less_signed'
>> linux-x86-low.o: In function `i386_emit_equal':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2128:
>> undefined reference to `end_i386_equal'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2128:
>> undefined reference to `start_i386_equal'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2128:
>> undefined reference to `start_i386_equal'
>> linux-x86-low.o: In function `i386_emit_bit_not':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2120:
>> undefined reference to `end_i386_bit_not'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2120:
>> undefined reference to `start_i386_bit_not'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2120:
>> undefined reference to `start_i386_bit_not'
>> linux-x86-low.o: In function `i386_emit_bit_xor':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2111:
>> undefined reference to `end_i386_xor'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2111:
>> undefined reference to `start_i386_xor'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2111:
>> undefined reference to `start_i386_xor'
>> linux-x86-low.o: In function `i386_emit_bit_or':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2102:
>> undefined reference to `end_i386_or'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2102:
>> undefined reference to `start_i386_or'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2102:
>> undefined reference to `start_i386_or'
>> linux-x86-low.o: In function `i386_emit_bit_and':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2093:
>> undefined reference to `end_i386_and'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2093:
>> undefined reference to `start_i386_and'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2093:
>> undefined reference to `start_i386_and'
>> linux-x86-low.o: In function `i386_emit_log_not':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2082:
>> undefined reference to `end_i386_log_not'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2082:
>> undefined reference to `start_i386_log_not'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2082:
>> undefined reference to `start_i386_log_not'
>> linux-x86-low.o: In function `i386_emit_ext':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2057:
>> undefined reference to `end_i386_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2057:
>> undefined reference to `start_i386_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2057:
>> undefined reference to `start_i386_ext_8'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2070:
>> undefined reference to `end_i386_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2070:
>> undefined reference to `start_i386_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2070:
>> undefined reference to `start_i386_ext_32'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2064:
>> undefined reference to `end_i386_ext_16'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2064:
>> undefined reference to `start_i386_ext_16'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2064:
>> undefined reference to `start_i386_ext_16'
>> linux-x86-low.o: In function `i386_emit_sub':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2020:
>> undefined reference to `end_i386_sub'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2020:
>> undefined reference to `start_i386_sub'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2020:
>> undefined reference to `start_i386_sub'
>> linux-x86-low.o: In function `i386_emit_add':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2011:
>> undefined reference to `end_i386_add'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2011:
>> undefined reference to `start_i386_add'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2011:
>> undefined reference to `start_i386_add'
>> linux-x86-low.o: In function `i386_emit_epilogue':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1999:
>> undefined reference to `end_i386_epilogue'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1999:
>> undefined reference to `start_i386_epilogue'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1999:
>> undefined reference to `start_i386_epilogue'
>> linux-x86-low.o: In function `i386_emit_prologue':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1989:
>> undefined reference to `end_i386_prologue'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1989:
>> undefined reference to `start_i386_prologue'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:1989:
>> undefined reference to `start_i386_prologue'
>> linux-x86-low.o: In function `i386_emit_reg':
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2302:
>> undefined reference to `end_i386_reg_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2302:
>> undefined reference to `start_i386_reg_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2302:
>> undefined reference to `start_i386_reg_a'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2311:
>> undefined reference to `end_i386_reg_b'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2311:
>> undefined reference to `start_i386_reg_b'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2311:
>> undefined reference to `start_i386_reg_b'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2316:
>> undefined reference to `end_i386_reg_c'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2316:
>> undefined reference to `start_i386_reg_c'
>> /home/teawater/gdb/bgdball/gdb/gdbserver/../../../src/gdb/gdbserver/linux-x86-low.c:2316:
>> undefined reference to `start_i386_reg_c'
>> collect2: ld returned 1 exit status
>> make[4]: *** [gdbserver] ?? 1
>> make[4]:?????? `/home/teawater/gdb/bgdball/gdb/gdbserver'
>> make[3]: *** [subdir_do] ?? 1
>> make[3]:?????? `/home/teawater/gdb/bgdball/gdb'
>> make[2]: *** [all] ?? 2
>> make[2]:?????? `/home/teawater/gdb/bgdball/gdb'
>> make[1]: *** [all-gdb] ?? 2
>> make[1]:?????? `/home/teawater/gdb/bgdball'
>>
>>
>> On Fri, Jun 18, 2010 at 02:03, Michael Snyder <msnyder@vmware.com> wrote:
>>> Stan Shebs wrote:
>>>>
>>>> Pedro Alves wrote:
>>>>>
>>>>> On Wednesday 16 June 2010 20:12:44, Stan Shebs wrote:
>>>>>
>>>>>>
>>>>>> Doug Evans wrote:
>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 14, 2010 at 3:19 PM, Pedro Alves <pedro@codesourcery.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks.  I've checked the whole thing in.
>>>>>>>>
>>>>>>>
>>>>>>> I'm getting build failures that go away when compiling linux-x86-low.c
>>>>>>> with -g.
>>>>>>>
>>>>>>> gcc is optimizing out the skipped over stuff I believe.
>>>>>>>
>>>>>>
>>>>>> Hmm, this particular trickery was my idea, but it always seemed
>>>>>> vulnerable to ever-smarter optimization.  Does anybody have any better
>>>>>> strategy?  Declaring the asm volatile didn't work, because the compiler was
>>>>>> whacking everything around it.
>>>>>>
>>>>>> The other approach is to build up instructions from bitfields, which is
>>>>>> reliable but needs a lot of setup and helper routines.
>>>>>>
>>>>>
>>>>> Quick thought: can we stick a couple of __attribute__((used))'s in the
>>>>> macro, so the compiler doesn optimized things away, thinking they're
>>>>> unused (given the uses are behind asm)?
>>>>>
>>>>
>>>> The compiler is discarding the code with the definitions of the labels,
>>>> because it's thinking they are maybe somewhere else in the program (the
>>>> error is at link time).  Moving the labels into C code would fix that I
>>>> think, but then it's hard to guarantee that the compiler won't sneak in a
>>>> bit of code between label and asm sequence.
>>>
>>> Hurrr.  Code that depends on such deep knowledge of the compiler's
>>> behavior is wrong code, IMO.
>>>
>>>
>>
>