[LLVMdev] ARM assembler's syntax in clang

Bernie Ogden bogden at arm.com
Fri Mar 8 01:02:31 PST 2013

IIRC, reads of the PC must behave as they did when ARM processors had three-stage pipelines, regardless of the length of the actual pipeline. The consequence is that, when using PC in this way, it's value will be 2 instructions ahead of the address of the current instruction. This is so that software remains portable across cores.


From: Ashi [mailto:ashi08104 at gmail.com] 
Sent: 08 March 2013 04:44
To: Tim Northover
Cc: Bernard Ogden; LLVM List
Subject: Re: [LLVMdev] ARM assembler's syntax in clang



> And be warned that the PC doesn't point at the next instruction when you use it like this - I believe you don't need to modify it at all if you swap the pop and the .long.
Bernie, is it related to ARM pipeline? I'm interesting in this, is there any other additional information?

On Fri, Mar 8, 2013 at 4:59 AM, Tim Northover <t.p.northover at gmail.com> wrote:

Hi Ashi,

> ld: illegal text-relocation to _data_table in table.o from foo in
> use_table.o for architecture armv7

It looks like you're using iOS. I'm not familiar with the exact
workings of that platform, but I think a similar message would occur
in ELF-land.

If iOS *is* comparable, your issue is that symbols in dynamically
loaded objects can't (usually) be referenced directly because the code
section (and any embedded litpools) need to be identical no matter
where everything is loaded in memory. This is most of the point of
.dylib files: the instructions only have to exist once in memory and
can be shared. If the bytes would be different for each user that's
not possible --  the linker spots places where that happens and gives
an error.

My advice would be to compile a .c file  (with "-S" to view the
assembly) which makes accesses like you're trying to do and copy its
code. There's no shame in it: I had a good idea of what ELF did but
still got the syntactic details wrong when I tried to write similar
code off the top of my head.

In this case, for example, I'd compile the C code (with "-fPIC" in
principle, though it seems to make no difference here. Actually, I'm
rather disturbed that you're trying to compile the C part of a .dylib
without "-fPIC". In the Linux world that's a no-no. Could be valid for
iOS, but I'd suggest you make sure if you don't know):

extern int data_table[];

int *wheres_data_table(void) {
    return &data_table[0];

(N.b. "armv7" uses a movw/movt pair which is perfectly valid. If you
want to see how to do it using litpools, you need to compile for
"armv6" which doesn't have those instructions).



Thanks for all your great reply! Finally, I got it work by several ways, compiler's assembly output would help a lot(thanks Tim) and a linker option:-Wl,-read_only_relocs,suppress would also help.
And here is a similar problem under powerPC :http://lists.apple.com/archives/unix-porting/2008/Jan/msg00027.html

here is my summary:
*** problem ***
LDR Rx, =Label is not supported under Clang

*** solution ***
replace LDR pseudo-instruction by manually loading Label. 2 methods are used, they are shown in use_table_m1.s and use_table_m2.s respectively. There are 7 targets in my Makefile, include several different option test(details are all in Makefile).
Test environment is Xcode4.6. The test_d_m1_1 can't be generated due to illegal text-relocation error and others can be generated, they are 3 dynamic targets and 3 static targets, the test_s_m1_2 have a warning due to -mdynamic-no-pic option. however I haven't test them on iOS device, I'm not sure whether the "-Wl,-read_only_relocs,suppress" option would really work.

/* ==begin table.c== */
int data_table[] = {0xff, 0xff};
/* ==end table.c== */

/* ==begin use_table_m1.s==
 * use table by LDR 
    .syntax unified
    .align   4
    .global   foo

    LDR         r0,[PC,#4]
    BX    lr
    .long _data_table    
/* ==end use_table_m1.s== */

/* ==begin use_table_m2.s==
 * use table by code from compiler's assembly out put  
    .syntax unified
    .align   4
    .global   foo

    /* these lines are from compiler's assembly output($(CC) -S):
     * extern int data_table[];
     * int *wheres_data_table(void) {
     * return &data_table[0];
     * }
    movw    r1, :lower16:(L_data_table$non_lazy_ptr-(LPC0_0+4))
    movt    r1, :upper16:(L_data_table$non_lazy_ptr-(LPC0_0+4))
    add    r1, pc
    ldr     r1, [r1]
    bx    lr

    .section        __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
    .align  2
    .indirect_symbol        _data_table
    .long   0
/* ==end use_table_m2.s== */

/* ==begin test.c ==*/
extern int data_table[];
int main(void)
  int a = data_table[0];
  return 0;
/* ==end test.c ==*/

/* ==Makefile== */

CC = /Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
AR = /Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar
CFLAG = -fPIC -Wall -arch armv7 -mcpu=cortex-a9 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk 

all:dynamic static

dynamic:test_d_m1_1 test_d_m1_2 test_d_m2_1 test_d_m2_2

static:test_s_m1_1 test_s_m1_2 test_s_m2_1

test_d_m1_1:test.c libtest_m1_1.dylib
    $(CC) $(CFLAG) test.c ./libtest_m1_1.dylib -o $@

test_d_m1_2:test.c libtest_m1_2.dylib
    $(CC) $(CFLAG) test.c ./libtest_m1_2.dylib -o $@

test_d_m2_1:test.c libtest_m2_2.dylib
    $(CC) $(CFLAG) test.c ./libtest_m2_2.dylib -o $@

test_d_m2_2:test.c libtest_m2_2.dylib
    $(CC) $(CFLAG) test.c ./libtest_m2_2.dylib -o $@

test_s_m1_1:test.c libtest_m1_1.a
    $(CC) $(CFLAG) $^ -o $@

test_s_m1_2:test.c libtest_m1_1.a
    $(CC) $(CFLAG) -mdynamic-no-pic $^ -o $@

test_s_m2_1:test.o libtest_m2_1.a
    $(CC) $(CFLAG) $^ -o $@

libtest_m1_1.dylib:table.o use_table_m1.o
    $(CC) -dynamiclib $(CFLAG) $^ -o $@

libtest_m1_2.dylib:table.o use_table_m1.o
    $(CC) -dynamiclib -Wl,-read_only_relocs,suppress $(CFLAG) $^ -o $@

libtest_m2_1.dylib:table.o use_table_m2.o
    $(CC) -dynamiclib $(CFLAG) $^ -o $@

libtest_m2_2.dylib:table.o use_table_m2.o
    $(CC) -dynamiclib -Wl,-read_only_relocs,suppress $(CFLAG) $^ -o $@

libtest_m1_1.a:table.o use_table_m1.o
    $(AR) rcs $@ $^ 

libtest_m2_1.a:table.o use_table_m2.o
    $(AR) rcs $@ $^ 

    $(CC) -c $(CFLAG) $^ -o $@

    $(CC) -c $(CFLAG) $^ -o $@

    $(CC) -c -integrated-as $(CFLAG) $^ -o $@

    $(CC) -c -integrated-as $(CFLAG) $^ -o $@

    rm -f *.o libtest* test_d_m* *~ test_s_m*

/* == end Makefile == */

(all of these files are also available at http://dl.dropbox.com/u/13855163/ill_text_relocation_test.tar.gz)

Best Regards,
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130308/a0ceb270/attachment.html>

More information about the llvm-dev mailing list