2011. 7. 7. 22:09

   



C언어포인터
카테고리 컴퓨터/IT > 프로그래밍/언어 > C
지은이 정재은 (정보문화사, 2003년)
상세보기 [ Down ]

   

[ 책소개 ]

이 책은 포인터와 배열만을 다룬것이 아니라 가벼운 인자, 함수포인터, 함수 인자포인터,

자기 참조 구조체등 C언어의 전반에서 모두 사용되는 포인터를 다루고 있다.

메모리해제에 관한 자세한 해설과 예제등 다양한 실무경험을 통해 터득한 내용들을 쉽게 서술하였다

   

[ 목차 ]

Chapter1 포인터의 기초

1 포인터란 무엇인가? 14

2 포인터 변수 15

3 포인터 변수 정의 15

4 쓰레기 주소 값 17

5 & 연산자 18

6 포인터 변수에 번지 할당 20

7 포인터 변수에 왜 타입을 지정하는가? 27

   

Chapter2 1차원 배열과 포인터

1 1차원 배열과 포인터 32

2 첨자 생략 35

3 다차원 배열 35

4 1차원 배열과 포인터 37

5 포인터 + 정수의 의미 39

6 배열명의 숨은 뜻 44

   

Chapter3 2차원 배열과 포인터

1 이것만 알면 만사 OK 50

2 기본 50

3 배열 포인터 정의 52

4 2차원 배열과 2차원 배열 포인터 변수 연결 53

5 2차원 배열 기본 다지기 56

6 imsip = imsi 60

7 int imsi[2][3]의 모든 것 61

8 함수 인자 포인터 65

9 2차원 포인터 다루기 66

10 2차원 포인터 이것만은 알아두자 72

11 int (*imsi)[2], int *temp[2]의 차이 81

12 *temp[3]에서 temp의 의미는? 86

   

Chapter4 문자열과 포인터

1 문자열이란 무엇인가? 92

2 a, 'a', "a"의 차이 92

3 문자열 포인터 변수 94

4 포인터를 이용한 문자열 조작 96

5 착각하기 쉬운 첨자 98

6 *string과 string[ ]의 차이 99

7 문자열 상수 변경 103

8 문자열과 포인터 배열 106

9 포인터 배열에 문자열 할당 109

   

Chapter5 포인터의 포인터

1 포인터의 포인터는 무엇인가? 118

2 포인터의 포인터 변수 정의 118

3 어디에 사용하는가? 118

4 초기화 119

5 포인터의 포인터 참조 121

6 주의 사항 125

7 주의 사항 하나 더 126

8 명령행 인자 127

   

Chapter6 scanf( )와 fgets( )

1 scanf( )와 fgets( ) 132

   

Chapter7 strcpy( )의 비밀

1 strcpy( )의 함정 140

2 배열을 이용한 strcpy( ) 142

3 포인터 변수를 이용한 strcpy( ) 143

4 배열과 malloc( )을 이용한 번지 할당 146

   

Chapter8 뒤죽박죽 포인터

1 뒤죽박죽 포인터? 150

   

Chapter9 포인터의 개념을 깨는 0

1 의문점 154

2 널 포인터 156

3 주의 사항 157

4 널 포인터의 사용처 157

   

Chapter10 바로 알자 getchar( )

1 getchar( )의 함정 162

   

Chapter11 가변 인자

1 가변 인자란? 166

2 가변 인자 사용 단계 167

3 가변 인자를 위한 매크로 168

4 가변 인자의 사용 169

5 주의 사항 171

   

Chapter12 될 것 같으면서 안 되는 코드

1 초보자들이 무시하는 쓰레기 주소 값 174

   

Chapter13 (int *)pointer

1 캐스트 연산자의 이해 186

   

Chapter14 void형 포인터

1 void형 포인터란? 192

2 void형 변수 포인터 정의 193

3 void형 포인터 변수의 성질 193

4 void형 포인터 변수의 사용 193

5 *((int *)voidp)++ 200

6 주의 사항 203

   

Chapter15 함수 인자 포인터

1 함수 인자 포인터란? 206

2 1차원 함수 인자 포인터 206

3 int형 배열 209

4 문자열 포인터 213

5 1차원 포인터 배열 214

6 2차원 포인터 배열 216

   

Chapter16 함수 포인터

1 함수 포인터의 매력 224

2 함수 포인터의 정의 224

3 함수 포인터의 초기화 225

4 함수 포인터 호출 225

   

Chapter17 구조체와 포인터

1 간단한 구조체 개념 230

2 주소록 230

3 구조체 선언과 정의 231

4 구조체 연산 233

5 구조체와 포인터 234

6 멤버 초기화 236

7 주의 사항 237

8 중첩 구조체 240

9 구조체 복사 242

10 매개변수가 구조체 배열인 함수 245

11 자기 참조 구조체 251

12 리스트 262

   

Chapter18 메모리 할당과 해제

1 동적 메모리 할당 270

2 동적 메모리 할당의 장·단점 272

3 malloc( ) 273

4 가장 간단한 메모리 할당 274

5 동적 메모리 영역 초기화 275

6 할당 가능한 메모리 영역 알아보기 276

7 문자열 포인터 변수를 위한 malloc( ) 277

8 구조체 포인터 변수를 위한 malloc( ) 278

9 calloc( ) 279

10 realloc( ) 281

11 메모리 해제 282

12 간단한 메모리 해제 283

13 리스트의 메모리 해제 283

14 복잡한 메모리 해제 287

   

Chapter19 라이브러리

1 라이브러리란? 296

2 라이브러리의 특징 298

3 ar 298

4 ar 옵션 (/usr/ccs/bin) 299

5 라이브러리 생성 단계 299

 

'Programming > C' 카테고리의 다른 글

The GNU C Library Reference Manual  (0) 2011.09.08
The C Library Reference Guide  (0) 2011.09.08
비트 제어 - 설정, 클리어, 반전, 검사, 추출  (0) 2011.07.29
연산자 우선순위  (0) 2010.05.05
매크로  (0) 2010.05.05
Posted by devanix
2011. 7. 7. 08:33

   


LearningtheviandVimEditors
카테고리 과학/기술>컴퓨터 > OS/운영체제
지은이 Linda Lamb , Arnold Robbins , Elbert Hannah (O'ReillyMedia, 1970년)
상세보기 [ view ]

[ 책소개 ]

There's nothing that hard-core Unix and Linux users are more fanatical

about than their text editor. Editors are the subject of adoration and worship,

or of scorn and ridicule, depending upon whether the topic of discussion is

your editor or someone else's. vi has been the standard editor for close to 30 years.

Popular on Unix and Linux, it has a growing following on Windows systems, too.

Most experienced system administrators cite vi as their tool of choice. And since 1986,

this book has been the guide for vi. However, Unix systems are not what they were 30

years ago, and neither is this book. While retaining all the valuable features of

previous editions, the 7th edition of Learning the vi and Vim Editors has been

expanded to include detailed information on vim, the leading vi clone. Vim is the

default version of vi on most Linux systems and on Mac OS X, and is available for many

other operating systems too. With this guide, you learn text editing basics and advanced

tools for both editors, such as multi-window editing, how to write both interactive

macros and scripts to extend the editor, and power tools for programmers - all in the

easy-to-follow style that has made this book a classic.

   

Posted by devanix
2011. 7. 7. 03:18

   


UNIXNETWORKPROGRAMMINGVOLUME1(제3판) 상세보기


[ 책소개 ]

UNIX NETWORK PROGRAMMING 제3판. 컴퓨터 통신을 전공하거나 현업에서 종사하고 있는 이들에게

도움이 된다. 특히 응용에서 직접 이용할 수 있는 많은 프로그램 예제들을 보여주고 있어 초보자

에게는 문제와 해법을 이해하는 데, 전문가에게는 더욱 효율적인 해법을 모색하는 데 참고가 될 것이다.

   

[ 목차 ]

Part 1. Introduction and TCP/IP

Chapter 1. Introduction and TCP/IP

Chapter 2. The Transport Layer : TCP and UDP, and SCTP

   

Part 2. Elementary Sockets

Chapter 3. Sockets Introduction

Chapter 4. Elementary TCP Sockets

Chapter 5. TCP Client-Server Example

Chapter 6. I/O Multiplexing : The select and poll Functions

Chapter 7. Socket Options

Chapter 8. Elementary UDP Sockets

Chapter 9. Elementary SCTP Sockets

Chapter 10. SCTP Client/Server Example

Chapter 11. Name and Address Conversions

   

Part 3. Advanced Sockets

Chapter 12. IPv4 and IPv6 Interoperability

Chapter 13. Daemon Processes and inetd Superserver

Chapter 14. Advanced I/O Functions

Chapter 15. Unix Domain Protocols

Chapter 16. Nonblocking I/O

Chapter 17. ioctl Operations

Chapter 18. Routing Sockets

Chapter 19. Key Management Sockets

Chapter 20. Broadcasting

Chapter 21. Multicasting

Chapter 22. Advanced UDP Sockets

Chapter 23. Advanced SCTP Sockets

Chapter 24. Out-of-Band Data

Chapter 25. Signal-Driven I/O

Chapter 26. Threads

Chapter 27. IP Options

Chapter 28. Raw Sockets

Chapter 29. Datalink Access

Chapter 30. Client-Server Design Alternatives

Chapter 31. STREAMS

   

Appendix A. IPv4, IPv6, ICMPv4, and ICMPv6

Appendix B. Virtual Networks

Appendix C. Debugging Techniques

Appendix D. Miscellaneous Source Code

 D.1 - unp.h Header.

 D.2 - config.h Header.

 D.3 - Standard Error Functions. 

Appendix E. Solutions to Selected Exercises

 

Posted by devanix
2011. 7. 7. 02:26

   PDF [ view ]
 

리눅스소켓프로그래밍
카테고리 미분류
지은이 웨런 W.게이 (인포북, 2004년)
상세보기

[ 책소개 ]

이 책은 리눅스 소켓 프로그래밍을 사용하는 방법을 가르치고 있다.

또한 네트워크 클라이언트/서버를 작성하는 방법을 "예제로 배우는"방식으로 소켓 프로그래밍에

접근하고 있다. 소켓의 기본 개념부터 다양한 용도의 서버 프로그램을 작성하기 위한 I/O 모델을

포함하여 보안의 개념까지 상당히 넓은 개념을 포함하고 있다.

   

[ 목차 ]

   

Part 1 기본적인 소켓 개념

Chapter 1 소켓의 개요

Chapter 2 도메인과 주소 패밀리

Chapter 3 주소 변환 함수

Chapter 4 소켓 형식과 프로토콜

Chapter 5 주소를 소켓에 바인드하기

Chapter 6 비연결 지향 프로토콜

Chapter 7 클라이언트를 위한 연결 지향 프로토콜

Chapter 8 서버를 위한 연결 지향 프로토콜

Chapter 9 호스트 이름과 네트워크 이름 조회

   

Part 2 고급 소켓 프로그래밍

Chapter 10 소켓에 표준 I/O 사용하기

Chapter 11 동시 클라이언트 서버

Chapter 12 소켓 옵션

Chapter 13 UDP를 사용하여 브로드캐스트하기

Chapter 14 Out-of-Band 데이터

Chapter 15 inetd 데몬 사용하기

Chapter 16 네트워크 보안 프로그래밍

Chapter 17 자격 증명(credential)과 파일 설명자 전달하기

Chapter 18 실제 네트워크 프로젝트

   

Part 3 부록

Appendix A 소켓 함수 요약 참조

Appendix B 소켓 관련 구조체 참조

Appendix C 유용한 네트워크 표

   

Posted by devanix
2011. 7. 7. 01:23



TCP/IP네트워크(TCP/IPILLUSTRATEDVOLUME1)
카테고리 컴퓨터/IT > 네트워크/보안 > TCP/IP
지은이 W.RICHARD STEVENS (진영사, 1998년)
상세보기


[ 책소개 ]

TCP /IP에 대한 기본적인 개요를 시작으로 표준화 작업과정,표준적인 단순 서비스,응용 프로그램

인터 페이스,링크 계층, 인터넷 프로토콜,주소 변환 프로토콜, 인터넷 제어 메시지 프로토콜, Ping 프로그램,

IP라우팅 등을 총 30장에 걸쳐 상세히 해설한 저서.

   

[ 목차 ]

001. 서론

002. 링크 계층

003. 인터넷 프로토콜

004. 주소 변환 프로토콜(ARP: Address Resolution Protocol)

005. 역주소 변환 프로토콜

006. 인터넷 제어 메시지 프로토콜

007. Ping 프로그램

008. Trscetoute 프로그램

009. IP 라우팅

010. 동적(Dynamic) 라우팅 프로토콜

011. UDP: 사용자 데이터그램 프로토콜

012. 브로드 캐스팅과 멀티 캐스팅

013. IGMP: 인터넷 그룹 관리 프로토콜

014. DNS: 도메인 이름 시스템

015. Trivial 파일 전송 프로토콜

016. BOOTP: Bootstrap 프로토콜

017. TCP: 전송 제어 프로토콜

018. TCP 연결 확립과 종료

019. TCP 대화식 데이터 흐름

020. TCP 대용량 데이터 흐름

021. TCP 타임아웃과 재전송

022. TCP 지속 타이머

023. TCP 유지 타이머

024. 그 밖의 TCP 기능과 성능

025. SNMP: 단순 네트워크 관리 프로토콜

026. telnet & Rlogin: 원격 로그인

027. FTP: 파일 전송 프로토콜

028. SMTP: 단순 전자우편 전송 프로토콜

029. NFS: 네트워크 파일 시스템

030. 그 밖의 TCP/IP 응용 프로그램

 

Posted by devanix
2011. 7. 6. 23:28



TCP/IP네트워크실험프로그래밍
카테고리 컴퓨터/IT > 네트워크/보안 > TCP/IP
지은이 무라야마 유키오 (성안당, 2005년)
상세보기

[ 책소개 ]

네트워크 프로그램을 통해 TCP/IP 프로토콜의 구조와 원리를 배우도록 구성되었다.

프로토콜의 특성이나 문제점, 운용 시에 주의해야 할 점을 경험할 수 있는 흥미로운 실험과

프로그램이 수록되어 있다. 

   

재미있게 네트워크 실험을 할 수 있도록 TCP/IP 프로토콜의 시큐리티적인 약점을 들추는 것 같은 
자극적인 프로그램이 몇 가지 포함되어 있다. 예를 들면, 특정 호스트를 통신 불능으로 만들어
버리는 
프로그램이나 TCP의 커넥션을 아예 없애는 그런 프로그램도 있다. 

   

또한 이들 프로그램을 효과적으로 이용하기 위해서 Ethernet의 패킷을 모니터링하고, 헤더의 구조를 잘 알 수 있는 형식으로 표시하는 소프트웨어도 실었다. 이 패킷 모니터링 툴을 사용하면서 실험해 봄으로써 프로토콜이나 패킷 헤더에 관한 이해를 한층 깊게 할 수 있을 것이다.

   

[ 목차 ]

제1장 TCP/IP 프로토콜 스택 입문 

1.1 TCP/IP 프로토콜과 프로토콜 스택의 기초 

1.2 프로토콜 스택 자세히 알아보기 

1.3 프로토콜 스택의 실현 방법 

   

제2장 TCP/IP 프로토콜과 헤더의 구조 

2.1 프로토콜 헤더와 구조체 

2.2 Ethernet 

2.3 ARP(Address Resolution Protocol) 

2.4 IP(Internet Protocol) 

2.5 ICMP(Internet Control Message Protocol) 

2.6 UDP(User Datagram Protocol) 

2.7 TCP(Transmission Control Protocol) 

2.8 체크섬 

   

제3장 소켓 

3.1 소켓의 개요 

3.2 소켓에 사용되는 구조체 

3.3 소켓 시스템 콜에 따른 처리의 흐름 

3.4 소켓 시스템 콜 자세히 알아보기 

3.5 UDP에 의한 통신 

3.6 TCP에 의한 통신 

   

제4장 패킷 모니터링 실험

4.1 패킷 모니터링의 기초 지식 

4.2 데이터 링크 액세스 인터페이스 

4.3 패킷 모니터링 프로그램 

   

제5장 TCP/IP 통신의 식별 

5.1 IP 어드레스와 포트 번호 

5.2 호스트 스캔 프로그램 

5.3 TCP 포트 스캔 프로그램 

5.4 UDP 포트 스캔 프로그램 

   

제6장 ARP의 실험 

6.1 ARP란 

6.2 ARP를 사용한 실험 프로그램 

   

제7장 IP와 ICMP의 실험 

7.1 라우팅 테이블과 경로 제어 

7.2 redirect 프로그램 

7.3 scanroute 프로그램 

   

제8장 TCP의 실험 

8.1 TCP란 

8.2 TCP SYN 프로그램 

8.3 TCP RST 프로그램 

8.4 TCP JACK 프로그램 

   

제9장 IPv6에 의한 통신 실험 

9.1 IPv6란 

9.2 IPv6를 사용한 실험 프로그램

   


Posted by devanix
2011. 7. 5. 17:57

[ 빌트인 함수 ]

♧ gcc에는 표준 라이브러리에 있을 듯한 몇몇 함수가 빌트인 함수로 마련되어 있음.

최적화 방법에 따라 소스에 쓰인 것과 다른 코드를 생성할 경우 있다.

   

▷ 예를 들면 printf(3) 함수의 경우 다음과 같이 문자열을 출력하는 코드에서는 실행할 때

pirntf(3)의 형식 문자열을 해석할 수 없으므로 다음과 같이 puts(3)를 호출하는 코드를 생성.

▷ 기본적으로는 같은 동작을 하고 더 빠르게 실행될 듯한 코드가 생성되어 문제는 없으나,

LD_PRELOAD 등으로 오버라이드(override)해서 동작을 변경하고자 할 경우에는 주의 할

필요가 있다. 최적화를 통해 어떤 코드가 생성되는지 gcc/builtins.c에 프로그램 되어 있다.

   

void *__builtin_return_address (unsigned int LEVEL)

→ 함수의 리턴 주소, 즉 함수를 호출한 지점의 주소를 반환.

매개변수 LEVEL은 호출 지점을 몇 번 거슬러 올라갈지를 정수로 지정하는데

통상 0(현재 함수)을 지정. 일반적으로 x86인 경우 %ebp + 4에 해당하는 포인터 값이 됨

   

void *__builtin_frame_address (unsigned int LEVEL)

→ 함수의 프레임 포인터(지역 변수나 레지스터 저장영역을 가리키는 포인터)를 반환.

매개변수 LEVEL은 호출 지점을 몇 번 거술러 올라갈지를 정수로 지정하는데

통상 0(현재 함수)을 지정. 일반적으로 X86인 경우 %ebp 가 된다.

   

int __builtin_types_compatible_p (TYPE1, TYPE2)

→ 매개변수 TYPE1과 TYPE2가 서로 호환성이 있는지를 검사.

일반적으로 매크로를 이용해 타입에 맞는 적당한 함수로 dispatch할 때 사용.

   

TYPE __builtin_choose_expr (CONST _EXP, EXP1, EXP2)

→ 이 함수는 CONST_EXT? EXT1 : EXT2와 동일한 기능을 하지만, 컴파일할 때 결정.

__builtin_types_compatible_p를 매개변수 CONST _EXP로 사용해서 적당한 함수호출을

선택하는 형태의 매크로를 작성할 때 사용.

   

int __builtin_constant_p (EXP)

→ 매개변수 EXP가 정수인지를 판정.

인수가 정수임을 알았을 때 최적화된 코드를 선택하는 편이 더 좋을 경우에 사용.

   

long __builtin_expect (long EXP, long C)

→ 매개변수 EXP의 값이 매개변수 C값이 될 경우가 많을 것이라는 판단의 근거로,

분기를 최적화하고자 할 경우에 사용.

   

long __builtin_prefetch (const void *ADDR, int RW, int LOCALITY)

→ 매개변수 ADDR에 있는 데이터를 캐시에 prefetch하고자 할 경우 사용한다.

매개변수 RW가 1일 경우는 가까운 곳에 기록할 내용이 있음을,

0일 경우는 가까운 곳에 읽어야 할 내용이 있음을 나타낸다.

매개변수 LOCALITY는 0~3사이 값으로 0은 사용하면 바로 불필요한 데이터,

3은 사용하기 시작하면 당분간 계속 사용할 데이터임을 나타냄.

  

   

[ 애트리뷰트 (__attribute__) ]

♧ 함수에 애트리뷰트를 덧붙여 선언하면

함수에 특별한 의미를 부여하거나 함수호출을 최적화 할 수 있다.

   

▶ 애트리뷰트 선언 2가지 방법

① int foo(int n) __attribute__((애트리뷰트));

int foo(int n) { … }

   

② __attribute__((애트리뷰트)) int foo(int n) { … }

   

▶ 함수에 관한 애트리뷰트에는 다음과 같은 것들이 있다.

attribute

설명

constructor

main 함수가 호출되기 전이나 공유 오브젝트가 로드 되었을 때

실행해야 하는 함수에 사용.

destructor

exit하기 전이나 공유 오브젝트가 언로드 되기 직전에

실행해야 하는 함수에 사용.

cleanup

auto 변수가 주어진 영역에서 벗어나 없어질 때 호출되는 함수를 지정.

section

특정 섹션에 코드를 배치.

used

어디에서도 호출하지 않는 경우에도 코드를 반드시 생성.

어셈블러 코드에서 호출되는 경우에 사용.

weak

weak 심볼인 코드를 생성

alias

다른 심볼의 별칭(앨리어스)을 지정. 통상 weak와 함께 사용

visibility

심볼의 가시성을 제어하기 위해 사용.

'default', 'hidden' (공유 객체 밖에서는 볼 수 없음),

'protected'(공유 객체 내에서 호출할 때는 LD_PRELOAD로도

오버라이드 되지 않음) , 'initernal' (함수 포인터 등을 포함한 객체

외부에서의 호출을 수행하지 않음) 등...

stdcall

x86 호출 규약 중 하나.

매개변수에 사용한 스택을 호출된 쪽에서 pop하는 경우 사용.

sdecl

x86 호출 규약 중 하나.

매개변수에 사용한 스택을 호출한 쪽에서 pop하는 경우 사용.

fastcall

x86 호출 규약 중 하나. 처음 두 매개변수를 %ecx, %edx를 이용해 호출

regparm

레지스터에 전달할 매개변수의 개수를 제어.

vector_size

변수의 벡터 크기를 지정.

dllimport

MS 윈도우의 dllimport.

dllexport

MS 윈도우의 dllexport

pure

전역 변수와 매개변수에 따라서만 반환 값이 결정되고 부작용이 없는 경우에

사용된다. 경우에 따라서는 불필요한 호출을 생략할 경우가 있다.

const

매개변수만으로 반환 값이 결정되고 부작용이 없는 경우에 사용.

malloc

NULL 외의 반환 값이 다른 포인터와 공유되지 않은 경우에 사용.

noreturn

exit(2)와 같이 반환되지 않는 함수에 사용.

noinline

인라인 전개되기를 원하지 않는 경우에 사용.

always_inline

최적화 레벨이 낮아도 인라인 전개한다.

nothrow

예외를 throw 하지 않는 경우 사용.

format

형식 문자열이 printf, scanf, strftime, strfmon 중

어떤 스타일과 같은지를 가리키는 것으로,

형식 문자열과 가변 매개변수 간 대응을 검사하게 된다.

format_arg

어떤 매개변수가 형식 문자열인지를 가리킨다.

nonnull

NULL이 될 수 없는 포인터 매개변수를 가리킨다.

unused

사용하지 않을 경우에도 경고를 출력하지 않는다.

deprecated

사용될 경우에 경고를 출력.

warn_unused_result

반환 값을 검사하지 않을 때 경고를 출력.

no_instrument_function

-finstrument-functions인 경우에도

프로파일 함수를 호출하지 않도록 한다.

데이터에 관한 애트리뷰트 

aligned

변수 영역의 정렬을 제어.

packed

구조체 내부에 정렬에 의한 채우기(padding)를 최소화 한다.

common

변수를 common 영역에 배치.

nocommon

변수를 common 영역에 배치하지 않는다.

shared

DLL을 사용한 프로세스 전체로 공유된 매개변수에 사용.

  

   

   

[ 레이블(label) 참조 ]

♧ C에서는 그다지 사용되지 않지만 goto로 점프할 위치를 지정할 때 레이블을 사용.

goto error

……

error:

/* 에러 처리 */

   

▷ GCC에서 레이블은 &&로 참조하고 void *형 함수에 대입할 수 있다.

void * label;

label = &&error;

……

goto *label;

……

error:

이와 같이 레이블을 변수에 대입할 수 있기 때문에 변수 값에 따라 점프할 위치를 변경하도록

하는 코드는 레이블로의 참조를 요소로 갖는 배열로도 구현할 수 있다.

레이블을 &&로 참조한 값은 void *에 대입할 수 있는 포인터형이므로 뺄셈으로 오프셋을

얻을 수 있다. 따라서 다음과 같은 코드를 작성할 수 있다.

static int labals[] = { &&labal0 - &&label0, &&label1 - &&label0, ...};

goto * (&&labal0 + labels[ i]);


label0:

label1:

  

   

[ 정리 ]

GCC는 C99표준에 준거하도록 노력하는 한편, 소스코드를 기술하기 쉽도록 하기 위한

확장 기능을 제공하고 있다. GCC의 확장기능임을 이해한 후 이 기능을 사용하면 편리한

경우가 있다. 예를 들면 리눅스 커널에는 GCC확장 기능을 이용한 코드를 볼 수 있다.

이러한 코드를 파악하려 할 경우에는 GCC 확장기능에 대한 이해가 필수적이다.

Posted by devanix
2011. 7. 5. 03:55

♧ 통상 GNU/리눅스의 공유 라이브러리를 만들 때는

각각의 .C 파일을 PIC(Position Independent Code)가 되도록 컴파일 한다.

그러나 실은 PIC로 컴파일 하지 안아도 공유 라이브러리는 만들 수 있다.

그러면 굳이 PIC로 컴파일 하는 이유가 있는 것일까?

   

▶ fpic.c 작성

#include <stdio.h>

void func() {

printf("");

printf("");

printf("");

}

   

PIC로 컴파일하기 위해 gcc -fpic 또는 fPIC 옵션을 지정한다.

-fpic :: 좀더 고속으로 코드를 생성할 가능성이 있지만,

CPU에 따라 -fpic로 생성할 수 있는 GOT(Glocal Offset Table)의 크기에 제한이 있다.

-fPIC :: CPU에 관계없이 사용할 수 있다. 여기서는 -fPIC를 사용한다.

(※ x86에서는 -fpic와 -fPIC가 동일)

   

% gcc -o fpic-no-pic.s -S fpic.c

% gcc -fPIC -o fpic-pic.s -S fpic.c

위와 같이 생성된 어셈블리어의 소스코드를 보면 PIC 버전은 printf를

PLT(Procedure Linkage Table)를 경유해서 호출하는 것을 알 수 있다.

(※ 우분투 7.04에서 테스트)

   

다음에는 공유 라이브러리를 만든다.

% gcc -shared -o fpic-no-pic.so fpic.c

% gcc -shared -fPIC -o fpic-pic.so fpic.c

   

▷ 위 공유 라이브러리의 동적 섹션(dynamic section)을 readelf 명령으로 보면,

비 PIC공유 라이브러리에서는 TEXTREL 이라는 엔트리가 있고 (텍스트 내의 재배치 필요),

RELCOUNT(재배치 수)가 5로, PIC 공유 라이브러리보다 3만큼 크다.

그 이유는 printf()3회 호출하기 때문이다.

   

PIC 공유 라이브러리에서의 RELCOUNT0이 아닌 이유는 gcc가 기본적으로 사용하는

시작 파일에 포함된 코드 때문이다. gcc에 -nostartfiles 옵션을 지정하면 이 값은 0이 된다.

   

[ PIC와 비 PIC 공유 라이브러리의 성능 비교 ]

♧ 위 예에서는 비 PIC 버전은 실행 시에(동적 링크 시에) 5개의 주소가

재배치 되어야 한다고 했다. 그러면 재배치 수가 매우 커지면 어떻게 될 것인가?

   

공유 라이브버리를 PIC버전과 비 PIC버전printf()를 천만 번 호출 ( 셸 스크립트로 실행 비교)

▶ 다음 셸 스크립트를 실행하면 printf()를 천만 번 호출하는 공유 라이브러리를

비 PIC버전과 PIC 버전으로 만들고, 각각을 링크한 실행 파일 fpic-no-pic와 fpic-pic를 생성.

#! /bin/sh

rm -f *.o *.so

num=1000

for i in `seq $num`; do

echo "void func$i() { " > fpic$i.c

ruby -e "10000.times { puts 'printf(\"\");' }" >> fpic$i.c

echo "} " >> fpic$i.c

gcc -o fpic-no-pic$i.o -c fpic$i.c

gcc -fPIC -o fpic-pic$i.0 -c fpic$i.c

done

gcc -o fpic-no-pic.so -shared fpic-no-pic*.o

gcc -o fpic-pic.so -shared fpic-pic*.o

echo "int main() { return 0; }" > fpic-main.c

gcc -o fpic-no-pic fpic-main.c ./fpic-no-pic.so

gcc -o fpic-pic fpic-main.c ./fpic-pic.so

   

비 PIC 버전이 첫 회 2.15초, 두 번째 이후에는 약 0.55초가 걸리고,

% repeat 3 time ./fpic-no-pic

2.15s total : 0.29s user 0.48s system 35% cpu

0.56s total : 0.25s user 0.31s system 99% cpu

0.55s total : 0.30s user 0.25s system 99% cpu

   

PIC 버전은 최초 0.02초, 두 번째 이후에는 0.00초가 되었다.

% repeat 3 time ./fpic-no-pic

2.15s total : 0.29s user 0.48s system 35% cpu

0.56s total : 0.25s user 0.31s system 99% cpu

0.55s total : 0.30s user 0.25s system 99% cpu

   

☞ main()의 내용은 없으므로 비 PIC 버전은 동적 링크할 때

재배치에 2.15 ~ 0.55초를 필요로 함을 알 수 있다.

실행 환경은 Xeon 2.8GHz + Debian GNU/리눅스 sarge + GCC 3.3.5이다.

   

▷ 비 PIC 버전의 단점은 실행할 때 재배치에 시간이 걸린다는 점만이 아니다.

재배치가 필요한 부분의 코드를 재작성 하기 위해

『텍스트 섹션 내의 재배치가 필요한 페이지를 로드 → 재작성

→ copy on write 발생 → 다른 프로세스와 텍스트를 공유할 수 없음』

이라는 사태가 발생. 즉, 여기서는 텍스트(프로그램 코드)를 다른 프로세스와

공유할 수 있는 『공유』라이브러리의 주요한 장점이 사라지고 만다.

   

한편, 비 PIC 버전의 fpic-no-pic.so 와 PIC 버전의 fpic-pic.so 파일 크기를 비교하면,

전자는 268MB, 후자는 134MB로 크게 차이가 난다. readelf -S로 섹션 데이터를 보면

다음과 같은 차이가 있다.

   

컴파일러

.rel.dyn

.text

비 PIC

152MB

114MB

PIC

0MB

133MB

비 PIC 버전은 코드(.text) 크기는 PIC 버전보다 작지만, 재배치에 필요한 정보(.rel.dyn)가

상당한 용량을 차지.

   

[ 정리 ]

여기서는 공유 라이브러리를 작성할 때 PIC로 컴파일 해야 하는 필요성에 대해 알아보았다.

비 PIC 공유 라이브러리를 작성할 수는 있지만 실행할 때 재배치에 시간이 소요되고 다른

프로세스와 코드(.text)를 공유할 수 없는 커다란 단점이 있다. 따라서 공유 라이브러리를

작성할 때는 .c 파일을 PIC로 컴파일 하도록 한다.

 

Posted by devanix