systemC 2.2.0 在 ubuntu9.10 with gcc4.4.1 加 helloworld 範例

因為上課的需求,我在 ubuntu9.10 安裝了 systemC

先到 Open SystemC Initiative ( OSCI ) 下載 systemc-2.2.0.tgz

一般使用者必須先加入這個網站的會員才能下載,成為會員是免費的,加入吧!

下載完之後解壓縮,閱讀 INSTALL ,裡面有寫 unix-like OS 如 linux, SunOS, 支援的gcc版本,注意!不支援 bsd 系統

按照 INSTALL 的說明步驟

  1. mkdir objdir
  2. cd objdir
  3. ../configure
  4. 這邊要注意看每行的檢測結果,例如有沒有安裝 g++。
    如果沒有的話可以用 sudo apt-get install g++ 進行安裝

  5. make
  6. make degub
  7. sudo make install

我在 make 時遇到這個問題

make[3]: Entering directory `/home/Pratik/SystemC/systemc-2.2.0/objdir/src/sysc/utils'
g++ -I. -I. -I../../../../src/sysc/utils -I../../../../src -Wall -DSC_INCLUDE_FX -O3 -c -o sc_utils_ids.o `test -f '../../../../src/sys/utils/sc_utils_ids.cpp' || echo '../../../../src/sysc/utils/'`../../../../src/sysc/utils/sc_utils_ids.cpp
../../../../src/sysc/utils/sc_utils_ids.cpp: In function ‘int sc_core::initialize()’:
../../../../src/sysc/utils/sc_utils_ids.cpp:110: error: ‘getenv’ is not a member of ‘std’
../../../../src/sysc/utils/sc_utils_ids.cpp:111: error: ‘strcmp’ was not declared in this scope
../../../../src/sysc/utils/sc_utils_ids.cpp: At global scope:
../../../../src/sysc/utils/sc_utils_ids.cpp:119: warning: ‘sc_core::forty_two’ defined but not used
make[3]: *** [sc_utils_ids.o] Error 1
make[3]: Leaving directory `/home/Pratik/SystemC/systemc-2.2.0/objdir/src/sysc/utils'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/home/Pratik/SystemC/systemc-2.2.0/objdir/src/sysc'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/Pratik/SystemC/systemc-2.2.0/objdir/src'
make: *** [all-recursive] Error 1

之後我在 這邊 找到解答

在檔案 systemc-2.2.0/src/sysc/utils/sc_utils_ids.cpp 裡面加入下面兩行

#include "string.h"
#include "cstdlib"

然後就可以正確編譯過囉!

正確編譯過後,到 objdir/examples/sysc/2.1/dpipe 裡面編譯一個範例試試看

  • make check

正確編譯過之後就會跑出這樣的結果

             SystemC 2.2.0 --- Dec  3 2009 10:12:54
        Copyright (c) 1996-2006 by all Contributors
                    ALL RIGHTS RESERVED
0: 0
1000: 0
2000: 0
3000: 0
4000: 1
5000: 2
6000: 3
7000: 4
8000: 5
9000: 6
PASS: sc_export
==================
All 1 tests passed
==================

以下是一個簡單的 hello world 範例

#include "systemc.h"

// Hello_world is module name
SC_MODULE (hello_world) {
        SC_CTOR (hello_world) {
                // Nothing in constructor
        }
        void say_hello() {
                //Print "Hello World" to the console.
                cout << "Hello World.n";
        }
};

// sc_main in top level function like in C++ main
int sc_main(int argc, char* argv[]) {
        hello_world hello("HELLO");
        // Print the hello world
        hello.say_hello();
        return(0);
}
  1. 每個 systemC 程式一定都要 include
  2. 每個 systemC 程式都從 SC_MODULE 開始
  3. 第四行包含了 hello_world 這個 module

REF:http://www.asic-world.com/systemc/first1.html#Introduction

編譯命令

g++ -Wall -DSC_INCLUDE_FX -I./systemC/include/ -L ./systemC/lib-linux/ hello.cpp -lsystemc

編譯命令的 Makefile 版本

prefix = /home/magicallove/systemC
inc = ${prefix}/include
lib = ${prefix}/lib-linux

all : hello.cpp
	g++ -o hello -Wall -DSC_INCLUDE_FX -I${inc} -L${lib} -lsystemc hello.cpp

clean :
	rm hello

NOTE: you have to modify the value of ${prefix}, replace it with the place you install the systemC

編譯過程會有蠻多 warning ,不影響結果。

執行結果如下:

               SystemC 2.2.0 --- Dec  3 2009 10:12:54
        Copyright (c) 1996-2006 by all Contributors
                    ALL RIGHTS RESERVED
Hello World.

buffer overflow

前幾天在 成功大學 電機系 BBS 站(telnet://bbs.ee.ncku.edu.tw) 看到 Hacker 版重新開張,第一篇文章討論的是 buffer overflow

對於 buffer overflow 從以前就有所聞,也知道他是利用輸入大量資料,覆蓋到其他資料的記憶體位址得來達成目標(取得 root 權限之類)

不過這類錯誤在現今的程式裡面應該全都修掉了吧,下面是版上的範例。

#include
#include
#include

int check(char * password)
{
        int ans_flag = 0;
        char passwd[16];
        strcpy(passwd, password);
        if( 0 == strcmp(passwd, "666") )
        {
                ans_flag = 1;
        }
        return ans_flag;
}
int main(int argc, char *argv[])
{
        if( argc < 2 )
        {
                printf("Usage: %s n", argv[0]);
                exit(0);
        }
        if( check(argv[1]) )
        {
                puts("ACCESS GRANTED.");
                // do private things here...
        }
        else
        {
                puts("ACCESS DENIED.");
        }
        return 0;
}
    $ ./a.out 123
    ACCESS DENIED.
    $ ./a.out 666
    ACCESS GRANTED.
    $ ./a.out AAAAAAAAAAAAAAAAA
    ACCESS GRANTED.

上面也是版上的範例,不過,我在我的機器上面實際運作的情況是…

*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7ffcda8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7ffcd60]
./a.out[0x8048546]
./a.out[0x804859b]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7f15775]
./a.out[0x8048451]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:05 1442393    /home/magicallove/c_practice/buffer_overflow/a.out
08049000-0804a000 r--p 00000000 08:05 1442393    /home/magicallove/c_practice/buffer_overflow/a.out
0804a000-0804b000 rw-p 00001000 08:05 1442393    /home/magicallove/c_practice/buffer_overflow/a.out
09545000-09566000 rw-p 09545000 00:00 0          [heap]
b7eef000-b7efc000 r-xp 00000000 08:03 1296       /lib/libgcc_s.so.1
b7efc000-b7efd000 r--p 0000c000 08:03 1296       /lib/libgcc_s.so.1
b7efd000-b7efe000 rw-p 0000d000 08:03 1296       /lib/libgcc_s.so.1
b7efe000-b7eff000 rw-p b7efe000 00:00 0
b7eff000-b805b000 r-xp 00000000 08:03 5749       /lib/tls/i686/cmov/libc-2.9.so
b805b000-b805c000 ---p 0015c000 08:03 5749       /lib/tls/i686/cmov/libc-2.9.so
b805c000-b805e000 r--p 0015c000 08:03 5749       /lib/tls/i686/cmov/libc-2.9.so
b805e000-b805f000 rw-p 0015e000 08:03 5749       /lib/tls/i686/cmov/libc-2.9.so
b805f000-b8062000 rw-p b805f000 00:00 0
b8073000-b8075000 rw-p b8073000 00:00 0
b8075000-b8076000 r-xp b8075000 00:00 0          [vdso]
b8076000-b8092000 r-xp 00000000 08:03 3201       /lib/ld-2.9.so
b8092000-b8093000 r--p 0001b000 08:03 3201       /lib/ld-2.9.so
b8093000-b8094000 rw-p 0001c000 08:03 3201       /lib/ld-2.9.so
bfd7e000-bfd93000 rw-p bffeb000 00:00 0          [stack]
Abort

他壞掉了XDD

另外,依據這個程式功能,我自己寫得是下面這個樣子。在自己寫過一遍之後,我想版上的作者是不是特地為了解釋 buffer overflow 而程式碼寫得那麼複雜!
還是那種寫法有其他特殊需求會用到?

#include 
#include 
#include 

int check(char* pw)
{
    if( strcmp(pw,"666") == 0 ){
        //right!
        return 0;
    }
    else{
        //wrong!
        return 1;
    }
}

int main(int argc, char* argv[])
{
    if( argc < 2 ){
        printf("Usage: %s n", argv[0]);
        exit(0);
    }
    if( check(argv[1]) == 0){
        printf("You are in root now!n");
    }
    else{
        printf("You are not root!n");
    }
}

附上我的環境

> gcc -v
使用內建 specs。
目的:i486-linux-gnu
配置為:../src/configure -v --with-pkgversion='Ubuntu 4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
執行緒模型:posix
gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)
> uname -a
Linux home 2.6.28-11-generic #42-Ubuntu SMP Fri Apr 17 01:57:59 UTC 2009 i686 GNU/Linux

buffer overflow失敗原因可能有:

1. randomized stack

2. ASLR

debian,gcc

剛重新安裝好的 Debian 沒有 gcc ,更新套件來源之後安裝gcc就可以了

  • sudo apt-get install gcc

順便貼一下我用的套件來源位址

deb http://ftp.tw.debian.org/debian/ lenny main
deb-src http://ftp.tw.debian.org/debian/ lenny main
    沒有 gcc 時,嘗試編譯(make etc…)會出現的錯誤訊息

  • no acceptable C compiler found in $PATH

下列的額外套件將被安裝:
  cpp cpp-4.3 gcc-4.3 libgmp3c2 libgomp1 libmpfr1ldbl
建議套件:
  cpp-doc gcc-4.3-locales gcc-multilib make
  manpages-dev autoconf automake1.9
  libtool flex bison gdb gcc-doc gcc-4.3-multilib
  libmudflap0-4.3-dev gcc-4.3-doc libgcc1-dbg
  libgomp1-dbg libmudflap0-dbg
下列【新】套件將會被安裝:
  cpp cpp-4.3 gcc gcc-4.3 libgmp3c2 libgomp1 libmpfr1ldbl

建議把上面紅色的套件也一併裝好,make 通常會用到

gcc_termios.h

使用 gcc3.4.6 編譯時產生以下錯誤

  • warning: #warning “Old BSD tty API used and depends on COMPAT_43TTY. Use termios.h instead"

原因如下:

因為 code 裡面有 include

而 sgtty.h 中 include

在新的版本中sys/ioctl要改用termioctl.h

而且在 sys/ioctl.h 裡面 #define 了 USE_OLD_TTY

在gcc34時沒有沒有對這個definf USE_OLD_TTY作處理

可是gcc4.2這個版本裡面有加上

#ifdef USE_OLD_TTY

#warning “Old BSD tty API used and depends on COMPAT_43TTY. Use termios.h instead"

所以在編譯時跑出一堆警告(即使安裝了gcc3.4也是,因為header版本依然是gcc4.2的header)

結論:不要理他!!