1. 세그먼트
리눅스에서는 프로세스의 메모리를 5가지의 세그먼트로 구분한다. 세그먼트(Segment)란 적재되는 데이터의 용도별로 메모리의 구획을 나눈 것이다. 1)코드 세그먼트, 2)데이터 세그먼트, 3)BSS 세그먼트, 4)힙 세그먼트, 5)스택 세그먼트로 구분한다.

1) 코드 세그먼트(텍스트 세그먼트)
실행 가능한 기계코드가 위치하는 영역이다. 프로그램이 동작하려면 코드를 실행해야 하기 때문에 코드 세그먼트는 읽기 권한과 실행 권한이 부여된다. 쓰기 권한이 있으면 공격자가 악의적인 코드를 삽입하기 쉬워지므로 현대 운영체제에서는 코드 세그먼트에 쓰기 권한을 제거한다.
2) 데이터 세그먼트
컴파일 시점에 값이 정해진 전역 변수 및 전역 상수들이 위치한다. CPU는 데이터 세그먼트의 데이터를 읽을 수 있어야 하므로 읽기 권한이 부여된다. 데이터 세그먼트는 쓰기가 가능한 세그먼트와 쓰기가 불가능한 세그먼트로 다시 분류한다.
(1) 쓰기가 가능한 세그먼트(data 세그먼트) : 전역 변수와 같이 프로그램이 실행되면서 값이 변할 수 있는 데이터들이 위치
(2) 쓰기가 불가능한 세그먼트(rodata(read-only data) 세그먼트) : 프로그램이 실행되면서 값이 변하면 안되는 데이터들이 위치, 즉 전역으로 선언된 상수 또한 포함된다.
3) BSS 세그먼트
컴파일 시점에 값이 정해지지 않은 전역 변수가 위치한다. 선언만 하고 초기화하지 않은 전역변수 등이 포함된다. BSS 세그먼트의 메모리 영역은 프로그램이 시작될 때 모두 0으로 값이 초기화된다. 또한 읽기 권한 및 쓰기 권한이 부여된다.
4) 스택 세그먼트
프로세스의 스택이 위치한다. 함수의 인자나 지역 변수와 같은 임시 변수들이 실행 중에 저장된다. 스택 세그먼트는 스택 프레임(Stack Frame)이라는 단위를 사용한다. 스택 프레임은 함수가 호출될 때 생성되고 반환될 때 해제된다. 그런데 프로그램의 전체 실행 흐름은 사용자의 입력에 영향을 받기 때문에 스택 프레임을 미리 계산하지 않고 작은 크기의 스택 세그먼트를 먼저 할당한 다음, 부족해 질 때마다 확장한다. 스택 세그먼트는 CPU가 자유롭게 값을 읽고 쓸 수 있어야 하므로 읽기 권한과 쓰기 권한이 부여된다.
5) 힙 세그먼트
힙 데이터가 위치한다. 스택과 마찬가지로 실행 중에 동적으로 할당되며 리눅스에서는 스택 세그먼트와 반대 방향으로 자란다. C언어에서 malloc(), calloc() 등을 호출해서 할당받는 메모리가 힙 세그먼트에 위치하며 읽기 권한과 쓰기 권한이 부여된다.
2. 힙과 스택 세그먼트가 반대 방향인 이유
힙과 스택 세그먼트가 동일한 방향으로 되어 있고 연속된 메모리 주소에 할당 되었다고 가정한다면 기존의 힙 세그먼트를 모두 사용하고 나면 확장하는 과정에서 스택 세그먼트와 충돌하게 된다. 이를 해결하기 위해 리눅스는 스택을 메모리 끝에 위치시키고 힙과 반대로 확장되게 하였다. 이러면 메모리를 최대한 사용 가능하며 충돌 문제를 해결할 수 있다.
'개념정리 > System Hacking' 카테고리의 다른 글
5. gdb 디버거 (0) | 2022.07.21 |
---|---|
4-2. 어셈블리(Assembly) - 스택, 프로시저, 시스템콜 (0) | 2022.07.07 |
4-1. 어셈블리(Assembly) - 산술연산, 논리연산, 비교, 분기 (2) | 2022.07.06 |
2. x86-64 아키텍처 (0) | 2022.07.04 |
1. 컴퓨터 아키텍처 (0) | 2022.06.30 |