Termination Operations

Function exit ends program execution.

ANSI_SYNOPSIS

	#include <stdlib.h>
	void exit(int code);

DESCRIPTION

Use exit to return control from a program to the host operating environment. Use the argument code to pass an exit status to the operating environment: two particular values,EXIT_SUCCESS and EXIT_FAILURE, are defined in <stdlib.h> to indicate success or failure in a portable fashion.

exit does two kinds of cleanup before ending execution of your program. First, it calls all application-defined cleanup functions you have enrolled with atexit. Second, files and streams are cleaned up: any pending output is delivered to the host system, each open file or stream is closed, and files created by tmpfile are deleted.

RETURNS

exit does not return to its caller.

Supporting OS subroutines required: _exit. (see source)

Source: exit.c


#include <stdlib.h>
#include <unistd.h>	/* for _exit() declaration */
#include <reent.h>

#ifndef _REENT_ONLY

/*
 * Exit, flushing stdio buffers if necessary.
 */

void 
_DEFUN (exit, (code),
	int code)
{
  register struct _atexit *p;
  register struct _on_exit_args * args;
  register int n;
  int i;

  p = _GLOBAL_REENT->_atexit;
  while (p)
    {
      args = & p->_on_exit_args;
  
      for (n = p->_ind - 1, i = (n >= 0) ? (1 << n) : 0; n >= 0; --n, i >>= 1)
        if (args->_fntypes & i)
          (*((void (*)(int, void *)) p->_fns[n]))(code, args->_fnargs[n]);
        else
          p->_fns[n] ();

      p = p->_next;
    }

#ifndef WANT_SMALL_STDIO
  if (_GLOBAL_REENT->__cleanup)
    (*_GLOBAL_REENT->__cleanup) (_GLOBAL_REENT);
#endif
  _exit (code);
}

#endif

Disassembly (exit)

000002d8 <exit>:
 2d8:    d0a00217     ldw    r2,-32760(gp)
 2dc:    defff804     addi    sp,sp,-32
 2e0:    dd800015     stw    r22,0(sp)
 2e4:    dfc00715     stw    ra,28(sp)
 2e8:    dc000615     stw    r16,24(sp)
 2ec:    dc400515     stw    r17,20(sp)
 2f0:    dc800415     stw    r18,16(sp)
 2f4:    dcc00315     stw    r19,12(sp)
 2f8:    dd000215     stw    r20,8(sp)
 2fc:    dd400115     stw    r21,4(sp)
 300:    15005217     ldw    r20,328(r2)
 304:    202d883a     mov    r22,r4
 308:    a0002526     beq    r20,zero,3a0 <exit+0xc8>
 30c:    a0800117     ldw    r2,4(r20)
 310:    a5402204     addi    r21,r20,136
 314:    0027883a     mov    r19,zero
 318:    143fffc4     addi    r16,r2,-1
 31c:    8006803a     cmplt    r3,r16,zero
 320:    1800021e     bne    r3,zero,32c <exit+0x54>
 324:    00800044     movi    r2,1
 328:    1426983a     sll    r19,r2,r16
 32c:    1800191e     bne    r3,zero,394 <exit+0xbc>
 330:    800490ba     slli    r2,r16,2
 334:    1025883a     mov    r18,r2
 338:    1505883a     add    r2,r2,r20
 33c:    14400204     addi    r17,r2,8
 340:    00000806     br    364 <exit+0x8c>
 344:    88800017     ldw    r2,0(r17)
 348:    29400017     ldw    r5,0(r5)
 34c:    843fffc4     addi    r16,r16,-1
 350:    94bfff04     addi    r18,r18,-4
 354:    103ee83a     callr    r2
 358:    8c7fff04     addi    r17,r17,-4
 35c:    9827d07a     srai    r19,r19,1
 360:    80000c16     blt    r16,zero,394 <exit+0xbc>
 364:    a8802017     ldw    r2,128(r21)
 368:    954b883a     add    r5,r18,r21
 36c:    b009883a     mov    r4,r22
 370:    14c4703a     and    r2,r2,r19
 374:    103ff31e     bne    r2,zero,344 <exit+0x6c>
 378:    88800017     ldw    r2,0(r17)
 37c:    843fffc4     addi    r16,r16,-1
 380:    94bfff04     addi    r18,r18,-4
 384:    103ee83a     callr    r2
 388:    8c7fff04     addi    r17,r17,-4
 38c:    9827d07a     srai    r19,r19,1
 390:    803ff40e     bge    r16,zero,364 <exit+0x8c>
 394:    a5000017     ldw    r20,0(r20)
 398:    a03fdc1e     bne    r20,zero,30c <exit+0x34>
 39c:    d0a00217     ldw    r2,-32760(gp)
 3a0:    10c00f17     ldw    r3,60(r2)
 3a4:    1800021e     bne    r3,zero,3b0 <exit+0xd8>
 3a8:    b009883a     mov    r4,r22
 3ac:    000045c0     call    45c <_exit>
 3b0:    1009883a     mov    r4,r2
 3b4:    183ee83a     callr    r3
 3b8:    003ffb06     br    3a8 <exit+0xd0>

Simulation (exit)

0x000002d8 <exit>:              0xd0a00217  ldw r2, -32760(gp) [memAddr=0x808 ldData=0x48c dstReg=r2]
0x000002dc <exit+0x4>:          0xdefff804  addi sp, sp, -32 [dstData=0x7fffedc dstReg=sp]
0x000002e0 <exit+0x8>:          0xdd800015  stw r22, 0(sp) [memAddr=0x7fffedc stData=0xdeadbeef]
0x000002e4 <exit+0xc>:          0xdfc00715  stw ra, 28(sp) [memAddr=0x7fffef8 stData=0x2cc]
0x000002e8 <exit+0x10>:         0xdc000615  stw r16, 24(sp) [memAddr=0x7fffef4 stData=0xdeadbeef]
0x000002ec <exit+0x14>:         0xdc400515  stw r17, 20(sp) [memAddr=0x7fffef0 stData=0xdeadbeef]
0x000002f0 <exit+0x18>:         0xdc800415  stw r18, 16(sp) [memAddr=0x7fffeec stData=0xdeadbeef]
0x000002f4 <exit+0x1c>:         0xdcc00315  stw r19, 12(sp) [memAddr=0x7fffee8 stData=0xdeadbeef]
0x000002f8 <exit+0x20>:         0xdd000215  stw r20, 8(sp) [memAddr=0x7fffee4 stData=0xdeadbeef]
0x000002fc <exit+0x24>:         0xdd400115  stw r21, 4(sp) [memAddr=0x7fffee0 stData=0xdeadbeef]
0x00000300 <exit+0x28>:         0x15005217  ldw r20, 328(r2) [memAddr=0x5d4 ldData=0x0 dstReg=r20]
0x00000304 <exit+0x2c>:         0x202d883a  mov r22, r4 [dstData=0x0 dstReg=r22]
0x00000308 <exit+0x30>:         0xa0002526  beq r20, r0, 0x3a0 <exit+0xc8> [passed]
0x000003a0 <exit+0xc8>:         0x10c00f17  ldw r3, 60(r2) [memAddr=0x4c8 ldData=0x0 dstReg=r3]
0x000003a4 <exit+0xcc>:         0x1800021e  bne r3, r0, 0x3b0 <exit+0xd8> [failed]
0x000003a8 <exit+0xd0>:         0xb009883a  mov r4, r22 [dstData=0x0 dstReg=r4]
0x000003ac <exit+0xd4>:         0x000045c0  call 0x45c <_exit> [dstData=0x3b0 dstReg=ra]

Source: nosys_exit.c

extern void _do_dtors (void);
void __fake_fini () { /* Do nothing */ }
void _fini () __attribute__ ((weak, alias ("__fake_fini")));

void
_exit (int exit_code)
{
  _fini ();
    
  /* ??? May want a return to germs (or other) here? */
  __asm__ (
	   "mov\tr2, %0\n"
	   "0:\n"
	   "\tbr\t0b" 
	   :  
	   : "r" (exit_code));
}

Disassembly (_exit)

Note that _exit finishes with an instruction that branches to itself (address 0x474) and therefore never returns.

00000458 <__fake_fini>:
 458:    f800283a     ret

0000045c <_exit>:
 45c:    defffe04     addi    sp,sp,-8
 460:    dc400015     stw    r17,0(sp)
 464:    dfc00115     stw    ra,4(sp)
 468:    2023883a     mov    r17,r4
 46c:    00004580     call    458 <__fake_fini>
 470:    8805883a     mov    r2,r17
 474:    003fff06     br    474 <_exit+0x18>
 478:    dfc00117     ldw    ra,4(sp)
 47c:    dc400017     ldw    r17,0(sp)
 480:    dec00204     addi    sp,sp,8
 484:    f800283a     ret

Simulation (_exit)

0x0000045c <_exit>:             0xdefffe04  addi sp, sp, -8 [dstData=0x7fffed4 dstReg=sp]
0x00000460:    0xdc400015  stw r17, 0(sp) [memAddr=0x7fffed4 stData=0xdeadbeef]
0x00000464:    0xdfc00115  stw ra, 4(sp) [memAddr=0x7fffed8 stData=0x3b0]
0x00000468:    0x2023883a  mov r17, r4 [dstData=0x0 dstReg=r17]
0x0000046c:    0x00004580  call 0x458 <__fake_fini> [dstData=0x470 dstReg=ra]
0x00000458 <__fake_fini>:       0xf800283a  ret [targetPcb=0x470]
0x00000470:    0x8805883a  mov r2, r17 [dstData=0x0 dstReg=r2]
0x00000474:    0x003fff06  br 0x474


Maintained by John Loomis, last updated 6 April 2007