Sunday, January 31, 2016

Lab 1 - Code Review

The purpose of this lab is to explore code review processes used in open source projects. We had to select two open source project that have different licenses.

Amarok
The first project I looked at was called Amarok. This is a iTunes like music player for Linux, Unix and Windows. https://amarok.kde.org/. This project is licensed under the GNU General Public License.

There are a few ways you can contribute to this project:
  • Create artwork for the application
  • Write code in C++ using the Qt and KDELibs toolkits
  • Write scripts that expand the application
To start contributing they recommend you take a look at the bugs and see if you can help with any bugs. Their bugtrackingsystem can be found at: https://bugs.kde.org/buglist.cgi?quicksearch=amarok

All the code that you write must be submitted to their reviewboard which can be found at https://git.reviewboard.kde.org/groups/amarok/?show-closed=1&page=1.
On this reviewboard all the members can comment on your contribution. However there are only a few members with commit rights. So when members comment that the code looks good and would be a nice addition, they'll most likely comment that someone with commit access should push this to the master branch. An example I found: https://git.reviewboard.kde.org/r/120930/#review69630

A more recent example of an actual submission: https://git.reviewboard.kde.org/r/2/
Here you can see that normal members comment on it and say to ship it, and a member with commit access commits the code. 

Chromium
The second project I looked at was Chromium, an open-source browser behind google chrome: http://www.chromium.org/Home. This project is licesned under the Creative Commons Attribution 2.5 License.

There are three major paths you can take to contribute to Chromium:
  • You have a new idea
  • You want to change exicting code
  • You want to work on an existing bug
When you have a new idea you want to add to Chromium you first have to post your idea to a discussion group. In this group they'll discuss if your idea if worth adding to the application. I couldn't find an example of this, because their discussion group is also for many other problems. It can be found here: https://groups.google.com/a/chromium.org/forum/#!forum/chromium-discuss

If you want to change existing code, you have to contact the person who originally wrote the code and ask if your idea would be good to add. 

Not all bugs in their system are assigned, so if it's not assigned youre allowed to pick it up and assign it to yourself. If the bug you want is already assigned you can contact the person it's assigned to and ask if you could help or take over. It's also possible to file your own bug and work on it, but these bugs cannot be whole new ideas. These bugs have to be nontrivial, like simple cleanups and style fixes. The listed bugs can be found here: https://code.google.com/p/chromium/issues/list

To submit your code you have to add it to the code review site: https://codereview.chromium.org/ 
Your code will be reviewd within 24-48 hours, if the patch is not too big. All members can comment on your code and give you feedback. Only some members have commit access. An exmaple I found: https://codereview.chromium.org/1650283002/

Overall Chromuim takes communication very seriously, if you're working on something you need to keep communicating to relevant people otherwise you might have a hard time getting your code reviewed.


Lab 3 - Code Building

Time to write some assembly! We did this lab in groups so we could put our heads together to write some good assembly code.

First of all we had to download the examples to our directories on the servers and unpack them. This was done with the tar and make command.
Once we had the example files we could take a look at the differences between dumping the C file and the assembler file. When dumping the c source code you get a bunch of information about all the source code. When dumping the assembler code you only get the instructions.

Now it was time to make our own little program. We needed to make a simple looper that goes from 0-9 and prints out the number.
After making our own file with the simple Hello World looper we needed to compile the assembler code using the following commands:
       Run the assembler: as -g -o test.o test.s
       Run the linker: ls -o test test.o
You're going to use these command a lot so it's easier to write it in one command and re-use it.
       as -g -o test.o test.s; ls -o test test.o; ./test

If you do not have the right permissions, use the following command:
       chmod 700 filename

Now to edit some assembler code. 
To print a number in assembler you need to work with ASCII codes. In our case we needed to add 48 to the number because this is the character for 0. We added this offset to an empty register that would not get trampled at the start of the program. In the loop itself we added the offset to the number it's supposed to be (0-9) and set the result in the rsi register. This is the message location register. 
In theory this was supposed to work, but we made a little mistake in the .data section. We set it to be .rodata, this means it was read-only. After changing this to .data it did print all the numbers, but we also had a newline character in our string but that did not seem to work. Appearently the mov command moves the full 64 bytes, even if you only have 1 byte of data. This caused the number to overwrite the newline character. This was an easy fix by adding the b suffix to mov and the register you move it from. 

The next step was to loop from 00-30. 
To get this to work we divided the loop number by 10 and kept track of our remainders. To do this you use the div command, this takes the rax register and divides it by a chosen register. It stored the outcome into rax and the remainder into rdx. The rdx register has to be set to 0 before you use the div command. As before we added our offset of 48 to rax and rdx and moved these into the string.

The last step was to supress the first zero when the number is below 10.
We did this by checking if the quotient was zero. If it was, we used the je(jump if equal) command to jump to a label. This label would be after the mov command to move the first digit to the string, so the first digit would not get printed if the jump occurred.

Lab 4 - Compiled C

This lab was about compiling code with different arguments. We'll be discussing 6 changes. Each change was done in differents groups. My group did change 5, so this one is more extensive.

Starting code
We used the simple hello world code for this lab:
#include <stdio.h>

int main() {
    printf("Hello World!\n");
}

We compiled this code using the GCC compiler with the following arguments.
-g               # enable debugging information
-O0              # do not optimize (that's a capital letter and then the digit zero)
-fno-builtin     # do not use builtin function optimizations

In the objdump you could see that <main> calls to <printf> to print Hello World.

1. Add the compiler option -static. Note and explain the change in size, section headers, and the function call.
When you add the option -static, the compiler imports the entire library when it only needs one function. This causes the file size to be much larger. 

2. Remove the compiler option -fno-builtin. Note and explain the change in the function call.
<printf> replaced with <puts>

3. Remove the compiler option -g. Note and explain the change in size, section headers, and disassembly output.
When you enter the command objdump --source you normally get the written code together with the assembler code. This is handy when you want to see which assembler code belongs to which C code. When you remove the option -g you remove all the debug information. This also means when you enter the command objdump --source, you do not get the C code in the file because this is seen as debug information.

4. Add additional arguments to the printf() function in your program. Note which register each argument is placed in. 
In the AARCH64 architecture 7 arguents get saved in registers, the overflow gets pushed on the stack. 
In the INTEL architecture only 5 arguments get stored in registerd, and the overflow also gets pushed on the stack.

5. Move the printf() call to a separate function named output(), and call that function from main(). Explain the changes in the object code.
5.1
Our task was to move the printf() function to a seperate function output().
#include <stdio.h>

void output(){
  printf("Hello World!\n");
}

int main() {
  output();
}

We compiled this with the same arguments stated above. The objdump now shows:
<main> calls <output> and that calls <printf>
<output> is the same as <main> without our output() function.

5.2
We now compiled the following code to inspect differences when you add parameters.
#include <stdio.h>

void output(char a[]){
  printf(a);
}

int main() {
  output("Hello World!\n");
}

In the objdump you see that it loads the given parameter to the x0 register.
The output function in the <main> adds a pointer to the parameter to register x0 before calling <output>.
<printf> in the <output> then takes the x0 parameter and puts it in the x1 register to put it as argument 2 for printf.

File size increased slightly with each change.

6. Remove -O0 and add -O3 to the gcc options. Note and explain the difference in the compiled code.These options have to do with optimizations. The compiler gets 'smarter' and deletes lines of code it doesn't need. For example, in O0 it sets up the stack but it never uses the stack after that. These lines are deleted in the O3 option. Another example is that after the <printf> is done, it doesn't return to main. It goes back to whatever called <main>.

Thursday, January 14, 2016

Lab 2 - Code Building

GNUChess
https://www.gnu.org/software/chess/
As recommended, I went to the GNU website to find some projects to install on my fedora installation.There was a whole list of projects and I decided to go with a game. One game I chose was gnuchess.
Since this was my first time installing an open source project on a Linux device, I had to find some instructions on how to install the game. Luckily the package had a install guide in it which told me to run the commands ./configure, make, make install. The command ./configure did work but I got error's when I tried to execute the make commands. Then I just tried to run the gnuchess file and it asked if I wanted to install the packages, which I said yes to. When I ran the gnuchess file again, the game started in the terminal.


I could not yet install a non-GNU project. The projects I found were too big, and I could not install all the needed components. I will try again later.