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

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, 19940148Bfile 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, 13706624Bfile  arch/x86/boot/vmlinux.bin
#arch/x86/boot/vmlinux.bin: data
#文件大小 6.5MB, 6752568Bfile  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   #39998readelf -s vmlinux.o | grep OBJECT  | wc -l   #43012
readelf -s vmlinux | grep OBJECT  | wc -l    #42644readelf -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()#文件名下标 自增1MATH(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 shExitCodeOUTPUT_VARIABLE shStdOutERROR_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.hqwc.cn/news/344303.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【模型评估 04】A/B测试的陷阱

互联网公司中,A/B测试是验证新模块、新功能、新产品是否有效;新算法、新模型的效果是否有提升;新设计是否受到用户欢迎;新更改是否影响用户体验的主要测试方法。在机器学习领域中,A/B测试是验证模型最终效果的主要手段…

Windows下安装部署Redis

一、下载 地址:https://github.com/MSOpenTech/redis/releases Redis-x64-3.2.100.msi版的比较简单,下载之后直接下一步,下一步… 即可完成安装部署。 这里主要演示Redis-x64-3.2.100.zip的安装部署过程,将Redis-x64-3.2.100.z…

超维空间M1无人机使用说明书——61、ROS无人机物体识别与精准投放

引言:基于空中物流的项目背景。我们提供了使用基于诗句的物体识别和精准投放、降落。实现原理如下: 1、在ROS下使用机载电脑实现物体识别 2、记载电脑根据反馈的位置发布运动控制指令 3、PX4解析机载电脑发布的命令,作出运动控制 4、设置…

MySQL的Windows系统安装

一、MySQL的Windows系统安装 1、下载MySQL安装包 打开如下链接地址,下载安装包 2、安装并配置 双击下载好的安装包进行安装,出现如下界面: 选择【 Full 】选项,然后单击【 Next 】按钮。 出现如下界面,单击【 Execute…

计算机毕业设计---SSH协会志愿者服务管理系统

项目介绍 该项目分为前后台,分为管理员与普通用户两种角色,前台为普通用户登录,后台为管理员登录; 管理员角色包含以下功能: 管理员登录,管理员管理,志愿者管理,活动管理,捐赠管理,关于我们管理,友情链接管理,新闻类…

第11章 GUI Page495~496 步骤三十一:另存为别的文件,为TrySaveFile()入参设置一些位操作

工程二 头文件中为TrySaveFile()入参设置一些位操作,修改一下TrySaveFile()的入参类型 修改TrySaveFile()的实现: 修改“保存”菜单项挂接事件响应函数: 修改“另存为”菜单项挂接事件响应函数

代码结构:为何重要算法不和接口编译到一个dll里面

这里是vision master的例子。 有两点需要向他学习的。 1 需要每个算子是一个dll。优点是方便业务上,针对不同的算子精细化的更新,或者售卖。 2 每个算子的dll我们理解,内容主要是其接口的实现。而真正的算法内容是在上面的algorithm.dll中…

竞赛保研 基于深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 …

vscode+opencv基础用法学习1

案例1&#xff1a;读取图片信息 如果是使用云服务器的话&#xff0c;由于图形界面的问题&#xff0c;使用cv::show来显示图片会报错 // 图片的读取和显示 // 导入opencv头文件 #include "opencv2/opencv.hpp" #include <iostream>int main(int argc, char** …

win10在启动游戏时报错,提示“d3dx9_25.dll文件丢失”,怎么办?d3dx9_25.dll丢失如何自动修复

一、d3dx9_25.dll文件是什么&#xff1f; d3dx9_25.dll是DirectX的一部分&#xff0c;DirectX是一种由微软开发的专门处理与多媒体、游戏程序和视频相关的应用程序接口。d3dx9_25.dll文件是DirectX9中一个重要的dll文件&#xff0c;主要负责处理3D图形程序&#xff0c;作用是帮…

React Native 环境安装

Notion – The all-in-one workspace for your notes, tasks, wikis, and databases. 搭建开发环境 React Native 中文网 Homebrew&#xff08;包管理器&#xff09; → rvm&#xff08;ruby版本管理&#xff09; → ruby → cocoapods 安装 Homebrew Homebrew /bin/ba…

PHP版学校教务管理系统源码带文字安装教程

PHP版学校教务管理系统源码带文字安装教程 运行环境 服务器宝塔面板 PHP 7.0 Mysql 5.5及以上版本 Linux Centos7以上 系统介绍&#xff1a; 后台权限控制&#xff1a;支持多个管理员&#xff0c;学生管理&#xff0c;学生成绩&#xff0c;教师管理&#xff0c;文章管理&#x…