5

我有一个 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)

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

4

1 回答 1

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)
于 2013-02-11T18:21:43.170 回答