在C++中,main是否可以通过函数指针定义?例如:
int f(int, char**) {
return 0;
}
int (*main)(int, char**) = &f;
Run Code Online (Sandbox Code Playgroud)
此代码正确编译和链接,但在运行时会触发分段错误.我相信这可能是因为它试图将函数指针的值作为代码执行.
另外,如果在普通的C++中不可能,那么可以通过gcc的非标准功能来实现(可能以某种方式改变导出符号的类型).
最后,如果使用gcc指令无法实现,可以使用自定义链接描述文件吗?
我已经阅读了本教程
我可以按照指南并运行代码。但是我有疑问。
1)为什么我们既需要加载地址又需要运行时地址。据我了解,这是因为我们也将.data放入了闪存;那么为什么我们不在那里运行应用程序,却需要启动代码将其复制到RAM?
http://www.bravegnu.org/gnu-eprog/c-startup.html
2)为什么我们在这里需要链接脚本和启动代码。我不仅可以按以下方式构建C源并使用qemu运行它吗?
arm-none-eabi-gcc -nostdlib -o sum_array.elf sum_array.c
Run Code Online (Sandbox Code Playgroud)
非常感谢
是否可以使用链接描述文件或映射文件来重命名符号?我正在尝试修改一些用C ++和Fortran混合编写的代码,以便它可以在Linux上与多个Fortran编译器一起使用。目前,它是为Solaris Studio编译器编写的,并且启用了区分大小写的选项。我想自动处理Fortran符号名称的变化(例如来自Makefile)。
似乎确实可以创建别名,因此,包含以下内容的链接描述文件:
C_Function_ = c_function;
Run Code Online (Sandbox Code Playgroud)
将工作。不幸的是,添加-T选项以引用此脚本会导致其他行为更改,由于找不到libdl.so.2 / librt.so.1,我得到了错误。我需要包括某种默认的链接描述文件吗?我已经尝试过在Linux上使用bfd和gold链接器。
我正在改编一些来自相当新的 AURIX TriCore MCU 的链接器脚本。
有一个我根本不明白的命令,文档 [0] 并没有真正的帮助。
有人可以告诉我原则上发生了什么吗?“全局地址”是什么意思,“核心本地地址”是什么意思?
[0] 英飞凌科技股份公司:TriCore 开发平台,2015。 - 手册
最近我一直在研究自动生成的 STM32 项目中使用的链接器脚本,我对堆栈和堆内存段的定义有点困惑。
例如,我一直在查看 ST 的“CubeMX”固件包中为其 F0 系列芯片提供的文件,这些芯片具有 ARM Cortex-M0 内核。如果文件的许可证允许,我会粘贴整个脚本,但如果您好奇,可以从 ST 免费下载整个程序包1。无论如何,以下是与我的问题相关的部分:
/* Highest address of the user mode stack */
_estack = 0x20001000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
<...>
SECTIONS {
<...>
.bss :
{
<...>
} >RAM
/* User_heap_stack section, used to check …Run Code Online (Sandbox Code Playgroud) 我使用 STM32H7 微控制器和 GNU/GCC,在我的代码中,我只使用 DTCM RAM,但我想将一些缓冲区存储在另一个可由 DMA 访问的内存中。
我对链接脚本完全陌生,是否需要编辑启动代码?
这是我的链接器脚本,我在其中添加了一些代码SECTIONS
/* Memories definition */
MEMORY
{
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K
}
/* Sections */
SECTIONS
{
...
.ram1block 0x24000000 …Run Code Online (Sandbox Code Playgroud) 我试着为stm32f334做一些例子(只是led闪烁).当我想使用.data部分约束时(通过使用初始化的全局变量),我遇到了链接器的问题我遇到了问题.全局变量的值不正确!
这是我的代码:
startup.s:
.global _start
.thumb_func
_start:
.word 0x20003000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.thumb_func
reset:
bl main
b hang
.thumb_func
hang: b .
Run Code Online (Sandbox Code Playgroud)
blink.c:
#define RCCBASE 0x40021000
#define GPIOBBASE 0x48000400
static int wymuszenie_bss;
int wymuszenie_data = GPIOBBASE;
int main ( void )
{
unsigned int* ptr;
wymuszenie_bss = 0x40021000;
ptr = (unsigned …Run Code Online (Sandbox Code Playgroud) 我想在链接器脚本中定义一个部分,并在运行时从源代码中获取其值。
到目前为止,我已经采用了默认gcc linker脚本文件,并添加了我的部分,如下所示:
...
.my_section : { BYTE(0xAA); }
...
Run Code Online (Sandbox Code Playgroud)
编译后,我可以看到以下部分:
> gcc -T ls.ld main.c -o main
> objdump -h main
...
...
27 .my_section 00000001 0000000000a01040 0000000000a01040 00001040 2**0
CONTENTS, ALLOC, LOAD, DATA
28 .comment 00000034 0000000000000000 0000000000000000 00001041 2**0
CONTENTS, READONLY
Run Code Online (Sandbox Code Playgroud)
现在,我想将该值打印到stdout(并且我期望获得0xAA):
#include <stdio.h>
static volatile unsigned char SECTION __attribute__((section(".my_section")));
int main(){
printf("hello %d\n", SECTION);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我获得的值始终为 0。我做错了什么?