无法打印全局变量地址的绝对地址。

huangapple go评论81阅读模式
英文:

Not able to print the absolute address of global variable address

问题

裸机的RISC-V GCC编译代码并链接。我可以将我的程序加载到任何地址。固件使用指向我的函数的指针调用我的程序。我无法打印全局变量的地址,它打印的是偏移量而不是绝对地址。该怎么办?在qemu上运行。如果我在内存映射中提供固定地址给RAM,我可以获得正确的地址,但如果不提供内存映射,我将获得偏移地址,而不是实际的绝对地址。但这不是我想要的。

以下是代码示例:

void fun() {
      __attribute__((used)) static const int lsc = 0x55; //.const
      printf("%d %x %x\n", lsc, lsc, &lsc);
}

当打印local_static_const的地址时,我得到了一些偏移量0xd0,而不是绝对地址。

我随机发现,使用-Wl,-mno-relax选项可以给我正确的输出,但如果我删除它,再次运行则会给我错误的输出,即偏移地址。我不明白为什么会这样。

注意:%p不是问题,我已将其更改为%x,它的工作方式与上述列表相同。

英文:

Baremetal riscv gcc compiled code and linked. I can load my program at any address. firmware calls my program using pointer to my function. I am not able to print the global variables address, its printing offsets instead of absolute address. what to do? running on qemu. If I am giving fixed address to ram in memory map. I am getting correct address but without giving memory map I am getting offset as its actual absolute address. But thats not I wanted.

this is the below code

void fun() {
      __attribute__((used)) static const int lsc = 0x55; //.const
      printf("%d %x %x\n",lsc,lsc,&lsc);
}

when printing the address of local_static_const, I am getting some offset 0xd0, but not absolute address.

I randomly found out that -Wl,-mno-relax giving me correct output but if I am removing then again its giving me wrong output .i.e giving offset address. I am not able to understand why.

Note: %p is not the issue, I have changed it to %x, its working in the same way listed above.

答案1

得分: 2

The printf format for pointers is %p and the address must be cast as (void *). Try this:

void fun() {
      __attribute__((used)) static const int lsc = 0x55; //.const
      printf("%d %x %p\n", lsc, lsc, (void *)&lsc);
}

If the above code prints 0x000000d0 for the third argument, that is the address of the static variable lsc, which should be part of the data segment. You say the program is loaded at a fixed address: you might want to print the address of the function fun itself to see if the text or code segment is loaded as requested.

英文:

The printf format for pointers is %p and the address must be cast as (void *). Try this:

void fun() {
      __attribute__((used)) static const int lsc = 0x55; //.const
      printf("%d %x %p\n", lsc, lsc, (void *)&lsc);
}

If the above code prints 0x000000d0 for the third argument, that is the address of the static variable lsc, which should be part of the data segment. You say the program is loaded at a fixed address: you might want to print the address of the function fun itself to see if the text or code segment is loaded as requested.

答案2

得分: 0

只返回翻译好的部分:

"看起来问题在于您正在使用不正确的转换说明符来输出指针。转换说明符%x被设计用于输出unsigned int类型的对象,通常占用4字节,而在64位系统中,指针占用8字节。要将指针转换为无符号整数类型,您需要使用头文件<stdint.h>中定义的类型说明符uintptr_t。因此,函数printf甚至无法使用转换说明符%x访问所有8字节。

而是尝试使用专门设计用于输出指针的转换说明符p

printf("%d %x %p\n", lsc, lsc, (void*)&lsc);

另一种方法是包括头文件<inttypes.h>并编写

#include <inttypes.h>

//...

printf("%d %x %" PRIxPTR "\n", lsc, lsc, (uintptr_t)(void*)&lsc);

"

英文:

It seems the problem is that you are using an incorrect conversion specifier to output a pointer. The conversion specification %x is designed to output objects of the type unsigned int that usually occupy 4 bytes while pointers in 64-bit systems occupy 8 bytes. To convert a pointer to an unsigned integer type you need to use type specification uintptr_t defined in header &lt;stdint.h&gt;. As a result the function printf is just even unable to access all 8 bytes using the convefrsion specification %x.

Instead try the following using conversion specifier p specially designed to output pointers

printf(&quot;%d %x %p\n&quot;,lsc,lsc, ( void * )&amp;lsc);

An alternative approach is to include header &lt;inttypes.h&gt; and write

#include &lt;inttypes.h&gt;

//...

printf(&quot;%d %x %&quot; PRIxPTR &quot;\n&quot;,lsc,lsc, ( uintptr_t )( void * )&amp;lsc);

答案3

得分: -1

如其他回答所解释的那样,您正在错误地使用 printf(),没有正确地将其他参数与格式进行类型匹配。其他回答没有明确提到,但这导致程序表现出未定义的行为。因此,C语言规范对为什么错误的程序会以其方式行为没有提供答案。记录上,正确的 printf 调用应该是:

printf("%d %x %p\n", lsc, (unsigned int)lsc, (void *)&lsc);

鉴于您已经提到将 -Wl,-mno-relax 添加到编译命令会导致程序输出您期望的结果,我们可以假设这可能是由于误用 printf 引发UB的一部分。-mno-relax 禁用了链接器可以执行的将绝对寻址模式转换为PC相对模式的优化,因此与您观察到的实际行为差异在主题上有关。

然而,无论如何,切换到上面正确的调用可能会给您带来期望的输出,而不管是否使用了 -mno-relax。但归根结底,您期望通过这种方式获取绝对地址的表示方式在语言规范中没有得到支持。在C中,指针值等同于地址,但这并不要求这些值是在平面地址空间中的绝对地址。从历史上看,有许多实现,有时(或总是)它们并不是绝对地址。C中对地址的唯一要求是在指向的对象的生命周期内可以使用它来访问该对象。

英文:

As other answers have explained, you are misusing printf() by not properly type matching the other arguments with the format. The other answers don't quite say so, but it is relevant that this causes the program to exhibit undefined behavior. The C language specifications therefore provide no answer about why that erroneous program behaves as it does. For the record, the correct printf call would be:

    printf(&quot;%d %x %p\n&quot;, lsc, (unsigned int) lsc, (void *) &amp;lsc);

Inasmuch as you have added the information that adding -Wl,-mno-relax to the compilation command causes the program to emit the output you expect, we can suppose that this may be a facet of the UB elicited by misuse of printf. The -mno-relax disables an optimization that the linker can perform to transform an absolute addressing mode into a PC-relative mode, so it is thematically linked to the actual behavior difference you observe.

It may be that switching to the correct call, above, will give you the expected output regardless of -mno-relax. At the end of the day, however, your expectation that you can obtain a representation of an absolute address that way is not supported by the language spec. Where C equates pointer values with addresses, that does not require such values to be absolute addresses in a flat address space. Historically, there have been many implementations where sometimes (or always) it isn't. The only requirement on an address in the C sense is that it can be used to access the pointed-to object during the lifetime of that object.

huangapple
  • 本文由 发表于 2023年7月3日 17:55:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定