I have the following module which I tried to print PCB information. However I couldn't figure out the output. It was supposed to print process related data. I appreciate any help.
modpcb.c
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/fs_struct.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
void retrieve(struct task_struct *task) {
struct task_struct *ts = current;
struct list_head *list;
if(task->state == 1)
printk(KERN_INFO "Process Name%s", ts->comm);
printk(KERN_INFO "Process Name%lu", ts->min_flt);
printk(KERN_INFO "Process Name%lu", ts->maj_flt);
printk(KERN_INFO "Process Name%li", ts->utime);
printk(KERN_INFO "Process Name%li", ts->stime);
printk(KERN_INFO "Process Name%d", ts->pid);
printk(KERN_INFO "Process Name%u", ts->flags);
printk(KERN_INFO "Process Name%u", ts->start_time);
printk(KERN_INFO "Process Name%ld", ts->state);
list_for_each(list, ¤t->children) {
ts = list_entry(list, struct task_struct, sibling);
retrieve(ts);
}
}
static int __init pcbinfo_init(void)
{
struct task_struct *node = current;
printk(KERN_INFO "Starting module...\n");
for(;node->pid != 1; node = node->parent)
retrieve(node);
return 0;
}
static void __exit pcbinfo_cleanup(void)
{
printk(KERN_INFO "Cleaning module...\n");
}
module_init(pcbinfo_init);
module_exit(pcbinfo_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("arioglu");
MODULE_DESCRIPTION("Prints PCB info");
Makefile
obj-m += modpcb.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
dmesg | tail
sudo insmod modpcb.ko
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
EDIT:Output. Error is gone by updating Makefile with insmod.
make -C /lib/modules/4.4.0-45-generic/build M=/home/emre-ubuntu/Desktop/21202135/finalB modules
make[1]: Entering directory '/usr/src/linux-headers-4.4.0-45-generic'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-45-generic'
dmesg | tail
[ 926.839624] cfg80211: (2457000 KHz - 2482000 KHz # 40000 KHz), (N/A, 2000 mBm), (N/A)
[ 926.839626] cfg80211: (2474000 KHz - 2494000 KHz # 20000 KHz), (N/A, 2000 mBm), (N/A)
[ 926.839628] cfg80211: (5170000 KHz - 5250000 KHz # 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (N/A)
[ 926.839631] cfg80211: (5250000 KHz - 5330000 KHz # 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (0 s)
[ 926.839633] cfg80211: (5490000 KHz - 5730000 KHz # 160000 KHz), (N/A, 2000 mBm), (0 s)
[ 926.839635] cfg80211: (5735000 KHz - 5835000 KHz # 80000 KHz), (N/A, 2000 mBm), (N/A)
[ 926.839637] cfg80211: (57240000 KHz - 63720000 KHz # 2160000 KHz), (N/A, 0 mBm), (N/A)
[ 926.840351] wlo1: associate with 04:18:d6:19:b7:61 (try 1/3)
[ 926.843708] wlo1: RX AssocResp from 04:18:d6:19:b7:61 (capab=0x421 status=0 aid=21)
[ 926.863483] wlo1: associated
sudo insmod modpcb.ko
My purpose is invoke a system call or libc functions from native code.
The native code is a executable memory block which I insert some machine code into it. In the native code I try to invoke puts() or printf() functions to output a string. Then I call the native code. This sequence model is the Mono tries to do. But when I porting the Mono into AIX, I met a segment fault when invokes system library functions such as printf() or abs(). I guess it must break calling stack somewhere. But I could not resolve such problem I am not familiar with IBM powerpc platform.
I have wrote a simple program to demonstrate the sequence, it also lead to segment fault at calling puts(). It takes so much time, please give me some advises, thank you in advance!
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/mman.h>
typedef uint8_t guint8;
typedef int16_t gint16;
typedef uint16_t guint16;
typedef int32_t gint32;
typedef uint32_t guint32;
typedef int64_t gint64;
typedef uint64_t guint64;
typedef float gfloat;
typedef double gdouble;
typedef int32_t gboolean;
typedef void * gpointer;
typedef enum {
ppc_r0 = 0,
ppc_r1,
ppc_sp = ppc_r1,
ppc_r2,
ppc_r3,
ppc_r4,
ppc_r5,
ppc_r6,
ppc_r7,
ppc_r8,
ppc_r9,
ppc_r10,
ppc_r11,
ppc_r12,
ppc_r13,
ppc_r14,
ppc_r15,
ppc_r16,
ppc_r17,
ppc_r18,
ppc_r19,
ppc_r20,
ppc_r21,
ppc_r22,
ppc_r23,
ppc_r24,
ppc_r25,
ppc_r26,
ppc_r27,
ppc_r28,
ppc_r29,
ppc_r30,
ppc_r31
} PPCIntRegister;
typedef enum {
ppc_lr = 256,
ppc_ctr = 256 + 32,
ppc_xer = 32
} PPCSpecialRegister;
#define G_STMT_START do
#define G_STMT_END while (0)
#define ppc_load32(c,D,v) G_STMT_START { \
ppc_lis ((c), (D), (guint32)(v) >> 16); \
ppc_ori ((c), (D), (D), (guint32)(v) & 0xffff); \
} G_STMT_END
#define ppc_emit32(c,x) do { *((guint32 *) (c)) = (guint32) (x); (c) = (gpointer)((guint8 *)(c) + sizeof ( guint32));} while (0)
#define ppc_stwux(c,S,A,B) ppc_emit32(c, (31 << 26) | (S << 21) | (A << 16) | (B << 11) | (183 << 1) | 0)
#define ppc_or(c,a,s,b) ppc_emit32 (c, (31 << 26) | ((s) << 21) | ((a) << 16) | ((b) << 11) | 888)
#define ppc_mr(c,a,s) ppc_or (c, a, s, s)
#define ppc_ori(c,S,A,ui) ppc_emit32 (c, (24 << 26) | ((S) << 21) | ((A) << 16) | (guint16)(ui))
#define ppc_addis(c,D,A,i) ppc_emit32 (c, (15 << 26) | ((D) << 21) | ((A) << 16) | (guint16)(i))
#define ppc_lis(c,D,v) ppc_addis (c, D, 0, (guint16)(v))
#define ppc_load_sequence(c,D,v) ppc_load32 ((c), (D), (guint32)(v))
#define ppc_load_func(c,D,V) ppc_load_sequence ((c), (D), (V))
#define ppc_mtspr(c,spr,S) ppc_emit32 (c, (31 << 26) | ((S) << 21) | ((spr) << 11) | (467 << 1))
#define ppc_mtlr(c,S) ppc_mtspr (c, ppc_lr, S)
#define ppc_blrl(c) ppc_emit32 (c, 0x4e800021)
#define ppc_mfspr(c,D,spr) ppc_emit32 (c, (31 << 26) | ((D) << 21) | ((spr) << 11) | (339 << 1))
#define ppc_mflr(c,D) ppc_mfspr (c, D, ppc_lr)
#define ppc_stw(c,S,d,A) ppc_emit32 (c, (36 << 26) | ((S) << 21) | ((A) << 16) | (guint16)(d))
#define ppc_stwu(c,s,d,A) ppc_emit32 (c, (37 << 26) | ((s) << 21) | ((A) << 16) | (guint16)(d))
#define ppc_addi(c,D,A,i) ppc_emit32 (c, (14 << 26) | ((D) << 21) | ((A) << 16) | (guint16)(i))
#define ppc_lwz(c,D,d,A) ppc_emit32 (c, (32 << 26) | ((D) << 21) | ((A) << 16) | (guint16)(d))
#define ppc_blr(c) ppc_emit32 (c, 0x4e800020)
#define ppc_bl(c,li) ppc_emit32 (c, (18 << 26) | ((li) << 2) | 1)
#define PPC_CALL_REG ppc_r12
void foo()
{
puts("Hello");
}
int main()
{
unsigned char codebuf [1024];
unsigned char* code;
void * mem;
unsigned char* codest;
void *values[1];
int rc;
foo();
code = codest = codebuf;
ppc_load_func(code, PPC_CALL_REG, *((void **)foo));
ppc_mtlr(code, PPC_CALL_REG);
ppc_blrl(code);
mem = mmap(NULL, code - codest, PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
memcpy(mem, codest, code - codest);
void (*func) () = &mem;
func();
return 0;
}
I must use gcc. the macros were copied from Mono. func() is good when not call system library functions.
It could step into func(), but when invokes puts, the register R2 value somehow was manipulated. I don't know why? following is debug step on my test box :
127 func();
=> 0x10000760 <main+304>: 80 1f 00 40 lwz r0,64(r31)
0x10000764 <main+308>: 7c 0b 03 78 mr r11,r0
0x10000768 <main+312>: 81 2b 00 00 lwz r9,0(r11)
0x1000076c <main+316>: 90 41 00 14 stw r2,20(r1)
0x10000770 <main+320>: 7c 0a 03 78 mr r10,r0
0x10000774 <main+324>: 81 6a 00 08 lwz r11,8(r10)
0x10000778 <main+328>: 7d 29 03 a6 mtctr r9
0x1000077c <main+332>: 7c 0a 03 78 mr r10,r0
0x10000780 <main+336>: 80 4a 00 04 lwz r2,4(r10)
0x10000784 <main+340>: 4e 80 04 21 bctrl
0x10000788 <main+344>: 80 41 00 14 lwz r2,20(r1)
above is the point of entering func().
below is the core dump snapshot:
(gdb)
0x10000550 90 puts("Hello");
0x1000054c <foo+20>: 80 62 00 58 lwz r3,88(r2)
=> 0x10000550 <foo+24>: 48 00 03 41 bl 0x10000890 <puts>
0x10000554 <foo+28>: 80 41 00 14 lwz r2,20(r1)
(gdb)
0x10000890 in puts ()
=> 0x10000890 <puts+0>: 81 82 00 5c lwz r12,92(r2)
(gdb)
0x10000894 in puts ()
=> 0x10000894 <puts+4>: 90 41 00 14 stw r2,20(r1)
(gdb) info reg r12
r12 0x0 0
(gdb) ni
0x10000898 in puts ()
=> 0x10000898 <puts+8>: 80 0c 00 00 lwz r0,0(r12)
(gdb)
0x1000089c in puts ()
=> 0x1000089c <puts+12>: 80 4c 00 04 lwz r2,4(r12)
(gdb)
0x100008a0 in puts ()
=> 0x100008a0 <puts+16>: 7c 09 03 a6 mtctr r0
(gdb) info reg r0
r0 0x0 0
(gdb) ni
0x100008a4 in puts ()
=> 0x100008a4 <puts+20>: 4e 80 04 20 bctr
(gdb)
Program received signal SIGILL, Illegal instruction.
0x00000000 in ?? ()
=> 0x00000000: 00 00 00 00 .long 0x0
in puts(), it jump to wrong address 0x0, at the begining of func(), compiler has modified R2(lwz r2,4(r10)), it leads to the problem, but it is compiler generated code, I can't change it. I don't know how to handle this issue. Please help me! Thank you.
You need to understand "glue code" and "glink code".
As a practical method, write just a simple program where main calls puts. Then look at the assembly produced as well as single step (i.e. stepi) through the code.
The "function pointer" puts() does not point to the executable when it is in another module. Instead it points to a toc entry that has three entries: the address of the function, the toc of the module, and another value that I can't recall. The glue code / glink code (IIRC) takes a pointer in r11 to this entry and it will then correctly call the destination function.
Upon return, the next instruction after the bl will be an instruction to restore the toc.
The compiler, ld, as well as the loader all participate in the magic to make this happen.
Happy hunting...
I am using zeromq api for my application and having below indicated link problems. I have installed both zeromq and czmq tar ball to my ubuntu 12.10 system and verified that the necessary header files (e.g. zmq.h)are present under /usr/local/include. Could you please tell me why I am getting these link problems? What would be possible solution. I also installed zmq c++ bindings (zmq.hpp).
/XXXX.cpp:92: undefined reference to `zmq_poll'
CMakeFiles/dummy.dir/__/xxx_api/TheQueue.cpp.o: In function`zmq::error_t::error_t()':
/usr/local/include/zmq.hpp:76: undefined reference to `zmq_errno'
CMakeFiles/dummy.dir/__/xxx_api/TheQueue.cpp.o: In function `zmq::error_t::what() const':
/usr/local/include/zmq.hpp:80: undefined reference to `zmq_strerror'
CMakeFiles/dummy.dir/__/xxx/TheQueue.cpp.o: In function`zmq::context_t::context_t(int)':
/usr/local/include/zmq.hpp:241: undefined reference to `zmq_init'
CMakeFiles/dummy.dir/__/control_api/TheQueue.cpp.o: In function `zmq::context_t::close()':
/usr/local/include/zmq.hpp:267: undefined reference to `zmq_term'
CMakeFiles/dummy.dir/__/xxx_api/TheQueue.cpp.o: In function `zmq::socket_t::socket_t(zmq::context_t&, int)':
collect2: error: ld returned 1 exit status
make[2]: *** [/xxx/build_output/dummy] Error 1
make[1]: *** [/xxx/CMakeFiles/dummy.dir/all] Error 2
The following example works for me:
Here I have my file, containing the following:
#include "cppzmq/zmq.hpp"
#include <string>
#include <iostream>
int main ()
{
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REQ);
std::cout << "Connecting to hello world server…" << std::endl;
socket.connect ("tcp://localhost:5555");
// Do 10 requests, waiting each time for a response
for (int request_nbr = 0; request_nbr != 10; request_nbr++) {
zmq::message_t request (6);
memcpy ((void *) request.data (), "Hello", 5);
std::cout << "Sending Hello " << request_nbr << "…" << std::endl;
socket.send (request);
// Get the reply.
zmq::message_t reply;
socket.recv (&reply);
std::cout << "Received World " << request_nbr << std::endl;
}
return 0;
}
Then here I have the following command, which compiles it:
g++ test.cpp -o test -lzmq
To make zmq work on my linux machine, I simply downloaded zeromq as a tarball (for unix/linux) from their site. I then ran
make && make install
I want to create a shared, in-memory database with SQLite by passing it URI like file:memdb1?mode=memory&cache=shared.
The following code looks simple enough to get the job done:
#include <iostream>
#include <sqlite3.h>
void main()
{
sqlite3 * db;
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI;
int returnCode = sqlite3_open_v2("file:memdb1?mode=memory&cache=shared", &db, flags, NULL);
if (returnCode == SQLITE_OK)
std::cout << "Success!" << std::endl;
else
std::cout << "Error: " << sqlite3_errmsg(db) << std::endl;
if (db) sqlite3_close(db);
}
Then I compile it like this:
$ g++ sample.cpp -lsqlite3
And this is what I get:
$ ./a.out
Error: no such access mode: memory
I have tried many different configurations for flags (some including SQLITE_OPEN_MEMORY) and I have not been able to get this simple program to run. I've tried it on both Windows (with a custom build of SQLite 3.7.15) and on Ubuntu (using the default apt-get package, version 3.7.9) with no success.
Has anyone encountered this and discovered a solution?
It turns out I was using the wrong version of SQLite. Shared caches are not supported in SQLite until version 3.7.13 (see changelog).