modify_ldt(2)

الاسم
modify_ldt - الحصول على أو تعيين إدخال LDT لكل عملية

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <asm/ldt.h>         /* Definition of struct user_desc */
#include <sys/syscall.h>     /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(unsigned long bytecount;
            SYS_modify_ldt, int func, void ptr[bytecount],
            unsigned long bytecount);

ملاحظة: لا توفر glibc غلافًا لـ modify_ldt()، مما يستلزم استخدام syscall(2).

الوصف
يقرأ أو يكتب modify_ldt() جدول الواصفات المحلي (LDT) لعملية. LDT هو مصفوفة من واصفات المقاطع التي يمكن للكود البرمجي للمستخدم الإشارة إليها. يسمح لينكس للعمليات بتكوين LDT لكل عملية (في الواقع لكل mm). لمزيد من المعلومات حول LDT، راجع دليل مطور برامج إنتل أو دليل برمجة بنية AMD.

عندما يكون func هو 0، يقرأ modify_ldt() LDT في الذاكرة المشار إليها بواسطة ptr. عدد البايتات المقروءة هو الأصغر بين bytecount والحجم الفعلي لـ LDT، على الرغم من أن النواة قد تتصرف كما لو أن LDT مبطن ببايتات صفرية إضافية في النهاية. عند النجاح، يُرجع modify_ldt() عدد البايتات المقروءة.

عندما يكون func هو 1 أو 0x11، يعدل modify_ldt() إدخال LDT المشار إليه بواسطة ptr->entry_number. يشير ptr إلى بنية user_desc ويجب أن يساوي bytecount حجم هذه البنية.

يتم تعريف بنية user_desc في <asm/ldt.h> على النحو التالي:

    struct user_desc {
        unsigned int  entry_number;
        unsigned int  base_addr;
        unsigned int  limit;
        unsigned int  seg_32bit:1;
        unsigned int  contents:2;
        unsigned int  read_exec_only:1;
        unsigned int  limit_in_pages:1;
        unsigned int  seg_not_present:1;
        unsigned int  useable:1;
    };

في لينكس 2.4 والإصدارات الأقدم، كانت هذه البنية تُسمى modify_ldt_ldt_s.

حقل contents هو نوع المقطع (بيانات، بيانات موسعة للأسفل، كود غير متوافق، أو كود متوافق). تتطابق الحقول الأخرى مع أوصافها في دليل وحدة المعالجة المركزية، على الرغم من أن modify_ldt() لا يمكنه تعيين البت "accessed" المحدد بواسطة العتاد والموصوف في دليل وحدة المعالجة المركزية.

يُعتبر user_desc "فارغًا" إذا تم تعيين read_exec_only و seg_not_present إلى 1 وجميع الحقول الأخرى هي 0. يمكن مسح إدخال LDT عن طريق تعيينه إلى user_desc "فارغ" أو، إذا كان func هو 1، عن طريق تعيين كل من base و limit إلى 0.

سيتم رفض مقطع كود متوافق (أي الذي يحتوي على contents==3) إذا كان func هو 1 أو إذا كان seg_not_present هو 0.

عندما يكون func هو 2، سيقرأ modify_ldt() أصفارًا. يبدو أن هذا بقايا من لينكس 2.4.

قيمة الإرجاع
عند النجاح، يُرجع modify_ldt() إما العدد الفعلي للبايتات المقروءة (للقراءة) أو 0 (للكتابة). عند الفشل، يُرجع modify_ldt() -1 ويضبط errno للإشارة إلى الخطأ.

الأخطاء

EFAULT
    يشير ptr إلى خارج مساحة العنوان.

EINVAL
    ptr هو 0، أو func هو 1 و bytecount لا يساوي حجم البنية user_desc، أو func هو 1 أو 0x11 وإدخال LDT الجديد يحتوي على قيم غير صالحة.

ENOSYS
    func ليس 0، 1، 2، ولا 0x11.

المعايير
لينكس.

ملاحظات
لا ينبغي استخدام modify_ldt() للتخزين المحلي للخيوط، لأنه يبطئ تبديل السياق ويدعم فقط عددًا محدودًا من الخيوط. يجب أن تستخدم مكتبات الخيوط set_thread_area(2) أو arch_prctl(2) بدلاً من ذلك، باستثناء النوى القديمة جدًا التي لا تدعم تلك الاستدعاءات النظامية.

الاستخدام الطبيعي لـ modify_ldt() هو تشغيل كود قديم 16 بت أو كود 32 بت مجزأ. ومع ذلك، لا تسمح جميع النوى بتثبيت مقاطع 16 بت.

حتى على النوى 64 بت، لا يمكن استخدام modify_ldt() لإنشاء مقطع كود وضع طويل (أي 64 بت). الحقل غير الموثق "lm" في user_desc ليس مفيدًا، وعلى الرغم من اسمه، لا ينتج عنه مقطع وضع طويل.

العلل
على النوى 64 بت قبل لينكس 3.19، يمنع تعيين بت "lm" في user_desc اعتبار الواصف فارغًا. ضع في اعتبارك أن بت "lm" غير موجود في الرؤوس 32 بت، لكن هذه النوى المعيبة ستظل تلاحظ البت حتى عند تعيينه في عملية 32 بت.

انظر أيضًا
arch_prctl(2), set_thread_area(2), vm86(2)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.