Tuesday, August 30, 2011

My first google chrome extension

Have you ever visited Indian railway PNR status enquiry page. Truth be told its a UX disaster. 


Why I hate it

  1. Don't know why they splited PNR in to 2 parts and provided 2 text fields to enter. Basic principle in user interface design - Keep It Simple Stupid
  2. Even before we enter the 10 digit PNR we get almost 2-3 popup(if u r lucky!!!)

Digging to solve the problem led me to write a chrome extension.
So a clean solution to those who are using google chrome. 
  1. Make those two fields in to one 
  2. No popups - I know what to enter ;)
here is before extension

here is after chrome extension


here is the extension, download and install in it.....
https://sites.google.com/site/vineelkumarreddy2/pnrfix.crx

code 
// get the parent of actual text fields 
var parent = document.getElementsByName('lccp_pnrno1')[0].parentNode.parentNode;

// remove validation done by submit button in original implementaion(with onclick event)
var submitpnr = document.getElementsByName('submitpnr')[0];
submitpnr.removeAttribute('onclick');

// insert new text field and make the old two text fields as hidden 
parent.innerHTML = '<input name="pnr" id="pnr" type="text" size="10" maxlength="10" alt="Enter PNR" /><input name="lccp_pnrno1" id="lccp_pnrno1" type="hidden" size="3" maxlength="3" alt="PNR First Field" /><input name="lccp_pnrno2" id="lccp_pnrno2" type="hidden" size="7" maxlength="7" alt="PNR Second Field"/>';

// fire up on modifing text field content.....
function updateOldPnrFields(){
	var pnr = document.getElementById('pnr');
	if(pnr.value.length == 10){
		var firstpnr = document.getElementById('lccp_pnrno1');
		var secondpnr = document.getElementById('lccp_pnrno2');
		
		firstpnr.value = pnr.value.substring(0,3);
		secondpnr.value = pnr.value.substring(3);
	}
};

// attach listeners......
var pnr = document.getElementById('pnr');
pnr.addEventListener("change",updateOldPnrFields , false);
pnr.addEventListener("keyup",updateOldPnrFields , false);

Monday, August 8, 2011

Gist of what I know about LLVM compiler tool chain


This tutorial is will give you a gist of what LLVM compiler tools offer. 
Following is the schematic over all use of LLVM tools to compile a source C program into target executable. This is totally my understanding of LLVM so it may not be accurate.




Above commands may automatically invoke the optimizer as well. So depending on how we invoke the commands some of the boundaries between frontend, optimizer may overlap. In any case we can also explicitly invoke the LLVM optimizer passing the input a .bc or .ll file(see below what they mean) from front end to opt.exe. 


Basically LLVM IR is a representation of the source program in a platform independent way.
This can come be stored in 3 ways.

  1. Binary form(also called bitcode)
  2. Textual form (contains actual LLVM IR in human readable form also called LLVM assembly language)
  3. In memory representation ( I have no idea what it is )
  • The first bitcode form is obtained using "-emit-llvm -c" switch and file produced is stored in .bc files
  • The second textual form is obtained using "-emit-llvm -S" switch and file produced is stored in .ll files


test.c
#include<stdio.h>

int main()
{
	printf("This is llvm compiler testing");
	return 0;
}

equivalent LLVM IR code for the above program test.ll
; ModuleID = 'test.c'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-f128:128:128-n8:16:32"
target triple = "i386-pc-mingw32"

@.str = private unnamed_addr constant [30 x i8] c"This is llvm compiler testing\00", align 1

define i32 @main() nounwind {
entry:
  %retval = alloca i32
  %0 = alloca i32
  %"alloca point" = bitcast i32 0 to i32
  %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([30 x i8]* @.str, i32 0, i32 0)) nounwind
  store i32 0, i32* %0, align 4
  %2 = load i32* %0, align 4
  store i32 %2, i32* %retval, align 4
  br label %return

return:                                           ; preds = %entry
  %retval1 = load i32* %retval
  ret i32 %retval1
}

declare i32 @printf(i8*, ...) nounwind

plethora of optimization techniques used by llvm optimizer(opt.exe) are listed below.
OVERVIEW: llvm .bc ->; .bc modular optimizer and analysis printer

USAGE: opt [options] <input bitcode file>

OPTIONS:
  -O1                                          - Optimization level 1. Similar to llvm-gcc -O1
  -O2                                          - Optimization level 2. Similar to llvm-gcc -O2
  -O3                                          - Optimization level 3. Similar to llvm-gcc -O3
  -S                                           - Write output as LLVM assembly
  -analyze                                     - Only perform analysis, no optimization
  -default-data-layout=         - data layout string to use if not specified by module
  -disable-inlining                            - Do not run the inliner pass
  -disable-internalize                         - Do not mark all symbols as internal
  -disable-opt                                 - Do not run any optimization passes
  -disable-simplify-libcalls                   - Disable simplify-libcalls
  -enable-correct-eh-support                   - Make the -lowerinvoke pass insert expensive, but correct, EH code
  -enable-load-pre                             - 
  -enable-tbaa                                 - 
  -f                                           - Enable binary output on terminals
  -funit-at-a-time                             - Enable IPO. This is same as llvm-gcc's -funit-at-a-time
  -help                                        - Display available options (-help-hidden for more)
  -internalize-public-api-file=      - A file containing list of symbol names to preserve
  -internalize-public-api-list=          - A list of symbol names to preserve
  -load=                       - Load the specified plugin
  -o=                                - Override output filename
  -p                                           - Print module after each transformation
  -print-after                                 - Print IR after specified passes
    =aa-eval                                   -   Exhaustive Alias Analysis Precision Evaluator
    =adce                                      -   Aggressive Dead Code Elimination
    =always-inline                             -   Inliner for always_inline functions
    =argpromotion                              -   Promote 'by reference' arguments to scalars
    =basicaa                                   -   Basic Alias Analysis (stateless AA impl)
    =basiccg                                   -   Basic CallGraph Construction
    =block-placement                           -   Profile Guided Basic Block Placement
    =break-crit-edges                          -   Break critical edges in CFG
    =codegenprepare                            -   Optimize for code generation
    =constmerge                                -   Merge Duplicate Global Constants
    =constprop                                 -   Simple constant propagation
    =correlated-propagation                    -   Value Propagation
    =count-aa                                  -   Count Alias Analysis Query Responses
    =dce                                       -   Dead Code Elimination
    =deadargelim                               -   Dead Argument Elimination
    =deadarghaX0r                              -   Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
    =deadtypeelim                              -   Dead Type Elimination
    =debug-aa                                  -   AA use debugger
    =die                                       -   Dead Instruction Elimination
    =domfrontier                               -   Dominance Frontier Construction
    =domtree                                   -   Dominator Tree Construction
    =dot-callgraph                             -   Print Call Graph to 'dot' file
    =dot-cfg                                   -   Print CFG of function to 'dot' file
    =dot-cfg-only                              -   Print CFG of function to 'dot' file (with no function bodies)
    =dot-dom                                   -   Print dominance tree of function to 'dot' file
    =dot-dom-only                              -   Print dominance tree of function to 'dot' file (with no function bodies)
    =dot-postdom                               -   Print postdominance tree of function to 'dot' file
    =dot-postdom-only                          -   Print postdominance tree of function to 'dot' file (with no function bodies)
    =dot-regions                               -   Print regions of function to 'dot' file
    =dot-regions-only                          -   Print regions of function to 'dot' file (with no function bodies)
    =dse                                       -   Dead Store Elimination
    =early-cse                                 -   Early CSE
    =extract-blocks                            -   Extract Basic Blocks From Module (for bugpoint use)
    =functionattrs                             -   Deduce function attributes
    =globaldce                                 -   Dead Global Elimination
    =globalopt                                 -   Global Variable Optimizer
    =globalsmodref-aa                          -   Simple mod/ref analysis for globals
    =gvn                                       -   Global Value Numbering
    =indvars                                   -   Canonicalize Induction Variables
    =inline                                    -   Function Integration/Inlining
    =insert-edge-profiling                     -   Insert instrumentation for edge profiling
    =insert-optimal-edge-profiling             -   Insert optimal instrumentation for edge profiling
    =insert-path-profiling                     -   Insert instrumentation for Ball-Larus path profiling
    =instcombine                               -   Combine redundant instructions
    =instcount                                 -   Counts the various types of Instructions
    =instnamer                                 -   Assign names to anonymous instructions
    =instsimplify                              -   Remove redundant instructions
    =internalize                               -   Internalize Global Symbols
    =intervals                                 -   Interval Partition Construction
    =ipconstprop                               -   Interprocedural constant propagation
    =ipsccp                                    -   Interprocedural Sparse Conditional Constant Propagation
    =iv-users                                  -   Induction Variable Users
    =jump-threading                            -   Jump Threading
    =lazy-value-info                           -   Lazy Value Information Analysis
    =lcssa                                     -   Loop-Closed SSA Form Pass
    =lda                                       -   Loop Dependence Analysis
    =libcall-aa                                -   LibCall Alias Analysis
    =licm                                      -   Loop Invariant Code Motion
    =lint                                      -   Statically lint-checks LLVM IR
    =loop-deletion                             -   Delete dead loops
    =loop-extract                              -   Extract loops into new functions
    =loop-extract-single                       -   Extract at most one loop into a new function
    =loop-idiom                                -   Recognize loop idioms
    =loop-instsimplify                         -   Simplify instructions in loops
    =loop-reduce                               -   Loop Strength Reduction
    =loop-rotate                               -   Rotate Loops
    =loop-simplify                             -   Canonicalize natural loops
    =loop-unroll                               -   Unroll loops
    =loop-unswitch                             -   Unswitch loops
    =loops                                     -   Natural Loop Information
    =loweratomic                               -   Lower atomic intrinsics to non-atomic form
    =lowerinvoke                               -   Lower invoke and unwind, for unwindless code generators
    =lowersetjmp                               -   Lower Set Jump
    =lowerswitch                               -   Lower SwitchInst's to branches
    =mem2reg                                   -   Promote Memory to Register
    =memcpyopt                                 -   MemCpy Optimization
    =memdep                                    -   Memory Dependence Analysis
    =mergefunc                                 -   Merge Functions
    =mergereturn                               -   Unify function exit nodes
    =module-debuginfo                          -   Decodes module-level debug info
    =no-aa                                     -   No Alias Analysis (always returns 'may' alias)
    =no-path-profile                           -   No Path Profile Information
    =no-profile                                -   No Profile Information
    =partial-inliner                           -   Partial Inliner
    =path-profile-loader                       -   Load path profile information from file
    =path-profile-verifier                     -   Compare the path profile derived edge profile against the edge profile.
    =postdomfrontier                           -   Post-Dominance Frontier Construction
    =postdomtree                               -   Post-Dominator Tree Construction
    =preverify                                 -   Preliminary module verification
    =print-alias-sets                          -   Alias Set Printer
    =print-callgraph                           -   Print a call graph
    =print-callgraph-sccs                      -   Print SCCs of the Call Graph
    =print-cfg-sccs                            -   Print SCCs of each function CFG
    =print-dbginfo                             -   Print debug info in human readable form
    =print-dom-info                            -   Dominator Info Printer
    =print-externalfnconstants                 -   Print external fn callsites passed constants
    =print-function                            -   Print function to stderr
    =print-memdeps                             -   Print MemDeps of function
    =print-module                              -   Print module to stderr
    =print-used-types                          -   Find Used Types
    =profile-estimator                         -   Estimate profiling information
    =profile-loader                            -   Load profile information from llvmprof.out
    =profile-verifier                          -   Verify profiling information
    =prune-eh                                  -   Remove unused exception handling info
    =reassociate                               -   Reassociate expressions
    =reg2mem                                   -   Demote all values to stack slots
    =regions                                   -   Detect single entry single exit regions
    =scalar-evolution                          -   Scalar Evolution Analysis
    =scalarrepl                                -   Scalar Replacement of Aggregates (DT)
    =scalarrepl-ssa                            -   Scalar Replacement of Aggregates (SSAUp)
    =sccp                                      -   Sparse Conditional Constant Propagation
    =scev-aa                                   -   ScalarEvolution-based Alias Analysis
    =simplify-libcalls                         -   Simplify well-known library calls
    =simplifycfg                               -   Simplify the CFG
    =sink                                      -   Code sinking
    =sretpromotion                             -   Promote sret arguments to multiple ret values
    =strip                                     -   Strip all symbols from a module
    =strip-dead-debug-info                     -   Strip debug info for unused symbols
    =strip-dead-prototypes                     -   Strip Unused Function Prototypes
    =strip-debug-declare                       -   Strip all llvm.dbg.declare intrinsics
    =strip-nondebug                            -   Strip all symbols, except dbg symbols, from a module
    =tailcallelim                              -   Tail Call Elimination
    =tailduplicate                             -   Tail Duplication
    =targetdata                                -   Target Data Layout
    =targetlibinfo                             -   Target Library Information
    =tbaa                                      -   Type-Based Alias Analysis
    =verify                                    -   Module Verifier
    =view-cfg                                  -   View CFG of function
    =view-cfg-only                             -   View CFG of function (with no function bodies)
    =view-dom                                  -   View dominance tree of function
    =view-dom-only                             -   View dominance tree of function (with no function bodies)
    =view-postdom                              -   View postdominance tree of function
    =view-postdom-only                         -   View postdominance tree of function (with no function bodies)
    =view-regions                              -   View regions of function
    =view-regions-only                         -   View regions of function (with no function bodies)
  -print-after-all                             - Print IR after each pass
  -print-before                                - Print IR before specified passes
    =aa-eval                                   -   Exhaustive Alias Analysis Precision Evaluator
    =adce                                      -   Aggressive Dead Code Elimination
    =always-inline                             -   Inliner for always_inline functions
    =argpromotion                              -   Promote 'by reference' arguments to scalars
    =basicaa                                   -   Basic Alias Analysis (stateless AA impl)
    =basiccg                                   -   Basic CallGraph Construction
    =block-placement                           -   Profile Guided Basic Block Placement
    =break-crit-edges                          -   Break critical edges in CFG
    =codegenprepare                            -   Optimize for code generation
    =constmerge                                -   Merge Duplicate Global Constants
    =constprop                                 -   Simple constant propagation
    =correlated-propagation                    -   Value Propagation
    =count-aa                                  -   Count Alias Analysis Query Responses
    =dce                                       -   Dead Code Elimination
    =deadargelim                               -   Dead Argument Elimination
    =deadarghaX0r                              -   Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
    =deadtypeelim                              -   Dead Type Elimination
    =debug-aa                                  -   AA use debugger
    =die                                       -   Dead Instruction Elimination
    =domfrontier                               -   Dominance Frontier Construction
    =domtree                                   -   Dominator Tree Construction
    =dot-callgraph                             -   Print Call Graph to 'dot' file
    =dot-cfg                                   -   Print CFG of function to 'dot' file
    =dot-cfg-only                              -   Print CFG of function to 'dot' file (with no function bodies)
    =dot-dom                                   -   Print dominance tree of function to 'dot' file
    =dot-dom-only                              -   Print dominance tree of function to 'dot' file (with no function bodies)
    =dot-postdom                               -   Print postdominance tree of function to 'dot' file
    =dot-postdom-only                          -   Print postdominance tree of function to 'dot' file (with no function bodies)
    =dot-regions                               -   Print regions of function to 'dot' file
    =dot-regions-only                          -   Print regions of function to 'dot' file (with no function bodies)
    =dse                                       -   Dead Store Elimination
    =early-cse                                 -   Early CSE
    =extract-blocks                            -   Extract Basic Blocks From Module (for bugpoint use)
    =functionattrs                             -   Deduce function attributes
    =globaldce                                 -   Dead Global Elimination
    =globalopt                                 -   Global Variable Optimizer
    =globalsmodref-aa                          -   Simple mod/ref analysis for globals
    =gvn                                       -   Global Value Numbering
    =indvars                                   -   Canonicalize Induction Variables
    =inline                                    -   Function Integration/Inlining
    =insert-edge-profiling                     -   Insert instrumentation for edge profiling
    =insert-optimal-edge-profiling             -   Insert optimal instrumentation for edge profiling
    =insert-path-profiling                     -   Insert instrumentation for Ball-Larus path profiling
    =instcombine                               -   Combine redundant instructions
    =instcount                                 -   Counts the various types of Instructions
    =instnamer                                 -   Assign names to anonymous instructions
    =instsimplify                              -   Remove redundant instructions
    =internalize                               -   Internalize Global Symbols
    =intervals                                 -   Interval Partition Construction
    =ipconstprop                               -   Interprocedural constant propagation
    =ipsccp                                    -   Interprocedural Sparse Conditional Constant Propagation
    =iv-users                                  -   Induction Variable Users
    =jump-threading                            -   Jump Threading
    =lazy-value-info                           -   Lazy Value Information Analysis
    =lcssa                                     -   Loop-Closed SSA Form Pass
    =lda                                       -   Loop Dependence Analysis
    =libcall-aa                                -   LibCall Alias Analysis
    =licm                                      -   Loop Invariant Code Motion
    =lint                                      -   Statically lint-checks LLVM IR
    =loop-deletion                             -   Delete dead loops
    =loop-extract                              -   Extract loops into new functions
    =loop-extract-single                       -   Extract at most one loop into a new function
    =loop-idiom                                -   Recognize loop idioms
    =loop-instsimplify                         -   Simplify instructions in loops
    =loop-reduce                               -   Loop Strength Reduction
    =loop-rotate                               -   Rotate Loops
    =loop-simplify                             -   Canonicalize natural loops
    =loop-unroll                               -   Unroll loops
    =loop-unswitch                             -   Unswitch loops
    =loops                                     -   Natural Loop Information
    =loweratomic                               -   Lower atomic intrinsics to non-atomic form
    =lowerinvoke                               -   Lower invoke and unwind, for unwindless code generators
    =lowersetjmp                               -   Lower Set Jump
    =lowerswitch                               -   Lower SwitchInst's to branches
    =mem2reg                                   -   Promote Memory to Register
    =memcpyopt                                 -   MemCpy Optimization
    =memdep                                    -   Memory Dependence Analysis
    =mergefunc                                 -   Merge Functions
    =mergereturn                               -   Unify function exit nodes
    =module-debuginfo                          -   Decodes module-level debug info
    =no-aa                                     -   No Alias Analysis (always returns 'may' alias)
    =no-path-profile                           -   No Path Profile Information
    =no-profile                                -   No Profile Information
    =partial-inliner                           -   Partial Inliner
    =path-profile-loader                       -   Load path profile information from file
    =path-profile-verifier                     -   Compare the path profile derived edge profile against the edge profile.
    =postdomfrontier                           -   Post-Dominance Frontier Construction
    =postdomtree                               -   Post-Dominator Tree Construction
    =preverify                                 -   Preliminary module verification
    =print-alias-sets                          -   Alias Set Printer
    =print-callgraph                           -   Print a call graph
    =print-callgraph-sccs                      -   Print SCCs of the Call Graph
    =print-cfg-sccs                            -   Print SCCs of each function CFG
    =print-dbginfo                             -   Print debug info in human readable form
    =print-dom-info                            -   Dominator Info Printer
    =print-externalfnconstants                 -   Print external fn callsites passed constants
    =print-function                            -   Print function to stderr
    =print-memdeps                             -   Print MemDeps of function
    =print-module                              -   Print module to stderr
    =print-used-types                          -   Find Used Types
    =profile-estimator                         -   Estimate profiling information
    =profile-loader                            -   Load profile information from llvmprof.out
    =profile-verifier                          -   Verify profiling information
    =prune-eh                                  -   Remove unused exception handling info
    =reassociate                               -   Reassociate expressions
    =reg2mem                                   -   Demote all values to stack slots
    =regions                                   -   Detect single entry single exit regions
    =scalar-evolution                          -   Scalar Evolution Analysis
    =scalarrepl                                -   Scalar Replacement of Aggregates (DT)
    =scalarrepl-ssa                            -   Scalar Replacement of Aggregates (SSAUp)
    =sccp                                      -   Sparse Conditional Constant Propagation
    =scev-aa                                   -   ScalarEvolution-based Alias Analysis
    =simplify-libcalls                         -   Simplify well-known library calls
    =simplifycfg                               -   Simplify the CFG
    =sink                                      -   Code sinking
    =sretpromotion                             -   Promote sret arguments to multiple ret values
    =strip                                     -   Strip all symbols from a module
    =strip-dead-debug-info                     -   Strip debug info for unused symbols
    =strip-dead-prototypes                     -   Strip Unused Function Prototypes
    =strip-debug-declare                       -   Strip all llvm.dbg.declare intrinsics
    =strip-nondebug                            -   Strip all symbols, except dbg symbols, from a module
    =tailcallelim                              -   Tail Call Elimination
    =tailduplicate                             -   Tail Duplication
    =targetdata                                -   Target Data Layout
    =targetlibinfo                             -   Target Library Information
    =tbaa                                      -   Type-Based Alias Analysis
    =verify                                    -   Module Verifier
    =view-cfg                                  -   View CFG of function
    =view-cfg-only                             -   View CFG of function (with no function bodies)
    =view-dom                                  -   View dominance tree of function
    =view-dom-only                             -   View dominance tree of function (with no function bodies)
    =view-postdom                              -   View postdominance tree of function
    =view-postdom-only                         -   View postdominance tree of function (with no function bodies)
    =view-regions                              -   View regions of function
    =view-regions-only                         -   View regions of function (with no function bodies)
  -print-before-all                            - Print IR before each pass
  -print-breakpoints-for-testing               - Print select breakpoints location for testing
  -profile-estimator-loop-weight= - Number of loop executions used for profile-estimator
  -profile-info-file=                - Profile file loaded by -profile-loader
  -profile-verifier-noassert                   - Disable assertions
  -stats                                       - Enable statistics output from program
  -std-compile-opts                            - Include the standard compile time optimizations
  -std-link-opts                               - Include the standard link time optimizations
  -strip-debug                                 - Strip debugger symbol info from translation unit
  Optimizations available:
    -aa-eval                                   - Exhaustive Alias Analysis Precision Evaluator
    -adce                                      - Aggressive Dead Code Elimination
    -always-inline                             - Inliner for always_inline functions
    -argpromotion                              - Promote 'by reference' arguments to scalars
    -basicaa                                   - Basic Alias Analysis (stateless AA impl)
    -basiccg                                   - Basic CallGraph Construction
    -block-placement                           - Profile Guided Basic Block Placement
    -break-crit-edges                          - Break critical edges in CFG
    -codegenprepare                            - Optimize for code generation
    -constmerge                                - Merge Duplicate Global Constants
    -constprop                                 - Simple constant propagation
    -correlated-propagation                    - Value Propagation
    -count-aa                                  - Count Alias Analysis Query Responses
    -dce                                       - Dead Code Elimination
    -deadargelim                               - Dead Argument Elimination
    -deadarghaX0r                              - Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
    -deadtypeelim                              - Dead Type Elimination
    -debug-aa                                  - AA use debugger
    -die                                       - Dead Instruction Elimination
    -domfrontier                               - Dominance Frontier Construction
    -domtree                                   - Dominator Tree Construction
    -dot-callgraph                             - Print Call Graph to 'dot' file
    -dot-cfg                                   - Print CFG of function to 'dot' file
    -dot-cfg-only                              - Print CFG of function to 'dot' file (with no function bodies)
    -dot-dom                                   - Print dominance tree of function to 'dot' file
    -dot-dom-only                              - Print dominance tree of function to 'dot' file (with no function bodies)
    -dot-postdom                               - Print postdominance tree of function to 'dot' file
    -dot-postdom-only                          - Print postdominance tree of function to 'dot' file (with no function bodies)
    -dot-regions                               - Print regions of function to 'dot' file
    -dot-regions-only                          - Print regions of function to 'dot' file (with no function bodies)
    -dse                                       - Dead Store Elimination
    -early-cse                                 - Early CSE
    -extract-blocks                            - Extract Basic Blocks From Module (for bugpoint use)
    -functionattrs                             - Deduce function attributes
    -globaldce                                 - Dead Global Elimination
    -globalopt                                 - Global Variable Optimizer
    -globalsmodref-aa                          - Simple mod/ref analysis for globals
    -gvn                                       - Global Value Numbering
    -indvars                                   - Canonicalize Induction Variables
    -inline                                    - Function Integration/Inlining
    -insert-edge-profiling                     - Insert instrumentation for edge profiling
    -insert-optimal-edge-profiling             - Insert optimal instrumentation for edge profiling
    -insert-path-profiling                     - Insert instrumentation for Ball-Larus path profiling
    -instcombine                               - Combine redundant instructions
    -instcount                                 - Counts the various types of Instructions
    -instnamer                                 - Assign names to anonymous instructions
    -instsimplify                              - Remove redundant instructions
    -internalize                               - Internalize Global Symbols
    -intervals                                 - Interval Partition Construction
    -ipconstprop                               - Interprocedural constant propagation
    -ipsccp                                    - Interprocedural Sparse Conditional Constant Propagation
    -iv-users                                  - Induction Variable Users
    -jump-threading                            - Jump Threading
    -lazy-value-info                           - Lazy Value Information Analysis
    -lcssa                                     - Loop-Closed SSA Form Pass
    -lda                                       - Loop Dependence Analysis
    -libcall-aa                                - LibCall Alias Analysis
    -licm                                      - Loop Invariant Code Motion
    -lint                                      - Statically lint-checks LLVM IR
    -loop-deletion                             - Delete dead loops
    -loop-extract                              - Extract loops into new functions
    -loop-extract-single                       - Extract at most one loop into a new function
    -loop-idiom                                - Recognize loop idioms
    -loop-instsimplify                         - Simplify instructions in loops
    -loop-reduce                               - Loop Strength Reduction
    -loop-rotate                               - Rotate Loops
    -loop-simplify                             - Canonicalize natural loops
    -loop-unroll                               - Unroll loops
    -loop-unswitch                             - Unswitch loops
    -loops                                     - Natural Loop Information
    -loweratomic                               - Lower atomic intrinsics to non-atomic form
    -lowerinvoke                               - Lower invoke and unwind, for unwindless code generators
    -lowersetjmp                               - Lower Set Jump
    -lowerswitch                               - Lower SwitchInst's to branches
    -mem2reg                                   - Promote Memory to Register
    -memcpyopt                                 - MemCpy Optimization
    -memdep                                    - Memory Dependence Analysis
    -mergefunc                                 - Merge Functions
    -mergereturn                               - Unify function exit nodes
    -module-debuginfo                          - Decodes module-level debug info
    -no-aa                                     - No Alias Analysis (always returns 'may' alias)
    -no-path-profile                           - No Path Profile Information
    -no-profile                                - No Profile Information
    -partial-inliner                           - Partial Inliner
    -path-profile-loader                       - Load path profile information from file
    -path-profile-verifier                     - Compare the path profile derived edge profile against the edge profile.
    -postdomfrontier                           - Post-Dominance Frontier Construction
    -postdomtree                               - Post-Dominator Tree Construction
    -preverify                                 - Preliminary module verification
    -print-alias-sets                          - Alias Set Printer
    -print-callgraph                           - Print a call graph
    -print-callgraph-sccs                      - Print SCCs of the Call Graph
    -print-cfg-sccs                            - Print SCCs of each function CFG
    -print-dbginfo                             - Print debug info in human readable form
    -print-dom-info                            - Dominator Info Printer
    -print-externalfnconstants                 - Print external fn callsites passed constants
    -print-function                            - Print function to stderr
    -print-memdeps                             - Print MemDeps of function
    -print-module                              - Print module to stderr
    -print-used-types                          - Find Used Types
    -profile-estimator                         - Estimate profiling information
    -profile-loader                            - Load profile information from llvmprof.out
    -profile-verifier                          - Verify profiling information
    -prune-eh                                  - Remove unused exception handling info
    -reassociate                               - Reassociate expressions
    -reg2mem                                   - Demote all values to stack slots
    -regions                                   - Detect single entry single exit regions
    -scalar-evolution                          - Scalar Evolution Analysis
    -scalarrepl                                - Scalar Replacement of Aggregates (DT)
    -scalarrepl-ssa                            - Scalar Replacement of Aggregates (SSAUp)
    -sccp                                      - Sparse Conditional Constant Propagation
    -scev-aa                                   - ScalarEvolution-based Alias Analysis
    -simplify-libcalls                         - Simplify well-known library calls
    -simplifycfg                               - Simplify the CFG
    -sink                                      - Code sinking
    -sretpromotion                             - Promote sret arguments to multiple ret values
    -strip                                     - Strip all symbols from a module
    -strip-dead-debug-info                     - Strip debug info for unused symbols
    -strip-dead-prototypes                     - Strip Unused Function Prototypes
    -strip-debug-declare                       - Strip all llvm.dbg.declare intrinsics
    -strip-nondebug                            - Strip all symbols, except dbg symbols, from a module
    -tailcallelim                              - Tail Call Elimination
    -tailduplicate                             - Tail Duplication
    -targetdata                                - Target Data Layout
    -targetlibinfo                             - Target Library Information
    -tbaa                                      - Type-Based Alias Analysis
    -verify                                    - Module Verifier
    -view-cfg                                  - View CFG of function
    -view-cfg-only                             - View CFG of function (with no function bodies)
    -view-dom                                  - View dominance tree of function
    -view-dom-only                             - View dominance tree of function (with no function bodies)
    -view-postdom                              - View postdominance tree of function
    -view-postdom-only                         - View postdominance tree of function (with no function bodies)
    -view-regions                              - View regions of function
    -view-regions-only                         - View regions of function (with no function bodies)
  -time-passes                                 - Time each pass, printing elapsed time for each on exit
  -verify-dom-info                             - Verify dominator info (time consuming)
  -verify-each                                 - Verify after each transform
  -verify-loop-info                            - Verify loop info (time consuming)
  -verify-region-info                          - Verify region info (time consuming)
  -version                                     - Display the version of this program




Friday, April 15, 2011

Use Google Chrome as PDF reader



Using Google Chrome as a PDF reader is a small tip, which I found very useful. Google Chrome can render PDF files inside the browser itself [Just drag and drop the file you want to read]. Reading pdf files in chrome has many more advantages. 

  1. Pages are rendered very very quickly than compared to Adobe reader
  2. Find feature of chrome is simply awesome it even works inside the open pdf file - check it 
  3. Scanned PDFs load faster
  4. No GUI clutter - No Menus nothing - Use left,right arrow keys......
  5. No extra software required
  6. Cross platform - Hope the same works even you are in linux
A PDF file rendered in Google Chrome Browser [ showing its awesome find feature ]

Hope this tip is useful......




Sunday, November 14, 2010

The Birth of Windows Desktop


Have you ever thought of how your operating system(windows) is loaded? It’s quite interesting to know about the miniature details that are involved in the process. This article will shed some light on this topic. The actual execution of the processor begins when you power on the system. Following are the major steps involved.


1.       BIOS performs some initial check and read the Zero sector of the hard disc, This Zero sector has a special name - MBR(Master Boot Record)


Snap from HxD hex editor


2.       MBR contains two sections 
2.1.    Boot Code(446 bytes)
2.2.    Partition Table Entries(16 bytes colored entries in the bottom)

3.       The purpose of boot code is to iterate over all the partition table entries and check for a bootable partition (if the first byte of the partition entry is 0x80 then it is a bootable partition. Also called as boot partition or system volume)(There can be only four entries specified in the MBR, does it mean we are limited with 4 drives ?)(this is where extended partitions come into picture)

4.       Now besides locating the boot partition it will know exactly from which sector the boot partition begins. This is done by examining the 8th-12th bytes in the partition entry(so in the above picture 3f 00 00 00 converted to little endian we get 0000003f = 63rd Sector). In general it will be 63rd sector.

5.       Again the first sector(63rd) of the bootable partition is called as Boot Sector which contain enough code to read a special file named ntldr (NT loader) from the root (c:\) drive. This is the time where you may at times see “NTLDR is missing” error message. Following are the tasks performed by ntldr
5.1.    The main purpose of ntldr is to setup the stage for the windows kernel to load.
5.2.    It enables paging and preliminary hardware detection using BIOS routines(int) and ntdetect.com
5.3.    Reads boot.ini  to display boot menu


Windows boot menu created from c:\boot.ini


5.4.    If the system is hibernated during the last shutdown it will resumed from hiberfil.sys
5.5.    Most importantly it loads boot start drivers ( these are the core drivers for proper functioning of OS) following are the examples for boot start drivers

Drivers tab in process hacker displaying boot start drivers

5.6.    Sets CPU registers e.t.c and pass on the control to ntoskrnl.exe(NT OS Kernel). This ends the life of ntldr

6.       Ntoskrnl is mainly responsible for setting up following OS services ( here you will see windows XP logo progress bar)
6.1.    Phase 0 Initialization
6.1.1. Memory Management Services
6.1.2. Process Management Services(First kernel mode process the system process is created)
6.1.3. Object Manger Services
6.1.4. Plug and Play Management Services
6.1.5. Security Reference Monitor Services
6.2.    Phase 1 Initialization
6.2.1. Hal initialization (Hardware Abstraction Layer)
6.2.2. Multi processor support
6.2.3. Scheduler support (inherently dependent on processor architecture)
6.2.4. Power management

kernel and boot drivers initialization
  
7.       Now the control is passed on to smss.exe(Session Manager Subsystem), It is the first user mode process that is created in the life span of windows.

Threads inside System and Smss processes 
7.1.    

7.2.    The following are the tasks performed by smss process

7.2.1.  Runs check disk ( disc check )

Disk check triggered by smss process

7.2.2.  Pending file copy and file deletes ( some softwares need to overwrite the files which are in use by the OS and they will ask you for reboot) and this is the phase where those pending copy and deletes will be performed.
7.2.3. Page file is created(pagefile.sys)

Registry path to PagingFiles - Used by Smss for creating page files

7.3.    Loads registry hives from \Windows\System32\Config\*.*

7.4.    Finally it creates two processes csrss.exe(Client Server Run-Time Subsystem), Winlogon.exe
7.4.1. Csrss.exe is responsible for user mode functionality of the system and sits as an interface for windows API)
7.4.2. Winlogon.exe is responsible for starting all auto-start services (services.exe) and creating the lsass.exe(Local Security and Authentication Subsystem)  this process is for authenticating the user logins
7.4.3. Next winlogon will show the logon screen to the user, upon successful logon winlogon will load the explorer.exe under the current user profile. This is where you will see the desktop

Winlogon displaying active login screen

Explorer created with current logged in user account
        
The Desktop is Born!
                        

Though the actual process involves more complicated steps I have over simplified the overall flow in favor of novice users and tried not to lose the brevity of the content. Please feel free to comment on the post. +ve criticism is most welcome.

References:
1.      Windows Internals 4thEd By Mark E. Russinovich, David A. Solomon

Friday, October 15, 2010

Setting up kernel mode debugger in windows

When ever there is a bug in your program you usually open a debugger(Turbo C++, GDB,visual studio debugger etc) to fix it, but how do you debug a bug in the operating system? Do you load the running OS in to debugger? Is it possible? The simple answer is no. It is not possible because in order for any debugger to work it requires help from the Os on which the program is being debugged. So we cannot debug an OS with the help of itself. So in such scenarios we require 2 machines one is your defective Os(slave) and other machine contains the debugger software(master). Earlier people used to connect slave and master machines using a high speed cable and then once the slave machine is started they used to pause its execution by connecting the debugger to it from the master machine. It used to be the only solution with many drawbacks. 
  1. The connection speed between the machines is too slow, because the data and commands should be passed to and fro between master and slave.
  2. Require extra hardware like cable and two separate machines
Fortunately we now have much better options for beginners who want to study the internals of the OS by debugging. With the help of virtual machines we now donot require two separate machines. The slave machine can be thought of as a one of the guest VMs and master machine can be thought of as a host computer(your real physical machine). The connection between these host and guest have been made even simpler with the help of a software called VirtualKD(Virtual Kernel Debugger)[with out this tool we have to manually set up a named pipe in the guest and modify boot.ini to enable some special options. Its little time consuming]. So in this tutorial I will help you set up kernel mode debugger.


I will be using following tools.

  1. WinDbg (Windows Kernel Debugger)
  2. Virtual Box (Virtual Machine Manager)
  3. VirtualKD (Tool to enable very high speed kernel debugging between host and just machines)

here after when ever I refer to OS it will be one version of windows


First thing we have to do is install virtual box and then install a guest OS of your choice Here I would like to demo you using Windows XP as my guest [installing a guest VM]


Second extract the virtualKD to some folder 
Rename the VBoxDD.dll file in your VirtualBox program files folder to VBoxDD0.dll.
Copy modified VBoxDD.dll from VirtualKD archive to VirtualBox directory(Ensure that you have selected correct version (x86 or x64) of VBoxDD.dll)




Third install WinDbg (simple next next install)
for any debugger to properly work we should have symbol files of the program being debugged, think of these files as extra information about your program which helps debugger in displaying meaningful information to the user. If we have correct symbol files we will have the extract function names and the line numbers etc getting showed in the debugger, without that we will see some hard to understand Hex address. So following few lines will help you configure symbol files for you operating system



If you have internet connection all the time follow this

o   Create an environment variable named _NT_SYMBOL_PATH and set its value to say srv*c:\symbols*http://msdl.microsoft.com/download/symbols       
o   Symbols will be downloaded from the microsoft symbol server on demand to c:\symbols
Else follow this
o   Create an environment variable named _NT_SYMBOL_PATH and set its value to say c:\symbols
o   C:\program files\symchk.exe  /r  c:\windows\system32\*  /s SRV*C:\symbols\*http://msdl.microsoft.com/download/symbols
o   The above command will fetch all the symbols for the files in system32 at once (takes time and space)
o   Its a one time task 


when WinDbg is launched it will check this variable to know the path of symbol files.


Fourth run VirtualKD in the guest machine and then reboot the guest as instructed.




once you are at the boot prompt open 




choose the highlighted one and then open vmmon.exe from VirtualKD which will automatically launch WinDBG and connect to the currently running VM and pauses its execution







done. the rest is left to your imagination.