Skip to content

Commit c94aadf

Browse files
authored
Add runtime relocation in dynamic linking and revert workarounds (#35)
Co-authored-by: Evgeny Karpov <[email protected]>
1 parent 87fd50f commit c94aadf

File tree

9 files changed

+35
-44
lines changed

9 files changed

+35
-44
lines changed

winsup/cygwin/pseudo-reloc.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ do_pseudo_reloc (void * start, void * end, void * base)
199199
ptrdiff_t reloc_target = (ptrdiff_t) ((char *)end - (char*)start);
200200
runtime_pseudo_reloc_v2 *v2_hdr = (runtime_pseudo_reloc_v2 *) start;
201201
runtime_pseudo_reloc_item_v2 *r;
202+
#ifdef __aarch64__
203+
uint32_t opcode;
204+
#endif
202205

203206
/* A valid relocation list will contain at least one entry, and
204207
* one v1 data structure (the smallest one) requires two DWORDs.
@@ -307,6 +310,13 @@ do_pseudo_reloc (void * start, void * end, void * base)
307310
if ((reldata & 0x8000) != 0)
308311
reldata |= ~((ptrdiff_t) 0xffff);
309312
break;
313+
#ifdef __aarch64__
314+
case 12:
315+
case 21:
316+
opcode = (*((unsigned int *)reloc_target));
317+
reldata = 0;
318+
break;
319+
#endif
310320
case 32:
311321
reldata = (ptrdiff_t) (*((unsigned int *)reloc_target));
312322
#if defined (__x86_64__) || defined (_WIN64)
@@ -339,6 +349,31 @@ do_pseudo_reloc (void * start, void * end, void * base)
339349
case 16:
340350
__write_memory ((void *) reloc_target, &reldata, 2);
341351
break;
352+
#ifdef __aarch64__
353+
case 12:
354+
/* Replace add Xn, Xn, :lo12:label with ldr Xn, [Xn, :lo12:__imp__func].
355+
That loads the address of _func into Xn. */
356+
opcode = 0xf9400000 | (opcode & 0x3ff); // ldr
357+
reldata = ((ptrdiff_t) base + r->sym) & ((1 << 12) - 1);
358+
reldata >>= 3;
359+
opcode |= reldata << 10;
360+
__write_memory ((void *) reloc_target, &opcode, 4);
361+
break;
362+
case 21:
363+
/* Replace adrp Xn, label with adrp Xn, __imp__func. */
364+
opcode &= 0x9f00001f;
365+
reldata = (((ptrdiff_t) base + r->sym) >> 12)
366+
- (((ptrdiff_t) base + r->target) >> 12);
367+
reldata &= (1 << 21) - 1;
368+
opcode |= (reldata & 3) << 29;
369+
reldata >>= 2;
370+
opcode |= reldata << 5;
371+
__write_memory ((void *) reloc_target, &opcode, 4);
372+
break;
373+
/* A note regarding 26 bits relocation.
374+
A single opcode is not sufficient for 26 bits relocation in dynamic linking.
375+
The linker generates a jump stub instead. */
376+
#endif
342377
case 32:
343378
#if defined (__CYGWIN__) && defined (__x86_64__)
344379
if (reldata > (ptrdiff_t) __INT32_MAX__

winsup/testsuite/winsup.api/ltp/execle01.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,6 @@ int exp_enos[]={0, 0}; /* Zero terminated list of expected errnos */
133133

134134
int pid; /* process id from fork */
135135
int status; /* status returned from waitpid */
136-
137-
#if defined(__aarch64__)
138-
__attribute__((dllimport)) /* workaround for large relocation issue in binutils */
139-
#endif
140136
extern char **environ; /* pointer to this processes env, to pass along */
141137

142138
int

winsup/testsuite/winsup.api/ltp/execve01.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,6 @@ int exp_enos[]={0, 0}; /* Zero terminated list of expected errnos */
134134
int pid; /* process id from fork */
135135
int status; /* status returned from waitpid */
136136
char *const args[2]={"/usr/bin/test", 0}; /* argument list for execve call */
137-
138-
#if defined(__aarch64__)
139-
__attribute__((dllimport)) /* workaround for large relocation issue in binutils */
140-
#endif
141137
extern char **environ; /* pointer to this processes env, to pass along */
142138

143139
int

winsup/testsuite/winsup.api/posix_spawn/chdir.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
#include <string.h>
88
#include <unistd.h>
99

10-
/* Workaround for large relocation issue in binutils. */
11-
#if defined(__aarch64__)
12-
__attribute__((dllimport))
13-
extern char **environ;
14-
#endif
15-
1610
/* Linux is behind the times a bit (also needs the *chdir_np functions) */
1711
#ifndef O_SEARCH
1812
# define O_SEARCH O_PATH

winsup/testsuite/winsup.api/posix_spawn/errors.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
#include <sys/stat.h>
77
#include <unistd.h>
88

9-
/* Workaround for large relocation issue in binutils. */
10-
#if defined(__aarch64__)
11-
__attribute__((dllimport))
12-
extern char **environ;
13-
#endif
14-
159
static char tmppath[] = "pspawn.XXXXXX";
1610
static const char exit0[] = "exit 0\n";
1711

winsup/testsuite/winsup.api/posix_spawn/fds.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
#include <string.h>
88
#include <unistd.h>
99

10-
/* Workaround for large relocation issue in binutils. */
11-
#if defined(__aarch64__)
12-
__attribute__((dllimport))
13-
extern char **environ;
14-
#endif
15-
1610
int handle_child (char *devfd, char *target)
1711
{
1812
char buf[PATH_MAX];

winsup/testsuite/winsup.api/posix_spawn/signals.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
#include <string.h>
77
#include <unistd.h>
88

9-
/* Workaround for large relocation issue in binutils. */
10-
#if defined(__aarch64__)
11-
__attribute__((dllimport))
12-
extern char **environ;
13-
#endif
14-
159
int handle_child (char *arg)
1610
{
1711
struct sigaction sa;

winsup/testsuite/winsup.api/posix_spawn/win32.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,6 @@
99
#include <sys/cygwin.h>
1010
#include <unistd.h>
1111

12-
/* Workaround for large relocation issue in binutils. */
13-
#if defined(__aarch64__)
14-
__attribute__((dllimport))
15-
extern char **environ;
16-
#endif
17-
1812
char * find_winchild (void)
1913
{
2014
static const char winchild[] = "/winchild";

winsup/utils/newgrp.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ details. */
2525

2626
#define PATH_PREFIX "PATH=/usr/bin:"
2727

28-
/* Workaround for large relocation issue in binutils. */
29-
#if defined(__aarch64__)
30-
__attribute__((dllimport))
31-
extern char **environ;
32-
#endif
33-
3428
char *
3529
create_env_var (const char *name, const char *val)
3630
{

0 commit comments

Comments
 (0)