gcc 什么时候会为函数生成 <UNDEFINED> 指令
When will gcc generate <UNDEFINED> instructions for function
我最近 运行 陷入了 SEGV_MAPPER 故障,由故障地址 0xfffffab8 引起。但是没有地方显式调用这个地址。所以我使用 arm-linux-androideabi-objdump 转储了 so 库,并在函数中找到了几个地方,例如:
000a42f8 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()>:
a42f8: 4b08 ldr r3, [pc, #32] ; (a431c <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x24>)
a42fa: 4a09 ldr r2, [pc, #36] ; (a4320 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x28>)
a42fc: 447b add r3, pc
a42fe: b510 push {r4, lr}
a4300: 4604 mov r4, r0
a4302: 589a ldr r2, [r3, r2]
a4304: 4907 ldr r1, [pc, #28] ; (a4324 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x2c>)
a4306: 320c adds r2, #12
a4308: 6022 str r2, [r4, #0]
a430a: 585b ldr r3, [r3, r1]
a430c: f103 0108 add.w r1, r3, #8
a4310: f840 1f04 str.w r1, [r0, #4]!
a4314: f7c3 ee80 blx 68018 <std::__1::ios_base::~ios_base()@plt>
a4318: 4620 mov r0, r4
a431a: bd10 pop {r4, pc}
a431c: 7758 strb r0, [r3, #29]
a431e: 0024 movs r4, r4
a4320: fabc ffff ; <UNDEFINED> instruction: 0xfabcffff
a4324: fab8 ffff ; <UNDEFINED> instruction: 0xfab8ffff
显然,这个问题是由访问这些未定义的指令引起的。所以我的问题是,为什么 gcc 会生成这些未定义的指令以及何时访问这些指令?它像编译器生成的某种保护吗?谢谢大家。
通常这些指令根本不是指令;它们要么是函数使用的内联数据,要么只是编译器或链接器发出的填充,以保持 function/method 地址正确对齐。无论哪种方式,除非您在某处跳转错误(例如损坏的函数指针),否则它们永远不会执行。
注意 - 在您的情况下,它们都是内联数据类型;检查在 a42f8、a42fa 和 a4304 进行的 PC 相对访问。
我最近 运行 陷入了 SEGV_MAPPER 故障,由故障地址 0xfffffab8 引起。但是没有地方显式调用这个地址。所以我使用 arm-linux-androideabi-objdump 转储了 so 库,并在函数中找到了几个地方,例如:
000a42f8 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()>:
a42f8: 4b08 ldr r3, [pc, #32] ; (a431c <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x24>)
a42fa: 4a09 ldr r2, [pc, #36] ; (a4320 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x28>)
a42fc: 447b add r3, pc
a42fe: b510 push {r4, lr}
a4300: 4604 mov r4, r0
a4302: 589a ldr r2, [r3, r2]
a4304: 4907 ldr r1, [pc, #28] ; (a4324 <std::__1::basic_ostream<char, std::__1::char_traits<char> >::~basic_ostream()+0x2c>)
a4306: 320c adds r2, #12
a4308: 6022 str r2, [r4, #0]
a430a: 585b ldr r3, [r3, r1]
a430c: f103 0108 add.w r1, r3, #8
a4310: f840 1f04 str.w r1, [r0, #4]!
a4314: f7c3 ee80 blx 68018 <std::__1::ios_base::~ios_base()@plt>
a4318: 4620 mov r0, r4
a431a: bd10 pop {r4, pc}
a431c: 7758 strb r0, [r3, #29]
a431e: 0024 movs r4, r4
a4320: fabc ffff ; <UNDEFINED> instruction: 0xfabcffff
a4324: fab8 ffff ; <UNDEFINED> instruction: 0xfab8ffff
显然,这个问题是由访问这些未定义的指令引起的。所以我的问题是,为什么 gcc 会生成这些未定义的指令以及何时访问这些指令?它像编译器生成的某种保护吗?谢谢大家。
通常这些指令根本不是指令;它们要么是函数使用的内联数据,要么只是编译器或链接器发出的填充,以保持 function/method 地址正确对齐。无论哪种方式,除非您在某处跳转错误(例如损坏的函数指针),否则它们永远不会执行。
注意 - 在您的情况下,它们都是内联数据类型;检查在 a42f8、a42fa 和 a4304 进行的 PC 相对访问。