Linux 编译内核模块出现--Unknown symbol mcount

这篇具有很好参考价值的文章主要介绍了Linux 编译内核模块出现--Unknown symbol mcount。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux suse:

# cat /etc/os-release
NAME="SLES"
VERSION="12-SP2"
VERSION_ID="12.2"
PRETTY_NAME="SUSE Linux Enterprise Server 12 SP2"
ID="sles"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:12:sp2"

# uname -r
4.4.120-92.70-default

在编译SUSE Linux Enterprise Server 12 SP时,使用低版本的docker镜像编译内核模块时,加载内核模块时出现:

# dmesg
[12996.210792] Spectre V2 : System may be vulnerable to spectre v2
[12996.210892] test: loading module not compiled with retpoline compiler.
[13299.232906] test: Unknown symbol mcount (err 0)

加载内核模块时:
(1)

# dmesg
[12996.210792] Spectre V2 : System may be vulnerable to spectre v2
[12996.210892] test: loading module not compiled with retpoline compiler.

指示系统可能受到 Spectre V2 漏洞的影响,并且正在加载的模块没有使用 retpoline 编译器进行编译。

Spectre V2(CVE-2017-5715)是 Spectre 漏洞家族中的一个变种,它是一种基于推测执行的侧信道攻击。Spectre V2 漏洞影响现代处理器,可能允许攻击者访问其他进程内存中的敏感信息。

Spectre V2 漏洞利用了分支预测的缺陷,这是一种现代处理器使用的性能优化技术。通过操纵分支的推测执行,攻击者可以欺骗处理器泄露应该是不可访问的敏感信息。

为了解决 Spectre V2 漏洞,需要在硬件和软件层面上采取综合的缓解措施。硬件厂商发布了包含处理器固件更新的微码更新,以在硬件层面上缓解漏洞。此外,操作系统厂商提供了软件补丁和更新,包括支持 Retpoline 的编译器和更新的内核,以在软件层面上缓解漏洞。

Retpoline(Return Trampoline)是一种软件缓解技术,用于应对 Spectre V2 漏洞。它是一种编译器技术,修改代码中的间接分支指令,防止推测执行访问未经授权的内存位置。Retpoline 可以在不需要昂贵的硬件修改的情况下缓解 Spectre V2 漏洞。

检查内核配置:检查您的内核配置,确保已启用retpoline支持。可以通过查看内核配置文件/proc/config.gz是否启用了retpoline选项:

# zgrep CONFIG_RETPOLINE /proc/config.gz
CONFIG_RETPOLINE=y

如果输出显示 CONFIG_RETPOLINE=y,则表示retpoline已启用。

这只是警告而已,不影响模块的加载运行。

(2)

# dmesg
[13299.232906] test: Unknown symbol mcount (err 0)

gcc 的 -pg 选项,它插入 mcount() 调用以与 gprof 一起使用。

当在Linux系统中加载内核模块时遇到 “Unknown symbol mcount (err 0)” 的错误消息时,这通常表示所加载的内核模块依赖于 mcount 符号,但该符号在当前系统内核中不可用或未定义。

mcount 是一个用于性能分析和跟踪的内核符号,通常由 gcc 编译器生成的代码调用。它用于计算函数调用的计数,以便进行性能分析和跟踪操作。

从 gcc 4.6 版开始,这个 mcount() 调用现在是 fentry()。

使用的 docker 容器 gcc 版本过低,低于 gcc 4.6,因此编译内核模块时出现了mcount符号,该符号在当前系统内核中是未定义。

# nm test.ko | grep mcount
                 U mcount
# cat /proc/kallsyms | grep mcount
ffffffff81eecb60 T __start_mcount_loc
ffffffff81f1dd78 T __stop_mcount_loc

可以看到当前内核版本没有 mcount 符号。

__start_mcount_loc 和 __stop_mcount_loc 这两个符号实际上是用于标记函数fentry()插装跟踪信息的起始和结束位置,这些符号是由编译器自动插入的。当使用 -pg 选项编译程序时,编译器会在每个函数的入口和出口处插入这些符号,以便在程序运行时收集函数调用和执行时间的数据。

__start_mcount_loc 标记了函数调用跟踪信息的起始位置,而 __stop_mcount_loc 则标记了其结束位置。这两个符号之间的范围表示了fentry() 插装数据的范围。

使用较高版本的docker(gcc)即可,比如 gcc 4.8:

# nm test.ko| grep __fentry__
                 U __fentry__
# cat /proc/kallsyms | grep __fentry__
ffffffff815f89d0 T __fentry__

内核当前镜像中有该内核符号__fentry__。

(3)内核顶层 makefile文章来源地址https://www.toymoban.com/news/detail-665418.html

vim /usr/src/linux-4.4.120-92.70/Makefile
KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security \
                   -std=gnu89 $(call cc-option,-fno-PIE)
ifdef CONFIG_FUNCTION_TRACER
ifndef CC_FLAGS_FTRACE
CC_FLAGS_FTRACE := -pg
endif
export CC_FLAGS_FTRACE
ifdef CONFIG_HAVE_FENTRY
CC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY)
endif
KBUILD_CFLAGS   += $(CC_FLAGS_FTRACE) $(CC_USING_FENTRY)
KBUILD_AFLAGS   += $(CC_USING_FENTRY)
ifdef CONFIG_DYNAMIC_FTRACE
        ifdef CONFIG_HAVE_C_RECORDMCOUNT
                BUILD_C_RECORDMCOUNT := y
                export BUILD_C_RECORDMCOUNT
        endif
endif
endif
# zgrep CONFIG_FUNCTION_TRACER /proc/config.gz
CONFIG_FUNCTION_TRACER=y

# zgrep CONFIG_HAVE_FENTRY /proc/config.gz
CONFIG_HAVE_FENTRY=y

# zgrep CONFIG_DYNAMIC_FTRACE /proc/config.gz
CONFIG_DYNAMIC_FTRACE=y

到了这里,关于Linux 编译内核模块出现--Unknown symbol mcount的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 勾选Use Microlib报错,解决编译出现Undefined symbol __use_two_region_memory 和Undefined symbol __initial_sp的问题

    在使用STM32串口打印函数过程中,我们往往会勾选 Use Microlib . 但是近期发现,勾选后编译会报俩个错误。 1. Undefined symbol __use_two_region_memory 2. Undefined symbol __initial_sp 解决方法:         打开 startup_stm32f103xb.s 文件, 翻到最底下找到图片中的两个语句。 将两句先 注释,编译,

    2024年02月13日
    浏览(59)
  • 内核模块(编译方法)

    目录 一、向内核添加新功能 1.1 静态加载法: 1.2 动态加载法: a、新功能源码与Linux内核源码在同一目录结构下时 b、新功能源码与Linux内核源码不在同一目录结构下时 c、主机ubuntu下使用ko文件 d、开发板Linux下使用ko文件 二、内核模块基础代码解析 Linux内核的插件机制——内

    2024年02月09日
    浏览(30)
  • 软件课设(Ⅲ)——padavan-ng编译以及内核模块修改

    我记得今年的很多笔试面试都遇到了linux相关的操作,答题状况都挺……昂。算是补课吧,正好大四的毕业实习、软3还有研0的项目都需要linux的环境进行推进,记录一下,聊作纪念。 实验要求 编译系统,下载并提交,验收的时候,我会找MIPS板子,让大家下载验证。 编译一个

    2024年02月02日
    浏览(42)
  • 【linux内核】Debian内核编译

    列出 Debian 内各种版本的核心软件包 apt安装软件包 编译内核源码 安装内核 更新grub 参考: 8.10. 编译内核 (debian.org) Debian编译内核教程 - 时光旅行的懒猫 - 博客园 (cnblogs.com) 内核编译方法-tony_ayuan-ChinaUnix博客

    2024年02月17日
    浏览(37)
  • Linux内核学习(包含Linux 2.6内核编译安装流程)

    Linux内核官方网站为:http://www.kernel.org 或者使用git将源码clone下来(我这里使用的版本为2.6): clone下来的源码目录结构如下:  其中比较重要的目录的官方描述如下: 对应的中文描述如下: 由于centos7.6初始gcc版本为4.8.5,而编译内核需要的最低版本为5.1.0,所以需要安装高

    2024年02月07日
    浏览(49)
  • IMX6ULLPRO单独编译kernel+dtb内核模块以及uboot

    目录 linux开发板启动流程 为什么编译驱动程序之前要先编译内核? 驱动程序要用到内核文件: 编译内核 编译安装内核模块 编译内核模块 安装内核模块到 Ubuntu 某个目录下备用  安装内核和模块到开发板上  Bootloader 介绍 编译 u-boot 镜像 Reset--ROM--bootloader--kernel+dtb--rootfs--AP

    2024年01月22日
    浏览(34)
  • Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)

    目录 一、设备类型 二、模块 构建模块 安装模块 载入模块 在 Linux 以及 Unix 系统中,设备被分为以下三种类型: 块设备(blkdev) :以块为寻址单位,块的大小随设备的不同而变化;块设备通常支持重定位(seeking)操作,也就是对数据的随机访问。如硬盘、蓝光光碟和 Flas

    2024年02月11日
    浏览(45)
  • 树莓派Linux内核编译

    树莓派内核源代码保存在GitHub上github.com/raspberrypi/linux,可以看做是Linux主线内核代码的一个分支。树莓派内核源代码是从Linux主线的长期维护的稳定版本加上树莓派特有的改动形成的。树莓派的内核更新可以通过apt命令自动更新到最新的稳定版本。但是如果你需要使用到最新

    2024年02月08日
    浏览(32)
  • linux内核分析编译体验

    linux-2.6.22.6 下载地址 https://mirrors.edge.kernel.org/pub/linux/kernel/v2.6/ linux-2.6.22.6_jz2440.patch下载地址 https://download.csdn.net/download/zjq_5586288/10438800?utm_source=bbsseo cd /home/li/kernel_learn/linux-2.6.22.6 patch -p1 …/linux-2.6.22.6_jz2440.patch 三种方式 (1)make menuconfig (2)使用默认配置(defconfig)在上面

    2023年04月11日
    浏览(30)
  • 编译Linux 2.6.34内核

    《Linux内核设计与实现(第三版)》中所用的内核版本为2.6.34,这个版本太旧了,在高版本系统中编译各种不支持,所以选了Ubuntu 14.04进行编译。 编译环境 :Ubuntu 14.04 GCC版本:4.8.4 编译的内核版本:Linux 2.6.34 内核源码下载:https://mirrors.edge.kernel.org/pub/linux/kernel/ 解压源码l

    2024年02月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包