vmlinux, System.map; cmake的find_package(Clang)产生的变量们; geogebra单位切向量(简单例子)

news2024/11/24 16:21:31

linux4.15.y内核中的函数个数

依赖关系: vmlinux, vmlinux.bin, bzImage

cd  /bal/linux-stable/
file  vmlinux
#vmlinux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=b99bbd9dda1ec2751da246d4a7ae4e6fcf7d789b, not stripped
#文件大小 20MB, 19940148B

file arch/x86/boot/compressed/vmlinux.bin
#arch/x86/boot/compressed/vmlinux.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=b99bbd9dda1ec2751da246d4a7ae4e6fcf7d789b, stripped
#文件大小 14MB, 13706624B

file  arch/x86/boot/vmlinux.bin
#arch/x86/boot/vmlinux.bin: data
#文件大小 6.5MB, 6752568B

file  arch/x86/boot/bzImage 
#arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 4.14.332+ (z@shinelon) #1 SMP Sat Jan 6 19:26:05 CST 2024, RO-rootFS, swap_dev 0X6, Normal VGA
#文件大小 6.5MB , 6767424B

编译产物ELF文件vmlinux 中的函数个数

cd /bal/linux-stable/

readelf -s vmlinux.o | grep FUNC | wc -l  #39998
readelf -s vmlinux | grep FUNC | wc -l   #39998

readelf -s vmlinux.o | grep OBJECT  | wc -l   #43012
readelf -s vmlinux | grep OBJECT  | wc -l    #42644

readelf -s vmlinux.o | wc -l   #95312
readelf -s vmlinux | wc -l   #85192

clang插件观测到的函数个数

sqlite3 -readonly ./SrcFileFuncIdGenService/fn.db "select count(*) from tbl_Func"  #51284

vmlinux

grep "vmlinux" /bal/make.log, 找到生成vmlinux的链接命令:

ld -m elf_i386 \
#指定目标架构为 32 位 x86 ELF 格式。
-z noexecstack \
#禁用栈的执行权限,提高安全性。
--emit-relocs \
#生成重定位信息。
--discard-none \
#不丢弃任何未使用的部分。
--build-id \
#为输出文件生成 Build ID。
-o vmlinux \
#指定输出文件名为 vmlinux。
-T ./arch/x86/kernel/vmlinux.lds \
#使用指定的链接脚本。
--whole-archive built-in.o --no-whole-archive \
#开始whole-archive ... 结束whole-archive, 即 强制包含 built-in.o 中的所有目标文件。
--start-group lib/lib.a arch/x86/lib/lib.a --end-group \
#将库文件 lib/lib.a 和 arch/x86/lib/lib.a 包围在一个组内,确保解析所有符号。
.tmp_kallsyms2.o # 输入的目标文件。

find /bal/linux-stable -path "*x86*Makefile" | xargs -I@ grep -Hn "vmlinux:" @ ,找到有目标vmlinux的:

/bal/linux-stable/arch/x86/boot/Makefile:111:$(obj)/compressed/vmlinux: FORCE
/bal/linux-stable/arch/x86/boot/compressed/Makefile:118:$(obj)/vmlinux: $(vmlinux-objs-y) FORCE

System.map

grep "System.map" make.log,主要有:/bin/bash ./scripts/mksysmap vmlinux System.map

cat /bal/linux-stable/scripts/mksysmap, 此文件mksysmap只有一行:
$NM -n $1 | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > $2

带入参数后为:
$NM -n vmlinux | grep -v '\( [aNUw] \)\|\(__crc_\)\|\( \$[adt]\)\|\( \.L\)\|\( L0\)' > System.map

chatgpt的解释开始

这个命令使用了 nm 命令来提取 Linux 内核 (vmlinux) 的符号表信息,并通过 grep 进行过滤,将结果保存到 System.map 文件中。下面是各个过滤条件的含义:

  • [aNUw] 这是一个字符类,匹配符号的类型。在这里,它过滤掉了类型为小写 ‘a’、‘N’ 或 ‘w’ 的符号。这通常是与代码、未定义符号或弱符号相关的标志。

  • \(__crc_\) 匹配包含 ‘_crc’ 的符号。这样的符号通常是与内核中的 CRC (Cyclic Redundancy Check) 相关的。

  • \$[adt] 匹配以 ‘ a ′ 、 ′ a'、' ad’ 或 ‘$t’ 开头的符号。通常这些符号表示代码、数据或文本段。

  • \.L 匹配以 ‘.L’ 开头的符号。这样的符号通常是由编译器生成的本地标签。

  • L0 匹配以 ‘L0’ 开头的符号。这也可能是编译器生成的本地标签。

通过这些过滤条件,命令排除了一些在内核符号表中不需要的信息,集中保留了主要的符号。这有助于提高 System.map 文件的可读性,使得在进行内核调试和分析时更容易找到感兴趣的符号。System.map 文件对于内核调试非常有用,因为它提供了符号名称和对应的内存地址,帮助开发人员理解和定位内核中的各种符号。

chatgpt的解释结束

makefile2graph 尝试可视化Makefile的依赖关系

sudo apt install makefile2graph
makefile2graph /bal/linux-stable/arch/x86/boot/compressed/Makefile  > /bal/makefile2graph.txt

将文件makefile2graph.txt的内容粘到 https://dreampuf.github.io/GraphvizOnline,选osage、png:在这里插入图片描述
得到一个14MB的图片,只能缩略传到这里:
在这里插入图片描述

, 实际图片

用makefile2graph直接可视化Makefile一定是不完整的,因为很显然:linux4是经过演化的,其编译过程的公共部分一定是抽象过的,而直观的依赖关系 可以体现在 编译过程中的(编译、链接)命令 序列。

类似于makefile2graph的工具有:

chatgpt回答开始

有几种工具可以用于将Makefile的依赖关系以图形化或其他方式展现出来。以下是一些常见的工具:

  1. Graphviz:

    • 描述: Graphviz 是一个开源的图形可视化工具集,可以用于绘制图形,包括依赖图。
    • 使用方式: 你可以使用 dot 命令行工具来生成依赖图。例如:
      make -Bnd | make2graph | dot -Tpng -o makefile.png
      
      其中,make -Bnd 用于获取Makefile的依赖关系,make2graph 将其转换为Graphviz的输入格式,dot 用于生成图形。
  2. Remake:

    • 描述: Remake 是一个增强版的 Make 工具,支持交互式查看和修改Makefile的依赖关系。
    • 使用方式: 通过运行 remake -x 进入交互模式,然后可以使用 graph 命令生成依赖图。
  3. CMake:

    • 描述: CMake 是一个跨平台的构建系统,可以生成各种构建文件,包括依赖图。
    • 使用方式: 通过在CMakeLists.txt文件中添加相关指令,然后运行CMake生成构建文件,并使用相应工具查看依赖图。
  4. makefile2graph: (此即上面用的)

    • 描述: makefile2graph 是一个专门为Makefile设计的工具,用于生成依赖图。
    • 使用方式: 安装 makefile2graph 后,运行 makefile2graph yourMakefile | dot -Tpng -o makefile.png 来生成图形。
  5. cmake-graph:

    • 描述: cmake-graph 是一个用于可视化CMake项目的工具,也可以用于Makefile。
    • 使用方式: 安装 cmake-graph 后,运行 cmake-graph yourMakefile | dot -Tpng -o makefile.png 来生成图形。

使用这些工具,你可以更好地理解和可视化Makefile中的依赖关系,以及构建过程中的各个步骤。选择适合你项目的工具,并根据需要进行配置。

chatgpt回答结束

结论

由此可见 , linux4.15.y内核编译过程中, clang插件观测到的函数个数(表tbl_Func中行数51284)比实际编译产物vmlinux中的函数个数(FUNC类型的符号数39998) 多了大约1万个函数

cmake 比较两次记录的所有变量差异

运行效果:

find_package(Clang REQUIRED CONFIG)一共新增了约79个cmake变量,如下:

保存cmake当前变量们并与上次变量们比较,第【64】行,退出码:【0】, 标准输出: 【比较命令:‘diff /tmp/cmake_vars_1200 /tmp/cmake_vars_1201’ , 差异行数:79 /tmp/cmake_vars_diff_1200_1201】, 错误输出:【】

在这里插入图片描述

例子 文件 CMakeLists.txt

#文件名: CMakeLists.txt
#...
save_cmake_vars__cur_diff_prev(${CMAKE_CURRENT_LIST_LINE})
find_package(Clang REQUIRED CONFIG)
save_cmake_vars__cur_diff_prev(${CMAKE_CURRENT_LIST_LINE})  #此为第64行
#...

文件名: diff2f.sh

#文件名:  diff2f.sh
#!/usr/bin/env bash

# me.sh  ${_OutFPathPrefix} ${_prevVarsFIdx} ${gVarsFIdx}
#若参数少于3个,则退出(退出码为55)
[ $# -lt 3 ] && exit 55

_OutFPathPrefix=$1
_prevVarsFIdx=$2
gVarsFIdx=$3
_prevOutFPath="${_OutFPathPrefix}${_prevVarsFIdx}"
outFPath="${_OutFPathPrefix}${gVarsFIdx}"
resultF="${_OutFPathPrefix}diff_${_prevVarsFIdx}_${gVarsFIdx}"

echo -n "比较命令:‘diff ${_prevOutFPath} ${outFPath}’ , "
echo -n "差异行数:"
diff --side-by-side --suppress-common-lines ${_prevOutFPath} ${outFPath} > $resultF ;
wc -l $resultF |  perl -pe 'chomp if eof'
#用命令 “ perl -pe 'chomp if eof'  ” 删除wc输出的换行符号

文件名: save_vars__cur_diff_prev.cmake

#文件名: save_vars__cur_diff_prev.cmake
set(_Text_gVarsFIdxDesc "变量描述: 'cmake CACHE (INTERNAL)' 即 cmake全局(同级)变量")
set(_OutFPathPrefix "/tmp/cmake_vars_")

#如果从没有定义过全局变量gVarsFIdx 则定义该全局变量
if(NOT DEFINED gVarsFIdx)
    set(gVarsFIdx 0 CACHE INTERNAL  ${_Text_gVarsFIdxDesc})
    # 'CACHE INTERNAL'变量gVarsFIdx 写入在文件  ./cmake-build-debug/CMakeCache.txt :
    #gVarsFIdx:INTERNAL=数值

    message(STATUS "初始化 gVarsFIdx=${gVarsFIdx}")
endif()

function(save_cmake_vars__cur_diff_prev _CMAKE_CURRENT_LIST_LINE)
#    message(STATUS "函数进入 gVarsFIdx=${gVarsFIdx}")
    MATH(EXPR _prevVarsFIdx "${gVarsFIdx} - 1")
#    set(_prevOutFPath "${_OutFPathPrefix}${_prevVarsFIdx}")

    set(_curVarsFIdx "${gVarsFIdx}")

    # 获取 cmake变量们
    get_cmake_property(_varNames VARIABLES)

    # cmake变量们写入文件
    set(_curOutFPath "${_OutFPathPrefix}${gVarsFIdx}")
    file(WRITE ${_curOutFPath} "")
    foreach(_varName ${_varNames})
        if (_varName MATCHES "^_"  #忽略_开头的变量名
                OR _varName STREQUAL "gVarsFIdx") #忽略此脚本用到的变量名gVarsFIdx
#            message(STATUS "忽略变量名【${_varName}】")
            continue()
        endif()

        #向文件中写入一行
        file(APPEND ${_curOutFPath} "${_varName}=${${_varName}}\n")
    endforeach()

    #文件名下标 自增1
    MATH(EXPR _nextVarsFIdx "${gVarsFIdx} + 1")
    set(gVarsFIdx ${_nextVarsFIdx} CACHE INTERNAL  ${_Text_gVarsFIdxDesc})
#####
# 执行 diff 命令
execute_process(
#        COMMAND   bash -x  ...
        COMMAND   bash  /bal/clang-add-funcIdAsm/cmake_script/save_vars__cur_diff_prev/diff2f.sh ${_OutFPathPrefix} ${_prevVarsFIdx} ${_curVarsFIdx}
        RESULT_VARIABLE shExitCode
        OUTPUT_VARIABLE shStdOut
        ERROR_VARIABLE shStdErr
)

message(STATUS "保存cmake当前变量们并与上次变量们比较,第【${_CMAKE_CURRENT_LIST_LINE}】行,退出码:【${shExitCode}】, 标准输出: 【${shStdOut}】, 错误输出:【${shStdErr}】")
#message(STATUS "函数出来 gVarsFIdx=${gVarsFIdx}")

endfunction()

# 调用函数保存所有变量
#save_cmake_vars__cur_diff_prev()

geogebra单位切向量(简单例子)

下载页面 —> GeoGebra5下载页面 --> GeoGebra5 Linux版本下载地址

或GeoGebra在线使用

启动 /app/GeoGebra-Linux-Portable-5-2-817-0/geogebra-portable后 在 最底下"Input"输入栏 一条一条输入以下命令(不包括#开头的注释行):

cent=(0,0)
t=Slider(0,10)
r=Slider(1,5)
cir=Circle(Point(cent),r)
p_c=Point({r sin(2π t), r cos(2π t)})
#v_r=Vector(p_c)
#UnitPerpendicularVector(v_r) #这个向量起点不能指定,想要起点在p_c
v_{utp}=UnitVector(Tangent(p_c, cir))

再导出 gif动画
在这里插入图片描述

导出的gif动画如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1372836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Git远端删除的分支,本地依然能看到 git remote prune origin

在远端已经删除ylwang_dev_786等三四个分支,本地git branch -a 时 依然显示存在。 执行 git remote show origin 会展示被删除的那些分支 当你在Git远程仓库(如GitLab)上删除一个分支后,这个变更不会自动同步到每个开发者的本地…

【教学类-45-01】X-Y之间的“三连加“题(a+b+c=)

作品展示: 背景需求: 我常去的大4班孩子们基本都适应了0-5之间的加法题,做题速度极快。 为了增加“花样”,吸引幼儿参与,修改参数,从二连加12变为三连加111。 素材准备: 代码重点 代码展示 X-Y 之间的3…

springboot基于java的小区物业管理系统(保安巡逻绿化消防)设计+jsp

小区物业管理系统采用的是JAVA语言开发,利用MySQL为数据库, 使用IDEA平台来编写代码,框架方面选择的是springbootweb框架,采用B/S结构实现系统。本系统的设计与开发过程中严格遵守软件工程的规范,运用软件设计模式&…

uniapp最简单的底部兼容安全区域显示

效果图&#xff1a; 1.html写上动态padding-bottom <view class"button-wrap" :style"padding-bottom:bottomPaddingrpx"><view class"com-btn cencel-btn">取消</view><view class"com-btn confirm-btn " cl…

Xcalibur软件Qual Brower程序的使用

找到Qual Brower&#xff1a;在System>Program里 打开采集的数据文件*.RAW&#xff0c;软件界面主窗口能查看色谱图和质谱图&#xff1a; 1、图形的放大和拷贝、色谱中查看峰的质谱信息&#xff1a; 点亮如图图像右上角的按钮&#xff0c;可以激活该图形并进行操作&#x…

前端 Node 项目迁徙为桌面 Electron 应用笔记

起因 我的服务器到期了&#xff0c;服务器上有几个服务&#xff0c;人家问这几个网站怎么不好使了&#xff0c;奈何服务器续费太贵租不起了… 但是服务还是要提供的&#xff0c;所以我在想如何把 node 的项目变成桌面端应用&#xff0c;于是有了这个笔记 效果展示 页面没啥…

强化学习10——免模型控制Q-learning算法

Q-learning算法 主要思路 由于 V π ( s ) ∑ a ∈ A π ( a ∣ s ) Q π ( s , a ) V_\pi(s)\sum_{a\in A}\pi(a\mid s)Q_\pi(s,a) Vπ​(s)∑a∈A​π(a∣s)Qπ​(s,a) &#xff0c;当我们直接预测动作价值函数&#xff0c;在决策中选择Q值最大即动作价值最大的动作&…

如何寻找到相对完整的真正的游戏的源码 用来学习?

在游戏开发的学习之路上&#xff0c;理论与实践是并重的两个方面。对于许多热衷于游戏开发的学习者来说&#xff0c;能够接触到真实的、完整的游戏源码无疑是一个极好的学习机会。但问题来了&#xff1a;我们该如何寻找到这些珍贵的资源呢&#xff1f; 开源游戏项目 GitHub:地…

BUUCTF ---> Encrypto

转眼就一月十号了&#xff0c;本来今天不想更的&#xff0c;&#xff08;因为我懒&#xff09;是因为明天要考python&#xff0c;好像还不止 但是呢&#xff0c;发现BUUCTF的密码学模块刚好可以用到py的脚本&#xff0c;那就当时复习一下吧&#xff01;&#xff01; 这里就要介…

http跟https有什么区别?

HTTPS和HTTP的概念&#xff1a; HTTP&#xff1a;是互联网上应用最为广泛的一种网络协议&#xff0c;是一个客户端和服务器端请求和应答的标准&#xff08;TCP&#xff09;&#xff0c;用于从WWW服务器传输超文本到本地浏览器的传输协议&#xff0c;它可以使浏览器更加高效&am…

2024--Django平台开发-Django知识点(六)

day06 Django知识点 今日概要&#xff1a; Form和ModelForm组件【使用】【源码】缓存【使用】ORM【使用】其他&#xff1a;ContentTypes、Admin、权限、分页、信号等 1.Form和ModelForm组件 背景&#xff1a;某个公司后台管理项目。 垃圾 def register(request):"&quo…

Qt/QML编程学习之心得:hicar手机投屏到车机中控的实现(32)

hicar,是华为推出的一款手机APP,有百度地图、华为音乐,更多应用中还有很多对应手机上装在的其他APP,都可以在这个里面打开使用,对开车的司机非常友好。但它不仅仅是用在手机上,它还可以投屏到车机中控上,这是比较神奇的一点。 HiCar本质上是一套智能投屏系统,理论上所有…

人工智能复习

机器学习中线性回归和逻辑回归&#xff1a; 机器学习的分类&#xff1a; 监督学习和无监督学习&#xff0c;半监督学习 监督学习&#xff08;Supervised Learning&#xff09;&#xff1a; 监督学习是一种利用带有标签&#xff08;标记&#xff09;的数据进行训练的机器学习…

用友U8流程审批效率-SQLServer+SSRS

文章目录 @[TOC]1、 需求及效果1.1 需求1.2 效果2、 思路及SQL语句3、实现折叠明细表4、结语1、 需求及效果 1.1 需求 想要查看U8的审批流程,查看流程在哪个节点或人停留的时间,这个单据整个流程走下来需要的时间。可以更加直观方便的查看审批效率 1.2 效果 采用了SSRS上…

【算法每日一练]-动态规划 (保姆级教程 篇15) #纸带 #围栏木桩 #四柱河内塔

目录 今日知识点&#xff1a; 计算最长子序列的方案个数&#xff0c;类似最短路径个数问题 四柱河内塔问题&#xff1a;dp[i]min{ (p[i-k]f[k])dp[i-k] } 纸带 围栏木桩 四柱河内塔 纸带 思路&#xff1a; 我们先设置dp[i]表示从i到n的方案数。 那么减法操作中&#xff…

TensorRt(5)动态尺寸输入的分割模型测试

文章目录 1、固定输入尺寸逻辑2、动态输入尺寸2.1、模型导出2.2、推理测试2.3、显存分配问题2.4、完整代码 这里主要说明使用TensorRT进行加载编译优化后的模型engine进行推理测试&#xff0c;与前面进行目标识别、目标分类的模型的网络输入是固定大小不同&#xff0c;导致输入…

Docker中镜像的相关操作

1.辅助操作 docker version&#xff1a;用查看docker客户端引擎和server端引擎版本信息。 docker info&#xff1a;用来查看docker引擎的详细信息。 docker --help&#xff1a;用来查看帮助信息。 2.镜像Image docker images&#xff1a;查看当前本地仓库中存在哪些镜像。 …

Mysql是怎样运行的--下

文章目录 Mysql是怎样运行的--下查询优化explainoptimizer_trace InnoDB的Buffer Pool&#xff08;缓冲池&#xff09;Buffer Pool的存储结构空闲页存储--free链表脏页&#xff08;修改后的数据&#xff09;存储--flush链表 使用Buffer PoolLRU链表的管理 事务ACID事务的状态事…

在CentOS环境下编译GreatSQL RPM包

本文介绍如何在CentOS环境下编译GreatSQL RPM包。 运行环境是docker中的CentOS 8 x86_64&#xff1a; $ docker -v Docker version 20.10.10, build b485636$ docker run -itd --hostname c8 --name c8 centos bash a0a2128591335ef41e6faf46b7e79953c097500e9f033733c3ab37f…

使用curl命令在Linux中进行HTTP请求

在Linux中&#xff0c;curl是一个非常强大的命令行工具&#xff0c;用于发送HTTP请求。它允许用户发送各种类型的HTTP请求&#xff0c;如GET、POST、PUT、DELETE等&#xff0c;并能够处理响应数据。 首先&#xff0c;确保您的Linux系统已经安装了curl。如果未安装&#xff0c;…