【问题标题】:GCC: disguising between GCC versionsGCC:在 GCC 版本之间伪装
【发布时间】:2012-03-29 15:48:36
【问题描述】:

这个问题来自this question。

问题是Linux 有一个NVidia 驱动程序,用GCC 4.5 编译。 kernel 是用 GCC 4.6 编译的。好吧,由于GCCs 之间的版本号差异,这些东西不起作用。 (安装程序说驱动程序不起作用 - 详细信息请访问上面的链接)

可以将使用GCC 4.5 编译的二进制文件伪装成使用GCC 4.6 编译的二进制文件吗?如果可以,在什么情况下会好用?

【问题讨论】:

  • 在拒绝加载或崩溃或...时不起作用?
  • 为什么不用 GCC 4.5 重新编译内核?
  • 让我提一下,原来的问题不是我的。安装程序说版本不合适。我在 UNIX/Linux 站点上建议重新编译内核,但我很好奇没有它如何解决问题。将其视为一个抽象问题:如果我们将它伪装成 $progname.$gccversion2,那么 $progname.$gccversion1 什么时候可以工作?

标签: gcc linux-kernel version driver nvidia


【解决方案1】:

您的问题称为 ABI:应用程序二进制接口。这是一组规则(除其他外),一段代码中的函数如何获取其参数(排序、堆栈上类型的填充)、函数命名,以便链接器可以解析符号和结构中字段的填充/对齐。

GCC 试图在编译器版本之间保持 ABI 稳定,但这并不总是可行的。

例如,GCC 4.4 fixed a bug in packed bit-fields 这意味着旧/新代码无法再使用此功能正确读取结构。如果您将 4.4 之前和之后的版本混合使用,则会发生数据损坏而不会崩溃。

在 4.6 发行说明中没有迹象表明 ABI 已更改,但这是 Linux 内核无法知道的 - 它只是读取用于编译代码的编译器版本,如果前两个数字发生更改,它假定运行代码是不安全的。

有两种解决方案:

  1. 您可以使用与内核相同的编译器来编译 Nvidia 驱动程序。 强烈推荐

  2. 您可以修补二进制文件中的版本字符串。这将欺骗内核加载模块,但有可能导致内部数据结构数据损坏。

【讨论】:

  • 是内核和驱动编译成相同的gcc版本更重要,还是驱动和程序编译更重要,还是三者都需要相同?
  • 这三个都使用相同的 ABI 编译,这一点很重要。您可以毫无问题地使用 4.6 编译内核和使用 4.7 编译程序。
猜你喜欢
  • 2017-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多