I am trying out CooCox CoIDE for developing software to a STM32F100.
When I compile after adding CooCox RTOS (CoOS), I get a error message:
[cc] Starting link
[cc] arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -g -nostartfiles -flto -Wl,-Map=OS_Test.map -O0 -Wl,--gc-sections -Wl,--entry=main -LC:\CooCox\CoIDE\configuration\ProgramData\OS_Test -Wl,-TC:\CooCox\CoIDE\configuration\ProgramData\OS_Test/arm-gcc-link.ld -g -o OS_Test.elf ..\obj\kernelHeap.o ..\obj\core.o ..\obj\startup_stm32f10x_md_vl.o ..\obj\core_cm3.o ..\obj\timer.o ..\obj\utility.o ..\obj\system_stm32f10x.o ..\obj\task.o ..\obj\serviceReq.o ..\obj\main.o ..\obj\mbox.o ..\obj\mm.o ..\obj\time.o ..\obj\event.o ..\obj\syscalls.o ..\obj\port.o ..\obj\queue.o ..\obj\mutex.o ..\obj\flag.o ..\obj\arch.o ..\obj\sem.o ..\obj\hook.o
[cc] C:\Users\Jonas\AppData\Local\Temp\cccpkRF6.s: Assembler messages:
[cc] C:\Users\Jonas\AppData\Local\Temp\cccpkRF6.s:240: Error: offset out of range
[cc] C:\Users\Jonas\AppData\Local\Temp\cccpkRF6.s:241: Error: offset out of range
I know this isn't much information, but I haven't seen this error before, so i am completely blank, please help :)
EDIT: Oh, and i found out that if I change the optimization from -O0 to -O1 the error becomes:
[cc] ccKXT9LB.s:1163: Error: registers may not be the same -- `strexb r0,r0,[r1]'
[cc] ccKXT9LB.s:1188: Error: registers may not be the same -- `strexh r0,r0,[r1]'
Oh, and i found out that if I change the optimization from -O0
to -O1 the error becomes: [cc] ccKXT9LB.s:1163: Error: registers
may not be the same -- strexb r0,r0,[r1]' [cc] ccKXT9LB.s:1188:
Error: registers may not be the same --strexh r0,r0,[r1]'
Go to cmsis directory of the firmware, open core_cm3.c and change these functions:
uint32_t __STREXB(uint8_t value, uint8_t *addr)
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value));
return(result);
}
uint32_t __STREXH(uint16_t value, uint16_t *addr)
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value));
return(result);
}
For the source of the solution see here and here
FOUND IT!
Someone more clever than me can probably explain it, but anyway I got it fixed by unchecking the "Enable LTO" box under linker configuration.
Right click project -> Configuration -> Link tab -> uncheck "Enable LTO". Done..
I hope this will help others.
Related
CGo appears to be removing preprocessor definitions. Has anyone else run into this?
In my other C code on the same machine, this works fine. In CGo, the "__AVX2__" definition gets removed.
I've tried this with and without the '-march=native'
How can I get it back ?
The code:
//go:build amd64 && !purego && gc
// +build amd64,!purego,gc
// #cgo CFLAGS: -march=native
package keccakAVX512
/*
// check if the amd64 machine supports AVX512 instructions at build time and call
// an assembly function using AVX512 if so.
#ifdef __AVX2__
void keccakF1600_AVX512(unsigned long* state);
this should fail with a syntax error but doesn't
#endif
// void keccakF1600_AVX512(unsigned long* state) {};
*/
import "C"
func KeccakF1600AMDAVX512(a *[25]uint64) {
C.keccakF1600_AVX512((*C.ulong)(&a[0]))
}
With the 'go tool cgo' command, I see that the default '-m64' is taking precedence, even with the CFLAGS set.
I found that the problem was in the #cgo syntax. It has to be inside the '/**/' comment block instead of the '//' comment block.
package keccakAVX512
/*
#cgo CFLAGS: -march=native
// check if the amd64 machine supports AVX512 instructions at build time and call
// an assembly function using AVX512 if so.
#ifdef __AVX2__
void keccakF1600_AVX512(unsigned long* state);
#else
void keccakF1600_AVX512(unsigned long* state) {};
#endif
*/
import "C"
func KeccakF1600AMDAVX512(a *[25]uint64) {
C.keccakF1600_AVX512((*C.ulong)(&a[0]))
}
I write a simple c++ program that use new function and don't use delete function, then I use asan, but it not report.
#include <iostream>
#include <stdint.h>
using namespace std;
int main()
{
int *p = new int[50];
for (uint32_t i = 0; i < 50; ++i)
{
*(p + i ) = i;
}
cout << *p << endl;
return 0;
}
then ./g++ main.cpp -lasan -L/root/local/lib64/ -fsanitize=address -fno-omit-frame-pointer -g
and print 0, but not report delete leak . why ?
if I use export LD_PRELOAD=/usr/local/lib64/libasan.so.0.0.0, then ./g++ main.cpp
report
g++: internal compiler error: Segmentation fault (program collect2)
0x40c400 execute
../../gcc/gcc.c:2823
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
it look like collect2 core dump ,so I run cd libexec/gcc/x86_64-unknown-linux-gnu/4.8.5/ && ./colloct2, report Segmentation fault (core dumped)
I use source to install gcc-4.8.5, centos 6.
gcc-4_8-branch doesn't even contain libsanitizer/lsan/ directory. Please try more recent GCC versions. by https://github.com/google/sanitizers/issues/699
NOTE - I don't have paging set up yet and my kernel is multi-boot, ELF. I do have irqs and the isrs done.
So I have this GAS file here:
.section .text
.global _start
_start:
mov $0xDEADBEEF, %eax
And GRUB2 setup to load the flat binary file:
menuentry "fOS-Terminal (25x80)" {
multiboot /boot/fos.elf
module /modules/program.bin
set gfxmode=80x25
}
And here in my kernel.c, I can parse the multiboot header to get the module's address and I am calling it:
typedef void (*call_module_t)(void);
call_module_t start_program = (call_module_t)mbd->mods_addr;
start_program();
Right now I am trying to compile my GAS file into a flat binary with these commands:
i686-elf-as --32 ./iso/modules/program.s -o ./iso/modules/program.o
i686-elf-ld -fPIC -shared --oformat binary ./iso/modules/program.o -o ./iso/modules/program.bin
PROBLEM - GRUB2 is surely loading the kernel, multi-boot header is telling me it's at address - 0x100ac but when I go there, I get the exception: INVALID OPCODE.
This seems helpful but is not :(
https://littleosbook.github.io/book.pdf#page=49&zoom=auto,-100,472
EDIT - 1 So when I gdb'd to the calling function, this comes up:
Here is the problem
typedef void (*call_module_t)(void);
call_module_t start_program = (call_module_t)mbd->mods_addr;
start_program();
mbd->mods_addr is the address of modules structure table. And not the address to module itself.
so what is the solution?
unsigned int* modules = (unsigned int*)mbd->mods_addr;
if (mbd->mods_count > 0)
{
unsigned int addr = modules[0];
unsigned int size = modules[1];
call_module_t start_program = (call_module_t)addr;
start_program();
}
else
painc("module wasn't loaded");
I'm using Eclipse 4.2, with CDT, and MinGW toolchain on a Windows machine (although I've a feeling the problem has nothing to do with this specific configuration). The G++ compiler is 4.7
I'm playing with c++11 features, with the following code:
#include <iostream>
#include <iomanip>
#include <memory>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main( int argc, char* argv[] )
{
vector<int> v { 1, 2, 3, 4, 5, 6, 7 };
int x {5};
auto mark = remove_if( v.begin(), v.end(), [x](int n) { return n<x; } );
v.erase( mark, v.end() );
for( int x : v ) { cout << x << ", "; }
cout << endl;
}
Everything is very straight forward and idiomatic c++11. The code compiles with no problems on the command line (g++ -std=c++11 hello.cpp).
In order to make this code compile In eclipse, I set the compiler to support C++11:
Properties -> C/C++ Build -> Settings -> Miscellaneous -> Ohter Flags:
I'm adding -std=c++11
Properties -> C/C++Build -> Discovery Options -> Compiler invocation arguments:
Adding -std=c++11
That's the only change I did to either the global preferences or to the project properties.
First Question: Why do I've to change the flags in two places? When each compiler flags is used?
If I hit Ctrl-B, the project will build successfully, as expected, and running it from within eclipse show the expected result (It prints: '5, 6, 7,').
However, the editor view shows red marks of error on both the 'remove_if' line, and the 'v.erase' line. Similarly, the Problems view shows I've these two problems. Looking at the details of the problem, I get:
For the remove_if line: 'Invalid arguments. Candidates are: #0 remove_if(#0, #0, #1)
For the erase line: 'Invalid arguments Candidates are: '? erase(?), ? erase(?,?)'
Second questions: It appears there are two different builds: one for continues status, and one for the actual build. Is that right? If so, do they have different rule (compilation flags, include paths, etc.)?
Third question: In the problem details I also see: 'Name resolution problem found by the indexer'. I guess this is why the error message are so cryptic. Are those messages coming from MinGW g++ compiler or from Eclipse? What is this Name resolution? How do I fix?
Appreciate your help.
EDIT (in reply to #Eugene): Thank you Eugene. I've opened a bug on Eclipse. I think that C++11 is only partially to blame. I've cleaned my code from C++11 stuff, and removed the -std=c++11 flag from both compilation switch. And yet, the CodAn barks on the remove_if line:
int pred( int n ) { return n < 5; }
int main( int argc, char* argv[] )
{
vector<int> v;
for( int i=0; i<=7; ++i ) {
v.push_back( i );
}
vector<int>::iterator mark = remove_if( v.begin(), v.end(), pred );
v.erase( mark, v.end() );
for( vector<int>::iterator i = v.begin(); i != v.end(); ++i ) {
cout << *i << ", ";
}
cout << endl;
}
The code compiles just fine (with Ctrl-B), but CodAn doesn't like the remove_if line, saying: Invalid Arguments, Candidates are '#0 remove_if(#0,#0,#1)'.
This is a very cryptic message - it appears it misses to substitute arguments in format string (#0 for 'iterator' and #1 for 'predicate'). I'm going to update the bug.
Interestingly, using 'list' instead of 'vector' clears up the error.
However, as for my question, I'm curious about how the CodAn work. Does it uses g++ (with a customized set of flags), or another external tool (lint?), or does it do it internally in Java? If there is a tool, how can I get its command line argument, and its output?
Build/Settings - these flags will be included into your makefile to do actual build. Build/Discovery - these flags will be passed to a compiler when "scanner settings" are discovered by IDE. IDE will run compiler in a special mode to discover values of the predefined macros, include paths, etc.
I believe, the problems you are seeing are detected by "Codan". Codan is a static analysis built into the CDT editor, you may find its settings on "C/C++ General"/"Code Analysis". You should report the problem to the bugs.eclipse.org if you feel the errors shown are bogus. Note that CDT does not yet support all C++11 features.
How is it done? What steps do I need to take and what pitfalls and gotchas are there to consider?
I've gotten this to work, thanks to some inside help over at the Apple Devforums, you should sign up if you're a dedicated IPhone developer.
First thing's first, it's __asm__(), not plain asm().
Secondly, by default, XCode generates a compilation target that compiles inline assembly against the ARM Thumb instruction set, so usat wasn't recognized as a proper instruction. To fix this, do "Get Info" on the Target. Scroll down to the section "GCC 4.0 - Code Generation" and uncheck "Compile for Thumb". Then this following snippet will compile just fine if you set the Active SDK to "Device"
inline int asm_saturate_to_255 (int a) {
int y;
__asm__("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
return y;
}
Naturally, now it won't work with the IPhone Simulator. But TargetConditionals.h has defines you can #ifdef against. Namely TARGET_OS_IPHONE and TARGET_IPHONE_SIMULATOR.
I write quite a bit of ARM Cortex-A8 assembly-code. The CPU on the iPhone is an ARM11 (afaik) so the core instruction set is the same.
What exactly are you looking for? I could give you some examples if you want.
EDIT:
I just found out that on the iPhone you have to use the llvm-gcc compiler. As far as I know it should understand the inline assembler syntax from GCC. If so all the ARM inline assembler tutorials will work on the iPhone as well.
Here is a very minimal inline assembler function (in C). Could you please tell me if it compiles and works on the iphone? If it works I can rant a bit how to do usefull stuff in ARM inline assembler, especially for the ARMv6 architecture and the DSP extensions.
inline int saturate_to_255 (int a)
{
int y;
asm ("usat %0, #8, %1\n\t" : "=r"(y) : "r"(a));
return y;
}
should be equivalent to:
inline int saturate_to_255 (int a)
{
if (a < 0) a =0;
if (a > 255) a = 255;
return a;
}
The registers can also be used explicitly in inline asm
void foo(void) {
#if TARGET_CPU_ARM64
__asm ("sub sp, sp, #0x60");
__asm ("str x29, [sp, #0x50]");
#endif
}
Thumb is recommended for application which do not require heavy float operation. Thumb makes the code size smaller and results also in a faster code execution.
So you should only turn Thumb off for application like 3D games...
Background
Now is 2021 year -> other answer seems is too old?
the most iOS device(iPhone etc.) is ARM 64bit: arm64
Inline assembly on the iPhone
asm keyword
GNU/GCC compiler
standard C (compile flag: -ansi / -std): use __asm__
GNU extensio: use asm
ARM compiler: use __asm
asm syntax
AFAIK, there many asm syntax
asm syntax
AT&T syntax ~= GNU syntax ~= UNIX syntax
Intel syntax
ARM syntax
here only focus on most common used GNU/GCC syntax
GNU/UNIX syntax
Basic Asm
asm("assembly code");
__asm__("assembly code");
Extended Asm
asm asm-qualifiers ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])
My Example code
environment
dev
macOS
IDE: XCode
compiler: clang
running
iOS - iPhone
hardware arch: ARM64
inline asm to call svc 0x80 for ARM64 using Extended Asm
inline asm inside ObjC code
// inline asm code inside iOS ObjC code
__attribute__((always_inline)) long svc_0x80_syscall(int syscall_number, const char * pathname, struct stat * stat_info) {
register const char * x0_pathname asm ("x0") = pathname; // first arg
register struct stat * x1_stat_info asm ("x1") = stat_info; // second arg
register int x16_syscall_number asm ("x16") = syscall_number; // special syscall number store to x16
register int x4_ret asm("x4") = -1; // store result
__asm__ volatile(
"svc #0x80\n"
"mov x4, x0\n"
: "=r"(x4_ret)
: "r"(x0_pathname), "r"(x1_stat_info), "r"(x16_syscall_number)
// : "x0", "x1", "x4", "x16"
);
return x4_ret;
}
call inline asm
// normal ObjC code
#import <sys/syscall.h>
...
int openResult = -1;
struct stat stat_info;
const char * filePathStr = [filePath UTF8String];
...
// call inline asm function
openResult = svc_0x80_syscall(SYS_stat64, filePathStr, &stat_info);
Doc
GCC-Inline-Assembly-HOWTO (ibiblio.org)
Extended Asm (Using the GNU Compiler Collection (GCC))
Procedure Call Standard for the Arm® 64-bit Architecture
ARM GCC Inline Assembler Cookbook
ConvertBasicAsmToExtended - GCC Wiki
ios - fork() implementation by using svc call - Stack Overflow
linux - ARM inline asm: exit system call with value read from memory - Stack Overflow