Wednesday 24 October 2012

Mount/link remote directory via ssh



ami@ami:~/Downloads/ram$ sudo sshfs jonna@172.16.99.67:/jonnasdd/android  /mnt/
The authenticity of host '172.16.99.67 (172.16.99.67)' can't be established.
ECDSA key fingerprint is a3:b3:4b:10:21:0b:76:19:62:b1:d6:f1:3f:a7:40:72.
Are you sure you want to continue connecting (yes/no)? yes
jonna@172.16.99.67's password:
ami@ami:~/Downloads/ram$

so the remote directory has been mounted.

Tuesday 11 September 2012

Embedding GDB breakpoints in C source code

Have you ever wanted to embed GDB breakpoints in C source code?
int main() {
    printf("Hello,\n");
    EMBED_BREAKPOINT;
    printf("world!\n");
    EMBED_BREAKPOINT;
    return 0;
}
One way is to directly insert your CPU's breakpoint instruction. On x86:
#define EMBED_BREAKPOINT  asm volatile ("int3;")
There are at least two problems with this approach:
  • They aren't real GDB breakpoints. You can't disable them, count how many times they've been hit, etc.
  • If you run the program outside GDB, the breakpoint instruction will crash your process.
Here is a small hack which solves both problems:
#define EMBED_BREAKPOINT \
    asm("0:"                              \
        ".pushsection embed-breakpoints;" \
        ".quad 0b;"                       \
        ".popsection;")
We place a local label into the instruction stream, and then save its address in the embed-breakpoints linker section.
Then we need to convert these addresses into GDB breakpoint commands. I wrote a tool that does this, as a wrapper for the gdb command. Here's how it works, on our initial example:
$ gcc -g -o example example.c$ ./gdb-with-breakpoints ./example
Reading symbols from example...done.
Breakpoint 1 at 0x4004f2: file example.c, line 8.
Breakpoint 2 at 0x4004fc: file example.c, line 10.
(gdb) run
Starting program: example 
Hello,

Breakpoint 1, main () at example.c:8
8           printf("world!\n");
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004004f2 in main at example.c:8
        breakpoint already hit 1 time
2       breakpoint     keep y   0x00000000004004fc in main at example.c:10
If we run the program normally, or in GDB without the wrapper, the EMBED_BREAKPOINT statements do nothing. The breakpoint addresses aren't even loaded into memory, because the embed-breakpoints section is not marked as allocatable.
You can find all of the code on GitHub under a BSD license. I've done only minimal testing, but I hope it will be a useful debugging tool for someone. Let me know if you find any bugs or improvements. You can comment here, or find my email address on GitHub.
I'm not sure about the decision to write the GDB wrapper in C using BFD. I also considered Haskell and elf, or Python and the new pyelftools. One can probably do something nicer using the GDB Python API, which was added a few years ago.
This code depends on a GNU toolchain: it uses GNU C extensions, GNU assembler syntax, and BFD. The GDB wrapper uses the Linux proc filesystem, so that it can pass to GDB a temporary file which has already been unlinked. You could port it to other UNIX systems by changing the tempfile handling. It should work on a variety of CPU architectures, but I've only tested it on 32- and 64-bit x86.

Sunday 9 September 2012

How to Create Dynamic Library in Linux

Step1: implement the library source. Let us assume there are two files namely one.c and two.c each implementing one function as follows
$ vim one.c
#include<stdio.h>
void fun1(){
printf("This is function 1\n");
}
 
$ vim two.c
#include<stdio.h>
void fun2(){
printf("This is function 2\n");
}
 
Step2: compile the sources to generate relocatables. Relocatable binary is created in two forms
position dependent : in this relocated code is bound to offset
position independent : in this relocated code is not bound to offset, because of which sharing of libraries among multiple applications becomes easy.
Preferably we compile them to get position independent relocatables because of some advantages (will cover latter on).
Note: ‘.so’ is the extension for dynamic libraries.

$ gcc -c -fpic one.c 
        ( to create a relocatable one.o )
$ gcc -c -fpic two.c 
       ( to create a relocatable two.o ) 
$ gcc -shared -o libmyown.so one.o two.o
        ( libmyown.so is the name of the dynamic library to be created )
         - shared flag used to create a shared library 
$ gcc -I ./ test.c -o testdynamic ./libmyown.so 
         - I option to let the compiler to check for "mylib.h" in current working directory
         
$ ./testdynamic
This is test to create own library
This is function 1
This is function 2

How to create a static library in linux


: Step 1: implement the library source. Let us assume there are two files namely one.c and two.c each implementing one function as follows
$ vim one.c
#include<stdio.h>
void fun1(){
printf("This is function 1\n");
}
~
$ vim two.c
#include<stdio.h>
void fun2(){
printf("This is function 2\n");
}
~


Step2: compile the sources (one.c, two.c) to generate relocatables
$ gcc -c one.c
$ gcc -c two.c
ls -l
total 16
-rw-r--r-- 1 ramchandra ramchandra 66 2011-01-23 14:59 one.c
-rw-r--r-- 1 ramchandra ramchandra 844 2011-01-23 15:01 one.o
-rw-r--r-- 1 ramchandra ramchandra 66 2011-01-23 14:58 two.c
-rw-r--r-- 1 ramchandra ramchandra 844 2011-01-23 15:01 two.o
$

Note: “.a “ is the extension for the static libraries.

Using the archive tool ar we create a static library.

$ ar rcs libmyown.a one.o two.o
- libmyown.a is the own static library to be created. According to the general naming conventions a library should start with “lib” .
- rcs are the options (replace, create, symbol) for more details refer to man pages as follows.
- one.o and two.o are the list of sources to be packed into archive.

The above created static library is position dependent.

$ man ar (this gives description about the usage of ar)
$ info ar (this gives information like an ebook)

To list what all files have gone into archive type use option‘t’ of ar.
$ ar -t libmyown.a
one.o
two.o

you can even view the list of file that are packed into libc.a standard library as follows. To see where libc.a located in your machine use whereis as follows, which gives the path for libc.a
$ whereis libc.a
libc: /usr/lib/libc.so /usr/lib/libc.a /usr/share/man/man7/libc.7.gz

$ ar -t /usr/lib/libc.a init-first.o |more
libc-start.o
sysdep.o
version.o
check_fds.o
libc-tls.o
elf-init.o
dso_handle.o
errno.o
 
Now we can ship our library to costumer, along with this we even need to ship the header file to give the function prototypes. Create a header file mylib.h as follows.

$ vim mylib.h
void fun1();
void fun2();

to make use of the library above created write a test application as follows.
$ vim test.c
#include<stdio.h>
#include<mylib.h>
main(){
printf("This is test to create own library\n");
fun1();/*call to function */
fun2();/*call to function */
}

Now compile the source file as follows.

$ gcc test.c -o test (gives an error)
test.c:2:18: error: mylib.h: No such file or directory

to figure out where the error occurred use the following option
$ gcc -v test.c -o test
v option with gcc, stands for verbose.
the error is because the header files included are searched at the following locations.
/usr/local/include
         /usr/lib/gcc/i486-linux-gnu/4.4.3/include
           /usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
           /usr/include
where in our header file exists in the current working directory, and is not in above of the paths, so we have to explicitly say this by using the option I.
$ gcc -I ./ test.c -o test (gives error)
/tmp/ccFPPIsN.o: In function `main':
test.c:(.text+0x16): undefined reference to `fun1'
test.c:(.text+0x1b): undefined reference to `fun2'
collect2: ld returned 1 exit status
$
Still we end up with the following errors.
$ gcc -I ./ test.c -o teststatic ./libmyown.a
$ ./test
This is test to create own library
This is function 1
This is function 2
$

Here important thing to note is what ever the executable (teststatic) we generated is not complete static, it is dynamically linked, this can be know by the tool file.
$ file teststatic
teststatic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$
Therefore to obtain a complete static executable use the -static flag with the above command and check out the type of file as above.
$ gcc -static -I ./ test.c -o test_complete_static ./libmyown.a
$ file test_complete_static
test_complete_static: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, not stripped
$
One more thing to discuss is, in the above output there is something like “not stripped”. Which means there is some extra information like metadata in the executable. That extra unnecessary information can be removed using the tool strip. After stripping the file check out the earlier and current file sizes.
$ ls -l test_complete_static
-rwxr-xr-x 1 ramchandra ramchandra 578100 2011-01-23 17:14 test_complete_static

$ strip test_complete_static
$ ls -l test_complete_static
-rwxr-xr-x 1 ramchandra ramchandra 515108 2011-01-23 17:15 test_complete_static

Friday 31 August 2012

example of char device driver

--------------------
 char_dev.c
--------------------

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h> // required for various structures related to files liked fops.
#include <asm/uaccess.h> // required for copy_from and copy_to user functions
#include <linux/semaphore.h>
#include <linux/cdev.h>
static int Major;
dev_t dev_no,dev;
struct device
{
char array[100];
struct semaphore sem;
}char_dev;

int open(struct inode *inode, struct file *filp)
 {
        printk(KERN_INFO "Inside open \n");
        if(down_interruptible(&char_dev.sem)) {
        printk(KERN_INFO " could not hold semaphore");
        return -1;
  }
 return 0;
}

int release(struct inode *inode, struct file *filp)
 {
        printk (KERN_INFO "Inside close \n");
        printk(KERN_INFO "Releasing semaphore");
        up(&char_dev.sem);
        return 0;
}

ssize_t read(struct file *filp, char *buff, size_t count, loff_t *offp)
{
       unsigned long ret;
       printk("Inside read \n");
       ret = copy_to_user(buff, char_dev.array, count);
       return ret;
}

ssize_t write(struct file *filp, const char *buff, size_t count, loff_t *offp)
{
       unsigned long ret;
       printk(KERN_INFO "Inside write \n");
       ret = copy_from_user(char_dev.array, buff, count);
       return count;
}

struct file_operations fops = {
 read:  read,
 write:  write,
 open:   open,
 release: release
};

struct cdev *kernel_cdev;

int char_dev_init (void)
{
      int ret;
      kernel_cdev = cdev_alloc();
      kernel_cdev->ops = &fops;
      kernel_cdev->owner = THIS_MODULE;
      printk (" Inside init module\n");
      ret = alloc_chrdev_region( &dev_no , 0, 1,"chr_arr_dev");
      if (ret < 0) {
      printk("Major number allocation is failed\n");
      return ret;
 }

Major = MAJOR(dev_no);
dev = MKDEV(Major,0);
sema_init(&char_dev.sem,1);
printk (" The major number for your device is %d\n", Major);
ret = cdev_add( kernel_cdev,dev,1);
if(ret < 0 )
{
     printk(KERN_INFO "Unable to allocate cdev");
     return ret;
}
     return 0;
}

void char_dev_cleanup(void)
{
     printk(KERN_INFO " Inside cleanup_module\n");
     cdev_del(kernel_cdev);
     unregister_chrdev_region(Major, 1);
}

MODULE_LICENSE("GPL");
module_init(char_dev_init);
module_exit(char_dev_cleanup);
-------------
Makefile :
-------------

ifneq ($(KERNELRELEASE),)
   obj-m := char_dev.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

----------------
creating a node:
----------------
mknod /dev/char_dev c 250 0



User Application :-
-------------------
main.c
------------------

#include <stdio.h>
#include <fcntl.h>

main ( )
 {
        int i,fd;
        char ch, write_buf[100], read_buf[100];
        fd = open("/dev/char_dev", O_RDWR);
        if (fd == -1)
        {
                printf("Error in opening file \n");
                exit(-1);
        }
        printf ("Press r to read from device or w to write the device ");
        scanf ("%c", &ch);

        switch (ch) {
                case 'w':
                       printf (" Enter the data to be written into device");
                        scanf (" %[^\n]", write_buf);
                        write(fd, write_buf, sizeof(write_buf));
                        break;
                case 'r':
                        read(fd, read_buf, sizeof(read_buf));
                        printf ("The data in the device is %s\n", read_buf);
                        break;
                default:
                        printf("Wrong choice \n");
                        break;
        }
        close(fd);
}
------------------------------
Compiling User Application :
------------------------------
$gcc -o main main.c

#./main
Press r to read from device or w to write the device : w
Enter the data to be written into device  : American Megatrends Inc.

#./main
Press r to read from device or w to write the device : r
The data in the device is : American Megatrends Inc.

Thursday 30 August 2012

Forgot Root Password


I think this must be a common problem to a lot of users, forgetting the root password of their system or in the case of New ubuntu like systems that do not have a root log in, if you forget the password for the only user in your system then you are stuck with no way of logging in. Well there is simple work around for situations like this.
Follow the following steps to reset your root password. [Please see below for ubuntu systems]

1. While your system boots go the GRUB menu by pressing "esc".
2. Highlight the OS you want to boot using the arrow keys.
3. Press "e"
4. You will see three options ( generally), move to the line that starts with "kernel".
5. press "e" again
6. You will see a line of text, move to the end of it.
7. Add "single" or "1" to the end of the line.
8. Hit Enter and press "b".

Your system should boot into a text mode, with a shell prompt.

typer  "passwd" and hit enter.
You will be prompted for a new password. enter the password , you will be asked for confirmation enter the password again.

enter the command "reboot" and hit enter.

The system should boot back to your normal log in screen, you can use the new password that you just set for the root log in.

In case of Ubuntu systems this method does not work very well so there is slightly different way of making it work.
in step 7: instead of adding "1"  add the text "/dev/sda=rw"  assuming sda is the partition on which you have your Linux installed.

Hope you are able to log into your system again :-)

User is not in the sudoers file. This incident will be reported

On using the sudo command if we see the error message:
 
"User is not in the sudoers file. This incident will be reported."

This means that the user as whom we have logged in and are trying to run the command "sudo" does not have the permission to do so.
Only the users listed in /etc/sudoers have the permission to use the command "sudo".
To give the sudo permission to a user we need to add the user to the file /etc/sudoers file.
Open the file /etc/sudoers as root.
 
$sudo vim /etc/sudoers

Add the line
 
username ALL = (ALL) ALL

under the User privilege specification section.
Save the file and exit, now the sudo command should work for the user which was added in the file.