محدودیت‌ها

فایل .dex قالب انتقال برای بایت‌کد Dalvik است. برای اینکه فایلی به‌عنوان فایل .dex معتبر شناخته شود، محدودیت‌های نحوی و معنایی خاصی وجود دارد و زمان اجرا برای پشتیبانی از فایل‌های .dex معتبر الزامی است.

محدودیت‌های کلی تمامیت .dex

محدودیت‌های یکپارچگی عمومی به ساختار بزرگ‌تر فایل .dex مربوط می‌شود، همان‌طور که به‌طور مفصل در قالب .dex شرح داده شده است.

شناسه شرح
G1 عدد magic در فایل .dex باید dex\n035\0 برای نسخه ۳۵، یا مشابه آن برای نسخه‌های بعدی باشد.
G2 مجموع کنترل باید مجموع کنترل Adler-32 از کل محتوای فایل به‌جز فیلدهای magic و checksum باشد.
G3 امضا باید درهم‌سازی SHA-1 از کل محتوای فایل به‌جز magic، checksum، و signature باشد.
G4

‫file_size باید با اندازه واقعی فایل به بایت مطابقت داشته باشد. (نسخه ۴۰ یا قدیمی‌تر)

file_size باید به سرایند بعدی در محفظه، یا به انتهای فایل فیزیکی (محفظه) اشاره کند. اگر به سرایند بعدی اشاره می‌کند، اندازه فایل باید ۴ بایتی تراز باشد. مجموع همه فیلدهای file_size باید برابر با container_size باشد. (نسخه ۴۱ یا جدیدتر)

G5

header_size باید این مقدار را داشته باشد: 0x70 (v40 یا قدیمی‌تر)

header_size باید این مقدار را داشته باشد: 0x78 (نسخه ۴۱ یا جدیدتر)

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 باید هر دو صفر یا هر دو غیرصفر باشند. در حالت دوم، افست باید چهار بایتی تراز باشد.

فیلدهای 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_id_item، فیلد string_data_off باید یک افست در ظرف و بعداز هر سرصفحه‌ای باشد که به‌طور گذرا از آن استفاده می‌کند. (نسخه ۴۱ یا جدیدتر)

برای 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 مطابقت داشته باشد.
G20 برای هر field_id_item، فیلد class_idx باید نمایه‌ای معتبر در فهرست type_ids باشد. ورودی ارجاع‌شده باید از نوع مرجع غیرآرایه‌ای باشد.

محدودیت‌های بایت‌کد ایستا

محدودیت‌های ایستا محدودیت‌هایی بر عناصر منفرد کدبایت هستند. معمولاً می‌توان آن‌ها را بدون استفاده از تکنیک‌های تحلیل کنترل یا جریان داده بررسی کرد.

شناسه شرح
A1 آرایه insns نباید خالی باشد.
A2 اولین کد عملیات در آرایه insns باید نمایه صفر داشته باشد.
A3 آرایه insns باید فقط حاوی کدهای عملیاتی Dalvik معتبر باشد.
A4 شاخص دستورالعمل n+1 باید برابر با شاخص دستورالعمل n به‌علاوه طول دستورالعمل n باشد، با درنظر گرفتن عملوندهای احتمالی.
A5 آخرین دستورالعمل در آرایه insns باید در شاخص insns_size-1 پایان یابد.
A6 همه هدف‌های goto و if-<kind> باید کدهای عملیاتی در همان روش باشند.
A7 همه هدف‌های دستور packed-switch باید کدهای عملیاتی در همان روش باشند. اندازه و فهرست هدف‌ها باید سازگار باشد.
A8 همه هدف‌های دستور sparse-switch باید کدهای عملیاتی در همان روش باشند. جدول مربوطه باید سازگار باشد و از کم به زیاد مرتب شده باشد.
A9 عملوند B دستورات const-string و const-string/jumbo باید نمایه‌ای معتبر در استخر ثابت رشته‌ای باشد.
A10 عملوند C دستورات iget<kind> و iput<kind> باید نمایه‌ای معتبر در استخر ثابت فیلد باشد. ورودی ارجاع‌شده باید نشانگر فیلد نمونه باشد.
A11 عملوند C دستورات sget<kind> و sput<kind> باید نمایه‌ای معتبر در استخر ثابت فیلد باشد. ورودی ارجاع‌شده باید نشان‌دهنده فیلد ایستا باشد.
A12 عملوند C دستورالعمل‌های invoke-virtual، invoke-super، invoke-direct، و invoke-static باید نمایه معتبری در مجموعه ثابت روش باشد.
A13 عملوند B دستورالعمل‌های invoke-virtual/range، invoke-super/range، invoke-direct/range، و invoke-static/range باید نمایه‌ای معتبر در مجموعه ثابت روش باشد.
A14 روشی که نام آن با «<» شروع می‌شود باید فقط به‌طور ضمنی توسط ماشین مجازی فراخوانی شود، نه توسط کدی که از فایل .dex منشأ می‌گیرد. تنها استثنا مقداردهی اولیه نمونه است که ممکن است توسط invoke-direct فراخوانی شود.
A15 عملوند C دستورالعمل invoke-interface باید نمایه‌ای معتبر در استخر ثابت روش باشد. method_id ارجاع‌شده باید متعلق به یک میانجی باشد (نه یک کلاس).
A16 عملوند B دستورالعمل invoke-interface/range باید نمایه معتبری در مجموعه ثابت روش باشد. ‫method_id ارجاع‌شده باید متعلق به یک میانای (نه یک کلاس) باشد.
A17 عملوند B از دستورالعمل‌های const-class، check-cast، new-instance، و filled-new-array/range باید نمایه معتبری در مجموعه ثابت نوع باشد.
A18 عملوند C از دستورالعمل‌های instance-of، new-array، و filled-new-array باید نمایه معتبری در مجموعه ثابت نوع باشد.
A19 ابعاد آرایه ایجادشده توسط دستور new-array باید کمتر از 256 باشد.
A20 دستورالعمل new نباید به کلاس‌های آرایه، میان‌ها، یا کلاس‌های انتزاعی اشاره کند.
A21 نوع ارجاع‌شده توسط دستورالعمل new-array باید نوع معتبر و غیرمرجع باشد.
A22 همه ثبات‌هایی که دستورالعمل به‌صورت تک‌عرض (غیرجفت) به آن‌ها ارجاع می‌دهد باید برای روش فعلی معتبر باشند. یعنی، نمایه‌های آن‌ها باید غیرمنفی و کوچک‌تر از registers_size باشد.
A23 همه ثبات‌هایی که در دستورالعمل به‌صورت پهنای دوبرابر (جفت) به آن‌ها اشاره شده است باید برای روش فعلی معتبر باشند. یعنی نمایه‌های آن‌ها باید غیرمنفی و کوچک‌تر از registers_size-1 باشد.
A24 عملوند method_id دستورالعمل‌های invoke-virtual و invoke-direct باید متعلق به یک کلاس باشد (نه یک میانجی). در فایل‌های Dex قبل‌از نسخه 037 همین امر باید برای دستورالعمل‌های invoke-super و invoke-static نیز صادق باشد.
A25 عملوند method_id دستورات invoke-virtual/range و invoke-direct/range باید متعلق به کلاس باشد (نه میانای). در فایل‌های Dex قبل‌از نسخه 037 همین امر باید برای دستورالعمل‌های invoke-super/range و invoke-static/range نیز صادق باشد.

محدودیت‌های ساختاری بایت‌کد

محدودیت‌های ساختاری محدودیت‌هایی در روابط بین چندین عنصر بایت‌کد هستند. معمولاً بدون استفاده از تکنیک‌های تحلیل کنترل یا جریان داده نمی‌توان آن‌ها را بررسی کرد.

شناسه شرح
B1 تعداد و نوع آرگومان‌ها (ثبات‌ها و مقادیر فوری) باید همیشه با دستورالعمل مطابقت داشته باشد.
B2 جفت‌های ثبت‌شده نباید هرگز از هم جدا شوند.
B3 ابتدا باید ثبتی (یا جفتی) اختصاص داده شود تا بتوان آن را خواند.
B4 دستور invoke-direct باید یک مقداردهی اولیه نمونه یا روشی را فقط در کلاس فعلی یا یکی از ابرکلاس‌های آن فراخوانی کند.
B5 راه‌انداز نمونه باید فقط روی نمونه اولیه فراخوانده شود.
B6 روش‌های نمونه فقط در نمونه‌ها فراخوانده می‌شوند و فیلدهای نمونه فقط در نمونه‌های ازقبل مقداردهی‌شده دردسترس هستند.
B7 اگر همان دستورالعمل new-instance دوباره قبل‌از مقداردهی اولیه نمونه اجرا شود، نباید از ثباتی که نتیجه دستورالعمل new-instance را نگه می‌دارد استفاده شود.
B8 پیش‌از اینکه بتوان به اعضای نمونه دسترسی پیدا کرد، مقداردهنده اولیه نمونه باید مقداردهنده اولیه نمونه دیگری (همان کلاس یا ابرکلاس) را فراخوانی کند. استثناها فیلدهای نمونه غیروراثتی هستند که می‌توانند قبل‌از فراخوانی مقداردهی اولیه دیگری اختصاص داده شوند، و به‌طور کلی کلاس Object.
B9 همه متغیرهای مستقل روش واقعی باید با متغیرهای مستقل رسمی مربوطه خود سازگار با تخصیص باشند.
B10 برای هر فراخوانی روش نمونه، نمونه واقعی باید با کلاس یا رابط مشخص‌شده در دستورالعمل سازگار با تخصیص باشد.
B11 دستور return<kind> باید با نوع برگشتی روش آن مطابقت داشته باشد.
B12 هنگام دسترسی به اعضای محافظت‌شده یک اَبَرکلاس، نوع واقعی نمونه‌ای که به آن دسترسی پیدا می‌شود باید کلاس فعلی یا یکی از زیرکلاس‌های آن باشد.
B13 نوع مقدار ذخیره‌شده در فیلد ایستا باید با نوع فیلد سازگار با تخصیص یا قابل‌تبدیل به آن باشد.
B14 نوع مقدار ذخیره‌شده در فیلد باید با نوع فیلد سازگار با تخصیص یا قابل‌تبدیل به آن باشد.
B15 نوع هر مقدار ذخیره‌شده در آرایه باید با نوع عنصر آرایه سازگار با تخصیص باشد.
B16 عملوند A دستورالعمل throw باید با java.lang.Throwable سازگار با تخصیص باشد.
B17 آخرین دستورالعمل قابل‌دسترس یک روش باید یا یک goto یا شاخه رو به عقب، یک return، یا یک دستورالعمل throw باشد. نباید بتوان آرایه insns را در پایین ترک کرد.
B18 تا زمانی که نیمه بدون تخصیص جفت ثبات قبلی توسط دستورالعمل دیگری مجدداً تخصیص داده نشود، نمی‌توان آن را خواند (نامعتبر درنظر گرفته می‌شود).
B19 دستورالعمل move-result<kind> باید بلافاصله قبل‌از دستورالعمل invoke-<kind> (در آرایه insns) قرار بگیرد. تنها استثنا دستورالعمل move-result-object است که ممکن است با دستورالعمل filled-new-array نیز همراه باشد.
B20 دستور move-result<kind> باید بلافاصله قبل‌از دستور return-<kind> منطبق (در جریان کنترل واقعی) قرار گیرد (نباید به آن پرش شود). تنها استثنا دستورالعمل move-result-object است که ممکن است با دستورالعمل filled-new-array نیز همراه باشد.
B21 دستورالعمل move-exception باید فقط به‌عنوان اولین دستورالعمل در گرداننده استثنا ظاهر شود.
B22 دستورات شبه packed-switch-data، sparse-switch-data، و fill-array-data نباید ازطریق جریان کنترل قابل‌دسترسی باشند.