assembly - 交叉组装臂组件时 _start 运行之前的 Segfault
问题描述
我正在尝试交叉组装我的手臂组件,因为我的目标系统(Raspberry Pi 4B)没有屏幕。作为一个你好世界,我有mcve.s
:
.global main
.section .text, "ax"
main:
movs r3, #10
组装使用:
arm-none-eabi-gcc mcve.s --specs=nosys.specs -g -o mcve
当使用并运行转移到 piscp
时,我得到一个段错误。当我将它加载到gdb
(+ gef
) 时,我立即得到一个段错误:
Reading symbols from mcve...
gef➤ start
[+] Breaking at '{<text variable, no debug info>} 0x821c <main>'
[+] Breaking at '{<text variable, no debug info>} 0x816c <_start>'
[+] Breaking at entry-point: 0x816c
[!] Command 'entry-break' failed to execute properly, reason: During startup program terminated with signal SIGSEGV, Segmentation fault.
环顾四周,我找到了几种诊断方法,但没有任何帮助。
starti
仍然立即崩溃:
gef➤ starti
Starting program: /path/mcve
During startup program terminated with signal SIGSEGV, Segmentation fault.
就像在入口点上打破一样:
gef➤ info files
Symbols from "/path/mcve".
Local exec file:
`/path/mcve', file type elf32-littlearm.
Entry point: 0x816c
0x00008000 - 0x00008018 is .init
0x00008018 - 0x00008650 is .text
0x00008650 - 0x00008668 is .fini
0x00008668 - 0x000086b4 is .rodata
0x000086b4 - 0x000086bc is .ARM.exidx
0x000086bc - 0x000086c0 is .eh_frame
0x000186c0 - 0x000186c8 is .init_array
0x000186c8 - 0x000186cc is .fini_array
0x000186d0 - 0x00018b04 is .data
0x00018b04 - 0x00018b44 is .bss
gef➤ break *0x816c
Breakpoint 1 at 0x816c
gef➤ start
[+] Breaking at '{<text variable, no debug info>} 0x821c <main>'
[+] Breaking at '{<text variable, no debug info>} 0x816c <_start>'
[+] Breaking at entry-point: 0x816c
[!] Command 'entry-break' failed to execute properly, reason: During startup program terminated with signal SIGSEGV, Segmentation fault.
虽然,我能够获得以下来源_start
:
gef➤ disass _start
Dump of assembler code for function _start:
0x0000816c <+0>: ldr r3, [pc, #148] ; 0x8208 <_start+156>
0x00008170 <+4>: cmp r3, #0
0x00008174 <+8>: ldreq r3, [pc, #128] ; 0x81fc <_start+144>
0x00008178 <+12>: mov sp, r3
0x0000817c <+16>: bl 0x80e4 <_stack_init>
0x00008180 <+20>: movs r1, #0
0x00008184 <+24>: mov r11, r1
0x00008188 <+28>: mov r7, r1
0x0000818c <+32>: ldr r0, [pc, #120] ; 0x820c <_start+160>
0x00008190 <+36>: ldr r2, [pc, #120] ; 0x8210 <_start+164>
0x00008194 <+40>: subs r2, r2, r0
0x00008198 <+44>: bl 0x82a8 <memset>
0x0000819c <+48>: ldr r3, [pc, #92] ; 0x8200 <_start+148>
0x000081a0 <+52>: cmp r3, #0
0x000081a4 <+56>: beq 0x81b0 <_start+68>
0x000081a8 <+60>: mov lr, pc
0x000081ac <+64>: mov pc, r3
0x000081b0 <+68>: ldr r3, [pc, #76] ; 0x8204 <_start+152>
0x000081b4 <+72>: cmp r3, #0
0x000081b8 <+76>: beq 0x81c4 <_start+88>
0x000081bc <+80>: mov lr, pc
0x000081c0 <+84>: mov pc, r3
0x000081c4 <+88>: movs r0, #0
0x000081c8 <+92>: movs r1, #0
0x000081cc <+96>: movs r4, r0
0x000081d0 <+100>: movs r5, r1
0x000081d4 <+104>: ldr r0, [pc, #56] ; 0x8214 <_start+168>
0x000081d8 <+108>: cmp r0, #0
0x000081dc <+112>: beq 0x81e8 <_start+124>
0x000081e0 <+116>: ldr r0, [pc, #48] ; 0x8218 <_start+172>
0x000081e4 <+120>: bl 0x84fc <atexit>
0x000081e8 <+124>: bl 0x8220 <__libc_init_array>
0x000081ec <+128>: movs r0, r4
0x000081f0 <+132>: movs r1, r5
0x000081f4 <+136>: bl 0x821c <main>
0x000081f8 <+140>: bl 0x8018 <exit>
0x000081fc <+144>: andeq r0, r8, r0
0x00008200 <+148>: andeq r0, r0, r0
0x00008204 <+152>: andeq r0, r0, r0
0x00008208 <+156>: andeq r0, r0, r0
0x0000820c <+160>: andeq r8, r1, r4, lsl #22
0x00008210 <+164>: andeq r8, r1, r4, asr #22
0x00008214 <+168>: ; <UNDEFINED> instruction: 0x000084fc
0x00008218 <+172>: andeq r8, r0, r12, lsl r5
为了尝试gcc
摆脱等式,我将入口点更改为_start
在我的程序集中,ld
并as
直接使用:
arm-none-eabi-as -g mcve.s -o mcve.o
arm-none-eabi-ld mcve.o -o mcve
但是我得到了与以前相同的行为(除了diass
显示我的程序集)。
解决方案
我使用了错误的工具链♂️。
我手动下载并使用了gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2;虽然回想起来,我不太清楚为什么。
我从我的虚拟机中清除了它,然后运行
sudo apt install gcc-arm-linux-gnueabihf
然后,我使用了已安装的二进制文件:
arm-linux-gnueabihf-as -g mcve.s -o mcve.o
arm-linux-gnueabihf-ld mcve.o -o mcve
现在它工作正常。
现在我又花了一个下午摆弄错误的工具链。我对现有的 Kali 进行了核对,并选择安装 64 位版本。这次的行为是它可以很好地组装,但是运行时会说Illegal Instruction
,并且加载时gdb
会导致它无限期挂起(但不会导致任何错误)。
解决方法是改用:
sudo apt install gcc-aarch64-linux-gnu
推荐阅读
- regex - Is there a way I can use a REGEX in Power Query (from Excel) without using R?
- automation - Why property "NewSession" in the activity Open Browser of RPA UIPath not working properly? I still can see the old values in the browser
- c# - 遍历列表令牌环 C#
- mysql - MySQL 分区或删除旧数据?
- php - PDO 在准备好的语句中使用引号来调用 mysql 过程?
- php - Laravel loginUsingId() 不记得新页面上的登录状态
- windows - 从一组 png 图像创建动画 gif
- typescript - TypeScript - 函数内没有“分配之前使用变量”
- sql - 计算从日期到日期结束的格式 hh:mm:ss 差异的最佳方法是什么?
- android - 如何在颤振中正确使用地理定位器包?