这接近于使用GCC生成可读组件?,但我的上下文是avr-gcc(并相应地avr-objdump)Atmel(虽然,我想它将适用于GCC董事会).
问题是,我有一个多个.c和.cpp文件的项目; 最终被编译成可执行文件,其名称与'master'.cpp文件相同.在这个过程中,我可以通过两种方式获得汇编列表:
gcc发出汇编列表源(参见Linux汇编和反汇编和简介)-S; 在这种情况下,我得到一个文件,内容如下:... loop: push r14 push r15 push r16 push r17 push r28 push r29 /* prologue: function / / frame size = 0 */ ldi r24,lo8(13) ldi r22,lo8(1) call digitalWrite rjmp .L2 .L3: ldi r24,lo8(MyObj) ldi r25,hi8(MyObj) call _ZN16MYOBJ7connectEv .L2: ldi r24,lo8(MyObj) ldi r25,hi8(MyObj) call _ZN16MYOBJ11isConnectedEv ...
(还没有尝试过;但我想这段代码是可编译的/可构建的....)
objdump使用该-S开关发出汇编列表源; 在这种情况下,我得到一个文件,内容如下:
...
0000066a <init>:
void init()
{ …如果我在(linux amd64).o文件上运行objdump -d,函数调用将显示,而不会完成链接时间分辨率.例:
90: 66 89 44 24 1c mov %ax,0x1c(%rsp)
95: 44 89 74 24 10 mov %r14d,0x10(%rsp)
9a: e8 00 00 00 00 callq 9f <foo+0x9f>
9f: 83 f8 ff cmp $0xffffffffffffffff,%eax
a2: 74 5e je 102 <foo+0x102>
Run Code Online (Sandbox Code Playgroud)
函数中的一个分支正确显示,但callq只是为链接器输入的存根(有四个字节的零可供链接器放入正确的地址).
有没有一种方法,没有实际链接,以获得已解决函数名称的汇编列表?我不关心最终将使用的地址,只关心函数的名称.该信息必须位于.o文件中,因为链接器必须使用它来完成其工作.
我问,因为有问题的代码进入的共享库大约是140Mb,并且需要很长时间才能运行objdump -d来获取asm转储,并将所有函数调用解析为实际名称.
我在下面编写了简单的C程序(test.c): -
#include<stdio.h>
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并执行以下内容以了解.bss段中的大小更改.
gcc test.c -o test
size test
Run Code Online (Sandbox Code Playgroud)
输出结果如下: -
text data bss dec hex filename
1115 552 8 1675 68b test
Run Code Online (Sandbox Code Playgroud)
我没有声明全局或静态范围.所以请解释为什么bss段大小为8个字节.
我做了以下改变: -
#include<stdio.h>
int x; //declared global variable
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但令我惊讶的是,输出与以前相同: -
text data bss dec hex filename
1115 552 8 1675 68b test
Run Code Online (Sandbox Code Playgroud)
请解释.然后我初始化了全球: -
#include<stdio.h>
int x=67; //initialized global variable
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
数据段大小按预期增加,但我没想到bss段的大小会减少到4(相反,当没有声明任何内容时为8).请解释.
text data bss dec hex filename …Run Code Online (Sandbox Code Playgroud) 我的目标是将 Rust 程序编译为尽可能小的二进制文件并提取机器代码。我编写了一个非常简单的程序来测试。
.cargo/配置
[target.x86_64-pc-windows-gnu]
rustflags = ["-C", "link-args=-e _start -static -nostartfiles"]
Run Code Online (Sandbox Code Playgroud)
Cargo.toml
[package]
name = "r"
version = "0.1.0"
edition = "2021"
[profile.release]
panic = "abort"
opt-level = "z"
lto = true
codegen-units = 1
Run Code Online (Sandbox Code Playgroud)
主程序.rs
#![no_std]
#![no_main]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
unsafe fn _start() -> isize {
42
}
Run Code Online (Sandbox Code Playgroud)
我编译cargo build --target x86_64-pc-windows-gnu --release并提取该.text部分objcopy -j .text -O binary target/x86_64-pc-windows-gnu/release/r.exe r.bin,但是当我显示机器代码时,我得到的比我预期的要多:
% objdump -D -b binary …Run Code Online (Sandbox Code Playgroud) 如何用源代码编译库?
我正在使用android ndk开发本机库.有时我从logcat获得崩溃转储消息.
06-18 15:24:58.545: INFO/DEBUG(24667): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-18 15:24:58.545: INFO/DEBUG(24667): Build fingerprint: 'nvidia/harmony/harmony/harmony:2.2/FRF91/20110304.134348:eng/test-keys'
06-18 15:24:58.545: INFO/DEBUG(24667): pid: 25870, tid: 26261 >>> com.andtv <<<
06-18 15:24:58.545: INFO/DEBUG(24667): signal 11 (SIGSEGV), fault addr 4a7b041c
06-18 15:24:58.545: INFO/DEBUG(24667): r0 4a7b041c r1 4a75220c r2 00000200 r3 0000006d
06-18 15:24:58.545: INFO/DEBUG(24667): r4 4a7b041d r5 00000000 r6 82434ad0 r7 4a752768
06-18 15:24:58.545: INFO/DEBUG(24667): r8 4a75220c r9 000004b4 10 4a752777 fp 00000000 …Run Code Online (Sandbox Code Playgroud) 转储可执行文件时,我只希望将代码段打印在标准输出上,而不是代码的偏移量和二进制形式。我无法从
man objdump
Run Code Online (Sandbox Code Playgroud)
有办法吗?
我正在编写一个反汇编程序,我正在查看指令格式(并手动进行一些反汇编),然后我遇到了一条似乎无法解码的指令.
该特定指令的输出(来自objdump)是:
c6 05 14 a0 04 08 01 movb $0x1,0x804a014
Run Code Online (Sandbox Code Playgroud)
但是,我不明白指令是如何解码的,因为操作码c6应该是MOV Eb Ib(Mod R/M到imm8).
有人可以告诉我它是如何解码的吗?
谢谢!
我目前正在构建一个可执行的裸机,它包含一些包含代码的特殊部分.但是,当我这样做时,objdump -d我只获取.text和.init.text部分的代码.该联机帮助页objdump仅表示在使用该-d选项时"仅拆解那些预计包含说明的部分" .这些是哪些部分,以及如何objdump解释要解码的部分?我知道我也可以使用该-D选项来获得所有部分的完整解码,但这通常比我需要的要多得多.
我的理解是,当您使用 编译 C 代码时gcc -g,gcc 将插入调试信息,其中包括对原始源代码的引用(例如行号)。然后其他程序如 gdb 和 objdump 可以稍后恢复这些引用。作为示例,我们将使用objdump -Swhich 打印与相应源代码交错的程序集。
我的目标是将编译后的二进制文件复制到另一台计算机,并且仍然能够检索此调试信息。但是,目前,当我这样做时,所有调试信息都丢失了。我也不介意复制源文件,但是第二台计算机运行的是不同的操作系统,所以文件结构不同,我不能将源文件放在完全相同的绝对位置,这会阻止 objdump 找到源代码。我查看了二进制文件,看到了一个看起来像这样的部分,中间穿插着一堆二进制文件:
/home/path/to/source/code
我尝试编辑它以匹配源的新路径,但它只是使二进制文件无效。
我还研究了gcc 标志,希望其中一个允许指定源代码的相对路径而不是绝对路径,但我找不到类似的东西。
作为参考,这是我希望从中获得的输出类型objdump - S:
0804840b <main>:
#include <stdio.h>
int main(){
804840b: 8d 4c 24 04 lea 0x4(%esp),%ecx
804840f: 83 e4 f0 and $0xfffffff0,%esp
8048412: ff 71 fc pushl -0x4(%ecx)
8048415: 55 push %ebp
8048416: 89 e5 mov %esp,%ebp
8048418: 51 push %ecx
8048419: 83 ec 14 sub $0x14,%esp
for(int varName = 0; varName < …Run Code Online (Sandbox Code Playgroud) objdump ×10
c ×3
gcc ×3
assembly ×2
disassembly ×2
linux ×2
android ×1
android-ndk ×1
bare-metal ×1
gdb ×1
i386 ×1
object-files ×1
rust ×1
size ×1
x86 ×1