首页 > 数据库 > Oracle > [20261001]nm输出的问题.txt
[20261001]nm输出的问题.txt
$ nm $(which oracle) | egrep "skgmhash|sskgphpjw"
00000000057909b0 T skgmhash
00000000057b5a30 t sskgphpjw
--//提问:小写的t,大写T有什么区别,分别表示什么意思?
--//deepseek解析如下:
nm 输出里的第二列是符号类型。 T 和 t 都表示符号在代码段 .text,也就是函数/可执行代码;区别在绑定属性:
符号 含义
T Global text symbol,全局代码符号,外部链接可见 |
t Local text symbol,局部代码符号,仅本目标文件/本模块内部可见 |
所以你这里的:
text
00000000057909b0 T skgmhash
00000000057b5a30 t sskgphpjw
含义是:
- skgmhash 是全局函数,链接时外部可见,可能被其他模块/共享库引用。
- sskgphpjw 是局部函数,通常只能被 oracle 这个可执行文件内部调用。
这也和前面反汇编对得上:sskgpwcr+1567 处直接调用:
asm
call 0x57b5a30 <sskgphpjw>
它是内部函数,所以是 t。
更一般地,nm 里大小写通常表示:
- 大写:global / external
- 小写:local / internal
常见类型:
字母 含义
T / t 代码段 .text,全局 / 局部
D / d 已初始化数据段,全局 / 局部
B / b BSS 段未初始化数据,全局 / 局部
R / r 只读数据段,全局 / 局部
U 未定义符号,通常是外部引用
W / w 弱符号
注意:t 不一定是源码里写了 static。它也可能是链接器做了本地化,或者编译时用了 -fvisibility=hidden,或者 Oracle 内部链接
脚本把很多内部函数 localize 了。
你可以用 readelf 看得更清楚:
bash
readelf -sW $(which oracle) | egrep 'skgmhash|sskgphpjw'
会看到类似:
text
Num: Value Size Type Bind Vis Ndx Name
... ... ... FUNC GLOBAL DEFAULT .text skgmhash
... ... ... FUNC LOCAL DEFAULT .text sskgphpjw
--//我的测试结果:
$ readelf -sW $(which oracle) | egrep 'skgmhash|sskgphpjw|^[A-Z]|Ndx Name$'
Symbol table '.dynsym' contains 225095 entries:
Num: Value Size Type Bind Vis Ndx Name
109910: 00000000057909b0 464 FUNC GLOBAL DEFAULT 14 skgmhash
Symbol table '.symtab' contains 402170 entries:
Num: Value Size Type Bind Vis Ndx Name
129581: 00000000057b5a30 432 FUNC LOCAL DEFAULT 14 sskgphpjw
389919: 00000000057909b0 464 FUNC GLOBAL DEFAULT 14 skgmhash
其中 Bind 列:
- GLOBAL 对应 T
- LOCAL 对应 t
对反汇编和 bpftrace 的影响:
- gdb 仍然可以按名字反汇编局部符号:
bash
(gdb) disassemble sskgphpjw
- bpftrace 的 uprobe 通常也能用局部符号名,只要 ELF 的 .symtab 还在:
bash
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:sskgphpjw
- 如果二进制被 strip 掉普通符号表,t 这类局部符号通常会消失;T 如果还在 .dynsym 里,nm -D 可能还能看到。
所以简单记:
T 是全局代码符号,t 是局部代码符号。两者都是函数,区别只在外部可见性。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3184447/ ,如需转载,请注明出处,否则将追究法律责任。