القيود

ملف .dex هو تنسيق النقل لرمز Dalvik الثانوي. هناك بعض القيود النحوية والدلالية لكي يكون الملف ملف .dex صالحًا، كما يلزم وجود وقت تشغيل لدعم ملفات .dex الصالحة فقط.

قيود سلامة .dex العامة

تتعلق قيود التكامل العامة بالبنية الأكبر لملف .dex ، كما هو موضح بالتفصيل في تنسيق .dex .

المعرف وصف
G1 يجب أن يكون الرقم magic لملف .dex dex\n035\0 أو dex\n037\0 .
G2 يجب أن يكون المجموع الاختباري عبارة عن مجموع اختباري Adler-32 لمحتويات الملف بالكامل باستثناء الحقل magic والمجموع checksum .
G3 يجب أن يكون التوقيع عبارة عن تجزئة SHA-1 لمحتويات الملف بالكامل باستثناء magic checksum signature .
G4 يجب أن يتطابق file_size مع حجم الملف الفعلي بالبايت.
G5 يجب أن تكون قيمة header_size هي: 0x70
G6 يجب أن تحتوي endian_tag على القيمة: ENDIAN_CONSTANT أو REVERSE_ENDIAN_CONSTANT
G7 بالنسبة لكل link و string_ids و type_ids و proto_ids و field_ids و method_ids و class_defs وأقسام data ، يجب أن يكون حقلا offset size إما صفرًا أو كلاهما غير صفر. وفي الحالة الأخيرة، يجب أن تكون الإزاحة محاذية لأربعة بايت.
G8 يجب أن تكون جميع حقول الإزاحة في الرأس باستثناء map_off محاذاة بأربعة بايت.
G9 يجب أن يكون حقل map_off إما صفرًا أو يشير إلى قسم البيانات. وفي الحالة الأخيرة، يجب أن يكون قسم data موجودًا.
G10 يجب ألا يتداخل أي من link و string_ids و type_ids و proto_ids و field_ids و method_ids و class_defs وأقسام data مع بعضها البعض أو مع الرأس.
G11 في حالة وجود خريطة، يجب أن يكون لكل إدخال خريطة نوع صالح. وقد يظهر كل نوع مرة واحدة على الأكثر.
G12 في حالة وجود خريطة، يجب أن يكون لكل إدخال خريطة إزاحة وحجم غير صفري. يجب أن تشير الإزاحة إلى القسم المقابل من الملف (أي يجب أن يشير string_id_item إلى قسم string_ids ) ويجب أن يتطابق الحجم الصريح أو الضمني للعنصر مع المحتويات والحجم الفعليين للقسم.
G13 في حالة وجود خريطة، فإن إزاحة إدخال الخريطة n+1 يجب أن تكون أكبر أو مساوية لإزاحة إدخال الخريطة n plus than size of map entry n . وهذا يعني عدم تداخل الإدخالات والترتيب من الأدنى إلى الأعلى.
G14 يجب أن تحتوي أنواع الإدخالات التالية على إزاحة محاذاة بأربعة بايت: string_id_item و type_id_item و proto_id_item و field_id_item و method_id_item و class_def_item و type_list و code_item و annotations_directory_item .
G15 بالنسبة لكل string_id_item ، يجب أن يحتوي الحقل string_data_off على مرجع صالح في قسم data . بالنسبة إلى string_data_item المشار إليه، يجب أن يحتوي حقل data على سلسلة MUTF-8 صالحة، ويجب أن يتطابق utf16_size مع طول السلسلة التي تم فك تشفيرها.
G16 بالنسبة لكل type_id_item ، يجب أن يحتوي الحقل descriptor_idx على مرجع صالح في قائمة string_ids . يجب أن تكون السلسلة المشار إليها واصف نوع صالح.
G17 بالنسبة لكل proto_id_item ، يجب أن يحتوي الحقل shorty_idx على مرجع صالح في قائمة string_ids . يجب أن تكون السلسلة المشار إليها واصفًا قصيرًا صالحًا. بالإضافة إلى ذلك، يجب أن يكون الحقل return_type_idx فهرسًا صالحًا في قسم type_ids ، ويجب أن يكون حقل parameters_off إما صفرًا أو إزاحة صالحة تشير إلى قسم data . إذا كانت القيمة غير صفرية، فيجب ألا تحتوي قائمة المعلمات على أي إدخالات فارغة.
G18 بالنسبة لكل field_id_item ، يجب أن يكون كلا الحقلين class_idx و type_idx مؤشرات صالحة في قائمة type_ids . يجب أن يكون الإدخال المشار إليه بواسطة class_idx نوعًا مرجعيًا غير مصفوفة. بالإضافة إلى ذلك، يجب أن يكون الحقل name_idx مرجعًا صالحًا في قسم string_ids ، ويجب أن تتوافق محتويات الإدخال المشار إليه مع مواصفات MemberName .
G19 بالنسبة لكل method_id_item ، يجب أن يكون الحقل class_idx فهرسًا صالحًا في قسم type_ids ، ويجب أن يكون الإدخال المشار إليه نوعًا مرجعيًا غير مصفوفة. يجب أن يكون الحقل proto_id مرجعًا صالحًا في قائمة proto_ids . يجب أن يكون الحقل name_idx مرجعًا صالحًا في قسم string_ids ، ويجب أن تتوافق محتويات الإدخال المشار إليه مع مواصفات MemberName .
مجموعة العشرين بالنسبة لكل field_id_item ، يجب أن يكون الحقل class_idx فهرسًا صالحًا في قائمة type_ids . يجب أن يكون الإدخال المشار إليه نوعًا مرجعيًا غير مصفوفة.

قيود البايت كود الثابتة

القيود الثابتة هي قيود على العناصر الفردية للكود الثانوي. ويمكن عادةً التحقق منها دون استخدام تقنيات التحكم أو تحليل تدفق البيانات.

المعرف وصف
أ1 يجب ألا يكون مصفوفة insns فارغة.
أ2 يجب أن يحتوي كود التشغيل الأول في مصفوفة insns على فهرس صفر.
أ3 يجب أن تحتوي مصفوفة insns على أكواد تشغيل Dalvik الصالحة فقط.
A4 فهرس التعليمة n+1 يجب أن يساوي فهرس التعليمة n بالإضافة إلى طول التعليمة n مع مراعاة المعاملات الممكنة.
أ5 يجب أن تنتهي التعليمة الأخيرة في مصفوفة insns عند الفهرس insns_size-1 .
أ6 يجب أن تكون جميع أهداف goto و if-<kind> رموز تشغيل ضمن نفس الطريقة.
أ7 يجب أن تكون جميع أهداف تعليمات packed-switch تشغيل ضمن نفس الطريقة. يجب أن يكون حجم وقائمة الأهداف متسقة.
أ8 يجب أن تكون جميع أهداف تعليمات sparse-switch أكواد تشغيل ضمن نفس الطريقة. يجب أن يكون الجدول المقابل متسقًا ومرتبًا من الأدنى إلى الأعلى.
أ9 يجب أن يكون المعامل B لتعليمات const-string و const-string/jumbo فهرسًا صالحًا في تجمع ثابت السلسلة.
أ10 يجب أن يكون المعامل C لتعليمات iget<kind> و iput<kind> فهرسًا صالحًا في تجمع ثابت الحقل. يجب أن يمثل الإدخال المشار إليه حقل مثيل.
أ11 يجب أن يكون المعامل C لتعليمات sget<kind> و sput<kind> فهرسًا صالحًا في تجمع ثابت الحقل. يجب أن يمثل الإدخال المشار إليه حقلاً ثابتًا.
أ12 يجب أن يكون المعامل C للتعليمات invoke-virtual و invoke-super و invoke-direct و invoke-static فهرسًا صالحًا في المجموعة الثابتة للطريقة.
أ13 يجب أن يكون المعامل B لتعليمات invoke-virtual/range ، invoke-super/range ، invoke-direct/range ، و invoke-static/range فهرسًا صالحًا في المجموعة الثابتة للطريقة.
أ14 الطريقة التي يبدأ اسمها بـ '<' يجب أن يتم استدعاؤها ضمنيًا فقط بواسطة الجهاز الظاهري، وليس بواسطة التعليمات البرمجية التي تنشأ من ملف .dex . الاستثناء الوحيد هو مُهيئ المثيل، والذي يمكن استدعاؤه عن طريق invoke-direct .
أ15 يجب أن يكون المعامل C لتعليمة invoke-interface فهرسًا صالحًا في التجمع الثابت للطريقة. يجب أن ينتمي معرف method_id المشار إليه إلى واجهة (وليس فئة).
أ16 يجب أن يكون المعامل B لتعليمة invoke-interface/range فهرسًا صالحًا في التجمع الثابت للطريقة. يجب أن ينتمي معرف method_id المشار إليه إلى واجهة (وليس فئة).
أ17 يجب أن يكون المعامل B لتعليمات const-class و check-cast و new-instance و filled-new-array/range فهرسًا صالحًا في تجمع النوع الثابت.
أ18 يجب أن يكون المعامل C لتعليمات instance-of new-array filled-new-array فهرسًا صالحًا في تجمع النوع الثابت.
أ19 يجب أن تكون أبعاد المصفوفة التي تم إنشاؤها بواسطة تعليمات new-array أقل من 256 .
أ20 يجب ألا تشير التعليمات new إلى فئات المصفوفات أو الواجهات أو الفئات المجردة.
أ21 يجب أن يكون النوع المشار إليه بواسطة تعليمات new-array نوعًا صالحًا وغير مرجعي.
أ22 يجب أن تكون جميع السجلات المشار إليها بواسطة تعليمات بطريقة العرض الفردي (غير الزوجي) صالحة للطريقة الحالية. أي أن مؤشراتها يجب أن تكون غير سالبة وأصغر من registers_size .
أ23 يجب أن تكون جميع السجلات المشار إليها بواسطة تعليمات بطريقة العرض المزدوج (الزوجي) صالحة للطريقة الحالية. أي أن مؤشراتها يجب أن تكون غير سالبة وأصغر من registers_size-1 .
أ24 يجب أن ينتمي معامل method_id لتعليمات invoke-virtual invoke-direct إلى فئة (وليس واجهة). في ملفات Dex قبل الإصدار 037 يجب أن ينطبق الأمر نفسه على تعليمات invoke-super invoke-static .
أ25 يجب أن ينتمي معامل method_id الخاص بتعليمات invoke-virtual/range invoke-direct/range إلى فئة (وليس واجهة). في ملفات Dex قبل الإصدار 037 ، يجب أن يكون الأمر نفسه صحيحًا بالنسبة لتعليمات invoke-super/range invoke-static/range .

قيود الرمز الثانوي الهيكلية

القيود الهيكلية هي قيود على العلاقات بين عدة عناصر من الكود الثانوي. ولا يمكن عادةً التحقق منها دون استخدام تقنيات التحكم أو تحليل تدفق البيانات.

المعرف وصف
ب1 يجب أن يتطابق عدد الوسائط وأنواعها (السجلات والقيم المباشرة) دائمًا مع التعليمات.
ب2 لا يجوز أبدًا تقسيم أزواج التسجيل.
ب3 يجب تعيين السجل (أو الزوج) أولاً قبل أن تتمكن من قراءته.
ب4 يجب أن تستدعي تعليمات invoke-direct مُهيئ مثيل أو طريقة فقط في الفئة الحالية أو إحدى فئاتها الفائقة.
ب5 يجب استدعاء مُهيئ المثيل فقط في مثيل غير مهيأ.
ب6 لا يجوز استدعاء أساليب المثيل إلا في المثيلات ولا يمكن الوصول إلى حقول المثيل إلا في المثيلات التي تمت تهيئتها بالفعل.
ب7 يجب عدم استخدام السجل الذي يحمل نتيجة تعليمات new-instance إذا تم تنفيذ نفس تعليمات new-instance مرة أخرى قبل تهيئة المثيل.
ب8 يجب أن يستدعي مُهيئ المثيل مُهيئ مثيل آخر (نفس الفئة أو الفئة الفائقة) قبل أن يتم الوصول إلى أي أعضاء مثيل. الاستثناءات هي حقول مثيل غير موروثة، والتي يمكن تعيينها قبل استدعاء مُهيئ آخر، وفئة Object بشكل عام.
ب9 يجب أن تكون كافة وسيطات الطريقة الفعلية متوافقة مع التعيين مع الوسيطات الرسمية الخاصة بها.
ب10 بالنسبة لكل استدعاء لطريقة المثيل، يجب أن يكون المثيل الفعلي متوافقًا مع المهمة مع الفئة أو الواجهة المحددة في التعليمات.
ب11 يجب أن تتطابق تعليمات return<kind> مع نوع الإرجاع الخاص بالأسلوب الخاص بها.
ب12 عند الوصول إلى الأعضاء المحميين في فئة فائقة، يجب أن يكون النوع الفعلي للمثيل الذي يتم الوصول إليه إما الفئة الحالية أو إحدى فئاتها الفرعية.
ب13 يجب أن يكون نوع القيمة المخزنة في حقل ثابت متوافقًا مع التعيين أو قابلاً للتحويل إلى نوع الحقل.
ب14 يجب أن يكون نوع القيمة المخزنة في الحقل متوافقًا مع التعيين أو قابلاً للتحويل إلى نوع الحقل.
ب15 يجب أن يكون نوع كل قيمة مخزنة في المصفوفة متوافقًا مع نوع مكون المصفوفة.
ب16 يجب أن يكون المعامل A لتعليمة throw متوافقًا مع المهمة java.lang.Throwable .
ب17 يجب أن تكون آخر تعليمات يمكن الوصول إليها لطريقة ما عبارة عن تعليمات goto أو فرع للخلف، أو تعليمات return ، أو تعليمات throw . يجب ألا يكون من الممكن ترك مصفوفة insns في الأسفل.
ب18 لا يجوز قراءة النصف غير المعين من زوج التسجيل السابق (يعتبر غير صالح) حتى يتم إعادة تعيينه بواسطة بعض التعليمات الأخرى.
ب19 يجب أن تكون تعليمات move-result<kind> مسبوقة مباشرة (في مصفوفة insns ) بتعليمة invoke-<kind> . الاستثناء الوحيد هو تعليمات move-result-object ، والتي قد تكون مسبوقة أيضًا بتعليمات filled-new-array .
ب20 يجب أن تكون تعليمات move-result<kind> مسبوقة مباشرة (في تدفق التحكم الفعلي) بتعليمات return-<kind> (يجب عدم القفز إليها). الاستثناء الوحيد هو تعليمات move-result-object ، والتي قد تكون مسبوقة أيضًا بتعليمات filled-new-array .
ب21 يجب أن تظهر تعليمات move-exception فقط كأول تعليمات في معالج الاستثناء.
ب22 يجب ألا تكون التعليمات packed-switch-data sparse-switch-data fill-array-data قابلة للوصول عن طريق تدفق التحكم.