aboutsummaryrefslogtreecommitdiff
path: root/testglue.c
blob: 3d2b272976eb1b6f5fd4fd624450727e9accdb8a (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
#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. */

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

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

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);
  REAL_EXIT (code);
  while (___constval);
}

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