如何检查链接描述文件中是否定义了符号

时间:2012-02-07 10:15:54

标签: gcc linker ld

我正在使用不同的链接描述文件。在某些情况下,定义了一个值,在其他情况下,它没有定义:

DIRECTORY_ADDRESS = 0x80100000;
DIRECTORY_SIZE = 32M;

在执行时,我希望在未定义此值时使用默认行为,并在定义此值时使用特殊行为。

经典地,我得到这样的值:

extern void * DIRECTORY_ADDRESS;
extern void * DIRECTORY_SIZE;

void f() { 
  void *dir_addr = &DIRECTORY_ADDRESS;
  int dir_size   = (int)&DIRECTORY_SIZE;
}

我根据链接器脚本中存在的这个值,第一次导致conditionnaly执行代码是弱引用:

extern void * DIRECTORY_ADDRESS  __attribute__ ((weak)) = 0x0;
extern void * DIRECTORY_SIZE __attribute__ ((weak)) = 0x0;

void f() {
  if ( DIRECTORY_ADDRESS )
    // special code
  else
    // default code
}

但它无法工作,因为我正在初始化指针值,而不是它的地址:即使是一个未经解释的弱符号也有一个地址。所以目录地址总是!= NULL。

我很确定此问题已经解决,但我在网上找不到任何相关问题。

2 个答案:

答案 0 :(得分:1)

我的错误!

我尝试了很多组合,这个实际上是错误的:

当我初始化弱符号时,有“半弱”

extern void * DIRECTORY_ADDRESS  __attribute__ ((weak)) = 0x0;
extern void * DIRECTORY_SIZE __attribute__ ((weak)) = 0x0;

为了解决我的问题,我只需要让弱符号未初始化,如果它们没有用强符号定义,那么符号地址将为NULL:

extern void * DIRECTORY_ADDRESS  __attribute__ ((weak));
extern void * DIRECTORY_SIZE __attribute__ ((weak));

答案 1 :(得分:1)

默认情况下,未初始化的全局变量很弱,因此您可以使用

void * DIRECTORY_ADDRESS;
void * DIRECTORY_SIZE;

如果没有为这些名称定义外部符号,则该值将默认为NULL。要强制使用不同于NULL的默认值,可以使用

void * DIRECTORY_ADDRESS __attribute__ ((weak)) = OTHER_VALUE;
void * DIRECTORY_SIZE __attribute__ ((weak)) = OTHER_VALUE;

请注意,初始化extern并不真正有意义:extern意味着定义在文件外部,但初始化提供了一个定义。我的编译器(gcc 4.4)警告用户这个,然后忽略extern修饰符。这意味着您的示例按预期工作(即使在初始化为0x0时),但也许您的编译器会以不同的方式处理这种不明确的情况。

相关问题