ABIDIFF(1) Libabigail ABIDIFF(1) نام (NAME) abidiff - مقایسه واسط‌های باینری کاربردی (ABI) فایل‌های ELF دستور abidiff واسط‌های باینری کاربردی (ABI) دو کتابخانه مشترک با فرمت ELF را با یکدیگر مقایسه می‌کند. این ابزار گزارش معناداری حاوی توصیف تفاوت‌های میان دو ABI تولید می‌کند. این ابزار همچنین می‌تواند نمایش‌های متنی ABI دو فایل باینری ELF (تولیدشده توسط abidw) یا یک فایل باینری ELF را در برابر نمایش متنی یک فایل باینری ELF دیگر مقایسه کند. جهت ارائه یک گزارش جامع از تغییرات ABI میان دو کتابخانه مشترک ورودی که شامل تغییرات مربوط به زیرنوع‌های توابع و متغیرها باشد، abidiff به‌طور پیش‌فرض از اطلاعات اشکال‌زدایی با فرمت DWARF (در صورت وجود) استفاده می‌کند؛ در غیر این صورت، واسط‌ها را با استفاده از اطلاعات اشکال‌زدایی در فرمت‌های CTF یا BTF (در صورت وجود) مقایسه می‌کند. در نهایت، اگر هیچ اطلاعات اشکال‌زدایی در این فرمت‌ها یافت نشود، فقط نمادهای ELF را در نظر می‌گیرد و اضافه یا حذف شدن آن‌ها را گزارش می‌کند. این ابزار از کتابخانه libabigail برای تحلیل باینری و همچنین اطلاعات اشکال‌زدایی وابسته به آن استفاده می‌کند. در ادامه نحوه عملکرد کلی آن شرح داده شده است. هنگامی که دستور اجرا می‌شود، فایل باینری و اطلاعات اشکال‌زدایی وابسته به آن خوانده و تحلیل می‌شوند. برای این منظور، libabigail به‌طور پیش‌فرض توضیحات مربوط به انواعی را تحلیل می‌کند که از طریق واسط‌های (توابع و متغیرها) قابل مشاهده در بیرون از واحد ترجمه (Translation Unit) خود در دسترس هستند. پس از اتمام این تحلیل، یک پیکره واسط باینری کاربردی (ABI Corpus) با در نظر گرفتن زیرمجموعه‌ای از انواع در دسترس از واسط‌های مرتبط با نمادهای ELF که توسط فایل باینری تعریف و صادر (Export) شده‌اند ساخته می‌شود. این پیکره نهایی ABI همان چیزی است که libabigail آن را به عنوان نماینده ABI باینری تحلیل‌شده در نظر می‌گیرد. سپس libabigail قابلیت تولید نمایش‌های متنی از پیکره‌های ABI، مقایسه آن‌ها، تحلیل تغییراتشان و گزارش‌دهی درباره آن‌ها را دارد. خلاصه دستور (SYNOPSIS) abidiff [گزینه‌ها] محیط (ENVIRONMENT) ابزار abidiff دو فایل پیش‌فرض مشخصات مهارسازی (Suppression) <#suppr- spec-label> را بارگذاری کرده، محتوای آن‌ها را ادغام می‌کند و برای فیلتر کردن گزارش‌های تغییرات ABI که ممکن است از نظر کاربران مثبت کاذب تلقی شوند، به کار می‌گیرد. • فایل سراسری پیش‌فرض مشخصات مهارسازی سیستم مسیر آن توسط متغیر محیطی اختیاری LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE تعیین می‌شود. اگر این متغیر محیطی تنظیم نشده باشد، abidiff تلاش می‌کند فایل مهارسازی $libdir/libabigail/libabigail-default.abignore را بارگذاری کند. اگر این فایل موجود نباشد، هیچ فایل مشخصات مهارسازی سراسری سیستمی بارگذاری نمی‌شود. • فایل پیش‌فرض مشخصات مهارسازی کاربر مسیر آن توسط متغیر محیطی اختیاری LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE تعیین می‌شود. اگر این متغیر محیطی تنظیم نشده باشد، abidiff تلاش می‌کند فایل مهارسازی $HOME/.abignore را بارگذاری کند. اگر این فایل موجود نباشد، هیچ مشخصات مهارسازی کاربری پیش‌فرضی بارگذاری نمی‌شود. گزینه‌ها (OPTIONS) • --add-binaries1 برای هر یک از فایل‌های باینری جداشده با کاما که به عنوان آرگومان به این گزینه داده می‌شود، در صورتی که فایل باینری در پوشه مشخص‌شده توسط گزینه --added-binaries-dir1 پیدا شود، abidiff پیکره ABI آن باینری را بارگذاری کرده و به مجموعه‌ای از پیکره‌ها (موسوم به گروه پیکره ABI) که شامل اولین آرگومان abidiff است اضافه می‌کند. سپس آن گروه پیکره ABI با دومین گروه پیکره داده‌شده به عنوان آرگومان به abidiff مقایسه می‌شود. • --add-binaries2 برای هر یک از فایل‌های باینری جداشده با کاما که به عنوان آرگومان به این گزینه داده می‌شود، در صورتی که فایل باینری در پوشه مشخص‌شده توسط گزینه --added-binaries-dir2 پیدا شود، abidiff پیکره ABI آن باینری را بارگذاری کرده و به مجموعه‌ای از پیکره‌ها (موسوم به گروه پیکره ABI) که شامل دومین آرگومان abidiff است اضافه می‌کند. سپس آن گروه پیکره ABI با اولین گروه پیکره داده‌شده به عنوان آرگومان به abidiff مقایسه می‌شود. • --added-binaries-dir1 | --abd1 این گزینه همراه با گزینه‌های --add-binaries1، --follow-dependencies و --list-dependencies به کار می‌رود. فایل‌های باینری ارجاع‌شده توسط این گزینه‌ها، در صورت یافت شدن در پوشه added-binaries-directory-1، به عنوان پیکره ABI بارگذاری شده و به اولین گروه پیکره ABI مورد استفاده در مقایسه افزوده می‌شوند. • --added-binaries-dir2 | --abd2 این گزینه همراه با گزینه‌های --add-binaries2، --follow-dependencies و --list-dependencies به کار می‌رود. فایل‌های باینری ارجاع‌شده توسط این گزینه‌ها، در صورت یافت شدن در پوشه added-binaries-directory-2، به عنوان پیکره ABI بارگذاری شده و به دومین گروه پیکره ABI مورد استفاده در مقایسه افزوده می‌شوند. • --added-fns در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط توابع با تعریف سراسری را که به second-shared-library اضافه شده‌اند نمایش می‌دهد. • --added-vars در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط متغیرهای سراسری را که به second-shared-library اضافه (تعریف) شده‌اند نمایش می‌دهد. • --allow-non-exported-interfaces هنگام بررسی اطلاعات اشکال‌زدایی همراه با یک باینری، این ابزار توضیحات انواعی را که توسط واسط‌های (توابع و متغیرها) قابل مشاهده در بیرون از واحد ترجمه خود در دسترس هستند تحلیل می‌کند. پس از انجام این تحلیل، یک پیکره ABI تنها با در نظر گرفتن زیرمجموعه‌ای از انواع در دسترس از واسط‌های مرتبط با نمادهای ELF که توسط فایل باینری تعریف و صادر شده‌اند ساخته می‌شود. این همان پیکره‌های نهایی ABI است که توسط این ابزار مقایسه می‌شوند. اما اشکال این رویکرد در آن است که تحلیل تمام واسط‌های قابل مشاهده از بیرون واحد ترجمه می‌تواند حجم بسیار زیادی از داده تولید کند، به‌ویژه زمانی که آن باینری‌ها برنامه‌های کاربردی باشند (در مقایسه با کتابخانه‌های مشترک). یک نمونه از این برنامه‌ها، هسته لینوکس است. تحلیل چنین پیکره‌های عظیمی از ABI می‌تواند به‌شدت کند باشد. با این حال، در حضور یک باینری با «اندازه متوسط»، می‌توان با استفاده از این گزینه به libabigail اجازه داد تمام واسط‌های قابل مشاهده از بیرون واحد ترجمه را تحلیل کند. توجه داشته باشید که این گزینه به‌طور پیش‌فرض فعال است، مگر اینکه در حال تحلیل هسته لینوکس باشیم. • --btf هنگام مقایسه باینری‌ها، اطلاعات ABI را از اطلاعات اشکال‌زدایی BTF (در صورت وجود) استخراج می‌کند. • --changed-fns در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط تغییرات در زیرنوع‌های توابع سراسری تعریف‌شده در first-shared-library را نمایش می‌دهد. • --changed-vars در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط تغییرات در زیرنوع‌های متغیرهای سراسری تعریف‌شده در first-shared-library را نمایش می‌دهد. • --ctf هنگام مقایسه باینری‌ها، اطلاعات ABI را از اطلاعات اشکال‌زدایی CTF (در صورت وجود) استخراج می‌کند. • --debug-info-dir1 | --d1 برای مواردی که اطلاعات اشکال‌زدایی first-shared-library در یک فایل جداگانه قرار دارد، به abidiff می‌گوید که آن فایل اطلاعات اشکال‌زدایی مجزا را در کجا پیدا کند. توجه داشته باشید که di-path باید به پوشه ریشه‌ای اشاره کند که اطلاعات اشکال‌زدایی به صورت درختی در زیر آن مرتب شده است. در سیستم‌های مبتنی بر Red Hat، این پوشه معمولاً /usr/lib/debug است. این گزینه را می‌توان چندین بار با پوشه‌های ریشه مختلف مشخص کرد. در این حالت، abidiff برای یافتن اطلاعات اشکال‌زدایی مجزای first-shared-library به‌طور بالقوه تمام آن پوشه‌های ریشه را جستجو می‌کند. همچنین توجه داشته باشید که این گزینه برای اطلاعات اشکال‌زدایی مجزایی که توسط مدیر بسته سیستم شما نصب شده‌اند اجباری نیست، زیرا در آن صورت abidiff می‌داند که آن را کجا پیدا کند. • --debug-info-dir2 | --d2 مانند --debug-info-dir1، این گزینه به abidiff می‌گوید که فایل اطلاعات اشکال‌زدایی مجزا را برای فایل second-shared-library در کجا پیدا کند. این گزینه را می‌توان چندین بار با پوشه‌های ریشه مختلف ارائه کرد. در این حالت، abidiff به دنبال اطلاعات اشکال‌زدایی مجزای second-shared-library در تمام آن پوشه‌های ریشه خواهد گشت. • --debug-self-comparison در این حالت، هنگام مقایسه یک باینری با خودش در شرایط خاص، برای انواعی که یکسان‌سازی نوع (Type Canonicalization) روی آن‌ها ناموفق بوده است، پیام‌های خطا صادر می‌شود. هنگام مقایسه یک باینری با خودش، انواع متعارف (Canonical Types) باینری دوم باید (تا حد ممکن) با انواع متعارف باینری اول برابر باشند. اگر در این حالت مغایرتی تشخیص داده شود، یک سیگنال توقف (Abort) ارسال شده و فرآیند متوقف می‌گردد. این گزینه باید هنگام اجرای ابزار در یک دیباگر، برای مقاصد عیب‌یابی مورد استفاده قرار گیرد. این یک گزینه اختیاری برای اشکال‌زدایی و بررسی سلامت است. برای فعال‌سازی آن، بسته libabigail باید با گزینه پیکربندی --enable-debug-self-comparison کامپایل شود. • --debug-tc در این حالت، فرآیند یکسان‌سازی نوع (Type Canonicalization) تحت نظارت و بررسی دقیق قرار می‌گیرد. اساساً در طول یکسان‌سازی نوع، هر مقایسه نوع دو بار انجام می‌شود: یک بار در حالت ساختاری (مقایسه عضوبه‌عضو تمام زیرنوع‌ها) و یک بار با استفاده از مقایسه متعارف (Canonical). هر دو مقایسه باید نتیجه یکسانی داشته باشند. در غیر این صورت، یک سیگنال توقف (Abort) ارسال می‌شود و می‌توان فرآیند را اشکال‌زدایی کرد تا مشخص شود چرا دو نوع مقایسه نتایج متفاوتی داده‌اند. این یک گزینه اختیاری برای اشکال‌زدایی و بررسی سلامت است. برای فعال‌سازی آن، بسته libabigail باید با گزینه پیکربندی --enable-debug-type-canonicalization کامپایل شود. • --deleted-fns در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط توابع با تعریف سراسری را که از first-shared-library حذف شده‌اند نمایش می‌دهد. • --deleted-vars در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، فقط متغیرهای با تعریف سراسری را که از first-shared-library حذف شده‌اند نمایش می‌دهد. • --drop هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، توابع و متغیرهای دارای تعریف سراسری که نام آن‌ها با عبارت باقاعده regex مطابقت دارد را نادیده می‌گیرد (حذف می‌کند). در نتیجه، هیچ تغییری شامل این توابع یا متغیرها در گزارش تفاوت صادر نخواهد شد. • --drop-fn هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، توابع دارای تعریف سراسری که نام آن‌ها با عبارت باقاعده regex مطابقت دارد را نادیده می‌گیرد. در نتیجه، هیچ تغییری شامل این توابع در گزارش تفاوت صادر نخواهد شد. • --drop-var هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، متغیرهای دارای تعریف سراسری که با عبارت باقاعده regex مطابقت دارند را نادیده می‌گیرد. • --drop-private-types این گزینه همراه با گزینه‌های --headers-dir1، header-file1، header-file2 و --headers-dir2 به کار می‌رود. با فعال بودن این گزینه، انواعی که در هدرها تعریف نشده‌اند به‌طور کامل از نمایش درونی ساخته‌شده توسط Libabigail برای نمایش ABI حذف می‌شوند. بنابراین، نیازی به فیلتر کردن آن‌ها از گزارش نهایی تغییرات ABI نیست زیرا اصلاً در نمایش درونی Libabigail وجود نخواهند داشت. اما بدون این گزینه، آن انواع خصوصی در نمایش درونی نگهداری شده و بعداً از گزارش فیلتر می‌شوند. بنابراین این گزینه به‌طور بالقوه مصرف حافظه Libabigail را کاهش می‌دهد. کاربرد اصلی آن بهینه‌سازی مصرف حافظه ابزار روی باینری‌هایی با تعداد زیادی انواع تعریف‌شده و صادرشده عمومی است. • --dump-diff-tree پس از گزارش تفاوت، یک نمایش متنی از درخت گره‌های تفاوت (Diff Nodes Tree) را که توسط موتور مقایسه برای نمایش توابع و متغیرهای تغییریافته استفاده شده است در خروجی خطا (stderr) صادر می‌کند. این نمایش برای مقاصد اشکال‌زدایی است. توجه داشته باشید که این درخت تفاوت فقط به توابع و متغیرهایی مربوط می‌شود که دارای تغییراتی در زیرنوع‌های خود هستند. توابع و متغیرهای اضافه‌شده یا حذف‌شده هیچ درخت گره تفاوتی وابسته به خود ندارند. • --exported-interfaces-only به‌طور پیش‌فرض، هنگام بررسی اطلاعات اشکال‌زدایی همراه با یک باینری، این ابزار توضیحات انواعی را تحلیل می‌کند که توسط واسط‌های (توابع و متغیرها) قابل مشاهده در بیرون از واحد ترجمه خود در دسترس هستند. پس از انجام آن تحلیل، یک پیکره ABI تنها با در نظر گرفتن زیرمجموعه‌ای از انواع در دسترس از واسط‌های مرتبط با نمادهای ELF که توسط فایل باینری تعریف و صادر شده‌اند ساخته می‌شود. این همان پیکره‌های نهایی ABI است که توسط این ابزار مقایسه می‌شوند. اما مشکل این رویکرد آن است که تحلیل تمام واسط‌های قابل مشاهده از خارج واحد ترجمه می‌تواند داده‌های بسیار زیادی تولید کند، به‌ویژه زمانی که آن باینری‌ها برنامه‌های کاربردی باشند (در مقایسه با کتابخانه‌های مشترک). یک نمونه از این برنامه‌ها هسته لینوکس است. تحلیل چنین پیکره‌های عظیمی از ABI می‌تواند به‌شدت کند باشد. برای کاهش این مشکل عملکردی، این گزینه به libabigail امکان می‌دهد فقط انواعی را تحلیل کند که از طریق واسط‌های مرتبط با نمادهای تعریف‌شده و صادرشده ELF در دسترس هستند. توجه داشته باشید که این گزینه هنگام تحلیل هسته لینوکس به‌طور پیش‌فرض فعال است؛ در غیر این صورت، به‌طور پیش‌فرض غیرفعال است. • --fail-no-debug-info اگر هیچ اطلاعات اشکال‌زدایی یافت نشود، این گزینه موجب شکست اجرای برنامه (خروج با خطا) می‌شود. در غیر این صورت، بدون این گزینه، برنامه تلاش می‌کند ویژگی‌های باینری‌ها را که به اطلاعات اشکال‌زدایی وابسته نیستند (مانند ویژگی‌های خالص ELF) مقایسه کند. • --follow-dependencies | --fdeps برای هر وابستگی آرگومان اول abidiff، اگر در پوشه مشخص‌شده با گزینه --added-binaries-dir1 یافت شود، یک پیکره ABI از آن وابستگی ایجاد کرده و به مجموعه‌ای از پیکره‌ها (موسوم به گروه پیکره ABI) که شامل اولین آرگومان abidiff است اضافه می‌کند. به‌همین ترتیب، برای هر وابستگی آرگومان دوم abidiff، اگر در پوشه مشخص‌شده با گزینه --added-binaries-dir2 یافت شود، یک پیکره ABI از آن وابستگی ایجاد کرده و به گروه پیکره ABI که شامل دومین آرگومان abidiff است اضافه می‌کند. سپس این دو گروه پیکره ABI در برابر یکدیگر مقایسه می‌شوند. به عبارت دیگر، این گزینه باعث می‌شود abidiff مجموعه ورودی اول و وابستگی‌های آن را در برابر مجموعه ورودی دوم و وابستگی‌های آن مقایسه کند. • --harmless در گزارش تفاوت، فقط تغییرات بی‌ضرر (Harmless) <#harmlesschangeconcept-label> را نمایش می‌دهد. به‌طور پیش‌فرض، تغییرات بی‌ضرر از گزارش تفاوت فیلتر می‌شوند تا شلوغی متن به حداقل برسد و شانس تشخیص مشکلات واقعی ABI افزایش یابد. • --headers-dir1 | --hd1 مشخص می‌کند که فایل‌های هدر عمومی اولین کتابخانه مشترک (یا به‌طور کلی باینری) که ابزار باید مد نظر قرار دهد در کجا قرار دارند. بدین ترتیب ابزار تغییرات ABI مربوط به انواعی را که در هدرهای عمومی تعریف نشده‌اند فیلتر خواهد کرد. توجه داشته باشید که می‌توان چندین پوشه هدر عمومی را برای اولین کتابخانه مشترک مشخص کرد. در این صورت، گزینه --headers-dir1 باید چندین بار در خط فرمان درج شود، همانند مثال زیر: $ abidiff --headers-dir1 /some/path \ --headers-dir1 /some/other/path \ binary-version-1 binary-version-2 • --headers-dir2 | --hd2 مشخص می‌کند که فایل‌های هدر عمومی دومین کتابخانه مشترک که ابزار باید مد نظر قرار دهد در کجا قرار دارند. بدین ترتیب ابزار تغییرات ABI مربوط به انواعی را که در هدرهای عمومی تعریف نشده‌اند فیلتر خواهد کرد. توجه داشته باشید که می‌توان چندین پوشه هدر عمومی را برای دومین کتابخانه مشترک مشخص کرد. در این صورت گزینه --headers-dir2 باید چندین بار درج شود، مانند مثال زیر: $ abidiff --headers-dir2 /some/path \ --headers-dir2 /some/other/path \ binary-version-1 binary-version-2 • --header-file1 | --hf1 مشخص می‌کند که یک هدر عمومی از اولین کتابخانه مشترک که ابزار باید مد نظر قرار دهد در کجا قرار دارد. بدین ترتیب ابزار تغییرات ABI انواعی را که در هدرهای عمومی تعریف نشده‌اند فیلتر خواهد کرد. • --header-file2 | --hf2 مشخص می‌کند که یک هدر عمومی از دومین کتابخانه مشترک که ابزار باید مد نظر قرار دهد در کجا قرار دارد. بدین ترتیب ابزار تغییرات ABI انواعی را که در هدرهای عمومی تعریف نشده‌اند فیلتر خواهد کرد. • --help | -h نمایش یک راهنمای کوتاه درباره دستور و خروج. • --ignore-soname چشم‌پوشی از تفاوت‌های موجود در SONAME هنگام انجام مقایسه. • --impacted-interfaces هنگام نمایش تغییرات برگ (Leaf changes)، این گزینه به abidiff دستور می‌دهد فهرست واسط‌های تحت تأثیر قرار گرفته را نشان دهد. بنابراین این گزینه باید در کنار گزینه --leaf-changes-only استفاده شود، در غیر این صورت نادیده گرفته می‌شود. • --keep هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، توابع و متغیرهای دارای تعریف سراسری را که نامشان با عبارت باقاعده regex مطابقت دارد نگه می‌دارد. تمام توابع و متغیرهای دیگر کنار گذاشته می‌شوند و در گزارش تفاوت نهایی ظاهر نخواهند شد. • --keep-fn هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، توابع دارای تعریف سراسری را که نامشان با عبارت باقاعده regex مطابقت دارد نگه می‌دارد. سایر توابع کنار گذاشته می‌شوند و در گزارش تفاوت نهایی ظاهر نخواهند شد. • --keep-var هنگام خواندن فایل‌های ورودی ELF شامل first-shared-library و second-shared-library، متغیرهای دارای تعریف سراسری را که نامشان با عبارت باقاعده regex مطابقت دارد نگه می‌دارد. سایر متغیرها کنار گذاشته می‌شوند و در گزارش تفاوت نهایی ظاهر نخواهند شد. • --kmi-whitelist | -w هنگام تحلیل یک فایل باینری هسته لینوکس، این گزینه به فهرست سفید نام نمادهای ELF توابع و متغیرهایی اشاره می‌کند که ABI آن‌ها باید مد نظر قرار گیرد. به این فهرست سفید، «فهرست سفید واسط ماژول هسته» (Kernel Module Interface white list یا KMI) گفته می‌شود. علت این نام‌گذاری این است که برای هسته، ما از واژه ABI استفاده نمی‌کنیم؛ بلکه درباره واسط میان هسته و ماژول‌های آن صحبت می‌کنیم؛ از این رو اصطلاح KMI به جای ABI به کار می‌رود. هر تابع یا متغیر دیگری که نماد ELF آن در این فهرست سفید موجود نباشد، توسط این ابزار در نظر گرفته نخواهد شد. اگر این گزینه مشخص نشود -- یعنی هیچ فهرست سفیدی ارائه نشود -- کل KMI، یعنی مجموعه تمام توابع و متغیرهای سراسری تعریف‌شده و صادرشده به صورت عمومی توسط باینری‌های هسته لینوکس، مد نظر قرار خواهد گرفت. • --leaf-changes-only|-l فقط تغییرات برگ را نشان می‌دهد و گزارش تحلیل اثرگذاری را نمایش نمی‌دهد. این گزینه متضمن گزینه --redundant است. خروجی معمول abidiff هنگام مقایسه دو باینری شبیه به این است: $ abidiff libtest-v0.so libtest-v1.so Functions changes summary: 0 Removed, 1 Changed, 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with some indirect sub-type change: [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes: parameter 1 of type 'C&' has sub-type changes: in referenced type 'struct C' at test-v1.cc:7:1: type size hasn't changed 1 data member change: type of 'leaf* C::m0' changed: in pointed to type 'struct leaf' at test-v1.cc:1:1: type size changed from 32 to 64 bits 1 data member insertion: 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1 $ بنابراین در این مثال، گزارش اطلاعاتی را درباره چگونگی دسترسی به تغییر درج عضو داده "struct leaf" از تابع "void fn(C&)" ارائه می‌دهد. به عبارت دیگر، گزارش نه تنها تغییر عضو داده روی "struct leaf" را نشان می‌دهد، بلکه تأثیر آن تغییر بر روی تابع "void fn(C&)" را نیز نمایش می‌دهد. در اصطلاح abidiff، به تغییر روی "struct leaf" تغییر برگ (Leaf Change) گفته می‌شود. بنابراین گزینه‌های --leaf-changes-only --impacted-interfaces فقط تغییر برگ را نمایش می‌دهند. خروجی به این صورت خواهد بود: $ abidiff -l libtest-v0.so libtest-v1.so 'struct leaf' changed: type size changed from 32 to 64 bits 1 data member insertion: 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1 one impacted interface: function void fn(C&) $ توجه کنید که گزارش با نمایش فهرستی از واسط‌های تحت تأثیر تغییر برگ به پایان می‌رسد. حال اگر مایل به مشاهده آن فهرست از واسط‌های تحت تأثیر نیستید، می‌توانید به سادگی از گزینه --impacted-interface استفاده نکنید. در هر صورت، توضیحات بیشتر درباره این گزینه در ادامه آمده است. • --list-dependencies | --ldeps این گزینه تمام وابستگی‌های آرگومان‌های ورودی abidiff را که در پوشه‌های مشخص‌شده توسط گزینه‌های --added-binaries-dir1 و --added-binaries-dir2 یافت می‌شوند، فهرست می‌کند. • --no-added-syms در گزارش حاصل از تفاوت‌های میان first-shared-library و second-shared-library، توابع یا متغیرهای اضافه‌شده را نمایش نمی‌دهد. نمادهای ELF توابع یا متغیرهای اضافه‌شده را نیز نمایش نمی‌دهد. تمام انواع دیگر تغییرات نمایش داده می‌شوند مگر اینکه صریحاً توسط سایر گزینه‌ها در خط فرمان منع شده باشند. • --no-assume-odr-for-cplusplus هنگام تحلیل یک باینری تولیدشده از کد C++ با استفاده از اطلاعات اشکال‌زدایی DWARF ، کتابخانه libabigail قاعده یک تعریف (One Definition Rule یا ODR) را برای افزایش سرعت تحلیل فرض می‌گیرد. در این حالت، هنگامی که چند نوع دارای نام یکسان در باینری باشند، فرض می‌شود که همگی برابر هستند. این گزینه آن فرض را غیرفعال کرده و به libabigail دستور می‌دهد تا انواع را واقعاً با یکدیگر مقایسه کند تا برابری آن‌ها مشخص گردد. • --no-architecture هنگام مقایسه واسط‌های کاربردی باینری (ABI)، معماری سیستم را مد نظر قرار نمی‌دهد. • --no-change-categorization | -x این گزینه دسته‌بندی تغییرات به تغییرات بی‌ضرر (Harmless) و زیان‌آور (Harmful) را غیرفعال می‌کند. توجه داشته باشید که این دسته‌بندی پیش‌نیاز فیلتر کردن تغییرات است؛ بنابراین این گزینه آن فیلترسازی را نیز غیرفعال می‌سازد. هدف از این گزینه، افزایش سرعت اجرای برنامه در مواردی است که گراف تغییرات بسیار بزرگ بوده و کاربر صرفاً علاقه‌مند به بررسی تغییرات گره‌های برگ بدون توجه به تأثیر بالقوه آن‌ها بر واسط‌ها باشد. در چنین حالتی، این گزینه معمولاً در کنار گزینه --leaf-changes-only استفاده می‌شود. • --no-corpus-path ویژگی مسیر (path attribute) را برای پیکره ABI صادر نمی‌کند. • --no-default-suppression فایل‌های پیش‌فرض مشخصات مهارسازی (Suppression) را بارگذاری نمی‌کند. • --no-harmful در گزارش تفاوت، تغییرات زیان‌آور (Harmful) <#harmfulchangeconcept- label> را نمایش نمی‌دهد. به‌طور پیش‌فرض، فقط تغییرات زیان‌آور در گزارش تفاوت نمایش داده می‌شوند. • --no-leverage-dwarf-factorization هنگام تحلیل باینری‌ای که اطلاعات اشکال‌زدایی DWARF آن توسط ابزار DWZ پردازش شده است، فرض بر این است که اطلاعات نوع از قبل فاکتورگیری شده‌اند. این زمینه توسط libabigail برای انجام برخی بهینه‌سازی‌های سرعتی به کار گرفته می‌شود. این گزینه آن بهینه‌سازی‌ها را غیرفعال می‌سازد. • --no-linkage-name در گزارش خروجی، نام‌های پیوند (Linkage Names) توابع یا متغیرهای اضافه‌شده، حذف‌شده یا تغییریافته را نمایش نمی‌دهد. • --no-linux-kernel-mode بدون این گزینه، اگر abidiff تشخیص دهد که باینری‌های مورد بررسی باینری‌های هسته لینوکس هستند (یا vmlinux یا ماژول‌ها)، فقط توابع و متغیرهایی را در نظر می‌گیرد که نمادهای ELF آن‌ها در بخش‌های __ksymtab و __ksymtab_gpl فهرست شده باشند. با این گزینه، abidiff باینری را به عنوان یک باینری ELF غیرویژه در نظر می‌گیرد و بنابراین توابع و متغیرهایی را که بر اساس مفهوم ELF تعریف و صادر شده‌اند بررسی می‌کند. • --no-redundant در گزارش تفاوت، تغییرات تکراری (Redundant) را نمایش نمی‌دهد. یک تغییر تکراری تغییری است که در جای دیگری از گزارش نمایش داده شده است. این گزینه به‌طور پیش‌فرض فعال است. • --no-show-locs اطلاعات مربوط به اینکه نوع مورد نظر در کجای second shared library تغییر یافته است را نمایش نمی‌دهد. • --no-show-relative-offset-changes بدون این گزینه، هنگامی که آفست یک عضو داده تغییر می‌کند، گزارش تغییرات علاوه بر ذکر آفست قدیم و جدید، مشخص می‌کند که عضو داده به چه میزان (چند بیت) تغییر کرده است. با این گزینه، این تفاوت بیتی نسبی نمایش داده نمی‌شود. • --no-unreferenced-symbols در گزارش خروجی، اطلاعات تغییرات مربوط به نمادهای توابع و متغیرهایی را که توسط هیچ اطلاعات اشکال‌زدایی ارجاع داده نشده‌اند نمایش نمی‌دهد. توجه داشته باشید که برای این نمادهای ارجاع‌نشده، اطلاعات تغییرات نمایش‌داده‌شده صرفاً شامل نمادهای اضافه‌شده یا حذف‌شده است. • --non-reachable-types|-t تحلیل و صدور گزارش‌های تغییرات را برای تمام انواع باینری، شامل انواعی که از طریق توابع و متغیرهای سراسری در دسترس نیستند، انجام می‌دهد. این گزینه ممکن است منجر به افت شدید عملکرد شود زیرا تعداد انواع تحلیل‌شده می‌تواند بسیار زیاد باشد. با این حال، اگر همراه با گزینه‌های --headers-dir{1,2} و/یا header-file{1,2} استفاده شود، انواع غیرقابل‌دسترس اضافی تحلیل‌شده به انواعی که در فایل‌های هدر عمومی تعریف شده‌اند محدود می‌شوند و در نتیجه افت عملکرد در حد قابل قبولی باقی می‌ماند. همچنین، استفاده از این گزینه در کنار مشخصات مهارسازی (با استفاده از گزینه --suppressions) می‌تواند به کنترل تعداد انواع تحلیل‌شده (و افت احتمالی کارایی) کمک کند. توجه داشته باشید که بدون این گزینه، فقط انواعی که از توابع و متغیرهای سراسری در دسترس هستند تحلیل می‌شوند؛ بنابراین ابزار تغییرات را فقط روی این انواع در دسترس تشخیص داده و گزارش می‌کند. • --redundant در گزارش تفاوت، تغییرات تکراری را نمایش می‌دهد. یک تغییر تکراری، تغییری است که در جای دیگری از گزارش نیز نمایش داده شده است. • --show-bits نمایش اندازه‌ها و آفست‌ها بر حسب بیت، نه بایت. این گزینه به‌طور پیش‌فرض فعال است. • --show-bytes نمایش اندازه‌ها و آفست‌ها بر حسب بایت، نه بیت. به‌طور پیش‌فرض، اندازه‌ها و آفست‌ها بر حسب بیت نمایش داده می‌شوند. • --show-dec نمایش اندازه‌ها و آفست‌ها در مبنای ده‌دهی (Decimal). این گزینه به‌طور پیش‌فرض فعال است. • --show-hex نمایش اندازه‌ها و آفست‌ها در مبنای شانزده‌شانزدهی (Hexadecimal). • --stat به جای نمایش تفاوت‌های تفصیلی ABI میان first-shared-library و second-shared-library، صرفاً برخی آمارهای خلاصه درباره این تفاوت‌ها را نمایش می‌دهد. • --stats صدور آمار درباره موارد گوناگون درونی برنامه. • --suppressions | --suppr استفاده از یک فایل مشخصات مهارسازی <#suppr-spec-label> واقع در path-to-suppressions. توجه داشته باشید که این گزینه می‌تواند چندین بار در خط فرمان درج شود. در این صورت، تمام فایل‌های مشخصات مهارسازی ارائه‌شده مد نظر قرار خواهند گرفت. لطفاً توجه داشته باشید که به‌طور پیش‌فرض، در صورت عدم ارائه این گزینه، فایل‌های پیش‌فرض مشخصات مهارسازی بارگذاری می‌شوند. • --symtabs فقط جدول‌های نمادهای first-shared-library و second-shared-library را نمایش می‌دهد. • --verbose صدور گزارش‌های پرجزئیات (Verbose) درباره روند انجام کارهای گوناگون درونی. • --version | -v نمایش نسخه برنامه و خروج. مقادیر بازگشتی (RETURN VALUES) کد خروج دستور abidiff در صورتی که ABI باینری‌های مورد مقایسه یکسان باشند برابر با 0 است، و در صورتی که تفاوت داشته باشند یا ابزار با خطایی مواجه شود، عددی غیر صفر خواهد بود. در حالت دوم، کد خروج یک فیلد بیتی ۸ بیتی است که در آن هر بیت دارای معنای ویژه‌ای است. بیت اول با مقدار عددی 1 و به نام ABIDIFF_ERROR، بیانگر رخ دادن یک خطا است. بیت دوم با مقدار عددی 2 و به نام ABIDIFF_USAGE_ERROR، بیانگر وجود خطا در نحوه فراخوانی ابزار توسط کاربر است. این بیت برای نمونه زمانی فعال می‌شود که کاربر ابزار را با یک گزینه خط فرمان ناشناخته، یا تعداد یا آرگومان‌های اشتباه فراخوانی کرده باشد. اگر این بیت تنظیم شود، بیت ABIDIFF_ERROR نیز باید تنظیم شده باشد. بیت سوم با مقدار عددی 4 و به نام ABIDIFF_ABI_CHANGE، بیانگر تفاوت در ABI باینری‌های مورد مقایسه است. بیت چهارم با مقدار عددی 8 و به نام ABIDIFF_ABI_INCOMPATIBLE_CHANGE، به این معنی است که ABI باینری‌های مورد مقایسه به صورتی ناسازگار دچار تفاوت شده‌اند. اگر این بیت تنظیم شود، بیت ABIDIFF_ABI_CHANGE نیز باید حتماً تنظیم شده باشد. اگر بیت ABIDIFF_ABI_CHANGE تنظیم شود اما بیت ABIDIFF_INCOMPATIBLE_CHANGE تنظیم نشده باشد، به این معناست که واسط‌های باینری کاربردی مقایسه‌شده ممکن است سازگار یا ناسازگار باشند. در چنین حالتی، یک بازبین انسانی باید تغییرات ABI را بررسی کند تا درباره سازگار یا ناسازگار بودن آن‌ها تصمیم بگیرد. توجه داشته باشید که در حال حاضر، تنها انواع خاصی از تغییرات ABI منجر به فعال شدن فلگ ABIDIFF_ABI_INCOMPATIBLE_CHANGE می‌شوند. این تغییرات ABI عبارتند از: • حذف نماد یک تابع یا متغیر که قبلاً تعریف و صادر (Export) شده بوده است. • تغییر اندیس یکی از اعضای جدول توابع مجازی (vtable) برای برنامه‌ها و کتابخانه‌های زبان C++. با گذشت زمان، هرگاه الگوهای تغییر بیشتری شناسایی شوند که همواره به معنای تغییر ناسازگار در ABI باشند، کد برنامه تطبیق داده خواهد شد تا آن موارد را شناسایی کرده و مقدار ABIDIFF_ABI_INCOMPATIBLE_CHANGE را متناسب با آن‌ها تنظیم کند. بنابراین، اگر با چنین الگوهایی روبرو شدید، لطفاً به ما اطلاع دهید. بیت‌های باقی‌مانده در حال حاضر مورد استفاده قرار نمی‌گیرند. مثال‌های کاربردی (USAGE EXAMPLES) 1. تشخیص تغییر در زیرنوع یک تابع: $ cat -n test-v0.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc 3 4 struct S0 5 { 6 int m0; 7 }; 8 9 void 10 foo(S0* /*parameter_name*/) 11 { 12 // do something with parameter_name. 13 } $ $ cat -n test-v1.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc 3 4 struct type_base 5 { 6 int inserted; 7 }; 8 9 struct S0 : public type_base 10 { 11 int m0; 12 }; 13 14 void 15 foo(S0* /*parameter_name*/) 16 { 17 // do something with parameter_name. 18 } $ $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc $ $ abidiff libtest-v0.so libtest-v1.so; echo "exit code: $?" Functions changes summary: 0 Removed, 1 Changed, 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with some indirect sub-type change: [C]'function void foo(S0*)' has some indirect sub-type changes: parameter 0 of type 'S0*' has sub-type changes: in pointed to type 'struct S0': size changed from 32 to 64 bits 1 base class insertion: struct type_base 1 data member change: 'int S0::m0' offset changed from 0 to 32 exit code: 4 $ توجه کنید که کد خروج 4 است؛ به این معنی که بیت سوم ABIDIFF_ABI_CHANGE با مقدار عددی 4 روی 1 تنظیم شده است. این بدان معناست که ابزار تغییرات ABI را به عنوان زیان‌آور (Harmful) <#harmfulchangeconcept-label> دسته‌بندی کرده و بنابراین نیازمند بازبینی کاربر است. 2. تشخیص یک تغییر ناسازگار در ABI در نوع یک تابع: $ cat -n test-v0.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc 3 4 struct S0 5 { 6 int m0; 7 }; 8 9 S0 10 foo() 11 { 12 S0 s = {}; 13 return s; 14 } $ $ cat -n test-v1.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc 3 4 struct type_base 5 { 6 int inserted; 7 }; 8 9 struct S0 : public type_base 10 { 11 int m0; 12 }; 13 14 S0 15 foo() 16 { 17 S0 s = {}; 18 return s; 19 } $ $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc $ $ abidiff libtest-v0.so libtest-v1.so; echo "exit code: $?" Functions changes summary: 0 Removed, 1 Changed, 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with incompatible sub-type changes: [C] 'function S0 foo(void)' at test-v0.cc:10:1 has some sub-type changes: return type changed: type size changed from 32 to 64 (in bits) 1 base class insertion: struct type_base at test-v1.cc:4:1 1 data member change: 'int m0' offset changed from 0 to 32 (in bits) (by +32 bits) exit code: 12 $ توجه کنید که کد خروج 12 است؛ به این معنی که هر دو بیت سوم ABIDIFF_ABI_CHANGE با مقدار 4 و بیت چهارم ABIDIFF_ABI_INCOMPATIBLE_CHANGE با مقدار 8 روی 1 تنظیم شده‌اند. این بدان معناست که ابزار تغییرات ABI را به عنوان ناسازگار <#incompatiblechangeconcept-label> دسته‌بندی کرده است. این یک شکست در ABI (یا ABI break) محسوب می‌شود. 3. تشخیص تغییر دیگری در یک زیرنوع از یک تابع: $ cat -n test-v0.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc 3 4 struct S0 5 { 6 int m0; 7 }; 8 9 void 10 foo(S0& /*parameter_name*/) 11 { 12 // do something with parameter_name. 13 } $ $ cat -n test-v1.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc 3 4 struct S0 5 { 6 char inserted_member; 7 int m0; 8 }; 9 10 void 11 foo(S0& /*parameter_name*/) 12 { 13 // do something with parameter_name. 14 } $ $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc $ $ abidiff libtest-v0.so libtest-v1.so; echo "exit code: $?" Functions changes summary: 0 Removed, 1 Changed, 0 Added function Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 function with some indirect sub-type change: [C]'function void foo(S0&)' has some indirect sub-type changes: parameter 0 of type 'S0&' has sub-type changes: in referenced type 'struct S0': size changed from 32 to 64 bits 1 data member insertion: 'char S0::inserted_member', at offset 0 (in bits) 1 data member change: 'int S0::m0' offset changed from 0 to 32 exit code: 4 $ 4. تشخیص حذف یا اضافه شدن توابع به یک کتابخانه: $ cat -n test-v0.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc 3 4 struct S0 5 { 6 int m0; 7 }; 8 9 void 10 foo(S0& /*parameter_name*/) 11 { 12 // do something with parameter_name. 13 } $ $ cat -n test-v1.cc 1 // Compile this with: 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc 3 4 struct S0 5 { 6 char inserted_member; 7 int m0; 8 }; 9 10 void 11 bar(S0& /*parameter_name*/) 12 { 13 // do something with parameter_name. 14 } $ $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc $ $ abidiff libtest-v0.so libtest-v1.so; echo "exit code: $?" Functions changes summary: 1 Removed, 0 Changed, 1 Added functions Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1 Removed function: 'function void foo(S0&)' {_Z3fooR2S0} 1 Added function: 'function void bar(S0&)' {_Z3barR2S0} exit code: 12 $ 5. مقایسه دو مجموعه باینری که در خط فرمان ارسال می‌شوند: $ abidiff --add-binaries1=file2-v1 \ --add-binaries2=file2-v2,file2-v1 \ --added-binaries-dir1 dir1 \ --added-binaries-dir2 dir2 \ file1-v1 file1-v2 توجه داشته باشید که فایل‌های file2-v1 و file2-v2 باید در dir1 و dir2 یا در دایرکتوری جاری یافت شوند. 6. مقایسه دو کتابخانه و وابستگی‌های آن‌ها: $ abidiff --follow-dependencies \ --added-binaries-dir1 /some/where \ --added-binaries-dir2 /some/where/else \ foo bar این دستور مجموعه باینری‌های تشکیل‌شده توسط foo و وابستگی‌های آن را در برابر مجموعه باینری‌های تشکیل‌شده توسط bar و وابستگی‌های آن مقایسه می‌کند. نویسندگان (AUTHORS) Dodji Seketeli حق نشر (COPYRIGHT) 2014-2025, Red Hat, Inc. 1 مه 2026 ABIDIFF(1)