GDB显示错误的本地变量地址 来源:反汇编: QEMU和GDB 编译链接器脚本build / loader.ld我尝试过的事情: PS:

问题描述

下面的代码是第二阶段加载程序的摘录。它在Real Mode中运行,并由引导加载程序调用。问题在于GDB向堆栈中分配的变量显示了错误的地址。

|------|------|------|
|Name  |GDB   |Actual|
|------|------|------|
|char a|0x7be7|0x7bfb|
|char b|0x7be6|0x7bfa|
|------|------|------|

来源:

__attribute__((noreturn)) 
void __main()
{
    char a = 'A';
    char b = 'B';
    while(1);
}

反汇编:

00008000 <__main>:
    8000:   66 55                   push   ebp
    8002:   66 89 e5                mov    ebp,esp
    8005:   66 83 ec 10             sub    esp,0x10
    8009:   67 c6 45 ff 41          mov    BYTE PTR [ebp-0x1],0x41  <--- char a
    800e:   67 c6 45 fe 42          mov    BYTE PTR [ebp-0x2],0x42  <--- char b
    8013:   eb fe                   jmp    8013 <__main+0x13>

此文件由自定义引导程序加载到物理位置0x8000

QEMU和GDB

> qemu-system-i386 -fda build/boot.flp -s -S
> gdb loader.sym
  target remote localhost:1234
  set architecture i386
  b __main
  c
  s
  s
  p &a
    0x7be7 "" <-- Not EBP - 1
  p &b
    0x7be6 "" <-- Not EBP - 2

  info reg
  eax            0x0                 0
  ecx            0x0                 0
  edx            0x7de3              32227
  ebx            0x8000              32768
  esp            0x7bec              0x7bec
  ebp            0x7bfc              0x7bfc  <-- char a is at 0x7bfb and char b is at 0x7bfa
  esi            0x0                 0
  edi            0x0                 0
  eip            0x8013              0x8013 <__main+19>
  eflags         0x202               [ IF ]
  cs             0x0                 0
  ss             0x0                 0
  ds             0x0                 0
  es             0x0                 0
  fs             0x0                 0
  gs             0x0                 0

我不太了解发生了什么。可能是-m16选项吗?

编译

gcc -std=c99 \
    -nostartfiles \
    -c \
    -g \
    -ffreestanding \
    -fno-pie \
    -fno-stack-protector \
    -m16 \
    -march=i386 \
    -Wpedantic \
    -Wextra \
    -Wall \
    -O0  bootloader/x86/phase2/loader.c -o $TEMPDIR/loader.o || exit

ld -m elf_i386 --nmagic --script=build/loader.ld $TEMPDIR/loader.o -o $TEMPDIR/loader.lo || exit

objcopy --only-keep-debug $TEMPDIR/loader.lo $SYMDIR/loader.sym||exit
objcopy -O binary $TEMPDIR/loader.lo $OBJDIR/LOADER.flt||exit

链接器脚本(build / loader.ld)

ENTRY (__main)
SECTIONS
{
    . = 0x8000;                 /* Loader is loaded at 0x0000:0x8000 */
    .text :AT(0x0)
    {
        *.o (.text);
    }
    .data :
    {
        *.o (.data);
        *.o (.bss);
        *.o (.rodata);
    }
    /DISCARD/ : 
    {
        *(.eh_frame)
    }
}

我尝试过的事情:

  1. 在C文件顶部使用-m32代替-m16.code16gcc
  2. 验证了GCC,GDB在编译本机应用程序时完美运行。
  3. --oformat binary中使用了ld选项,而不是objcopy

PS:

  • GCC版本:8.3.0
  • GNU ld版本:2.31.1
  • Linux Debian 10

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...