2.5. RHEL 7 이후 툴체인의 변경
다음 섹션에서는 Red Hat Enterprise Linux 7에 설명된 구성 요소의 릴리스 이후 툴체인의 변경 사항을 나열합니다. Red Hat Enterprise Linux 8.0의 릴리스 노트 를 참조하십시오.
2.5.1. RHEL 8 GCC의 변경 사항
Red Hat Enterprise Linux 8에서 GCC 툴체인은 GCC 8.2 릴리스 시리즈를 기반으로 합니다. Red Hat Enterprise Linux 7 이후 주요 변경 사항은 다음과 같습니다.
- 별칭 분석, 벡터라이저 개선, 동일한 코드 접기, 절차 간 분석, 저장 최적화 패스 등의 다양한 일반적인 최적화가 추가되었습니다.
- Address Sanitizer가 개선되었습니다.
- 메모리 누수를 감지하기 위한 Leak Sanitizer가 추가되었습니다.
- 정의되지 않은 동작의 탐지를 위한 Undefined Behavior Sanitizer가 추가되었습니다.
- 이제 DWARF5 형식으로 디버그 정보를 생성할 수 있습니다. 이 기능은 실험적입니다.
- 소스 코드 적용 범위 분석 도구 GCOV가 다양한 개선 사항으로 확장되었습니다.
- OpenMP 4.5 사양에 대한 지원이 추가되었습니다. 또한 OpenMP 4.0 사양의 오프로드 기능은 이제 C, C++ 및 Fortran 컴파일러에서 지원됩니다.
- 가능한 특정 프로그래밍 오류를 정적 감지하기 위해 새로운 경고 및 개선된 진단이 추가되었습니다.
- 이제 소스 위치가 포인트 대신 범위로 추적되어 훨씬 더 풍부한 진단이 가능합니다. 컴파일러는 이제 "fix-it" 힌트를 제공하여 가능한 코드 수정 사항을 제안합니다. 대체 이름을 제공하고 오타를 쉽게 감지하기 위해 맞춤법 검사기가 추가되었습니다.
보안
GCC는 생성된 코드를 추가로 강화할 수 있도록 툴을 제공하도록 확장되었습니다.
자세한 내용은 2.5.2절. “RHEL 8 GCC의 보안 개선 사항” 의 내용을 참조하십시오.
아키텍처 및 프로세서 지원
아키텍처 및 프로세서 지원 개선 사항은 다음과 같습니다.
- Intel AVX-512 아키텍처, 많은 마이크로 아키텍처 및 Intel SGX(Software Guard Extensions)에 대한 여러 가지 새로운 아키텍처별 옵션이 추가되었습니다.
- 코드 생성은 64비트 ARM 아키텍처 LSE 확장, ARMv8.2-A 16비트 부동 소수점 확장(FPE) 및 ARMv8.2-A, ARMv8.3-A, ARMv8.4-A 아키텍처 버전을 대상으로 할 수 있습니다.
-
ARM 및 64비트 ARM 아키텍처에서
-march=native
옵션 처리가 수정되었습니다. - 64비트 IBM Z 아키텍처의 z13 및 z14 프로세서에 대한 지원이 추가되었습니다.
언어 및 표준
언어 및 표준과 관련된 주요 변경 사항은 다음과 같습니다.
- C 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장으로 C17로 변경되었습니다.
- C++ 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장과 함께 C++14로 변경되었습니다.
- C++ 런타임 라이브러리는 이제 C++11 및 C++14 표준을 지원합니다.
-
C++ 컴파일러는 이제 변수 템플릿과 같은 많은 새로운 기능을 사용하고, 비정적 데이터 멤버 초기화기, 확장된
constexpr
, 크기 조정된 거래 할당 함수, 일반 lambdas, 변수 길이 배열 및 숫자 구분 기호 등의 많은 새로운 기능을 통해 C++14 표준을 구현합니다. - C 언어 표준 C11에 대한 지원이 향상되었습니다. ISO C11 원자성, 일반 선택 및 스레드 로컬 스토리지를 사용할 수 있습니다.
-
새로운
__auto_type
GNU C 확장은 C 언어에서 C++11auto
키워드의 기능 하위 집합을 제공합니다. -
ISO/EC TS 18661-3:2015 표준에 지정된
_FloatN
및 _FloatNx -
C 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장으로 C17로 변경되었습니다. 이는
--std=gnu17
옵션을 사용하는 것과 동일한 효과가 있습니다. 이전에는 GNU 확장이 포함된 기본값은 C89였습니다. - GCC는 이제 C++17 언어 표준 및 C++20 표준의 특정 기능을 사용하여 코드를 실험적으로 컴파일할 수 있습니다.
- 이제 플랫폼 ABI에 필요한 대로 빈 클래스를 인수로 전달하면 Intel 64 및 AMD64 아키텍처 공간이 필요하지 않습니다. 삭제된 복사본만 있는 클래스를 전달하거나 반환합니다. 이제 생성자가 아닌 복사본 또는 이동 생성자가 있는 클래스와 동일한 호출 규칙을 사용합니다.
-
C++11
alignof
연산자가 반환한 값이 C_Alignof
연산자와 일치하도록 수정되었으며 최소 정렬을 반환합니다. 선호하는 정렬을 찾으려면 GNU 확장__alignof__
를 사용합니다. -
Fortran 언어 코드에 대한
libgfortran
라이브러리의 주요 버전이 5로 변경되었습니다. - Ada(GNAT), GCC Go 및 Objective C/C++ 언어에 대한 지원이 제거되었습니다. Go 코드 개발을 위해 Go Toolset을 사용합니다.
2.5.2. RHEL 8 GCC의 보안 개선 사항
다음은 보안과 관련된 GCC 변경 사항이며 Red Hat Enterprise Linux 7.0 릴리스 이후 추가됩니다.
새 경고
이러한 경고 옵션이 추가되었습니다.
옵션 | 에 대한 경고 표시 |
---|---|
|
|
|
인증되지 않은 클래스 유형의 개체는 경고는 사용자 정의 생성자 또는 복사 할당 연산자를 우회하는 호출을 탐지하는 데 도움이 되며, 손상된 가상 테이블 포인터, const-qualified 형식 또는 참조의 데이터 구성원 또는 멤버 포인터를 감지하는 데 도움이 됩니다. 경고는 데이터 멤버에 대한 액세스 제어를 바이패스하는 호출도 탐지합니다. |
| 코드의 들여쓰기가 코드 블록 구조에 대한 잘못된 아이디어를 사람 리더에게 제공하는 위치를 배치합니다. |
|
할당할 메모리 양이 크기를 초과하는 메모리 할당 함수 호출. 두 매개 변수와 |
|
메모리 양이 0개인 메모리 할당 함수에 대한 호출입니다. 두 매개 변수와 |
|
all |
|
요청된 메모리가 크기보다 큰 |
| 지정된 크기를 초과하거나 바인딩이 충분히 제한될 수 없는 VLA(변수 길이 배열) 정의. |
|
포맷된 출력 함수의 |
|
포맷된 출력 함수의 스니프 제품군에 대한 호출 |
|
|
경고 개선
이러한 GCC 경고가 개선되었습니다.
-
인바운드 배열 인덱스 및 포인터 오프셋의 더 많은 인스턴스를 감지하도록
-Warray-bounds
옵션이 개선되었습니다. 예를 들어 유연한 배열 멤버 및 문자열 리터럴에 대한 음수 또는 과도한 인덱스가 감지됩니다. -
GCC 7에 도입된
-Wrestrict
옵션은 표준 메모리 및memcpy
및strcpy
와 같은 문자열 조작 기능에 대한 제한 정규화된 인수를 통해 개체에 대한 중복 액세스의 많은 인스턴스를 감지하도록 향상되었습니다. -
W
nonnull
옵션은 null 포인터를 비null 인수를 예상하는 함수에 전달하는 광범위한 사례를 감지하도록 향상되었습니다(null이 아닌 특성으로 결정됨
).
New UndefinedBehaviorSanitizer
UndefinedBehaviorSanitizer라는 정의되지 않은 동작을 감지하기 위한 새로운 런타임 제거 기능이 추가되었습니다. 다음 옵션은 참고할 수 있습니다.
옵션 | 검사 |
---|---|
| 부동 소수점 분할을 0으로 감지. |
| 부동 소수점 유형에서 정수 변환으로의 결과가 오버플로우되지 않는지 확인합니다. |
| 배열 바운드의 계측을 활성화하고 아웃 오브 바운드 액세스를 감지합니다. |
| 정렬 검사를 활성화하고 다양한 잘못 정렬된 개체를 감지합니다. |
| 개체 크기 검사를 활성화하고 다양한 인바운드 액세스를 감지합니다. |
| C++ 멤버 함수 호출, 멤버 액세스 및 기본 클래스에 대한 포인터 간 일부 변환을 확인할 수 있습니다. 또한 참조되는 오브젝트에 올바른 동적 유형이 없는 경우 탐지합니다. |
|
배열 범위를 엄격하게 검사할 수 있습니다. 이렇게 하면 |
| 일반 벡터를 사용하는 산술 연산에서도 산술 오버플로 진단. |
|
런타임 시 잘못된 인수를 |
|
포인터 래핑을 위해 저렴한 런타임 테스트를 수행합니다. |
AddressSanitizer의 새로운 옵션
이 옵션은 AddressSanitizer에 추가되었습니다.
옵션 | 검사 |
---|---|
| 다른 메모리 개체를 가리키는 포인터에 대해 경고합니다. |
| 다른 메모리 개체를 가리키는 포인터의 빼기에 대해 경고합니다. |
| 변수가 정의된 범위 뒤에 주소를 가져와 사용하는 변수를 삭제합니다. |
기타 바이저 및 계측
-
스택 공간이 정적 또는 동적으로 할당된 경우 프로브를 삽입하기 위해
-fstack-clash-protection
옵션이 추가되어 스택 오버플로를 안정적으로 감지하여 운영 체제에서 제공하는 스택 보호 페이지로 이동하는 공격 벡터가 완화되었습니다. -
새로운 옵션
-fcf-protection=[full|branch|return|none]
이 추가되어 코드 계측을 수행하고 제어 흐름 전송 명령의 대상 주소(예: 간접 함수 호출, 함수 반환, 간접 건너뛰)가 유효한지 확인하여 프로그램 보안이 향상되었습니다.
추가 리소스
위의 옵션에 제공되는 일부 값에 대한 자세한 내용과 설명은 gcc(1) 매뉴얼 페이지를 참조하십시오.
$ man gcc
2.5.3. RHEL 8 GCC의 호환성 혁신적인 변경 사항
std:: string 및 std::
list
에서 C++ ABI 변경
std::
list
libstdc++
라이브러리의 std::string
및 std::list
클래스의 ABI(Application Binary Interface)는 RHEL 7(GCC 4.8)과 RHEL 8(GCC 8) 간에 변경되어 C++11 표준을 준수합니다. libstdc++
라이브러리는 이전 ABI와 새 ABI를 모두 지원하지만, 일부 다른 C++ 시스템 라이브러리는 지원하지 않습니다. 따라서 이러한 라이브러리에 대해 동적으로 연결되는 애플리케이션을 다시 빌드해야 합니다. 이는 C++98을 포함한 모든 C++ 표준 모드에 영향을 미칩니다. 또한 이전 ABI가 시스템 라이브러리와의 호환성을 유지하기 위해 RHEL 7용 Red Hat Developer Toolset 컴파일러로 구축된 애플리케이션에도 영향을 미칩니다.
GCC는 더 이상 Ada, Go 및 Objective C/C++ 코드를 빌드하지 않습니다.
Ada(GNAT), GCC Go 및 Objective C/C++ 언어에서 코드 빌드 기능이 GCC 컴파일러에서 제거되었습니다.
Go 코드를 빌드하려면 대신 Go Toolset을 사용합니다.