dlinfo(3)

الاسم
dlinfo - الحصول على معلومات حول كائن محمل ديناميكياً

المكتبة
مكتبة الربط الديناميكي (libdl، -ldl)

موجز
#define _GNU_SOURCE
#include <link.h>
#include <dlfcn.h>

int dlinfo(void *restrict handle, int request, void *restrict info);

الوصف
الدالة dlinfo() تحصل على معلومات حول الكائن المحمّل ديناميكيًا المشار إليه بواسطة handle (يُحصل عليه عادةً باستدعاء سابق لـ dlopen(3) أو dlmopen(3)). المُعامل request يُحدد أي معلومات تُرجع. المُعامل info هو مؤشر لمخزن يُستخدم لتخزين المعلومات المُرجعة من الاستدعاء؛ نوع هذا المُعامل يعتمد على request.

القيم التالية مدعومة لـ request (مع النوع المُقابل لـ info المُظهر بين قوسين):

RTLD_DI_LMID (Lmid_t *)
    الحصول على مُعرّف قائمة خريطة الربط (الفضاء الاسمي) الذي حُمّل فيه handle.

RTLD_DI_LINKMAP (struct link_map **)
    الحصول على مؤشر للهيكل link_map المُقابل لـ handle. المُعامل info يشير إلى مؤشر لهيكل link_map، المُعرّف في <link.h> كالتالي:

        struct link_map {
            ElfW(Addr) l_addr;  /* الفرق بين العنوان
                                   في ملف ELF والعنوان
                                   في الذاكرة */
            char      *l_name;  /* مسار المسار المطلق حيث
                                   وُجد الكائن */
            ElfW(Dyn) *l_ld;    /* القسم الديناميكي للكائن
                                   المشترك */
            struct link_map *l_next, *l_prev;
                                /* سلسلة الكائنات المحملة */

            /* بالإضافة إلى حقول إضافية خاصة بـ
               التنفيذ */
        };

RTLD_DI_ORIGIN (char *)
    نسخ مسار أصل الكائن المُشارك المُقابل لـ handle إلى الموقع المُشار إليه بواسطة info.

RTLD_DI_SERINFO (Dl_serinfo *)
    الحصول على مسارات بحث المكتبة للكائن المُشارك المُشار إليه بواسطة handle. المُعامل info هو مؤشر لـ Dl_serinfo يحتوي على مسارات البحث. نظرًا لأن عدد مسارات البحث قد يختلف، فإن حجم الهيكل المُشار إليه بواسطة info يمكن أن يختلف. طلب RTLD_DI_SERINFOSIZE الموصوف أدناه يسمح للتطبيقات بحجم المخزن بشكل مناسب. يجب على المُستدعي تنفيذ الخطوات التالية:

    (1) استخدام طلب RTLD_DI_SERINFOSIZE لملء هيكل Dl_serinfo بالحجم (dls_size) للهيكل المطلوب لطلب RTLD_DI_SERINFO اللاحق.

    (2) تخصيص مخزن Dl_serinfo بالحجم الصحيح (dls_size).

    (3) استخدام طلب RTLD_DI_SERINFOSIZE إضافي لملء حقلي dls_size و dls_cnt للمخزن المُخصص في الخطوة السابقة.

    (4) استخدام RTLD_DI_SERINFO للحصول على مسارات بحث المكتبة.

    الهيكل Dl_serinfo مُعرّف كالتالي:

        typedef struct {
            size_t dls_size;           /* الحجم بالبايت للمخزن المؤقت (buffer) بأكمله */
            unsigned int dls_cnt;      /* عدد العناصر في 'dls_serpath' */
            Dl_serpath dls_serpath[1]; /* أطول في الواقع، بعدد 'dls_cnt' من العناصر */
        } Dl_serinfo;

    كل عنصر من عناصر dls_serpath في البنية أعلاه هو بنية بالشكل التالي:

        typedef struct {
            char *dls_name;            /* اسم دليل مسار البحث عن المكتبات */
            unsigned int dls_flags;    /* يشير إلى مصدر هذا الدليل */
        } Dl_serpath;

    حقل dls_flags غير مستخدم حالياً، ويحتوي دائماً على صفر.

RTLD_DI_SERINFOSIZE (Dl_serinfo *)
    يُملأ حقلي dls_size و dls_cnt من بنية Dl_serinfo المشار إليها بواسطة info بقيم مناسبة لتخصيص مخبأ لاستخدامه في طلب RTLD_DI_SERINFO لاحق.

RTLD_DI_TLS_MODID (size_t *, منذ glibc 2.4)
    يحصل على معرف الوحدة لمقطع TLS (التخزين المحلي للخيط) لهذا الكائن المشترك، كما يُستخدم في إعادة توطين TLS. إذا لم يُعرّف هذا الكائن مقطع TLS، يُوضع صفر في *info.

RTLD_DI_TLS_DATA (void **, منذ glibc 2.4)
    يحصل على مؤشر إلى كتلة TLS للخيط المستدعي المطابقة لمقطع TLS لهذا الكائن المشترك. إذا لم يُعرّف هذا الكائن مقطع PT_TLS، أو إذا لم يخصص الخيط المستدعي كتلة له، يُوضع NULL في *info.

RTLD_DI_PHDR (const ElfW(Phdr *), منذ glibc 2.34.1)
    يحصل على عنوان رأس البرنامج لهذا الكائن المشترك ويضعه في *info. يُرجع استدعاء dlinfo هذا عدد رؤوس البرنامج في الكائن المشترك.

قيمة الإرجاع
عند النجاح، يُرجع dlinfo() 0 (إذا لم يُحدد صراحة)، أو قيمة موجبة مطابقة للطلب. عند الخطأ، يُرجع -1؛ يمكن تشخيص الخطأ باستخدام dlerror(3).

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
dlinfo() | سلامة الخيوط | MT-Safe

الإصدارات
مجموعات الطلبات المدعومة من التطبيقات المختلفة تتداخل جزئياً فقط.

المعايير
GNU.

التاريخ
glibc 2.3.3. Solaris.

أمثلة
البرنامج أدناه يفتح كائناً مشتركاً باستخدام dlopen(3) ثم يستخدم طلبي RTLD_DI_SERINFOSIZE و RTLD_DI_SERINFO للحصول على قائمة مسار بحث المكتبة للمكتبة. إليك مثال لما قد نراه عند تشغيل البرنامج:

    $ ./a.out /lib64/libm.so.6;
    dls_serpath[0].dls_name = /lib64
    dls_serpath[1].dls_name = /usr/lib64

  مصدر البرنامج
    #define _GNU_SOURCE
    #include <dlfcn.h>
    #include <link.h>
    #include <stdio.h>
    #include <stdlib.h>

    int
    main(int argc, char *argv[])
    {
        void *handle;
        Dl_serinfo serinfo;
        Dl_serinfo *sip;

        if (argc != 2) {
            fprintf(stderr, "Usage: %s <libpath>\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        /* Obtain a handle for shared object specified on command line.  */

        handle = dlopen(argv[1], RTLD_NOW);
        if (handle == NULL) {
            fprintf(stderr, "dlopen() failed: %s\n", dlerror());
            exit(EXIT_FAILURE);
        }

        /* Discover the size of the buffer that we must pass to
           RTLD_DI_SERINFO.  */

        if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
            fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
            exit(EXIT_FAILURE);
        }

        /* Allocate the buffer for use with RTLD_DI_SERINFO.  */

        sip = malloc(serinfo.dls_size);
        if (sip == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }

        /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly
           allocated buffer.  */

        if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {
            fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
            exit(EXIT_FAILURE);
        }

        /* Fetch and print library search list.  */

        if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {
            fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror());
            exit(EXIT_FAILURE);
        }

        for (size_t j = 0; j < serinfo.dls_cnt; j++)
            printf("dls_serpath[%zu].dls_name = %s\n",
                   j, sip->dls_serpath[j].dls_name);

        exit(EXIT_SUCCESS);
    }

انظر أيضًا
dl_iterate_phdr(3), dladdr(3), dlerror(3), dlopen(3), dlsym(3), ld.so(8)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.