I need to write the following C code in NIOS II assembly code. and know the stack state from the L1 label.
struct lelt
{
int value;
struct lelt* next;
}
struct lelt x = {3,NULL};
lelt* get_tail(lelt *ptr)
{
lelt* last;
L1: last = NULL;
while(ptr != NULL)
{
last = ptr;
ptr = ptr -> next;
}
return last;
}
Here's what I've wrote till now but I don't know how to manage the write the rest of the code because I'm not very familiar with the structs in assembly code. So if someone can help me out and explain a little bit I'd be grateful.
x:
value .word 3
next .word 0
get_tail:
subi sp, sp,12
stw ra, 0(sp)
stw r16, 4(sp) // ptr
stw r17, 8(sp) // last
movia r16,zero,r4
bne r4,zero,endwhile
add r17,zero,r16
... // i don't know how to write ptr=ptr->next
endwhile:
add r2,r17,zero
br end
end:
ldw ra,0(sp)
ldw r16,4(sp)
ldw r17,8(sp)
addi sp,sp,12
ret
So I guess r16 is your ptr. The next member in the struct is at offset 4. To load that into ptr, just do ldw r16, 4(r16).
Related
I have an example program I am running here to see if the substring matches the string and then print them out. So far, I am having trouble running the program due to a bad address. I am wondering if there is a way to fix this problem? I have attached the entire code but my problem is mostly related to isSubstring.
#include <uapi/linux/bpf.h>
#define ARRAYSIZE 64
struct data_t {
char buf[ARRAYSIZE];
};
BPF_ARRAY(lookupTable, struct data_t, ARRAYSIZE);
//char name[20];
//find substring in a string
static bool isSubstring(struct data_t stringVal)
{
char substring[] = "New York";
int M = sizeof(substring);
int N = sizeof(stringVal.buf) - 1;
/* A loop to slide pat[] one by one */
for (int i = 0; i <= N - M; i++) {
int j;
/* For current index i, check for
pattern match */
for (j = 0; j < M; j++)
if (stringVal.buf[i + j] != substring[j])
break;
if (j == M)
return true;
}
return false;
}
int Test(void *ctx)
{
#pragma clang loop unroll(full)
for (int i = 0; i < ARRAYSIZE; i++) {
int k = i;
struct data_t *line = lookupTable.lookup(&k);
if (line) {
// bpf_trace_printk("%s\n", key->buf);
if (isSubstring(*line)) {
bpf_trace_printk("%s\n", line->buf);
}
}
}
return 0;
}
My python code here:
import ctypes
from bcc import BPF
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
string = contents[i].encode('utf-8')
print(len(string))
lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="Test")
b.trace_print()
Edit: Forgot to add the error: It's really long and can be found here: https://pastebin.com/a7E9L230
I think the most interesting part of the error is near the bottom where it mentions:
The sequence of 8193 jumps is too complex.
And a little bit farther down mentions: Bad Address.
The verifier checks all branches in your program. Each time it sees a jump instruction, it pushes the new branch to its “stack of branches to check”. This stack has a limit (BPF_COMPLEXITY_LIMIT_JMP_SEQ, currently 8192) that you are hitting, as the verifier tells you. “Bad Address” is just the translation of kernel's errno value which is set to -EFAULT in that case.
Not sure how to fix it though, you could try:
With smaller strings, or
On a 5.3+ kernel (which supports bounded loops): without unrolling the loop with clang (I don't know if it would help).
Ok, so I have this program that is suppose to simulate an "Uber" driver picking up and dropping off customers and informing him of how far he has driven and how much gas he should have felt. I basically have it all worked out but for the life of me I can't get the gas to go down it stays at a static number. I know it is probably something so simple its dumb but I can't see it.
in my FuelGauge.h
#ifndef FuelGauge_h
#define FuelGauge_h
#define MAXG 15
// Class FuelGauge definition
class FuelGauge
{
// Data member
static int gallons;
public:
// Overloading -- operator
void operator --()
{
--gallons;
}// End of function
// Function to return gallons
int getGallons()
{
return gallons;
}// End of function
};// End of class
// Initializes static data member
int FuelGauge::gallons = MAXG;
#endif /* FuelGauge_hpp */
in my Car.h
#ifndef Car_h
#define Car_h
#include "FuelGauge.h"
#include "Odometer.h"
// Class car definition
class Car
{
public:
// Declares object as data member using deligation
FuelGauge *fg;
Odometer *om;
// Overloads >> operator
friend std::istream & operator >>(std::istream &is, Car &c)
{
int no;
// Loops till valid mileage entered by the user
do
{
// Accepts mileage
std::cin>>no;
// Checks if the mileage is zero or negative show error message
if(no <= 0)
std::cout<<"\n Invalid response, mileage should be greater than 0. \n Please reenter data.";
// Otherwise come out of the loop
else
break;
}while(1);
// Loops till no
for(int x = 0; x < no; x++)
// Increase the mileage by one
++*c.om;
// Checks if the current mileage is greater than or equals to 24 and entered mileage is less than 24
if(c.om->getCurrentMileage() >= 24 && no < 24)
// Decrement by one
--*c.fg;
// Otherwise
else
{
// Calculate the remainder
int rem = (no / 24);
// Loops till remainder
for(int x = 0; x < rem; x++)
// Decrease by one
--*c.fg;
}// End of else
// return istream object
return is;
}// End of function
// Overload << operator
friend std::ostream & operator <<(std::ostream &os, Car &c)
{
// Checks if the current gallon is less than or equals to zero
if(c.fg->getGallons() <= 0)
{
// Display message and stop
std::cout<<"\n Drove "<<c.om->getCurrentMileage()<<" miles I'm out of gas.";
exit(0);
}// End of if condition
// Otherwise display total mileage traveled and fuel left
else
std::cout<<"\n Drove "<<c.om->getCurrentMileage()<<" miles now I have "<<c.fg->getGallons()<<" gallons left.";
return os;
}// End of function
};// End of class
#endif /* Car_hpp */
and lastly Main.cpp
#include<iostream>
#include<stdlib.h>
#include "FuelGauge.h"
#include "Odometer.h"
#include "Car.h"
using namespace std;
// main function definition
int main()
{
int customer = 1;
// Creates car object
Car cc;
// Loops till = 0 fuel available
do
{
// Accepts data and displays data using object
cout<<"\n How far away is customer #"<<customer<<"? ";
cin>>cc;
cout<<cc;
cout<<"\n How far does customer #"<<customer<<" need to go?";
cin>>cc;
cout<<cc;
}while(static_cast<void>(customer++),1);// End of do - while
}// End of main function
I believe that problem is in my FuelGauge.h but I'm not seeing it. If someone would be so kind to look it over and let me know if they see anything I would greatly appreciate it.
I am working in C with Netbeans8.0
I have to read files in an iterative approach to get list of words. That is, in single iteration a file is read into an array of strings and then merge this array into a single array.
void merge_array(char** a,int* M, char** b,int N)
{
//............. Add extra memory to a ..............*/
void *tmp = realloc(a, (*M+N) * sizeof(*a));
if (tmp == NULL)
{
perror("Merging -> Could not reallocate");
exit(EXIT_FAILURE);
}
a = tmp;
memset(a+(*M), 0, N*sizeof(*a));
//............. copy strings in b to a ..............*/
int i,j=0;
for(i=*M; i<((*M)+N); i++)
{
size_t wlen = strlen(b[j]);
a[i] = malloc((wlen+1) * sizeof(char));
if (a[i] == NULL)
{
perror("Failed to replicate string");
exit(EXIT_FAILURE);
}
memcpy(a[i], b[j], wlen+1);
j++;
}
(*M) = (*M)+N; // resetting the count
printf("Confirm - %s, %d\n",a[0],*M);
}
Above function reads the contents of a file. In main above function is called iteratively and merged into a single array named 'termlist'. Main code is given below
char** termlist;
int termCount=0;
while(files[i]){
char **word_array;
int wdCnt,a;
char* tmp = (char*) malloc(strlen(path)*sizeof(char));
strcpy(tmp,path); strcat(tmp,files[i]); strcpy(files[i],tmp);
printf("\n\n******* Reading file %s...\n",files[i]);
word_array = getTerms_fscanf(files[i],&a); //reading contents of file
wdCnt = a;
if(i==0) // before reading the first file initializing the termlist
{
termlist = (char**) malloc(wdCnt*sizeof(char*));
}
merge_array(termlist,&termCount,word_array,wdCnt);
printf("CHECK - %s, %d\n",termlist[0],termCount);
free(word_array);
++i;
}
Now the problem is that,
After 1st two iterations, Inside function everything works fine but in main values of termlist[0], termlist[1] turns out to be junk.. That is first 2 words read from first file is lost. The 3rd iteration returns with failure at merge_array function call.
Output is
******* Reading F:/Netbeans C/Test Docs/doc1.txt...
Confirm - tour, 52
CHECK - tour, 52
******* Reading F:/Netbeans C/Test Docs/doc2.txt...
Confirm - tour, 71
CHECK - Ôk'aÔk'a`œ€`œ€äk'aäk'aìk'aìk'aôk'aôk'aük'aük'ah“€, 71
I am not able to identify problem with this.. Please help with this..
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/sem.h>
#include<sys/ipc.h>
int sem_id;
void update_file(int number)
{
struct sembuf sem_op;
FILE* file;
printf("Inside Update Process\n");
/* wait on the semaphore, unless it's value is non-negative. */
sem_op.sem_num = 0;
sem_op.sem_op = -1; /* <-- Amount by which the value of the semaphore is to be decreased */
sem_op.sem_flg = 0;
semop(sem_id, &sem_op, 1);
/* we "locked" the semaphore, and are assured exclusive access to file. */
/* manipulate the file in some way. for example, write a number into it. */
file = fopen("file.txt", "a+");
if (file) {
fprintf(file, " \n%d\n", number);
fclose(file);
}
/* finally, signal the semaphore - increase its value by one. */
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
}
void write_file(char* contents)
{
printf("Inside Write Process\n");
struct sembuf sem_op;
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
FILE *file = fopen("file.txt","w");
if(file)
{
fprintf(file,contents);
fclose(file);
}
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop( sem_id, &sem_op, 1);
}
int main()
{
//key_t key = ftok("file.txt",'E');
sem_id = semget( IPC_PRIVATE, 1, 0600 | IPC_CREAT);
/*here 100 is any arbit number to be assigned as the key of the
semaphore,1 is the number of semaphores in the semaphore set, */
if(sem_id == -1)
{
perror("main : semget");
exit(1);
}
int rc = semctl( sem_id, 0, SETVAL, 1);
pid_t u = fork();
if(u == 0)
{
update_file(100);
exit(0);
}
else
{
wait();
}
pid_t w = fork();
if(w == 0)
{
write_file("Hello!!");
exit(0);
}
else
{
wait();
}
}
If I run the above code as a c code, the write_file() function is called after the update_file () function
Whereas if I run the same code as a c++ code, the order of execution is reverse... why is it so??
Just some suggestions, but it looks to me like it could be caused by a combination of things:
The wait() call is supposed to take a pointer argument (that can
be NULL). Compiler should have caught this, but you must be picking
up another definition somewhere that permits your syntax. You are
also missing an include for sys/wait.h. This might be why the
compiler isn't complaining as I'd expect it to.
Depending on your machine/OS configuration the fork'd process may
not get to run until after the parent yields. Assuming the "wait()"
you are calling isn't working the way we would be expecting, it is
possible for the parent to execute completely before the children
get to run.
Unfortunately, I wasn't able to duplicate the same temporal behavior. However, when I generated assembly files for each of the two cases (C & C++), I noticed that the C++ version is missing the "wait" system call, but the C version is as I would expect. To me, this suggests that somewhere in the C++ headers this special version without an argument is being #defined out of the code. This difference could be the reason behind the behavior you are seeing.
In a nutshell... add the #include, and change your wait calls to "wait(0)"
For a project, I'm trying to send UDP packets from Linux kernel-space. I'm currently 'hard-coding' my code into the kernel (which I appreciate isn't the best/neatest way) but I'm trying to get a simple test to work (sending "TEST"). It should be mentioned I'm a newbie to kernel hacking - I'm not that clued up on many principles and techniques!
Every time my code gets run the system hangs and I have to reboot - no mouse/keyboard response and the scroll and caps lock key lights flash together - I'm not sure what this means, but I'm assuming it's a kernel panic?
The repeat_send code is unnecessary for this test code, yet when it's working I want to send large messages that may require multiple 'send's - I'm not sure that if could be a cause of my issues?
N.B. This code is being inserted into neighbour.c of linux-source/net/core/ origin, hence the use of NEIGH_PRINTK1, it's just a macro wrapper round printk.
I'm really banging my head against a brick wall here, I can't spot anything obvious, can anyone point me in the right direction (or spot that blindingly obvious error!)?
Here's what I have so far:
void mymethod()
{
struct socket sock;
struct sockaddr_in addr_in;
int ret_val;
unsigned short port = htons(2048);
unsigned int host = in_aton("192.168.1.254");
unsigned int length = 5;
char *buf = "TEST\0";
struct msghdr msg;
struct iovec iov;
int len = 0, written = 0, left = length;
mm_segment_t oldmm;
NEIGH_PRINTK1("forwarding sk_buff at: %p.\n", skb);
if ((ret_val = sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock)) < 0) {
NEIGH_PRINTK1("Error during creation of socket; terminating. code: %d\n", ret_val);
return;
}
memset(&addr_in, 0, sizeof(struct sockaddr_in));
addr_in.sin_family=AF_INET;
addr_in.sin_port = port;
addr_in.sin_addr.s_addr = host;
if((ret_val = sock.ops->bind(&sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in))) < 0) {
NEIGH_PRINTK1("Error trying to bind socket. code: %d\n", ret_val);
goto close;
}
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_flags = 0;
msg.msg_name = &addr_in;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
repeat_send:
msg.msg_iov->iov_len = left;
msg.msg_iov->iov_base = (char *)buf + written;
oldmm = get_fs();
set_fs(KERNEL_DS);
len = sock_sendmsg(&sock, &msg, left);
set_fs(oldmm);
if (len == -ERESTARTSYS)
goto repeat_send;
if (len > 0) {
written += len;
left -= len;
if (left)
goto repeat_send;
}
close:
sock_release(&sock);
}
Any help would be hugely appreciated, thanks!
You may find it easier to use the netpoll API for UDP. Take a look at netconsole for an example of how it's used. The APIs you're using are more intended for userspace (you should never have to play with segment descriptors to send network data!)
Run your code when you're in a text mode console (i.e. press Ctrl+Alt+F1 to go to the text console). This way a kernel panic will print out the stack trace and any extra information about what went wrong.
If that doesn't help you, update your question with the stack trace.
I'm not much of a Linux Kernel developer, but can you throw some printk's in there and watch dmesg before it goes down? Or have you thought about hooking up with a kernel debugger?
I think you should try to put all variables outside mymethod() function and make them static. Remember, that the size of kernel stack is limited do 8KiB, so to much of/too big local variables may cause stack overflow and system hangup.