2023. 9. 11. 10:15ㆍ카테고리 없음
1. 구름 IDE로 리눅스 개발환경 만들기

(1) 소스코드 에디터 창
(2) 코드 수정 후, 저장 실행 버튼

vs code 버튼 누르고, 체크, Yes 버튼 누르기

(1) src폴더 하위에 main.c 있음
(2) 아래 터미널 창 닫기

Ctrl + ` 키를 누르면 vscode의 터미널 창이 열림

리눅스 명령어로 이 터미널 창에서 직접 컴파일 명령어 수행 가능

맨 처음 화면으로 돌아가고 싶으면 왼쪽 상단 서류 가방 아이콘 클릭

마우스 오른쪽 키 누르면 다양한 기능 많음
3. 오버플로 예제를 언더플로로 바꿔서 해보기

char 자료형이 나타낼 수 있는 최소값은 -128인데 거기서 1을 빼면 -129가 될 거라고 생각하지만,
char 자료형이 나타낼 수 있는 범위가 아니다.
언더플로가 되어서 127이 된다.

디버깅

main에 중단점 설정하고 실행함.
original value를 print하는 코드까지 실행하면
10000000가 나오는데, 이 값은 -128을 2진수로 나타낸 것이다.

original value에 1을 뺀 값을 출력하면 1111111이 나온다.
이 값은 127을 2진수로 나타낸 것이다.
127을 8진수로 나타내면 0177이다.
4. 비트 연산 프로그램 바꿔보기

특정 위치의 비트를 끄려면
1. 특정 위치 만큼 1을 시프트 해야 한다. (1 << position)
2. 1에서 만든 수를 NOT 연산으로 비트 반전 시켜야 한다. ~ (1 << position)
3. 비교하고 싶은 수와 AND 연산 해서 원하는 위치 비트만 꺼야 한다. value & ( ~ (1 << position))
만든 함수

전체 코드

실행 결과

3번째 비트가 꺼져서 0이 되었다.
5. c언어가 기계어가 되는 과정 직접 해보기
1. gcc 컴파일러 - 전처리 과정 (.i 파일 확인하기)


$ gcc -E main.c -o main.i // 실행 시 main.i 파일 생성됨
2. gcc 컴파일러 - 전처리 과정 (.s 파일 확인하기)

$ gcc -S main.i -o main.s // 실행 시 main.s 파일 생성됨
3. gcc 컴파일러 - 전처리 과정 (.o 파일 확인하기)

$ gcc -c main.s -o main.o // 실행 시 main.o 파일 생성됨
그런데, 기계어라서 파일 내용이 확인이 안된다.

1. ELF: Executable and Linkable Format. ELF는 유닉스와 유닉스 기반 시스템에서 사용되는 공통 바이너리 파일 포맷은 실행 가능한 프로그램, 오브젝트 파일, 공유 라이브러리 등에 사용
2. 64-bit: 바이너리가 64비트 아키텍처용으로 컴파일 됨
3. LSB: Little Endian 바이트 순서를 사용
4. relocatable: 이 오브젝트 파일은 재배치 가능.
즉, 링커에 의해 다른 오브젝트 파일이나 공유 라이브러리와 연결될 수 있음
5. x86-64: 이 오브젝트 파일은 x86-64 (또는 AMD64) 아키텍처용으로 컴파일됨
6. version 1 (sysV): ELF 포맷의 버전과 변형을 나타냄. SySV는 System V 유닉스를 의미
7. not stripped: “stripped”는 디버깅 정보나 심볼 테이블 등의 추가 정보를 제거한 상태를 의미 not stripped는 이러한 추가 정보가 아직 오브젝트 파일에 포함되어 있음
오브젝트 파일은 소스 코드가 컴파일된 후의 중간 결과물로, 링커에 의해 실행 가능한 바이너리나 라이브러리로 만들어지기 전의 형태입니다.
오브젝트 파일의 주요 특징:
바이너리 형태: 오브젝트 파일은 기계어 코드를 포함하는 바이너리 파일입니다. 그러나 이 파일 자체로는 실행될 수 없습니다. 다른 오브젝트 파일이나 라이브러리와 링크되어야 실행 가능한 바이너리가 됩니다.
재배치 가능: 오브젝트 파일은 다른 오브젝트 파일이나 라이브러리와 링크되어 완전한 프로그램을 형성할 수 있습니다. 이 과정에서 링커는 긱 각의 변수나 함수 참조를 올바른 메모리 주소나 올바른 함수로 연결합니다.
심볼 테이블: 오브젝트 파일에는 심볼 테이블이 포함되어 있습니다. 이는 파일 내의 각 함수나 변수의 이름과 위치 정보를 나타냅니다. 이 테이 블은 링커가 다른 오브젝트 파일이나 라이브러리와 해당 오브젝트 파일을 링크할 때 참조됩니다.
플랫 및 컴파일러 특정: 오브젝트 파일은 특정 아키텍처, 운영 체제, 컴파일러에 따라 다르게 생성될 수 있습니다.
대표적인 오브젝트 파일 확장자로는 UNIX 또는 Linux 시스템에서 .o, Windows에서는 .obj가 있습니다.

readelf:
1.전용 도구: readelf는 ELF 파일 형식에 특화된 도구. ELF 파일의 모든 색션과 헤더 정보를 자세히 확인가능
2.출력 형식: readelf의 출력은 사람이 읽기 쉬운 형식으로 제공
3.주요 기능: ELF 파일의 헤더, 색션 헤더, 프로그램 헤더, 심볼 테이블, 노트 색션 등의 정보를 표시
ELF 헤더는 파일의 전반적인 구조와 특성을 기술한다.

hex editor로 확인 가능하다.

objdump:
1.다기능 도구: objdump는 ELF 파일뿐만 아니라 다른 파일 형식의 바이너리에도 사용 가능
2.딜수어셈블; ppdump의 중요 김능 중 한날는 밤인너리 콘드를 어셈블리 언어로 디스어셈블.
이를 통해 사용자는 바이너리의 기계어 코드를 직접 볼 수 있음
3.다양한 정보: objdump는 바이너리의 헤더 정보, 섹션 내용, 심볼 테이블 등 다양한 정보를 표시. 또한, 바이너리의 공유 라이브러리 의존성, 재배치 정보 등도 확인.
4. gcc 컴파일러 - 링킹 과정


$ gcc main.o -o main// 실행 시 main 파일 생성됨

오브젝트 파일과 실행파일 차이

각 단계에서 파일 크기도 다르다.

Main.o 와 main 의 readelf -a 결과를 보면 다른 점 이 많음 (링킹되면서 다른 파일과 많이 합쳐지고 재배치됨)
Main.o 와 main 의 objdump-d 결과를 봐도 뭐가 많이 생김 (실행에 필요한 함수들)

objdump -d의 결과

gdb 디버거로 확인한 결과 동일함


프로세스 상태 -> 메모리에 올라감 -> 실제 메모리 주소가 잡힘
