如何在目标文件中引用绝对符号?

时间:2021-11-27 09:55:20

I have compiled a jpg into an object file and am trying to reference it in my program. The symbol table is below:

我已将jpg编译成目标文件,并尝试在我的程序中引用它。符号表如下:

user@host:~$ nm binary_artifacts.o 
000000000000ade3 D _binary_obj_jpg_end
000000000000ad00 A _binary_obj_jpg_size
00000000000000e3 D _binary_obj_jpg_start
user@host:~$

For the _binary_obj_jpg_start and _binary_obj_jpg_end symbols, it's pretty straightforward to use a char* to access them. However, the _binary_obj_jpg_size symbol is giving me some trouble.

对于_binary_obj_jpg_start和_binary_obj_jpg_end符号,使用char *访问它们非常简单。但是,_binary_obj_jpg_size符号给了我一些麻烦。

I tried declaring it as:

我尝试将其声明为:

extern const unsigned int const _binary_obj_jpg_size;

but I got segfaults when I used the symbol directly. I got the size correctly when I used it in my program as:

但是当我直接使用符号时,我得到了段错误。当我在我的程序中使用它时,我的大小正确:

extern const unsigned int const _binary_obj_jpg_size;
printf("Size: %d\n", (int)&_binary_obj_jpg_size); 

But this just seems wrong to declare it as an int and then take its address.

但是将它声明为int然后取其地址似乎是错误的。

Is there a "more" correct way of doing this that I'm unaware of?

是否有一种“更”正确的做法,我不知道?

1 个解决方案

#1


3  

This is the correct way to do it - the object file doesn't really distinguish symbols as being "addresses" versus just "values". Indeed, to the linker, _binary_obj_jpg_size just looks like a variable at address 0xad00, which causes the segfault. That's why you need to use its address.

这是正确的方法 - 目标文件并没有真正将符号区分为“地址”而不仅仅是“值”。实际上,对于链接器,_binary_obj_jpg_size看起来像地址0xad00处的变量,这会导致段错误。这就是你需要使用它的地址的原因。

Another way to think about it is that _binary_obj_jpg_size is effectively a difference of pointers (which is nominally ptrdiff_t) cast to a pointer. While such a conversion is valid, use of that pointer is undefined behavior. Casting back to an integer, however, is not.

考虑它的另一种方法是_binary_obj_jpg_size实际上是一个指针的差异(名义上是ptrdiff_t)。虽然这种转换是有效的,但使用该指针是未定义的行为。但是,回流到整数不是。

To get around the "wrongness" of it, you can disguise it in a macro:

为了解决它的“错误”,你可以在宏中伪装它:

extern const void *_binary_obj_jpg_size; // note that the type doesn't really matter - only the address does
#define BINARY_OBJ_JPG_SIZE ((size_t)(uintptr_t)&_binary_obj_jpg_size)

Then, you can use BINARY_OBJ_JPG_SIZE naturally as the object's size.

然后,您可以自然地使用BINARY_OBJ_JPG_SIZE作为对象的大小。

#1


3  

This is the correct way to do it - the object file doesn't really distinguish symbols as being "addresses" versus just "values". Indeed, to the linker, _binary_obj_jpg_size just looks like a variable at address 0xad00, which causes the segfault. That's why you need to use its address.

这是正确的方法 - 目标文件并没有真正将符号区分为“地址”而不仅仅是“值”。实际上,对于链接器,_binary_obj_jpg_size看起来像地址0xad00处的变量,这会导致段错误。这就是你需要使用它的地址的原因。

Another way to think about it is that _binary_obj_jpg_size is effectively a difference of pointers (which is nominally ptrdiff_t) cast to a pointer. While such a conversion is valid, use of that pointer is undefined behavior. Casting back to an integer, however, is not.

考虑它的另一种方法是_binary_obj_jpg_size实际上是一个指针的差异(名义上是ptrdiff_t)。虽然这种转换是有效的,但使用该指针是未定义的行为。但是,回流到整数不是。

To get around the "wrongness" of it, you can disguise it in a macro:

为了解决它的“错误”,你可以在宏中伪装它:

extern const void *_binary_obj_jpg_size; // note that the type doesn't really matter - only the address does
#define BINARY_OBJ_JPG_SIZE ((size_t)(uintptr_t)&_binary_obj_jpg_size)

Then, you can use BINARY_OBJ_JPG_SIZE naturally as the object's size.

然后,您可以自然地使用BINARY_OBJ_JPG_SIZE作为对象的大小。