weblog d’un abbe

20081216

Hacking a codegen

Filed under: Experiences, Fun, Hacking, Yippee!! — Tags: , , , , , , — abbe @ 0456

So, finally I’ve hacked a basic AMD64 code generator, after so many tries. This code generator is hacked in Common Lisp, and is currently generating a code for a very simple toy like language. I’ve not written any grammar specification for it. It is a LISP like language. This piece of code generator is dedicated to one of my cool friend Edwin Jose, and is thus named as louzer. Following is an example of the language for which louzer generates code.

(source
	 (let principal rate time amount x)
	 (= principal 1000)
	 (= rate 10)
	 (= time 100)
	 (= x 100)
	 (= amount
		(/ (* principal (* rate time))
		 100))
	 (print "Amount (%d) - %d is %d.\\n"  amount x (- amount x))
	 (print "Hello World, louzer\\n"))

The language code is also embedded along with the source code in the LISP file. Following is how I’m using it with GNU clisp implementation:

% clisp louzer.lisp |tee test.S
.section .text
.extern printf
.type main,@function
.globl main
main:
 pushq %rbp
 movq %rsp, %rbp
 subq $40, %rsp
 movq $1000, %rbx
 movq %rbx, -8(%rbp)
 movq $10, %rbx
 movq %rbx, -16(%rbp)
 movq $100, %rbx
 movq %rbx, -24(%rbp)
 movq $100, %rbx
 movq %rbx, -40(%rbp)
 movq -16(%rbp), %rbx
 imul -24(%rbp), %rbx
 imul -8(%rbp), %rbx
 movq %rbx, %rax
 movq $100, %rbx
 xorq %rdx,%rdx
 idiv %rbx
 movq %rax, -32(%rbp)
 leaq __string_0,%rdi
 movq -32(%rbp), %rsi
 movq -40(%rbp), %rdx
 movq -32(%rbp), %rbx
 subq -40(%rbp), %rbx
 movq %rbx, %rcx
 xorq %rax,%rax
 call printf
 leaq __string_1,%rdi
 xorq %rax,%rax
 call printf
 xorq %rax, %rax
 movq %rbp, %rsp
 popq %rbp
 ret
.section .rodata
__string_1: .string "Hello, louzer World\n"
__string_0: .string "Amount (%d) - %d is %d.\n"
/* Generated by louzer :) */

Above is the piece of AMD64 assembly code emitted by the louzer. So, now time to assemble and link the above assembly code and generate the output of the above code.

% cc -o test test.S
% ./test
Amount (10000) - 100 is 9900.
Hello, louzer World

Voila. Oh, sorry to keep you waiting, now you can download the louzer.lisp and have fun. BtW, code is not perfect and has couple of limitations, which I’ve not fixed due to lack of time, as I’ve an exam day after tomorrow. So, I’ll be able to work on it only after 20081219. Happy hacking codegens…;)

NOTE (for Grammar Nazis): Forgive me for any grammatical mistakes you encounter above, and ofcourse point out the mistake :).

P.S. Forgot to mention, you’ll need an AMD64 architecture CPU, toolchain and POSIX OS to test out above stuff.

20081211

Ready to assassinate spam

Filed under: Experiments, Fun, Hacking — Tags: , , , , , — abbe @ 2136

Since a week or two, I noticed I suddenly started to get many spams (at the rate of around 10/day) delivered to my gmail inbox. I reported them every time, but that is of not much use. So tired of reporting spams, I started to create filters (in gmail) based on From address, ‘Subject’ etc. to delete them as soon they arrive, and I noticed that some of the ham mails also got deleted due to my filters. So, to get rid of this problem yesternight I installed SpamAssassin (which I’m afraid of installing earlier because I heard of its complex configuration) on my box integrated with postfix instance on my Gentoo GNU/Linux. The installation (thanks to portage) is very easy and integration with postfix is also quite easy and well documented on its wiki. And now, the best part, my SpamAssassin today recognized those mails as spam, which gmail‘s spam filters delivered into my inbox :).

Following is a Gnus hack to report spam as ham and ham as spam :

(defun my-gnus-mark-spam()
  (interactive)
  (gnus-summary-show-raw-article)
  (gnus-summary-save-in-pipe "spamc -L spam")
  (gnus-summary-show-article)
  ;; substitute "nnmaildir:spam" with the name of group holding "spam"
  (gnus-summary-move-article nil "nnmaildir:spam"))

(defun my-gnus-mark-ham()
  (interactive)
  (gnus-summary-show-raw-article)
  (gnus-summary-save-in-pipe "spamc -L ham")
  (gnus-summary-show-article)
  (gnus-summary-respool-article nil))

;; in summary mode use "B s" and "B h" keys to mark a mail as spam and ham
;; respectively for SpamAssassin to learn, and to also move to "spam" maildir
;; or respool mail accordingly
(define-key gnus-summary-mode-map (kbd "B s") 'my-gnus-mark-spam)
(define-key gnus-summary-mode-map (kbd "B h") 'my-gnus-mark-ham)

I could have used Gnus built-in spam filtering, but Gnus is not the only MUA I use ;) . Anyways, happy assassinating spam…;)

20081203

fake identd server

Filed under: Fun, Hacking — Tags: , , — abbe @ 2007
-- identd: RFC1413 incompliant identd server
-- author: Ashish Shukla <gmail.com!wahjava>
-- license: GNU GPLv2 or later version at your option
-- special thanks to: consolers on #emacs
-- 1. Compile the file: abbe@chateau $ ghc --make identd.hs
-- 2. Make it setuid root: abbe@chateau $ chown 0 identd; chmod u+s identd
-- 3. Execute it: abbe@chateau $ ./identd abbe
-- happy faking ident

import System.IO (hGetContents, hClose, openFile, hPutStrLn, hGetLine)
import System.Random (randomRIO)
import IO
import Network.BSD
import Network.Socket

import System.Environment (getArgs, getProgName)

import System.Posix.User (getUserEntryForName, setUserID, UserEntry, userID)

import Control.Exception (evaluate)

wordsFile = "/usr/share/dict/words"

loadWords :: FilePath -> IO [String]
loadWords fileName = do
    handle <- openFile fileName ReadMode
    contents <- hGetContents $ handle
    let listOfWords = lines contents
    lenWords <- evaluate (length $ listOfWords)
    hClose handle
    return listOfWords

getUserName :: [String] -> IO String
getUserName words = do
    index <- randomRIO (0, length words - 1) :: IO Int
    return (words !! index)

handleSocket :: [String] -> IO (Socket, SockAddr) -> IO Bool
handleSocket words struct = do
  (socket, sockaddr) <- struct
  handle <- socketToHandle socket ReadWriteMode
  line <- hGetLine handle
  name <- getUserName words
  -- logged-in from a LISP Machine ;)
  hPutStrLn handle $ (withoutWS line) ++ " : USERID : LISPM : " ++ name
  hClose handle
  return True
  where withoutWS = filter (\x -> x `notElem` [ '\r', '\n'])

main = do
  args <- getArgs
  progName <- getProgName
  if null args
    then putStrLn $ "Usage: " ++ progName ++ " [username]"
    else do
        user <- getUserEntryForName $ args !! 0
        let uid = userID user
        rng <- getStdGenuu
        ssock <- socket AF_INET6 Stream defaultProtocol
        bindSocket ssock (SockAddrInet6 113 0 (0,0,0,0) 0)
        setUserID uid
        words <- loadWords wordsFile
        sockaddr <- getSocketName $ ssock
        listen ssock 5
        loopForever (handleSocket words . accept) ssock
        sClose ssock
  where loopForever function y = do
            retval <- function y
            if retval
              then (loopForever function y)
              else return ()

Happy faking ident…;)

Blog at WordPress.com.