Egloos | Log-in
F/OSS study
F/OSS study
[global] global을 통한 gcc 소스 코드 분석
global : 5.7.5


global은 ctags, cscope와 같이 소스 코드를 분석하여 태그를 작성해 주는 도구이다.
(보통 ctags나 cscope은 많이 사용하고 있지만 global은 그리 널리 알려지지 않은 것 같다.)

global은 ctags와 cscope을 섞어놓은 듯한 특징을 가지고 있는데
cscope에서는 가능하지만 ctags에서는 지원하지 않는 reference 검색이 가능하고
ctags 보다는 훨씬 적지만 (C/C++ 밖에는 지원하지 않는 cscope에 비해 많은..;;)
Java, PHP, Yacc 등의 언어도 지원한다는 장점이 있다.

그리고 경로에 따라 태그 파일을 자동으로 인식하여
별다른 설정 없이도 간단하게 사용할 수 있다는 것도 장점이다.

그래서 현재는 거의 global을 이용하고 있는데
최근 GCC 소스를 분석하기 위해 사용하다 보니 의외로 찾지 못하는 심볼들이 많이 나타났다.
(참고로 ctags/cscope 등에서는 잘 찾는 것 같았다..;;)

문제가 되는 부분은 다음과 같이 선언부에 GTY 옵션을 사용한 것들이었다.

struct function GTY(())
{
  ...
}

이 경우 struct 다음에 이름(identifier)이 오고 그 다음에 '{' 가 와야하는
규칙에 벗어나기 때문에 이를 인식하지 않고 무시했던 것이 원인이었다.

이 경우 단순히 GTY((...)) 부분을 무시하면 해결될 문제이므로
global 소스를 변경해 보기로 마음먹었다..!

global에서 태그 파일을 생성하는 명령은 gtags이며
gtags는 gtags-parser 명령을 출력을 받아서 처리하는 것이므로
실제로는 gtags-parser의 소스를 변경하면 될 것 같다.

살펴보니 gtags-parser에서 C 소스 파일의 파싱을 처리하는 부분은 C.c 파일에 있었다.
이 파일 내의 C_family() 함수에는 다음과 같이 부분이 있다.

        case C_STRUCT:
        case C_ENUM:
        case C_UNION:
            c = nexttoken(interested, c_reserved_word);
            if (c == SYMBOL) {
                if (peekc(0) == '{') /* } */ {
                    if (target == DEF)
                        PUT(token, lineno, sp);

현재 토큰이 struct 혹은 enum 혹은 union 인 경우 다음 토큰을 받고
다음 토큰이 심볼 타입인 경우 이는 해당 자료형의 이름(태그)이 되므로
그 다음에 오는 토큰이 '{' 인 경우에 토큰 정보를 기록(PUT)하는 것이다.
(target이 DEF인 경우는 definition을 찾고 있는 경우를 의미한다.)

즉 여기서 GTY 인 경우를 건너뛰게 하면 문제가 해결될 것 같다.
GTY를 그냥 심볼 타입으로 두고 검사를 해도 되겠지만
GTY는 다른 곳에서도 쓰이므로 키워드로 등록해두고 처리하는 것이 더 좋을 듯 싶다.

global에서 C 언어에 대한 키워드를 등록하려면 gperf를 이용한다.
(gperf는 주어진 키 집합에 대한 perfect hash function을 생성해주는 프로그램이다.)

먼저 gtags-parser/c_res.in 파일을 열고 C reserved word list의 맨 마지막에 다음을 추가한다.

GTY         word

그리고 다음 명령들을 수행한다.

namhyung@NHK-XNOTE:~/global-5.7.5/gtags-parser$ ./reserved.pl --prefix=c c_res.in > c_res.gpf
namhyung@NHK-XNOTE:~/global-5.7.5/gtags-parser$ gperf $(./reserved.pl --prefix=c --option) c_res.gpf > c_res.h

이제 소스 파일에서 C_GTY 라는 타입의 토큰을 사용할 수 있게 되었다.
위에서 살펴본 C_family() 함수의 해당 부분을 다음과 같이 수정하면 된다.

        case C_STRUCT:
        case C_ENUM:
        case C_UNION:
            c = nexttoken(interested, c_reserved_word);
            if (c == SYMBOL) {
                if (target == DEF) {
                    if (peekc(0) == '{') /* } */ {
                        PUT(token, lineno, sp);
                    } else if (peekc(0) == 'G') {
                        /* it should be GTY((...)) option */
                        PUT(token, lineno, sp);
                       
                        c = nexttoken(interested, c_reserved_word);
                        if (c == C_GTY) {
                            process_GTY(target);
                        } else {
                            pushbacktoken();
                        }
                    }

위에서 peekc(0)로 토큰의 첫번째 문자만 확인하지 않고
nexttoken을 직접 받아서 C_GTY인지 검사할 수도 있지만
그러면 PUT 작업 시 자료형의 이름이 아닌 'GTY'라는 이름 자체가 등록되므로
그냥 peekc(0)를 이용하기로 하였다.

그리고 밑에 추가한 process_GTY() 함수는 다음과 같이 단지 () 사이의 것들을 무시한다.

static void
process_GTY(int target)
{
    int brace = 0;
    int c;
   
    /* Skip '...' in GTY((...)) */
    while ((c = nexttoken("()", c_reserved_word)) != EOF) {
        if (c == '(')
            brace++;
        else if (c == ')')
            brace--;
        else
            /* just ignore it */;

        if (brace == 0)
            break;
    }
}

이제 make && sudo make install 하면 수정된 gtags/global을 이용할 수 있다.
위에서 찾지 못한 구조체의 정의를 이제 찾을 수 있다.. ^^

namhyung@NHK-XNOTE:~/study/gcc-4.4.0/srcdir$ global -x function
function          471 gcc/function.h   struct function GTY(())


by namhyung | 2009/07/05 22:52 | Application | 트랙백(1) | 덧글(2)
트랙백 주소 : http://studyfoss.egloos.com/tb/5032090
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from F/OSS study at 2011/02/25 11:17

제목 : [global] 리눅스 커널 소스 분석을 위한 gl..
global: 5.9.3 이전 글 보기: [global] global을 통한 gcc 소스 코드 분석 최근 리눅스 커널 소스 분석을 위해서 global을 이용하고 있다. 얼마전에 다시 홈페이지를 방문해보니 버전 5.8과 5.9를 거쳐 많은 성능 향상이 이루어 진 듯 하여 우분투에서 제공하는 패키지 대신 직접 빌드해서 쓰고 있다. (그러고보니 gcc 코드 살펴볼 때도 GTY 문제 때문에 소스 받아다가 수정해서 쓰긴 했었다..) 하지......more

Commented by namhyung at 2009/07/12 23:58
쓰다보니 결정적인 문제 한 가지를 발견했다. 바로 변수에 대한 정의는 못 찾는다는 것이다.. ;; 물론 symbol 검색 기능으로 찾아볼 수는 있지만, 정의를 바로 찾아주는 것이 아니라서 조금 불편하다. 흠..
Commented by 홍성빈 at 2014/04/25 20:18
안녕하세요 멘토님!!!
이..이런 걸 하셨었군요!!!

:         :

:

비공개 덧글

◀ 이전 페이지 다음 페이지 ▶

카테고리
General
Application
System
Kernel
Book
Tips
태그
memory SMP CAaQA3 documentation blktrace kernel compiler block-layer scm elf CARM perf binutils synchronization patch gcc C linux sed awk glibc git script algorithm build x86 bash computer-architecture vcs emacs
전체보기
이글루 파인더

최근 등록된 덧글
http://serbaserbiinfoterkini56..
by cakra at 09/22
informsi yang bagus dan b..
by cakra at 09/16
informsi yang bagus dan be..
by pordanaia at 08/05
최근 등록된 트랙백
Tod's Ferrari Homme
by Tods Pas Cher,Kodak did ..
Mocassin Femme
by Mocassins Homme, I got so..
natural garcinia cambogia
by
rss

skin by jiinny


X