I have quite strange issue when try to create the jump table in my asm program for iphone (arm64):
.globl my_func
my_func:
...
//jump (switch) table
.L.f_switch:
.short .L.case0 - .L.f_switch
.short .L.case1 - .L.f_switch
...
.L.case0:
//some case code
...
.L.case1:
//other case code
After compilation this table is filled by zeros instead of actual values. It could be seen by dumping compiled object file.
(__TEXT,__text) section
_my_func:
0000000000000000 adr x4, #16
0000000000000004 ldrh w5, [x4, x3, lsl #1]
0000000000000008 add x4, x4, w5, uxth
000000000000000c br x4
.L.f_switch:
0000000000000010 .long 0x00000000
0000000000000014 .long 0x00000000
0000000000000018 .long 0x00000000
000000000000001c nop
How to resolve it?
I believe that what you are observing with entries being set to 0 is related to relocation. The compiler may emit relocation information that the linker will ultimately resolve. To that end I created this small sample program:
test.s
I'm using XCode 7 and clang reports this version info for
clang --version
:To simplify things at the command line I set an environment variable to point to my iPhone SDK with:
First experiment is to compile
test.s
totest.o
. I use this command:Now if I dump test.o with
otool
using:I get this:
The compiler(assembler) has emitted relocation entries for 00000010, 00000014, and 00000018 for both parts of the equation (
.L.case#
and.L.F_switch
). The table itself is filled with place holder zeros. It will be the linker's job to resolve the relocations. I can manually link thetest.o
above with a command like:I can now use
otool
to dump the final executable with a command like:And get this output:
Notice that all the relocations have been resolved by the linker in the final executable.
Alternatively I could have compiled and linked all in one step to produce the executable
test
with a command like:I split it up to show what the object file looked like and then the resulting executable after linking.
First of all, I want to thank Michael Petch for his contribute to this discussion which was very helpful.
Secondly, I want to highlight that the size of data in jump table is important. Clang doesn't have any issues with '.word' (4 Byte) offsets. While the troubles are beginning when other '.byte' (1 Byte) or '.short'/'.hword' (2 Byte) offsets are used.
Test 1. Data type is '.short' (2 Byte).
the dump is:
till now is everything is going as Michael described in his answer (except there is reservation for 2 Bytes offset entities)
After that linker returns error:
Please note that there would not be any errors if 4 Bytes entities were used.
Test 2. Could be treated as workaround.
the dump of this approach is:
As you could notice compiler fills the jump table straight by right offset values. As a result there is not relocation information and any issues with linker.
Also I want to bring attention the the following facts.