ld的数据文件使数据大小为* ABS *而不是整数

时间:2013-02-11 15:07:48

标签: c++ c variables pointers ld

我有一个c ++程序,它包含对空​​xlsx文件的外部依赖。要删除此依赖项,我将此文件转换为二进制对象,以便直接链接它,使用:

ld -r -b binary -o template.o template.xlsx

接着是

objcopy --rename-section .data=.rodata,alloc,load,readonly,data,contents template.o template.o

使用objdump,我可以看到声明的三个变量:

$ objdump -x template.o

template.o:     file format elf64-x86-64
template.o
architecture: i386:x86-64, flags 0x00000010:
HAS_SYMS
start address 0x0000000000000000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .rodata       00000fd1  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l    d  .rodata        0000000000000000 .rodata
0000000000000fd1 g       *ABS*  0000000000000000 _binary_template_xlsx_size
0000000000000000 g       .rodata        0000000000000000 _binary_template_xlsx_start
0000000000000fd1 g       .rodata        0000000000000000 _binary_template_xlsx_end

然后我告诉我的程序这个数据:

template.h:
#ifndef TEMPLATE_H
#define TEMPLATE_H

#include <cstddef>
extern "C" {
  extern const char _binary_template_xlsx_start[];
  extern const char _binary_template_xlsx_end[];
  extern const int  _binary_template_xlsx_size;
}
#endif

编译和链接很好,(虽然我在使用cmake自动化时遇到一些麻烦,请看这里:compile and add object file from binary with cmake

但是,当我在代码中使用_binary_template_xlsx_size时,它被解释为指向不存在的地址的指针。因此,为了获得我的数据大小,我必须通过(int)&_binary_template_xlsx_size(或(int)(_binary_template_xlsx_end - _binary_template_xlsx_start)

一些研究告诉我,上面的objdump *ABS*意味着“绝对价值”,但我不明白为什么。如何让我的c ++(或c)程序将变量看作int而不是指针?

1 个答案:

答案 0 :(得分:3)

*ABS*符号是绝对地址;它通常是通过将--defsym foo=0x1234传递给ld。

来创建的
--defsym symbol=expression
     

在输出文件中创建一个包含绝对值的全局符号      表达式给出的地址。 [...]

因为绝对符号是常量,所以不可能将它作为变量链接到C源文件中;所有C对象变量都有一个地址,但常量不具有。

为确保不会意外取消引用地址(即读取变量),最好将其定义为const char []和其他符号一样:

  extern const char _binary_template_xlsx_size[];

如果您想确保将其用作int,则可以使用宏:

  extern const char _abs_binary_template_xlsx_size[] asm("_binary_template_xlsx_size");
  #define _binary_template_xlsx_size ((int) (intptr_t) _abs_binary_template_xlsx_size)