如何创建静态链接共享库

2024-03-02

在我的硕士论文中,我尝试为 ARM Cortex-M3 嵌入式系统采用共享库方法。由于我们的目标板没有 MMU,我认为使用“普通”动态共享库是没有意义的。因为 .text 是直接从闪存执行的,而 .data 在启动时被复制到 RAM,所以我无法相对于代码寻址 .data,因此也得到了。 GOT 必须通过必须在链接时定义的绝对地址来访问。那么为什么不在链接时为所​​有符号分配固定的绝对地址......?

从书中“链接器和加载器” http://www.iecc.com/linker/linker09.html我意识到“静态链接共享库,即库中的程序和数据地址在链接时绑定到可执行文件的库”。链接的章节描述了如何创建此类库,并提供了对 Unix System V、BSD/OS 的引用;而且还提到了 Linux 及其 uselib() 系统调用。不幸的是,本书没有提供如何实际创建此类库(例如工具和/或编译器/链接器开关)的信息。除了那本书之外,我几乎找不到关于“野外”此类图书馆的任何其他信息。我在这方面唯一发现的是prelink http://linux.die.net/man/8/prelink对于Linux。但由于这在“正常”动态库上运行,这并不是我真正要寻找的。

我担心这些类型的库的使用非常具体,因此不存在创建它们的通用工具。尽管在这种情况下提到的 uselib() 系统调用让我想知道。但我想确保在开始破解我自己的链接器之前我没有忽略任何事情......;)那么有人可以给我有关此类库的更多信息吗?

此外,我想知道是否有任何 gcc/ld 开关可以链接和重定位文件,但将重定位条目保留在文件中 - 以便可以重新定位它?我找到了“-r”选项,但这完全跳过了重定位过程。有人有想法吗?

edit:

是的,我也知道链接描述文件。和gcc libfoo.c -o libfoo -nostdlib -e initLib -Ttext 0xdeadc0de我设法获得某种链接和重新定位的对象文件。但到目前为止,我还没有找到任何链接主程序并将其用作共享库的可能性。 (链接动态共享库的“正常方式”将被链接器拒绝。)


Concepts

这种共享库的最基本概念。

  • 相同的代码
  • 不同的数据

这方面存在一些变体。您支持库之间的链接吗?参考文献是DAG http://en.wikipedia.org/wiki/Directed_acyclic_graph结构还是全循环?您想将代码放入ROM中,还是支持代码更新?您希望在之后加载库吗?process最初运行的是?最后一项通常是之间的区别静态共享库 and 动态共享库。尽管很多人也会禁止图书馆之间的引用。

设施

最终,一切都将取决于处理器的寻址模式。在本例中为 ARM 拇指。这loader通常与操作系统和使用的二进制格式耦合。您的工具链(编译器和链接器)还必须支持二进制格式并且可以生成所需的代码。

通过寄存器访问数据的支持是固有的APCS http://www.chiark.greenend.org.uk/%7Etheom/riscos/docs/CodeStds/APCS.txt(ARM 过程调用标准)。在这种情况下,数据是通过sb(对于静态基址)这是寄存器R9. The 静态基地 and 堆栈检查是可选功能。我相信您可能需要配置/编译 GCC 来启用或禁用这些选项。

选项-msingle-pic-base and -mpic-register都在海湾合作委员会手册 https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/ARM-Options.html。这个想法是,操作系统最初会为每个库用户分配单独的数据,然后加载/重新加载sb在上下文切换上。当代码运行到库时,通过以下方式访问数据sb对于该实例的数据。

Gcc's arm.c code https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/arm/arm.c;hb=HEAD#l6387 has the require_pic_register() which does code generation for data references in a shared library. It may correspond to the ARM ATPCS shared library http://infocenter.arm.com/help/topic/com.arm.doc.espc0002/ATPCS.pdf mechanics.See Sec 5.5

您可以通过使用宏和内联汇编器以及可能的函数注释来规避工具链,例如naked and section https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html。然而,在这种情况下,库和可能的进程需要修改代码;即,非标准宏,例如EXPORT(myFunction), etc.

一种可能性

如果系统已完全指定(ROM 映像),您可以预先生成系统中每个库唯一的数据偏移量。使用链接器脚本可以相当轻松地完成此操作。使用NOLOAD并将图书馆数据放入某个虚假部分。甚至可以将主程序设为静态共享库。例如,您正在制作一个具有四个以太网端口的网络设备。主应用程序处理一个端口上的流量。您可以使用不同的数据生成应用程序的四个实例,以指示正在处理哪个端口。

如果您有大量混合/匹配的库类型,则库数据的占用空间可能会变大。这种情况下需要重新调整sb当通过外部 API 上的包装函数对库进行调用时。

  void *__wrap_malloc(size_t size)  /* Wrapped version. */
  {
       /* Locals on stack */
       unsigned int new_sb = glob_libc; /* accessed via current sb. */
       void * rval;
       unsigned int old_sb;

       volatile asm(" mov %0, sb\n" : "=r" (old_sb);
       volatile asm(" mov sb, %0\n" :: "r" (new_sb);
       rval = __real_malloc(size);
       volatile asm(" mov sb, %0\n" :: "r" (old_sb);
       return rval;
  }

See the GNU ld --wrap https://sourceware.org/binutils/docs/ld/Options.html选项。如果您有更大的同质库集,则需要这种复杂性。如果您的库仅包含“libc/libsupc++”,那么您可能不需要包装任何内容。

The ARM ATPCS http://infocenter.arm.com/help/topic/com.arm.doc.espc0002/ATPCS.pdf编译器插入了具有等效功能的胶合板,

LDR a4, [PC, #4] ; data address
MOV SB, a4
LDR a4, [PC, #4] ; function-entry
BX a4
DCD data-address
DCD function-entry

使用此技术的库数据的大小为 4k(可能是 8k,但这可能需要编译器修改)。限制是通过ldr rN, [sb, #offset],ARM 将偏移量限制为 12 位。使用包装时,每个库都有 4k 的限制。

如果您有多个在构建原始应用程序时未知的库,那么您需要包装每个库,并通过操作系统加载程序将 GOT 类型表放置在主应用程序静态库中的固定位置。每个应用程序都需要为每个库的指针提供空间。如果应用程序不使用该库,则操作系统不需要分配空间,并且该指针可以是NULL.

The 图书馆桌可以通过已知位置访问.text,通过原始流程sb或通过堆栈的掩码。例如,如果所有进程都有 2K 堆栈,则可以为库表保留较低的 16 个字。sp & ~0x7ff将为所有任务提供隐式锚点。操作系统还需要分配任务堆栈。

请注意,此机制与 ATPCS 不同,后者使用sb作为一个表格来获取实际库数据的偏移量。由于所描述的 Cortex-M3 的内存相当有限,因此每个单独的库不太可能需要使用超过 4k 的数据。如果系统支持分配器,则可以解决此限制。

参考

  • Xflat 技术概述 http://xflat.sourceforge.net/NoMMUSharedLibs.html- 技术讨论Xflat作者;Xflat http://xflat.sourceforge.net/XFLATTableOfContents.html是支持共享库的 uCLinux 二进制格式。非常好的读物。
  • 联动表与GOT https://stackoverflow.com/questions/9688076/process-linkage-table-and-global-offset-table- PLT 和 GOT 也是如此。
  • ARM EABI http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0036b/index.html- 正常的 ARM 二进制格式。
  • 组装机和装载机 http://www.davidsalomon.name/assem.advertis/asl.pdf, by 大卫·所罗门。特别是,pg262A.3 基址寄存器
  • ARM ATPCS http://infocenter.arm.com/help/topic/com.arm.doc.espc0002/ATPCS.pdf, 尤其第 5.5 节,共享库, pg18.
  • bFLT https://web.archive.org/web/20080229171450/http://www.beyondlogic.org/uClinux/bflt.htm是另一种支持共享库的 uCLinux 二进制格式。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建静态链接共享库 的相关文章

  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • SSL/TLS/HTTPS 站点在 C#/.NET WebBrowser 控件中非常慢,但在 Internet Explorer 中则很好

    背景 我正在修改自动维基浏览器 http en wikipedia org wiki Wikipedia AutoWikiBrowser使用托管在安全服务器上的 MediaWiki 站点 我允许用户通过 C 应用程序中的 WebBrowse
  • 在 C++ 中将成对向量转换为两个独立向量的最快方法

    假设我有一个vector of pair
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • 如何使用MySqlCommand和prepare语句进行多行插入?(#C)

    Mysql 给出了如何使用准备语句和 NET 插入行的示例 http dev mysql com doc refman 5 5 en connector net programming prepared html http dev mysq
  • 劫持系统调用

    我正在编写一个内核模块 我需要劫持 包装一些系统调用 我正在暴力破解 sys call table 地址 并使用 cr0 来禁用 启用页面保护 到目前为止一切顺利 一旦完成 我将公开整个代码 因此如果有人愿意 我可以更新这个问题 无论如何
  • 无法解析远程名称 - webclient

    我面临这个错误 The remote name could not be resolved russgates85 001 site1 smarterasp net 当我请求使用 Web 客户端读取 html 内容时 出现错误 下面是我的代
  • C++ 插件的“最适合”动态类型匹配

    我有一个几乎所有东西都是插件的架构 该架构以图形用户界面为基础 其中每个插件都由一个 表面 即用户可以通过其与插件交互的 UI 控件 表示 这些表面也是插件 每当添加新插件时 瘦主机都会自动确定哪个可用表面与其最匹配的 UI 如何在 C 中
  • C# 中的常量和只读? [复制]

    这个问题在这里已经有答案了 可能的重复 const 和 readonly 之间有什么区别 https stackoverflow com questions 55984 what is the difference between cons
  • 如何随着分辨率的变化自动调整大小和调整表单控件

    我注意到某些应用程序会更改控件的位置以尽可能适应当前的分辨率 例如 如果窗口最大化 则控件的设置方式应使整个 GUI 看起来平衡 是否可以使用 C 在 Visual studio 2010 中制作或实现此功能 Use Dock http m
  • 二叉树中的 BFS

    我正在尝试编写二叉树中广度优先搜索的代码 我已将所有数据存储在队列中 但我不知道如何访问所有节点并消耗它们的所有子节点 这是我的 C 代码 void breadthFirstSearch btree bt queue q if bt NUL
  • asp.net网格分页的SQL查询

    我在用iBatis and SQLServer 使用偏移量和限制进行分页查询的最佳方法是什么 也许我添加该列ROW NUMBER OVER ORDER BY Id AS RowNum 但这只会阻止简单查询的数据访问 在某些情况下 我使用选择
  • 为什么要在 C++ 中使用 typedef?

    可以说我有 set
  • 使用 mingw32 在 Windows 上构建 glew 时“DllMainCRTStartup@12”的多个定义

    我关注了这个主题 使用 mingw 使建筑物在 Windows 上闪闪发光 https stackoverflow com questions 6005076 building glew on windows with mingw 6005
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • C语言声明数组没有初始大小

    编写一个程序来操纵温度详细信息 如下所示 输入要计算的天数 主功能 输入摄氏度温度 输入功能 将温度从摄氏度转换为华氏度 独立功能 查找华氏度的平均温度 我怎样才能在没有数组初始大小的情况下制作这个程序 include
  • 为什么文件更新时“如果较新则复制”不复制文件?

    我在 Visual Studio Express 中有一个解决方案 如下所示 The LogicSchemaC 中的类 将在运行时解析指定的 XML 文件 以下是在main的方法Program cs LogicSchema ls new L
  • 带有私有设置器的 EFCore Base 实体模型属性 - 迁移奇怪的行为

    实体模型继承的类内的私有设置器似乎会导致 EFCore 迁移出现奇怪的问题 考虑以下示例 其中有多个类 Bar and Baz 继承自Foo 跑步时Add Migration多次命令 添加 删除private修饰符 生成的模式在多个方面都是
  • 以 UTF8 而不是 UTF16 输出 DataTable XML

    我有一个 DataTable 我正在使用 WriteXML 创建一个 XML 文件 尽管我在以 UTF 16 编码导出它时遇到问题 并且似乎没有明显的方法来更改它 我了解 NET 在字符串内部使用 UTF 16 这是正确的吗 然后 我通过
  • 如何使用 C# 以低分辨率形式提供高分辨率图像

    尝试使用 300dpi tif 图像在网络上显示 目前 当用户上传图像时 我正在动态创建缩略图 如果创建的页面引用宽度为 500x500px 的高分辨率图像 我可以使用相同的功能即时转换为 gif jpg 吗 将创建的 jpg 的即将分辨率

随机推荐

  • JavaScript 实例化

    你能在下面的例子中告诉我为什么吗sub instanceof Super is false function Super var obj prop1 value1 return obj var sub new Super sub insta
  • 带变量的 iframe 源

    我有一些问题 Is 与 HTMLIFrameElement 相同吗 Why 工作正常 但是 a document getElementsByTagName body 0 b document createElement iframe b s
  • 模块“PDO”已加载到未知行 0

    我将 nginx 与 php5 fpm 一起使用 由于某种原因 我的 php5 fpm 一直说 模块 PDO 已经加载到未知的第 0 行 老实说 我不知道为什么 该扩展不会加载到 php ini 内部 而是从 with config fil
  • 溢出隐藏隐藏下拉菜单,但将溢出隐藏隐藏在隐藏导航背景中

    首先 这是一个 js 小提琴 http jsfiddle net B6DSv http jsfiddle net B6DSv 我遇到的问题是我的 css nav overflow hidden THIS LINE background co
  • ASP.NET WebApi DateTimeOffset 序列化为 Json/JavaScript (angular2)

    我没有找到一个很好的方法来获取 JavaScript Angular2 的 DateTimeOffset 值 我正在使用 WebApi 5 2 3 和 angular2 在网上我看到日期如下 RecordModifiedAt 2016 03
  • OpenGL ES 2.0 中的光线拾取

    我正在尝试在 OpenGL ES 2 0 中实现光线拾取以确定是否已单击对象 到目前为止 我只是想检查是否已按下特定的三角形 我使用这个网站作为动力http android raypick blogspot ca 2012 04 first
  • CodeIgniter 仅允许在登录时访问某些控制器

    我有一些 CodeIgniter 控制器 只能由已登录的用户访问 即 this gt session gt userdata username 不为空 如果未经身份验证的人尝试访问所述控制器 他们应该收到 header location a
  • chromedriver:ubuntu 14.04 64 位上缺少各种 lib 依赖项

    所以我尝试运行从下载的 chromedriver 2 20 wget http chromedriver storage googleapis com 2 20 chromedriver linux64 zip 在我的 ubuntu 14
  • 如何向 UILabel 添加填充? [复制]

    这个问题在这里已经有答案了 UILabel 内的文本与左边框和右边框相冲突 有没有办法向 UILabel 添加一些内部填充 以便文本不会如此紧密地接触内部边框 只需调整标签的位置 我不知道任何其他方法 尽管其他人可能会 如果您对背景颜色有疑
  • OpenXML:Excel 中自动调整列宽

    我已经编写了使用 OpenXML 生成 Excel 文件的代码 下面是在 Excel 中生成列的代码 Worksheet worksheet new Worksheet Columns columns new Columns int num
  • HistoryRecord 的活动空闲超时?

    W ActivityManager 81 Launch timeout has expired giving up wake lock W ActivityManager 81 Activity idle timeout for Histo
  • log4j:记录包,但不包括其子包

    您好 我想排除某些子包被我的一个记录器记录 因为它们正在被另一个记录器记录 例如 com mysite app logger1 com mysite app news logger2 com mysite app events logger
  • 如何使用 ASP.NET MVC 将字典绑定到一组复选框?

    我的需要是 绑定 Dictionary
  • Maven 的 Jersey 问题 - Shade 插件

    我的问题非常类似于 仅当依赖项组装到单个 jar 中时才会抛出 Jersey 异常 https stackoverflow com questions 12611213 jersey exception only thrown when d
  • 过滤R中所有列包含相同数据的行

    我有一个数据集 要求每个参与者回答一系列问题 有些人对每个问题都给出了相同的回答 我想丢弃这些参与者的数据 但不知道如何去做 我的意思是我可以尝试过滤 区分 但我遇到的问题是大约有 100 个问题 所以 100 列 我不确定使 R 过滤所有
  • 使用PHP 5.5的password_hash和password_verify函数

    假设我想存储用户的密码 这是否是使用 PHP 5 5 的正确方法password hash 函数 或 PHP 5 3 7 的此版本 https github com ircmaxell password compat https githu
  • 我在 Visual Studio 2010 中找不到从工具菜单生成本地资源

    我在网页的设计视图 标记 中 我在工具菜单中找不到 生成本地资源 谁能告诉我如何启用这个工具 查看 aspx 或 ascx 文件时 确保您正在查看 设计 或 拆分 选项卡 而不是 源 选项卡 此外 这篇文章可能会有所帮助 其中部分指出 如果
  • C# 中的 'volatile' 关键字仍然被破坏吗?

    乔 阿尔巴哈里有一个很棒的系列 http www albahari com threading 关于多线程 这是必读的内容 对于任何从事 C 多线程处理的人来说都应该牢记于心 然而 在第 4 部分中 他提到了 volatile 的问题 请注
  • 获取用户信息 Google-PHP-Client 问题?

    首先 我只想说我需要从用户那里获取哪些信息 全名 名字 姓氏 电子邮件地址 主帐户 而不是 google plus com 位置 国家 州 城市 地址 Youtube 用户名 为了获取所有这些信息 我继续下载 安装位于以下位置的 PHP 客
  • 如何创建静态链接共享库

    在我的硕士论文中 我尝试为 ARM Cortex M3 嵌入式系统采用共享库方法 由于我们的目标板没有 MMU 我认为使用 普通 动态共享库是没有意义的 因为 text 是直接从闪存执行的 而 data 在启动时被复制到 RAM 所以我无法