配備 Apple 晶片之 Mac 上的 Rosetta 2
配備 Apple 晶片的 Mac 可使用一套稱為 Rosetta 2 的轉譯機制來執行以 x86_64 指令集編譯的程式碼。此機制提供兩種類型的轉譯:即時和提前。
即時轉譯
即時(JIT)轉譯流程中,系統會在映像執行路徑的早期階段識別 x86_64 Mach 物件。遇到這些映像時,核心會將控制權轉移給特殊的 Rosetta 轉譯虛設常式,而非動態連結編輯器 dyld(1)
。接著這個轉譯虛設常式會在映像執行期間轉譯 x86_64 頁面。這個轉譯作業完全在處理序中進行。核心仍會根據頁面發生錯誤時附加至二進位檔的程式碼簽章,驗證每個 x86_64 頁面的程式碼雜湊。若雜湊不相符,核心就會強制執行適用於該處理序的修復規則。
提前轉譯
若採用提前(AOT)轉譯路徑,當系統認為這種方式可以使程式碼達到最佳的回應效率時,就會從儲存體讀取 x86_64 二進位檔。轉譯完的成品會作為特殊類型的 Mach 物件檔案寫入儲存體中。該檔案類似可執行的映像,但是系統會將其標記以指出它是轉譯另一個映像所產生的成品。
在這個模式中,AOT 成品會從原始的 x86_64 可執行映像衍生出所有識別資訊。為了強制這個綁定關係,有特殊權限的使用者空間實體會使用裝置專屬的密鑰(受到「安全隔離區」管理)來簽署轉譯成品。這個密鑰只會發佈給有特殊權限的使用者空間實體,而系統會利用受限制的權限來識別這個實體。為了轉譯成品而製作的程式碼目錄中,包含原始 x86_64 可執行映像的程式碼目錄雜湊。轉譯成品本身上的簽章也稱為補充簽章。
AOT 流程的開始方式類似 JIT 流程,核心會將控制權轉移給 Rosetta 執行階段,而非動態連結編輯器 dyld(1)
。但是接著 Rosetta 執行階段會傳送程序間通訊(IPC)查詢給 Rosetta 系統服務,詢問目前的可執行映像是否有可用的 AOT 轉譯。如果有找到,Rosetta 服務會提供一個控制代碼給該轉譯,再將它對應到處理序中並執行。執行期間,核心會強制執行轉譯成品(藉由根植在裝置專屬簽署密鑰中的簽章進行認證)的程式碼目錄雜湊。這個處理序與原始 x86_64 映像的程式碼目錄雜湊無關。
轉譯後的成品會儲存在 Data Vault 中;除了 Rosetta 服務以外,任何實體都不能在執行階段存取該 Data Vault。Rosetta 服務會藉由分發唯讀檔案描述元給個別轉譯成品來管理快取的存取,這樣可限制存取 AOT 成品快取。這個服務的程序間通訊和獨立的磁碟使用量會刻意維持在極小的範圍內,藉此限縮其攻擊面。
如果原始 x86_64 映像的程式碼目錄雜湊不符合編碼為 AOT 轉譯成品的簽章,系統就會將此結果視為等同於無效的程式碼簽章,並採取適當的強制措施。
如果遠端處理序向核心查詢 AOT 轉譯可執行檔的權限或其他程式碼識別屬性,則會傳回原始 x86_64 映像的識別屬性。
靜態信任快取內容
macOS 11 或以上版本隨附 Mach「厚實」二進位檔,其中包含 x86_64 和 arm64 電腦程式碼的配量。在配備 Apple 晶片的 Mac 上,使用者可選擇透過 Rosetta 流程執行系統二進位檔的 x86_64 配量,例如需載入不含原生 arm64 變體的外掛模組。為支援此作法,macOS 隨附的靜態信任快取通常包含每個 Mach 物件檔案的三個程式碼目錄雜湊:
arm64 配量的程式碼目錄雜湊
x86_64 配量的程式碼目錄雜湊
x86_64 配量之 AOT 轉譯的程式碼目錄雜湊
Rosetta AOT 轉譯程序具確定性,因為其會為任何提供的輸入重製相同的輸出,無論轉譯何時執行或是在哪個裝置上執行結果都一樣。
建立 macOS 期間,每個 Mach 物件檔案都會經歷與建立中 macOS 版本相關聯的 Rosetta AOT 轉譯流程,藉此將程式碼目錄雜湊記錄在信任快取中。為求效率,實際的轉譯產品不會隨作業系統提供,且會在使用者提出要求時隨需重新建構。
當 x86_64 映像在配備 Apple 晶片的 Mac 上執行時,如果該映像的程式碼目錄雜湊位於靜態信任快取中,所產生 AOT 成品的程式碼目錄雜湊也預期會存在於靜態信任快取中。這類產品沒有經過裝置專屬密鑰簽署,因為簽署管理中心根植在 Apple 安全開機鏈中。
未簽署的 x86_64 程式碼
配備 Apple 晶片的 Mac 不允許原生 arm64 程式碼在沒有附加有效簽章的情況下執行。這個簽章可以像「臨機操作」程式碼簽章(cf. codesign(1)
)一樣簡單,不包含來自非對稱式密鑰組秘密部分的任何實際的識別資料(只是二進位檔的未認證測量)。
為了讓二進位檔具有相容性,系統允許轉譯的 x86_64 程式碼在沒有簽章的情況下透過 Rosetta 執行。不會有任何識別資料透過裝置專用的「安全隔離區」簽署程序傳達到這個程式碼中,且其執行限制與在採用 Intel 架構的 Mac 上執行的原生未簽署程式碼完全一致。