ARM Clang: couldn't allocate output register for constraint 'w' - android-ndk

uint8_t* dataPtr;
uint8x8x4_t dataVec;
__asm__ __volatile__( "vldmia %1, %h0" : "=w"( dataVec ) : "r"( dataPtr ) );
Above ARM inline assembly code works fine when compiled with Android NDK using GCC toolchain for armeabi-v7a ABI. However, I get following compiler error when I switch to Clang
error: couldn't allocate output register for constraint 'w'
According to LLVM docs, constraint 'w' can be used for SIMD register on ARM target.
Am I missing something? Has anyone encountered this issue? Is it a bug in LLVM?
Thanks

As mentioned in the LLVM Docs:
The constraint codes are, in general, expected to behave the same way
they do in GCC. LLVM’s support is often implemented on an ‘as-needed’
basis, to support C inline asm code which was supported by GCC. A
mismatch in behavior between LLVM and GCC likely indicates a bug in
LLVM.
Maybe it's a good idea for you to report this on https://bugs.llvm.org/

Related

How to determine the wordsize in Linux kernel programming?

In userspace code, the macro __WORDSIZE is used, included in <bits/wordsize.h>. However, when I do Linux kernel programming, the __WORDSIZE seems not available.
If <bits/wordsize.h> is included, it will receive a compile error, saying:
error: bits/wordsize.h: No such file or directory
but if <bits/wordsize.h> is not included, it will receive another compile error, saying:
error: ‘__WORDSIZE’ undeclared.
It seems that kernel programming doesn't support the <bits/wordsize.h> header file. What should I do to determine the wordsize in Linux kernel programming?
P.S. my compiler version is gcc (GCC) 4.4.6.
Each supported architecture under Linux defines BITS_PER_LONG in
<asm/types.h> to the length of the C long type, which is the system
word size.
From http://www.makelinux.net/books/lkd2/ch19lev1sec2
Word Size in any architecture is equivalent to of size of long datatype.
So use
#define __WORDSIZE sizeof(long)
You can alternatively use size of pointer too.

Segmentation Fault When I run Neon code built with Hard Float option on Linux

I have a code with one function optimized with neon assembly. I build it with gcc and run on Cortex A9 (hard float image).
When I build a non optimized code (pure c without assembly) with hard float options such as:
-mapc -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=neon , it works fine.
When I introduce my assembly code and assemble it with following flags :
-march=armv7-a -mfloat-abi=hard -mfpu=neon it builds fine but gives a segmentation fault.
Also a point to be noted is that, if i build the assembly optimized code with -mfloat-abi=softfp in place of hard(and link with -static option), it runs fine.
Why is assembly code creating a problem with Hard float? I have encountered other posts on hard/soft abi options, however I did not find a solution to my particular case (C code working but neon assembly giving segmentation fault)
Edit:
The board does not have a gdb and I did try remotely via gdb server but that raised other issues of connectivity. So I am not able to debug using gdb. However, what I did to debug: As soon as i entered the assembly function, I pushed registers, then branched to the end and popped the registers again. It still gave a segmentation fault. Can I infer that it is not a particular instruction giving the fault. Some flag missing in the makefile or other formalities and syntax in the assembly specific to Hard float?
Also, when I built the library using armcc with option --fpu=vfpv3_d16 it still works. That is hard float right?. So I infer that the combination GCC + Assembly code + Hard Float is a problem...
Please give in your suggestions if you have worked with this/similar combination.
Edit
The code runs if the assembly code has plain instructions like MOV r0, r1 or ADD r1, r2,r2 but gives segmentation fault in case of any constant or memory related operation like LDR r1, [r2] or mov r0, #0 . Does it help to decipher the fault?
Okay, so here is what I found out.
The missing line was one attribute:
.type function_name, %function
One may also check other attributes required if missing. This line worked for me.
Thank you for contributing your answers
I suspect you have a problem with alignment calling conventin (in particular, stack allocation) but don't have enough information to say anything conclusive.
Can you use GCC inline assembly in your function instead of writing the whole function with assembly? Then GCC should take care of alignment and calling convention. Inline assembly should be enough for accelareted arithmetics with NEON SIMD.

glibc: elf file OS ABI invalid

downloaded and compiled glibc-2.13. when i try to run a sample C program which does a malloc(). I get following error
elf file OS ABI invalid
Can anybody please pass my any pointer helpful in resolving this issue.Please note that my kernel version is linux-2.6.35.9
It's not your kernel version that's the problem.
The loader on your system does not support the new Linux ABI. Until relatively recently, Linux ELF binaries used the System V ABI. Recently, in support of STT_GNU_IFUNC, the Linux ABI was added. You would have to update your system C library to have a loader that support STT_GNU_IFUNC, and then it will also recognize ELF objects with the Linux ABI type.
See Dave Miller's blog entry on STT_GNU_IFUNC for Sparc (archived) to gain an understanding of what STT_GNU_IFUNC does, if you care.
If you get your hands in the loader from a newer system, you might be able to make it work using that. But you'll have to carry the loader wherever your program go. You can either compile your program to use that loader as explained here, or compile your program and patch it later using patchelf, in a way similar to what I mention here. I was able to run a program that was giving me the OS ABI invalid error on a linux 2.6.18 (older than yours) that had ld-2.5.so, by copying a ld-2.15.so from somewhere else.
NOTE: do NOT overwrite your system ld*.so or ld-linux. ;-/
It is possible your glibc was built with the --enable-multiarch flag that forced using ifunc and new LINUX ABI
From what I can tell is that --enable-multiarch is the default setting and you should disable it by setting --enable-multiarch=no.

On linux, what can cause dlopen to emit SIGFPE?

I have a library of dubious origins which is identified by file as a 32 bit executable. However, when I try to dlopen it on a 32 bit CentOS 4.4 machine, dlopen terminates with SIGFPE. Surely if there was something wrong with the format of the binary then dlopen should be handling an error?
So the question is: What kinds of problems can cause dlopen to emit SIGFPE?
Some possible reasons are:
Division by zero (rule this out with gdb)
Architecture mismatch (did you compile the DSO yourself on the same architecture? or is it prebuilt?)
ABI compatibility problems (loading a DSO built for one Linux distro on a different one).
Here is an interesting discussion regarding hash generation in the ELF format in GNU systems where an ABI mismatch can cause SIGFPE on systems when you mix and match DSOs not built on that distro/system.
Run GDB against your executable with:
]$ gdb ./my_executable
(gdb) run
When the program crashes, get a backtrace with
(gdb) bt
If the stack ends in do_lookup_x () then you likely have the same problem and should ensure your DSO is correct for the system you are trying to load it on ... However you do say it has dubious origins so the problem is probably an ABI problem similar to the one described.
Get a non-dubious library / executable! ;)
Good Luck

compiling linux kernel with non-gcc

Linux kernel is written for compiling with gcc and uses a lot of small and ugly gcc-hacks.
Which compilers can compile linux kernel except gcc?
The one, which can, is the Intel Compiler. What minimal version of it is needed for kernel compiling?
There also was a Tiny C compiler, but it was able to compile only reduced and specially edited version of the kernel.
Is there other compilers capable of building kernel?
An outdatet information: you need to patch the kernel in order to compile using the Intel CC
Download Linux kernel patch for Intel® Compiler
See also Is it possible to compile Linux kernel with something other than gcc for further links and information
On of the most recent sources :http://forums.fedoraforum.org/showthread.php?p=1328718
There is ongoing process of committing LLVMLinux patches into vanilla kernel (2013-2014).
The LLVMLinux is project by The Linux Foundation: http://llvm.linuxfoundation.org/ to enable vanilla kernel to be built with LLVM. Lot of patches are prepared by Behan Webster, who is LLVMLinux project lead.
There is LWN article about the project from May 2013
https://lwn.net/Articles/549203/ "LFCS: The LLVMLinux project"
Current status of LLVMLinux project is tracked at page http://llvm.linuxfoundation.org/index.php/Bugs#Linux_Kernel_Issues
Things (basically gcc-isms) already eliminated from kernel:
* Expicit Registers Variables (non-C99)
* VLAIS (non C99-compliant undocumented GCC feature "Variable length arrays in structs") like struct S { int array[N];} or even struct S { int array[N]; int array_usb_gadget[M]; } where N and M are non-constant function argument
* Nested Functions (Ada feature ported into C by GCC/Gnat developers; not allowed in C99)
* Some gcc/gas magic like special segments, or macro
Things to be done:
* Usage of __builtin_constant_p builtin to implement scary magic like BUILD_BUG_ON(!__builtin_constant_p(offset));
The good news about LLVMLinux are that after its patches kernel not only becomes buildable with LLVM+clang, but also easier to build by other non-GCC compilers, because the project kills much not C99 code like VLAIS, created by usb gadget author, by netfilter hackers, and by crypto subsystem hackers; also nested functions are killed.
In short, you cannot, because the kernel code was written to take advantage of the gcc's compiler semantics...and between the kernel and the compiled code, the relationship is a very strong one, i.e. must be compiled with gcc...Since gcc uses 'ELF' (Embedded Linking Format) object files, the kernel must be built using the object code format. Unless you can hack it up to work with another compiler - it may well compile but may not work, as the compilers under Windows produces PE code, there could be unexpected results, meaning the kernel may not boot at all!

Resources