Cygwin gcc - asm error: - c

I have a project written in C that originally was being done on Linux, but now must be done on Windows. Part of the code include this line in several places
asm("movl temp, %esp");
But that causes an "undefined reference to `temp'" error.
This has no problem compiling on Linux using the gcc 4.3.2 compiler (tested on another machine), which is the version I have on Cygwin. Is there another way to accomplish what this line is doing?

You need to change the cygwin version from
asm("movl temp, %esp");
to
asm("movl _temp, %esp");
Yes, it's the same compiler and assembler but they are set up differently for compatibility with the host system.
You can isolate the system-dependent symbol prefixing by simply telling gcc a specific name to use:
int *temp asm("localname");
...
__asm__("movl localname,%esp");
This avoids an #if of some sort and removes a host OS dependency but adds a compiler dependency. Speaking of compiler extensions, some people would write (see info as) something like:
#ifdef __GNUC__
__asm__("movl %[newbase],%%esp"
:
: [newbase] "r,m" (temp)
: "%esp");
#else
#error haven't written this yet
#endif
The idea here is that this syntax allows the compiler to help you out, by finding temp, even if it's lying about in a register or takes a few instructions to load, and also to avoid conflicting with you, it case it was using a register you clobbered. It needs this because a plain __asm__() is not parsed in any way by the compiler.
In your case, you seem to be implementing your own threading package, and so none of this really matters. Gcc wasn't about to use %esp for a calculation. (But why not just use pthreads...?)

Related

Ignore SDCC compiler language extensions when compiling with GCC

I'm trying to compile some c-code that was originally written for SDCC using GCC to run some unit tests on a host computer.
There are some language extensions for SDCC like __xdata or __pdata (for memory control) which should remain for SDCC but that should be ignored when compiled with GCC. I would strongly prefer not to modify the modules under test. Is there any way to do this?
I already figured out that it works if I add something like #define __xdata in the module under test. Maybe it is possible to have something like a "global definition" therefore? I have little experience with the GCC. Maybe there are compiler flags that could help me?
There are two compiler flags, you could use:
-include allows you to give a c file that is additionally included and do the defines in that file.
Define macros via command line options -D__xdata=

Trying to port GCC specific asm goto to Clang

I've been trying to turn a bit of GNU extensions in to actual standard C so it'll run on clang, knowing standard C and not GNU extensions, I'm at a bit of a loss.
__asm__ (goto("1:"
STATIC_KEY_INITIAL_NOP
".pushsection __jump_table, \"aw\" \n\t"
_ASM_ALIGN "\n\t"
_ASM_PTR "1b, %l[l_yes], %c0 \n\t"
".popsection \n\t"
: : "i" (key) : : l_yes););
I've tried to turn this in to actual asm, but have yet to be successful.
If you're curious, this is part of a kernel I've just about got to build on clang, besides that one section.
You seem to be having a problem compiling arch/x86/include/asm/jump_label.h. The entire code-snippet is to enable support for "jump label patching". A new feature quite useful to allow debugging(print logs etc.) with have near-zero overhead when debugging is disabled.
The implementation you encounter depends on gcc(v4.5) which adds a new asm goto statement that allows branching to a label.
It appears that Clang/LLVM < 9.0.0 does NOT support asm goto.
As a quick fix to get your Linux kernel compiling properly, you can disable CONFIG_JUMP_LABEL in your kernel configuration. This config option is used to disable the optimisation when the compiler does NOT support asm goto properly.
Update: Initial support for asm goto was added to Clang in v9.0.0.
Initial support for asm goto statements (a GNU C extension) has been
added for control flow from inline assembly to labels. The main consumers of
this construct are the Linux kernel (CONFIG_JUMP_LABEL=y) and glib. There are
still a few unsupported corner cases in Clang's integrated assembler and
IfConverter. Please file bugs for any issues you run into.

C/pre-processor: detect if a __builtin function is available

Is it possible to somehow determine whether an intrinsic function, such as __builtin_bswap16 is provided by the compiler? Preferably, I would like to be able to determine whether this function exists using just preprocessor.
In my particular case, I was using __builtin_bswap16 / 32 / 64 functions in my code which worked fine with GCC 4.x when compiling for 32-bit. Later I switched to a 64-bit Linux and noticed that __builtin_bswap16 suddenly disappeared - I received a linker error:
"undefined reference to `__builtin_bswap16'".
I guess this has something to do with the availability of certain ASM operations in 64-bit mode.
On a later occasion I was trying to compile this code on a different machine where unfortunately only an older version of GCC is installed and does not support these functions at all.
I would like to make this code compilable everywhere, using __builtin_bswap functions if provided, and fall back to hand-coded byteswap routine if not. Is it possible to achieve this somehow with just preprocessor?
My obvious attempt, e.g.:
...
#define MYBSWAP16(v) (v>>8)|(v<<8)
#ifdef __builtin_bswap16
printf("bswap16 is defined : %04x\n", __builtin_bswap16(0x1234));
#else
printf("bswap16 is not defined : %04x\n", MYBSWAP16(0x1234) );
#endif
...
was not successful, as __builtin_bswap16/32/64 are always evaluated to be undefined. Is there any way to make it work automatically within the C source, or is the only way to manually define constants in the Makefile, e.g. HAVE_BSWAP and pass them via -D option?
Please note that my question is not necessarily specific to __builtin_bswap, I'm looking for a general way to detect if the certain functions are available.
Unavailability of __builtin_bswap16 is a gcc bug which was fixed in gcc 4.8.
Sincw it is missing from some versions of gcc you can always add it to your code yourself :
static inline unsigned short __builtin_bswap16(unsigned short a)
{
return (a<<8)|(a>>8);
}

Compiling without libc

I want to compile my C-code without the (g)libc. How can I deactivate it and which functions depend on it?
I tried -nostdlib but it doesn't help: The code is compilable and runs, but I can still find the name of the libc in the hexdump of my executable.
If you compile your code with -nostdlib, you won't be able to call any C library functions (of course), but you also don't get the regular C bootstrap code. In particular, the real entry point of a program on Linux is not main(), but rather a function called _start(). The standard libraries normally provide a version of this that runs some initialization code, then calls main().
Try compiling this with gcc -nostdlib -m32:
// Tell the compiler incoming stack alignment is not RSP%16==8 or ESP%16==12
__attribute__((force_align_arg_pointer))
void _start() {
/* main body of program: call main(), etc */
/* exit system call */
asm("movl $1,%eax;"
"xorl %ebx,%ebx;"
"int $0x80"
);
__builtin_unreachable(); // tell the compiler to make sure side effects are done before the asm statement
}
The _start() function should always end with a call to exit (or other non-returning system call such as exec). The above example invokes the system call directly with inline assembly since the usual exit() is not available.
The simplest way to is compile the C code to object files (gcc -c to get some *.o files) and then link them directly with the linker (ld). You will have to link your object files with a few extra object files such as /usr/lib/crt1.o in order to get a working executable (between the entry point, as seen by the kernel, and the main() function, there is a bit of work to do). To know what to link with, try linking with the glibc, using gcc -v: this should show you what normally comes into the executable.
You will find that gcc generates code which may have some dependencies to a few hidden functions. Most of them are in libgcc.a. There may also be hidden calls to memcpy(), memmove(), memset() and memcmp(), which are in the libc, so you may have to provide your own versions (which is not hard, at least as long as you are not too picky about performance).
Things might get clearer at times if you look at the produced assembly (use the -S flag).

How to force gcc use int for system calls, not sysenter?

Is it possible to force gcc use int instruction for all the system calls, but not sysenter? This question may sound strange but I have to compile some projects like Python and Firefox this way.
Summary
Thanks to jbcreix, I've downloaded glibc 2.9 source code, and modified the lines in sysdeps/unix/sysv/linux/i386/sysdep.h, to disable use of sysenter by #undef I386_USE_SYSENTER, and it works.
Recompile your C library after replacing sysenter by int 0x80 in syscall.s and link again.
This is not compiler generated code which means you are lucky.
The ultimate origin of the actual syscall is here, as the OP says:
http://cvs.savannah.gnu.org/viewvc/libc/sysdeps/unix/sysv/linux/i386/sysdep.h?root=libc&view=markup
And as I suspected there really was a syscall.S it's just that the glibc sources are a labyrinth.
http://cvs.savannah.gnu.org/viewvc/libc/sysdeps/unix/sysv/linux/i386/syscall.S?root=libc&view=markup
So I think he got it right, asveikau.
You don't modify gcc; you modify libc (or more accurately, recompile it) and the kernel. gcc doesn't emit sysenter instructions; it generates calls to the generic syscall(2) interface, which presents a unified front end to system call entry and exit.
Or, you could use a Pentium; SYSENTER wasn't introduced until PII =]. Note the following KernelTrap link for the interesting methods used by Linux: http://kerneltrap.org/node/531

Resources