Friday, September 01, 2006
favicon
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
(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
Friday, July 28, 2006
A FoRtune Cookie
"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
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
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
Monday, May 15, 2006
Ruubeek's Cube
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
Thursday, April 20, 2006
So Sayeth, Wanda The Fish
Friday, April 14, 2006
Visions Of Paradise
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
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
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
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
{
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:
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.
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)
Let's move on to the GIMPLE output (unnecessary output skipped):
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:
;; 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);
....
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....


Monday, January 16, 2006
Ooga Mooga Ga
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]
Thursday, January 12, 2006
Identity
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!!!!
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);As we see, the address of SO_FUNC before & after the call are different. To further confirm this, we can look at /proc/
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
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.