C++FILT(1) دستورات کاربر C++FILT(1)

c++filt - بازگردانی نمادهای C++ و جاوا به نامهای خوانا (Demangle)

c++filt [-_|--strip-underscore]
[-n|--no-strip-underscore]
[-p|--no-params]
[-t|--types]
[-i|--no-verbose]
[-r|--no-recurse-limit]
[-R|--recurse-limit]
[-s format|--format=format]
[--help] [--version] [symbol...]

زبان‌های C++ و جاوا قابلیتی به نام سربارگذاری توابع (Function Overloading) دارند؛ یعنی برنامه‌نویس می‌تواند چندین تابع هم‌نام بنویسد، به شرطی که هر کدام پارامترهایی با انواع متفاوت دریافت کنند. کامپایلر برای آنکه بتواند این توابع هم‌نام را از یکدیگر تشخیص دهد، نام هر تابع را به‌همراه مشخصات و نوع پارامترهای آن در قالب یک شناسه سطح پایین اسمبلی کدگذاری می‌کند که به آن نسخه از تابع هویتی یکتا می‌دهد. به این فرآیند در اصطلاح کامپایلر، منگل کردن یا درهم‌سازی نام‌ها (mangling) می‌گویند. برنامه c++filt [1] عکس این مسیر را طی می‌کند: شناسه‌های سطح پایین رمزشده را رمزگشایی (demangle) کرده و نام‌های خوانا و اصلی آن‌ها را بازمی‌گرداند.

در ورودی، هر واژه الفبایی-عددی (شامل حروف، ارقام، زیرخط، علامت دلار یا نقطه) یک شناسه منگل‌شده بالقوه در نظر گرفته می‌شود. اگر این واژه به یک نام معتبر در C++ رمزگشایی شود، نام بازگردانی‌شده جایگزین شناسه اولیه در خروجی خواهد شد؛ در غیر این صورت، همان واژه بدون تغییر به خروجی فرستاده می‌شود. با این سازوکار، می‌توانید یک فایل کامل از سورس اسمبلی را که پر از نام‌های منگل‌شده است به c++filt بسپارید و نسخه بازگردانی‌شده آن را با نام‌های خوانا دریافت کنید.

علاوه بر این، می‌توانید شناسه‌ها را به‌صورت مستقیم از طریق خط فرمان به c++filt بدهید تا رمزگشایی شوند:

c++filt <symbol>

برای نمونه، تابع f() در C++ به شناسه منگل‌شده _Z1fv و تابع دیگر f(int*) به شناسه _Z1fPi تبدیل می‌شود. با اجرای دستور زیر:

c++filt _Z1fv _Z1fPi

خروجی رمزگشایی‌شده به شکل زیر بازگردانده می‌شود:

f()
f(int*)

اگر هیچ آرگومان symbol در خط فرمان وارد نشود، c++filt شناسه‌ها را از ورودی استاندارد می‌خواند و نتایج را در خروجی استاندارد چاپ می‌کند. تفاوت خواندن نام‌ها از خط فرمان با خواندن از ورودی استاندارد در این است که آرگومان‌های خط فرمان صرفاً یک شناسه منگل‌شده در نظر گرفته می‌شوند و برنامه تلاشی برای تفکیک نماد از نویسه‌های چسبیده به آن انجام نمی‌دهد. بنابراین، دستور زیر:

c++filt -n _Z1fv

به‌درستی کار می‌کند و نام را به "f()" بازمی‌گرداند؛ در حالی که دستور زیر:

c++filt -n _Z1fv,

کار نخواهد کرد؛ زیرا وجود علامت ویرگول در انتهای شناسه، آن را نامعتبر می‌کند. اما اجرای همین دستور از طریق ورودی استاندارد:

echo _Z1fv, | c++filt -n

نتیجه مطلوب را خواهد داد و مقدار "f()," یعنی نام بازگردانی‌شده به همراه ویرگول انتهایی را چاپ می‌کند. دلیل این تفاوت این است که هنگام خواندن از ورودی استاندارد، برنامه فرض می‌کند ورودی ممکن است خطی از یک فایل اسمبلی باشد که در آن نویسه‌های دیگری بلافاصله پس از شناسه قرار گرفته‌اند؛ مانند:

.type   _Z1fv, @function

-_, --strip-underscore
در برخی سیستم‌ها، کامپایلرهای C و C++ پیش از تمام نام‌ها یک زیرخط (_) اضافه می‌کنند. برای مثال، نام foo در C به شناسه سطح پایین _foo تبدیل می‌شود. این گزینه زیرخط ابتدایی را از ابتدای نام حذف می‌کند. اینکه c++filt به‌طور پیش‌فرض این زیرخط را حذف کند یا نه، به معماری و سیستم هدف بستگی دارد.
زیرخط ابتدایی حذف نشود.
هنگام رمزگشایی و بازگردانی نام توابع، نوع پارامترهای ورودی تابع نمایش داده نشود.
علاوه بر نام توابع، بازگردانی نوع‌ها (Types) نیز آزمایش شود. این گزینه به‌طور پیش‌فرض غیرفعال است؛ زیرا شناسه‌های مربوط به انواع معمولاً تنها در داخل کامپایلر کاربرد دارند و ممکن است با نام‌های معمولی اشتباه گرفته شوند. برای مثال، تابعی به نام "a" اگر به عنوان یک نوع منگل‌شده تفسیر شود، به "signed char" ترجمه خواهد شد.
جزئیات پیاده‌سازی (در صورت وجود) در خروجی بازگردانی‌شده نمایش داده نشود.
فعال یا غیرفعال کردن محدودیت عمق بازگشت (Recursion) هنگام رمزگشایی رشته‌ها. از آنجا که ساختار قالب‌های منگل کردن اجازه سطوح بازگشت نامحدود را می‌دهد، ممکن است رشته‌هایی تولید شوند که پردازش آن‌ها کل فضای پشته (Stack) سیستم را مصرف کرده و باعث خطای دسترسی به حافظه (Segmentation fault) شود. این محدودیت با تحدید عمق بازگشت به ۲۰۴۸ سطح تودرتو، از وقوع چنین خطایی جلوگیری می‌کند.

این محدودیت به‌طور پیش‌فرض فعال است؛ با این حال ممکن است برای بازگردانی نام‌های بسیار پیچیده، غیرفعال کردن آن ضروری باشد. توجه داشته باشید در صورت خاموش کردن این محدودیت، احتمال سرریز پشته وجود دارد و هیچ گزارش باگی در این خصوص پذیرفته نخواهد شد.

گزینه -r مترادف --no-recurse-limit است و گزینه -R مترادف --recurse-limit محسوب می‌شود.

دستور c++filt می‌تواند روش‌های مختلف منگل‌سازی مورد استفاده در کامپایلرهای گوناگون را رمزگشایی کند. آرگومان این گزینه مشخص می‌کند که چه روشی برای رمزگشایی به کار رود:
انتخاب خودکار قالب بر اساس فایل اجرایی (روش پیش‌فرض).
روش استفاده‌شده در کامپایلر GNU C++ (یعنی g++).
روش استفاده‌شده در کامپایلر Lucid (یعنی lcc).
روش مشخص‌شده در راهنمای مرجع تفسیری C++ (C++ Annotated Reference Manual).
روش استفاده‌شده در کامپایلر HP (یعنی aCC).
روش استفاده‌شده در کامپایلر EDG.
روش استفاده‌شده در کامپایلر GNU C++ (یعنی g++) همراه با ABI نسخه ۳ (V3 ABI).
روش استفاده‌شده در کامپایلر GNU Java (یعنی gcj).
روش استفاده‌شده در کامپایلر GNU Ada (یعنی GNAT).
چاپ خلاصه‌ای از گزینه‌های c++filt و خروج.
چاپ شماره نسخه c++filt و خروج.
@file
خواندن گزینه‌های خط فرمان از file. گزینه‌های خوانده‌شده دقیقاً در محل قرارگیری آرگومان @file جایگزین می‌شوند. اگر file پیدا نشود یا قابل خواندن نباشد، این گزینه به‌صورت لفظی در نظر گرفته شده و حذف نمی‌شود.

گزینه‌های درون file با نویسه‌های فاصله خالی (Whitespace) تفکیک می‌شوند. در صورتی که می‌خواهید یک گزینه حاوی فاصله باشد، باید کل آن را درون گیومه تکی یا جفتی قرار دهید. هر نویسه‌ای (از جمله بک‌اسلش) را می‌توان با درج یک بک‌اسلش در ابتدای آن وارد کرد. همچنین فایل می‌تواند حاوی گزینه‌های @file دیگری باشد که آن‌ها نیز به‌صورت بازگشتی بررسی و اعمال خواهند شد.

1.
سیستم‌عامل MS-DOS اجازه درج نویسه «+» در نام فایل‌ها را نمی‌دهد؛ به همین دلیل در آن سیستم‌عامل، نام این برنامه CXXFILT است.

مدخل‌های Info برای binutils.

حق نشر © ۱۹۹۱-۲۰۲۳ بنیاد نرم‌افزارهای آزاد (Free Software Foundation, Inc.)

مجوز کپی، توزیع یا تغییر این سند تحت شرایط مجوز مستندات آزاد گنو (GNU Free Documentation License)، نسخه ۱.۳ یا هر نسخه جدیدتر منتشرشده توسط بنیاد نرم‌افزارهای آزاد صادر شده است؛ بدون بخش‌های تغییرناپذیر، بدون متون روی جلد و بدون متون پشت جلد. نسخه‌ای از این مجوز در بخش با عنوان «GNU Free Documentation License» قرار داده شده است.

2023-01-14 binutils-2.40.00