我有一个应用程序,当我尝试运行它时会出错:
/lib/libc.so.6: version `GLIBC_2.7' not found
Run Code Online (Sandbox Code Playgroud)
但是glibc 2.7需要的唯一符号是
__isoc99_sscanf@@GLIBC_2.7
Run Code Online (Sandbox Code Playgroud)
我想写一个小的单个函数"library",用这个符号作为__sscanf()的别名
我怎么能用gcc/ld做到这一点?
我的变体不被接受,因为"@@"符号
int __isoc99_sscanf@@GLIBC_2.7(const char *, const char *, ...) __attribute__((alias("__sscanf")));
Run Code Online (Sandbox Code Playgroud)
第二个是我的变种
#include <stdarg.h>
int __isoc99_sscanf1(const char *a, const char *b, va_list args)
{
int i;
va_list ap;
va_copy(ap,args);
i=sscanf(a,b,ap);
va_end(ap);
return i;
}
// __asm__(".symver __isoc99_sscanf,__isoc99_sscanf@@GLIBC_2.7");
__asm__(".symver __isoc99_sscanf1,__isoc99_sscanf@@GLIBC_2.7");
Run Code Online (Sandbox Code Playgroud)
但它以链接器中的"找不到符号__isoc99_sscanf @@ GLIBC_2.7的版本节点"结束.
我正在编写ARM CPU的启动代码.没有内部RAM,但是有1GB的DDRAM连接到CPU,在初始化之前无法直接访问.代码存储在闪存中,初始化RAM,然后将自身和数据段复制到RAM并继续执行.我的计划是:
#define REG_BASE_BOOTUP 0xD0000000
#define INTER_REGS_BASE REG_BASE_BOOTUP
#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x887000
#define DRAM_BASE 0x0
#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE+ 0x1484)
... //a lot of registers
void sdram_init() __attribute__((section(".text_sdram_init")));
void ram_init()
{
static volatile unsigned int* const sdram_ftdll_config_left_reg = (unsigned int*)(INTER_REGS_BASE + SDRAM_FTDLL_CONFIG_LEFT_REG);
... //a lot of registers assignments
*sdram_ftdll_config_left_reg = SDRAM_FTDLL_REG_DEFAULT_LEFT;
}
Run Code Online (Sandbox Code Playgroud)
目前我的程序工作不正常,因为寄存器值最终被链接到RAM,并且在程序尝试访问它们时,只有闪存可用.
我怎么能改变我的链接器脚本或我的程序,以便这些值在闪存中的地址?有没有办法在文本段中包含这些值?
实际上,当它们在文件范围内声明时,那些定义的值是全局数据还是静态数据?
编辑:
目标文件与以下链接描述文件链接:
MEMORY
{
RAM (rw) : ORIGIN = 0x00001000, LENGTH = 12M-4K
ROM (rx) : ORIGIN = 0x007f1000, LENGTH = 60K
VECTOR (rx) : ORIGIN = …Run Code Online (Sandbox Code Playgroud) 我刚刚开始学习一些ARM编程,但我遇到了一个有点恼人的问题.我用来编译源代码的工具链是Sourcery CodeBench Lite 2013.05-23(可以在这里找到:https://sourcery.mentor.com/GNUToolchain/release2449 )
我需要的是告诉GCC或LD或OBJCOPY将'main'函数的编译字节码放在.text段的开头.
有没有办法实现这个目标?(也许通过链接器脚本?)
谢谢
为了对主机上的嵌入式项目进行单元测试,我开始使用函数指针来在函数的"真实"实现和运行时的模拟之间进行切换.所以,我的函数'foo'在.c文件中看起来像这样:
// the 'real' implementation of the function to be used during runtime
void fooImplementation ( )
{
/* ... */
}
// the function pointer, initialized to the 'real' implementation
void (*foo) ( ) = fooImplementation;
Run Code Online (Sandbox Code Playgroud)
结果是目标处理器(Blackfin)产生异常,因为函数指针驻留在内部L1数据存储器中,不允许携带代码而只允许数据.
一个有效的解决方案是为每个函数指针分配一个属性,以便将它放入不在L1数据存储器中的不同部分,例如:
void (*foo) ( ) __attribute__ (( section(".ext_mem"))) = fooImplementation;
Run Code Online (Sandbox Code Playgroud)
但是这使得代码有点难以阅读并且容易出错(如果您忘记分配属性,单元测试将运行正常,但代码将在目标上调用函数后立即生成异常).
所以我的问题是,如果有一些方法告诉gcc默认将所有函数指针放到不同的部分.
我想在虚拟内存的末尾创建一个带有特殊部分的程序.所以我想做一个像这样的链接器脚本:
/* ... */
.section_x 0xffff0000 : {
_start_section_x = .;
. = . + 0xffff;
_end_section_x = .;
}
Run Code Online (Sandbox Code Playgroud)
的问题是,GCC/LD/glibc的似乎在该位置处由默认32位应用程序加载堆栈,即使它重叠的已知部分.上面的代码为0,导致异常.有没有办法告诉链接器为堆栈使用另一个VM内存位置?(同样,我想确保堆不会跨越虚拟内存的这一部分......).
我正在尝试使用 x86_64 上的链接器脚本更改堆栈的起始位置。我能够使用这个移动我的可执行起始地址:
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x200000)); . = SEGMENT_START("text-segment", 0x200000) + SIZEOF_HEADERS;
Run Code Online (Sandbox Code Playgroud)
我像这样改变了我的全局变量:
.data ALIGN(0x10000000) :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下内容来移动堆栈区域:
. = 0x50000000;
.stack :
{
stack_start = .;
PROVIDE( stack_start = . );
*(.stack)
. += 0x2000;
stack_end = . ;
PROVIDE( stack_end = . );
}
Run Code Online (Sandbox Code Playgroud)
但这并没有让我去任何地方。
这是我用来测试堆栈位置的测试程序:
#include <stdio.h>
#include <stdlib.h>
int global_var = 555;
void test()
{
int local_test = 666;
printf("address of global_var: %p\n", &global_var);
printf("address of local_test: %p\n", &local_test); …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用STARTUPLD 脚本中的指令将程序与我自己的启动文件链接起来:
...
ENTRY(_start)
STARTUP(my_crt1.o)
...
Run Code Online (Sandbox Code Playgroud)
GCC 驱动程序用于链接程序(不要打扰 libgcc 等库路径):
gcc -T my_script.ld ...
Run Code Online (Sandbox Code Playgroud)
不幸的是,它只适用于为 powerpc 目标编译的 GCC,而 arm 或 i686 目标不支持并且仍然在 collect2 中包含 crt0.o。例如:
arm-eabi-g++ -v -T my_script.ld ...
Run Code Online (Sandbox Code Playgroud)
给我:
collect2 ... /opt/lib/gcc/arm-eabi/4.8.0/../../../../arm-eabi/lib/crt0.o ...
Run Code Online (Sandbox Code Playgroud)
因此:
crt0.S:101: multiple definition of `_start'
Run Code Online (Sandbox Code Playgroud)
似乎该STARTUP指令被完全忽略(除非STARTUP指定了该指令,否则 powerpc 目标也使用其默认的 crt0 )并且无法禁用默认的 crt0。
是否有一种可移植的方式来链接另一个启动文件?
我的启动文件的使用libgcc功能(打电话给构建函数和dtors)等等crtbegin.o,crtend.o等需要,所以我想,以避免-nostartfiles其禁用选项crt*.o-我需要禁用crt0.o只。
谢谢
我有一个与 gcc 链接器相关的问题。
我正在处理嵌入式内容(PIC32),但 PIC32 的编译器和链接器基于 gcc,因此,“常规”gcc 链接器和 PIC32 链接器的主要内容应该是通用的。
为了节省闪存空间(这在微控制器上通常是不够的),我需要在引导加载程序中放置几个大函数,应用程序应该只通过指针调用这些函数。
所以,我需要在生成的代码中创建向量表。
我正在尝试获取函数的绝对地址并将其写入生成的代码,但仍然出现错误。
在下面的示例中,我试图获取函数的地址_formatted_write。
代码:
.user_addr_table _USER_ADDR_TABLE_ADDR :
{
KEEP(*(.user_addr_table))
LONG((ABSOLUTE(_formatted_write))); /* _formatted_write is a name of my function */
} > user_addr_table
Run Code Online (Sandbox Code Playgroud)
链接器返回错误:“ unresolvable symbol '_formatted_write' referenced in expression”。
我注意到如果我写了一些垃圾而不是_formatted_write,那么它会返回错误“ undefined symbol .....”,因此,_formatted_write链接器知道。
这让我觉得我应该执行一些额外的步骤以使其“可解决”。但仍然不知道如何做到这一点。
我们正在为 STM32 芯片上的 ARM Cortex M4 编写一些代码。
我的理解是 Cortex-M4 有一些 32 位指令,但这些不是 32 位 ARM 指令,它们只是一些特殊指令。我认为粘合剂是为了在 ARM 和拇指指令集之间转换。那么为什么链接描述文件需要胶水呢?
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
Run Code Online (Sandbox Code Playgroud)
由于处理器仅支持拇指指令,我可以删除glue_7和吗?glue_7t这样做会释放任何闪存吗?
我的问题可能看起来很奇怪,事实上,这是上下文:
我目前面临一个奇怪的问题,同时切换 -在我正在从事的项目上- 从pullinino到CV32的核心(也发生了一些其他变化,例如关于crt0,如一些数据RAM重置)。
这是一个(真实的)示例,说明了一个相当简单的 main 所发生的情况(我无法对startup/crt0 文件进行编辑:我在帖子后面部分给出了它)。
#include <string.h>
#include <inttypes.h>
#include <stdio.h>
typedef struct
{
uintptr_t addr;
uint32_t foo;
} some_struct_t;
static uint32_t text_in_data[8] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888};
uint32_t text_in_data2[8] = {0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555, 0x66666666, 0x77777777, 0x88888888};
some_struct_t text_in = {(uintptr_t)text_in_data, 8};
static some_struct_t text_in2 = {(uintptr_t)text_in_data, 8};
int main(void)
{
some_struct_t text_in3 = {(uintptr_t)text_in_data, 8};
static some_struct_t text_in4 = {(uintptr_t)text_in_data, 8};
static some_struct_t text_in5 = {(uintptr_t)text_in_data2, …Run Code Online (Sandbox Code Playgroud)