मैं एक जेनेरिक फ़ंक्शन लिखना चाहता हूं जो सिस्टम कॉल करता है। कुछलिनक्स पर सिस्टम कॉल तर्कों का प्रकार क्या है?
long my_syscall2(long number, long arg1, long arg2);
मैं इसे यथासंभव पोर्टेबल बनना चाहता हूं। कार्यान्वयन सभी आर्किटेक्चर के लिए स्पष्ट रूप से अलग है। क्या समारोह के हस्ताक्षर को भी अलग होना चाहिए? क्या मैं long
का उपयोग कर सकता हूं या मुझे कुछ और उपयोग करना चाहिए?
- गिरी कुछ dark magic का उपयोग करता है: (__SYSCALL_DEFINEx __SC_LONG कॉल प्रकार प्राप्त करने के लिए, __SC_LONG जादू होता है)
यहाँ संभव समाधान है कि मैंने पाया है। मैंने कहीं कहीं सुना है कि उपयोगकर्ता स्थान में प्रकार हमेशा कर्नेल स्पेस के समान नहीं होते हैं, इसलिए मुझे नहीं पता कि मैं इसका उपयोग कर सकता हूं या नहीं।
- musl-libc uses long for all architectures that it supports except x32: ([arch] /syscall_arch.h में परिभाषित)।
- मैं उन सभी प्रोसेसर आर्किटेक्चर और कंपाइलर्स के लिए प्रलेखन ढूंढ सकता हूं जिन्हें मैं समर्थन देना चाहता हूं, रजिस्टर आकार और पूर्णांक प्रकार के आकार देखें और रजिस्टरों के समान आकार वाले किसी भी पूर्णांक प्रकार को चुनें।
तो मुझे लगता है कि सवाल यह है कि "वहाँ कुछ नियम कहता है कि 'सिस्टम कॉल तर्क का प्रकार हमेशा से रहे हैं x32 जैसे कुछ अपवादों के साथ long
' या मैं हर वास्तुकला और संकलक के लिए दस्तावेज़ को देखने की जरूरत है है?"
संपादित करें: मुझे पता है कि कुछ सिस्टम कॉल पॉइंटर्स और अन्य प्रकार पैरामीटर के रूप में लेते हैं। मैं सामान्य कार्यों को लिखना चाहता हूं जो जेनेरिक पैरामीटर प्रकारों के साथ किसी भी सिस्टम कॉल को कॉल कर सकते हैं। ये जेनेरिक पैरामीटर प्रकार वास्तविक पैरामीटर प्रकारों को पकड़ने के लिए काफी बड़े होना चाहिए। मुझे पता है कि यह संभव है क्योंकि syscall() फ़ंक्शन मौजूद है।
संपादित 2: यहां इस समस्या का एक और आंशिक समाधान है। इन कार्यों के
क्रियान्वयन वर्तमान में इस तरह दिखेगा:
static __inline long my_syscall2(long number, long arg1, long arg2)
{
unsigned long ret;
__asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(number), "D"(arg1), "S"(arg2)
: "rcx", "r11", "memory");
return ret;
}
दिलचस्प हिस्सा "=a"(ret)
है, इसका मतलब है कि syscall वापसी मान कि रजिस्टर a
में संग्रहित है चर ret
में बचाया जाना चाहिए। स्थानीय चर बनाता है जो एक समारोह लिखने के बजाय, syscall बनाता है, इसके वापसी मूल्य को चर में सहेजता है और चर लौटाता है मैं एक मैक्रो लिख सकता हूं जो syscall बनाता है और परिणाम को कॉलर द्वारा प्रदान किए गए चर में संग्रहीत करता है। यह इस तरह दिखेगा:
#define my_syscall2(RET, NUMBER, ARG1, ARG2) \
__asm__ __volatile__ ("syscall" : "=a"(RET) : "a"(NUMBER), "D"(ARG1), "S"(ARG2) \
: "rcx", "r11", "memory");
और यह इस तरह इस्तेमाल किया जाएगा:
long result;
void * arg1;
int arg2;
my_syscall2(result, <syscall number>, arg1, arg2);
इस तरह से मैं पता करने के लिए रजिस्टर आकार और पूर्णांक प्रकार है कि काफी बड़ा एक मूल्य धारण करने के लिए है की जरूरत नहीं है रजिस्टर का
आप सिस्टम कॉल को कैसे संभालेंगे जो कोई पैरामीटर नहीं लेता है? – edmz
@black मैं 6 कार्यों को परिभाषित करता हूं my_syscall {0-5} – alkedr
यह वास्तव में यहां तक कि अधिक जटिल है जब तक कि आप एक आर्किटेक्चर निर्दिष्ट नहीं करते हैं), लेकिन syscall() मैक्रो और syscall0 के मेरे सार्वजनिक डोमेन कार्यान्वयन का उपयोग करने के लिए स्वतंत्र महसूस करें () -syscall6() https://github.com/technosaurus/BQC पर फ़ंक्शंस ... जिनमें से सभी पैरामीटर – technosaurus