Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
fac95383
Commit
fac95383
authored
Aug 30, 1996
by
Stan Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial revision
From-SVN: r12679
parent
abf3bf38
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
562 additions
and
0 deletions
+562
-0
gcc/config/i386/gmon-sol2.c
+402
-0
gcc/config/i386/sol2-gc1.asm
+160
-0
No files found.
gcc/config/i386/gmon-sol2.c
0 → 100644
View file @
fac95383
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Re rework of the solaris 2 version of gmon by J.W.Hawtin 12/8/1996
* Does not work right yet.
*/
/*
* This is a modified gmon.c by J.W.Hawtin <J.W.Hawtin@lboro.ac.uk>,
* 14/8/96 based on the original gmon.c in GCC and the hacked version
* solaris 2 sparc version (config/sparc/gmon-sol.c) by Mark Eichin. To do
* process profiling on solaris 2.4 X86
*
* It must be used in conjunction with sol2-gc1.asm, which is used to start
* and stop process monitoring.
*
* Differences.
*
* On Solaris 2 _mcount is called my library functions not mcount, so support
* has been added for both.
*
* Also the prototype for profil() is different
*
* Solaris 2 does not seem to have char *minbrk whcih allows the setting of
* the minimum SBRK region so this code has been removed and lets pray malloc
* does not mess it up.
*
* Notes
*
* This code could easily be integrated with the orginal gmon.c and perhaps
* should be.
*/
#ifndef lint
static
char
sccsid
[]
=
"@(#)gmon.c 5.3 (Berkeley) 5/22/91"
;
#endif
/* not lint */
#if 0
#include <unistd.h>
#endif
#ifdef DEBUG
#include <stdio.h>
#endif
#if 0
#include "i386/gmon.h"
#else
struct
phdr
{
char
*
lpc
;
char
*
hpc
;
int
ncnt
;
};
#define HISTFRACTION 2
#define HISTCOUNTER unsigned short
#define HASHFRACTION 1
#define ARCDENSITY 2
#define MINARCS 50
#define BASEADDRESS 0x8000000
/* On Solaris 2 X86 all excutables start here
and not at 0 */
struct
tostruct
{
char
*
selfpc
;
long
count
;
unsigned
short
link
;
};
struct
rawarc
{
unsigned
long
raw_frompc
;
unsigned
long
raw_selfpc
;
long
raw_count
;
};
#define ROUNDDOWN(x,y) (((x)/(y))*(y))
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
#endif
/* char *minbrk; */
#ifdef __alpha
extern
char
*
sbrk
();
#endif
/*
* froms is actually a bunch of unsigned shorts indexing tos
*/
static
int
profiling
=
3
;
static
unsigned
short
*
froms
;
static
struct
tostruct
*
tos
=
0
;
static
long
tolimit
=
0
;
static
char
*
s_lowpc
=
0
;
static
char
*
s_highpc
=
0
;
static
unsigned
long
s_textsize
=
0
;
static
int
ssiz
;
static
char
*
sbuf
;
static
int
s_scale
;
/* see profil(2) where this is describe (incorrectly) */
#define SCALE_1_TO_1 0x10000L
#define MSG "No space for profiling buffer(s)\n"
extern
int
errno
;
monstartup
(
lowpc
,
highpc
)
char
*
lowpc
;
char
*
highpc
;
{
int
monsize
;
char
*
buffer
;
register
int
o
;
/*
* round lowpc and highpc to multiples of the density we're using
* so the rest of the scaling (here and in gprof) stays in ints.
*/
lowpc
=
(
char
*
)
ROUNDDOWN
((
unsigned
)
lowpc
,
HISTFRACTION
*
sizeof
(
HISTCOUNTER
));
s_lowpc
=
lowpc
;
highpc
=
(
char
*
)
ROUNDUP
((
unsigned
)
highpc
,
HISTFRACTION
*
sizeof
(
HISTCOUNTER
));
s_highpc
=
highpc
;
s_textsize
=
highpc
-
lowpc
;
monsize
=
(
s_textsize
/
HISTFRACTION
)
+
sizeof
(
struct
phdr
);
buffer
=
(
char
*
)
sbrk
(
monsize
);
if
(
buffer
==
(
char
*
)
-
1
)
{
write
(
2
,
MSG
,
sizeof
(
MSG
)
);
return
;
}
froms
=
(
unsigned
short
*
)
sbrk
(
s_textsize
/
HASHFRACTION
);
if
(
froms
==
(
unsigned
short
*
)
-
1
)
{
write
(
2
,
MSG
,
sizeof
(
MSG
)
);
froms
=
0
;
return
;
}
tolimit
=
s_textsize
*
ARCDENSITY
/
100
;
if
(
tolimit
<
MINARCS
)
{
tolimit
=
MINARCS
;
}
else
if
(
tolimit
>
65534
)
{
tolimit
=
65534
;
}
tos
=
(
struct
tostruct
*
)
sbrk
(
tolimit
*
sizeof
(
struct
tostruct
)
);
if
(
tos
==
(
struct
tostruct
*
)
-
1
)
{
write
(
2
,
MSG
,
sizeof
(
MSG
)
);
froms
=
0
;
tos
=
0
;
return
;
}
/* minbrk = (char *) sbrk(0);*/
tos
[
0
].
link
=
0
;
sbuf
=
buffer
;
ssiz
=
monsize
;
(
(
struct
phdr
*
)
buffer
)
->
lpc
=
lowpc
;
(
(
struct
phdr
*
)
buffer
)
->
hpc
=
highpc
;
(
(
struct
phdr
*
)
buffer
)
->
ncnt
=
ssiz
;
monsize
-=
sizeof
(
struct
phdr
);
if
(
monsize
<=
0
)
return
;
o
=
highpc
-
lowpc
;
if
(
monsize
<
o
)
#ifndef hp300
s_scale
=
(
(
float
)
monsize
/
o
)
*
SCALE_1_TO_1
;
#else
/* avoid floating point */
{
int
quot
=
o
/
monsize
;
if
(
quot
>=
0x10000
)
s_scale
=
1
;
else
if
(
quot
>=
0x100
)
s_scale
=
0x10000
/
quot
;
else
if
(
o
>=
0x800000
)
s_scale
=
0x1000000
/
(
o
/
(
monsize
>>
8
));
else
s_scale
=
0x1000000
/
((
o
<<
8
)
/
monsize
);
}
#endif
else
s_scale
=
SCALE_1_TO_1
;
moncontrol
(
1
);
}
_mcleanup
()
{
int
fd
;
int
fromindex
;
int
endfrom
;
char
*
frompc
;
int
toindex
;
struct
rawarc
rawarc
;
moncontrol
(
0
);
fd
=
creat
(
"gmon.out"
,
0666
);
if
(
fd
<
0
)
{
perror
(
"mcount: gmon.out"
);
return
;
}
# ifdef DEBUG
fprintf
(
stderr
,
"[mcleanup] sbuf 0x%x ssiz %d
\n
"
,
sbuf
,
ssiz
);
# endif DEBUG
write
(
fd
,
sbuf
,
ssiz
);
endfrom
=
s_textsize
/
(
HASHFRACTION
*
sizeof
(
*
froms
));
for
(
fromindex
=
0
;
fromindex
<
endfrom
;
fromindex
++
)
{
if
(
froms
[
fromindex
]
==
0
)
{
continue
;
}
frompc
=
s_lowpc
+
(
fromindex
*
HASHFRACTION
*
sizeof
(
*
froms
));
for
(
toindex
=
froms
[
fromindex
];
toindex
!=
0
;
toindex
=
tos
[
toindex
].
link
)
{
# ifdef DEBUG
fprintf
(
stderr
,
"[mcleanup] frompc 0x%x selfpc 0x%x count %d
\n
"
,
frompc
,
tos
[
toindex
].
selfpc
,
tos
[
toindex
].
count
);
# endif DEBUG
rawarc
.
raw_frompc
=
(
unsigned
long
)
frompc
;
rawarc
.
raw_selfpc
=
(
unsigned
long
)
tos
[
toindex
].
selfpc
;
rawarc
.
raw_count
=
tos
[
toindex
].
count
;
write
(
fd
,
&
rawarc
,
sizeof
rawarc
);
}
}
close
(
fd
);
}
/* Solaris 2 libraries use _mcount. */
asm
(
".globl _mcount; _mcount: jmp internal_mcount"
);
/* This is for compatibility with old versions of gcc which used mcount. */
asm
(
".globl mcount; mcount: jmp internal_mcount"
);
internal_mcount
()
{
register
char
*
selfpc
;
register
unsigned
short
*
frompcindex
;
register
struct
tostruct
*
top
;
register
struct
tostruct
*
prevtop
;
register
long
toindex
;
/*
* find the return address for mcount,
* and the return address for mcount's caller.
*/
/* selfpc = pc pushed by mcount call.
This identifies the function that was just entered. */
selfpc
=
(
void
*
)
__builtin_return_address
(
0
);
/* frompcindex = pc in preceding frame.
This identifies the caller of the function just entered. */
frompcindex
=
(
void
*
)
__builtin_return_address
(
1
);
/*
* check that we are profiling
* and that we aren't recursively invoked.
*/
if
(
profiling
)
{
goto
out
;
}
profiling
++
;
/*
* check that frompcindex is a reasonable pc value.
* for example: signal catchers get called from the stack,
* not from text space. too bad.
*/
frompcindex
=
(
unsigned
short
*
)((
long
)
frompcindex
-
(
long
)
s_lowpc
);
if
((
unsigned
long
)
frompcindex
>
s_textsize
)
{
goto
done
;
}
frompcindex
=
&
froms
[((
long
)
frompcindex
)
/
(
HASHFRACTION
*
sizeof
(
*
froms
))];
toindex
=
*
frompcindex
;
if
(
toindex
==
0
)
{
/*
* first time traversing this arc
*/
toindex
=
++
tos
[
0
].
link
;
if
(
toindex
>=
tolimit
)
{
goto
overflow
;
}
*
frompcindex
=
toindex
;
top
=
&
tos
[
toindex
];
top
->
selfpc
=
selfpc
;
top
->
count
=
1
;
top
->
link
=
0
;
goto
done
;
}
top
=
&
tos
[
toindex
];
if
(
top
->
selfpc
==
selfpc
)
{
/*
* arc at front of chain; usual case.
*/
top
->
count
++
;
goto
done
;
}
/*
* have to go looking down chain for it.
* top points to what we are looking at,
* prevtop points to previous top.
* we know it is not at the head of the chain.
*/
for
(;
/* goto done */
;
)
{
if
(
top
->
link
==
0
)
{
/*
* top is end of the chain and none of the chain
* had top->selfpc == selfpc.
* so we allocate a new tostruct
* and link it to the head of the chain.
*/
toindex
=
++
tos
[
0
].
link
;
if
(
toindex
>=
tolimit
)
{
goto
overflow
;
}
top
=
&
tos
[
toindex
];
top
->
selfpc
=
selfpc
;
top
->
count
=
1
;
top
->
link
=
*
frompcindex
;
*
frompcindex
=
toindex
;
goto
done
;
}
/*
* otherwise, check the next arc on the chain.
*/
prevtop
=
top
;
top
=
&
tos
[
top
->
link
];
if
(
top
->
selfpc
==
selfpc
)
{
/*
* there it is.
* increment its count
* move it to the head of the chain.
*/
top
->
count
++
;
toindex
=
prevtop
->
link
;
prevtop
->
link
=
top
->
link
;
top
->
link
=
*
frompcindex
;
*
frompcindex
=
toindex
;
goto
done
;
}
}
done
:
profiling
--
;
/* and fall through */
out
:
return
;
/* normal return restores saved registers */
overflow
:
profiling
++
;
/* halt further profiling */
# define TOLIMIT "mcount: tos overflow\n"
write
(
2
,
TOLIMIT
,
sizeof
(
TOLIMIT
));
goto
out
;
}
/*
* Control profiling
* profiling is what mcount checks to see if
* all the data structures are ready.
*/
moncontrol
(
mode
)
int
mode
;
{
if
(
mode
)
{
/* start */
profil
((
unsigned
short
*
)(
sbuf
+
sizeof
(
struct
phdr
)),
ssiz
-
sizeof
(
struct
phdr
),
(
int
)
s_lowpc
,
s_scale
);
profiling
=
0
;
}
else
{
/* stop */
profil
((
unsigned
short
*
)
0
,
0
,
0
,
0
);
profiling
=
3
;
}
}
gcc/config/i386/sol2-gc1.asm
0 → 100644
View file @
fac95383
!
gcrt1
.
s
for
Solaris
2
,
x86
!
Copyright
(
C
)
1993
Free
Software
Foundation
,
Inc
.
!
Written
By
Fred
Fish
,
Nov
1992
!
!
This
file
is
free
software
; you can redistribute it and/or modify it
!
under
the
terms
of
the
GNU
General
Public
License
as
published
by
the
!
Free
Software
Foundation
; either version 2, or (at your option) any
!
later
version
.
!
!
In
addition
to
the
permissions
in
the
GNU
General
Public
License
,
the
!
Free
Software
Foundation
gives
you
unlimited
permission
to
link
the
!
compiled
version
of
this
file
with
other
programs
,
and
to
distribute
!
those
programs
without
any
restriction
coming
from
the
use
of
this
!
file
.
(
The
General
Public
License
restrictions
do
apply
in
other
!
respects
; for example, they cover modification of the file, and
!
distribution
when
not
linked
into
another
program
.)
!
!
This
file
is
distributed
in
the
hope
that
it
will
be
useful
,
but
!
WITHOUT
ANY
WARRANTY
; without even the implied warranty of
!
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
GNU
!
General
Public
License
for
more
details
.
!
!
You
should
have
received
a
copy
of
the
GNU
General
Public
License
!
along
with
this
program
; see the file COPYING. If not, write to
!
the
Free
Software
Foundation
,
59
Temple
Place
-
Suite
330
,
!
Boston
,
MA
02111
-
1307
,
USA
.
!
!
As
a
special
exception
,
if
you
link
this
library
with
files
!
compiled
with
GCC
to
produce
an
executable
,
this
does
not
cause
!
the
resulting
executable
to
be
covered
by
the
GNU
General
Public
License
.
!
This
exception
does
not
however
invalidate
any
other
reasons
why
!
the
executable
file
might
be
covered
by
the
GNU
General
Public
License
.
!
!
This
file
takes
control
of
the
process
from
the
kernel
,
as
specified
!
in
section
3
of
the
System
V
Application
Binary
Interface
,
Intel386
!
Processor
Supplement
.
It
has
been
constructed
from
information
obtained
!
from
the
ABI
,
information
obtained
from
single
stepping
existing
!
Solaris
executables
through
their
startup
code
with
gdb
,
and
from
!
information
obtained
by
single
stepping
executables
on
other
i386
SVR4
!
implementations
.
This
file
is
the
first
thing
linked
into
any
executable
.
!
This
is
a
modified
crt1
.
s
by
J
.
W
.
Hawtin
<
J
.
W
.
Hawtin
@
lboro
.
ac
.
uk
>
15
/
8
/
96
,
!
to
allow
program
profiling
,
by
calling
monstartup
on
entry
and
_mcleanup
!
on
exit
.
file
"gcrt1.s"
.
ident
"GNU C gcrt1.s"
.
weak
_DYNAMIC
.
text
!
Start
creating
the
initial
frame
by
pushing
a
NULL
value
for
the
return
!
address
of
the
initial
frame
,
and
mark
the
end
of
the
stack
frame
chain
!
(
the
innermost
stack
frame
)
with
a
NULL
value
,
per
page
3
-
32
of
the
ABI
.
!
Initialize
the
first
stack
frame
pointer
in
%
ebp
(
the
contents
of
which
!
are
unspecified
at
process
initialization
).
.
globl
_start
_start
:
pushl
$
0x0
pushl
$
0x0
movl
%
esp
,
%
ebp
!
As
specified
per
page
3
-
32
of
the
ABI
,
%
edx
contains
a
function
!
pointer
that
should
be
registered
with
atexit
(),
for
proper
!
shared
object
termination
.
Just
push
it
onto
the
stack
for
now
!
to
preserve
it
.
We
want
to
register
_cleanup
()
first
.
pushl
%
edx
!
Check
to
see
if
there
is
an
_cleanup
()
function
linked
in
,
and
if
!
so
,
register
it
with
atexit
()
as
the
last
thing
to
be
run
by
!
atexit
().
movl
$
_mcleanup
,
%
eax
testl
%
eax
,
%
eax
je
.
L1
pushl
$
_mcleanup
call
atexit
addl
$
0x4
,
%
esp
.
L1
:
!
Now
check
to
see
if
we
have
an
_DYNAMIC
table
,
and
if
so
then
!
we
need
to
register
the
function
pointer
previously
in
%
edx
,
but
!
now
conveniently
saved
on
the
stack
as
the
argument
to
pass
to
!
atexit
().
movl
$
_DYNAMIC
,
%
eax
testl
%
eax
,
%
eax
je
.
L2
call
atexit
.
L2
:
!
Register
_fini
()
with
atexit
().
We
will
take
care
of
calling
_init
()
!
directly
.
pushl
$
_fini
call
atexit
!
Start
profiling
pushl
%
ebp
movl
%
esp
,
%
ebp
pushl
$
_etext
pushl
$
_start
call
monstartup
addl
$
8
,
%
esp
popl
%
ebp
!
Compute
the
address
of
the
environment
vector
on
the
stack
and
load
!
it
into
the
global
variable
_environ
.
Currently
argc
is
at
8
off
!
the
frame
pointer
.
Fetch
the
argument
count
into
%
eax
,
scale
by
the
!
size
of
each
arg
(
4
bytes
)
and
compute
the
address
of
the
environment
!
vector
which
is
16
bytes
(
the
two
zero
words
we
pushed
,
plus
argc
,
!
plus
the
null
word
terminating
the
arg
vector
)
further
up
the
stack
,
!
off
the
frame
pointer
(
whew
!
).
movl
8
(
%
ebp
),
%
eax
leal
16
(
%
ebp
,
%
eax
,
4
),
%
edx
movl
%
edx
,
_environ
!
Push
the
environment
vector
pointer
,
the
argument
vector
pointer
,
!
and
the
argument
count
on
to
the
stack
to
set
up
the
arguments
!
for
_init
(),
_fpstart
(),
and
main
().
Note
that
the
environment
!
vector
pointer
and
the
arg
count
were
previously
loaded
into
!
%
edx
and
%
eax
respectively
.
The
only
new
value
we
need
to
compute
!
is
the
argument
vector
pointer
,
which
is
at
a
fixed
address
off
!
the
initial
frame
pointer
.
pushl
%
edx
leal
12
(
%
ebp
),
%
edx
pushl
%
edx
pushl
%
eax
!
Call
_init
(
argc
,
argv
,
environ
),
_fpstart
(
argc
,
argv
,
environ
),
and
!
main
(
argc
,
argv
,
environ
).
call
_init
call
__fpstart
call
main
!
Pop
the
argc
,
argv
,
and
environ
arguments
off
the
stack
,
push
the
!
value
returned
from
main
(),
and
call
exit
().
addl
$
12
,
%
esp
pushl
%
eax
call
exit
!
An
inline
equivalent
of
_exit
,
as
specified
in
Figure
3
-
26
of
the
ABI
.
pushl
$
0x0
movl
$
0x1
,
%
eax
lcall
$
7
,
$
0
!
If
all
else
fails
,
just
try
a
halt
!
hlt
.
type
_start
,
@
function
.
size
_start
,.
-
_start
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment