NASM 和 GDB 符号:“在符号文件中找不到任何代码段。”
Posted
技术标签:
【中文标题】NASM 和 GDB 符号:“在符号文件中找不到任何代码段。”【英文标题】:NASM and GDB Symbols: "Can't find any code sections in symbol file." 【发布时间】:2011-12-27 22:32:33 【问题描述】:我正在尝试从我正在阅读的汇编书中获得一个简单的示例。我试图让 gdb 与我正在使用 NASM 汇编器组装的简单汇编程序一起工作。下面是代码,以及elf格式的目标文件。
; Version : 1.0
; Created Date : 11/12/2011
; Last Update : 11/12/2011
; Author : Jeff Duntemann
; Description : A simple assembly app for Linux, using NASM 2.05,
; demonstrating the use of Linux INT 80H syscalls
; to display text.
; Build using these commands:
; nasm -f elf -g -F stabs eatsyscall.asm
; ld -o eatsyscall eatsyscall.o
;
SECTION .data ; Section containing initialized data
EatMsg: db "Eat at Joe's!",10
EatLen: equ $-EatMsg
SECTION .bss ; Section containing uninitialized data
SECTION .txt ; Section containing code
global _start ; Linker needs this to find the entry point!
_start:
nop ; This no_op keeps gdb happy (see text)
mov eax,4 ; Specify sys_write syscall
mov ebx,1 ; Specify File Descriptor 1: Standard Output
mov ecx,EatMsg ; Pass offset of the message
mov edx,EatLen ; Pass the length of the mesage
int 80H ; Make syscall to output the text to stdout
mov eax,1 ; Specify Exit syscall
mov ebx,0 ; Return a code of zero
int 80H ; Make syscall to terminate the program
和
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ objdump -s ./eatsyscall.o
./eatsyscall.o: file format elf32-i386
Contents of section .data:
0000 45617420 6174204a 6f652773 210a Eat at Joe's!.
Contents of section .txt:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .stab:
0000 00000000 64000100 00000000 ....d.......
Contents of section .stabstr:
0000 00
我正在使用以下命令进行组装:
nasm -f elf -g -F stabs eatsyscall.asm
我正在使用以下命令进行链接:
ld -o eatsyscall eatsyscall.o
当我在可执行文件上运行 GDB 时,我得到以下信息:
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ gdb eatsyscall
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/mehoggan/Code/AsmWork/eatsyscall/eatsyscall...Can't find any code sections in symbol file
(gdb) quit
除了上面的操作,我还需要做什么才能让 gdb 读取使用 -g 标志指定给 NASM 的调试符号?
仅供参考
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ cat /etc/*release*
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=11.10
DISTRIB_CODENAME=oneiric
DISTRIB_DESCRIPTION="Ubuntu 11.10"
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ uname -a
Linux mehoggan 3.0.0-12-generic-pae #20-Ubuntu SMP Fri Oct 7 16:37:17 UTC 2011 i686 i686 i386 GNU/Linux
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$
--更新--
即使我使用以下命令采用 64 位路由,我仍然没有成功:
mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ nasm -f elf64 -g -F stabs eatsyscall.asm mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ ld -o eatsyscall eatsyscall.o -melf_x86_64 mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ ./eatsyscall bash: ./eatsyscall: 无法执行二进制文件 mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$ objdump -seatsyscall.o
eatsyscall.o:文件格式elf64-x86-64
.data 部分的内容: 0000 45617420 6174204a 6f652773 210a 在乔家吃饭!. .txt 部分的内容: 0000 9048b804 00000000 00000048 bb010000 .H..........H.... 0010 00000000 0048b900 00000000 00000048 .....H..........H 0020 ba0e0000 00000000 00cd8048 b8010000 ...... 0030 00000000 0048bb00 00000000 000000cd .....H....... 0040 80 . .stab 部分的内容: 0000 00000000 64000100 00000000 ....d....... .stabstr 部分的内容: 0000 00 . mehoggan@mehoggan:~/Code/AsmWork/eatsyscall$
【问题讨论】:
【参考方案1】:用section .text
代替section .txt
怎么样?`
即:
SECTION .data ; Section containing initialized data
EatMsg: db "Eat at Joe's!",10
EatLen: equ $-EatMsg
SECTION .bss ; Section containing uninitialized data
SECTION .text ; instead of .txt
之后在 gdb 中应该可以正常工作,如果您使用的是 x64 架构,请使用 x64 标志。
【讨论】:
【参考方案2】:我想我和你有同样的问题。几乎是字面意思。我正在研究 Duntemann 书中的相同示例。 (源代码的唯一区别是我将字符串的一部分从 Joe 更改为 Bob,同时试图确认我在源代码中所做的差异对编译的可执行文件有预期的影响。)
我的发现有点好奇。我有两台计算机,并且正在使用同步的保管箱目录在每台计算机上交替工作。旧机器运行的是 Ubuntu Karmic,因为它对 Duntemann 书中的大部分内容提供了最好的支持。我也尝试将 Karmic 安装在新机器上,但有些东西根本无法安装,因为它不再受支持。所以我在上面运行 Ubuntu Oneiric。
事情就是这样。我可以在两台机器上编译和运行exe。但是在 Oneiric 机器上编译的任何东西似乎都缺少 gdb/kdbg/Insight 乐于使用的符号信息。在 Karmic 机器上编译的东西运行良好。一旦在 Karmic 机器上构建并与 Dropbox 同步,gdb/kdbg/Insight 将在 Oneiric 机器上运行 THAT exe。
所以问题似乎是 Oneiric 上的编译过程。它丢失或更改了一些会破坏调试器正常使用它的能力的东西。
这里是 Karmic 对象文件的转储:
$ cat karmic.txt
eatsyscall.o: file format elf32-i38
Contents of section .data:
0000 45617420 61742042 6f622773 210a Eat at Bob's!.
Contents of section .text:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .comment:
0000 00546865 204e6574 77696465 20417373 .The Netwide Ass
0010 656d626c 65722032 2e30352e 303100 embler 2.05.01.
Contents of section .stab:
0000 01000000 00000a00 02000000 01000000 ................
0010 64000000 00000000 00000000 44001a00 d...........D...
0020 00000000 00000000 44001b00 01000000 ........D.......
0030 00000000 44001c00 06000000 00000000 ....D...........
0040 44001d00 0b000000 00000000 44001e00 D...........D...
0050 10000000 00000000 44001f00 15000000 ........D.......
0060 00000000 44002100 17000000 00000000 ....D.!.........
0070 44002200 1c000000 00000000 44002300 D.".........D.#.
0080 21000000 !...
Contents of section .stabstr:
0000 00656174 73797363 616c6c2e 61736d00 .eatsyscall.asm.
这里是 Oneiric 目标文件的转储:
$ cat oneiric.txt
eatsyscall.o: file format elf32-i386
Contents of section .data:
0000 45617420 61742042 6f622773 210a Eat at Bob's!.
Contents of section .text:
0000 90b80400 0000bb01 000000b9 00000000 ................
0010 ba0e0000 00cd80b8 01000000 bb000000 ................
0020 00cd80 ...
Contents of section .stab:
0000 01000000 00000b00 02000000 01000000 ................
0010 64000000 00000000 00000000 44001a00 d...........D...
0020 00000000 00000000 44001b00 01000000 ........D.......
0030 00000000 44001c00 06000000 00000000 ....D...........
0040 44001d00 0b000000 00000000 44001e00 D...........D...
0050 10000000 00000000 44001f00 15000000 ........D.......
0060 00000000 44002100 17000000 00000000 ....D.!.........
0070 44002200 1c000000 00000000 44002300 D.".........D.#.
0080 21000000 00000000 64000000 00000000 !.......d.......
Contents of section .stabstr:
0000 00656174 73797363 616c6c2e 61736d00 .eatsyscall.asm.
你可以看到这两个文件是不同的(在非工作的 Oneiric 文件的末尾有几个额外的字节)。无论 nasm 在 Oneiric 上做什么,调试器似乎都不能正常运行。
【讨论】:
只是为了跟进:我使用 Bless 编辑了不符合要求的 .o 文件,并手动将 .stab 部分中最终“d”对应的 64 归零。使用此手动更改的文件重建 exe 后,一切正常。这 64 是否表示它正在尝试创建 64 位目标文件? (我的 Oneiric 版本是 32 位的。)【参考方案3】:似乎可以与当前 CVS 版本的 GDB 一起正常工作:“GNU gdb (GDB) 7.3.50.20111108-cvs”,也可以与 GDB 7.2 一起使用。
听起来“Ubuntu/Linaro 7.3-0ubuntu2”在某种程度上被破坏了。
【讨论】:
【参考方案4】:尝试使用节/段 .text 而不是 .txt 或 .code :)
【讨论】:
以上是关于NASM 和 GDB 符号:“在符号文件中找不到任何代码段。”的主要内容,如果未能解决你的问题,请参考以下文章