nm命令如何查看目标文件符号表

概述

  • 在Linux环境下,nm 是一个用来查看目标文件(如可执行文件、动态库或静态库)符号表的工具。
  • 使用nm命令可以很方便的查看可执行程序中有哪些函数以及动态库中有哪些导出函数。

nm命令简述

打印结果含义

  • 先使用nm命令查看一个可执行程序,分析下结果是什么意思
  •   [root@dev nmparse]# nm res00000000004004e8 T _init0000000000600df8 t __init_array_end0000000000600df0 t __init_array_start00000000004006d8 R _IO_stdin_usedw _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable00000000004006c0 T __libc_csu_fini0000000000400650 T __libc_csu_initU __libc_start_main@@GLIBC_2.2.50000000000400621 T mainU myMathAdd00000000004005a0 t register_tm_clones0000000000400530 T _start0000000000601028 D __TMC_END__0000000000400616 T _Z6myfuncv
    
  • 可以看到有三列数据,第一列是地址,第二列是符号类型标识符,第三列是符号名称
    • 地址:即符号在内存中的地址
    • 符号类型标识符
      • T:全局函数
      • B: 静态变量
      • D: 未初始化的数据段
      • U: 外部引用。比如调用的动态库函数
    • 符号名称: 它代表了具体的函数名、变量名或者标签等

nm参数

  • 可以通过nm --help命令查看nm的参数都有哪些,这里重点介绍常用的几个
  • nm -g: 只显示全局符号,一般用来查看可执行程序中都有哪些函数
  • nm -D: 只显示动态符号, 一般用来查看动态库中导出了哪些函数
  • nm -C: 对C++等语言产生的低级符号名称进行解码,显示为可读的形式

查看动态库的导出函数

  • 我们写两个函数,然后生成一个动态库

实现动态库

  • 文件内容
    • myMath.h
    •   #ifndef __MY_MATH_H__#define __MY_MATH_H__int myMathAdd(int num1, int num2);int myMathMinus(int num1, int num2);#endif
      
    • myMath.cpp
    •   #include "myMath.h"int myMathAdd(int num1, int num2){return num1 + num2;}int myMathMinus(int num1, int num2){return num1 - num2;}
      
  • 生成动态库
    •   g++ -c myMath.cpp -o myMath.o -fPICg++ -shared -o libmyMath.so myMath.o
      

使用nm -D命令查看动态库的导出函数

  •   nm -D libmyMath.so
    
  • 可以看到我们写的那两个函数 myMathAddmyMathMinus
  •   [root@dev nmparse]# nm -D libmyMath.so0000000000201020 B __bss_startw __cxa_finalize0000000000201020 D _edata0000000000201028 B _endw __gmon_start__w _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable00000000000005bd T _Z11myMathMinusii00000000000005a9 T _Z9myMathAddii
    
  • 但是这两个函数前后都出现了特殊符号,这是因为默认使用的C++编译器,C++是支持重载的,因此在编译出来的库,导出函数不仅包含函数名,还包含参数个数个类型。因此会出现特殊符号。
  • 可以加一个 -C 参数,把特殊符号转换为可读符号。可以看到导出函数包含了参数个数和参数类型
  •   [root@dev nmparse]# nm -D -C libmyMath.so0000000000201020 B __bss_startw __cxa_finalize0000000000201020 D _edata0000000000201028 B _endw __gmon_start__w _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable00000000000005ed T myMathMinus(int, int)00000000000005d9 T myMathAdd(int, int)
    
  • 如果不想导出函数的参数个数和类型,编译动态库时可指定使用C编译器编译, 修改myMath.h如下
  •   #ifndef __MY_MATH_H__#define __MY_MATH_H__extern "C" {int myMathAdd(int num1, int num2);int myMathMinus(int num1, int num2);}#endif
    
  • 重新编译动态库后在使用nm -D命令查看,可以看到导出函数只有函数名了。
  •   [root@dev nmparse]# nm -D libmyMath.so0000000000201020 B __bss_startw __cxa_finalize0000000000201020 D _edata0000000000201028 B _endw __gmon_start__w _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable00000000000005c9 T myMathAdd00000000000005dd T myMathMinus
    

查看可执行程序中的函数

生成可执行程序

  • 写一个可执行程序,链接上面写的那个库文件
  • 文件内容
    •   #include "myMath.h"int dataTemp = 0;int myfunc(){return 0;}int main(){int sum = 0;sum = myMathAdd(10, 20);return 0;}
  • 生成可执行程序并链接动态库
    •   gcc main.cpp -L. -lmyMath -o res
      

使用nm -g命令查看可执行程序中的函数

  •   nm -g res
    
  • 可以看到自己实现的函数myfunc, 全局变量dataTemp以及引用的外部函数myMathAdd
  •   [root@dev nmparse]# nm -g -C res0000000000601024 B __bss_start0000000000601020 D __data_start0000000000601020 W data_start0000000000601028 B dataTemp0000000000400560 T _dl_relocate_static_pie00000000004006e0 R __dso_handle0000000000601024 D _edata0000000000601030 B _end00000000004006c8 T _finiw __gmon_start__00000000004004e8 T _init00000000004006d8 R _IO_stdin_usedw _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable00000000004006c0 T __libc_csu_fini0000000000400650 T __libc_csu_initU __libc_start_main@@GLIBC_2.2.50000000000400621 T mainU myMathAdd0000000000400530 T _start0000000000601028 D __TMC_END__0000000000400616 T myfunc()
    

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

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

相关文章

【IM】如何保证消息可用性(一)

目录 1. 基本概念1.1 长连接 和 短连接1.2 PUSH模式和PULL模式 2. 背景介绍2.1 理解端到端的思想 3. 方案选型3.1 技术挑战3.2 技术目标 1. 基本概念 在讲解消息可用性之前,需要理解几个通信领域的基本概念。 1.1 长连接 和 短连接 什么是长连接,短连接…

MQ面试题之Kafka

前言 前文介绍了消息队列相关知识,并未针对某个具体的产品,所以略显抽象。本人毕业到现在使用的都是公司内部产品,对于通用产品无实际经验,但是各种消息中间件大差不差,故而本次选择一个相对较熟悉的Kafka进行详细介绍…

YoloV8改进策略:BackBone改进|DCNv4最新实践|高效涨点|多种改进教程|完整论文翻译

摘要 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.77,涨点明显! DCNv4是可变形卷积的第四版,速度和v3相比有了大幅度的提升,但是环境搭建有一定的难度,对新手不太友好。如果在使用过程遇到编译的问题,请严格按照我写的环境配置。 …

编程笔记 html5cssjs 061 JavaScrip简介

编程笔记 html5&css&js 061 JavaScrip简介 一、JavaScript概述二、JavaScript的主要特点三、历史延革四、JavaScript与前端开发小结 JavaScript 是 web 开发者必学的三种语言之一:HTML 定义网页的内容;CSS 规定网页的布局;JavaScript…

RBD —— Fracture SOP

目录 Assemble —— 清理破碎操作并生成碎片 Boolean Fracture —— 使用切割面破碎输入的几何体 Convex Decomposition —— 将输入几何体分解为凸线段 Glue Cluster —— 构建cluster值想glue约束添加强度 RBD Material Fracture —— 基于材质类型预破碎 Concrete Gl…

C++ 之LeetCode刷题记录(二十)

😄😊😆😃😄😊😆😃 开始cpp刷题之旅。 依旧是追求耗时0s的一天。 110. 平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二…

RK3588平台开发系列讲解(视频篇)RKMedia框架

文章目录 一、 RKMedia框架介绍二、 RKMedia框架API三、 视频处理流程四、venc 测试案例沉淀、分享、成长,让自己和他人都能有所收获!😄 📢RKMedia是RK提供的一种多媒体处理方案,可实现音视频捕获、音视频输出、音视频编解码等功能。 一、 RKMedia框架介绍 功能: VI(输…

【Redis笔记】缓存——缓存分类、缓存穿透、缓存雪崩、缓存击穿

缓存 缓存(Cache),就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于高速存储媒介上。 缓存的本质就是用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据,减少数据库IO&#…

2401llvm,匹配器参考

返回类型名字参数Matcher<attr>attrMatcher<Attr>... 匹配属性. 属性可附加各种不同的语法(包括关键字,C11属性,GNU的__attribute和MSVC的__declspec,和#pragma等).也可能是隐含的. 给定 struct [[nodiscard]] Foo{};void bar(int * __attribute__((nonnull)) );…

一起学习ETCD系列——运维操作之etcdctl使用

文章目录 概要一、命令二、实操2.1、基本操作2.2、watch2.3、租约2.4、分布式锁2.5、角色2.6、用户2.7、认证2.8、集群 概要 本文主要用来总结ETCD客户端ctcdctl的命令操作&#xff0c;在运维过程中可能常常用到的。 一、命令 etcd工具 etcdctl官方命令示例 [roottest etcd…

【牛客刷题】笔试选择题整理(day1-day2)

每天都在进步呀 文章目录 1. 小数求模运算2. 进程的分区&#xff0c;这里说的不是JVM的分区。进程中&#xff0c;方法存放在方法区。3. 访问权限控制4. 继承与多态5. 与equals()6. 类加载顺序7. super()与this()7.1 super7.1.1 super调用父类构造方法7.1.2 super调用父类属性和…

私人漫画图书馆:分类管理,一目了然 | 开源日报 No.157

tachiyomiorg/tachiyomi Stars: 26.9k License: Apache-2.0 tachiyomi 是一个免费开源的安卓漫画阅读器。 该项目的主要功能、关键特性、核心优势包括&#xff1a; 从多种来源在线阅读本地阅读已下载内容可配置的阅读器&#xff0c;具有多个查看器、翻页方向和其他设置支持追…

大数据处理系统的架构

大数据处理系统的架构介绍 Lamdba架构 Lambda 架构是一种用于处理大规模数据的设计模式,旨在结合批处理和实时处理,以应对对大量数据进行高效处理的需求。Lambda 架构的核心思想是将数据处理流程分为批处理层和实时处理层,并将它们整合在一起,以获得高可扩展性和灵活性。…

什么叫高斯分布?

高斯分布&#xff0c;也称为正态分布&#xff0c;是统计学中最常见的概率分布之一。它具有钟形曲线的形态&#xff0c;对称分布在均值周围&#xff0c;且由均值和标准差两个参数完全描述。 高斯分布的概率密度函数&#xff08;Probability Density Function, PDF&#xff09;可…

mysql数据库的备份和恢复

登录&#xff1a; mysql -uroot -proot -h127.0.0.1 退出&#xff1a; mysql > exit; mysql > quit; mysql > \q;备份所有数据库 mysqldump命令备份所有数据库的语法如下&#xff1a; mysqldump -u username -p -all-databases > BackupName.sql 示例&#xf…

SpringBoot 有什么优点?

Spring Boot 是一个用于简化和加速 Spring 框架应用程序开发的项目。它构建在 Spring 框架之上&#xff0c;提供了一种快速开发、简化配置和集成的方式。以下是 Spring Boot 的一些优点&#xff1a; 1、简化配置&#xff1a; Spring Boot 使用约定大于配置的理念&#xff0c;通…

[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

DevOps系列文章之 GitLabCI汇总

GitlabCI环境搭建 前提 先安装 docker Docker容器化安装 docker pull gitlab/gitlab-ee:12.4.0-ee.0 创建挂载目录 mkdir -p /srv/gitlab mkdir -p /srv/gitlab/config # 映射到 Glitlab 容器中的配置目录 mkdir -p /srv/gitlab/logs # 映射到 Glitlab 容器中的日志目录 m…

mac裁剪图片

今天第一次用mac裁剪图片&#xff0c;记录一下过程&#xff0c;差点我还以为我要下载photoshop了&#xff0c; 首先准备好图片 裁剪的目的是把图片的标题给去掉&#xff0c;但是不能降低分辨率&#xff0c;否则直接截图就可以了 解决办法 打开原始图片(不要使用预览&#xf…

Python环境下基于机器学习的NASA涡轮风扇发动机剩余使用寿命RUL预测

本例所用的数据集为C-MAPSS数据集&#xff0c;C-MAPSS数据集是美国NASA发布的涡轮风扇发动机数据集&#xff0c;其中包含不同工作条件和故障模式下涡轮风扇发动机多源性能的退化数据&#xff0c;共有 4 个子数据集&#xff0c;每个子集又可分为训练集、 测试集和RUL标签。其中&…