Vicente Bergas via llvm-dev
2021-Dec-20 16:03 UTC
[llvm-dev] How to force address of symbol
Hello, i would like to force the address of the symbol "start" which is a function. (there is also the use case where the symbol of interest is a data array) The symbol is declared in file test.c: __asm__ ( " .section .test \n" " .global start \n" " .syntax unified \n" " .thumb \n" " .thumb_func \n" " .type start, %function \n" "start: \n" " ldr r0, stack_addr \n" " mov sp, r0 \n" " b reset \n" " .align 2 \n" "stack_addr: \n" " .word stack \n" ); void reset(void) { while (1); } and compiled this way: clang --target=armv6-m -mfloat-abi=soft -c test.c -o test.o or ${CROSS_COMPILE}gcc -c test.c -o test.o When linking i am using the script file link.ld: MEMORY { RAM (rwx) : ORIGIN = 0x1000, LENGTH = 0x1000 } ENTRY(start) SECTIONS { .text : { *(.test) } > RAM stack = ORIGIN(RAM) + LENGTH(RAM); } and linked this way: ld.lld -T link.ld test.o --gc-sections -o test.elf or ${CROSS_COMPILE}ld -T link.ld test.o --gc-sections -o test.elf In the llvm case, there is a warning reported: ld.lld: warning: test.c:(.test+0x4): has non-ABS relocation R_ARM_THM_JUMP11 against symbol 'reset' but it succeeds. Finally, i check that the "start" symbol is placed at the correct address with: llvm-objdump --syms test.elf or ${CROSS_COMPILE}objdump --syms test.elf The result is wrong for the llvm case (address is zero) and correct for the gnu case (address is 0x1000). Am i doing something wrong? Is this difference between gnu and llvm expected or is it a bug? LLVM/CLANG version: 13.0.0 (https://archlinux.org/) GCC version: 11.2.1 (http://musl.cc/) LD version: 2.37 (http://musl.cc/) Regards, Vicenç.
Jessica Clarke via llvm-dev
2021-Dec-22 20:53 UTC
[llvm-dev] How to force address of symbol
On 20 Dec 2021, at 16:03, Vicente Bergas via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hello, > i would like to force the address of the symbol "start" which is a function. > (there is also the use case where the symbol of interest is a data array) > The symbol is declared in file test.c: > __asm__ ( > " .section .test \n" > " .global start \n" > " .syntax unified \n" > " .thumb \n" > " .thumb_func \n" > " .type start, %function \n" > "start: \n" > " ldr r0, stack_addr \n" > " mov sp, r0 \n" > " b reset \n" > " .align 2 \n" > "stack_addr: \n" > " .word stack \n" > ); > void reset(void) { while (1); } > > and compiled this way: > clang --target=armv6-m -mfloat-abi=soft -c test.c -o test.o > or > ${CROSS_COMPILE}gcc -c test.c -o test.o > > When linking i am using the script file link.ld: > MEMORY { RAM (rwx) : ORIGIN = 0x1000, LENGTH = 0x1000 } > ENTRY(start) > SECTIONS { > .text : { *(.test) } > RAM > stack = ORIGIN(RAM) + LENGTH(RAM); > } > > and linked this way: > ld.lld -T link.ld test.o --gc-sections -o test.elf > or > ${CROSS_COMPILE}ld -T link.ld test.o --gc-sections -o test.elf > > In the llvm case, there is a warning reported: > ld.lld: warning: test.c:(.test+0x4): has non-ABS relocation > R_ARM_THM_JUMP11 against symbol 'reset' > but it succeeds. > > Finally, i check that the "start" symbol is placed at the correct address with: > llvm-objdump --syms test.elf > or > ${CROSS_COMPILE}objdump --syms test.elf > > The result is wrong for the llvm case (address is zero) and correct > for the gnu case (address is 0x1000). > > Am i doing something wrong? > Is this difference between gnu and llvm expected or is it a bug? > > LLVM/CLANG version: 13.0.0 (https://archlinux.org/) > GCC version: 11.2.1 (http://musl.cc/) > LD version: 2.37 (http://musl.cc/)You need to set the flags for .test in your .section directive; currently it ends up with no flags when using LLVM’s integrated assembler, and so isn’t an SHF_ALLOC section. You want “ax”, and should probably also be providing %progbits for good measure, i.e.: .section .test, "ax", %progbits Jess