💻
Notes-CS
  • INTRO
  • 操作系统
    • 操作系统原理
      • 操作系统概述
        • 操作系统的分类
          • 批处理操作系统
          • 分时操作系统
          • 实时操作系统
          • 个人计算机操作系统
          • 网络操作系统
          • 分布式操作系统
          • 嵌入式操作系统
        • 操作系统的运行环境与机制
          • 中断与异常
          • 系统调用
      • 进程与线程
        • 进程
        • 线程
        • 协程
      • 处理器调度
      • 同步机制
      • 存储模型
      • 文件系统
        • 分区类型
      • 输入输出系统
    • 通用操作系统
      • GNU/Linux
        • Linux 内核
          • Linux 启动过程
          • 几种内核映像的区别
          • 终端设备
          • Ptrace
        • 可执行文件 ELF
        • 文件系统
          • swap
          • Linux 文件系统目录描述
          • 特殊文件
        • 软件生态
          • 基于 Linux 的 OS
            • Arch Linux
            • CentOS
            • Debian
            • Fedora
            • Gentoo
            • Kali
            • OpenSUSE
            • OpenWRT
            • Ubuntu
          • 桌面环境
            • KDE
            • GNOME
            • Xfce
            • DDE
            • Unity
            • MATE
          • 包管理器
            • apt
              • apt install
            • yum
            • pacman
        • Utils
          • dd
          • motd
          • 系统状态分析工具
          • TTY和PTS
          • SysVInit 与 SystemD
          • Linux 系统参考手册
          • 文本IO处理
            • awk
            • sed
            • cut
            • grep
            • xargs
            • diff & patch
      • MacOS
        • Darwin 内核
        • 快捷键
      • Windows
        • NT 内核
        • 可执行文件 PE
        • 文件系统组织
        • 发行版本
          • 古董
            • Windows 3.1
            • Windows 95
            • Windows 98
            • Windows 2000
            • Windows me
            • Windows Vista
            • Windows 8
          • Windows XP
          • Windows 7
          • Windows 10
            • 常用快捷键
      • Android
        • 系统结构
        • 软件包格式 APK
        • 版本历史
    • 通用系统概念
      • ANSI转义序列
        • 终端颜色控制符
      • POSIX
      • 虚拟化
        • 常见虚拟化OS镜像格式
      • Secure Boot
      • 常见文件系统
        • NTFS
        • FAT
        • JFFS
        • tmpfs
  • 编程
    • 编程语言
      • C
        • 语法
          • const
          • typedef
        • 库
          • C standard library(libc)
            • glibc
              • ptrace
          • C POSIX library
            • pthread
        • GNU C
        • 其它
          • 链接库的构成
          • 头文件规范
          • 动态链接库
      • C++
        • 语法
        • 库
          • SL/STL
            • 容器
              • vector
              • string
              • unordered_map
            • 迭代器
            • 其它
              • man page 解决方案
        • 面向对象
          • 重写与重载
            • 运算符重载
      • Python
        • 语法
        • 包
          • 内建
          • 第三方
            • requests
        • 其它
          • PyPI 的使用
          • 内建模块
      • Rust
        • 入门实例
      • Java
      • shell
        • set
    • 数据结构与算法
      • 数据结构
        • 栈
        • 队列
        • 链表
        • 哈希表
        • 并查集
        • 堆
        • 树
          • 二叉树
        • 图
      • 算法
        • 算法基础
          • 枚举
          • 模拟
          • 递归 & 分治
          • 贪心
          • 排序
        • 搜索
        • 动态规划
        • 字符串
        • 数学
          • 快速幂
        • 图论
    • 编译原理
      • 编译器与解释器
      • 词法分析
      • 语法分析
      • 类型检查
      • 中间代码生成
      • 目标代码生成
      • 代码优化
    • 软件工程
      • 编程范式
        • 指令式
          • 过程式
          • 块结构
          • 结构化
          • 非结构化
          • 递归
          • 模块化
        • 面向对象
          • 基于类
          • 基于原型
        • 声明式
          • 函数式
            • 纯函数式
            • 函数响应
        • 多态
          • 多分派
          • 泛型
            • 模板
        • 元编程
          • 宏
          • 元类
          • 反射式
      • 开发方法
        • 敏捷开发
        • 过程模型
          • 瀑布模型
          • V 模型
          • 增量模型
          • 螺旋模型
      • 开发流程
        • 问题定义
        • 可行性研究
        • 需求分析
        • 概要设计
        • 详细设计
        • 编码与测试
        • 运行与维护
      • 开源软件
        • 版本后缀规则
        • 开源协议
          • GPL
          • LGPL
          • MIT
          • BSD
          • Apache
          • Mozilla
  • 信息安全
    • 信息安全原理
      • IoT
        • 交叉编译
        • 固件格式
        • 常见协议
          • UPnP
      • 二进制
        • 常见漏洞
          • Stack Overflow
          • Format String Bug
          • Integer Overflow
          • Double Free
          • Use After Free
          • Race Condition
        • 通用工具
          • IDA
          • ghidra
          • pwntools
          • binutils
          • GDB
          • 脚本工具
            • LibcSearcher
            • main_arena_offset
            • one_gadget
            • ROPgadget
        • 常用技术
          • 符号执行
            • 传统符号执行
            • 现代符号执行
          • 模糊测试
      • Web
        • 常见漏洞
          • SQLi - SQL injection
          • XSS - Cross Site Scripting
            • 基本原理
          • CSRF - Cross Site Request Forgery
          • SSRF - Server-Side Request Forgery
          • XXE - XML External Entity
            • 基本原理
        • 通用工具
          • Burp Suite
          • Wireshark
      • 密码学
        • 流密码
          • XOR
          • RC4
        • 分组密码
          • DES - Data Encryption Standard
          • AES - Advanced Encryption Standard
        • 公钥密码
          • RSA
            • 欧几里得算法
            • 扩展欧几里得算法
            • 中国剩余定理
            • 共模攻击
          • 椭圆曲线算法
        • 数字签名
        • 数据校验
          • CRC
      • 区块链
        • 以太坊
    • 信息安全实践
      • 环境准备
        • IOT
          • 固件获取
          • 固件打包与解包
          • QEMU 模拟
          • 交叉编译
          • 制作文件系统镜像
          • UART 调试
      • 漏洞挖掘
        • 漏洞概览
          • 漏洞编号与管理机构
        • 漏洞挖掘技术
          • 静态分析
          • 模糊测试
            • 工具与框架
              • AFL
          • 污点分析
          • 符号执行
            • 工具与框架
              • Angr
              • KLEE
              • S2E
      • 安全开发
      • 渗透测试
        • shell
        • 网络空间测绘系统
          • quake
          • shodan
        • 内网渗透
          • Linux 靶机
            • 信息搜集
            • 持久化
            • 痕迹清理
        • 工具与框架
          • Metasploit
    • 论文与演示
  • Web 与计算机网络
    • 协议栈
      • 链接层
        • PPP
        • ARP
        • MAC
      • 网络层
        • IP - Internet Protocol
          • IPv4
            • IPv4 分级式寻址
            • IPv4 私有地址划分
          • IPv6
        • ICMP - Internet Control Message Protocol
      • 传输层
        • TCP
        • UDP
        • TLS/SSL
      • 应用层
        • UPnP
        • HTTP
        • DNS
        • FTP
    • Web
      • 浏览器
        • Chrome
          • 内建功能
          • 快捷键
        • Tor
      • Web容器
        • Apache
        • Nginx
        • lighttpd
      • CGI
      • MIME type
      • 搜索引擎
  • 体系结构与硬件
    • 计算机体系结构
      • 指令集
        • X86
        • AMD64
        • ARM
        • RISC-V
        • MIPS
    • 设备与接口
      • 接口协议
        • UART
        • USB
        • HDMI
        • PCI
      • 存储设备
        • 固态硬盘
          • 闪存颗粒 ?LC
        • 识别 Linux上的设备(磁盘)类型
        • 字符设备与块设备
        • MTD
      • 网络设备
        • 路由器
        • 交换机
        • 网卡与虚拟网卡
        • 光接入网络
          • 光猫
  • 数学
    • 离散数学
    • 线性代数
    • 概率与统计
    • 计算理论
  • 软件与框架
    • 通用
      • bash
      • Vim
        • 配置
        • 快捷键
        • 插件
        • VIM Script
      • git
      • Tmux
      • gdb
      • ssh
      • make
      • 双拼
    • 专用
      • 🪜Untitled
        • clash
      • gcc
      • nmap
      • QEMU
        • QEMU source
        • 模拟 raw Linux
        • 模拟发行版
      • docker
      • buildroot
      • burpsuite
    • 轮子
      • LaTeX
      • LLVM
      • libpcap
  • reCTF
    • PWN
      • QEMU PWN
      • Kernel PWN
    • Web
    • Reverse
    • Crypto
    • MISC
  • 资源
    • 学习站
      • 安全学习站
        • 门户
        • 论坛
        • 教程
        • 会议
        • 博客
      • 编程学习站
        • 文档
    • 工具站
      • 安全工具站
        • 二进制
        • Web
        • IoT
        • 社工
      • 应用工具站
  • 实践记录
    • 事件
      • 对于 UDPt 漏洞的跟踪实践
    • 编译
      • alware 静态交叉编译
      • buildroot 编译 arm target
由 GitBook 提供支持
在本页

最后更新于3年前

linux内核中GNU C和标准C的区别

今天看了一下午的linux内核编程方面的内容,发现linux 内核中GNU C与标准C有一些差别,特记录如下:

linux 系统上可用的C编译器是GNU C编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布。GNU C对标准C进行进一步扩展,以增强标准C的功能。下面我们对GNU C中的扩展进行一下总结:

1、零长度数组

GNU C 允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。例如:

结构的最后一个元素定义为零长度数组,它不占结构的空间。在标准 C 中则需要定义数组长度为 1,分配时计算对象大小比较复杂。

2、case范围

GNU C 允许在一个 case 标号中指定一个连续范围的值,例如:

其中case '0' ... '9': 相当于 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':

3、语句表达式

GNU C 把包含在括号中的复合语句看做是一个表达式,称为语句表达式,它可以出现在任何允许表达式的地方,你可以在语句表达式中使用循环、局部变量等,原本只能在复合语句中使用。例如:

复合语句的最后一个语句应该是一个表达式,它的值将成为这个语句表达式的值。这里定义了一个安全的求最小值的宏,在标准 C 中,通常定义为:

这个定义计算 x 和 y 分别两次,当参数有副作用时(比如出现参数自增或自减语句时),将产生不正确的结果,使用语句表达式只计算参数一次,避免了可能的错误。语句表达式通常用于宏定义。

4、typeof关键字

使用前一节定义的宏需要知道参数的类型,利用 typeof 可以定义更通用的宏,不 必事先知道参数的类型,例如:

这里 typeof(x)表示 x 的值类型, const typeof(x) _x = (x); 中定义了一个与 x 类型相同的局部变量 _x并初使化为 x, (void) (&_x == &_y); 的作用是检查参数 x 和 y 的类型是否相同。typeof 可以用在任何类型可以使用的地方,通常用于宏定义。

5、可变参数的宏

在 GNU C 中,宏可以接受可变数目的参数,就象函数一样,例如:

这里 arg 表示其余的参数,可以是零个或多个,这些参数以及参数之间的逗号构成 arg 的值,在宏扩展时替换 arg,例如:

会被扩展为

使用 ## 的原因是处理 arg 不匹配任何参数的情况,这时 arg 的值为空,GNU C 预处理器在这种特殊情况下,丢弃 ## 之前的逗号,这样

会被扩展为

注意最后的逗号。

6、标号元素

标准 C 要求数组或结构变量的初使化值必须以固定的顺序出现,在 GNU C 中,通过指定索引或结构域名,允许初始化值以任意顺序出现。指定数组索引的方法是在初始化值前写 '[INDEX] =',要指定一个范围使用 '[FIRST ... LAST] ='` 的形式,例如:

将数组的所有元素初使化为 ~0UL,这可以看做是一种简写形式。 要指定结构元素,在元素值前写 'FIELDNAME:',例如:

将结构ext2_file_operations的元素 llseek 初始化为 generic_file_llseek,元素 read 初始化为 genenric_file_read,依次类推。我觉得这是 GNU C 扩展中最好的特性之一,当结构的定义变化以至元素的偏移改变时,这种初始化方法仍然保证已知元素的正确性。对于未出现在初始化中的元素,其初值为 0。

7、当前函数名

GNU CC 预定义了两个标志符保存当前函数的名字,__FUNCTION__保存函数在源码中的名字,__PRETTY_FUNCTION__保存带语言特色的名字。在 C 函数中,这两个名字是相同的,在 C++ 函数中,__PRETTY_FUNCTION__包括函数返回类型等额外信息,Linux 内核只使用了

代码中__FUNCTION__意味着字符串“example”。

8、特殊属性声明

GNU C 允许声明函数、变量和类型的特殊属性,以便手工的代码优化和更仔细的代码检查。要指定一个声明的属性,在声明后写 attribute (( ATTRIBUTE ))其中 ATTRIBUTE 是属性说明,多个属性以逗号分隔。GNU C 支持十几个属性,这里介绍最常用的:

* noreturn

属性 noreturn 用于函数,表示该函数从不返回。这可以让编译器生成稍微优化的代码,最重要的是可以消除不必要的警告信息比如未初使化的变量。例如:

* format

属性 format 用于函数,表示该函数使用 printf, scanf 或 strftime 风格的参数,使用这类函数最容易犯的错误是格式串与参数不匹配,指定 format 属性可以让编译器根据格式串检查参数类型。例如:

表示第一个参数是格式串,从第二个参数起根据格式串检查参数。

* unused

属性 unused 用于函数和变量,表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

* aligned

属性 aligned 用于变量、结构或联合类型,指定变量、结构域、结构或联合的对齐量,以字节为单位,例如:

表示该结构类型的变量以4字节对界。

  • packed 属性 packed 用于变量和类型,用于变量或结构域时表示使用最小可能的对齐,用 于枚举、结构或联合类型时表示该类型使用最小的内存。例如:

对于结构体example_struct而言,在i386平台下,其sizeof的结果为9,如果删除其中的2个—attribute__((packed)),其sizeof将为12.

9、内建函数

GNU C 提供了大量的内建函数,其中很多是标准 C 库函数的内建版本,例如memcpy,它们与对应的 C 库函数功能相同,不属于库函数的其他内建函数的名字通常以 __builtin开始。例如:

  • __builtin_return_address (LEVEL)

    • 内建函数 __builtin_return_address 返回当前函数或其调用者的返回地址,参数 LEVEL 指定在栈上搜索框架的个数,0 表示当前函数的返回地址,1 表示当前函数的调用者的返回地址,依此类推。

  • __builtin_constant_p(EXP)

    • 内建函数 __builtin_constant_p 用于判断一个值是否为编译时常数,如果参数EXP 的值是常数,函数返回 1,否则返回 0。

  • __builtin_expect(EXP, C)

    • 内建函数 __builtin_expect 用于为编译器提供分支预测信息,其返回值是整数表 达式 EXP 的值,C 的值必须是编译时常数。 例如,下面的代码检测第一个参数是否为编译时常数以确定采用参数版本还是非参数版本代码:

struct minix_dir_entry { 
    __u16 inode; 
char name[0];
}; 
case '0' ... '9': c -= '0'; break; 
case 'a' ... 'f': c -= 'a'-10; break; 
case 'A' ... 'F': c -= 'A'-10; break; 
#define min_t(type,x,y) \ 
   ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) 
#define min(x,y) ((x) < (y) ? (x) : (y)) 
#define min(x,y) ({ \ 
   const typeof(x) _x = (x);    \ 
   const typeof(y) _y = (y);    \ 
   (void) (&_x == &_y);          \ 
_x < _y ? _x : _y; }) 
#define pr_debug(fmt,arg...) \
printk(fmt,##arg) 
pr_debug("%s:%d",filename,line) 
printk("%s:%d", filename, line) 
pr_debug("success!\n") 
printk("success!\n") 
而不是printk("success!\n",)
static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; 
struct file_operations ext2_file_operations = { 
      llseek:       generic_file_llseek, 
      read:           generic_file_read, 
   write:       generic_file_write, 
      ioctl:       ext2_ioctl, 
       mmap:           generic_file_mmap, 
       open:           generic_file_open, 
   release:        ext2_release_file, 
   fsync:       ext2_sync_file, 
}; 
__FUNCTION__。 
void example()
{
printf{“This is function:%s”, __FUNCTION__};
}
# define ATTRIB_NORET   __attribute__((noreturn)).... 
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET; 
asmlinkage int printk(const char * fmt, ...)    __attribute__ ((format (printf, 1, 2))); 
struct example_struct
{
char a;
int   b;
long c;
} __attribute__((aligned(4)));
struct example_struct
{
char a;
int b__attribute__ ((packed));
long c__attribute__((packed));
};
#define test_bit(nr,addr) \ 
(__builtin_constant_p(nr) ? \ 
constant_test_bit((nr),(addr)) : \
   variable_test_bit((nr),(addr)))
  1. 编程
  2. 编程语言
  3. C

GNU C

上一页pthread下一页其它
  • linux内核中GNU C和标准C的区别
  • 1、零长度数组
  • 2、case范围
  • 3、语句表达式
  • 4、typeof关键字
  • 5、可变参数的宏
  • 6、标号元素
  • 7、当前函数名
  • 8、特殊属性声明
  • 9、内建函数