虚拟/逻辑内存和程序重定位

时间:2015-07-22 14:02:52

标签: linker loader virtual-memory systems-programming relocation

虚拟内存和逻辑内存有助于确保程序不会破坏彼此的数据。

程序重定位几乎类似于确保多个程序不会相互损坏。重定位修改目标程序,以便可以在新的备用地址加载。

虚拟内存,逻辑内存和程序重定位如何相关?它们相似吗? 如果它们相同/相似,那么为什么我们需要程序重定位?

2 个答案:

答案 0 :(得分:1)

可重定位程序,或称另一种与位置无关的代码,传统上在两种情况下使用:

  • 没有虚拟内存的系统(或太基本的虚拟内存,例如经典的MacOS),适用于任何代码
  • 对于动态库,即使在具有虚拟内存的系统上也是如此,因为如果其他代码已经在主机程序的地址空间中的那个空间,动态库可能会发现自己在一个不是其首选地址的地址上。 / LI>

然而,今天,即使是具有虚拟存储器的系统上的主要可执行程序也倾向于与位置无关(例如,Mac OS X上的PIE *构建标志),因此可以将它们加载到随机地址以防止利用,例如,那些使用ROP **。

*位置独立可执行文件
**面向回归的编程

答案 1 :(得分:0)

虚拟内存不会阻止程序干扰其他程序。这是逻辑记忆。不幸的是,这两个概念通常被混为“虚拟内存”。

有两种类型的重定位,并且不清楚您指的是哪种类型。但是,它们是相互联系的。另一方面,这个概念与虚拟内存并不真正相关。

可重定位代码的第一个概念。这对于通常必须映射到不同地址的共享库至关重要。

可重定位代码使用偏移而不是绝对地址。当程序产生类似的指令序列时:

JUMP the-number-of-bytes-to-SOMELABEL

计算机或汇编程序将其编码为

JUMP to-the-address-of-somelabel.

而不是

Writing config/database.yml to read from DATABASE_URL
-----> Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       NameError: uninitialized constant OpenConferenceWare
       /tmp/staged/app/config/initializers/01_open_conference_ware.rb:3:in `<top (required)>'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/engine.rb:609:in `block (2 levels) in <class:Engine>'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/engine.rb:608:in `each'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/engine.rb:608:in `block in <class:Engine>'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/initializable.rb:30:in `instance_exec'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/initializable.rb:30:in `run'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/initializable.rb:55:in `block in run_initializers'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/initializable.rb:54:in `run_initializers'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/application.rb:215:in `initialize!'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/railtie/configurable.rb:30:in `method_missing'
       /tmp/staged/app/config/environment.rb:5:in `<top (required)>'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/application.rb:189:in `require_environment!'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/railties-4.0.2/lib/rails/application.rb:250:in `block in run_tasks_blocks'
       /tmp/staged/app/vendor/bundle/ruby/2.1.0/gems/sprockets-rails-2.0.1/lib/sprockets/rails/task.rb:54:in `block (2 levels) in define'
       Tasks: TOP => environment
       (See full trace by running task with --trace)
 !
 !     Precompiling assets failed.
 !
Staging failed: Buildpack compilation step failed

通过使用偏移量,无论JMP指令位于何处,代码都以相同的方式工作。

第二种类型的重定位使用第一种。在过去,搬迁主要用于图书馆。现在,一些操作系统将在内存中的不同位置加载程序段。这是为了安全。它旨在防止依赖于在特定地址加载应用程序的恶意破解。

这两个概念都可以使用或不使用虚拟内存。

请注意,通常不会修改程序以重新定位它。我通常,因为可执行文件通常会有一些需要在运行时修复的地址。