如何获取指向MSVC中二进制部分的指针? [英] How to get a pointer to a binary section in MSVC?

查看:129
本文介绍了如何获取指向MSVC中二进制部分的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



在GCC中,我使用_ 属性 _((section ...))加上一些特别命名的extern指针,它们被链接器奇迹般地填充了,这里有一个简单的例子:

 #包括< 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 printf(%d \ n,__start ___ mysection [i]);
}

return 0;
}

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



我在网上看到了一些与_ 属性相关的示例 _ ((构造函数))在MSVC中,但它似乎像黑客特定于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条目



请参阅此msdn页面以获取更多详情


I'm writing some code which stores some data structures in a special named binary section. These are all instances of the same struct which are scattered across many C files and are not within scope of each other. By placing them all in the named section I can iterate over all of them.

In GCC, I use _attribute_((section(...)) plus some specially named extern pointers which are magically filled in by the linker. Here's a trivial example:

#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;
}

I'm trying to figure out how to do this in MSVC but I'm drawing a blank. I see from the compiler documentation that I can declare the section using __pragma(section(...)) and declare data to be in that section with __declspec(allocate(...)) but I can't see how I can get a pointer to the start and end of the section at runtime.

I've seen some examples on the web related to doing _attribute_((constructor)) in MSVC, but it seems like hacking specific to CRT and not a general way to get a pointer to the beginning/end of a section. Anyone have any ideas?

解决方案

There is also a way to do this with out using an assembly file.

#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;

The first 3 line defines the segments. These define the sections and take the place of the assembly file. Unlike the data_seg pragma, the section pragma only create the section. The __declspec(allocate()) lines tell the compiler to put the item in that segment.

From the microsoft page: The order here is important. Section names must be 8 characters or less. The sections with the same name before the $ are merged into one section. The order that they are merged is determined by sorting the characters after the $.

Another important point to remember are sections are 0 padded to 256 bytes. The START and END pointers will NOT be directly before and after as you would expect.

If you setup your table to be pointers to functions or other none NULL values, it should be easy to skip NULL entries before and after the table, due to the section padding

See this msdn page for more details

这篇关于如何获取指向MSVC中二进制部分的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆