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
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







|
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 -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
#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)



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

struct ObjFWRTBase {
	struct Library library;
	void *seg_list;


	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;

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

FILE *stdout;
FILE *stderr;

__asm__ (
    ".text\n"
    ".globl ___restore_a4\n"

    "___restore_a4:\n"
    "	movea.l	40(a6), a4\n"
    "	rts"
);

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

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

	return data_seg;
}













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->data_seg = get_data_seg();

	return &base->library;
}

static struct Library *
OBJC_M68K_FUNC(lib_open, struct ObjFWRTBase *base OBJC_M68K_REG("a6"))
{
	OBJC_M68K_ARG(struct ObjFWRTBase *, base, REG_A6)







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








	return &base->library;





























}

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






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

	seg_list = base->seg_list;







>
>











>
>

<






|

<



>






>

|



|


|


|




>
>
>
>
>
>
>
>
>
>
>
>











>





|



>
>
>

>
>
>



>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>







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;

	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, *__data_size;


#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	42(a6), a4\n"
    "	rts"
);

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

	__asm__ __volatile__ (
	    "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;
}

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 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
}

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->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->library.lib_OpenCnt == 0 &&
	    (base->library.lib_Flags & LIBF_DELEXP))
		return expunge(base);

	return 0;
}







>
>
>
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>







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]);

		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;
}