ObjFW  Check-in [2376865a0f]

Overview
Comment:runtime: Support to open Amiga lib multiple times
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2376865a0f8c6947720b6dd87d4545ed6d01f691a955969c7fde78a23f1054b2
User & Date: js on 2018-05-11 17:59:49
Other Links: manifest | tags
Context
2018-05-11
19:42
runtime: Let objc_init() take a version number check-in: c5c95f9fe2 user: js tags: trunk
17:59
runtime: Support to open Amiga lib multiple times check-in: 2376865a0f user: js tags: trunk
2018-05-06
21:39
runtime: Make Amiga library work with -fbaserel check-in: 482698c5be user: js tags: trunk
Changes

Modified src/runtime/Makefile from [846f7565d8] to [a15409d34a].

57
58
59
60
61
62
63
64

57
58
59
60
61
62
63

64







-
+
AMIGA_LIB_CFLAGS += -DOBJC_COMPILING_AMIGA_LIBRARY
LD = ${OBJC}
FRAMEWORK_LIBS = ${LIBS}

# For 68000, GCC emits calls to helper functions that expect a4 to be set.
# Remove this once the library is using -fbaserel.
AMIGA_LIB_CFLAGS += -mcpu=68020 -fbaserel
AMIGA_LIB_LDFLAGS += -mcpu=68020 -fbaserel -nostdlib -lnix
AMIGA_LIB_LDFLAGS += -mcpu=68020 -fbaserel -resident

Modified src/runtime/amiga-library.m from [7a454ada46] to [c1362b9b23].

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
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184







+
+











+
+

-






-
+

-



+






+

-
+



-
+


-
+


-
+




+
+
+
+
+
+
+
+
+
+
+
+











+





-
+



+
+
+

+
+
+



+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






+
+
+
+
+







#include <exec/nodes.h>
#include <exec/resident.h>
#include <proto/exec.h>

#define CONCAT_VERSION2(major, minor) #major "." #minor
#define CONCAT_VERSION(major, minor) CONCAT_VERSION2(major, minor)
#define VERSION_STRING CONCAT_VERSION(OBJFW_RT_LIB_MAJOR, OBJFW_RT_LIB_MINOR)

#define DATA_OFFSET 0x7FFE

/* This always needs to be the first thing in the file. */
int
_start()
{
	return -1;
}

struct ObjFWRTBase {
	struct Library library;
	void *seg_list;
	struct ObjFWRTBase *parent;
	char *data_seg;
	bool initialized;
	void *data_seg;
	struct objc_libc libc;
};

extern uintptr_t __CTOR_LIST__[], __DTOR_LIST__[];
extern const void *_EH_FRAME_BEGINS__;
extern void *_EH_FRAME_OBJECTS__;
extern void *__a4_init;
extern void *__a4_init, *__data_size;

struct ExecBase *SysBase;
#ifdef OF_MORPHOS
const ULONG __abox__ = 1;
#endif
struct ExecBase *SysBase;
FILE *stdout;
FILE *stderr;

__asm__ (
    ".text\n"
    ".globl ___restore_a4\n"
    ".align 1\n"
    "___restore_a4:\n"
    "	movea.l	40(a6), a4\n"
    "	movea.l	42(a6), a4\n"
    "	rts"
);

static OF_INLINE void *
static OF_INLINE char *
get_data_seg(void)
{
	void *data_seg;
	char *data_seg;

	__asm__ __volatile__ (
	    "lea.l	___a4_init, %0" : "=a"(data_seg)
	    "move.l	#___a4_init, %0" : "=r"(data_seg)
	);

	return data_seg;
}

static OF_INLINE size_t *
get_datadata_relocs(void)
{
	size_t *datadata_relocs;

	__asm__ __volatile__ (
	    "move.l	#___datadata_relocs, %0" : "=r"(datadata_relocs)
	);

	return datadata_relocs;
}

static struct Library *
lib_init(struct ExecBase *sys_base OBJC_M68K_REG("a6"),
    void *seg_list OBJC_M68K_REG("a0"),
    struct ObjFWRTBase *base OBJC_M68K_REG("d0"))
{
	__asm__ __volatile__ (
	    "move.l	a6, _SysBase" :: "a"(sys_base)
	);

	base->seg_list = seg_list;
	base->parent = NULL;
	base->data_seg = get_data_seg();

	return &base->library;
}

static struct Library *
struct Library *__saveds
OBJC_M68K_FUNC(lib_open, struct ObjFWRTBase *base OBJC_M68K_REG("a6"))
{
	OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6)
	struct ObjFWRTBase *child;
	size_t data_size, *datadata_relocs;
	ptrdiff_t displacement;

	if (base->parent != NULL)
		return NULL;

	base->library.lib_OpenCnt++;
	base->library.lib_Flags &= ~LIBF_DELEXP;

	/*
	 * We cannot use malloc here, as that depends on the libc passed from
	 * the application.
	 */
	if ((child = AllocMem(base->library.lib_NegSize +
	    base->library.lib_PosSize, MEMF_ANY)) == NULL) {
		base->library.lib_OpenCnt--;
	return &base->library;
		return NULL;
	}

	memcpy(child, (char *)base - base->library.lib_NegSize,
	    base->library.lib_NegSize + base->library.lib_PosSize);

	child = (struct ObjFWRTBase *)
	    ((char *)child + base->library.lib_NegSize);
	child->library.lib_OpenCnt = 1;
	child->parent = base;

	data_size = (uintptr_t)&__data_size -
	    ((uintptr_t)&__a4_init - DATA_OFFSET);

	if ((child->data_seg = AllocMem(data_size, MEMF_ANY)) == NULL) {
		base->library.lib_OpenCnt--;
		return NULL;
	}

	memcpy(child->data_seg, base->data_seg - DATA_OFFSET, data_size);

	datadata_relocs = get_datadata_relocs();
	displacement = child->data_seg - (base->data_seg - DATA_OFFSET);

	for (size_t i = 1; i <= datadata_relocs[0]; i++)
		*(long *)(child->data_seg + datadata_relocs[i]) += displacement;

	child->data_seg += DATA_OFFSET;

	return &child->library;
}

static void *
expunge(struct ObjFWRTBase *base)
{
	void *seg_list;

	if (base->parent != NULL) {
		base->parent->library.lib_Flags |= LIBF_DELEXP;
		return 0;
	}

	if (base->library.lib_OpenCnt > 0) {
		base->library.lib_Flags |= LIBF_DELEXP;
		return 0;
	}

	seg_list = base->seg_list;
135
136
137
138
139
140
141



142
143
144
145
146















147
148
149
150
151
152
153
199
200
201
202
203
204
205
206
207
208





209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230







+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







}

static void *__saveds
OBJC_M68K_FUNC(lib_close, struct ObjFWRTBase *base OBJC_M68K_REG("a6"))
{
	OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6)

	if (base->parent != NULL) {
		struct ObjFWRTBase *parent;

	if (base->initialized &&
	    (size_t)_EH_FRAME_BEGINS__ == (size_t)_EH_FRAME_OBJECTS__)
		for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++)
			base->libc.__deregister_frame_info(
			    (&_EH_FRAME_BEGINS__)[i]);
		if (base->initialized &&
		    (size_t)_EH_FRAME_BEGINS__ == (size_t)_EH_FRAME_OBJECTS__)
			for (size_t i = 1; i <= (size_t)_EH_FRAME_BEGINS__; i++)
				base->libc.__deregister_frame_info(
				    (&_EH_FRAME_BEGINS__)[i]);

		parent = base->parent;

		FreeMem(base->data_seg - DATA_OFFSET, (uintptr_t)&__data_size -
		    ((uintptr_t)&__a4_init - DATA_OFFSET));
		FreeMem((char *)base - base->library.lib_NegSize,
		    base->library.lib_NegSize + base->library.lib_PosSize);

		base = parent;
	}

	if (--base->library.lib_OpenCnt == 0 &&
	    (base->library.lib_Flags & LIBF_DELEXP))
		return expunge(base);

	return 0;
}