I'm trying to write a simple system call on XV6 (documentation available here and Github here) in order to understand how they're implemented. I've used these steps
In syscall.c, declared extern int sys_hello(void) and added [SYS_hello] sys_hello into static int (*syscalls[])(void) array
In syscall.h, defined SYS_hello as call number 22
In user.h, declared the function prototype as int hello (void);
In usys.S, added SYSCALL(hello) to the macro
In sysproc.c, added the function sys_hello(void) at the bottom
int sys_hello(void)
{
cprintf ("Hello World System Call\n");
return 0;
}
Created hello.c which simply calls the hello() system call
Added hello.c to the Makefile and ran the code
It worked as expected.
Now, my question is that it seems that the array in syscall.c matches the indexes of the commands with the system call numbers in syscall.h file
However, if I move the hello position to the second spot in the syscall.c and let the system command number in syscall.h stay 22 the system command works as before. Where as, I expected that it'd break. Can you help me understand how the array syscall.c maps (if that's even the correct word) to the syscall.h system call number?
I'm fairly new to XV6 and C so please don't get mad at me if this question seems silly, I'm only trying to learn.
Here is the Github link to my fork of the XV6 repository if that helps: github.com/AdityaSingh/XV6
The array of syscalls is syscall.c makes use of the designated initialization syntax where you can specify at which index to assign the value.
static int (*syscalls[])(void) = {
[SYS_fork] sys_fork,
}
SYS_fork, defined as 1, specifies the index where to assign sys_fork. Thus the order of the elements doesn't matter using this syntax.
Related
Let's say I have a program (program.c) that uses rand function in standard C library.
1 #include <stdlib.h>
2 int main(){
3 int rand_number = rand();
4 }
I also have a shared library (intercept.c) that I created to change the behaviour of rand function (simply adds +1 to the result) in the standard library.
int rand(void){
int (*rand_func)();
rand_func = dlsym(RTLD_NEXT, "rand");
int result = (*rand_func)();
return result + 1;
}
And I run the program with
LD_PRELOAD=./intercept.so ./program
Is there any way to get the line number (Line 3) and name of the caller function (main) without modifying the program.c's source code?
It is not immediate, but you can use backtrace() in order to obtain each frame in the call stack.
Then invoking the external command eu-addr2line -f -C -s --pretty-print -p your_pid the_previous_frames... (with popen() or pipe()/fork()/dup2()/exec()...) and parsing its output will provide the information you need
(if compiled with -g).
regarding:
Is there any way to get the line number (Line 3) and name of the caller function (main) without modifying the program.c's source code?
compile the program with the -ggdb3 option, Then set a break point where you want to stop the program. Then use the backtrace command bt. This will show the function names, the line numbers, etc
Another (Linux specific) approach is to compile everything with -g (perhaps also -O) using GCC and to use Ian Taylor's excellent libbacktrace.
That library parses the DWARF debug information and knows line numbers.
You'll need several hours to understand libbacktrace (read carefully the header file). I am using it in RefPerSys
I have several files in the structure
/algorithms
/a1
a1.c
/a2
a2.c
/a3
a3.c
Each of these files contains a function of the same name. Each has the same signature, except for the name (which is the same as the filename). Essentially, each algorithm is a different implementation of the same thing -- different means to the same end. There may however be small helper functions.
The content of the files (comments, functions, layout, etc) cannot change.
I want to create some method that will test each algorithm. This method is not confined to being implemented in C.
I have a C file that essentially contains three functions:
// Runs the algorithm, which modifies the given integer array.
void run(void (*algorithm) (int*, size_t));
// Checks that the algorithm successfully completed and
// the array is correct.
int check(int*, size_t);
// Should call run() with appropriate algorithm and a random data set
// and then call check() to make sure it worked.
int main(int, char**);
I need an automated way of including the appropriate files and then calling
the function within them. Currently, I have a bash file that gets all the algorithms, copies the tester file, prepends an #include statement at the beginning and a generated injected_main() function that gets called by the actual main() function. It runs the copied tester and then deletes it.
function testC() {
local tempout=temptest.c
local filename="$(basename -- $1)"
local functionname="${filename%.*}"
local main="void injectedMain() {test(&$functionname);}"
local include="#include\"$1\"\n$main"
touch $tempout
chmod +x $tempout
printf "$filename: "
cp $TESTER_C $tempout
printf "$include" >> $tempout
gcc $tempout -o tempout -Wall -Wextra -pedantic
./tempout
rm $tempout tempout
}
Where the function is run in a loop for every algorithm C file.
However, this method is prone to error, not extendable, and just downright ugly. Is there a better way to do this?
Combine your existing code and #Herve's answer.
You could let the bash script just collect all algorithms and build a C source like that proposed by #Herve. This way there will be no error prone manual step.
To run all tests compile this automatically generated source and link it to your test runner. Let the latter loop through all.
Can't you just a header including your algorithm implementations and loop through all of them?
Something like
#include "a1/a1.h"
#include "a2/a2.h"
#include "a3/a3.h"
typedef void (*AlgorithmImplemetation)(void); //Your algorithm function signature goes here
AlgorithmImplemetation *all = {
a1,
a2,
a3
};
Then include this header in your main.c and loop through all.
I'm working on an application which defines it's own printf() to get around differences between the different CRTs out there or because some other platforms don't have it.
When building the application with gcc this automatically seems to work and the custom printf is used instead of libc's one; if I understand it correctly this is because of the order in which object files/libraries appear in the link command or maybe because object files are always searched before CRT libs, correct?
I'd like to do the same using msvc. Just building the project gives the expected 'LNK2005: _printf already defined in printf.obj' because printf is also in msvcrtd.lib. Fair enough. I know about /NODEFAULTLIB but that excludes everything resulting in unresolved references for everything but printf. I scanned through the other linker settings but couldn't find anything which allows this (apart from /FORCE maybe, but the 'might produce an invalid executable' comment doesn't make it sound like a good idea). Also nothing in the module definition file docs; the latter got me thinking it might be possible to create a stub library which has all exports from msvcrt.lib except printf but that seems a brittle solution even if it works.
In the end the question is simple: how do I tell msvc's linker it should skip msvcrt's printf definition and use the one from my printf.obj instead. Basically /NODEFAULTFUNCTION:printf or so. Just an answer for one single executable is ok, though I'd also be interested to know if and how it can be done when building a dll instead where the custom printf is exported: how to tell the linker it should use the export from my .lib instead of msvcrt.lib?
edit simplest repo I could find: create a file main.c:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello");
return 0;
}
and a file printf.c:
int printf(const char *fmt, ...)
{
write(1, "ok\n", 3);
return 3;
}
For VS2013 (though the other versions might work as well): create a new empty C++ project and add both files then build. (For gcc: just gcc main.c printf.c and the resulting a.out prints 'ok')
The culptrit for VS is #include : without that it works ok but I have yet to find out if the original code allows getting rid of it in some way. But even if it does I'd still want to know if this can be solved at the link level.
I'm new to programming and currently I'm learning C programming. I'm writing codes on the code blocks and in it using GCC compiler. When I create a new project, (as you know it creates main.c file with it) and due to that I'm not able to compile another file in that project.
File 1:
#include<stdio.h>
int main()
{
int a,b,c,d;
printf("Enter three numbers\n");
scanf("%d%d%d",&a,&b,&c);
d=a;
if(b>d)
d=b;
if(c>d)
d=c;
printf("\n The maximum of three numbers is %d",d);
}
File 2: main.c
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
When I compile the first programme, it shows the following error:
multiple definition of 'main'
first defined here
I've searched every where I could and I'm not able to solve this. In one of the answers here on stack overflow, someone had suggested to write this in
(Project->Build options...->Linker settings (tab))
-Wl,--allow-multiple-definition
When I wrote it, there were no errors. But it wasn't able to run my File 1 and instead, it runs that main.c file. Even when I close the main.c file, it opens there again and runs main.c file which gives the output "Hello World!".
Initially when I was using code blocks there were no such errors. I don't know why this is happening and I've not much knowledge about compilers.
As noted in comments you can only have one main function.
So when you start a new project you need to replace the main.c file with the main.c file you want to use. Or you can edit the 'hello world' main.c program.
When you start a new project in code::blocks you can get a new directory with a simple program that prints 'Hello World'. This file is usually main.c. You need to edit this file or replace it. The reason that code::blocks puts this simple main.c program in the new project is so that you can compile it and test your system without having to write a new program.
Some computer languages allow you to use the same function name for different functions ( which are identified by their parameters and sometimes return types ). That's called overloading. C does not allow this. Functions in C must have unique names.
The main() function is a special one in C as it is used as the standard entry point for applications. That is, the main() function will be called first and your application should start and (typically) end in that function.
As a beginner I would suggest you avoid automated editor features that create and build projects for you. You will miss out on learning how things work doing that. Use an editor to start from empty files and learn how they all connect and how to use the compiler from the command line. The command line is something every beginner should start from, IMO.
It may be harder to learn, but it will give you a much better feel for what is going on.
I guess what you maybe trying to do is have multiple sandbox "gists" that you may wanna run all as their own main function. If that is the case, then just close your project and open the files directly. As long as they are not in a project, they will run fine.
Ever since Go 1.5 came out, I started taking another look at how I could integrate it into an existing project of mine.
The project's codebase is written entirely in C for low level access to to hardware and other fun stuff. However, some of the higher level things are tedious, and I would like to start writing them in a higher level language (Go)
Is there any way I can call Go code from a C program? I installed Go 1.5, which added -buildmode=c-archive (https://golang.org/s/execmodes) which I am trying to get working.
However, I can't seem to get Go to generate the appropriate header files to allow my project to actually compile. When I generate the archive, I see the function in the exported symbols (using objdump), but without the header files to include gcc complains about the function not existing (as expected)
I'm quite new to Go - however, I love the language and would like to make use of it. Is there any idiomatic way ("idiomatic" gets used a lot in the world of Go I see...) to get this to play nicely with each other?
The reason I asked this question and specifically mentioned Go 1.5 is that according to this document, https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit?pli=1#heading=h.1gw5ytjfcoke
Go 1.5 added support for non-Go programs to call Go code. Specifically, mentioned under the section "Go code linked into, and called from, a non-Go program"
To build an archive callable from C, you will need to mark them as exported CGo symbols.
For example, if I create a file foo.go with the following contents:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x int) {
fmt.Println(x)
}
func main() {}
The important things to note are:
The package needs to be called main
You need to have a main function, although it can be empty.
You need to import the package C
You need special //export comments to mark the functions you want callable from C.
I can compile it as a C callable static library with the following command:
go build -buildmode=c-archive foo.go
The results will be an archive foo.a and a header foo.h. In the header, we get the following (eliding irrelevant parts):
...
typedef long long GoInt64;
...
typedef GoInt64 GoInt;
...
extern void PrintInt(GoInt p0);
...
So that's enough to call the exported function. We can write a simple C program that calls it like so:
#include "foo.h"
int main(int argc, char **argv) {
PrintInt(42);
return 0;
}
We can compile it with a command like:
gcc -pthread foo.c foo.a -o foo
The -pthread option is needed because the Go runtime makes use of threads. When I run the resulting executable it prints 42.
The code above work just fine, but gcc will complain about functions and headers.
The includes should be:
#define _GNU_SOURCE
#include <stdio.h>
#include "mygopkg.h"
If you forget the #define _GNU_SOURCE, the gcc will complain:
warning: implicit declaration of function 'asprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]
If you forget the #include "mygopkg.h", the gcc will complain:
warning: implicit declaration of function 'PrintString' [-Wimplicit-function-declaration]
The last but not less important. The build command line I recommend for production code is:
go build -ldflags "-s -w" -buildmode c-archive -o mygopkg.a
It'll save you 53% size of final mygopkg.a.