HeadlinesBriefing favicon HeadlinesBriefing.com

GCC নেস্টেড ফাংশন ট্র্যাম্পোলিন স্ট্যাক অপ্টিমাইজেশন

Hacker News •
×

GCC নেস্টেড ফাংশন ট্র্যাম্পোলিন স্ট্যাক অপ্টিমাইজেশন। এক্সিকিউটেবল স্ট্যাক ছাড়া GCC-এ নেস্টেড ফাংশনগুলোর ইনডায়রেক্ট কলিং। মার্টিন উএকার, ২০২৬-০৮-২৯। আমরা গতবারের কথা বলেছিলাম কিভাবে GCC এবং Clang-এ নেস্টেড ফাংশন ব্যবহার করে কলব্যাক করা যায় এক্সিকিউটেবল স্ট্যাক ছাড়া। কিন্তু কেউ যদি পুরানো GCC ভার্সন সাপোর্ট করতে চায় তবে কী? অবশ্যই কেউ এক্সিকিউটেবল স্ট্যাক মেনে নিতে পারে, কিন্তু একটি হ্যাক দিয়ে এটাও এড়িয়ে যাওয়া সম্ভব। GCC: নেস্টেড ফাংশন এবং ট্র্যাম্পোলিন। প্রথমে আলোচনা করি GCC কিভাবে নেস্টেড ফাংশনের অ্যাড্রেস নেওয়া সাপোর্ট করে। নতুন ম্যাক্রোগুলো ব্যবহার ছাড়া আমাদের টয় উদাহরণ নিচে দেখানো হলো। x86_64-এ, জেনারেটেড অ্যাসেম্বলি স্ট্যাকে একটি ট্র্যাম্পোলিন রাখে এবং ইনলাইন baz ফাংশন দিয়ে তা অবিলম্বে আহ্বান করে। ট্র্যাম্পোলিন হল একটি ছোট কোড সিকোয়েন্স যা স্ট্যাটিক ফ্রেম রেজিস্টারকে স্ট্যাকে একটি স্ট্রাকচারে লোড করে যাতে প্যারেন্ট ফাংশন থেকে ক্যাপচার করা ভেরিয়েবল থাকে এবং তারপর লোকাল ফাংশনে জাম্প করে। যদি কেউ কনস্ট্যান্ট গুলো -17591, -17847, এবং -1864106167 কে আবার অ্যাসেম্বলি ইনস্ট্রাকশনে অনুবাদ করে তবে নিচের x86_64 কোড পাওয়া যায়: movq $bar.0, %r11, movq $frame, %r10, jump *%r11। স্ট্যাটিক চেইন এবং কোড অ্যাড্রেস দুটোই ট্র্যাম্পোলিনের কোডে মুভ ইনস্ট্রাকশন দ্বারা ব্যবহৃত ইমিডিয়েট কনস্ট্যান্ট। ট্র্যাম্পোলিনের অ্যাড্রেস দিয়ে ফাংশন কল করার বদলে, আমরা ট্র্যাম্পোলিন থেকে কোড অ্যাড্রেস এবং স্ট্যাটিক চেইন বের করে সেগুলো __builtin_call_with_static_chain বিল্ট-ইন ফাংশন দিয়ে লোকাল ফাংশনকে সরাসরি কল করতে পারি। এইভাবে, আমরা এই দুটি পয়েন্টার ভ্যালু ট্র্যাম্পোলিন থেকে পড়ার ব্যবহার পুরানো GCC ভার্সনে ফলব্যাক মেকানিজম হিসেবে করতে পারি। ডাউনসাইড গুলো হলো ট্র্যাম্পোলিন এখনও তৈরি হচ্ছে, কম্পাইলার এখনও ইনডায়রেক্ট কল ডিভার্চুয়ালাইজ করতে পারছে না, এবং স্ট্যাক এখনও এক্সিকিউটেবল হিসেবে মার্কড থাকবে। তো কী লাভ হয়েছে? যেহেতু আমরা কখনোই আসলে ট্র্যাম্পোলিন আহ্বান করি না, আমরা নিচের কমান্ড দিয়ে স্ট্যাককে আবার নন-এক্সিকিউটেবল করতে পারি, যা কমপক্ষে এই ফিচারের সিকিউরিটি কনসার্ন গুলো সমাধান করে। patchelf --clear-execstack program। এই আইডিয়া আমার এক্সপেরিমেন্টাল লাইব্রেরি noplate-এ ইমপ্লিমেন্ট করা হয়েছে, যেখানে কোড অ্যাড্রেস এবং স্ট্যাটিক চেইন থেকে একটি ওয়াইড পয়েন্টার কনস্ট্রাক্ট করা হয়েছে। ট্র্যাম্পোলিন এজ ফাংশন ডেসক্রিপ্টর। আর একটি আইডিয়া আছে যা আমি এক্সপ্লোর করার যোগ্য মনে করি: ট্র্যাম্পোলিনকে নিজে ফাংশন ডেসক্রিপ্টর হিসেবে ব্যবহার করা যেতে পারে। ট্র্যাম্পোলিন তৈরি হওয়ার সময় স্ট্যাটিক চেইন এবং কোড পয়েন্টার বের করার বদলে, আমরা সাদা ভাবে ট্র্যাম্পোলিনের অ্যাড্রেস পাস করি। কিন্তু সব জায়গায় যেখানে আমরা ট্র্যাম্পোলিন কল করতে পারি, সেখানে প্রথমে চেক করি পয়েন্টারটা ট্র্যাম্পোলিনের দিকে পয়েন্ট করছে কিনা, এবং তারপর কোড অ্যাড্রেস এবং স্ট্যাটিক চেইন বের করে __builtin_call_with_static_chain দিয়ে নেস্টেড ফাংশনকে সরাসরি কল করি। একটা সেন্সে বলা যায় আমরা ট্র্যাম্পোলিন আহ্বান করার বদলে, কল সাইটে একটি সুপার সিম্পল ইন্টারপ্রেটার দিয়ে ট্র্যাম্পোলিনের কোড ইন্টারপ্রেট করছি যা শুধু এই স্পেসিফিক কোড সিকোয়েন্স ইন্টারপ্রেট করতে পারে এবং যা এতটাই সিম্পল যে...