1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
/* Chrysalide - Outil d'analyse de fichiers binaires
* objhole.h - définitions internes pour ll'utilisation d'un espace inutilisé dans la structure GObject
*
* Copyright (C) 2024 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Chrysalide is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _GLIBEXT_OBJHOLE_INT_H
#define _GLIBEXT_OBJHOLE_INT_H
#include "objhole.h"
#include "../common/cpp.h"
/**
* Une structure GObject a la définition suivante :
*
* struct _GObject
* {
* GTypeInstance g_type_instance;
* volatile guint ref_count;
* GData *qdata;
* };
*
* Chaque objet GLib alloué comporte ainsi 4 octets inutilisés :
*
* (gdb) pt /o GObject
* type = struct _GObject {
* / 0 | 8 / GTypeInstance g_type_instance;
* / 8 | 4 / guint ref_count;
* / XXX 4-byte hole /
* / 16 | 8 / GData *qdata;
*
* / total size (bytes): 24 /
* }
*
* La situation n'a pas échappé aux développeurs GLib, avec la définition réelle
* de la structure (cf. https://github.com/GNOME/glib/blob/main/gobject/gobject.c) :
*
* #if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8
* #define HAVE_OPTIONAL_FLAGS
* #endif
*
* typedef struct
* {
* GTypeInstance g_type_instance;
* guint ref_count;
* #ifdef HAVE_OPTIONAL_FLAGS
* guint optional_flags;
* #endif
* GData *qdata;
* } GObjectReal;
*
* G_STATIC_ASSERT(sizeof(GObject) == sizeof(GObjectReal));
* G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, ref_count) == G_STRUCT_OFFSET(GObjectReal, ref_count));
* G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal, qdata));
*
* L'espace entre les deux derniers champs ne peut donc être pleinement exploité deux fois.
*/
/**
* Les bits effectivements utilisés par GLib s'identifie ainsi (02/12/24) :
*
* $ wget -qO /dev/stdout https://raw.githubusercontent.com/GNOME/glib/refs/heads/main/gobject/gobject.c \
* | grep ' * #define OPTIONAL_FLAG_'
* #define OPTIONAL_FLAG_IN_CONSTRUCTION (1 << 0)
* #define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER (1 << 1)
* #define OPTIONAL_FLAG_HAS_NOTIFY_HANDLER (1 << 2)
* #define OPTIONAL_FLAG_LOCK (1 << 3)
* #define OPTIONAL_FLAG_EVER_HAD_WEAK_REF (1 << 4)
*
* Les n premiers bits doivent ainsi être préservés, même s'il est possible de
* partager le bit de verrouilage OPTIONAL_FLAG_LOCK.
*/
#ifndef HAVE_OPTIONAL_FLAGS_IN_GOBJECT
# if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P >= 8
# define HAVE_OPTIONAL_FLAGS_IN_GOBJECT 1
# else
# define HAVE_OPTIONAL_FLAGS_IN_GOBJECT 0
# endif
#endif
/* Nouvelle version dense des objets (instance) */
typedef struct _GThickObject
{
/**
* (cf. structure GObjectReal officielle).
*/
GTypeInstance g_type_instance; /* Type d'objet */
guint ref_count; /* Décompte des références */
#ifdef HAVE_OPTIONAL_FLAGS_IN_GOBJECT
guint extra; /* Zone partagée avec GLib */
#endif
GData *qdata; /* Données complémentaires ? */
#ifndef HAVE_OPTIONAL_FLAGS_IN_GOBJECT
guint extra; /* Zone supplémentaire propre */
#endif
} GThickObject;
/* Nouvelle version dense des objets (classe) */
struct _GThickObjectClass
{
GObjectClass parent; /* A laisser en premier */
};
/**
* Définition du périmètre et des moyens d'accès.
*/
/* GLib 2.83.0 - cfa36f5e9 */
#define GOBJECT_RESERVED_EXTRA_BITS 5
#define GET_GOBJECT_EXTRA(obj, tp) \
({ \
BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \
tp *___result; \
guint __val; \
__val = g_thick_object_get_extra(obj); \
___result = (tp *)(guint []){ __val }; \
___result; \
})
#define SET_GOBJECT_EXTRA(obj, tp, data) \
({ \
BUILD_BUG_ON(sizeof(tp) > sizeof(guint)); \
BUILD_BUG_ON(sizeof(data) > sizeof(guint *)); \
guint __val; \
__val = *(guint *)data; \
g_thick_object_set_extra(obj, __val); \
})
#endif /* _GLIBEXT_OBJHOLE_INT_H */
|