Lets say I have a user-defined syscall: foo (with code number 500).
To call it, I simply write in a C file:
syscall(SYS_code, args);
How can I call it using just foo(args)?
You cannot. Not unless you first convince the kernel developers that your syscall is worth being added, then it gets added, and then userspace libraries such as the standard C library (glibc on most Linux distributions) decide to implement a wrapper for it like they do for most of the syscalls.
In other words: since the above is impossible, all you can do is define the wrapper function yourself in your own program.
#define SYS_foo 500
long foo(int a, char *b) {
return syscall(SYS_foo, a, b);
}
Related
Some compilers, says old gcc or egcs, apply ABI-breaking optimization for static functions within single file, like passing arguments or returning results with arbitrary registers.
Consider some source code like:
// Original foobar.c
// This example targets MIPS o32 ABI.
// Shared subroutine
// Compiler decided to use $16, $17 to pass a0 and a1 to minimize stack usage and move between registers.
static void __bar(int a0, int a1) {
// Something very complicated
}
// ...
void foo(int a0, int a1) {
// ...
/*
This call was compiled to something like:
ori $16, $0, 0x1
jal __bar
ori $17, $0, 0x1
*/
__bar(1, 1);
// ...
}
// ...
Suppose someone want to restore / reimplement foobar.c from the compiled assembly without access to the original source.
One would probably like to decompile / rewrite some part first, says start from foo() or other standard functions.
However, in order to test the correctness of the implementation, one must deal with calls to non-standard ABI routines.
A trivial way is to workaround with global register variables provided by gcc / clang:
// Restoration of foobar.c
// void __bar(int asm("s0"), int asm("s1"))
// External function in assembly, says foobar.s, which is from compiled original foobar.c.
void __bar();
volatile register int s0 asm ("s0"); // $16 = s0
volatile register int s1 asm ("s1"); // $17 = s1
// ...
void foo(int a0, int a1) {
// ...
// __bar(1, 1);
s0 = 1; s1 = 1;
__bar();
// ...
}
// ...
The question is:
Does gcc / clang supports customize calling convention for some specific functions?
Are there any way to deal with non-standard ABI calls more elegantly?
Does gcc / clang supports customize calling convention for some specific functions?
The best you can do is opt in to one of the specific supported calling conventions, e.g. one of these for x86. If the static function in question does not conform to any of them, then you're stuck.
Are there any way to deal with non-standard ABI calls more elegantly?
Nothing truly elegant. If none of the supported calling conventions apply, you're stuck with either:
Reversing & rebuilding the whole thing (so it can compile as normal without relying on original binaries), or at least enough of it that you're replacing ABI conforming functions and all their dependencies completely, or
Calling it from assembly, explicitly passing the arguments per the non-standard calling conventions of the compiled function.
#2 is the basis for the most elegant solution, which is basically to write a wrapper function in assembly that receives the arguments and returns the values according to the ABI, and otherwise does nothing but rearrange them to pass to the non-standard function it wraps (and possibly fix up the return value if it's not returning according to normal rules). You write the wrapper(s) once, and now the rest of your code can be written in C, calling the wrapper functions which adhere to the ABI and being blissfully unaware of the weirdness under the covers.
Similarly, if you're trying to replace the existing non-standard function with another, you'd write the non-conforming wrapper in assembly, then write your replacement function in plain C and have the wrapper call it, and swap in your wrapper in your hacked together mix of the original binary and the new code.
In computer software, an application binary interface (ABI) is an interface between two binary program modules; often, one of these modules is a library or operating system facility, and the other is a program that is being run by a user.
An ABI defines how data structures or computational routines are accessed in machine code, which is a low-level, hardware-dependent format; in contrast, an API defines this access in source code, which is a relatively high-level, relatively hardware-independent, often human-readable format. A common aspect of an ABI is the calling convention, which determines how data is provided as input to or read as output from computational routines; examples are the x86 calling conventions.
-- https://en.wikipedia.org/wiki/Application_binary_interface
I am sure that the standard "Function Calling Sequence" described in Sys V ABI specs (both i386 and AMD64) constraints the calling of those extern functions in a C library, but does it constraints the calling of those static functions too?
Here is an example:
$cat abi.c
#include<stdio.h>
typedef void (*ret_function_t)(int,int);
ret_function_t gl_fp = NULL;
static void prnt(int i, int j){
printf("hi from static prnt:%d:%d\n", i, j);
}
void api_1(int i){
gl_fp = prnt;
printf("hi from extern api_1:%d\n", i);
}
ret_function_t api_2(void){
return gl_fp;
}
$cat abi_main.c
#include<stdio.h>
typedef void (*ret_function_t)(int,int);
extern void api_1(int i);
extern ret_function_t api_2(void);
int main(){
api_1(1111);
api_2()(2222, 3333);
}
$gcc abi_main.c abi.c -o abi_test
$./abi_test
hi from extern api_1:1111
hi from static prnt:2222:3333
The function calling sequence (including registers usage, stack frame, parameters passing, variable arguments...) details are defined in the Sys V ABI when abi_main.c call the api_1 and api_2 since they are extern, but what about the calling of the static function prnt which been defined in abi.c? Does it belong to the ABI standard or to the compiler to decide?
Yes, they do apply. Static functions are just plain functions with traslation-unit visibility. The ABI is a compiler generation task, C standard deliberately says nothing about it. It becomes clear when removing the static word from your code. The reasoning is the same. The drawback with this approach is that compiler cannot check the linkage right (caller-callee), but only its type (void (*ret_function_t)(int,int);) at compile time, since you are the one who links at runtime. So, it is not recommended.
What happens is that your compiler will generate code for any calling function, following some ABI, lets call it ABI-a. And it will generate code for
a function being called according to some other ABI, lets say ABI-b. If ABI-a == ABI-b, that always work, and this is the case if you compile both files with the same ABI.
For example, this works if prnt function were located at address 0x12345678:
ret_function_t gl_fp = (ret_function_t)0x12345678;
It also works as long as there is a function with the right arguments at 0x12345678. As you can see, the function cannot be inlined because the compiler does not know which function definition will end up in that memory spot, there could be many.
So I am currently learning assembly language (AT&T syntax). We all know that gcc has an option to generate assembly code from C code with -S argument. Now, I would like to look at some code, how it looks in assembly. The problem is, on laboratories we compile it with as+ld, and as for now, we cannot use C libraries. So for example we cannot use printf. We should do it by syscalls (32 bit is enough). And now I have this code in C:
#include <stdio.h>
int main()
{
int a = 5;
int b = 3;
int c = a + b;
printf("%d", c);
return 0;
}
This is simple code, so I know how it will look with syscalls. But if I have some more complicated code, I don't want to mess around and replace every call printf and modify other registers, cuz gcc generated code for printf, and I should have it with syscalls. So can I somehow make gcc generate assembly code with syscalls (for example for I/O (console, files)), not with C libs?
Under Linux there exist the macro family _syscallX to generate a syscall where the X names the number of parameters. It is marked as obsolete, but IMHO still working. E.g., the following code should work (not tested here):
_syscall3(int,syswrite,int,handle,char*,str,int len);
// ---
char str[]="Hello, world!\n";
// file handle 1 is stdout
syswrite(1,str,14);
I have written a program and i want to link it to another c program. In the sense, by using the include or any other directive, I need to link the programs, such that a function of the former can be called by the latter. How can i accomplish this in codebloacks ?
Suppose you have now two programs A and B. And in A you have function c. So, move c to separate file c.c and make c.h file, that can be included in both A and B program as #include "c.h". Than compile A and B independently.
It will be the simplest way.
EDIT:
All function that uses one another should be in the "library". E.g.:
// c.h
int c(int x1, int x2); // this will be called from outside
extern int callCount; // to be available outside
and
// c.c
#include "c.h"
int d(int x); // this cannot be called from outside
// global variable to count calls of c function
int callCount = 0;
int c(int x1, int x2)
{
callCount++; // changing of global variable
return (x1 + x2) * d(x1);
}
int d(int x)
{
return x * x;
}
and usage
// prog A
#include <stdio.h>
#include "c.h"
int main(void)
{
int a = 1, b = 2;
printf("c = %d\n", c(a, b));
printf("c = %d\n", c(2*a, b - 1));
printf("Function c was called %d times\n", callCount);
return 0;
}
All the functions that you are planning to call from other files should be declared in h-file. It is the common approach, but also lots of tips can be find in the Internet, such as static functions, #define detectives and conditional compilation, etc.
It (loading a C program in another one) cannot be stricto sensu done, since there is only one single main function in any given program. However the system(3) & popen(3) functions enable you to start another program -thru a command line- from a first one. On Linux and POSIX systems you also can start a process using fork(2) and you can execute a program in a process using execve(2). Of course this is operating system specific!
However, on some operating systems and platforms, you can use dynamic linking to load some plugin at runtime. The loaded plugin is not a program (it does not have any main function), but a library.
For example, on Linux and POSIX systems, you could use the dlopen function to load a plugin (often some shared library), and the dlsym function to get a symbol inside it.
On Linux, dlopen is loading an ELF shared object which should contain position-independent code.
PS. You can also link a library (at build time) to your program.
I would like to compile the functions of glibc to an object file which will then be linked to a program which I am running on a computer without any operating system. Some functions, such as open, I want to just fail with ENOSYS. Other functions I will write myself, such as putchar, and then have glibc use those functions in it's own (like printf). I also want to use functions that don't need a file system or process management system or anything like that, such as strlen. How can I do this?
Most C libraries rely on the kernel heavily, so it's not reasonable to port 'em. But since most of it doesn't need to be implemented, you can get away easily with a few prototypes for stubs and gcc builtins.
You can implement stubs easily using weak symbols:
#define STUB __attribute__((weak, alias("__stub"))) int
#define STUB_PTR __attribute__((weak, alias("__stub0"))) void *
int __stub();
void *__stub0();
Then defining the prototypes becomes trivial:
STUB read(int, void*, int);
STUB printf(const char *, ...);
STUB_PTR mmap(void*, int, int, int, int, int);
And the actual functions could be:
int __stub()
{
errno = ENOSYS;
return -1;
}
void *__stub0()
{
errno = ENOSYS;
return NULL;
}
If you need some non-trivial function, like printf, take it from uClibc instead of glibc (or some other smaller implementation).