From 9753695744854686a6b80012c89b0d850a44b4b0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 27 Mar 2025 15:39:15 +0100 Subject: [PATCH] The `no_mangle` attribute is unsafe since Rust 2024 --- .../posts/01-freestanding-rust-binary/index.fa.md | 4 ++-- .../posts/01-freestanding-rust-binary/index.fr.md | 6 +++--- .../posts/01-freestanding-rust-binary/index.ja.md | 6 +++--- .../posts/01-freestanding-rust-binary/index.ko.md | 6 +++--- .../posts/01-freestanding-rust-binary/index.md | 6 +++--- .../posts/01-freestanding-rust-binary/index.ru.md | 6 +++--- .../01-freestanding-rust-binary/index.zh-CN.md | 4 ++-- .../01-freestanding-rust-binary/index.zh-TW.md | 4 ++-- .../posts/02-minimal-rust-kernel/index.fa.md | 4 ++-- .../posts/02-minimal-rust-kernel/index.fr.md | 8 ++++---- .../posts/02-minimal-rust-kernel/index.ja.md | 8 ++++---- .../posts/02-minimal-rust-kernel/index.ko.md | 8 ++++---- .../posts/02-minimal-rust-kernel/index.md | 8 ++++---- .../posts/02-minimal-rust-kernel/index.ru.md | 8 ++++---- .../posts/02-minimal-rust-kernel/index.zh-CN.md | 8 ++++---- .../edition-2/posts/03-vga-text-buffer/index.fa.md | 6 +++--- .../edition-2/posts/03-vga-text-buffer/index.ja.md | 6 +++--- .../edition-2/posts/03-vga-text-buffer/index.ko.md | 6 +++--- .../edition-2/posts/03-vga-text-buffer/index.md | 6 +++--- .../posts/03-vga-text-buffer/index.zh-CN.md | 6 +++--- .../content/edition-2/posts/04-testing/index.fa.md | 12 ++++++------ .../content/edition-2/posts/04-testing/index.ja.md | 12 ++++++------ .../content/edition-2/posts/04-testing/index.ko.md | 14 +++++++------- blog/content/edition-2/posts/04-testing/index.md | 12 ++++++------ .../edition-2/posts/04-testing/index.zh-CN.md | 12 ++++++------ .../edition-2/posts/05-cpu-exceptions/index.fa.md | 4 ++-- .../edition-2/posts/05-cpu-exceptions/index.ja.md | 4 ++-- .../edition-2/posts/05-cpu-exceptions/index.ko.md | 4 ++-- .../edition-2/posts/05-cpu-exceptions/index.md | 4 ++-- .../posts/05-cpu-exceptions/index.zh-CN.md | 4 ++-- .../edition-2/posts/06-double-faults/index.fa.md | 8 ++++---- .../edition-2/posts/06-double-faults/index.ja.md | 8 ++++---- .../edition-2/posts/06-double-faults/index.ko.md | 8 ++++---- .../edition-2/posts/06-double-faults/index.md | 8 ++++---- .../posts/06-double-faults/index.zh-CN.md | 8 ++++---- .../posts/07-hardware-interrupts/index.fa.md | 6 +++--- .../posts/07-hardware-interrupts/index.ja.md | 6 +++--- .../posts/07-hardware-interrupts/index.ko.md | 6 +++--- .../posts/07-hardware-interrupts/index.md | 6 +++--- .../posts/07-hardware-interrupts/index.zh-CN.md | 6 +++--- .../posts/08-paging-introduction/index.fa.md | 4 ++-- .../posts/08-paging-introduction/index.ja.md | 4 ++-- .../posts/08-paging-introduction/index.md | 4 ++-- .../posts/08-paging-introduction/index.zh-CN.md | 4 ++-- .../posts/09-paging-implementation/index.ja.md | 2 +- .../posts/09-paging-implementation/index.md | 2 +- .../posts/09-paging-implementation/index.zh-CN.md | 2 +- 47 files changed, 149 insertions(+), 149 deletions(-) diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fa.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fa.md index 51fb64c2..06cbb3b1 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fa.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fa.md @@ -219,7 +219,7 @@ fn panic(_info: &PanicInfo) -> ! { ممکن است متوجه شده باشید که ما تابع `main` را حذف کردیم. دلیل این امر این است که `main` بدون یک رانتایم اساسی که آن را صدا کند معنی ندارد. در عوض، ما در حال بازنویسی نقطه ورود سیستم‌عامل با تابع `start_` خود هستیم: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } @@ -469,7 +469,7 @@ rustflags = ["-C", "link-args=-e __start -static -nostartfiles"] use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fr.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fr.md index 7f1c69a9..9bd4e7d7 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fr.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.fr.md @@ -216,13 +216,13 @@ fn panic(_info: &PanicInfo) -> ! { Vous remarquerez peut-être que nous avons retiré la fonction `main`. La raison est que la présence de cette fonction n'a pas de sens sans un environnement d'exécution sous-jacent qui l'appelle. À la place, nous réécrivons le point d'entrée du système d'exploitation avec notre propre fonction `_start` : ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } ``` -En utilisant l'attribut `#[no_mangle]`, nous désactivons la [décoration de nom] pour assurer que le compilateur Rust crée une fonction avec le nom `_start`. Sans cet attribut, le compilateur génèrerait un symbol obscure `_ZN3blog_os4_start7hb173fedf945531caE` pour donner un nom unique à chaque fonction. L'attribut est nécessaire car nous avons besoin d'indiquer le nom de la fonction de point d'entrée à l'éditeur de lien (*linker*) dans l'étape suivante. +En utilisant l'attribut `#[unsafe(no_mangle)]`, nous désactivons la [décoration de nom] pour assurer que le compilateur Rust crée une fonction avec le nom `_start`. Sans cet attribut, le compilateur génèrerait un symbol obscure `_ZN3blog_os4_start7hb173fedf945531caE` pour donner un nom unique à chaque fonction. L'attribut est nécessaire car nous avons besoin d'indiquer le nom de la fonction de point d'entrée à l'éditeur de lien (*linker*) dans l'étape suivante. Nous devons aussi marquer la fonction avec `extern C` pour indiquer au compilateur qu'il devrait utiliser la [convention de nommage] de C pour cette fonction (au lieu de la convention de nommage de Rust non-spécifiée). Cette fonction se nomme `_start` car c'est le nom par défaut des points d'entrée pour la plupart des systèmes. @@ -466,7 +466,7 @@ Un exécutable Rust autoporté minimal ressemble à ceci : use core::panic::PanicInfo; -#[no_mangle] // ne pas décorer le nom de cette fonction +#[unsafe(no_mangle)] // ne pas décorer le nom de cette fonction pub extern "C" fn _start() -> ! { // cette fonction est le point d'entrée, comme le linker cherche une fonction // nomée `_start` par défaut diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ja.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ja.md index 142da049..4e34de09 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ja.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ja.md @@ -218,13 +218,13 @@ fn panic(_info: &PanicInfo) -> ! { `main` 関数を削除したことに気付いたかもしれません。`main` 関数を呼び出す基盤となるランタイムなしには置いていても意味がないからです。代わりに、OS のエントリポイントを独自の `_start` 関数で上書きしていきます: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } ``` -Rust コンパイラが `_start` という名前の関数を実際に出力するように、`#[no_mangle]` attributeを用いて[名前修飾][name mangling]を無効にします。この attribute がないと、コンパイラはすべての関数にユニークな名前をつけるために、 `_ZN3blog_os4_start7hb173fedf945531caE` のようなシンボルを生成します。次のステップでエントリポイントとなる関数の名前をリンカに伝えるため、この属性が必要となります。 +Rust コンパイラが `_start` という名前の関数を実際に出力するように、`#[unsafe(no_mangle)]` attributeを用いて[名前修飾][name mangling]を無効にします。この attribute がないと、コンパイラはすべての関数にユニークな名前をつけるために、 `_ZN3blog_os4_start7hb173fedf945531caE` のようなシンボルを生成します。次のステップでエントリポイントとなる関数の名前をリンカに伝えるため、この属性が必要となります。 また、(指定されていない Rust の呼び出し規約の代わりに)この関数に [C の呼び出し規約][C calling convention]を使用するようコンパイラに伝えるために、関数を `extern "C"` として定義する必要があります。`_start`という名前をつける理由は、これがほとんどのシステムのデフォルトのエントリポイント名だからです。 @@ -473,7 +473,7 @@ rustflags = ["-C", "link-args=-e __start -static -nostartfiles"] use core::panic::PanicInfo; -#[no_mangle] // この関数の名前修飾をしない +#[unsafe(no_mangle)] // この関数の名前修飾をしない pub extern "C" fn _start() -> ! { // リンカはデフォルトで `_start` という名前の関数を探すので、 // この関数がエントリポイントとなる diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ko.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ko.md index 3b24f91c..d3dddf68 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ko.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ko.md @@ -234,13 +234,13 @@ fn panic(_info: &PanicInfo) -> ! { 우리는 운영체제가 호출하는 프로그램 실행 시작 지점 대신 우리의 새로운 `_start` 함수를 실행 시작 지점으로 대체할 것입니다. ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } ``` -`#[no_mangle]` 속성을 통해 [name mangling]을 해제하여 Rust 컴파일러가 `_start` 라는 이름 그대로 함수를 만들도록 합니다. 이 속성이 없다면, 컴파일러가 각 함수의 이름을 고유하게 만드는 과정에서 이 함수의 실제 이름을 `_ZN3blog_os4_start7hb173fedf945531caE` 라는 이상한 이름으로 바꿔 생성합니다. 우리가 원하는 실제 시작 지점 함수의 이름을 정확히 알고 있어야 링커 (linker)에도 그 이름을 정확히 전달할 수 있기에 (후속 단계에서 진행) `#[no_mangle]` 속성이 필요합니다. +`#[unsafe(no_mangle)]` 속성을 통해 [name mangling]을 해제하여 Rust 컴파일러가 `_start` 라는 이름 그대로 함수를 만들도록 합니다. 이 속성이 없다면, 컴파일러가 각 함수의 이름을 고유하게 만드는 과정에서 이 함수의 실제 이름을 `_ZN3blog_os4_start7hb173fedf945531caE` 라는 이상한 이름으로 바꿔 생성합니다. 우리가 원하는 실제 시작 지점 함수의 이름을 정확히 알고 있어야 링커 (linker)에도 그 이름을 정확히 전달할 수 있기에 (후속 단계에서 진행) `#[unsafe(no_mangle)]` 속성이 필요합니다. 또한 우리는 이 함수에 `extern "C"`라는 표시를 추가하여 이 함수가 Rust 함수 호출 규약 대신에 [C 함수 호출 규약][C calling convention]을 사용하도록 합니다. 함수의 이름을 `_start`로 지정한 이유는 그저 런타임 시스템들의 실행 시작 함수 이름이 대부분 `_start`이기 때문입니다. @@ -487,7 +487,7 @@ Linux, Windows 또는 macOS 위에서 동작하는 freestanding 실행파일을 use core::panic::PanicInfo; -#[no_mangle] // 이 함수의 이름을 mangle하지 않습니다 +#[unsafe(no_mangle)] // 이 함수의 이름을 mangle하지 않습니다 pub extern "C" fn _start() -> ! { // 링커는 기본적으로 '_start' 라는 이름을 가진 함수를 실행 시작 지점으로 삼기에, // 이 함수는 실행 시작 지점이 됩니다 diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.md index afe21cd3..1550ec59 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.md @@ -213,13 +213,13 @@ fn panic(_info: &PanicInfo) -> ! { You might notice that we removed the `main` function. The reason is that a `main` doesn't make sense without an underlying runtime that calls it. Instead, we are now overwriting the operating system entry point with our own `_start` function: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } ``` -By using the `#[no_mangle]` attribute, we disable [name mangling] to ensure that the Rust compiler really outputs a function with the name `_start`. Without the attribute, the compiler would generate some cryptic `_ZN3blog_os4_start7hb173fedf945531caE` symbol to give every function a unique name. The attribute is required because we need to tell the name of the entry point function to the linker in the next step. +By using the `#[unsafe(no_mangle)]` attribute, we disable [name mangling] to ensure that the Rust compiler really outputs a function with the name `_start`. Without the attribute, the compiler would generate some cryptic `_ZN3blog_os4_start7hb173fedf945531caE` symbol to give every function a unique name. The attribute is required because we need to tell the name of the entry point function to the linker in the next step. We also have to mark the function as `extern "C"` to tell the compiler that it should use the [C calling convention] for this function (instead of the unspecified Rust calling convention). The reason for naming the function `_start` is that this is the default entry point name for most systems. @@ -463,7 +463,7 @@ A minimal freestanding Rust binary looks like this: use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ru.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ru.md index ebb4daed..c3ad25e8 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ru.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.ru.md @@ -216,13 +216,13 @@ fn panic(_info: &PanicInfo) -> ! { Можно заметить, что мы удалили функцию `main`. Причина в том, что `main` не имеет смысла без стандартного runtime, которая ее вызывает. Вместо этого мы переопределим точку входа операционной системы с помощью нашей собственной функции `_start`: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } ``` -Используя атрибут `#[no_mangle]`, мы отключаем [искажение имен][name mangling], чтобы гарантировать, что компилятор Rust сгенерирует функцию с именем `_start`. Без этого атрибута компилятор генерировал бы какой-нибудь загадочный символ `_ZN3blog_os4_start7hb173fedf945531caE`, чтобы дать каждой функции уникальное имя. Атрибут необходим, потому что на следующем этапе нам нужно сообщить имя функции точки входа компоновщику. +Используя атрибут `#[unsafe(no_mangle)]`, мы отключаем [искажение имен][name mangling], чтобы гарантировать, что компилятор Rust сгенерирует функцию с именем `_start`. Без этого атрибута компилятор генерировал бы какой-нибудь загадочный символ `_ZN3blog_os4_start7hb173fedf945531caE`, чтобы дать каждой функции уникальное имя. Атрибут необходим, потому что на следующем этапе нам нужно сообщить имя функции точки входа компоновщику. Мы также должны пометить функцию как `extern "C"`, чтобы указать компилятору, что он должен использовать [соглашение о вызове C][C calling convention] для этой функции (вместо неопределенного соглашения о вызове Rust). Причина именования функции `_start` в том, что это имя точки входа по умолчанию для большинства систем. @@ -465,7 +465,7 @@ rustflags = ["-C", "link-args=-e __start -static -nostartfiles"] use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-CN.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-CN.md index 3eec8692..b5012238 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-CN.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-CN.md @@ -184,7 +184,7 @@ fn panic(_info: &PanicInfo) -> ! { 读者也许会注意到,我们移除了 `main` 函数。原因很显然,既然没有底层运行时调用它,`main` 函数也失去了存在的必要性。为了重写操作系统的入口点,我们转而编写一个 `_start` 函数: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } @@ -422,7 +422,7 @@ rustflags = ["-C", "link-args=-e __start -static -nostartfiles"] use core::panic::PanicInfo; -#[no_mangle] // 不重整函数名 +#[unsafe(no_mangle)] // 不重整函数名 pub extern "C" fn _start() -> ! { // 因为链接器会寻找一个名为 `_start` 的函数,所以这个函数就是入口点 // 默认命名为 `_start` diff --git a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-TW.md b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-TW.md index 8e706bc1..55e45de1 100644 --- a/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-TW.md +++ b/blog/content/edition-2/posts/01-freestanding-rust-binary/index.zh-TW.md @@ -216,7 +216,7 @@ fn panic(_info: &PanicInfo) -> ! { 您可能會注意到我們移除了 `main` 函式,原因是因為既然沒有了底層的執行時系統呼叫,那麼 `main` 也沒必要存在。我們要重寫作業系統的入口點,定義為 `_start` 函式: ```rust -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { loop {} } @@ -465,7 +465,7 @@ rustflags = ["-C", "link-args=-e __start -static -nostartfiles"] use core::panic::PanicInfo; -#[no_mangle] // 不修飾函式名稱 +#[unsafe(no_mangle)] // 不修飾函式名稱 pub extern "C" fn _start() -> ! { // 因為連結器預設會尋找 `_start` 函式名稱 // 所以這個函式就是入口點 diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fa.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fa.md index a8987e77..a178ceef 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fa.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fa.md @@ -245,7 +245,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default @@ -367,7 +367,7 @@ target = "x86_64-blog_os.json" ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index a903a24e..1dbe07e7 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -241,7 +241,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // ne pas massacrer le nom de cette fonction +#[unsafe(no_mangle)] // ne pas massacrer le nom de cette fonction pub extern "C" fn _start() -> ! { // cette fonction est le point d'entrée, puisque le lieur cherche une fonction // nommée `_start` par défaut @@ -306,7 +306,7 @@ Nous voyons que `cargo build` recompile maintenant les bibliothèques `core`, `r Le compilateur Rust assume qu'un certain ensemble de fonctions intégrées sont disponibles pour tous les systèmes. La plupart de ces fonctions sont fournies par la crate `compiler_builtins` que nous venons de recompiler. Toutefois, certaines fonctions liées à la mémoire dans cette crate ne sont pas activées par défaut puisqu'elles sont normalement fournies par la bibliothèque C sur le système. Parmi ces fonctions, on retrouve `memset`, qui définit tous les octets dans un bloc mémoire à une certaine valeur, `memcpy`, qui copie un bloc mémoire vers un autre, et `memcmp`, qui compare deux blocs mémoire. Alors que nous n'avions pas besoin de ces fonctions pour compiler notre noyau maintenant, elles seront nécessaires aussitôt que nous lui ajouterons plus de code (par exemple, lorsque nous copierons des `struct`). -Puisque nous ne pouvons pas lier avec la bibliothèque C du système d'exploitation, nous avons besoin d'une méthode alternative de fournir ces fonctions au compilateur. Une approche possible pour ce faire serait d'implémenter nos propre fonctions `memset`, etc. et de leur appliquer l'attribut `#[no_mangle]` (pour prévenir le changement de nom automatique pendant la compilation). Or, ceci est dangereux puisque toute erreur dans l'implémentation pourrait mener à un comportement indéterminé. Par exemple, implémenter `memcpy` avec une boucle `for` pourrait mener à une recursion infinie puisque les boucles `for` invoquent implicitement la méthode _trait_ [`IntoIterator::into_iter`], qui pourrait invoquer `memcpy` de nouveau. C'est donc une bonne idée de plutôt réutiliser des implémentations existantes et éprouvées. +Puisque nous ne pouvons pas lier avec la bibliothèque C du système d'exploitation, nous avons besoin d'une méthode alternative de fournir ces fonctions au compilateur. Une approche possible pour ce faire serait d'implémenter nos propre fonctions `memset`, etc. et de leur appliquer l'attribut `#[unsafe(no_mangle)]` (pour prévenir le changement de nom automatique pendant la compilation). Or, ceci est dangereux puisque toute erreur dans l'implémentation pourrait mener à un comportement indéterminé. Par exemple, implémenter `memcpy` avec une boucle `for` pourrait mener à une recursion infinie puisque les boucles `for` invoquent implicitement la méthode _trait_ [`IntoIterator::into_iter`], qui pourrait invoquer `memcpy` de nouveau. C'est donc une bonne idée de plutôt réutiliser des implémentations existantes et éprouvées. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -324,7 +324,7 @@ build-std = ["core", "compiler_builtins"] (Le support pour la fonctionnalité `compiler-builtins-mem` a [été ajouté assez récemment](https://github.com/rust-lang/rust/pull/77284), donc vous aurez besoin de la version nocturne `2020-09-30` de Rust ou plus récent pour l'utiliser.) -Dans les coulisses, ce drapeau active la [fonctionnalité `mem`][`mem` feature] de la crate `compiler_builtins`. Le résultat est que l'attribut `#[no_mangle]` est appliqué aux [implémentations `memcpy` et autres][`memcpy` etc. implementations] de la caise, ce qui les rend disponible au lieur. +Dans les coulisses, ce drapeau active la [fonctionnalité `mem`][`mem` feature] de la crate `compiler_builtins`. Le résultat est que l'attribut `#[unsafe(no_mangle)]` est appliqué aux [implémentations `memcpy` et autres][`memcpy` etc. implementations] de la caise, ce qui les rend disponible au lieur. [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -362,7 +362,7 @@ L'implémentation ressemble à ceci : ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ja.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ja.md index 183972d4..faf191e4 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ja.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ja.md @@ -239,7 +239,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default @@ -304,7 +304,7 @@ build-std = ["core", "compiler_builtins"] Rustコンパイラは、すべてのシステムにおいて、特定の組み込み関数が利用可能であるということを前提にしています。それらの関数の多くは、私達がちょうど再コンパイルした`compiler_builtins`クレートによって提供されています。しかしながら、通常システムのCライブラリによって提供されているので標準では有効化されていない、メモリ関係の関数がいくつかあります。それらの関数には、メモリブロック内のすべてのバイトを与えられた値にセットする`memset`、メモリーブロックを他のブロックへとコピーする`memcpy`、2つのメモリーブロックを比較する`memcmp`などがあります。これらの関数はどれも、現在の段階で我々のカーネルをコンパイルするのに必要というわけではありませんが、コードを追加していくとすぐに必要になるでしょう(たとえば、構造体をコピーする、など)。 -オペレーティングシステムのCライブラリにリンクすることはできませんので、これらの関数をコンパイラに与えてやる別の方法が必要になります。このための方法として考えられるものの一つが、自前で`memset`を実装し、(コンパイル中の自動リネームを防ぐため)`#[no_mangle]`アトリビュートをこれらに適用することでしょう。しかし、こうすると、これらの関数の実装のちょっとしたミスが未定義動作に繋がりうるため危険です。たとえば、`for`ループを使って`memcpy`を実装すると無限再帰を起こしてしまうかもしれません。なぜなら、`for`ループは暗黙のうちに[`IntoIterator::into_iter`]トレイトメソッドを呼び出しており、これが`memcpy`を再び呼び出しているかもしれないためです。なので、代わりに既存のよくテストされた実装を再利用するのが良いでしょう。 +オペレーティングシステムのCライブラリにリンクすることはできませんので、これらの関数をコンパイラに与えてやる別の方法が必要になります。このための方法として考えられるものの一つが、自前で`memset`を実装し、(コンパイル中の自動リネームを防ぐため)`#[unsafe(no_mangle)]`アトリビュートをこれらに適用することでしょう。しかし、こうすると、これらの関数の実装のちょっとしたミスが未定義動作に繋がりうるため危険です。たとえば、`for`ループを使って`memcpy`を実装すると無限再帰を起こしてしまうかもしれません。なぜなら、`for`ループは暗黙のうちに[`IntoIterator::into_iter`]トレイトメソッドを呼び出しており、これが`memcpy`を再び呼び出しているかもしれないためです。なので、代わりに既存のよくテストされた実装を再利用するのが良いでしょう。 [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -321,7 +321,7 @@ build-std-features = ["compiler-builtins-mem"] (`compiler-builtins-mem`機能のサポートが追加されたのは[つい最近](https://github.com/rust-lang/rust/pull/77284)なので、`2019-09-30`以降のRust nightlyが必要です。) -このとき、裏で`compiler_builtins`クレートの[`mem`機能][`mem` feature]が有効化されています。これにより、このクレートの[`memcpy`などの実装][`memcpy` etc. implementations]に`#[no_mangle]`アトリビュートが適用され、リンカがこれらを利用できるようになっています。 +このとき、裏で`compiler_builtins`クレートの[`mem`機能][`mem` feature]が有効化されています。これにより、このクレートの[`memcpy`などの実装][`memcpy` etc. implementations]に`#[unsafe(no_mangle)]`アトリビュートが適用され、リンカがこれらを利用できるようになっています。 [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L51-L52 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -359,7 +359,7 @@ target = "x86_64-blog_os.json" ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ko.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ko.md index 25f19702..f1eaec8c 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ko.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ko.md @@ -249,7 +249,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // 이 함수의 이름을 mangle하지 않습니다 +#[unsafe(no_mangle)] // 이 함수의 이름을 mangle하지 않습니다 pub extern "C" fn _start() -> ! { // 링커는 기본적으로 '_start' 라는 이름을 가진 함수를 실행 시작 지점으로 삼기에, // 이 함수는 실행 시작 지점이 됩니다 @@ -314,7 +314,7 @@ cargo 설정 키 `unstable.build-std`를 설정하고 `rust-src` 컴포넌트를 Rust 컴파일러는 특정 군의 내장 함수들이 (built-in function) 모든 시스템에서 주어진다고 가정합니다. 대부분의 내장 함수들은 우리가 방금 컴파일한 `compiler_builtins` 크레이트가 이미 갖추고 있습니다. 하지만 그중 몇몇 메모리 관련 함수들은 기본적으로 사용 해제 상태가 되어 있는데, 그 이유는 해당 함수들을 호스트 시스템의 C 라이브러리가 제공하는 것이 관례이기 때문입니다. `memset`(메모리 블럭 전체에 특정 값 저장하기), `memcpy` (한 메모리 블럭의 데이터를 다른 메모리 블럭에 옮겨쓰기), `memcmp` (메모리 블럭 두 개의 데이터를 비교하기) 등이 이 분류에 해당합니다. 여태까지는 우리가 이 함수들 중 어느 하나도 사용하지 않았지만, 운영체제 구현을 더 추가하다 보면 필수적으로 사용될 함수들입니다 (예를 들어, 구조체를 복사하여 다른 곳에 저장할 때). -우리는 운영체제의 C 라이브러리를 링크할 수 없기에, 다른 방식으로 이러한 내장 함수들을 컴파일러에 전달해야 합니다. 한 방법은 우리가 직접 `memset` 등의 내장함수들을 구현하고 컴파일 과정에서 함수명이 바뀌지 않도록 `#[no_mangle]` 속성을 적용하는 것입니다. 하지만 이 방법의 경우 우리가 직접 구현한 함수 로직에 아주 작은 실수만 있어도 undefined behavior를 일으킬 수 있기에 위험합니다. 예를 들어 `memcpy`를 구현하는 데에 `for`문을 사용한다면 무한 재귀 루프가 발생할 수 있는데, 그 이유는 `for`문의 구현이 내부적으로 trait 함수인 [`IntoIterator::into_iter`]를 호출하고 이 함수가 다시 `memcpy` 를 호출할 수 있기 때문입니다. 그렇기에 충분히 검증된 기존의 구현 중 하나를 사용하는 것이 바람직합니다. +우리는 운영체제의 C 라이브러리를 링크할 수 없기에, 다른 방식으로 이러한 내장 함수들을 컴파일러에 전달해야 합니다. 한 방법은 우리가 직접 `memset` 등의 내장함수들을 구현하고 컴파일 과정에서 함수명이 바뀌지 않도록 `#[unsafe(no_mangle)]` 속성을 적용하는 것입니다. 하지만 이 방법의 경우 우리가 직접 구현한 함수 로직에 아주 작은 실수만 있어도 undefined behavior를 일으킬 수 있기에 위험합니다. 예를 들어 `memcpy`를 구현하는 데에 `for`문을 사용한다면 무한 재귀 루프가 발생할 수 있는데, 그 이유는 `for`문의 구현이 내부적으로 trait 함수인 [`IntoIterator::into_iter`]를 호출하고 이 함수가 다시 `memcpy` 를 호출할 수 있기 때문입니다. 그렇기에 충분히 검증된 기존의 구현 중 하나를 사용하는 것이 바람직합니다. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -332,7 +332,7 @@ build-std = ["core", "compiler_builtins"] (`compiler-builtins-mem` 기능에 대한 지원이 [굉장히 최근에 추가되었기에](https://github.com/rust-lang/rust/pull/77284), Rust nightly `2020-09-30` 이상의 버전을 사용하셔야 합니다.) -이 기능은 `compiler_builtins` 크레이트의 [`mem` 기능 (feature)][`mem` feature]를 활성화 시킵니다. 이는 `#[no_mangle]` 속성이 [`memcpy` 등의 함수 구현][`memcpy` etc. implementations]에 적용되게 하여 링크가 해당 함수들을 식별하고 사용할 수 있게 합니다. +이 기능은 `compiler_builtins` 크레이트의 [`mem` 기능 (feature)][`mem` feature]를 활성화 시킵니다. 이는 `#[unsafe(no_mangle)]` 속성이 [`memcpy` 등의 함수 구현][`memcpy` etc. implementations]에 적용되게 하여 링크가 해당 함수들을 식별하고 사용할 수 있게 합니다. [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -371,7 +371,7 @@ VGA 버퍼가 정확히 어떤 구조를 하고 있는지는 다음 포스트에 ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.md index 26eda248..81f224d2 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.md @@ -236,7 +236,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default @@ -301,7 +301,7 @@ We see that `cargo build` now recompiles the `core`, `rustc-std-workspace-core` The Rust compiler assumes that a certain set of built-in functions is available for all systems. Most of these functions are provided by the `compiler_builtins` crate that we just recompiled. However, there are some memory-related functions in that crate that are not enabled by default because they are normally provided by the C library on the system. These functions include `memset`, which sets all bytes in a memory block to a given value, `memcpy`, which copies one memory block to another, and `memcmp`, which compares two memory blocks. While we didn't need any of these functions to compile our kernel right now, they will be required as soon as we add some more code to it (e.g. when copying structs around). -Since we can't link to the C library of the operating system, we need an alternative way to provide these functions to the compiler. One possible approach for this could be to implement our own `memset` etc. functions and apply the `#[no_mangle]` attribute to them (to avoid the automatic renaming during compilation). However, this is dangerous since the slightest mistake in the implementation of these functions could lead to undefined behavior. For example, implementing `memcpy` with a `for` loop may result in an infinite recursion because `for` loops implicitly call the [`IntoIterator::into_iter`] trait method, which may call `memcpy` again. So it's a good idea to reuse existing, well-tested implementations instead. +Since we can't link to the C library of the operating system, we need an alternative way to provide these functions to the compiler. One possible approach for this could be to implement our own `memset` etc. functions and apply the `#[unsafe(no_mangle)]` attribute to them (to avoid the automatic renaming during compilation). However, this is dangerous since the slightest mistake in the implementation of these functions could lead to undefined behavior. For example, implementing `memcpy` with a `for` loop may result in an infinite recursion because `for` loops implicitly call the [`IntoIterator::into_iter`] trait method, which may call `memcpy` again. So it's a good idea to reuse existing, well-tested implementations instead. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -319,7 +319,7 @@ build-std = ["core", "compiler_builtins"] (Support for the `compiler-builtins-mem` feature was only [added very recently](https://github.com/rust-lang/rust/pull/77284), so you need at least Rust nightly `2020-09-30` for it.) -Behind the scenes, this flag enables the [`mem` feature] of the `compiler_builtins` crate. The effect of this is that the `#[no_mangle]` attribute is applied to the [`memcpy` etc. implementations] of the crate, which makes them available to the linker. +Behind the scenes, this flag enables the [`mem` feature] of the `compiler_builtins` crate. The effect of this is that the `#[unsafe(no_mangle)]` attribute is applied to the [`memcpy` etc. implementations] of the crate, which makes them available to the linker. [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -357,7 +357,7 @@ The implementation looks like this: ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ru.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ru.md index dea0b18f..bcf97fa7 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ru.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.ru.md @@ -243,7 +243,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { // this function is the entry point, since the linker looks for a function // named `_start` by default @@ -309,7 +309,7 @@ build-std = ["core", "compiler_builtins"] Компилятор Rust предполагает, что определенный набор встроенных функций доступен для всех систем. Большинство этих функций обеспечивается модулем `compiler_builtins`, который мы только что перекомпилировали. Однако в этом модуле есть некоторые функции, связанные с памятью, которые не включены по умолчанию, потому что они обычно предоставляются библиотекой C в системе. Эти функции включают `memset`, которая устанавливает все байты в блоке памяти в заданное значение, `memcpy`, которая копирует один блок памяти в другой, и `memcmp`, которая сравнивает два блока памяти. Хотя ни одна из этих функций нам сейчас не понадобилась для компиляции нашего ядра, они потребуются, как только мы добавим в него дополнительный код (например, при копировании структур). -Поскольку мы не можем ссылаться на С библиотеку хостовой операционной системы, нам нужен альтернативный способ предоставления этих функций компилятору. Одним из возможных подходов для этого может быть реализация наших собственных функций `memset` и т.д. и применение к ним атрибута `#[no_mangle]` (чтобы избежать автоматического переименования во время компиляции). Однако это опасно, поскольку малейшая ошибка в реализации этих функций может привести к неопределенному поведению. Например, при реализации `memcpy` с помощью цикла `for` вы можете получить бесконечную рекурсию, поскольку циклы `for` неявно вызывают метод трейта [`IntoIterator::into_iter`], который может снова вызвать `memcpy`. Поэтому хорошей идеей будет повторное использование существующих, хорошо протестированных реализаций. +Поскольку мы не можем ссылаться на С библиотеку хостовой операционной системы, нам нужен альтернативный способ предоставления этих функций компилятору. Одним из возможных подходов для этого может быть реализация наших собственных функций `memset` и т.д. и применение к ним атрибута `#[unsafe(no_mangle)]` (чтобы избежать автоматического переименования во время компиляции). Однако это опасно, поскольку малейшая ошибка в реализации этих функций может привести к неопределенному поведению. Например, при реализации `memcpy` с помощью цикла `for` вы можете получить бесконечную рекурсию, поскольку циклы `for` неявно вызывают метод трейта [`IntoIterator::into_iter`], который может снова вызвать `memcpy`. Поэтому хорошей идеей будет повторное использование существующих, хорошо протестированных реализаций. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -327,7 +327,7 @@ build-std = ["core", "compiler_builtins"] (Поддержка функции `compiler-builtins-mem` была [добавлена совсем недавно](https://github.com/rust-lang/rust/pull/77284), поэтому для нее вам нужен как минимум Rust nightly `2020-09-30`). -За кулисами этот флаг включает функцию [`mem`][`mem` feature] крейта `compiler_builtins`. Это приводит к тому, что атрибут `#[no_mangle]` применяется к [реализациям `memcpy` и т.п.][`memcpy` etc. implementations] из этого крейта, что делает их доступными для компоновщика. +За кулисами этот флаг включает функцию [`mem`][`mem` feature] крейта `compiler_builtins`. Это приводит к тому, что атрибут `#[unsafe(no_mangle)]` применяется к [реализациям `memcpy` и т.п.][`memcpy` etc. implementations] из этого крейта, что делает их доступными для компоновщика. [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -364,7 +364,7 @@ target = "x86_64-blog_os.json" ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.zh-CN.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.zh-CN.md index 4a907339..afdd9a6f 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.zh-CN.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.zh-CN.md @@ -208,7 +208,7 @@ fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // 不重整函数名 +#[unsafe(no_mangle)] // 不重整函数名 pub extern "C" fn _start() -> ! { // 因为编译器会寻找一个名为 `_start` 的函数,所以这个函数就是入口点 // 默认命名为 `_start` @@ -276,7 +276,7 @@ build-std = ["core", "compiler_builtins"] 比如,`memset`(该函数可以为一个内存块内的所有比特进行赋值)、`memcpy`(将一个内存块里的数据拷贝到另一个内存块)以及`memcmp`(比较两个内存块的数据)。 好在我们的内核暂时还不需要用到这些函数,但是不要高兴的太早,当我们编写更丰富的功能(比如拷贝数据结构)时就会用到了。 -现在我们当然无法提供操作系统相关的标准C库,所以我们需要使用其他办法提供这些东西。一个显而易见的途径就是自己实现 `memset` 这些函数,但不要忘记加入 `#[no_mangle]` 语句,以避免编译时被自动重命名。 当然,这样做很危险,底层函数中最细微的错误也会将程序导向不可预知的未来。比如,你可能在实现 `memcpy` 时使用了一个 `for` 循环,然而 `for` 循环本身又会调用 [`IntoIterator::into_iter`] 这个trait方法,这个方法又会再次调用 `memcpy`,此时一个无限递归就产生了,所以还是使用经过良好测试的既存实现更加可靠。 +现在我们当然无法提供操作系统相关的标准C库,所以我们需要使用其他办法提供这些东西。一个显而易见的途径就是自己实现 `memset` 这些函数,但不要忘记加入 `#[unsafe(no_mangle)]` 语句,以避免编译时被自动重命名。 当然,这样做很危险,底层函数中最细微的错误也会将程序导向不可预知的未来。比如,你可能在实现 `memcpy` 时使用了一个 `for` 循环,然而 `for` 循环本身又会调用 [`IntoIterator::into_iter`] 这个trait方法,这个方法又会再次调用 `memcpy`,此时一个无限递归就产生了,所以还是使用经过良好测试的既存实现更加可靠。 [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter @@ -294,7 +294,7 @@ build-std = ["core", "compiler_builtins"] (`compiler-builtins-mem` 特性是在 [这个PR](https://github.com/rust-lang/rust/pull/77284) 中被引入的,所以你的Rust nightly更新时间必须晚于 `2020-09-30`。) -该参数为 `compiler_builtins` 启用了 [`mem` 特性][`mem` feature],至于具体效果,就是已经在内部通过 `#[no_mangle]` 向链接器提供了 [`memcpy` 等函数的实现][`memcpy` etc. implementations]。 +该参数为 `compiler_builtins` 启用了 [`mem` 特性][`mem` feature],至于具体效果,就是已经在内部通过 `#[unsafe(no_mangle)]` 向链接器提供了 [`memcpy` 等函数的实现][`memcpy` etc. implementations]。 [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 @@ -331,7 +331,7 @@ target = "x86_64-blog_os.json" ```rust static HELLO: &[u8] = b"Hello World!"; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { let vga_buffer = 0xb8000 as *mut u8; diff --git a/blog/content/edition-2/posts/03-vga-text-buffer/index.fa.md b/blog/content/edition-2/posts/03-vga-text-buffer/index.fa.md index 972b250f..ad2766a9 100644 --- a/blog/content/edition-2/posts/03-vga-text-buffer/index.fa.md +++ b/blog/content/edition-2/posts/03-vga-text-buffer/index.fa.md @@ -272,7 +272,7 @@ pub fn print_something() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { vga_buffer::print_something(); @@ -567,7 +567,7 @@ lazy_static! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { use core::fmt::Write; vga_buffer::WRITER.lock().write_str("Hello again").unwrap(); @@ -658,7 +658,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/03-vga-text-buffer/index.ja.md b/blog/content/edition-2/posts/03-vga-text-buffer/index.ja.md index de8bae45..3a018d48 100644 --- a/blog/content/edition-2/posts/03-vga-text-buffer/index.ja.md +++ b/blog/content/edition-2/posts/03-vga-text-buffer/index.ja.md @@ -272,7 +272,7 @@ pub fn print_something() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { vga_buffer::print_something(); @@ -580,7 +580,7 @@ lazy_static! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { use core::fmt::Write; vga_buffer::WRITER.lock().write_str("Hello again").unwrap(); @@ -671,7 +671,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/03-vga-text-buffer/index.ko.md b/blog/content/edition-2/posts/03-vga-text-buffer/index.ko.md index f84e3ffb..c9feeffd 100644 --- a/blog/content/edition-2/posts/03-vga-text-buffer/index.ko.md +++ b/blog/content/edition-2/posts/03-vga-text-buffer/index.ko.md @@ -271,7 +271,7 @@ pub fn print_something() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { vga_buffer::print_something(); @@ -566,7 +566,7 @@ lazy_static! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { use core::fmt::Write; vga_buffer::WRITER.lock().write_str("Hello again").unwrap(); @@ -658,7 +658,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/03-vga-text-buffer/index.md b/blog/content/edition-2/posts/03-vga-text-buffer/index.md index 380be0f3..b74e1612 100644 --- a/blog/content/edition-2/posts/03-vga-text-buffer/index.md +++ b/blog/content/edition-2/posts/03-vga-text-buffer/index.md @@ -268,7 +268,7 @@ Then it writes the byte `b'H'` to it. The `b` prefix creates a [byte literal], w ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { vga_buffer::print_something(); @@ -564,7 +564,7 @@ Now we can delete the `print_something` function and print directly from our `_s ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { use core::fmt::Write; vga_buffer::WRITER.lock().write_str("Hello again").unwrap(); @@ -655,7 +655,7 @@ Now we can use `println` in our `_start` function: ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/03-vga-text-buffer/index.zh-CN.md b/blog/content/edition-2/posts/03-vga-text-buffer/index.zh-CN.md index 4c20d69d..5fcd5f41 100644 --- a/blog/content/edition-2/posts/03-vga-text-buffer/index.zh-CN.md +++ b/blog/content/edition-2/posts/03-vga-text-buffer/index.zh-CN.md @@ -254,7 +254,7 @@ pub fn print_something() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { vga_buffer::print_something(); loop {} @@ -523,7 +523,7 @@ lazy_static! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { use core::fmt::Write; vga_buffer::WRITER.lock().write_str("Hello again").unwrap(); @@ -606,7 +606,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/04-testing/index.fa.md b/blog/content/edition-2/posts/04-testing/index.fa.md index b91da275..cfba58c5 100644 --- a/blog/content/edition-2/posts/04-testing/index.fa.md +++ b/blog/content/edition-2/posts/04-testing/index.fa.md @@ -105,7 +105,7 @@ pub fn test_runner(tests: &[&dyn Fn()]) { #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -655,7 +655,7 @@ fn test_println_output() { use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { test_main(); @@ -738,7 +738,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); loop {} @@ -805,7 +805,7 @@ pub mod vga_buffer; use core::panic::PanicInfo; use blog_os::println; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -918,7 +918,7 @@ fn panic(_info: &PanicInfo) -> ! { #![test_runner(test_runner)] #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); @@ -985,7 +985,7 @@ harness = false use core::panic::PanicInfo; use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode}; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { should_fail(); serial_println!("[test did not panic]"); diff --git a/blog/content/edition-2/posts/04-testing/index.ja.md b/blog/content/edition-2/posts/04-testing/index.ja.md index fa49bbc1..52878a9d 100644 --- a/blog/content/edition-2/posts/04-testing/index.ja.md +++ b/blog/content/edition-2/posts/04-testing/index.ja.md @@ -109,7 +109,7 @@ pub fn test_runner(tests: &[&dyn Fn()]) { #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -658,7 +658,7 @@ Rustにおける[結合テスト][integration tests]では、慣習としてプ use core::panic::PanicInfo; -#[no_mangle] // この関数の名前を変えない +#[unsafe(no_mangle)] // この関数の名前を変えない pub extern "C" fn _start() -> ! { test_main(); @@ -740,7 +740,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! { /// `cargo test`のときのエントリポイント #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); loop {} @@ -806,7 +806,7 @@ pub mod vga_buffer; use core::panic::PanicInfo; use blog_os::println; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -919,7 +919,7 @@ fn panic(_info: &PanicInfo) -> ! { #![test_runner(test_runner)] #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); @@ -992,7 +992,7 @@ harness = false use core::panic::PanicInfo; use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode}; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { should_fail(); serial_println!("[test did not panic]"); diff --git a/blog/content/edition-2/posts/04-testing/index.ko.md b/blog/content/edition-2/posts/04-testing/index.ko.md index 73d7875b..9de2584e 100644 --- a/blog/content/edition-2/posts/04-testing/index.ko.md +++ b/blog/content/edition-2/posts/04-testing/index.ko.md @@ -108,7 +108,7 @@ fn test_runner(tests: &[&dyn Fn()]) { #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -671,7 +671,7 @@ Rust에서는 [통합 테스트][integration tests]들을 프로젝트 루트에 use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { test_main(); @@ -754,7 +754,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); loop {} @@ -820,7 +820,7 @@ pub mod vga_buffer; use core::panic::PanicInfo; use blog_os::println; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -936,7 +936,7 @@ fn panic(_info: &PanicInfo) -> ! { #![test_runner(test_runner)] #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); @@ -1005,7 +1005,7 @@ harness = false use core::panic::PanicInfo; use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode}; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { should_fail(); serial_println!("[test did not panic]"); @@ -1042,4 +1042,4 @@ fn panic(_info: &PanicInfo) -> ! { ## 다음 단계는 무엇일까요? -다음 글에서는 _CPU exception (예외)_ 에 대해 알아볼 것입니다. 분모가 0인 나누기 연산 혹은 매핑되지 않은 메모리 페이지에 대한 접근 (페이지 폴트) 등 허가되지 않은 작업이 일어났을 때 CPU가 예외를 발생시킵니다. 이러한 예외 발생을 포착하고 분석할 수 있어야 앞으로 커널에 발생할 수많은 오류를 디버깅할 수 있을 것입니다. 예외를 처리하는 과정은 하드웨어 인터럽트를 처리하는 과정(예: 컴퓨터의 키보드 입력을 지원할 때)과 매우 유사합니다. \ No newline at end of file +다음 글에서는 _CPU exception (예외)_ 에 대해 알아볼 것입니다. 분모가 0인 나누기 연산 혹은 매핑되지 않은 메모리 페이지에 대한 접근 (페이지 폴트) 등 허가되지 않은 작업이 일어났을 때 CPU가 예외를 발생시킵니다. 이러한 예외 발생을 포착하고 분석할 수 있어야 앞으로 커널에 발생할 수많은 오류를 디버깅할 수 있을 것입니다. 예외를 처리하는 과정은 하드웨어 인터럽트를 처리하는 과정(예: 컴퓨터의 키보드 입력을 지원할 때)과 매우 유사합니다. diff --git a/blog/content/edition-2/posts/04-testing/index.md b/blog/content/edition-2/posts/04-testing/index.md index c4d36733..8cbb5cdc 100644 --- a/blog/content/edition-2/posts/04-testing/index.md +++ b/blog/content/edition-2/posts/04-testing/index.md @@ -102,7 +102,7 @@ To fix this, we first need to change the name of the generated function to somet #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -659,7 +659,7 @@ All integration tests are their own executables and completely separate from our use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { test_main(); @@ -741,7 +741,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); loop {} @@ -807,7 +807,7 @@ Now we can update our `main.rs` to use the library: use core::panic::PanicInfo; use blog_os::println; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -920,7 +920,7 @@ This test is still incomplete as it doesn't define a `_start` function or any of #![test_runner(test_runner)] #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); @@ -987,7 +987,7 @@ Now we vastly simplify our `should_panic` test by removing the `test_runner`-rel use core::panic::PanicInfo; use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode}; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { should_fail(); serial_println!("[test did not panic]"); diff --git a/blog/content/edition-2/posts/04-testing/index.zh-CN.md b/blog/content/edition-2/posts/04-testing/index.zh-CN.md index 5a7c26db..f1ed7810 100644 --- a/blog/content/edition-2/posts/04-testing/index.zh-CN.md +++ b/blog/content/edition-2/posts/04-testing/index.zh-CN.md @@ -106,7 +106,7 @@ pub fn test_runner(tests: &[&dyn Fn()]) { #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -663,7 +663,7 @@ fn test_println_output() { use core::panic::PanicInfo; -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { test_main(); @@ -745,7 +745,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); loop {} @@ -811,7 +811,7 @@ pub mod vga_buffer; use core::panic::PanicInfo; use blog_os::println; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -924,7 +924,7 @@ fn panic(_info: &PanicInfo) -> ! { #![test_runner(test_runner)] #![reexport_test_harness_main = "test_main"] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { test_main(); @@ -991,7 +991,7 @@ harness = false use core::panic::PanicInfo; use blog_os::{QemuExitCode, exit_qemu, serial_println, serial_print}; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { should_fail(); serial_println!("[test did not panic]"); diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md index 3ec27874..39f43ed4 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.fa.md @@ -393,7 +393,7 @@ pub fn init() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -428,7 +428,7 @@ pub extern "C" fn _start() -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); // new test_main(); diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md index e23dde16..15246b46 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.ja.md @@ -391,7 +391,7 @@ pub fn init() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -426,7 +426,7 @@ pub extern "C" fn _start() -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); // new test_main(); diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.ko.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.ko.md index 0c4620f2..99808eb3 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.ko.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.ko.md @@ -398,7 +398,7 @@ pub fn init() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -433,7 +433,7 @@ pub extern "C" fn _start() -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); // 새로 추가한 코드 test_main(); diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.md index d017a735..5c51b5b0 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.md @@ -390,7 +390,7 @@ Now we can update the `_start` function of our `main.rs` to call `init` and then ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -425,7 +425,7 @@ Let's create a test that ensures that the above continues to work. First, we upd /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); // new test_main(); diff --git a/blog/content/edition-2/posts/05-cpu-exceptions/index.zh-CN.md b/blog/content/edition-2/posts/05-cpu-exceptions/index.zh-CN.md index 08c34708..127f7f5a 100644 --- a/blog/content/edition-2/posts/05-cpu-exceptions/index.zh-CN.md +++ b/blog/content/edition-2/posts/05-cpu-exceptions/index.zh-CN.md @@ -394,7 +394,7 @@ pub fn init() { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -429,7 +429,7 @@ pub extern "C" fn _start() -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); // new test_main(); diff --git a/blog/content/edition-2/posts/06-double-faults/index.fa.md b/blog/content/edition-2/posts/06-double-faults/index.fa.md index 970c0680..d822fc92 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.fa.md +++ b/blog/content/edition-2/posts/06-double-faults/index.fa.md @@ -40,7 +40,7 @@ rtl = true ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -176,7 +176,7 @@ extern "x86-interrupt" fn double_fault_handler( ```rust // in src/main.rs -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -440,7 +440,7 @@ lazy_static! { use core::panic::PanicInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { unimplemented!(); } @@ -474,7 +474,7 @@ harness = false use blog_os::serial_print; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { serial_print!("stack_overflow::stack_overflow...\t"); diff --git a/blog/content/edition-2/posts/06-double-faults/index.ja.md b/blog/content/edition-2/posts/06-double-faults/index.ja.md index 920ba3bd..48ce89b2 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.ja.md +++ b/blog/content/edition-2/posts/06-double-faults/index.ja.md @@ -36,7 +36,7 @@ translators = ["garasubo"] ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -169,7 +169,7 @@ CPUはダブルフォルトハンドラを呼べるようになったので、 ```rust // in src/main.rs -#[no_mangle] // この関数の名前修飾をしない +#[unsafe(no_mangle)] // この関数の名前修飾をしない pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -429,7 +429,7 @@ lazy_static! { use core::panic::PanicInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { unimplemented!(); } @@ -463,7 +463,7 @@ harness = false use blog_os::serial_print; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { serial_print!("stack_overflow::stack_overflow...\t"); diff --git a/blog/content/edition-2/posts/06-double-faults/index.ko.md b/blog/content/edition-2/posts/06-double-faults/index.ko.md index fc136555..10919f48 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.ko.md +++ b/blog/content/edition-2/posts/06-double-faults/index.ko.md @@ -39,7 +39,7 @@ translation_contributors = ["dalinaum"] ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -172,7 +172,7 @@ CPU는 이제 _더블 폴트 처리 함수_ 를 호출하려고 시도합니다. ```rust // in src/main.rs -#[no_mangle] // 이 함수의 이름을 mangle하지 않습니다 +#[unsafe(no_mangle)] // 이 함수의 이름을 mangle하지 않습니다 pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -429,7 +429,7 @@ lazy_static! { use core::panic::PanicInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { unimplemented!(); } @@ -463,7 +463,7 @@ harness = false use blog_os::serial_print; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { serial_print!("stack_overflow::stack_overflow...\t"); diff --git a/blog/content/edition-2/posts/06-double-faults/index.md b/blog/content/edition-2/posts/06-double-faults/index.md index fe2c72ad..5d024557 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.md +++ b/blog/content/edition-2/posts/06-double-faults/index.md @@ -34,7 +34,7 @@ Let's provoke a double fault by triggering an exception for which we didn't defi ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -167,7 +167,7 @@ Let's try it ourselves! We can easily provoke a kernel stack overflow by calling ```rust // in src/main.rs -#[no_mangle] // don't mangle the name of this function +#[unsafe(no_mangle)] // don't mangle the name of this function pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -422,7 +422,7 @@ Let's start with a minimal skeleton: use core::panic::PanicInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { unimplemented!(); } @@ -456,7 +456,7 @@ The implementation of the `_start` function looks like this: use blog_os::serial_print; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { serial_print!("stack_overflow::stack_overflow...\t"); diff --git a/blog/content/edition-2/posts/06-double-faults/index.zh-CN.md b/blog/content/edition-2/posts/06-double-faults/index.zh-CN.md index 4d2ff51c..6231ed2e 100644 --- a/blog/content/edition-2/posts/06-double-faults/index.zh-CN.md +++ b/blog/content/edition-2/posts/06-double-faults/index.zh-CN.md @@ -39,7 +39,7 @@ double fault 的行为和普通异常十分相似,我们可以通过在IDT中 ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -175,7 +175,7 @@ guard page 是一类位于栈底部的特殊内存页,所以如果发生了栈 ```rust // in src/main.rs -#[no_mangle] // 禁止函数名自动修改 +#[unsafe(no_mangle)] // 禁止函数名自动修改 pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -435,7 +435,7 @@ lazy_static! { use core::panic::PanicInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { unimplemented!(); } @@ -469,7 +469,7 @@ harness = false use blog_os::serial_print; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { serial_print!("stack_overflow::stack_overflow...\t"); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md index 3315fb1c..4ac9a16e 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.fa.md @@ -298,7 +298,7 @@ _never_ | _unlock `WRITER`_ | ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] loop { @@ -461,7 +461,7 @@ pub fn hlt_loop() -> ! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] @@ -486,7 +486,7 @@ fn panic(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); test_main(); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.ja.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.ja.md index c46e614c..158bb83e 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.ja.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.ja.md @@ -297,7 +297,7 @@ _(決して起こらない)_ | _`WRITER` のロックを解放する_ | ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] loop { @@ -460,7 +460,7 @@ pub fn hlt_loop() -> ! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] @@ -485,7 +485,7 @@ fn panic(info: &PanicInfo) -> ! { /// `cargo test` のエントリポイント #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); test_main(); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.ko.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.ko.md index 331bf36a..3b62d287 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.ko.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.ko.md @@ -299,7 +299,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] loop { @@ -462,7 +462,7 @@ pub fn hlt_loop() -> ! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] @@ -487,7 +487,7 @@ fn panic(info: &PanicInfo) -> ! { /// `cargo test`의 실행 시작 지점 #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); test_main(); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.md index 9826fc37..c3c5c427 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.md @@ -294,7 +294,7 @@ We can easily provoke such a deadlock in our kernel by printing something in the ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] loop { @@ -457,7 +457,7 @@ We can now use this `hlt_loop` instead of the endless loops in our `_start` and ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] @@ -482,7 +482,7 @@ Let's update our `lib.rs` as well: /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); test_main(); diff --git a/blog/content/edition-2/posts/07-hardware-interrupts/index.zh-CN.md b/blog/content/edition-2/posts/07-hardware-interrupts/index.zh-CN.md index 539945ec..4e298ec1 100644 --- a/blog/content/edition-2/posts/07-hardware-interrupts/index.zh-CN.md +++ b/blog/content/edition-2/posts/07-hardware-interrupts/index.zh-CN.md @@ -300,7 +300,7 @@ pub fn _print(args: fmt::Arguments) { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] loop { @@ -463,7 +463,7 @@ pub fn hlt_loop() -> ! { ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { […] @@ -488,7 +488,7 @@ fn panic(info: &PanicInfo) -> ! { /// Entry point for `cargo test` #[cfg(test)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { init(); test_main(); diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.fa.md b/blog/content/edition-2/posts/08-paging-introduction/index.fa.md index bdba3b4b..d85ecea5 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.fa.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.fa.md @@ -314,7 +314,7 @@ extern "x86-interrupt" fn page_fault_handler( ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -372,7 +372,7 @@ println!("write worked"); ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.ja.md b/blog/content/edition-2/posts/08-paging-introduction/index.ja.md index 915ccf77..ea5303f7 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.ja.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.ja.md @@ -321,7 +321,7 @@ extern "x86-interrupt" fn page_fault_handler( ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -379,7 +379,7 @@ println!("write worked"); ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.md b/blog/content/edition-2/posts/08-paging-introduction/index.md index 10bff5b5..6698317a 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.md @@ -309,7 +309,7 @@ Now we can try to access some memory outside our kernel: ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -367,7 +367,7 @@ Let's try to take a look at the page tables that define how our kernel is mapped ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/08-paging-introduction/index.zh-CN.md b/blog/content/edition-2/posts/08-paging-introduction/index.zh-CN.md index 154f2aeb..68b258ab 100644 --- a/blog/content/edition-2/posts/08-paging-introduction/index.zh-CN.md +++ b/blog/content/edition-2/posts/08-paging-introduction/index.zh-CN.md @@ -318,7 +318,7 @@ extern "x86-interrupt" fn page_fault_handler( ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); @@ -376,7 +376,7 @@ println!("write worked"); ```rust // in src/main.rs -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start() -> ! { println!("Hello World{}", "!"); diff --git a/blog/content/edition-2/posts/09-paging-implementation/index.ja.md b/blog/content/edition-2/posts/09-paging-implementation/index.ja.md index 782cfaf5..14782136 100644 --- a/blog/content/edition-2/posts/09-paging-implementation/index.ja.md +++ b/blog/content/edition-2/posts/09-paging-implementation/index.ja.md @@ -303,7 +303,7 @@ bootloader = { version = "0.9", features = ["map_physical_memory"]} use bootloader::BootInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! { // 新しい引数 […] } diff --git a/blog/content/edition-2/posts/09-paging-implementation/index.md b/blog/content/edition-2/posts/09-paging-implementation/index.md index 2ce73303..49122d92 100644 --- a/blog/content/edition-2/posts/09-paging-implementation/index.md +++ b/blog/content/edition-2/posts/09-paging-implementation/index.md @@ -301,7 +301,7 @@ The bootloader passes the `BootInfo` struct to our kernel in the form of a `&'st use bootloader::BootInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! { // new argument […] } diff --git a/blog/content/edition-2/posts/09-paging-implementation/index.zh-CN.md b/blog/content/edition-2/posts/09-paging-implementation/index.zh-CN.md index b3def29b..018bcec4 100644 --- a/blog/content/edition-2/posts/09-paging-implementation/index.zh-CN.md +++ b/blog/content/edition-2/posts/09-paging-implementation/index.zh-CN.md @@ -312,7 +312,7 @@ Bootloader将 `BootInfo` 结构以 `&'static BootInfo`参数的形式传递给 use bootloader::BootInfo; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn _start(boot_info: &'static BootInfo) -> ! { // new argument […] }