c - 如何获取指向 MSVC 中二进制部分的指针?

标签 c visual-c++ gcc linker

我正在编写一些代码,将一些数据结构存储在一个特殊命名的二进制部分中。这些都是同一结构的所有实例,它们分散在许多 C 文件中,并且不在彼此的范围内。通过将它们全部放在命名部分中,我可以遍历所有这些部分。

在 GCC 中,我使用 _attribute_((section(...)) 加上一些特别命名的 extern 指针,它们由链接器神奇地填充。这是一个简单的例子:

#include <stdio.h>

extern int __start___mysection[];
extern int __stop___mysection[];

static int x __attribute__((section("__mysection"))) = 4;
static int y __attribute__((section("__mysection"))) = 10;
static int z __attribute__((section("__mysection"))) = 22;

#define SECTION_SIZE(sect) \
    ((size_t)((__stop_##sect - __start_##sect)))

int main(void)
{
    size_t sz = SECTION_SIZE(__mysection);
    int i;

    printf("Section size is %u\n", sz);

    for (i=0; i < sz; i++) {
        printf("%d\n", __start___mysection[i]);
    }

    return 0;
}

我正在尝试弄清楚如何在 MSVC 中执行此操作,但我画的是一片空白。我从编译器文档中看到我可以使用 __pragma(section(...)) 声明该部分并使用 __declspec(allocate(...)) 声明数据在该部分中,但我看不到如何获得运行时指向该部分开始和结束的指针。

我在网上看到了一些与在 MSVC 中执行 _attribute_((constructor)) 相关的示例,但它似乎是针对 CRT 的黑客攻击,而不是获取指针的通用方法到一个部分的开头/结尾。有人有什么想法吗?

最佳答案

还有一种不使用程序集文件的方法。

#pragma section(".init$a")
#pragma section(".init$u")
#pragma section(".init$z")

__declspec(allocate(".init$a")) int InitSectionStart = 0;
__declspec(allocate(".init$z")) int InitSectionEnd   = 0;

__declspec(allocate(".init$u")) int token1 = 0xdeadbeef;
__declspec(allocate(".init$u")) int token2 = 0xdeadc0de;

前 3 行定义了段。这些定义了部分并取代了程序集文件。与 data_seg pragma 不同,section pragma 只创建节。 __declspec(allocate()) 行告诉编译器将项目放在该段中。

来自微软页面: 这里的顺序很重要。部分名称不得超过 8 个字符。 $ 之前的同名部分合并为一个部分。它们合并的顺序由 $ 之后的字符排序决定。

另一个要记住的重要点是部分被 0 填充到 256 字节。 START 和 END 指针不会像您预期的那样直接位于前后。

如果您将表设置为指向函数或其他非 NULL 值的指针,由于部分填充,应该很容易跳过表前后的 NULL 条目

参见 this msdn page了解更多详情

关于c - 如何获取指向 MSVC 中二进制部分的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3808053/

相关文章:

c - Gtk 打开默认文件管理器文件夹

c - 如何从 bsearch 或 lfind 返回索引? - 排序会扭曲返回值

c++ - 是 char 空终止符是否包含在长度计数中

c - MSVC#pragma 优化参数示例

c++ - fatal error LNK2019 C++,Unreal Engine Build

linux - Arch Linux 没有 i586-elf-gcc 或 i586-elf-gcc

c - 如何在不复制代码的情况下创建不可转换的 C 类型?

c++ - Visual C++ 2012 中的编译器错误? (乱七八糟的跳转地址)

c - 内核编译但不会与 unistd.h 引用链接

C++运算符重载解析歧义