summaryrefslogtreecommitdiff
path: root/testglue.c
blob: 06f4a90fb023ee395338573d29f73981e3013791 (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <stdio.h>
#include <string.h>
#ifndef NO_UNISTD_H
#include <sys/unistd.h>
#endif

/* A simple glue file for embedded targets so we can get the real exit
   status from the program. This assumes we're using GNU ld and can use
   the -wrap option, and that write(1, ...) does something useful. */

/* There is a bunch of weird cruft with #ifdef UNDERSCORES. This is needed
   because currently GNU ld doesn't deal well with a.out targets and
   the -wrap option. When GNU ld is fixed, this should definitely be
   removed. Note that we actually wrap __exit, not _exit on a target
   that has UNDERSCORES defined.  On non-UNDERSCORE targets, we
   wrap _exit separately; it's actually a different function.  */

#ifdef WRAP_M68K_AOUT
#define REAL_EXIT(code) asm ( "trap %0" : : "i" (0) );
#define REAL_ABORT() REAL_EXIT(6)
#define ORIG_EXIT _exit
#define ORIG_ABORT abort
#else
#ifdef UNDERSCORES
#define REAL_EXIT _real___exit
#define REAL_MAIN _real__main
#define REAL_ABORT _real__abort
#define ORIG_EXIT _wrap___exit
#define ORIG_ABORT _wrap__abort
#define ORIG_MAIN _wrap__main
#else
#define REAL_EXIT __real_exit
#ifndef VXWORKS
#define REAL__EXIT __real__exit
#endif
#define REAL_MAIN __real_main
#define REAL_ABORT __real_abort
#define ORIG_EXIT __wrap_exit
#define ORIG__EXIT __wrap__exit
#define ORIG_ABORT __wrap_abort
#define ORIG_MAIN __wrap_main

#endif

extern void abort (void);
extern void exit (int);

#endif

#ifdef REAL_MAIN
extern void REAL_EXIT ();
extern void REAL_ABORT ();
extern int REAL_MAIN (int argc, char **argv, char **envp);
#endif
#ifdef REAL__EXIT
extern void REAL__EXIT ();
#endif

static int done_exit_message = 0;
int ___constval = 1;

#ifdef VXWORKS
static void __runexit();
#endif

static char *
write_int(val, ptr)
     int val;
     char *ptr;
{
  char c;
  if (val<0) {
    *(ptr++) = '-';
    val = -val;
  }
  if (val>9) {
    ptr = write_int (val/10, ptr);
  }
  c = (val%10)+'0';
  *(ptr++) = c;
  return ptr;
}

void
ORIG_EXIT (code)
     int code;
{
  char buf[30];
  char *ptr;

#ifdef VXWORKS
  __runexit ();
#endif
  strcpy (buf, "\n*** EXIT code ");
  ptr = write_int (code, buf + strlen(buf));
  *(ptr++) = '\n';
  write (1, buf, ptr-buf);
  done_exit_message = 1;
  REAL_EXIT (code);
  while (___constval);
}

#ifdef ORIG__EXIT
void
ORIG__EXIT (code)
     int code;
{
  char buf[30];
  char *ptr;

  /* Since exit may call _exit, we need to avoid a second message.  */
  if (! done_exit_message)
    {
      strcpy (buf, "\n*** EXIT code ");
      ptr = write_int (code, buf + strlen(buf));
      *(ptr++) = '\n';
      write (1, buf, ptr-buf);
    }

  REAL__EXIT (code);
  while (___constval);
}
#endif

void
ORIG_ABORT ()
{
  write (1, "\n*** EXIT code 4242\n", 20);
  REAL_ABORT ();
  while (___constval);
  abort ();
}

#ifdef REAL_MAIN
int
ORIG_MAIN (argc, argv, envp)
     int argc;
     char **argv;
     char **envp;
{
#ifdef WRAP_FILE_ARGS
  extern int __argc;
  extern char *__args[];

  exit (REAL_MAIN (__argc,__args,envp));
#else
  exit (REAL_MAIN (argc, argv, envp));
#endif
  while (___constval);
}
#endif

#ifdef VXWORKS
void
_exit (status)
     int status;
{
  REAL_EXIT (status);
}

typedef (*PFV)(void);

static PFV __list[32];
static int __listcnt = 0;
static int __running = 0;

int
atexit (PFV func)
{
  __list[__listcnt++] = func;
}

static void
__runexit ()
{
  int i;
  if (__running++)
    return;

  for (i = 0; i < __listcnt; i++)
    __list[i]();
  __running = 0;
}
#endif