Friday, September 01, 2006

favicon

My list of favourite applications on kubuntu:

Amarok - Rocks. Period.
Firefox - Need I say more.
apt-get - For installing updates and programs.
Katapult - Breathtaking. A stylish application-launcher.
keyTouch - For my Logitech keyboard's special keys.
VLC Player - Watching movies.
d4x - Download Manager.
k3b - CD/DVD Writer.
gimp - Minimal Image Editing.
kpdf/Adobe Reader - Pdf Viewer.
emacs - For everything else.

Monday, August 21, 2006

Elisp

The default yes-or-no-p function in Emacs is a total nightmare. However, one can alias it to y-or-n-p in order to enter y for "yes" and n for "no". But, it has its own quirk, which is not to clear the minibuffer after entering y or n. So, I wrote this tiny function to clear the minibuffer after the y/n response is typed. It's a useless & fun function to have.

(defun clear-y-or-n-p (prompt)

(interactive)
(prog1 (y-or-no-p prompt) (message nil)))

Another function, that actually does something is this:

(defun indent-buffer ()

"Indent the current buffer"
(interactive)
(indent-region (point-min) (point-max) nil))

This indents the entire buffer (or the rectangle) according to the current indentation. Very handy when editing files which have various levels of "2-spaces/4-spaces per tab" indentation(Ugh!).

Wednesday, August 09, 2006

19-19

His fingers were sweaty. Gripping the mouse as hard as real-world physics will allow him, he concentrated hard on the monitor in front of him ; eyes behind hard-rimmed glasses, searching frantically for that elusive rocket-launcher. Tension reaching a culminating point. One wrong move, one misfire, one sneeze even and it was all possibly over. The crosshair focussed intently in the centre of the screen. "The Temple Of Retribution." Retribution for what? he could'nt help but wonder. "All my life, I've been here. Walking through simulated walls, speaking with AI, completing quests. All from a dark corner in the room. Void. There are no dreams anymore. Just nightmares....of a fearsome creature from the depths of Hell." Convulsing in the darkness, looking at the scrolling lines of text in the chat rooms - One frag left. "I don't know the time anymore, or what day it is. The sweet smell of flowers, the cracking dawn of light, the melancholy of a sunset or the exhilaration of rain - Just memories now." He could see the rocket launcher ahead. The opponent was just rounding the corner of the central arena. "The fury of death. And the swiftness of rebirth. It's all just a respawn." The Tibetan Book Of The Dead. "The Red Rose. The last sight for the eyes." Mortality. "It's a scary thought. The thought of not thinking anymore." Silence. "I am". Time hit standstill. He stood rooted to the ground. Nothing mattered.Not the flipping rocket launcher hanging inches off the ground or the opponent lunging for it. Not the sight of a rocket hurtling at breakneck speed towards him, creating a tiny sonic boom behind it. Not the sneer of an invisible face. Microseconds later, the screen went black. The mouse was left dangling. The room was empty. A life was born. A new one. It was tabula rasa all over again.

Friday, July 28, 2006

A FoRtune Cookie

This brought a smile to my face.
"WoMan _does not_ replace `man', although it does use a number of the facilities implemented in the Emacs `man' library. WoMan and man can happily co-exist, which is very useful for comparison and debugging purposes. The only way in which WoMan affects `man' is that it adds a timer to indicate how long `man' has taken to format a man page."
(From the info page for WoMan - Emacs' manual page browser).

Tuesday, July 04, 2006

The Pill

It was raining outside.
I could see it through the curtains.
Thunderstorms bellowed in the distance.
We just sat looking at each other.
I could see he was reading my thoughts.
I was no longer uncomfortable.
I rested my arms against the velvet of the armchair.
I closed my eyes.
I could hear him speak for a long time.
A dark, monotonic voice.
I could feel it.
Something crawling up on my skin.
An experience that could be felt.
He stopped talking.
I opened my eyes.
He looked at me.
He outstretched his arms and opened up his palms.
There were two pills - one red and the other blue.
They were shining against the dim light in the room.
He said, "It does not end here. It begins. The blue pill returns you to the drab life you've been leading till now. The red pill shows you how deep the rabbit-hole really goes. It's your choice."
I looked at him.
I looked at the rain outside.
I chose the yellow pill.

Monday, July 03, 2006

"Long" Live The King

I was recently involved in a framework that had to provide consistent behavior over both 32 and 64 bit systems ; which was when I came across the wierd standards followed by some compilers, when it comes to data-type sizes, more specifically int, long and a pointer (abbreviated as ILP). Now, both gcc (Linux) and the VC++ compiler(Windows) use ILP32 when compiling for 32-bit systems. This means, that an int, a long and a pointer are all 32-bits in length. To support a 64-bit data type, the type long long has been added, in later compilers. But, on a 64-bit machine, things start to get a little hazy. There exists 3(yes, three!!!) standard conventions :
ILP64 (Int, Long and Pointer are 64-bits)
LP64 (An int is still 32-bits, but a long and pointer are 64-bits)
LLP64 (Both an int and a long are 32-bits, and only pointers are 64-bits).
Faced with these choices, one would think the ILP64 to be a fairly obvious choice. I mean, what's the use of a 64-bit number-crunching machine if one can't do native 64-bit arithmetic on it? But, Linux chose LP64, while Windows embraced the LLP64 standard.
One of the reasons against ILP64 from both these systems was that an int was(and still is) C's most popular data-type and extending it to 64-bits would likely waste more space (4 bytes extra), than it does now. Face it, the average programmer tends to use an int to return even a single bit such as 1 or 0. So, a programmer should be forced(by the compiler) to use 64-bits only when it's absolutely necessary. But, the other argument against ILP64 is an interesting one. Let's consider the types int and long on a 32-bit system. Both are 32-bits in length and are indistinguishable from each other. But why? Because, in the age of 16-bit systems, an int was 16-bits in length, but a long was 32-bits. As we moved onto 32-bit systems, an int became 32-bits, but a long remained the same. This is where we lost it. Should'nt long be 64-bits in length? I don't know why this was done(insufficent hardware support could've been the reason), but it was this mistake that made both int and long equal in size, which made programmers careless and start intermixing them. So, the best thing to fix it, is by making int remain at 32-bits, while extending the long to 64, and this was the approach Linux took. But, Windows faced with a bigger issue, that of "not breaking" existing code, which assumed an int and a long to be the same size. So, they went the way of LLP64, with an int and a long remaining at 32 bits, and the pointer extended to 64-bits. But, there's a subtle loophole here. The size of a long long variable in a 64-bit system, is not, as you would expect it to be, 128-bits, but it remains at 64. So, what happens when moving from a 64-bit to a 128-bit system? The same problems, that we struggled to avoid resurface. The legacy lives on.

Thursday, May 25, 2006

Motion Blur

The sheer diversity and ingenuity of today's programs never cease to amaze me. A new wave of programs that take advantage of the motion sensors in laptops have cropped up, and it just got really wierd and "interesting". MacBook Pros and Thinkpads have motion sensors built in to take care of impact-scenarios. "Nominally, it's there to protect the internal hard drive. The basic idea is if the accelerometer suddenly notices that the gravitational pull of earth is no longer present, the most likely explanation is that the laptop, sensor and all, is currently accelerating at 9.81 m/s² towards the earth. In that case, it will (wisely) try to turn the hard drive off in preparation for impact." So, now we have programs that let us switch between virtual desktops at a tap on the screen, squeal when the laptop is lifted of a table(to protect against thefts) and make light-saber noises as it's hurled across(ala Star Wars). Brace yourself, 'cause the next-gen of programs might just arrive like a fleet of warships hurtling through space. Oh, that reminds me, gotta grab my towel today. "Happy Towel Day" everyone!

Monday, May 15, 2006

Ruubeek's Cube

I broke my last Rubik's cube some months back. I'd just completed learning to solve it by that time, when the cube came apart in my hands. I tried putting it back together, but one of the center pieces was broken. The assembly of the cube is itself quite interesting. All the parts sit perfectly on top and beside each other, with a minimal scaffolding at the center ; and 'course there's more than one way to assemble it, meaning you can basically create a unsolvable cube (Now, there's a trick to play on someone). Anyway, I got my new cube a few days back, thanks to a friend from the US. It looks very rigid, just like the last one, and initially takes some time to loosen it ; but after that it's smooth sailing all the way, that is of course, if you know how to solve it. There are loads of tutorials on the web to get anyone started on this. But initially, the best way would be to just mess around with it a bit, try getting a particular piece to a particular place and such; get used to moving stuff in three dimensions as opposed to 2-D jigsaw puzzles.
The most basic approach to solve it uses layering. The 3x3 cube is split upto into 3 horizontal layers, and one goes about solving a layer at a time. The first two layers are pretty easy and basic intuitiveness is sufficient to complete them. The last layer is the most difficult of them all, partly because one has very little room to work with without disturbing the completed layers. If you're really good and patient at it, you might figure it out by yourself, or if you're like me, then search for the easiest algorithm, and solve it that-a-way. Either way, after some time, the modus operandi will gradually evolve right into the cuber's hands and a feeling of accomplishment is inevitable. This is a really good tutorial to get started with, and frankly I don't want to get past it. I'm just a casual end-user of the cube, not a geek trying to speed-cube my way into 16 seconds. Of course, if one is really good at it, then the 4x4 Rubik's Revenge is definitely the worthy adversary.

Tuesday, May 02, 2006

A Scanner Darkly

My last two novels, having similar dystopian themes, a political regime taking control of a war-waging humanity and the idea of a bleak future ( V For Vendetta and A Brave New World), I had pretty much decided to give myself a break from sci-fi. But, as so often happens with me, nothing ever goes according to plan. I fell, head over feet, for the trailer of A Scanner Darkly, the first film of its kind - purely cel-shaded, and gorgeous. The protagonist is voiced by Keanu Reeves, and there was something in it that just grasped me by the shoulders and shook me violently. I just had to read the book, by Philip K. Dick - a renowned sci-fi writer of his time. Truth be told, it was nothing like I imagined from a sci-fi author. The story weaves through the impact of drugs on our oh-so-impressionable minds, taking control of our brain and reducing us to pulp. I've begun to cherish this kind of writing, where there's not too much of emphasis placed on the technology ; but rather its effect on us and our moral values and principles. The shock with which we realize that every moment of our lives is hopelessly dependent on technology ; and our inability to accept that fact. I just hope the movie turns out to be as good as the book.

Thursday, April 20, 2006

So Sayeth, Wanda The Fish

Big Fish, directed by Tim Burton is one of the movies I kept missing regularly everytime it's shown on TV, along with Donnie Darko and Requiem for a Dream. I finally caught it yesterday on HBO, at a very odd hour of 1:00 AM. The movie was not something I expected, throwing me a bit off-guard ; and definitely not the sterotypical Burton. A fantasy of events woven in flashbacks to a skeptical son, it definitely has fantastic visuals. What is confusing is the fact whether the father is actually telling the truth or not ; because the stories he narrates are bizarre and impossible, in the world we live in ; but yet, there's some element of truth in it, as the son discovers that all characters from the story are not made-up manequins, but they actually exist ; albeit different from the way narrated. People gain immortality, through the stories told about them, sometimes by them, that live after they're long gone. A fine cast of Danny DeVito, Ewan McGregor, Jessica Lange and Albert Finney makes the film a memorable experience. Something that stays on your mind for quite sometime....

Friday, April 14, 2006

Visions Of Paradise

Oblivion seems to have quite created a rage in the gaming industry. An RPG that's raised quite a few eyebrows regarding its success and made gamers and critics alike, all over the world, cry in joy and heap accolades on it certainly doesn't happen quite so often in this world ; this geeky world of pumped up gaming rigs, artistic case mods, liquid cooling, high-end graphics cards, dual-core processors, ergonomic gaming keyboards and mice for the hunched-up gamer drooling over 21'' LCD screens, pumpin' metal into every friggin' marine, or blowing to smithereens every alien scum that dares to show its ugly face, or precariously managing a dwindling economy while warding off another enemy attack on the base, or getting lost in eerie caves and foggy tunnels trying to find a red fire-breathing dragon that's guarding an ancient treasure. If memory serves me right, the last such phenomenon is the now oh-so-popular World Of Warcraft. It might very well be the product that single-handedly boosted this industry the last year, and is still going strong. In fact, after recent reports of addicted gamers,virtual threats and ransoms, and viruses unleashed onto the virtual world killing virtual characters, it's gotten a bit frightening, to say the least. But these are the artificial worlds, entire universes created by games that we tend to lose ourselves in, staying up late trying to ward off that evil spell casted by a level 30 mage. Oblivion does this and more, it seems. I had'nt heard of this game, quite surprisingly (probably because I was not frequenting Gamespot or Gamespy or Kotaku or Pixel Kill or countless other sites out there), until a friend asked me if I'd read the review. I said no, but made a mental note to read it later. Needless to say, I was swept, swept hard by the current, swaying left and right before steadying myself and realising it's never, not even in my wildest dreams gonna run on my system. Still running a paltry processor with a single core and a borrowed withered-by-age graphics card, I solemnly retired to my usual gawking-over-every-new-game-while-
cursing-my-inability-and-staunch-stubborness-to-upgrade routine. I mentally ticked this one off too. Oblivion. Like the lone survivor of a ship-wreck who's lost the complete meaning of time and ticks off every day against the wall with a sharpened twig, I etched the name deep into my heart. One more game to play. My list is all the while getting longer, with each passing month, starting off from Painkiller:Battle out of Hell to Doom III, F.E.A.R, Quake IV, Call Of Duty 2, GTA:San Andreas, Serious Sam 2, LOTR: Battle for Middle Earth 2, Black And White 2, ad infinitum. What's one more to the list, eh? *Sigh*. Getting restless - but just a tad bit at having missed out on all the fun of my first love with computers. And with the release of Apple's Intel-based Mac systems and the beta Boot-Camp that dual-boots with Windows, I have all the more reason to vigorously scratch my head and ponder ; weighing in the positives and negatives of either upgrading my system now(which has complications I don't want to delve in right now), or wait for a sufficiently stable Intel Dual-Core Mac with a reliable Boot-Camp at an affordable price (yeah right!), or just give up on all this and settle for one of my two latest crushes, a DSLR or an electric guitar. Oh, the travails of free will :)

Friday, April 07, 2006

The Musical Harp

Pandora is a music lover's paradise. An eternity of fresh and eclectic music from authors all around the world, with a penchant for discovery and excitement like I've never experienced before. And I mean this from the humming C Major of my musical veins. Powered by the Music Genome Project and flashing a simple flash-based interface, it grips you right from the moment you step through the humming doors. The concept is ridiculously intuitive, even for a childish Steve Vai ("The Audience is listening"). I'm a long-time self proclaimed addict of Pandora. It made me discover some amazing artists. At the time I started using this service, I was more into a new-age, trance kind of music. I was listening to a lot of Enya, Chicane, Vangelis and Dido then. So, having set up my station to imitate music of this vague genre, I discovered some fabulous artists in Imogen Heap(Frou Frou), Bent, Pentatonik and Adrian Belew. After that, I had some recordings played to the tunes of 80's pop and Country. A few artists like The Decemberists, David Gray and Ph 7 captured my attention. Music, as an art form, uplifts the soul, brings on a sense of detachment from an inconsequentiality and propels the innate desire to be self-satisfied. A feeling of completeness, a full circle - Is that not what Life is all about? The Creation always outlives the creator. The creator is nothing more than an entity, a body form constrained by the physics of the universe. But not the creation. It is limitless. Not bounded by any laws or rules. It touches the heart, in a way nothing else can. That's all that matters in the end, I guess. A feeling of holding hands with Nature. An embrace with the skies. A tryst with the sea.
Every breath we take,
Every move we make,
Every bond we break,
Every step we take.........

If you haven't checked out Pandora, please do. Did I mention it's free?

Thursday, March 30, 2006

Detached

Love, and the Lack of it,
Mind, and the Madness of it,
Truth, and the Tenderness of it,
Pain, and the Purpose of it,
Darkness, and the Depth of it,
Tears, and the Truth of it,
Past, and the Pain of it,
Eyes, and the Emptiness in it,
Time, and the Trap of it,
Idle, and the Intimacy with it,
Fire, and just a Flicker of it,
Gale, and only the Gust of it,
Veil, and the Visions from it,
Death, and the Design of it,
Paradise, and just a Picture of it,
Child, and the Cruelty of it,
Eden, and the Entrapment of it,
God, are you the Garden I am in,
Or I the Dream in You?

Wednesday, March 08, 2006

Summer of '06

Winter’s now practically disappeared and it’s summer-time again. I can feel the sweat on my brow, feel it crawling down my neck, I can sense the stickiness of my clothes and that familiar body odor that no deo can mask away. Oh, how I miss Winter, the cold that makes me feel warm inside, grey clouds hovering in the distance, a steaming cup of masala chai, a hint of rain when I take my bike out in the morning, the afternoon sun casting a gentle smile on me before hiding behind the clouds again, the evening rain, watching the rain sipping tea from the balcony and lost in thought, getting drenched from head to toe in the night rain, getting scolded from my mom every single time and just laughing back.
The only obvious advantages of this hot and humid climate is that I can now stop applying Vaseline on my dry skin, travel to coastal areas and frolic on the beaches and have all the ice-cream I crave for. My midnight snack’s now officially chocolate/vanilla ice-cream topped with banana and grapes.
Yum.

Friday, February 17, 2006

Demystifying virtual functions

Yesterday, I got caught up with a problem where a virtual function in a derived class was never getting called. Foolishly, I decided to see how gcc implemented virtual functions and what I was doing wrong, instead of debugging the code from a different angle (vis-a-vis gdb). Anyway, it turned out, the virtual function was indeed getting called, and the problem was in another part of the code. But, the silver lining of all this heinous activity was that I kinda got an idea of how virtual functions are actually implemented by the compiler. Let's start with some basic code.

class BASE_CLASS
{
public:
virtual void PRINT_FUNCTION(void);
};

class DERIVED_CLASS : public BASE_CLASS
{
public:
void PRINT_FUNCTION(void);
};

void BASE_CLASS::PRINT_FUNCTION(void)
{
printf("Base Function\n");
}

void DERIVED_CLASS::PRINT_FUNCTION(void)
{
printf("Derived Function\n");
}

int main()
{
DERIVED_CLASS *dobject=new DERIVED_CLASS;
dobject->PRINT_FUNCTION();
return 0;
}

This has to be self-explanatory. Obviously, the print from the above code, if run, would be "Derived Function". The basic concepts of how virtual functions are implemented using vtables & vptr are explained beautifully here. To surmise, each object has a vptr that points to the correct vtable of the class, where the vtable is a list of pointers to virtual functions defined in that class.

Now, let's put this code under the magnifying glass.

g++ -fdump-tree-gimple -fdump-class-hierarchy -S virtual.cpp

Compiling it with -fdump-tree-gimple gives us the GIMPLE output, which I recently found out from here.
-fdump-class-hierarchy "dumps a representation of each class' hierarchy and virtual function table layout to a file." (quoting the man page of gcc).
-S gives us the assembler output.

Before analyzing the dumps, let me just explain whatever little name-mangling I had to learn for this experiment. The G++ ABI mangles all names with a preceding _Z. After this, certain patterns occur, followed by the mangled name :

TV - Vtables. Pointed to by polymorphic objects and those with virtual bases.
TI - Type information. Returned by the typeid operator, pointed to by the vtable.
TS - Type string. Returned by type_info::name, and used for type comparisons.
In most of the cases, the mangled name consists of two things - a number specifying the length of the string following and the string itself (usually the name of a class or a function).

Okay, let's look at the class hierarchy dump first:

Vtable for BASE_CLASS
BASE_CLASS::_ZTV10BASE_CLASS: 3u entries
0 (int (*)(...))0
4 (int (*)(...))(& _ZTI10BASE_CLASS)
8 BASE_CLASS::PRINT_FUNCTION

Class BASE_CLASS
size=4 align=4
base size=4 base align=4
BASE_CLASS (0xb7d1bbc0) 0 nearly-empty
vptr=((& BASE_CLASS::_ZTV10BASE_CLASS) + 8u)

Vtable for DERIVED_CLASS
DERIVED_CLASS::_ZTV13DERIVED_CLASS: 3u entries
0 (int (*)(...))0
4 (int (*)(...))(& _ZTI13DERIVED_CLASS)
8 DERIVED_CLASS::PRINT_FUNCTION
Class DERIVED_CLASS
size=4 align=4
base size=4 base align=4
DERIVED_CLASS (0xb7d1bc80) 0 nearly-empty
vptr=((& DERIVED_CLASS::_ZTV13DERIVED_CLASS) + 8u)
BASE_CLASS (0xb7d1bcc0) 0 nearly-empty
primary-for DERIVED_CLASS (0xb7d1bc80)
The first thing we see is that the vtable (if it exists) always consists of two entries, by default. The first one is a NULL pointer and the second one is a pointer to the type-info of the class ( Maybe this is used for RTTI? ). Right, from then on, we have one pointer each for each virtual function in the class. The vptr for the base class is defined to be the value &(Base Class's virtual table) + 8. The 8 bytes skip the first two entries (on a 32-bit machine). Similarly, the vptr for the derived class is &(Derived Class's virtual table) + 8. Now, where is the vptr for each object stored? In the case of gcc, it is always the first word in the object's memory. Well, that's pretty much the vtable structure. So, calling a virtual function is now simply finding the vptr for the object ( in the first word ) & getting the address of the corresponding vtable. Index into the table using the appropriate index (calculated during compile-time), and you get the actual function to be called.

Let's move on to the GIMPLE output (unnecessary output skipped):


;; Function BASE_CLASS::BASE_CLASS() (_ZN10BASE_CLASSC2Ev)

BASE_CLASS::BASE_CLASS() (this)
{
int (*__vtbl_ptr_type) (void) * D.2250;

try
{
{
D.2250 = &_ZTV10BASE_CLASS + 8;
this->_vptr.BASE_CLASS = D.2250;
}
}
catch
{
<<>>
{
__cxa_call_unexpected (<<>>);
}
}
}

;; Function DERIVED_CLASS::DERIVED_CLASS() (_ZN13DERIVED_CLASSC1Ev)

DERIVED_CLASS::DERIVED_CLASS() (this)
{
struct BASE_CLASS * D.2259;
int (*__vtbl_ptr_type) (void) * D.2260;

try
{
{
D.2259 = &this->D.2202;
__base_ctor (D.2259);
D.2260 = &_ZTV13DERIVED_CLASS + 8;
this->D.2202._vptr.BASE_CLASS = D.2260;
}
}
catch
{
<<>>
{
__cxa_call_unexpected (<<>>);
}
}
}

;; Function int main() (main)

int main() ()
{
struct DERIVED_CLASS * D.2215;
void * D.2261;
int (*__vtbl_ptr_type) (void) * D.2262;
int (*__vtbl_ptr_type) (void) D.2263;
int D.2264;

{
{
struct DERIVED_CLASS * dobject;

D.2261 = operator new (4);
D.2215 = (struct DERIVED_CLASS *) D.2261;
try
{
__comp_ctor (D.2215);
}
catch
{
operator delete (D.2215);
}
dobject = D.2215;
D.2262 = dobject->D.2202._vptr.BASE_CLASS;
D.2263 = *D.2262;
OBJ_TYPE_REF(D.2263;dobject->0) (dobject);
....

We first see that the constructor for the base class and the derived class are implicitly called with the "this" pointer. This pointer points to the object in memory. Let's look at the base constructor. All we're doing here is getting the vtable for this class and making the vptr point to it. The vptr is depicted here as "this->_vptr.BASE_CLASS". Next comes the derived class's constructor. Since the derived class also has access to the base class's members/functions, it does contain a "pointer" to the base class within itself. In our case, this is the pointer &this->D.2202, which we pass on to the base' constructor. I haven't been able to figure out how the pointer is being obtained. Anyway, after the call to the base constructor, the vptr is now made to point correctly to the derived class's vtable as:
this->D.2202._vptr.BASE_CLASS = D.2260;
Remember, the base and derived classes both share the same vptr, hence it gets overwritten after the call to the base constructor has finished.
Now, let's look at how the virtual function is called from main() :
We first get the vptr of the object as :
vptr->D.2202._vptr.BASE_CLASS and then dereference it directly to get the function. Since the function is at the 0th index, we don't need any indexing here. We then call this deferenced function, which is pointing to the derived PRINT_FUNCTION and voila! There's your rabbit out of the hat!

On a more personal note, I just had an amazing last 3 weeks. Went to Goa (my second visit), the Jethro Tull concert, Bryan Adams concert, started on a couple of B&N free courses and still trying to keep my head above all this. It's now 3:35 AM and I've to leave for Mangalore in half an hour ( I've decided getting even a wink of sleep won't work for me now ). Maybe, I can nap along the way....

Monday, January 23, 2006

A couple of movies I recently saw....

Rounders is a movie about Poker. It starts off with Mike(Matt Damon) losing miserably in a game against a Frenchman "KGB"(John Malkovich) and thereafter vowing never to play again. But the guy's a genius. He comments he can even defeat a group of judges at Poker blindfolded, after having figured out the exact hands each one was playing. His friend Lester(Edward Norton) , having just gotten out of jail, is shocked to find his old friend has quit. But soon, the two friends start playing together, after Lester insinuatingly persuades Mike to start up again. But, Mike soon finds out Lester is ripping him off and ends up owing $15,000 to KGB. Meanwhile, his girlfriend's left him when she finds out he's started gambling again. This is not an underdog story. You don't feel ecstatic at the end of the movie ; you feel comforted and satisfied, after having seen Mike suffer for something that's not even his fault and finally overcoming it, by playing an unbelievable last game against KGB. You cannot get away from what you are, no matter how hard you try - that seems to be the moral of this movie. And it's stylish ; Matt Damon excels in his scattered monologue and can really deliver that I-don't-give-a-damn-I'm-a-genius character, that he played in Good Will Hunting. The movie had some appealing visuals too and overall, was entertaining. Definitely worth watching.


eXistenZ is a movie about virtual reality(VR) - Reality being simulated in a game. Allegra (Jennifer Jason Leigh) is a game designer, who's spent the last 5 years developing a 38 million-dollar game. The interface to all such VR games is a bio-port - A hole at the back of the spine into which a cord is attached. The other end of the cord goes to a game-controller ; which is actually an organism, with its own neural system, built from parts of various animals and engineered to simulate reality. Everything goes haywire from the very beginning. An assassination attempt on Allegra leads her and Ted(Jude Law), a PR guy for the company promoting the game, to go into hiding. They soon plug into the game Allegra developed - "eXistenZ", and start playing. Some interesting observations are then realised. The game has a start-point, where a character tells you what you should do next. From there, you're on your own. Your character has it's own motions and instincts, which are displayed as the game progresses. An ingame character goes into a loop, if not confronted with the right dialogue. A loop is similar to a program loop, where the character blindly moves his eyes up and down and stares, dumbfounded at the floor or the ceiling. Soon, Ted cannot distinguish from the game-world and the real-world. They all seem the same ; the same texture and ambience rots through everything he sees. Even after pausing the game and returning to the real world, he still feels it's a game. How do you know where you are, if you can't tell the difference between what's real and what's not? Simple, you cannot. Having looked closely, I realized that eXistenZ can itself simulate another game environment and set up VR games from within itself. Forget VR controllers simulating reality ; this is VR simulating VR. And you can go as deep as you can, you can have a VR game running from within a VR, which is under another VR environment. The movie depicts exactly this, and saying anything more would give away the ending. I would definitely recommend this movie to anyone, even though the visuals are forgettable at best and the acting just so-so.

Monday, January 16, 2006

Ooga Mooga Ga

GNU's list of funny "C" declarations are hilarious indeed. Some of these are ingenious, actually. Personally, I think code, especially the ones that are a little difficult to understand or even otherwise, should be written in such a way that, people who happen to come across it should find it curious or amusing or even plain funny; 'cause if they do, then they might atleast take the effort to learn and understand it. Of course, writing obfuscated code is taking it a bit too far. I mean, seriously, any programmer worth his hat, should atleast take a glance or even a sideways teensy-weensy peek at any piece of code that appears interesting; even if it is not in his or her area of expertise, it would'nt harm to take a look at it. It's happened to me tons of times. One line, one lousy, stinking, good-for-nothing line that has a wierd statement, or a function declaration, or the name of a variable, that's all it takes to grab my attention. That's partly why reading the Linux source code is quite enjoyable at times. And that's also exactly why you should code a bit differently, or humorously, if possible, 'cause if you think you've written something interesting, then you better grab all the attention you can get to it. After all, there's a gazillion lines of code out there, and not as many programmers. So, put on you thinking cap and start writing code, "code that boldly goes where no code has gone before." May the source be with you.

As a sidenote, this is something I came up with as I was writing this post:
struct on_you; /* You know....the movie???? "Stuck On You"?? Ring a bell????...Oh, come on.... */
void aleehooo; /* would have made a yodeller proud */
float er_ahoy;
[courtesy digg]

Three To Tango


The 3 movies I saw over the weekend.

Thursday, January 12, 2006

Identity

What would happen if someday, someplace, you met yourself?
A question that is hypothetical at best and better left that way; at least till we find a way to hitchhike in the fourth dimension. But, what would happen if, one day, we somehow came face-to-face with our own self? Now, I don’t mean the physical self, but I’m rather more interested in the mind, or the spirit, or the karma….you get the drift. So, how will you feel if you met someone who thinks and behaves exactly like you do? I mean, this person, except for his or her appearance, likes everything you like, hates all the things you hate, dresses up exactly like you and basically has all the niceties and oddities that you might possess. What’ll be your first impression of this person? Will you be elated at having discovered something; something that feels so personal, like finding a toy you’ve hidden in your childhood?
Well, for me at least, I know it’ll be quite an astronomical shock. As far as I can remember, I’ve never met anyone who share all their passions with mine, who get irritated at all the miniscule and irrelevant things I get irritated at, who laugh at all the things I find funny and also hate the things I positively despise. Suppose I met myself, say at a coffee shop and we start talking. Now, I obviously don’t know the other guy is actually me and neither does he. So, we chat for a while and suddenly discover that we have almost everything in common, overlooking all the facts of life, like parents, schooling and stuff. We both love the same kind of music (mostly new-age, rock and alternative), the same authors (Crichton, Rand, Christie, Austen, Woolf, Tolkein….), the same sit-coms and also the same genre of movies (Surreal, Horror….). We also love technology and have lately taken up an interest in classical music and fine art ( we also quickly realize that neither of us understands what exactly art and music is, but want to find out exactly how it’s worth millions of dollars). Having extinguished this initial high-intensity flame to a cinder, I finally settle down and briefly sip my tea. Now, I always feel like an outcast when I’m in a coffee shop, ‘cause I don’t like coffee at all. I’m a tea guy and always will be. So, having ordered whatever basic tea that this joint had to offer, I immediately realized that the guy in front of me had also ordered tea. “Tea in a coffee shop. I feel like an idiot, but I can’t help it. I hate coffee” – he tells me. “Amazing. I was thinking the same thing” – I say. Wow, this person likes everything I like. Fun!!!! So, for the next few days, I meet up with this guy a lot and discuss everything I’m working on right now, talking about all the crazy stuff that I'm trying to implement. I also discover this guy loves Linux and has a keen interest in the same areas that I just enjoy working on. So, I come up with some good solutions and insights to most of these problems. But, very soon, I discovered that I never felt completely satisfied with the way I’ve solved it. There’s no sense of anticipation or discovery anymore. No sense of excitement or the realization of having done something wrong, or overlooked a minor detail. Everything felt so dull and dreary. It took me a while to realize why. I figured out, I cannot learn anything new from this guy ; I know nothing that I’ve not known before I met him that day. Moreover, hearing the same thoughts, like an echo, both from within my head and from his mouth, was beginning to get boring. It sounded both monotonous and repetitive. The next time we met, he told me that he was feeling the exact same thing. Whatever he was thinking came out of my mouth and he felt it best that we both go our separate ways. I agreed. We shook hands. We left. Opposite Ways. As I was walking home, it started drizzling. I stopped and looked up at the sky. Water ran down my hair and face. Strangely, I felt warm and fuzzy inside. I immediately knew he was feeling the same thing. We wished each other and resolved to meet up in the future.

Thursday, December 08, 2005

Look Ma, I'm Lazy!!!!

Lazy binding on Linux implies that dynamic symbols are not resolved by either the link-editor during link-time or the dynamic linker at run-time, until the first time the symbols are actually referenced. Referencing in the case of variables means accessing them & in the case of functions, it means calling them. Let's prove Linux actually does what it claims by means of a small program.
I'm considering only the ELF format for analysis here. First off, all symbols (static or dynamic) have a symbol-table entry specifying its name ( actually an index into the string table) & an offset (or virtual address). Functions are also symbols, hence they too reside in this symbol table. Furthermore, all programs that are dynamically linked with a shared library also have stub-code within the executable for all functions that are called in the shared-library. This is used at runtime to find its actual address. The stub-code resides in a segment of the memory called PLT ( Procedure Linkage Table ). This is usually ro (read-only) memory. The executable in memory also has a GOT ( Global Offset Table ) that contains the actual address of the symbol at run-time. Whenever a symbol's address has to be resolved at runtime, the dynamic linker queries for the symbol in each of the dependent shared-libraries, finds out the base-address of the library where this symbol is present and populates the symbol's actual run-time address into the GOT. Now, the first instruction of the stub-code in the PLT is always of the form:
jmp *(got-address).
Here, got-address specifies the location in the GOT, where the address of the function resides. Initially, however, got-address points to the next instruction in the PLT itself, which pushes certain identifiers for the dynamic linker and jumps to the linker code itself. Now, the dynamic linker locates the load-address of the function and modifies the GOT entry to contain the actual address. So, the next time a function call is made, the overhead of skipping to the dynamic linker is omitted and the function is called directly.
The program that demonstrates all this is shown below (assuming there's a function called SO_FUNC in a shared-library and this file is linked with that library) :
extern void SO_FUNC(void);
int main(void)
{
Elf32_Addr *gotAddr, *lazyAddr, *pltAddr;

pltAddr = (Elf32_Addr*)SO_FUNC;
//Skip the opcode and MOD-REG-R/M....
gotAddr = (Elf32_Addr*)( (char*)(pltAddr)+0x2 );
lazyAddr = (Elf32_Addr*)(*gotAddr);
printf("Address of SO_FUNC before the Call: %x\n", *lazyAddr);
SO_FUNC();
printf("Address of SO_FUNC after the Call: %x\n", *lazyAddr);
}
Output:
Address of SO_FUNC before the Call: 804834e
Address of SO_FUNC after the Call: 40024704
As we see, the address of SO_FUNC before & after the call are different. To further confirm this, we can look at /proc//maps, where pid is the process-id of the above process and see that the address 0x40024704 falls in the memory mapped for that shared library where the function is present.
Of course, this the lazy way of doing this. The correct method would be to locate the address of
the function from the symbol table, its GOT entry from the relocation section ( the rel & rela sections are somehow not present in memory, however ), and then print its contents. But then, to do that, we need to read the ELF header, the Program Header & the Dynamic Segment or use
hashing. Then again, all programmers are born lazy.