الإجراءات المفككة‬

يتم فرز التعليمات البرمجية المفككة في ترتيب تنازلي. عند حدوث استثناء , يتم تخزين السياق الكامل من قبل نظام التشغيل في سجل سياق. فى ذلك الوقت يتم استدعاء منطق إرسال الاستثناء، والذي يقوم بتنفيذ الخطوات التالية بشكل متكرر للعثور على معالج استثناء.

  1. قم بـاستخدام الـ RIP الحالي المخزن في سجل السياق للبحث عن إدخال جدول RUNTIME_FUNCTION الذى يصف الدالة الحالية (أو جزء من الدالة , في حالة إدخالات UNWIND_INFO المتسلسلة).

  2. إذا لم يتم العثور على إدخال جدول دالة , إذاً فهى دالة طرفية، وسوف تقوم الـ RSP بمخاطبة مؤشر الإرجاع مباشرة . يتم تخزين مؤشر الإرجاع في [RSP] في السياق المحدث ,تزيد الـ RSP التى تمت محاكاتها بمقدار 8 و يتم تكرار الخطوة 1.

  3. اذا تم إيجاد إدخال جدول دالة , تكمن RIP في داخل ثلاث مناطق أ) فى epilog (الخاتمة) , ب) في prolog (المقدمة), أو ج) فى تعليمات برمجية يمكن تغطيتها بمعالج استثناء.

    • حالة أ) إذا كان RIP داخل epilog ,إذاً عنصر التحكم يغادر الدالة ،لا يمكن أن يكون هناك معالج استثناء مقترن بهذا الاستثناء لهذه الدالة ، و تأثير epilog يجب أن يكون مستمراً ليتم حساب سياق الدالة المستدعية. لتحديد ما إذا كان RIP داخل epilog , يتم فحص دفق التعليمات البرمجية من على RIP . إذا تطابق دفق التعليمات البرمجية مع الجزء الزائد من epilog شرعية , اذاً فهى في epilog , و يتم محاكاة الجزء المتبقي من الـ epilog ، مع تحديث سجل السياق أثناء معالجة كل تعليمة . بعد ذلك، يتم تكرار الخطوة 1.

    • الحالة ب) إذا كان RIP يقع ضمن المقدمة(prologue)، إذاً عنصر التحكم لم يدخل الدالة ، لا يمكن أن يكون هناك معالج إستثناء مقترن بهذا الاستثناء لهذة الدالة ، و يجب التراجع عن تأثيرات prolog ليتم حساب سياق الدالة المستدعية. RIP داخل prolog إذا كانت المسافة من بدء الدالة حتى RIP أقل من أو تساوي حجم prolog المشفّر في المعلومات المفككة (unwind). يتم تفكيك تأثيرات prolog بواسطة التفحص للأمام عبر صفيفة تعليمات unwind البرمجية الخاصة بالإدخال الأول مع إزاحة أقل من أو تساوي إزاحة RIP من بدء الدالة ثم التراجع عن تأثير كافة العناصر المتبقية في صفيفة تعليمات unwind البرمجية. ثم يتم تكرار الخطوة 1.

    • حالة c) إذا لم يكن RIP داخل prolog أو epilog والدالة تحتوي على معالج استثناء (تم تعيين UNW_FLAG_EHANDLER) ، ثم يتم استدعاء معالج اللغة المعين. يقوم المعالج بفحص البيانات الخاصة به وتصفية استدعاءات الدالات بالشكل المناسب. يستطيع معالج اللغة المعين إرجاع أنه تمت معالجة الاستثناء أو أنه يجب متابعة البحث. يمكنك أيضاً بدء unwind مباشرة.

  4. إذا قام معالج اللغة المعين بإرجاع حالة "تمت المعالجة"، إذاً يتم متابعة التنفيذ باستخدام سجل السياق الأصلي.

  5. إذا كان لا يوجد أي معالج لغة معين أو يقوم المعالج بإرجاع حالة “ متابعة البحث ” إذاً يجب تفكيك سجل السياق إلى حالة المستدعِى. ويتم تحقيق ذلك بواسطة معالجة كافة عناصر صفيفة تعليمات unwind البرمجية،مع التراجع عن تأثير كل منهم. ثم يتم تكرار الخطوة 1.

عند تضمين معلومات unwind المرتبطة ، لا يزال يتم اتباع هذه الخطوات الأساسية. الاختلاف الوحيد هو أنه أثناء تمرير صفيفة تعليمات unwind البرمجية لتفكيك تأثيرات prolog، فبمجرد الوصول إلى نهاية الصفيف، يتم ربطه بمعلومات unwind الأصل و يتم تمرير صفيفة تعليمات unwind البرمجية بأكملها التي تم العثور عليها. هذا الارتباط يستمر حتى الوصول إلى معلومات unwind بدون إشارة UNW_CHAINED_INFO و الانتهاء من تمرير صفيفة تعليمات unwind البرمجية الخاصة بها.

أصغر مجموعة من بيانات unwind هي 8 بايت. قد يمثل هذا دالة ملأت فقط 128 بايت أو أقل من المكدس وقد تكون حفظت سجلاً واحداً غير مُتغير. هذا هو أيضاً حجم بنية معلومات unwind المرتبطة بـ prolog ذى الطول الصفري بدون معلومات unwind.

راجع أيضًا:

المرجع

معالجة استثناء (x64)