gpt4 book ai didi

c++ - 如何将来自多个翻译单元的多个 const 对象放置在一个内存块中?

转载 作者:行者123 更新时间:2023-12-02 10:35:05 25 4
gpt4 key购买 nike

我正在为某些设备开发固件,它们中的每一个都包含配置对象,这些对象的值可以被外部应用程序更改。这是此类对象的示例:

struct TObjectParams
{
ObjectId ID; // enum
void* Data; // pointer to configuration data
unsigned short Length; // size of data

TAccessControl AccessControl; //object access control
};
TObjectParams 的每个实例是 const 并且在运行时不能更改。
固件由多个模块组成,每个模块都有自己的配置对象。这样做是因为不同的设备可以包含不同的模块,并且强制每个设备包含所有关闭的对象将浪费资源。
我的目标是将所有对象分组到一个位置(数组或单个部分),并按 ID 排序。 number (排序将显着降低搜索复杂度,从 O(n)O(log n)

我的第一个想法是使用 constexpr注册对象(在对象的构造函数中)并在编译期间创建 constexpr包含所有对象的数组。但据我所知,只有当所有对象都在同一个翻译单元中时它才会起作用。

我的第二个想法是使用 __attribute__((used, section("objects_section")))现在我确保链接器不会删除任何已定义的对象,并且它们都将位于同一部分。问题是排序。有没有办法强制链接器对这些对象进行排序?或者也许可以通过editig .elf文件?我知道我可以轻松转储 objects_section ,排序(通过自己的应用程序)并通过 objcopy更新但它会完全弄乱调试体验和直接调用任何对象,因为更新部分内容不会更新符号地址(或者我错了)。

您知道如何不仅更新部分内容而且还更新符号地址吗?或者,也许您知道解决此类问题的更好方法?我愿意接受所有建议。

最佳答案

Is there any way to force linker to sort these objects?


不,特别是考虑到排序标准可以是任意的。
但是,您实际上并不需要对对象进行排序:您可以对指向对象的指针数组(在初始化期间创建)进行排序,然后对该数组进行后续搜索。

I know that I can easily dump objects_section, sort it (by own app) and update through objcopy but it will totally mess debugging experience and direct call of any object because updating section content won't update symbols addresses (or maybe I am wrong).


这不是唯一的 objcopy会搞砸的。它还会破坏正确性:您的 Data member 指向其他一些数据,这意味着每个实例都有关联的重定位记录。如果您排序 TObjectParams在不更新搬迁记录的情况下,您的 Data objcopy 之后的指针将指向错误的配置数据.
更新:

that solution is partially satisfying.


如果您可以将配置数据直接包含到 TObjectParams ,它们会变大,指针的开销会变小。
如果配置数据本身没有指向其他数据的指针,那么您可以直接对部分内容进行排序,完全避免开销。
如果你不能摆脱指针,那么你将不得不编写一个自定义的 ELF 操作工具来对数据和相关的重定位记录进行排序。这样的工具还可以更新符号部分以解决调试问题。
但是,我认为有一个更简单的解决方案,至少在存在 TObjectParams 的单个实例的情况下。在给定的 .o文件(或者当给定的 .o 保证只有连续的 ID s 并且 .o 文件在其中包含的 ID s 中不重叠):
  • 把所有的TObjectParams像现在一样在一个单独的部分中。
  • 链接二进制文件。这将生成一个带有未排序部分的二进制文件,此链接的唯一原因是获取进入此二进制文件的对象列表。
    如果您已经单独维护了这样的列表,则可以跳过此步骤。
  • 对于步骤 2 ( foo.o ) 列表中的每个目标文件,使用 objcopy获得两个新对象:一个只包含感兴趣的部分( foo_w.o ),另一个删除了该部分( foo_x.o )。
  • {foo,bar,baz}_w.o 的列表进行排序由 ID包含在里面。
  • 使用 {foo,bar,baz}_x.o 执行最终链接以任何顺序,和{foo,bar,baz}_w.o按排序顺序。链接器通常不会重新排序该部分的内容,并且该链接应生成所需的最终二进制文件。
  • 关于c++ - 如何将来自多个翻译单元的多个 const 对象放置在一个内存块中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60687856/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com