xfree86/loader: Apply unloadsubmodule gentoo patch

See: https://github.com/gentoo/gentoo/blob/master/x11-base/xorg-server/files/xorg-server-1.12-unloadsubmodule.patch
See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=686152#14

Verbatim copy of https://github.com/X11Libre/xserver/issues/319#issuecomment-3033729517 ,which gives more context for this patch:

I took a closer look at that patch.
It is logically equivalent to:
```
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index 2cdf91fd2..49785fdc8 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -885,6 +885,7 @@ RemoveChild(ModuleDescPtr child)
     parent = child->parent;
     if (parent->child == child) {
         parent->child = child->sib;
+        child->sib = NULL;
         return;
     }
```
RemoveChild is a static function that is only called in UnloadSubModule:
```
void
UnloadSubModule(ModuleDescPtr mod)
{
    /* Some drivers are calling us on built-in submodules, ignore them */
    if (mod == (ModuleDescPtr) 1)
        return;
    RemoveChild(mod);
    UnloadModule(mod);
}
```
Whether or not child->sib is NULL tells UnloadModule if it should recursively unload child->sib or not:
```
    if (mod->child)
        UnloadModule(mod->child);
    if (mod->sib)
        UnloadModule(mod->sib);
    free(mod);
```
Looking at the source, the module loader uses some weird kind of tree-like structure,
where every node has at most one child and one sibling (but then, if foo has child bar, and bar has sibling baz, shouldn't baz also be foo's child?).
```
typedef struct module_desc {
    struct module_desc *child;
    struct module_desc *sib;
    struct module_desc *parent;
    void *handle;
    ModuleSetupProc SetupProc;
    ModuleTearDownProc TearDownProc;
    void *TearDownData;         /* returned from SetupProc */
    const XF86ModuleVersionInfo *VersionInfo;
} ModuleDesc, *ModuleDescPtr;
```

All in all, this patch makes UnloadSubModule to never unload the sibling of the unloaded module, whereas
as it is now, UnloadSubModule would also unload the module's sibling if `child->parent == child->parent->child`
(master child?).

I don't see how this patch changed the behavior on ia64, or any other arch.

@metux Could you tell me what kind of data structure this is, and whether or not this patch is right?

Fixes: https://github.com/X11Libre/xserver/issues/319

Signed-off-by: stefan11111 <stefan11111@shitposting.expert>
This commit is contained in:
stefan11111
2025-11-02 03:54:14 +02:00
committed by Enrico Weigelt
parent 7468cd4ee0
commit 0e851b9710

View File

@@ -883,6 +883,7 @@ RemoveChild(ModuleDescPtr child)
parent = child->parent;
if (parent->child == child) {
parent->child = child->sib;
child->sib = NULL;
return;
}