forked from Imagelibrary/binutils-gdb
Compare commits
1 Commits
binutils-2
...
binutils-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f9545368b |
42
.gitignore
vendored
42
.gitignore
vendored
@@ -1,42 +0,0 @@
|
||||
*.diff
|
||||
*.patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
*~
|
||||
.#*
|
||||
*#
|
||||
|
||||
*.flt
|
||||
*.gmo
|
||||
*.info
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.pyc
|
||||
*.tmp
|
||||
|
||||
.deps
|
||||
.libs
|
||||
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.h
|
||||
config.intl
|
||||
config.log
|
||||
config.status
|
||||
libtool
|
||||
POTFILES
|
||||
*-POTFILES
|
||||
|
||||
TAGS
|
||||
TAGS.sub
|
||||
|
||||
.gdbinit
|
||||
.gdb_history
|
||||
|
||||
# ignore core files, but not java/net/protocol/core/
|
||||
core
|
||||
!core/
|
||||
|
||||
lost+found
|
||||
52
djunpack.bat
52
djunpack.bat
@@ -1,52 +0,0 @@
|
||||
@echo off
|
||||
Rem
|
||||
Rem WARNING WARNING WARNING: This file needs to have DOS CRLF end-of-line
|
||||
Rem format, or else stock DOS/Windows shells will refuse to run it.
|
||||
Rem
|
||||
Rem This batch file unpacks the GDB distribution while simultaneously
|
||||
Rem renaming some of the files whose names are invalid on DOS or conflict
|
||||
Rem with other file names after truncation to DOS 8+3 namespace.
|
||||
Rem
|
||||
Rem Invoke like this:
|
||||
Rem
|
||||
Rem djunpack gdb-XYZ.tar
|
||||
Rem
|
||||
Rem where XYZ is the version number. If the argument includes leading
|
||||
Rem directories, it MUST use backslashes, not forward slashes.
|
||||
Rem
|
||||
Rem The following 2 lines need to be changed with each new GDB release, to
|
||||
Rem be identical to the name of the top-level directory where the GDB
|
||||
Rem distribution unpacks itself.
|
||||
set GDBVER=gdb-5.0
|
||||
if "%GDBVER%"=="gdb-5.0" GoTo EnvOk
|
||||
Rem If their environment space is too small, re-exec with a larger one
|
||||
command.com /e:4096 /c %0 %1
|
||||
GoTo End
|
||||
:EnvOk
|
||||
if not exist %1 GoTo NoArchive
|
||||
djtar -x -p -o %GDBVER%/gdb/config/djgpp/fnchange.lst %1 > fnchange.tmp
|
||||
Rem The following uses a feature of COPY whereby it does not copy
|
||||
Rem empty files. We need that because the previous line will create
|
||||
Rem an empty fnchange.tmp even if the command failed for some reason.
|
||||
copy fnchange.tmp junk.tmp > nul
|
||||
if not exist junk.tmp GoTo NoDjTar
|
||||
del junk.tmp
|
||||
sed -e "s,@V@,%GDBVER%,g" < fnchange.tmp > fnchange.lst
|
||||
Rem See the comment above about the reason for using COPY.
|
||||
copy fnchange.lst junk.tmp > nul
|
||||
if not exist junk.tmp GoTo NoSed
|
||||
del junk.tmp
|
||||
djtar -x -n fnchange.lst %1
|
||||
GoTo End
|
||||
:NoSed
|
||||
echo FAIL: Sed is not available.
|
||||
GoTo End
|
||||
:NoDjTar
|
||||
echo FAIL: DJTAR is not available or no fnchange.lst file in %1.
|
||||
GoTo End
|
||||
:NoArchive
|
||||
echo FAIL: the file %1 does not seem to exist.
|
||||
echo Remember that %1 cannot use forward slashes, only backslashes.
|
||||
GoTo End
|
||||
:End
|
||||
set GDBVER=
|
||||
@@ -1,24 +0,0 @@
|
||||
;; Emacs settings.
|
||||
;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
|
||||
;; This program 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 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(
|
||||
(tcl-mode . ((tcl-indent-level . 4)
|
||||
(tcl-continued-indent-level . 4)
|
||||
(indent-tabs-mode . t)))
|
||||
(nil . ((bug-reference-url-format . "http://sourceware.org/bugzilla/show_bug.cgi?id=%s")))
|
||||
(c-mode . ((c-file-style . "GNU")
|
||||
(indent-tabs-mode . t)))
|
||||
)
|
||||
20
gdb/.gitignore
vendored
20
gdb/.gitignore
vendored
@@ -1,20 +0,0 @@
|
||||
/version.c
|
||||
/xml-builtin.c
|
||||
|
||||
/ada-exp.c
|
||||
/ada-lex.c
|
||||
/c-exp.c
|
||||
/cp-name-parser.c
|
||||
/f-exp.c
|
||||
/gdb
|
||||
/gdbtui
|
||||
/gcore
|
||||
/go-exp.c
|
||||
/init.c
|
||||
/jit-reader.h
|
||||
/jv-exp.c
|
||||
/m2-exp.c
|
||||
/objc-exp.c
|
||||
/observer.h
|
||||
/observer.inc
|
||||
/p-exp.c
|
||||
144
gdb/CONTRIBUTE
144
gdb/CONTRIBUTE
@@ -1,144 +0,0 @@
|
||||
|
||||
Contributing to GDB
|
||||
|
||||
GDB is a collaborative project and one which wants to encourage new
|
||||
development. You may wish to fix GDB bugs, improve testing, port GDB
|
||||
to a new platform, update documentation, add new GDB features, and the
|
||||
like. To help with this, there is a lot of documentation
|
||||
available.. In addition to the user guide and internals manual
|
||||
included in the GDB distribution, the GDB web pages also contain much
|
||||
information.
|
||||
|
||||
You may also want to submit your change so that can be considered for
|
||||
conclusion in a future version of GDB (see below). Regardless, we
|
||||
encourage you to distribute the change yourself.
|
||||
|
||||
If you don't feel up to hacking GDB, there are still plenty of ways to
|
||||
help! You can answer questions on the mailing lists, write
|
||||
documentation, find bugs, create a GDB related website (contribute to
|
||||
the official GDB web site), or create a GDB related software
|
||||
package. We welcome all of the above and feel free to ask on the GDB
|
||||
mailing lists if you are looking for feedback or for people to review
|
||||
a work in progress.
|
||||
|
||||
Ref: http://www.gnu.org/software/gdb/
|
||||
|
||||
Finally, there are certain legal requirements and style issues which
|
||||
all contributors need to be aware of.
|
||||
|
||||
o Coding Standards
|
||||
|
||||
All contributions must conform to the GNU Coding Standard.
|
||||
Submissions which do not conform to the standards will be
|
||||
returned with a request to reformat the changes.
|
||||
|
||||
GDB has certain additional coding requirements. Those
|
||||
requirements are explained in the GDB internals documentation
|
||||
in the gdb/doc directory.
|
||||
|
||||
Ref: http://www.gnu.org/prep/standards_toc.html
|
||||
|
||||
|
||||
o Copyright Assignment
|
||||
|
||||
Before we can accept code contributions from you, we need a
|
||||
copyright assignment form filled out and filed with the FSF.
|
||||
|
||||
See some documentation by the FSF for details and contact us
|
||||
(either via the GDB mailing list or the GDB maintainer that is
|
||||
taking care of your contributions) to obtain the relevant
|
||||
forms.
|
||||
|
||||
Small changes can be accepted without a copyright assignment form
|
||||
on file.
|
||||
|
||||
Ref: http://www.gnu.org/prep/maintain.html#SEC6
|
||||
|
||||
|
||||
o Submitting Patches
|
||||
|
||||
Every patch must have several pieces of information before we
|
||||
can properly evaluate it.
|
||||
|
||||
A description of the bug and how your patch fixes this
|
||||
bug. A reference to a testsuite failure is very helpful. For
|
||||
new features a description of the feature and your
|
||||
implementation.
|
||||
|
||||
A ChangeLog entry as plaintext (separate from the patch); see
|
||||
the various ChangeLog files for format and content. Note that,
|
||||
unlike some other projects, we do require ChangeLogs also for
|
||||
documentation (i.e., .texi files).
|
||||
|
||||
The patch itself. If you are accessing the CVS repository use
|
||||
"cvs update; cvs diff -up"; else, use "diff -up OLD NEW". If
|
||||
your version of diff does not support these options, then get
|
||||
the latest version of GNU diff.
|
||||
|
||||
We accept patches as plain text (preferred for the compilers
|
||||
themselves), MIME attachments (preferred for the web pages),
|
||||
or as uuencoded gzipped text.
|
||||
|
||||
When you have all these pieces, bundle them up in a mail
|
||||
message and send it to gdb-patches@sourceware.org. All
|
||||
patches and related discussion should be sent to the
|
||||
gdb-patches mailinglist. For further information on the GDB
|
||||
CVS repository, see the Anonymous read-only CVS access and
|
||||
Read-write CVS access page.
|
||||
|
||||
--
|
||||
|
||||
Supplemental information for GDB:
|
||||
|
||||
o Please try to run the relevant testsuite before and after
|
||||
committing a patch
|
||||
|
||||
If the contributor doesn't do it then the maintainer will. A
|
||||
contributor might include before/after test results in their
|
||||
contribution.
|
||||
|
||||
|
||||
o For bug fixes, please try to include a way of
|
||||
demonstrating that the patch actually fixes something.
|
||||
|
||||
The best way of doing this is to ensure that the
|
||||
testsuite contains one or more test cases that
|
||||
fail without the fix but pass with the fix.
|
||||
|
||||
People are encouraged to submit patches that extend
|
||||
the testsuite.
|
||||
|
||||
|
||||
o Please read your patch before submitting it.
|
||||
|
||||
A patch containing several unrelated changes or
|
||||
arbitrary reformats will be returned with a request
|
||||
to re-formatting / split it.
|
||||
|
||||
|
||||
o If ``gdb/configure.ac'' is modified then you don't
|
||||
need to include patches to the regenerated file
|
||||
``configure''.
|
||||
|
||||
The maintainer will re-generate those files
|
||||
using autoconf (2.64 as of 2009-08-22).
|
||||
|
||||
|
||||
o If ``gdb/gdbarch.sh'' is modified, you don't
|
||||
need to include patches to the generated files
|
||||
``gdbarch.h'' and ``gdbarch.c''.
|
||||
|
||||
See ``gdb/configure.ac'' above.
|
||||
|
||||
|
||||
o When submitting a patch that fixes a bug
|
||||
in GDB's bug database a brief reference
|
||||
to the bug can be included in the ChangeLog
|
||||
vis
|
||||
|
||||
* CONTRIBUTE: Mention PR convention.
|
||||
Fix PR gdb/4705.
|
||||
|
||||
The text ``PR gdb/4705'' should also be included
|
||||
in the CVS commit message. That causes the
|
||||
patch to automatically be archived with the PR.
|
||||
674
gdb/COPYING
674
gdb/COPYING
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
9749
gdb/ChangeLog
9749
gdb/ChangeLog
File diff suppressed because it is too large
Load Diff
3155
gdb/ChangeLog-1990
3155
gdb/ChangeLog-1990
File diff suppressed because it is too large
Load Diff
5175
gdb/ChangeLog-1991
5175
gdb/ChangeLog-1991
File diff suppressed because it is too large
Load Diff
6285
gdb/ChangeLog-1992
6285
gdb/ChangeLog-1992
File diff suppressed because it is too large
Load Diff
7597
gdb/ChangeLog-1993
7597
gdb/ChangeLog-1993
File diff suppressed because it is too large
Load Diff
5705
gdb/ChangeLog-1994
5705
gdb/ChangeLog-1994
File diff suppressed because it is too large
Load Diff
4915
gdb/ChangeLog-1995
4915
gdb/ChangeLog-1995
File diff suppressed because it is too large
Load Diff
5116
gdb/ChangeLog-1996
5116
gdb/ChangeLog-1996
File diff suppressed because it is too large
Load Diff
2909
gdb/ChangeLog-1997
2909
gdb/ChangeLog-1997
File diff suppressed because it is too large
Load Diff
7220
gdb/ChangeLog-1998
7220
gdb/ChangeLog-1998
File diff suppressed because it is too large
Load Diff
9296
gdb/ChangeLog-1999
9296
gdb/ChangeLog-1999
File diff suppressed because it is too large
Load Diff
8204
gdb/ChangeLog-2000
8204
gdb/ChangeLog-2000
File diff suppressed because it is too large
Load Diff
9895
gdb/ChangeLog-2001
9895
gdb/ChangeLog-2001
File diff suppressed because it is too large
Load Diff
15039
gdb/ChangeLog-2002
15039
gdb/ChangeLog-2002
File diff suppressed because it is too large
Load Diff
15447
gdb/ChangeLog-2003
15447
gdb/ChangeLog-2003
File diff suppressed because it is too large
Load Diff
15228
gdb/ChangeLog-2004
15228
gdb/ChangeLog-2004
File diff suppressed because it is too large
Load Diff
6743
gdb/ChangeLog-2005
6743
gdb/ChangeLog-2005
File diff suppressed because it is too large
Load Diff
4734
gdb/ChangeLog-2006
4734
gdb/ChangeLog-2006
File diff suppressed because it is too large
Load Diff
10627
gdb/ChangeLog-2007
10627
gdb/ChangeLog-2007
File diff suppressed because it is too large
Load Diff
11610
gdb/ChangeLog-2008
11610
gdb/ChangeLog-2008
File diff suppressed because it is too large
Load Diff
13575
gdb/ChangeLog-2009
13575
gdb/ChangeLog-2009
File diff suppressed because it is too large
Load Diff
11959
gdb/ChangeLog-2010
11959
gdb/ChangeLog-2010
File diff suppressed because it is too large
Load Diff
12658
gdb/ChangeLog-2011
12658
gdb/ChangeLog-2011
File diff suppressed because it is too large
Load Diff
13328
gdb/ChangeLog-2012
13328
gdb/ChangeLog-2012
File diff suppressed because it is too large
Load Diff
4838
gdb/ChangeLog-3.x
4838
gdb/ChangeLog-3.x
File diff suppressed because it is too large
Load Diff
703
gdb/MAINTAINERS
703
gdb/MAINTAINERS
@@ -1,703 +0,0 @@
|
||||
GDB Maintainers
|
||||
===============
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This file describes different groups of people who are, together, the
|
||||
maintainers and developers of the GDB project. Don't worry - it sounds
|
||||
more complicated than it really is.
|
||||
|
||||
There are four groups of GDB developers, covering the patch development and
|
||||
review process:
|
||||
|
||||
- The Global Maintainers.
|
||||
|
||||
These are the developers in charge of most daily development. They
|
||||
have wide authority to apply and reject patches, but defer to the
|
||||
Responsible Maintainers (see below) within their spheres of
|
||||
responsibility.
|
||||
|
||||
- The Responsible Maintainers.
|
||||
|
||||
These are developers who have expertise and interest in a particular
|
||||
area of GDB, who are generally available to review patches, and who
|
||||
prefer to enforce a single vision within their areas.
|
||||
|
||||
- The Authorized Committers.
|
||||
|
||||
These are developers who are trusted to make changes within a specific
|
||||
area of GDB without additional oversight.
|
||||
|
||||
- The Write After Approval Maintainers.
|
||||
|
||||
These are developers who have write access to the GDB source tree. They
|
||||
can check in their own changes once a developer with the appropriate
|
||||
authority has approved the changes; they can also apply the Obvious
|
||||
Fix Rule (below).
|
||||
|
||||
All maintainers are encouraged to post major patches to the gdb-patches
|
||||
mailing list for comments, even if they have the authority to commit the
|
||||
patch without review from another maintainer. This especially includes
|
||||
patches which change internal interfaces (e.g. global functions, data
|
||||
structures) or external interfaces (e.g. user, remote, MI, et cetera).
|
||||
|
||||
The term "review" is used in this file to describe several kinds of feedback
|
||||
from a maintainer: approval, rejection, and requests for changes or
|
||||
clarification with the intention of approving a revised version. Review is
|
||||
a privilege and/or responsibility of various positions among the GDB
|
||||
Maintainers. Of course, anyone - whether they hold a position but not the
|
||||
relevant one for a particular patch, or are just following along on the
|
||||
mailing lists for fun, or anything in between - may suggest changes or
|
||||
ask questions about a patch!
|
||||
|
||||
There's also a couple of other people who play special roles in the GDB
|
||||
community, separately from the patch process:
|
||||
|
||||
- The Official FSF-appointed GDB Maintainers.
|
||||
|
||||
These maintainers are the ones who take the overall responsibility
|
||||
for GDB, as a package of the GNU project. Other GDB contributors
|
||||
work under the official maintainers' supervision. They have final
|
||||
and overriding authority for all GDB-related decisions, including
|
||||
anything described in this file. As individuals, they may or not
|
||||
be generally involved in day-to-day development.
|
||||
|
||||
- The Release Manager.
|
||||
|
||||
This developer is in charge of making new releases of GDB.
|
||||
|
||||
- The Patch Champions.
|
||||
|
||||
These volunteers make sure that no contribution is overlooked or
|
||||
forgotten.
|
||||
|
||||
Most changes to the list of maintainers in this file are handled by
|
||||
consensus among the global maintainers and any other involved parties.
|
||||
In cases where consensus can not be reached, the global maintainers may
|
||||
ask the official FSF-appointed GDB maintainers for a final decision.
|
||||
|
||||
|
||||
The Obvious Fix Rule
|
||||
--------------------
|
||||
|
||||
All maintainers listed in this file, including the Write After Approval
|
||||
developers, are allowed to check in obvious fixes.
|
||||
|
||||
An "obvious fix" means that there is no possibility that anyone will
|
||||
disagree with the change.
|
||||
|
||||
A good mental test is "will the person who hates my work the most be
|
||||
able to find fault with the change" - if so, then it's not obvious and
|
||||
needs to be posted first. :-)
|
||||
|
||||
Something like changing or bypassing an interface is _not_ an obvious
|
||||
fix, since such a change without discussion will result in
|
||||
instantaneous and loud complaints.
|
||||
|
||||
For documentation changes, about the only kind of fix that is obvious
|
||||
is correction of a typo or bad English usage.
|
||||
|
||||
|
||||
The Official FSF-appointed GDB Maintainers
|
||||
------------------------------------------
|
||||
|
||||
These maintainers as a group have final authority for all GDB-related
|
||||
topics; they may make whatever changes that they deem necessary, or
|
||||
that the FSF requests.
|
||||
|
||||
The current official FSF-appointed GDB maintainers are listed below,
|
||||
in alphabetical order. Their affiliations are provided for reference
|
||||
only - their maintainership status is individual and not through their
|
||||
affiliation, and they act on behalf of the GNU project.
|
||||
|
||||
Pedro Alves (Red Hat)
|
||||
Joel Brobecker (AdaCore)
|
||||
Doug Evans (Google)
|
||||
Jan Kratochvil (Red Hat)
|
||||
Tom Tromey (Red Hat)
|
||||
Eli Zaretskii
|
||||
|
||||
Global Maintainers
|
||||
------------------
|
||||
|
||||
The global maintainers may review and commit any change to GDB, except in
|
||||
areas with a Responsible Maintainer available. For major changes, or
|
||||
changes to areas with other active developers, global maintainers are
|
||||
strongly encouraged to post their own patches for feedback before
|
||||
committing.
|
||||
|
||||
The global maintainers are responsible for reviewing patches to any area
|
||||
for which no Responsible Maintainer is listed.
|
||||
|
||||
Global maintainers also have the authority to revert patches which should
|
||||
not have been applied, e.g. patches which were not approved, controversial
|
||||
patches committed under the Obvious Fix Rule, patches with important bugs
|
||||
that can't be immediately fixed, or patches which go against an accepted and
|
||||
documented roadmap for GDB development. Any global maintainer may request
|
||||
the reversion of a patch. If no global maintainer, or responsible
|
||||
maintainer in the affected areas, supports the patch (except for the
|
||||
maintainer who originally committed it), then after 48 hours the maintainer
|
||||
who called for the reversion may revert the patch.
|
||||
|
||||
No one may reapply a reverted patch without the agreement of the maintainer
|
||||
who reverted it, or bringing the issue to the official FSF-appointed
|
||||
GDB maintainers for discussion.
|
||||
|
||||
At the moment there are no documented roadmaps for GDB development; in the
|
||||
future, if there are, a reference to the list will be included here.
|
||||
|
||||
The current global maintainers are (in alphabetical order):
|
||||
|
||||
Pedro Alves palves@redhat.com
|
||||
Joel Brobecker brobecker@adacore.com
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
Andrew Cagney cagney@gnu.org
|
||||
Doug Evans dje@google.com
|
||||
Daniel Jacobowitz drow@false.org
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
Jan Kratochvil jan.kratochvil@redhat.com
|
||||
Stan Shebs stan@codesourcery.com
|
||||
Tom Tromey tromey@redhat.com
|
||||
Ulrich Weigand Ulrich.Weigand@de.ibm.com
|
||||
Elena Zannoni elena.zannoni@oracle.com
|
||||
Eli Zaretskii eliz@gnu.org
|
||||
|
||||
|
||||
Release Manager
|
||||
---------------
|
||||
|
||||
The current release manager is: Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
His responsibilities are:
|
||||
|
||||
* organizing, scheduling, and managing releases of GDB.
|
||||
|
||||
* deciding the approval and commit policies for release branches,
|
||||
and can change them as needed.
|
||||
|
||||
|
||||
|
||||
Patch Champions
|
||||
---------------
|
||||
|
||||
These volunteers track all patches submitted to the gdb-patches list. They
|
||||
endeavor to prevent any posted patch from being overlooked; work with
|
||||
contributors to meet GDB's coding style and general requirements, along with
|
||||
FSF copyright assignments; remind (ping) responsible maintainers to review
|
||||
patches; and ensure that contributors are given credit.
|
||||
|
||||
Current patch champions (in alphabetical order):
|
||||
|
||||
Randolph Chung <tausq@debian.org>
|
||||
|
||||
|
||||
|
||||
Responsible Maintainers
|
||||
-----------------------
|
||||
|
||||
These developers have agreed to review patches in specific areas of GDB, in
|
||||
which they have knowledge and experience. These areas are generally broad;
|
||||
the role of a responsible maintainer is to provide coherent and cohesive
|
||||
structure within their area of GDB, to assure that patches from many
|
||||
different contributors all work together for the best results.
|
||||
|
||||
Global maintainers will defer to responsible maintainers within their areas,
|
||||
as long as the responsible maintainer is active. Active means that
|
||||
responsible maintainers agree to review submitted patches in their area
|
||||
promptly; patches and followups should generally be answered within a week.
|
||||
If a responsible maintainer is interested in reviewing a patch but will not
|
||||
have time within a week of posting, the maintainer should send an
|
||||
acknowledgement of the patch to the gdb-patches mailing list, and
|
||||
plan to follow up with a review within a month. These deadlines are for
|
||||
initial responses to a patch - if the maintainer has suggestions
|
||||
or questions, it may take an extended discussion before the patch
|
||||
is ready to commit. There are no written requirements for discussion,
|
||||
but maintainers are asked to be responsive.
|
||||
|
||||
If a responsible maintainer misses these deadlines occasionally (e.g.
|
||||
vacation or unexpected workload), it's not a disaster - any global
|
||||
maintainer may step in to review the patch. But sometimes life intervenes
|
||||
more permanently, and a maintainer may no longer have time for these duties.
|
||||
When this happens, he or she should step down (either into the Authorized
|
||||
Committers section if still interested in the area, or simply removed from
|
||||
the list of Responsible Maintainers if not).
|
||||
|
||||
If a responsible maintainer is unresponsive for an extended period of time
|
||||
without stepping down, please contact the Global Maintainers; they will try
|
||||
to contact the maintainer directly and fix the problem - potentially by
|
||||
removing that maintainer from their listed position.
|
||||
|
||||
If there are several maintainers for a given domain then any one of them
|
||||
may review a submitted patch.
|
||||
|
||||
Target Instruction Set Architectures:
|
||||
|
||||
The *-tdep.c files. ISA (Instruction Set Architecture) and OS-ABI
|
||||
(Operating System / Application Binary Interface) issues including CPU
|
||||
variants.
|
||||
|
||||
The Target/Architecture maintainer works with the host maintainer when
|
||||
resolving build issues. The Target/Architecture maintainer works with
|
||||
the native maintainer when resolving ABI issues.
|
||||
|
||||
alpha --target=alpha-elf ,-Werror
|
||||
|
||||
arm --target=arm-elf ,-Werror
|
||||
|
||||
avr --target=avr ,-Werror
|
||||
|
||||
cris --target=cris-elf ,-Werror ,
|
||||
(sim does not build with -Werror)
|
||||
|
||||
frv --target=frv-elf ,-Werror
|
||||
|
||||
h8300 --target=h8300-elf ,-Werror
|
||||
|
||||
i386 --target=i386-elf ,-Werror
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
|
||||
ia64 --target=ia64-linux-gnu ,-Werror
|
||||
(--target=ia64-elf broken)
|
||||
|
||||
lm32 --target=lm32-elf ,-Werror
|
||||
|
||||
m32c --target=m32c-elf ,-Werror
|
||||
|
||||
m32r --target=m32r-elf ,-Werror
|
||||
|
||||
m68hc11 --target=m68hc11-elf ,-Werror ,
|
||||
Stephane Carrez Stephane.Carrez@gmail.com
|
||||
|
||||
m68k --target=m68k-elf ,-Werror
|
||||
|
||||
m88k --target=m88k-openbsd ,-Werror
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
|
||||
mcore Deleted
|
||||
|
||||
mep --target=mep-elf ,-Werror
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
|
||||
microblaze --target=microblaze-xilinx-elf ,-Werror
|
||||
--target=microblaze-linux-gnu ,-Werror
|
||||
Michael Eager eager@eagercon.com
|
||||
|
||||
mips --target=mips-elf ,-Werror
|
||||
Maciej W. Rozycki macro@codesourcery.com
|
||||
|
||||
mn10300 --target=mn10300-elf broken
|
||||
(sim/ dies with make -j)
|
||||
|
||||
moxie --target=moxie-elf ,-Werror
|
||||
Anthony Green green@moxielogic.com
|
||||
|
||||
ms1 --target=ms1-elf ,-Werror
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
|
||||
ns32k Deleted
|
||||
|
||||
pa --target=hppa-elf ,-Werror
|
||||
|
||||
powerpc --target=powerpc-eabi ,-Werror
|
||||
|
||||
rl78 --target=rl78-elf ,-Werror
|
||||
|
||||
rx --target=rx-elf ,-Werror
|
||||
|
||||
s390 --target=s390-linux-gnu ,-Werror
|
||||
|
||||
score --target=score-elf
|
||||
Qinwei qinwei@sunnorth.com.cn
|
||||
|
||||
sh --target=sh-elf ,-Werror
|
||||
--target=sh64-elf ,-Werror
|
||||
|
||||
sparc --target=sparc64-solaris2.10 ,-Werror
|
||||
(--target=sparc-elf broken)
|
||||
|
||||
spu --target=spu-elf ,-Werror
|
||||
Ulrich Weigand uweigand@de.ibm.com
|
||||
|
||||
tic6x --target=tic6x-elf ,-Werror
|
||||
Yao Qi yao@codesourcery.com
|
||||
|
||||
v850 --target=v850-elf ,-Werror
|
||||
|
||||
vax --target=vax-netbsd ,-Werror
|
||||
|
||||
x86-64 --target=x86_64-linux-gnu ,-Werror
|
||||
|
||||
xstormy16 --target=xstormy16-elf
|
||||
Corinna Vinschen vinschen@redhat.com
|
||||
|
||||
xtensa --target=xtensa-elf
|
||||
Maxim Grigoriev maxim2405@gmail.com
|
||||
|
||||
All developers recognized by this file can make arbitrary changes to
|
||||
OBSOLETE targets.
|
||||
|
||||
The Bourne shell script gdb_mbuild.sh can be used to rebuild all the
|
||||
above targets.
|
||||
|
||||
|
||||
Host/Native:
|
||||
|
||||
The Native maintainer is responsible for target specific native
|
||||
support - typically shared libraries and quirks to procfs/ptrace/...
|
||||
The Native maintainer works with the Arch and Core maintainers when
|
||||
resolving more generic problems.
|
||||
|
||||
The host maintainer ensures that gdb can be built as a cross debugger on
|
||||
their platform.
|
||||
|
||||
AIX Joel Brobecker brobecker@adacore.com
|
||||
Darwin Tristan Gingold gingold@adacore.com
|
||||
djgpp native Eli Zaretskii eliz@gnu.org
|
||||
GNU Hurd Alfred M. Szmidt ams@gnu.org
|
||||
GNU/Linux/x86 native & host
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
GNU/Linux MIPS native & host
|
||||
Daniel Jacobowitz drow@false.org
|
||||
GNU/Linux m68k Andreas Schwab schwab@linux-m68k.org
|
||||
FreeBSD native & host Mark Kettenis kettenis@gnu.org
|
||||
|
||||
|
||||
|
||||
Core: Generic components used by all of GDB
|
||||
|
||||
threads Mark Kettenis kettenis@gnu.org
|
||||
|
||||
language support
|
||||
Ada Joel Brobecker brobecker@adacore.com
|
||||
Paul Hilfinger hilfinger@gnat.com
|
||||
C++ Daniel Jacobowitz drow@false.org
|
||||
Objective C support Adam Fedor fedor@gnu.org
|
||||
shared libs Kevin Buettner kevinb@redhat.com
|
||||
MI interface Vladimir Prus vladimir@codesourcery.com
|
||||
|
||||
documentation Eli Zaretskii eliz@gnu.org
|
||||
(including NEWS)
|
||||
testsuite
|
||||
gdbtk (gdb.gdbtk) Keith Seitz keiths@redhat.com
|
||||
|
||||
|
||||
UI: External (user) interfaces.
|
||||
|
||||
gdbtk (c & tcl) Fernando Nasser fnasser@redhat.com
|
||||
Keith Seitz keiths@redhat.com
|
||||
libgui (w/foundry, sn) Keith Seitz keiths@redhat.com
|
||||
|
||||
|
||||
Misc:
|
||||
|
||||
gdb/gdbserver Daniel Jacobowitz drow@false.org
|
||||
|
||||
Makefile.in, configure* ALL
|
||||
|
||||
mmalloc/ ALL Host maintainers
|
||||
|
||||
sim/ See sim/MAINTAINERS
|
||||
|
||||
readline/ Master version: ftp://ftp.cwru.edu/pub/bash/
|
||||
ALL
|
||||
Host maintainers (host dependant parts)
|
||||
(but get your changes into the master version)
|
||||
|
||||
tcl/ tk/ itcl/ ALL
|
||||
|
||||
contrib/ari Pierre Muller muller@sourceware.org
|
||||
|
||||
|
||||
Authorized Committers
|
||||
---------------------
|
||||
|
||||
These are developers working on particular areas of GDB, who are trusted to
|
||||
commit their own (or other developers') patches in those areas without
|
||||
further review from a Global Maintainer or Responsible Maintainer. They are
|
||||
under no obligation to review posted patches - but, of course, are invited
|
||||
to do so!
|
||||
|
||||
PowerPC Andrew Cagney cagney@gnu.org
|
||||
ARM Richard Earnshaw rearnsha@arm.com
|
||||
CRIS Hans-Peter Nilsson hp@axis.com
|
||||
IA64 Jeff Johnston jjohnstn@redhat.com
|
||||
MIPS Joel Brobecker brobecker@adacore.com
|
||||
m32r Kei Sakamoto sakamoto.kei@renesas.com
|
||||
PowerPC Kevin Buettner kevinb@redhat.com
|
||||
CRIS Orjan Friberg orjanf@axis.com
|
||||
HPPA Randolph Chung tausq@debian.org
|
||||
S390 Ulrich Weigand uweigand@de.ibm.com
|
||||
djgpp DJ Delorie dj@delorie.com
|
||||
[Please use this address to contact DJ about DJGPP]
|
||||
tui Stephane Carrez Stephane.Carrez@gmail.com
|
||||
ia64 Kevin Buettner kevinb@redhat.com
|
||||
AIX Kevin Buettner kevinb@redhat.com
|
||||
GNU/Linux PPC native Kevin Buettner kevinb@redhat.com
|
||||
gdb.java tests Anthony Green green@redhat.com
|
||||
FreeBSD native & host David O'Brien obrien@freebsd.org
|
||||
event loop Elena Zannoni elena.zannoni@oracle.com
|
||||
generic symtabs Elena Zannoni elena.zannoni@oracle.com
|
||||
dwarf readers Elena Zannoni elena.zannoni@oracle.com
|
||||
elf reader Elena Zannoni elena.zannoni@oracle.com
|
||||
stabs reader Elena Zannoni elena.zannoni@oracle.com
|
||||
readline/ Elena Zannoni elena.zannoni@oracle.com
|
||||
NetBSD native & host Jason Thorpe thorpej@netbsd.org
|
||||
Pascal support Pierre Muller muller@sourceware.org
|
||||
avr Theodore A. Roth troth@openavr.org
|
||||
Modula-2 support Gaius Mulley gaius@glam.ac.uk
|
||||
|
||||
|
||||
Write After Approval
|
||||
(alphabetic)
|
||||
|
||||
To get recommended for the Write After Approval list you need a valid
|
||||
FSF assignment and have submitted one good patch.
|
||||
|
||||
Pedro Alves pedro_alves@portugalmail.pt
|
||||
David Anderson davea@sgi.com
|
||||
John David Anglin dave.anglin@nrc-cnrc.gc.ca
|
||||
Shrinivas Atre shrinivasa@kpitcummins.com
|
||||
Sterling Augustine saugustine@google.com
|
||||
Scott Bambrough scottb@netwinder.org
|
||||
Thiago Jung Bauermann bauerman@br.ibm.com
|
||||
Jon Beniston jon@beniston.com
|
||||
Gary Benson gbenson@redhat.com
|
||||
Jan Beulich jbeulich@novell.com
|
||||
Anton Blanchard anton@samba.org
|
||||
Jim Blandy jimb@codesourcery.com
|
||||
David Blaikie dblaikie@gmail.com
|
||||
Philip Blundell philb@gnu.org
|
||||
Eric Botcazou ebotcazou@libertysurf.fr
|
||||
Per Bothner per@bothner.com
|
||||
Joel Brobecker brobecker@adacore.com
|
||||
Dave Brolley brolley@redhat.com
|
||||
Paul Brook paul@codesourcery.com
|
||||
Julian Brown julian@codesourcery.com
|
||||
Kevin Buettner kevinb@redhat.com
|
||||
Andrew Burgess aburgess@broadcom.com
|
||||
Andrew Cagney cagney@gnu.org
|
||||
David Carlton carlton@bactrian.org
|
||||
Stephane Carrez Stephane.Carrez@gmail.com
|
||||
Michael Chastain mec.gnu@mindspring.com
|
||||
Renquan Cheng crq@gcc.gnu.org
|
||||
Eric Christopher echristo@apple.com
|
||||
Randolph Chung tausq@debian.org
|
||||
Nick Clifton nickc@redhat.com
|
||||
J.T. Conklin jtc@acorntoolworks.com
|
||||
Brendan Conoboy blc@redhat.com
|
||||
Ludovic Courtès ludo@gnu.org
|
||||
Tiago Stürmer Daitx tdaitx@linux.vnet.ibm.com
|
||||
Sanjoy Das sanjoy@playingwithpointers.com
|
||||
Jean-Charles Delay delay@adacore.com
|
||||
DJ Delorie dj@redhat.com
|
||||
Chris Demetriou cgd@google.com
|
||||
Philippe De Muyter phdm@macqel.be
|
||||
Dhananjay Deshpande dhananjayd@kpitcummins.com
|
||||
Markus Deuling deuling@de.ibm.com
|
||||
Klee Dienes kdienes@apple.com
|
||||
Gabriel Dos Reis gdr@integrable-solutions.net
|
||||
Sergio Durigan Junior sergiodj@redhat.com
|
||||
Michael Eager eager@eagercon.com
|
||||
Richard Earnshaw rearnsha@arm.com
|
||||
Steve Ellcey sje@cup.hp.com
|
||||
Frank Ch. Eigler fche@redhat.com
|
||||
Ben Elliston bje@gnu.org
|
||||
Doug Evans dje@google.com
|
||||
Adam Fedor fedor@gnu.org
|
||||
Brian Ford ford@vss.fsi.com
|
||||
Orjan Friberg orjanf@axis.com
|
||||
Nathan Froyd froydnj@codesourcery.com
|
||||
Gary Funck gary@intrepid.com
|
||||
Mircea Gherzan mircea.gherzan@intel.com
|
||||
Paul Gilliam pgilliam@us.ibm.com
|
||||
Tristan Gingold gingold@adacore.com
|
||||
Anton Gorenkov xgsa@yandex.ru
|
||||
Raoul Gough RaoulGough@yahoo.co.uk
|
||||
Anthony Green green@redhat.com
|
||||
Matthew Green mrg@eterna.com.au
|
||||
Matthew Gretton-Dann matthew.gretton-dann@arm.com
|
||||
Maxim Grigoriev maxim2405@gmail.com
|
||||
Jerome Guitton guitton@act-europe.fr
|
||||
Ben Harris bjh21@netbsd.org
|
||||
Richard Henderson rth@redhat.com
|
||||
Aldy Hernandez aldyh@redhat.com
|
||||
Paul Hilfinger hilfinger@gnat.com
|
||||
Matt Hiller hiller@redhat.com
|
||||
Kazu Hirata kazu@cs.umass.edu
|
||||
Jeff Holcomb jeffh@redhat.com
|
||||
Don Howard dhoward@redhat.com
|
||||
Nick Hudson nick.hudson@dsl.pipex.com
|
||||
Martin Hunt hunt@redhat.com
|
||||
Meador Inge meadori@codesourcery.com
|
||||
Jim Ingham jingham@apple.com
|
||||
Baurzhan Ismagulov ibr@radix50.net
|
||||
Manoj Iyer manjo@austin.ibm.com
|
||||
Daniel Jacobowitz drow@false.org
|
||||
Andreas Jaeger aj@suse.de
|
||||
Janis Johnson janisjo@codesourcery.com
|
||||
Jeff Johnston jjohnstn@redhat.com
|
||||
Geoff Keating geoffk@redhat.com
|
||||
Mark Kettenis kettenis@gnu.org
|
||||
Marc Khouzam marc.khouzam@ericsson.com
|
||||
Jim Kingdon kingdon@panix.com
|
||||
Paul Koning paul_koning@dell.com
|
||||
Jan Kratochvil jan.kratochvil@redhat.com
|
||||
Maxim Kuvyrkov maxim@kugelworks.com
|
||||
Jonathan Larmour jifl@ecoscentric.com
|
||||
Jeff Law law@redhat.com
|
||||
Justin Lebar justin.lebar@gmail.com
|
||||
David Lecomber david@streamline-computing.com
|
||||
Don Lee don.lee@sunplusct.com
|
||||
Robert Lipe rjl@sco.com
|
||||
Lei Liu lei.liu2@windriver.com
|
||||
Sandra Loosemore sandra@codesourcery.com
|
||||
H.J. Lu hjl.tools@gmail.com
|
||||
Michal Ludvig mludvig@suse.cz
|
||||
Edjunior B. Machado emachado@linux.vnet.ibm.com
|
||||
Luis Machado lgustavo@codesourcery.com
|
||||
Glen McCready gkm@redhat.com
|
||||
Greg McGary greg@mcgary.org
|
||||
Roland McGrath roland@redhat.com
|
||||
Bryce McKinlay mckinlay@redhat.com
|
||||
Jason Merrill jason@redhat.com
|
||||
David S. Miller davem@redhat.com
|
||||
Mark Mitchell mark@codesourcery.com
|
||||
Marko Mlinar markom@opencores.org
|
||||
Alan Modra amodra@gmail.com
|
||||
Fawzi Mohamed fawzi.mohamed@nokia.com
|
||||
Jason Molenda jmolenda@apple.com
|
||||
Chris Moller cmoller@redhat.com
|
||||
Phil Muldoon pmuldoon@redhat.com
|
||||
Pierre Muller muller@sourceware.org
|
||||
Gaius Mulley gaius@glam.ac.uk
|
||||
Masaki Muranaka monaka@monami-software.com
|
||||
Joseph Myers joseph@codesourcery.com
|
||||
Fernando Nasser fnasser@redhat.com
|
||||
Adam Nemet anemet@caviumnetworks.com
|
||||
Will Newton will.newton@linaro.org
|
||||
Nathanael Nerode neroden@gcc.gnu.org
|
||||
Hans-Peter Nilsson hp@bitrange.com
|
||||
David O'Brien obrien@freebsd.org
|
||||
Alexandre Oliva aoliva@redhat.com
|
||||
Karen Osmond karen.osmond@gmail.com
|
||||
Pawandeep Oza oza.pawandeep@gmail.com
|
||||
Denis Pilat denis.pilat@st.com
|
||||
Andrew Pinski apinski@cavium.com
|
||||
Kevin Pouget kevin.pouget@st.com
|
||||
Paul Pluzhnikov ppluzhnikov@google.com
|
||||
Marek Polacek mpolacek@redhat.com
|
||||
Siddhesh Poyarekar siddhesh@redhat.com
|
||||
Vladimir Prus vladimir@codesourcery.com
|
||||
Yao Qi yao@codesourcery.com
|
||||
Qinwei qinwei@sunnorth.com.cn
|
||||
Siva Chandra Reddy sivachandra@google.com
|
||||
Matt Rice ratmice@gmail.com
|
||||
Frederic Riss frederic.riss@st.com
|
||||
Aleksandar Ristovski aristovski@qnx.com
|
||||
Tom Rix trix@redhat.com
|
||||
Nick Roberts nickrob@snap.net.nz
|
||||
Bob Rossi bob_rossi@cox.net
|
||||
Theodore A. Roth troth@openavr.org
|
||||
Ian Roxborough irox@redhat.com
|
||||
Maciej W. Rozycki macro@linux-mips.org
|
||||
Grace Sainsbury graces@redhat.com
|
||||
Kei Sakamoto sakamoto.kei@renesas.com
|
||||
Mark Salter msalter@redhat.com
|
||||
Richard Sandiford richard@codesourcery.com
|
||||
Iain Sandoe iain@codesourcery.com
|
||||
Peter Schauer Peter.Schauer@mytum.de
|
||||
Andreas Schwab schwab@linux-m68k.org
|
||||
Thomas Schwinge tschwinge@gnu.org
|
||||
Keith Seitz keiths@redhat.com
|
||||
Carlos Eduardo Seo cseo@linux.vnet.ibm.com
|
||||
Ozkan Sezer sezeroz@gmail.com
|
||||
Marcus Shawcroft marcus.shawcroft@arm.com
|
||||
Stan Shebs stan@codesourcery.com
|
||||
Joel Sherrill joel.sherrill@oarcorp.com
|
||||
Mark Shinwell shinwell@codesourcery.com
|
||||
Craig Silverstein csilvers@google.com
|
||||
Aidan Skinner aidan@velvet.net
|
||||
Jiri Smid smid@suse.cz
|
||||
Andrey Smirnov andrew.smirnov@gmail.com
|
||||
David Smith dsmith@redhat.com
|
||||
Stephen P. Smith ischis2@cox.net
|
||||
Jackie Smith Cashion jsmith@redhat.com
|
||||
Petr Sorfa petrs@caldera.com
|
||||
Andrew Stubbs ams@codesourcery.com
|
||||
Emi Suzuki emi-suzuki@tjsys.co.jp
|
||||
Ian Lance Taylor ian@airs.com
|
||||
Walfred Tedeschi walfred.tedeschi@intel.com
|
||||
Gary Thomas gthomas@redhat.com
|
||||
Jason Thorpe thorpej@netbsd.org
|
||||
Caroline Tice ctice@apple.com
|
||||
Kai Tietz ktietz@redhat.com
|
||||
Andreas Tobler andreast@fgznet.ch
|
||||
Tom Tromey tromey@redhat.com
|
||||
David Ung davidu@mips.com
|
||||
D Venkatasubramanian dvenkat@noida.hcltech.com
|
||||
Corinna Vinschen vinschen@redhat.com
|
||||
Sami Wagiaalla swagiaal@redhat.com
|
||||
Keith Walker keith.walker@arm.com
|
||||
Ricard Wanderlof ricardw@axis.com
|
||||
Jiong Wang jiwang@tilera.com
|
||||
Kris Warkentin kewarken@qnx.com
|
||||
Philippe Waroquiers philippe.waroquiers@skynet.be
|
||||
Ulrich Weigand uweigand@de.ibm.com
|
||||
Ken Werner ken.werner@de.ibm.com
|
||||
Mark Wielaard mjw@redhat.com
|
||||
Nathan Williams nathanw@wasabisystems.com
|
||||
Bob Wilson bob.wilson@acm.org
|
||||
Jim Wilson wilson@tuliptree.org
|
||||
Mike Wrighton wrighton@codesourcery.com
|
||||
Kwok Cheung Yeung kcy@codesourcery.com
|
||||
Elena Zannoni elena.zannoni@oracle.com
|
||||
Eli Zaretskii eliz@gnu.org
|
||||
Jie Zhang jzhang918@gmail.com
|
||||
Wu Zhou woodzltc@cn.ibm.com
|
||||
Yoshinori Sato ysato@users.sourceforge.jp
|
||||
Hui Zhu teawater@gmail.com
|
||||
Khoo Yit Phang khooyp@cs.umd.edu
|
||||
|
||||
Past Maintainers
|
||||
|
||||
Whenever removing yourself, or someone else, from this file, consider
|
||||
listing their areas of development here for posterity.
|
||||
|
||||
Jimmy Guo (gdb.hp, tui) guo at cup dot hp dot com
|
||||
Jeff Law (hppa) law at cygnus dot com
|
||||
Daniel Berlin (C++ support) dan at cgsoftware dot com
|
||||
Nick Duffek (powerpc, SCO, Sol/x86) nick at duffek dot com
|
||||
David Taylor (d10v, sparc, utils, defs,
|
||||
expression evaluator, language support) taylor at candd dot org
|
||||
J.T. Conklin (dcache, NetBSD, remote, global) jtc at acorntoolworks dot com
|
||||
Frank Ch. Eigler (sim) fche at redhat dot com
|
||||
Per Bothner (Java) per at bothner dot com
|
||||
Anthony Green (Java) green at redhat dot com
|
||||
Fernando Nasser (testsuite/, mi, cli, KOD) fnasser at redhat dot com
|
||||
Mark Salter (testsuite/lib+config) msalter at redhat dot com
|
||||
Jim Kingdon (web pages) kingdon at panix dot com
|
||||
Jim Ingham (gdbtk, libgui) jingham at apple dot com
|
||||
Mark Kettenis (hurd native) kettenis at gnu dot org
|
||||
Ian Roxborough (in-tree tcl, tk, itcl) irox at redhat dot com
|
||||
Robert Lipe (SCO/Unixware) rjl at sco dot com
|
||||
Peter Schauer (global, AIX, xcoffsolib,
|
||||
Solaris/x86) Peter.Schauer at mytum dot de
|
||||
Scott Bambrough (ARM) scottb at netwinder dot org
|
||||
Philippe De Muyter (coff) phdm at macqel dot be
|
||||
Michael Chastain (testsuite) mec.gnu at mindspring dot com
|
||||
Fred Fish (global)
|
||||
Jim Blandy (global) jimb@red-bean.com
|
||||
Michael Snyder (global)
|
||||
Christopher Faylor (MS Windows, host & native)
|
||||
|
||||
|
||||
Folks that have been caught up in a paper trail:
|
||||
|
||||
David Carlton carlton@bactrian.org
|
||||
Ramana Radhakrishnan ramana.r@gmail.com
|
||||
|
||||
;; Local Variables:
|
||||
;; coding: utf-8
|
||||
;; End:
|
||||
2303
gdb/Makefile.in
2303
gdb/Makefile.in
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
|
||||
Known problems in GDB 7.2.50
|
||||
|
||||
See also: http://www.gnu.org/software/gdb/bugs/
|
||||
|
||||
None worth mentioning here.
|
||||
666
gdb/README
666
gdb/README
@@ -1,666 +0,0 @@
|
||||
README for GDB release
|
||||
|
||||
This is GDB, the GNU source-level debugger.
|
||||
|
||||
A summary of new features is in the file `gdb/NEWS'.
|
||||
|
||||
Check the GDB home page at http://www.gnu.org/software/gdb/ for up to
|
||||
date release information, mailing list links and archives, etc.
|
||||
|
||||
The file `gdb/PROBLEMS' contains information on problems identified
|
||||
late in the release cycle. GDB's bug tracking data base at
|
||||
http://www.gnu.org/software/gdb/bugs/ contains a more complete list of
|
||||
bugs.
|
||||
|
||||
|
||||
Unpacking and Installation -- quick overview
|
||||
==========================
|
||||
|
||||
The release is provided as a gzipped tar file called
|
||||
'gdb-VERSION.tar.gz', where VERSION is the version of GDB.
|
||||
|
||||
The GDB debugger sources, the generic GNU include
|
||||
files, the BFD ("binary file description") library, the readline
|
||||
library, and other libraries all have directories of their own
|
||||
underneath the gdb-VERSION directory. The idea is that a variety of GNU
|
||||
tools can share a common copy of these things. Be aware of variation
|
||||
over time--for example don't try to build GDB with a copy of bfd from
|
||||
a release other than the GDB release (such as a binutils release),
|
||||
especially if the releases are more than a few weeks apart.
|
||||
Configuration scripts and makefiles exist to cruise up and down this
|
||||
directory tree and automatically build all the pieces in the right
|
||||
order.
|
||||
|
||||
When you unpack the gdb-VERSION.tar.gz file, it will create a
|
||||
source directory called `gdb-VERSION'.
|
||||
|
||||
You can build GDB right in the source directory:
|
||||
|
||||
cd gdb-VERSION
|
||||
./configure
|
||||
make
|
||||
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
|
||||
|
||||
However, we recommend that an empty directory be used instead.
|
||||
This way you do not clutter your source tree with binary files
|
||||
and will be able to create different builds with different
|
||||
configuration options.
|
||||
|
||||
You can build GDB in any empty build directory:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
<full path to your sources>/gdb-VERSION/configure
|
||||
make
|
||||
cp gdb/gdb /usr/local/bin/gdb (or wherever you want)
|
||||
|
||||
(Building GDB with DJGPP tools for MS-DOS/MS-Windows is slightly
|
||||
different; see the file gdb-VERSION/gdb/config/djgpp/README for details.)
|
||||
|
||||
This will configure and build all the libraries as well as GDB. If
|
||||
`configure' can't determine your system type, specify one as its
|
||||
argument, e.g., `./configure sun4' or `./configure decstation'.
|
||||
|
||||
Make sure that your 'configure' line ends in 'gdb-VERSION/configure':
|
||||
|
||||
/berman/migchain/source/gdb-VERSION/configure # RIGHT
|
||||
/berman/migchain/source/gdb-VERSION/gdb/configure # WRONG
|
||||
|
||||
The GDB package contains several subdirectories, such as 'gdb',
|
||||
'bfd', and 'readline'. If your 'configure' line ends in
|
||||
'gdb-VERSION/gdb/configure', then you are configuring only the gdb
|
||||
subdirectory, not the whole GDB package. This leads to build errors
|
||||
such as:
|
||||
|
||||
make: *** No rule to make target `../bfd/bfd.h', needed by `gdb.o'. Stop.
|
||||
|
||||
If you get other compiler errors during this stage, see the `Reporting
|
||||
Bugs' section below; there are a few known problems.
|
||||
|
||||
GDB requires an ISO C (ANSI C) compiler. If you do not have an ISO
|
||||
C compiler for your system, you may be able to download and install
|
||||
the GNU CC compiler. It is available via anonymous FTP from the
|
||||
directory `ftp://ftp.gnu.org/pub/gnu/gcc'. GDB also requires an ISO
|
||||
C standard library. The GDB remote server, GDBserver, builds with some
|
||||
non-ISO standard libraries - e.g. for Windows CE.
|
||||
|
||||
GDB uses Expat, an XML parsing library, to implement some target-specific
|
||||
features. Expat will be linked in if it is available at build time, or
|
||||
those features will be disabled. The latest version of Expat should be
|
||||
available from `http://expat.sourceforge.net'.
|
||||
|
||||
GDB can be used as a cross-debugger, running on a machine of one
|
||||
type while debugging a program running on a machine of another type.
|
||||
See below.
|
||||
|
||||
|
||||
More Documentation
|
||||
******************
|
||||
|
||||
All the documentation for GDB comes as part of the machine-readable
|
||||
distribution. The documentation is written in Texinfo format, which
|
||||
is a documentation system that uses a single source file to produce
|
||||
both on-line information and a printed manual. You can use one of the
|
||||
Info formatting commands to create the on-line version of the
|
||||
documentation and TeX (or `texi2roff') to typeset the printed version.
|
||||
|
||||
GDB includes an already formatted copy of the on-line Info version
|
||||
of this manual in the `gdb/doc' subdirectory. The main Info file is
|
||||
`gdb-VERSION/gdb/doc/gdb.info', and it refers to subordinate files
|
||||
matching `gdb.info*' in the same directory. If necessary, you can
|
||||
print out these files, or read them with any editor; but they are
|
||||
easier to read using the `info' subsystem in GNU Emacs or the
|
||||
standalone `info' program, available as part of the GNU Texinfo
|
||||
distribution.
|
||||
|
||||
If you want to format these Info files yourself, you need one of the
|
||||
Info formatting programs, such as `texinfo-format-buffer' or
|
||||
`makeinfo'.
|
||||
|
||||
If you have `makeinfo' installed, and are in the top level GDB
|
||||
source directory (`gdb-VERSION'), you can make the Info file by
|
||||
typing:
|
||||
|
||||
cd gdb/doc
|
||||
make info
|
||||
|
||||
If you want to typeset and print copies of this manual, you need
|
||||
TeX, a program to print its DVI output files, and `texinfo.tex', the
|
||||
Texinfo definitions file. This file is included in the GDB
|
||||
distribution, in the directory `gdb-VERSION/texinfo'.
|
||||
|
||||
TeX is a typesetting program; it does not print files directly, but
|
||||
produces output files called DVI files. To print a typeset document,
|
||||
you need a program to print DVI files. If your system has TeX
|
||||
installed, chances are it has such a program. The precise command to
|
||||
use depends on your system; `lpr -d' is common; another (for PostScript
|
||||
devices) is `dvips'. The DVI print command may require a file name
|
||||
without any extension or a `.dvi' extension.
|
||||
|
||||
TeX also requires a macro definitions file called `texinfo.tex'.
|
||||
This file tells TeX how to typeset a document written in Texinfo
|
||||
format. On its own, TeX cannot read, much less typeset a Texinfo file.
|
||||
`texinfo.tex' is distributed with GDB and is located in the
|
||||
`gdb-VERSION/texinfo' directory.
|
||||
|
||||
If you have TeX and a DVI printer program installed, you can typeset
|
||||
and print this manual. First switch to the `gdb' subdirectory of
|
||||
the main source directory (for example, to `gdb-VERSION/gdb') and then type:
|
||||
|
||||
make doc/gdb.dvi
|
||||
|
||||
If you prefer to have the manual in PDF format, type this from the
|
||||
`gdb/doc' subdirectory of the main source directory:
|
||||
|
||||
make gdb.pdf
|
||||
|
||||
For this to work, you will need the PDFTeX package to be installed.
|
||||
|
||||
|
||||
Installing GDB
|
||||
**************
|
||||
|
||||
GDB comes with a `configure' script that automates the process of
|
||||
preparing GDB for installation; you can then use `make' to build the
|
||||
`gdb' program.
|
||||
|
||||
The GDB distribution includes all the source code you need for GDB in
|
||||
a single directory. That directory contains:
|
||||
|
||||
`gdb-VERSION/{COPYING,COPYING.LIB}'
|
||||
Standard GNU license files. Please read them.
|
||||
|
||||
`gdb-VERSION/bfd'
|
||||
source for the Binary File Descriptor library
|
||||
|
||||
`gdb-VERSION/config*'
|
||||
script for configuring GDB, along with other support files
|
||||
|
||||
`gdb-VERSION/gdb'
|
||||
the source specific to GDB itself
|
||||
|
||||
`gdb-VERSION/include'
|
||||
GNU include files
|
||||
|
||||
`gdb-VERSION/libiberty'
|
||||
source for the `-liberty' free software library
|
||||
|
||||
`gdb-VERSION/opcodes'
|
||||
source for the library of opcode tables and disassemblers
|
||||
|
||||
`gdb-VERSION/readline'
|
||||
source for the GNU command-line interface
|
||||
NOTE: The readline library is compiled for use by GDB, but will
|
||||
not be installed on your system when "make install" is issued.
|
||||
|
||||
`gdb-VERSION/sim'
|
||||
source for some simulators (ARM, D10V, SPARC, M32R, MIPS, PPC, V850, etc)
|
||||
|
||||
`gdb-VERSION/texinfo'
|
||||
The `texinfo.tex' file, which you need in order to make a printed
|
||||
manual using TeX.
|
||||
|
||||
`gdb-VERSION/etc'
|
||||
Coding standards, useful files for editing GDB, and other
|
||||
miscellanea.
|
||||
|
||||
Note: the following instructions are for building GDB on Unix or
|
||||
Unix-like systems. Instructions for building with DJGPP for
|
||||
MS-DOS/MS-Windows are in the file gdb/config/djgpp/README.
|
||||
|
||||
The simplest way to configure and build GDB is to run `configure'
|
||||
from the `gdb-VERSION' directory.
|
||||
|
||||
First switch to the `gdb-VERSION' source directory if you are
|
||||
not already in it; then run `configure'.
|
||||
|
||||
For example:
|
||||
|
||||
cd gdb-VERSION
|
||||
./configure
|
||||
make
|
||||
|
||||
Running `configure' followed by `make' builds the `bfd',
|
||||
`readline', `mmalloc', and `libiberty' libraries, then `gdb' itself.
|
||||
The configured source files, and the binaries, are left in the
|
||||
corresponding source directories.
|
||||
|
||||
`configure' is a Bourne-shell (`/bin/sh') script; if your system
|
||||
does not recognize this automatically when you run a different shell,
|
||||
you may need to run `sh' on it explicitly:
|
||||
|
||||
sh configure
|
||||
|
||||
If you run `configure' from a directory that contains source
|
||||
directories for multiple libraries or programs, `configure' creates
|
||||
configuration files for every directory level underneath (unless
|
||||
you tell it not to, with the `--norecursion' option).
|
||||
|
||||
You can install `gdb' anywhere; it has no hardwired paths. However,
|
||||
you should make sure that the shell on your path (named by the `SHELL'
|
||||
environment variable) is publicly readable. Remember that GDB uses the
|
||||
shell to start your program--some systems refuse to let GDB debug child
|
||||
processes whose programs are not readable.
|
||||
|
||||
|
||||
Compiling GDB in another directory
|
||||
==================================
|
||||
|
||||
If you want to run GDB versions for several host or target machines,
|
||||
you need a different `gdb' compiled for each combination of host and
|
||||
target. `configure' is designed to make this easy by allowing you to
|
||||
generate each configuration in a separate subdirectory, rather than in
|
||||
the source directory. If your `make' program handles the `VPATH'
|
||||
feature correctly (GNU `make' and SunOS 'make' are two that should),
|
||||
running `make' in each of these directories builds the `gdb' program
|
||||
specified there.
|
||||
|
||||
To build `gdb' in a separate directory, run `configure' with the
|
||||
`--srcdir' option to specify where to find the source. (You also need
|
||||
to specify a path to find `configure' itself from your working
|
||||
directory. If the path to `configure' would be the same as the
|
||||
argument to `--srcdir', you can leave out the `--srcdir' option; it
|
||||
will be assumed.)
|
||||
|
||||
For example, you can build GDB in a separate
|
||||
directory for a Sun 4 like this:
|
||||
|
||||
cd gdb-VERSION
|
||||
mkdir ../gdb-sun4
|
||||
cd ../gdb-sun4
|
||||
../gdb-VERSION/configure
|
||||
make
|
||||
|
||||
When `configure' builds a configuration using a remote source
|
||||
directory, it creates a tree for the binaries with the same structure
|
||||
(and using the same names) as the tree under the source directory. In
|
||||
the example, you'd find the Sun 4 library `libiberty.a' in the
|
||||
directory `gdb-sun4/libiberty', and GDB itself in `gdb-sun4/gdb'.
|
||||
|
||||
One popular reason to build several GDB configurations in separate
|
||||
directories is to configure GDB for cross-compiling (where GDB runs on
|
||||
one machine--the host--while debugging programs that run on another
|
||||
machine--the target). You specify a cross-debugging target by giving
|
||||
the `--target=TARGET' option to `configure'.
|
||||
|
||||
When you run `make' to build a program or library, you must run it
|
||||
in a configured directory--whatever directory you were in when you
|
||||
called `configure' (or one of its subdirectories).
|
||||
|
||||
The `Makefile' that `configure' generates in each source directory
|
||||
also runs recursively. If you type `make' in a source directory such
|
||||
as `gdb-VERSION' (or in a separate configured directory configured with
|
||||
`--srcdir=PATH/gdb-VERSION'), you will build all the required libraries,
|
||||
and then build GDB.
|
||||
|
||||
When you have multiple hosts or targets configured in separate
|
||||
directories, you can run `make' on them in parallel (for example, if
|
||||
they are NFS-mounted on each of the hosts); they will not interfere
|
||||
with each other.
|
||||
|
||||
|
||||
Specifying names for hosts and targets
|
||||
======================================
|
||||
|
||||
The specifications used for hosts and targets in the `configure'
|
||||
script are based on a three-part naming scheme, but some short
|
||||
predefined aliases are also supported. The full naming scheme encodes
|
||||
three pieces of information in the following pattern:
|
||||
|
||||
ARCHITECTURE-VENDOR-OS
|
||||
|
||||
For example, you can use the alias `sun4' as a HOST argument or in a
|
||||
`--target=TARGET' option. The equivalent full name is
|
||||
`sparc-sun-sunos4'.
|
||||
|
||||
The `configure' script accompanying GDB does not provide any query
|
||||
facility to list all supported host and target names or aliases.
|
||||
`configure' calls the Bourne shell script `config.sub' to map
|
||||
abbreviations to full names; you can read the script, if you wish, or
|
||||
you can use it to test your guesses on abbreviations--for example:
|
||||
|
||||
% sh config.sub sun4
|
||||
sparc-sun-sunos4.1.1
|
||||
% sh config.sub sun3
|
||||
m68k-sun-sunos4.1.1
|
||||
% sh config.sub decstation
|
||||
mips-dec-ultrix4.2
|
||||
% sh config.sub hp300bsd
|
||||
m68k-hp-bsd
|
||||
% sh config.sub i386v
|
||||
i386-pc-sysv
|
||||
% sh config.sub i786v
|
||||
Invalid configuration `i786v': machine `i786v' not recognized
|
||||
|
||||
`config.sub' is also distributed in the GDB source directory.
|
||||
|
||||
|
||||
`configure' options
|
||||
===================
|
||||
|
||||
Here is a summary of the `configure' options and arguments that are
|
||||
most often useful for building GDB. `configure' also has several other
|
||||
options not listed here. *note : (configure.info)What Configure Does,
|
||||
for a full explanation of `configure'.
|
||||
|
||||
configure [--help]
|
||||
[--prefix=DIR]
|
||||
[--srcdir=PATH]
|
||||
[--norecursion] [--rm]
|
||||
[--enable-build-warnings]
|
||||
[--target=TARGET]
|
||||
[--host=HOST]
|
||||
[HOST]
|
||||
|
||||
You may introduce options with a single `-' rather than `--' if you
|
||||
prefer; but you may abbreviate option names if you use `--'.
|
||||
|
||||
`--help'
|
||||
Display a quick summary of how to invoke `configure'.
|
||||
|
||||
`-prefix=DIR'
|
||||
Configure the source to install programs and files under directory
|
||||
`DIR'.
|
||||
|
||||
`--srcdir=PATH'
|
||||
*Warning: using this option requires GNU `make', or another `make'
|
||||
that compatibly implements the `VPATH' feature.*
|
||||
Use this option to make configurations in directories separate
|
||||
from the GDB source directories. Among other things, you can use
|
||||
this to build (or maintain) several configurations simultaneously,
|
||||
in separate directories. `configure' writes configuration
|
||||
specific files in the current directory, but arranges for them to
|
||||
use the source in the directory PATH. `configure' will create
|
||||
directories under the working directory in parallel to the source
|
||||
directories below PATH.
|
||||
|
||||
`--host=HOST'
|
||||
Configure GDB to run on the specified HOST.
|
||||
|
||||
There is no convenient way to generate a list of all available
|
||||
hosts.
|
||||
|
||||
`HOST ...'
|
||||
Same as `--host=HOST'. If you omit this, GDB will guess; it's
|
||||
quite accurate.
|
||||
|
||||
`--norecursion'
|
||||
Configure only the directory level where `configure' is executed;
|
||||
do not propagate configuration to subdirectories.
|
||||
|
||||
`--rm'
|
||||
Remove the configuration that the other arguments specify.
|
||||
|
||||
`--enable-build-warnings'
|
||||
When building the GDB sources, ask the compiler to warn about any
|
||||
code which looks even vaguely suspicious. You should only using
|
||||
this feature if you're compiling with GNU CC. It passes the
|
||||
following flags:
|
||||
-Wimplicit
|
||||
-Wreturn-type
|
||||
-Wcomment
|
||||
-Wtrigraphs
|
||||
-Wformat
|
||||
-Wparentheses
|
||||
-Wpointer-arith
|
||||
|
||||
`--enable-werror'
|
||||
Treat compiler warnings as werrors. Use this only with GCC. It
|
||||
adds the -Werror flag to the compiler, which will fail the
|
||||
compilation if the compiler outputs any warning messages.
|
||||
|
||||
`--target=TARGET'
|
||||
Configure GDB for cross-debugging programs running on the specified
|
||||
TARGET. Without this option, GDB is configured to debug programs
|
||||
that run on the same machine (HOST) as GDB itself.
|
||||
|
||||
There is no convenient way to generate a list of all available
|
||||
targets.
|
||||
|
||||
`--with-gdb-datadir=PATH'
|
||||
Set the GDB-specific data directory. GDB will look here for
|
||||
certain supporting files or scripts. This defaults to the `gdb'
|
||||
subdirectory of `datadir' (which can be set using `--datadir').
|
||||
|
||||
`--with-relocated-sources=DIR'
|
||||
Sets up the default source path substitution rule so that
|
||||
directory names recorded in debug information will be
|
||||
automatically adjusted for any directory under DIR. DIR should
|
||||
be a subdirectory of GDB's configured prefix, the one mentioned
|
||||
in the `--prefix' or `--exec-prefix' options to configure. This
|
||||
option is useful if GDB is supposed to be moved to a different
|
||||
place after it is built.
|
||||
|
||||
`--enable-64-bit-bfd'
|
||||
Enable 64-bit support in BFD on 32-bit hosts.
|
||||
|
||||
`--disable-gdbmi'
|
||||
Build GDB without the GDB/MI machine interface.
|
||||
|
||||
`--enable-tui'
|
||||
Build GDB with the text-mode full-screen user interface (TUI).
|
||||
Requires a curses library (ncurses and cursesX are also
|
||||
supported).
|
||||
|
||||
`--enable-gdbtk'
|
||||
Build GDB with the gdbtk GUI interface. Requires TCL/Tk to be
|
||||
installed.
|
||||
|
||||
`--with-libunwind-ia64'
|
||||
Use the libunwind library for unwinding function call stack on ia64
|
||||
target platforms.
|
||||
See http://www.nongnu.org/libunwind/index.html for details.
|
||||
|
||||
`--with-curses'
|
||||
Use the curses library instead of the termcap library, for
|
||||
text-mode terminal operations.
|
||||
|
||||
`--enable-profiling' Enable profiling of GDB itself. Necessary if you
|
||||
want to use the "maint set profile" command for profiling GDB.
|
||||
Requires the functions `monstartup' and `_mcleanup' to be present
|
||||
in the standard C library used to build GDB, and also requires a
|
||||
compiler that supports the `-pg' option.
|
||||
|
||||
`--with-system-readline'
|
||||
Use the readline library installed on the host, rather than the
|
||||
library supplied as part of GDB tarball.
|
||||
|
||||
`--with-expat'
|
||||
Build GDB with the libexpat library. (Done by default if
|
||||
libexpat is installed and found at configure time.) This library
|
||||
is used to read XML files supplied with GDB. If it is
|
||||
unavailable, some features, such as remote protocol memory maps,
|
||||
target descriptions, and shared library lists, that are based on
|
||||
XML files, will not be available in GDB. If your host does not
|
||||
have libexpat installed, you can get the latest version from
|
||||
http://expat.sourceforge.net.
|
||||
|
||||
`--with-python[=PATH]'
|
||||
Build GDB with Python scripting support. (Done by default if
|
||||
libpython is present and found at configure time.) Python makes
|
||||
GDB scripting much more powerful than the restricted CLI
|
||||
scripting language. If your host does not have Python installed,
|
||||
you can find it on http://www.python.org/download/. The oldest
|
||||
version of Python supported by GDB is 2.4. The optional argument
|
||||
PATH says where to find the Python headers and libraries; the
|
||||
configure script will look in PATH/include for headers and in
|
||||
PATH/lib for the libraries.
|
||||
|
||||
`--without-included-regex'
|
||||
Don't use the regex library included with GDB (as part of the
|
||||
libiberty library). This is the default on hosts with version 2
|
||||
of the GNU C library.
|
||||
|
||||
`--with-sysroot=DIR'
|
||||
Use DIR as the default system root directory for libraries whose
|
||||
file names begin with `/lib' or `/usr/lib'. (The value of DIR
|
||||
can be modified at run time by using the "set sysroot" command.)
|
||||
If DIR is under the GDB configured prefix (set with `--prefix' or
|
||||
`--exec-prefix' options), the default system root will be
|
||||
automatically adjusted if and when GDB is moved to a different
|
||||
location.
|
||||
|
||||
`--with-system-gdbinit=FILE'
|
||||
Configure GDB to automatically load a system-wide init file.
|
||||
FILE should be an absolute file name. If FILE is in a directory
|
||||
under the configured prefix, and GDB is moved to another location
|
||||
after being built, the location of the system-wide init file will
|
||||
be adjusted accordingly.
|
||||
|
||||
`configure' accepts other options, for compatibility with configuring
|
||||
other GNU tools recursively; but these are the only options that affect
|
||||
GDB or its supporting libraries.
|
||||
|
||||
|
||||
Remote debugging
|
||||
=================
|
||||
|
||||
The files m68k-stub.c, i386-stub.c, and sparc-stub.c are examples
|
||||
of remote stubs to be used with remote.c. They are designed to run
|
||||
standalone on an m68k, i386, or SPARC cpu and communicate properly
|
||||
with the remote.c stub over a serial line.
|
||||
|
||||
The directory gdb/gdbserver/ contains `gdbserver', a program that
|
||||
allows remote debugging for Unix applications. GDBserver is only
|
||||
supported for some native configurations, including Sun 3, Sun 4, and
|
||||
Linux.
|
||||
The file gdb/gdbserver/README includes further notes on GDBserver; in
|
||||
particular, it explains how to build GDBserver for cross-debugging
|
||||
(where GDBserver runs on the target machine, which is of a different
|
||||
architecture than the host machine running GDB).
|
||||
|
||||
There are a number of remote interfaces for talking to existing ROM
|
||||
monitors and other hardware:
|
||||
|
||||
remote-mips.c MIPS remote debugging protocol
|
||||
remote-sds.c PowerPC SDS monitor
|
||||
remote-sim.c Generalized simulator protocol
|
||||
|
||||
|
||||
Reporting Bugs in GDB
|
||||
=====================
|
||||
|
||||
There are several ways of reporting bugs in GDB. The prefered
|
||||
method is to use the World Wide Web:
|
||||
|
||||
http://www.gnu.org/software/gdb/bugs/
|
||||
|
||||
As an alternative, the bug report can be submitted, via e-mail, to the
|
||||
address "bug-gdb@gnu.org".
|
||||
|
||||
When submitting a bug, please include the GDB version number, and
|
||||
how you configured it (e.g., "sun4" or "mach386 host,
|
||||
i586-intel-synopsys target"). Since GDB now supports so many
|
||||
different configurations, it is important that you be precise about
|
||||
this. If at all possible, you should include the actual banner
|
||||
that GDB prints when it starts up, or failing that, the actual
|
||||
configure command that you used when configuring GDB.
|
||||
|
||||
For more information on how/whether to report bugs, see the
|
||||
Reporting Bugs chapter of the GDB manual (gdb/doc/gdb.texinfo).
|
||||
|
||||
|
||||
Graphical interface to GDB -- X Windows, MS Windows
|
||||
==========================
|
||||
|
||||
Several graphical interfaces to GDB are available. You should
|
||||
check:
|
||||
|
||||
http://www.gnu.org/software/gdb/links/
|
||||
|
||||
for an up-to-date list.
|
||||
|
||||
Emacs users will very likely enjoy the Grand Unified Debugger mode;
|
||||
try typing `M-x gdb RET'.
|
||||
|
||||
|
||||
Writing Code for GDB
|
||||
=====================
|
||||
|
||||
There is information about writing code for GDB in the file
|
||||
`CONTRIBUTE' and at the website:
|
||||
|
||||
http://www.gnu.org/software/gdb/
|
||||
|
||||
in particular in the wiki.
|
||||
|
||||
If you are pondering writing anything but a short patch, especially
|
||||
take note of the information about copyrights and copyright assignment.
|
||||
It can take quite a while to get all the paperwork done, so
|
||||
we encourage you to start that process as soon as you decide you are
|
||||
planning to work on something, or at least well ahead of when you
|
||||
think you will be ready to submit the patches.
|
||||
|
||||
|
||||
GDB Testsuite
|
||||
=============
|
||||
|
||||
Included with the GDB distribution is a DejaGNU based testsuite
|
||||
that can either be used to test your newly built GDB, or for
|
||||
regression testing a GDB with local modifications.
|
||||
|
||||
Running the testsuite requires the prior installation of DejaGNU,
|
||||
which is generally available via ftp. The directory
|
||||
ftp://sources.redhat.com/pub/dejagnu/ will contain a recent snapshot.
|
||||
Once DejaGNU is installed, you can run the tests in one of the
|
||||
following ways:
|
||||
|
||||
(1) cd gdb-VERSION
|
||||
make check-gdb
|
||||
|
||||
or
|
||||
|
||||
(2) cd gdb-VERSION/gdb
|
||||
make check
|
||||
|
||||
or
|
||||
|
||||
(3) cd gdb-VERSION/gdb/testsuite
|
||||
make site.exp (builds the site specific file)
|
||||
runtest -tool gdb GDB=../gdb (or GDB=<somepath> as appropriate)
|
||||
|
||||
When using a `make'-based method, you can use the Makefile variable
|
||||
`RUNTESTFLAGS' to pass flags to `runtest', e.g.:
|
||||
|
||||
make RUNTESTFLAGS=--directory=gdb.cp check
|
||||
|
||||
If you use GNU make, you can use its `-j' option to run the testsuite
|
||||
in parallel. This can greatly reduce the amount of time it takes for
|
||||
the testsuite to run. In this case, if you set `RUNTESTFLAGS' then,
|
||||
by default, the tests will be run serially even under `-j'. You can
|
||||
override this and force a parallel run by setting the `make' variable
|
||||
`FORCE_PARALLEL' to any non-empty value. Note that the parallel `make
|
||||
check' assumes that you want to run the entire testsuite, so it is not
|
||||
compatible with some dejagnu options, like `--directory'.
|
||||
|
||||
The last method gives you slightly more control in case of problems
|
||||
with building one or more test executables or if you are using the
|
||||
testsuite `standalone', without it being part of the GDB source tree.
|
||||
|
||||
See the DejaGNU documentation for further details.
|
||||
|
||||
|
||||
Copyright and License Notices
|
||||
=============================
|
||||
|
||||
Most files maintained by the GDB Project contain a copyright notice
|
||||
as well as a license notice, usually at the start of the file.
|
||||
|
||||
To reduce the length of copyright notices, consecutive years in the
|
||||
copyright notice can be combined into a single range. For instance,
|
||||
the following list of copyright years...
|
||||
|
||||
1986, 1988, 1989, 1991-1993, 1999, 2000, 2007, 2008, 2009, 2010, 2011
|
||||
|
||||
... is abbreviated into:
|
||||
|
||||
1986, 1988-1989, 1991-1993, 1999-2000, 2007-2011
|
||||
|
||||
Every year of each range, inclusive, is a copyrightable year that
|
||||
could be listed individually.
|
||||
|
||||
|
||||
(this is for editing this file with GNU emacs)
|
||||
Local Variables:
|
||||
mode: text
|
||||
End:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,301 +0,0 @@
|
||||
/* Target-dependent code for GNU/Linux AArch64.
|
||||
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include "gdbarch.h"
|
||||
#include "glibc-tdep.h"
|
||||
#include "linux-tdep.h"
|
||||
#include "aarch64-tdep.h"
|
||||
#include "aarch64-linux-tdep.h"
|
||||
#include "osabi.h"
|
||||
#include "solib-svr4.h"
|
||||
#include "symtab.h"
|
||||
#include "tramp-frame.h"
|
||||
#include "trad-frame.h"
|
||||
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
#include "regset.h"
|
||||
|
||||
/* The general-purpose regset consists of 31 X registers, plus SP, PC,
|
||||
and PSTATE registers, as defined in the AArch64 port of the Linux
|
||||
kernel. */
|
||||
#define AARCH64_LINUX_SIZEOF_GREGSET (34 * X_REGISTER_SIZE)
|
||||
|
||||
/* The fp regset consists of 32 V registers, plus FPCR and FPSR which
|
||||
are 4 bytes wide each, and the whole structure is padded to 128 bit
|
||||
alignment. */
|
||||
#define AARCH64_LINUX_SIZEOF_FPREGSET (33 * V_REGISTER_SIZE)
|
||||
|
||||
/* Signal frame handling.
|
||||
|
||||
+----------+ ^
|
||||
| saved lr | |
|
||||
+->| saved fp |--+
|
||||
| | |
|
||||
| | |
|
||||
| +----------+
|
||||
| | saved lr |
|
||||
+--| saved fp |
|
||||
^ | |
|
||||
| | |
|
||||
| +----------+
|
||||
^ | |
|
||||
| | signal |
|
||||
| | |
|
||||
| | saved lr |-->interrupted_function_pc
|
||||
+--| saved fp |
|
||||
| +----------+
|
||||
| | saved lr |--> default_restorer (movz x8, NR_sys_rt_sigreturn; svc 0)
|
||||
+--| saved fp |<- FP
|
||||
| |
|
||||
| |<- SP
|
||||
+----------+
|
||||
|
||||
On signal delivery, the kernel will create a signal handler stack
|
||||
frame and setup the return address in LR to point at restorer stub.
|
||||
The signal stack frame is defined by:
|
||||
|
||||
struct rt_sigframe
|
||||
{
|
||||
siginfo_t info;
|
||||
struct ucontext uc;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
... 128 bytes
|
||||
} siginfo_t;
|
||||
|
||||
The ucontext has the following form:
|
||||
struct ucontext
|
||||
{
|
||||
unsigned long uc_flags;
|
||||
struct ucontext *uc_link;
|
||||
stack_t uc_stack;
|
||||
sigset_t uc_sigmask;
|
||||
struct sigcontext uc_mcontext;
|
||||
};
|
||||
|
||||
typedef struct sigaltstack
|
||||
{
|
||||
void *ss_sp;
|
||||
int ss_flags;
|
||||
size_t ss_size;
|
||||
} stack_t;
|
||||
|
||||
struct sigcontext
|
||||
{
|
||||
unsigned long fault_address;
|
||||
unsigned long regs[31];
|
||||
unsigned long sp; / * 31 * /
|
||||
unsigned long pc; / * 32 * /
|
||||
unsigned long pstate; / * 33 * /
|
||||
__u8 __reserved[4096]
|
||||
};
|
||||
|
||||
The restorer stub will always have the form:
|
||||
|
||||
d28015a8 movz x8, #0xad
|
||||
d4000001 svc #0x0
|
||||
|
||||
We detect signal frames by snooping the return code for the restorer
|
||||
instruction sequence.
|
||||
|
||||
The handler then needs to recover the saved register set from
|
||||
ucontext.uc_mcontext. */
|
||||
|
||||
/* These magic numbers need to reflect the layout of the kernel
|
||||
defined struct rt_sigframe and ucontext. */
|
||||
#define AARCH64_SIGCONTEXT_REG_SIZE 8
|
||||
#define AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET 128
|
||||
#define AARCH64_UCONTEXT_SIGCONTEXT_OFFSET 176
|
||||
#define AARCH64_SIGCONTEXT_XO_OFFSET 8
|
||||
|
||||
/* Implement the "init" method of struct tramp_frame. */
|
||||
|
||||
static void
|
||||
aarch64_linux_sigframe_init (const struct tramp_frame *self,
|
||||
struct frame_info *this_frame,
|
||||
struct trad_frame_cache *this_cache,
|
||||
CORE_ADDR func)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
CORE_ADDR sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
|
||||
CORE_ADDR fp = get_frame_register_unsigned (this_frame, AARCH64_FP_REGNUM);
|
||||
CORE_ADDR sigcontext_addr =
|
||||
sp
|
||||
+ AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET
|
||||
+ AARCH64_UCONTEXT_SIGCONTEXT_OFFSET;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 31; i++)
|
||||
{
|
||||
trad_frame_set_reg_addr (this_cache,
|
||||
AARCH64_X0_REGNUM + i,
|
||||
sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET
|
||||
+ i * AARCH64_SIGCONTEXT_REG_SIZE);
|
||||
}
|
||||
|
||||
trad_frame_set_reg_addr (this_cache, AARCH64_FP_REGNUM, fp);
|
||||
trad_frame_set_reg_addr (this_cache, AARCH64_LR_REGNUM, fp + 8);
|
||||
trad_frame_set_reg_addr (this_cache, AARCH64_PC_REGNUM, fp + 8);
|
||||
|
||||
trad_frame_set_id (this_cache, frame_id_build (fp, func));
|
||||
}
|
||||
|
||||
static const struct tramp_frame aarch64_linux_rt_sigframe =
|
||||
{
|
||||
SIGTRAMP_FRAME,
|
||||
4,
|
||||
{
|
||||
/* movz x8, 0x8b (S=1,o=10,h=0,i=0x8b,r=8)
|
||||
Soo1 0010 1hhi iiii iiii iiii iiir rrrr */
|
||||
{0xd2801168, -1},
|
||||
|
||||
/* svc 0x0 (o=0, l=1)
|
||||
1101 0100 oooi iiii iiii iiii iii0 00ll */
|
||||
{0xd4000001, -1},
|
||||
{TRAMP_SENTINEL_INSN, -1}
|
||||
},
|
||||
aarch64_linux_sigframe_init
|
||||
};
|
||||
|
||||
/* Fill GDB's register array with the general-purpose register values
|
||||
in the buffer pointed by GREGS_BUF. */
|
||||
|
||||
void
|
||||
aarch64_linux_supply_gregset (struct regcache *regcache,
|
||||
const gdb_byte *gregs_buf)
|
||||
{
|
||||
int regno;
|
||||
|
||||
for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
|
||||
regcache_raw_supply (regcache, regno,
|
||||
gregs_buf + X_REGISTER_SIZE
|
||||
* (regno - AARCH64_X0_REGNUM));
|
||||
}
|
||||
|
||||
/* The "supply_regset" function for the general-purpose register set. */
|
||||
|
||||
static void
|
||||
supply_gregset_from_core (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *regbuf, size_t len)
|
||||
{
|
||||
aarch64_linux_supply_gregset (regcache, (const gdb_byte *) regbuf);
|
||||
}
|
||||
|
||||
/* Fill GDB's register array with the floating-point register values
|
||||
in the buffer pointed by FPREGS_BUF. */
|
||||
|
||||
void
|
||||
aarch64_linux_supply_fpregset (struct regcache *regcache,
|
||||
const gdb_byte *fpregs_buf)
|
||||
{
|
||||
int regno;
|
||||
|
||||
for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
|
||||
regcache_raw_supply (regcache, regno,
|
||||
fpregs_buf + V_REGISTER_SIZE
|
||||
* (regno - AARCH64_V0_REGNUM));
|
||||
|
||||
regcache_raw_supply (regcache, AARCH64_FPSR_REGNUM,
|
||||
fpregs_buf + V_REGISTER_SIZE * 32);
|
||||
regcache_raw_supply (regcache, AARCH64_FPCR_REGNUM,
|
||||
fpregs_buf + V_REGISTER_SIZE * 32 + 4);
|
||||
}
|
||||
|
||||
/* The "supply_regset" function for the floating-point register set. */
|
||||
|
||||
static void
|
||||
supply_fpregset_from_core (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *regbuf, size_t len)
|
||||
{
|
||||
aarch64_linux_supply_fpregset (regcache, (const gdb_byte *) regbuf);
|
||||
}
|
||||
|
||||
/* Implement the "regset_from_core_section" gdbarch method. */
|
||||
|
||||
static const struct regset *
|
||||
aarch64_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name,
|
||||
size_t sect_size)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
if (strcmp (sect_name, ".reg") == 0
|
||||
&& sect_size == AARCH64_LINUX_SIZEOF_GREGSET)
|
||||
{
|
||||
if (tdep->gregset == NULL)
|
||||
tdep->gregset = regset_alloc (gdbarch, supply_gregset_from_core,
|
||||
NULL);
|
||||
return tdep->gregset;
|
||||
}
|
||||
|
||||
if (strcmp (sect_name, ".reg2") == 0
|
||||
&& sect_size == AARCH64_LINUX_SIZEOF_FPREGSET)
|
||||
{
|
||||
if (tdep->fpregset == NULL)
|
||||
tdep->fpregset = regset_alloc (gdbarch, supply_fpregset_from_core,
|
||||
NULL);
|
||||
return tdep->fpregset;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
tdep->lowest_pc = 0x8000;
|
||||
|
||||
set_solib_svr4_fetch_link_map_offsets (gdbarch,
|
||||
svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
/* Enable TLS support. */
|
||||
set_gdbarch_fetch_tls_load_module_address (gdbarch,
|
||||
svr4_fetch_objfile_link_map);
|
||||
|
||||
/* Shared library handling. */
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||
|
||||
set_gdbarch_get_siginfo_type (gdbarch, linux_get_siginfo_type);
|
||||
tramp_frame_prepend_unwinder (gdbarch, &aarch64_linux_rt_sigframe);
|
||||
|
||||
/* Enable longjmp. */
|
||||
tdep->jb_pc = 11;
|
||||
|
||||
set_gdbarch_regset_from_core_section (gdbarch,
|
||||
aarch64_linux_regset_from_core_section);
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_aarch64_linux_tdep;
|
||||
|
||||
void
|
||||
_initialize_aarch64_linux_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_LINUX,
|
||||
aarch64_linux_init_abi);
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/* GNU/Linux on AArch64 target support, prototypes.
|
||||
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
struct regcache;
|
||||
|
||||
extern void aarch64_linux_supply_gregset (struct regcache *regcache,
|
||||
const gdb_byte *gregs_buf);
|
||||
extern void aarch64_linux_supply_fpregset (struct regcache *regcache,
|
||||
const gdb_byte *fpregs_buf);
|
||||
@@ -1,47 +0,0 @@
|
||||
/* Target-dependent code for Newlib AArch64.
|
||||
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include "gdbarch.h"
|
||||
#include "aarch64-tdep.h"
|
||||
#include "osabi.h"
|
||||
|
||||
/* Implement the 'init_osabi' method of struct gdb_osabi_handler. */
|
||||
|
||||
static void
|
||||
aarch64_newlib_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Jump buffer - support for longjmp.
|
||||
Offset of original PC in jump buffer (in registers). */
|
||||
tdep->jb_pc = 11;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_aarch64_newlib_tdep;
|
||||
|
||||
void
|
||||
_initialize_aarch64_newlib_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_aarch64, 0, GDB_OSABI_NEWLIB,
|
||||
aarch64_newlib_init_abi);
|
||||
}
|
||||
2729
gdb/aarch64-tdep.c
2729
gdb/aarch64-tdep.c
File diff suppressed because it is too large
Load Diff
@@ -1,97 +0,0 @@
|
||||
/* Common target dependent code for GDB on AArch64 systems.
|
||||
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
Contributed by ARM Ltd.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#ifndef AARCH64_TDEP_H
|
||||
#define AARCH64_TDEP_H
|
||||
|
||||
/* Forward declarations. */
|
||||
struct gdbarch;
|
||||
struct regset;
|
||||
|
||||
/* AArch64 Dwarf register numbering. */
|
||||
#define AARCH64_DWARF_X0 0
|
||||
#define AARCH64_DWARF_SP 31
|
||||
#define AARCH64_DWARF_V0 64
|
||||
|
||||
/* Register numbers of various important registers. */
|
||||
enum aarch64_regnum
|
||||
{
|
||||
AARCH64_X0_REGNUM, /* First integer register */
|
||||
|
||||
/* Frame register in AArch64 code, if used. */
|
||||
AARCH64_FP_REGNUM = AARCH64_X0_REGNUM + 29,
|
||||
AARCH64_LR_REGNUM = AARCH64_X0_REGNUM + 30, /* Return address */
|
||||
AARCH64_SP_REGNUM, /* Stack pointer */
|
||||
AARCH64_PC_REGNUM, /* Program counter */
|
||||
AARCH64_CPSR_REGNUM, /* Contains status register */
|
||||
AARCH64_V0_REGNUM, /* First floating point / vector register */
|
||||
|
||||
/* Last floating point / vector register */
|
||||
AARCH64_V31_REGNUM = AARCH64_V0_REGNUM + 31,
|
||||
AARCH64_FPSR_REGNUM, /* Floating point status register */
|
||||
AARCH64_FPCR_REGNUM, /* Floating point control register */
|
||||
|
||||
/* Other useful registers. */
|
||||
|
||||
/* Last integer-like argument */
|
||||
AARCH64_LAST_X_ARG_REGNUM = AARCH64_X0_REGNUM + 7,
|
||||
AARCH64_STRUCT_RETURN_REGNUM = AARCH64_X0_REGNUM + 8,
|
||||
AARCH64_LAST_V_ARG_REGNUM = AARCH64_V0_REGNUM + 7
|
||||
};
|
||||
|
||||
/* Size of integer registers. */
|
||||
#define X_REGISTER_SIZE 8
|
||||
#define B_REGISTER_SIZE 1
|
||||
#define H_REGISTER_SIZE 2
|
||||
#define S_REGISTER_SIZE 4
|
||||
#define D_REGISTER_SIZE 8
|
||||
#define V_REGISTER_SIZE 16
|
||||
#define Q_REGISTER_SIZE 16
|
||||
|
||||
/* Total number of general (X) registers. */
|
||||
#define AARCH64_X_REGISTER_COUNT 32
|
||||
|
||||
/* Target-dependent structure in gdbarch. */
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
/* Lowest address at which instructions will appear. */
|
||||
CORE_ADDR lowest_pc;
|
||||
|
||||
/* Offset to PC value in jump buffer. If this is negative, longjmp
|
||||
support will be disabled. */
|
||||
int jb_pc;
|
||||
|
||||
/* And the size of each entry in the buf. */
|
||||
size_t jb_elt_size;
|
||||
|
||||
/* Cached core file helpers. */
|
||||
struct regset *gregset;
|
||||
struct regset *fpregset;
|
||||
|
||||
/* Types for AdvSISD registers. */
|
||||
struct type *vnq_type;
|
||||
struct type *vnd_type;
|
||||
struct type *vns_type;
|
||||
struct type *vnh_type;
|
||||
struct type *vnb_type;
|
||||
};
|
||||
|
||||
#endif /* aarch64-tdep.h */
|
||||
473
gdb/acinclude.m4
473
gdb/acinclude.m4
@@ -1,473 +0,0 @@
|
||||
dnl written by Rob Savoye <rob@cygnus.com> for Cygnus Support
|
||||
dnl major rewriting for Tcl 7.5 by Don Libes <libes@nist.gov>
|
||||
|
||||
# Keep these includes in sync with the aclocal_m4_deps list in
|
||||
# Makefile.in.
|
||||
|
||||
sinclude(acx_configure_dir.m4)
|
||||
|
||||
# This gets GDB_AC_LIBMCHECK.
|
||||
sinclude(libmcheck.m4)
|
||||
|
||||
dnl gdb/configure.in uses BFD_NEED_DECLARATION, so get its definition.
|
||||
sinclude(../bfd/bfd.m4)
|
||||
|
||||
dnl This gets the standard macros.
|
||||
sinclude(../config/acinclude.m4)
|
||||
|
||||
dnl This gets AC_PLUGINS, needed by ACX_LARGEFILE.
|
||||
sinclude(../config/plugins.m4)
|
||||
|
||||
dnl For ACX_LARGEFILE.
|
||||
sinclude(../config/largefile.m4)
|
||||
|
||||
dnl For AM_SET_LEADING_DOT.
|
||||
sinclude(../config/lead-dot.m4)
|
||||
|
||||
dnl This gets autoconf bugfixes.
|
||||
sinclude(../config/override.m4)
|
||||
|
||||
dnl For ZW_GNU_GETTEXT_SISTER_DIR.
|
||||
sinclude(../config/gettext-sister.m4)
|
||||
|
||||
dnl For AC_LIB_HAVE_LINKFLAGS.
|
||||
sinclude(../config/lib-ld.m4)
|
||||
sinclude(../config/lib-prefix.m4)
|
||||
sinclude(../config/lib-link.m4)
|
||||
|
||||
dnl For ACX_PKGVERSION and ACX_BUGURL.
|
||||
sinclude(../config/acx.m4)
|
||||
|
||||
dnl for TCL definitions
|
||||
sinclude(../config/tcl.m4)
|
||||
|
||||
dnl For dependency tracking macros.
|
||||
sinclude([../config/depstand.m4])
|
||||
|
||||
dnl For AM_LC_MESSAGES
|
||||
sinclude([../config/lcmessage.m4])
|
||||
|
||||
dnl For AM_LANGINFO_CODESET.
|
||||
sinclude([../config/codeset.m4])
|
||||
|
||||
sinclude([../config/zlib.m4])
|
||||
|
||||
## ----------------------------------------- ##
|
||||
## ANSIfy the C compiler whenever possible. ##
|
||||
## From Franc,ois Pinard ##
|
||||
## ----------------------------------------- ##
|
||||
|
||||
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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.
|
||||
|
||||
# This program 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; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# serial 1
|
||||
|
||||
# @defmac AC_PROG_CC_STDC
|
||||
# @maindex PROG_CC_STDC
|
||||
# @ovindex CC
|
||||
# If the C compiler in not in ANSI C mode by default, try to add an option
|
||||
# to output variable @code{CC} to make it so. This macro tries various
|
||||
# options that select ANSI C on some system or another. It considers the
|
||||
# compiler to be in ANSI C mode if it handles function prototypes correctly.
|
||||
#
|
||||
# If you use this macro, you should check after calling it whether the C
|
||||
# compiler has been set to accept ANSI C; if not, the shell variable
|
||||
# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
|
||||
# code in ANSI C, you can make an un-ANSIfied copy of it by using the
|
||||
# program @code{ansi2knr}, which comes with Ghostscript.
|
||||
# @end defmac
|
||||
|
||||
AC_DEFUN([AM_PROG_CC_STDC],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_BEFORE([$0], [AC_C_INLINE])
|
||||
AC_BEFORE([$0], [AC_C_CONST])
|
||||
dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
|
||||
dnl a magic option to avoid problems with ANSI preprocessor commands
|
||||
dnl like #elif.
|
||||
dnl FIXME: can't do this because then AC_AIX won't work due to a
|
||||
dnl circular dependency.
|
||||
dnl AC_BEFORE([$0], [AC_PROG_CPP])
|
||||
AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C])
|
||||
AC_CACHE_VAL(am_cv_prog_cc_stdc,
|
||||
[am_cv_prog_cc_stdc=no
|
||||
ac_save_CC="$CC"
|
||||
# Don't try gcc -ansi; that turns off useful extensions and
|
||||
# breaks some systems' header files.
|
||||
# AIX -qlanglvl=ansi
|
||||
# Ultrix and OSF/1 -std1
|
||||
# HP-UX 10.20 and later -Ae
|
||||
# HP-UX older versions -Aa -D_HPUX_SOURCE
|
||||
# SVR4 -Xc -D__EXTENSIONS__
|
||||
for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
|
||||
do
|
||||
CC="$ac_save_CC $ac_arg"
|
||||
AC_TRY_COMPILE(
|
||||
[#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
|
||||
struct buf { int x; };
|
||||
FILE * (*rcsopen) (struct buf *, struct stat *, int);
|
||||
static char *e (p, i)
|
||||
char **p;
|
||||
int i;
|
||||
{
|
||||
return p[i];
|
||||
}
|
||||
static char *f (char * (*g) (char **, int), char **p, ...)
|
||||
{
|
||||
char *s;
|
||||
va_list v;
|
||||
va_start (v,p);
|
||||
s = g (p, va_arg (v,int));
|
||||
va_end (v);
|
||||
return s;
|
||||
}
|
||||
int test (int i, double x);
|
||||
struct s1 {int (*f) (int a);};
|
||||
struct s2 {int (*f) (double a);};
|
||||
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
|
||||
int argc;
|
||||
char **argv;
|
||||
], [
|
||||
return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
|
||||
],
|
||||
[am_cv_prog_cc_stdc="$ac_arg"; break])
|
||||
done
|
||||
CC="$ac_save_CC"
|
||||
])
|
||||
if test -z "$am_cv_prog_cc_stdc"; then
|
||||
AC_MSG_RESULT([none needed])
|
||||
else
|
||||
AC_MSG_RESULT([$am_cv_prog_cc_stdc])
|
||||
fi
|
||||
case "x$am_cv_prog_cc_stdc" in
|
||||
x|xno) ;;
|
||||
*) CC="$CC $am_cv_prog_cc_stdc" ;;
|
||||
esac
|
||||
])
|
||||
|
||||
dnl Originally from Bruno Haible, but with some modifications
|
||||
dnl for the GDB project.
|
||||
|
||||
AC_DEFUN([AM_ICONV],
|
||||
[
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
|
||||
AC_ARG_WITH([libiconv-prefix],
|
||||
AS_HELP_STRING([--with-libiconv-prefix=DIR], [search for libiconv in DIR/include and DIR/lib]), [
|
||||
for dir in `echo "$withval" | tr : ' '`; do
|
||||
if test -d $dir/include; then LIBICONV_INCLUDE="-I$dir/include"; fi
|
||||
if test -d $dir/lib; then LIBICONV_LIBDIR="-L$dir/lib"; fi
|
||||
done
|
||||
])
|
||||
|
||||
BUILD_LIBICONV_LIBDIRS="../libiconv/lib/.libs ../libiconv/lib/_libs"
|
||||
BUILD_LIBICONV_INCLUDE="-I../libiconv/include"
|
||||
|
||||
AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
|
||||
am_cv_func_iconv="no, consider installing GNU libiconv"
|
||||
am_cv_lib_iconv=no
|
||||
am_cv_use_build_libiconv=no
|
||||
am_cv_build_libiconv_path=
|
||||
|
||||
# If libiconv is part of the build tree, then try using it over
|
||||
# any system iconv.
|
||||
if test -d ../libiconv; then
|
||||
for lib_dir in $BUILD_LIBICONV_LIBDIRS; do
|
||||
am_save_LIBS="$LIBS"
|
||||
am_save_CPPFLAGS="$CPPFLAGS"
|
||||
LIBS="$LIBS $lib_dir/libiconv.a"
|
||||
CPPFLAGS="$CPPFLAGS $BUILD_LIBICONV_INCLUDE"
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
am_cv_use_build_libiconv=yes
|
||||
am_cv_build_libiconv_path=$lib_dir/libiconv.a
|
||||
am_cv_lib_iconv=yes
|
||||
am_cv_func_iconv=yes)
|
||||
LIBS="$am_save_LIBS"
|
||||
CPPFLAGS="$am_save_CPPFLAGS"
|
||||
if test "$am_cv_use_build_libiconv" = "yes"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Next, try to find iconv in libc.
|
||||
if test "$am_cv_func_iconv" != yes; then
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
am_cv_func_iconv=yes)
|
||||
fi
|
||||
|
||||
# If iconv was not in libc, try -liconv. In this case, arrange to
|
||||
# look in the libiconv prefix, if it was specified by the user.
|
||||
if test "$am_cv_func_iconv" != yes; then
|
||||
am_save_CPPFLAGS="$CPPFLAGS"
|
||||
am_save_LIBS="$LIBS"
|
||||
if test -n "$LIBICONV_INCLUDE"; then
|
||||
CPPFLAGS="$CPPFLAGS $LIBICONV_INCLUDE"
|
||||
LIBS="$LIBS $LIBICONV_LIBDIR"
|
||||
fi
|
||||
LIBS="$LIBS -liconv"
|
||||
AC_TRY_LINK([#include <stdlib.h>
|
||||
#include <iconv.h>],
|
||||
[iconv_t cd = iconv_open("","");
|
||||
iconv(cd,NULL,NULL,NULL,NULL);
|
||||
iconv_close(cd);],
|
||||
am_cv_lib_iconv=yes
|
||||
am_cv_func_iconv=yes)
|
||||
LIBS="$am_save_LIBS"
|
||||
CPPFLAGS="$am_save_CPPFLAGS"
|
||||
fi
|
||||
])
|
||||
|
||||
# Set the various flags based on the cache variables. We can't rely
|
||||
# on the flags to remain set from the above code, due to caching.
|
||||
LIBICONV=
|
||||
if test "$am_cv_lib_iconv" = yes; then
|
||||
LIBICONV="-liconv"
|
||||
else
|
||||
LIBICONV_LIBDIR=
|
||||
LIBICONV_INCLUDE=
|
||||
fi
|
||||
if test "$am_cv_use_build_libiconv" = yes; then
|
||||
LIBICONV="$am_cv_build_libiconv_path"
|
||||
LIBICONV_LIBDIR=""
|
||||
LIBICONV_INCLUDE="$BUILD_LIBICONV_INCLUDE"
|
||||
fi
|
||||
CPPFLAGS="$CPPFLAGS $LIBICONV_INCLUDE"
|
||||
LIBS="$LIBS $LIBICONV_LIBDIR $LIBICONV"
|
||||
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
|
||||
AC_MSG_CHECKING([for iconv declaration])
|
||||
AC_CACHE_VAL(am_cv_proto_iconv, [
|
||||
AC_TRY_COMPILE([
|
||||
#include <stdlib.h>
|
||||
#include <iconv.h>
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
|
||||
#else
|
||||
size_t iconv();
|
||||
#endif
|
||||
], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
|
||||
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
|
||||
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
|
||||
AC_MSG_RESULT([$]{ac_t:-
|
||||
}[$]am_cv_proto_iconv)
|
||||
AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
|
||||
[Define as const if the declaration of iconv() needs const.])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva
|
||||
dnl Version 1.3 (2001/03/02)
|
||||
dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
|
||||
|
||||
AC_DEFUN([AC_DEFINE_DIR], [
|
||||
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
|
||||
ac_define_dir=`eval echo [$]$2`
|
||||
ac_define_dir=`eval echo [$]ac_define_dir`
|
||||
ifelse($3, ,
|
||||
AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
|
||||
AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
|
||||
])
|
||||
|
||||
dnl See whether we need a declaration for a function.
|
||||
dnl The result is highly dependent on the INCLUDES passed in, so make sure
|
||||
dnl to use a different cache variable name in this macro if it is invoked
|
||||
dnl in a different context somewhere else.
|
||||
dnl gcc_AC_CHECK_DECL(SYMBOL,
|
||||
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECL],
|
||||
[AC_MSG_CHECKING([whether $1 is declared])
|
||||
AC_CACHE_VAL(gcc_cv_have_decl_$1,
|
||||
[AC_TRY_COMPILE([$4],
|
||||
[#ifndef $1
|
||||
char *(*pfn) = (char *(*)) $1 ;
|
||||
#endif], eval "gcc_cv_have_decl_$1=yes", eval "gcc_cv_have_decl_$1=no")])
|
||||
if eval "test \"`echo '$gcc_cv_have_decl_'$1`\" = yes"; then
|
||||
AC_MSG_RESULT(yes) ; ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no) ; ifelse([$3], , :, [$3])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Check multiple functions to see whether each needs a declaration.
|
||||
dnl Arrange to define HAVE_DECL_<FUNCTION> to 0 or 1 as appropriate.
|
||||
dnl gcc_AC_CHECK_DECLS(SYMBOLS,
|
||||
dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]])
|
||||
AC_DEFUN([gcc_AC_CHECK_DECLS],
|
||||
[for ac_func in $1
|
||||
do
|
||||
changequote(, )dnl
|
||||
ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
|
||||
changequote([, ])dnl
|
||||
gcc_AC_CHECK_DECL($ac_func,
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 1) $2],
|
||||
[AC_DEFINE_UNQUOTED($ac_tr_decl, 0) $3],
|
||||
dnl It is possible that the include files passed in here are local headers
|
||||
dnl which supply a backup declaration for the relevant prototype based on
|
||||
dnl the definition of (or lack of) the HAVE_DECL_ macro. If so, this test
|
||||
dnl will always return success. E.g. see libiberty.h's handling of
|
||||
dnl `basename'. To avoid this, we define the relevant HAVE_DECL_ macro to
|
||||
dnl 1 so that any local headers used do not provide their own prototype
|
||||
dnl during this test.
|
||||
#undef $ac_tr_decl
|
||||
#define $ac_tr_decl 1
|
||||
$4
|
||||
)
|
||||
done
|
||||
dnl Automatically generate config.h entries via autoheader.
|
||||
if test x = y ; then
|
||||
patsubst(translit([$1], [a-z], [A-Z]), [\w+],
|
||||
[AC_DEFINE([HAVE_DECL_\&], 1,
|
||||
[Define to 1 if we found this declaration otherwise define to 0.])])dnl
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Find the location of the private Tcl headers
|
||||
dnl When Tcl is installed, this is TCL_INCLUDE_SPEC/tcl-private/generic
|
||||
dnl When Tcl is in the build tree, this is not needed.
|
||||
dnl
|
||||
dnl Note: you must use first use SC_LOAD_TCLCONFIG!
|
||||
AC_DEFUN([CY_AC_TCL_PRIVATE_HEADERS], [
|
||||
AC_MSG_CHECKING([for Tcl private headers])
|
||||
private_dir=""
|
||||
dir=`echo ${TCL_INCLUDE_SPEC}/tcl-private/generic | sed -e s/-I//`
|
||||
if test -f ${dir}/tclInt.h ; then
|
||||
private_dir=${dir}
|
||||
fi
|
||||
|
||||
if test x"${private_dir}" = x; then
|
||||
AC_ERROR(could not find private Tcl headers)
|
||||
else
|
||||
TCL_PRIVATE_INCLUDE="-I${private_dir}"
|
||||
AC_MSG_RESULT(${private_dir})
|
||||
fi
|
||||
])
|
||||
|
||||
dnl Find the location of the private Tk headers
|
||||
dnl When Tk is installed, this is TK_INCLUDE_SPEC/tk-private/generic
|
||||
dnl When Tk is in the build tree, this not needed.
|
||||
dnl
|
||||
dnl Note: you must first use SC_LOAD_TKCONFIG
|
||||
AC_DEFUN([CY_AC_TK_PRIVATE_HEADERS], [
|
||||
AC_MSG_CHECKING([for Tk private headers])
|
||||
private_dir=""
|
||||
dir=`echo ${TK_INCLUDE_SPEC}/tk-private/generic | sed -e s/-I//`
|
||||
if test -f ${dir}/tkInt.h; then
|
||||
private_dir=${dir}
|
||||
fi
|
||||
|
||||
if test x"${private_dir}" = x; then
|
||||
AC_ERROR(could not find Tk private headers)
|
||||
else
|
||||
TK_PRIVATE_INCLUDE="-I${private_dir}"
|
||||
AC_MSG_RESULT(${private_dir})
|
||||
fi
|
||||
])
|
||||
|
||||
dnl GDB_AC_DEFINE_RELOCATABLE([VARIABLE], [ARG-NAME], [SHELL-VARIABLE])
|
||||
dnl For use in processing directory values for --with-foo.
|
||||
dnl If the path in SHELL_VARIABLE is relative to the prefix, then the
|
||||
dnl result is relocatable, then this will define the C macro
|
||||
dnl VARIABLE_RELOCATABLE to 1; otherwise it is defined as 0.
|
||||
AC_DEFUN([GDB_AC_DEFINE_RELOCATABLE], [
|
||||
if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then
|
||||
if test "x$prefix" = xNONE; then
|
||||
test_prefix=/usr/local
|
||||
else
|
||||
test_prefix=$prefix
|
||||
fi
|
||||
else
|
||||
test_prefix=$exec_prefix
|
||||
fi
|
||||
value=0
|
||||
case [$3] in
|
||||
"${test_prefix}"|"${test_prefix}/"*|\
|
||||
'${exec_prefix}'|'${exec_prefix}/'*)
|
||||
value=1
|
||||
;;
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED([$1]_RELOCATABLE, $value, [Define if the $2 directory should be relocated when GDB is moved.])
|
||||
])
|
||||
|
||||
dnl GDB_AC_WITH_DIR([VARIABLE], [ARG-NAME], [HELP], [DEFAULT])
|
||||
dnl Add a new --with option that defines a directory.
|
||||
dnl The result is stored in VARIABLE. AC_DEFINE_DIR is called
|
||||
dnl on this variable, as is AC_SUBST.
|
||||
dnl ARG-NAME is the base name of the argument (without "--with").
|
||||
dnl HELP is the help text to use.
|
||||
dnl If the user's choice is relative to the prefix, then the
|
||||
dnl result is relocatable, then this will define the C macro
|
||||
dnl VARIABLE_RELOCATABLE to 1; otherwise it is defined as 0.
|
||||
dnl DEFAULT is the default value, which is used if the user
|
||||
dnl does not specify the argument.
|
||||
AC_DEFUN([GDB_AC_WITH_DIR], [
|
||||
AC_ARG_WITH([$2], AS_HELP_STRING([--with-][$2][=PATH], [$3]), [
|
||||
[$1]=$withval], [[$1]=[$4]])
|
||||
AC_DEFINE_DIR([$1], [$1], [$3])
|
||||
AC_SUBST([$1])
|
||||
GDB_AC_DEFINE_RELOCATABLE([$1], [$2], ${ac_define_dir})
|
||||
])
|
||||
|
||||
dnl GDB_AC_CHECK_BFD([MESSAGE], [CV], [CODE], [HEADER])
|
||||
dnl Check whether BFD provides a feature.
|
||||
dnl MESSAGE is the "checking" message to display.
|
||||
dnl CV is the name of the cache variable where the result is stored.
|
||||
dnl The result will be "yes" or "no".
|
||||
dnl CODE is some code to compile that checks for the feature.
|
||||
dnl A link test is run.
|
||||
dnl HEADER is the name of an extra BFD header to include.
|
||||
AC_DEFUN([GDB_AC_CHECK_BFD], [
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
OLD_LDFLAGS=$LDFLAGS
|
||||
OLD_LIBS=$LIBS
|
||||
# Put the old CFLAGS/LDFLAGS last, in case the user's (C|LD)FLAGS
|
||||
# points somewhere with bfd, with -I/foo/lib and -L/foo/lib. We
|
||||
# always want our bfd.
|
||||
CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS"
|
||||
LDFLAGS="-L../bfd -L../libiberty $LDFLAGS"
|
||||
intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'`
|
||||
# -ldl is provided by bfd/Makfile.am (LIBDL) <PLUGINS>.
|
||||
if test "$plugins" = "yes"; then
|
||||
AC_SEARCH_LIBS(dlopen, dl)
|
||||
fi
|
||||
LIBS="-lbfd -liberty $intl $LIBS"
|
||||
AC_CACHE_CHECK([$1], [$2],
|
||||
[AC_TRY_LINK(
|
||||
[#include <stdlib.h>
|
||||
#include "bfd.h"
|
||||
#include "$4"
|
||||
],
|
||||
[return $3;], [[$2]=yes], [[$2]=no])])
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
LDFLAGS=$OLD_LDFLAGS
|
||||
LIBS=$OLD_LIBS])
|
||||
109
gdb/aclocal.m4
vendored
109
gdb/aclocal.m4
vendored
@@ -1,109 +0,0 @@
|
||||
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 9
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ(2.52)dnl
|
||||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5
|
||||
|
||||
# AM_MAINTAINER_MODE([DEFAULT-MODE])
|
||||
# ----------------------------------
|
||||
# Control maintainer-specific portions of Makefiles.
|
||||
# Default is to disable them, unless `enable' is passed literally.
|
||||
# For symmetry, `disable' may be passed as well. Anyway, the user
|
||||
# can override the default with the --enable/--disable switch.
|
||||
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||
[m4_case(m4_default([$1], [disable]),
|
||||
[enable], [m4_define([am_maintainer_other], [disable])],
|
||||
[disable], [m4_define([am_maintainer_other], [enable])],
|
||||
[m4_define([am_maintainer_other], [enable])
|
||||
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
|
||||
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
|
||||
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
|
||||
AC_ARG_ENABLE([maintainer-mode],
|
||||
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer],
|
||||
[USE_MAINTAINER_MODE=$enableval],
|
||||
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
|
||||
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||
MAINT=$MAINTAINER_MODE_TRUE
|
||||
AC_SUBST([MAINT])dnl
|
||||
]
|
||||
)
|
||||
|
||||
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||
|
||||
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
m4_include([acinclude.m4])
|
||||
@@ -1,115 +0,0 @@
|
||||
# Copyright (C) 1992-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# ACX_CONFIGURE_DIR(SRC-DIR-NAME, BUILD-DIR-NAME)
|
||||
# ---------------------------
|
||||
#
|
||||
# Configure a subdirectory. This is an alternative to
|
||||
# AC_CONFIG_SUBDIRS that allows pointing the source directory
|
||||
# somewhere else. The build directory is always a subdirectory of the
|
||||
# top build directory. This is heavilly based on Autoconf 2.64's
|
||||
# _AC_OUTPUT_SUBDIRS.
|
||||
#
|
||||
# Inputs:
|
||||
# - SRC-DIR-NAME is the source directory, relative to $srcdir.
|
||||
# - BUILD-DIR-NAME is `top-build -> build'
|
||||
|
||||
AC_DEFUN([ACX_CONFIGURE_DIR],
|
||||
[
|
||||
in_src=$1
|
||||
in_build=$2
|
||||
|
||||
# Remove --cache-file, --srcdir, and --disable-option-checking arguments
|
||||
# so they do not pile up.
|
||||
ac_sub_configure_args=
|
||||
ac_prev=
|
||||
eval "set x $ac_configure_args"
|
||||
shift
|
||||
for ac_arg
|
||||
do
|
||||
if test -n "$ac_prev"; then
|
||||
ac_prev=
|
||||
continue
|
||||
fi
|
||||
case $ac_arg in
|
||||
-cache-file | --cache-file | --cache-fil | --cache-fi \
|
||||
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
|
||||
ac_prev=cache_file ;;
|
||||
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
|
||||
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
|
||||
| --c=*)
|
||||
;;
|
||||
--config-cache | -C)
|
||||
;;
|
||||
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
|
||||
ac_prev=srcdir ;;
|
||||
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
|
||||
;;
|
||||
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
|
||||
ac_prev=prefix ;;
|
||||
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
|
||||
;;
|
||||
--disable-option-checking)
|
||||
;;
|
||||
*)
|
||||
case $ac_arg in
|
||||
*\'*) ac_arg=`AS_ECHO(["$ac_arg"]) | sed "s/'/'\\\\\\\\''/g"` ;;
|
||||
esac
|
||||
AS_VAR_APPEND([ac_sub_configure_args], [" '$ac_arg'"]) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Always prepend --prefix to ensure using the same prefix
|
||||
# in subdir configurations.
|
||||
ac_arg="--prefix=$prefix"
|
||||
case $ac_arg in
|
||||
*\'*) ac_arg=`AS_ECHO(["$ac_arg"]) | sed "s/'/'\\\\\\\\''/g"` ;;
|
||||
esac
|
||||
ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
|
||||
|
||||
# Pass --silent
|
||||
if test "$silent" = yes; then
|
||||
ac_sub_configure_args="--silent $ac_sub_configure_args"
|
||||
fi
|
||||
|
||||
# Always prepend --disable-option-checking to silence warnings, since
|
||||
# different subdirs can have different --enable and --with options.
|
||||
ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
|
||||
|
||||
ac_popdir=`pwd`
|
||||
ac_dir=$in_build
|
||||
|
||||
ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
|
||||
_AS_ECHO_LOG([$ac_msg])
|
||||
_AS_ECHO([$ac_msg])
|
||||
AS_MKDIR_P(["$ac_dir"])
|
||||
|
||||
case $srcdir in
|
||||
[[\\/]]* | ?:[[\\/]]* )
|
||||
ac_srcdir=$srcdir/$in_src ;;
|
||||
*) # Relative name.
|
||||
ac_srcdir=../$srcdir/$in_src ;;
|
||||
esac
|
||||
|
||||
cd "$ac_dir"
|
||||
|
||||
ac_sub_configure=$ac_srcdir/configure
|
||||
|
||||
# Make the cache file name correct relative to the subdirectory.
|
||||
case $cache_file in
|
||||
[[\\/]]* | ?:[[\\/]]* ) ac_sub_cache_file=$cache_file ;;
|
||||
*) # Relative name.
|
||||
ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
|
||||
esac
|
||||
|
||||
AC_MSG_NOTICE([running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir])
|
||||
# The eval makes quoting arguments work.
|
||||
eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
|
||||
--cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
|
||||
AC_MSG_ERROR([$ac_sub_configure failed for $ac_dir])
|
||||
|
||||
cd "$ac_popdir"
|
||||
])# ACX_CONFIGURE_DIR
|
||||
1544
gdb/ada-exp.y
1544
gdb/ada-exp.y
File diff suppressed because it is too large
Load Diff
12943
gdb/ada-lang.c
12943
gdb/ada-lang.c
File diff suppressed because it is too large
Load Diff
393
gdb/ada-lang.h
393
gdb/ada-lang.h
@@ -1,393 +0,0 @@
|
||||
/* Ada language support definitions for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1992-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#if !defined (ADA_LANG_H)
|
||||
#define ADA_LANG_H 1
|
||||
|
||||
struct frame_info;
|
||||
struct inferior;
|
||||
struct type_print_options;
|
||||
|
||||
#include "value.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "breakpoint.h"
|
||||
|
||||
/* Names of specific files known to be part of the runtime
|
||||
system and that might consider (confusing) debugging information.
|
||||
Each name (a basic regular expression string) is followed by a
|
||||
comma. FIXME: Should be part of a configuration file. */
|
||||
#if defined(__alpha__) && defined(__osf__)
|
||||
#define ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS \
|
||||
"^[agis]-.*\\.ad[bs]$", \
|
||||
"/usr/shlib/libpthread\\.so",
|
||||
#elif defined (__linux__)
|
||||
#define ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS \
|
||||
"^[agis]-.*\\.ad[bs]$", \
|
||||
"/lib.*/libpthread\\.so[.0-9]*$", "/lib.*/libpthread\\.a$", \
|
||||
"/lib.*/libc\\.so[.0-9]*$", "/lib.*/libc\\.a$",
|
||||
#endif
|
||||
|
||||
#if !defined (ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS)
|
||||
#define ADA_KNOWN_RUNTIME_FILE_NAME_PATTERNS \
|
||||
"^unwind-seh.c$", \
|
||||
"^[agis]-.*\\.ad[bs]$",
|
||||
#endif
|
||||
|
||||
/* Names of compiler-generated auxiliary functions probably of no
|
||||
interest to users. Each name (a basic regular expression string)
|
||||
is followed by a comma. */
|
||||
#define ADA_KNOWN_AUXILIARY_FUNCTION_NAME_PATTERNS \
|
||||
"___clean[.$a-zA-Z0-9_]*$", \
|
||||
"___finalizer[.$a-zA-Z0-9_]*$",
|
||||
|
||||
/* The maximum number of frame levels searched for non-local,
|
||||
* non-global symbols. This limit exists as a precaution to prevent
|
||||
* infinite search loops when the stack is screwed up. */
|
||||
#define MAX_ENCLOSING_FRAME_LEVELS 7
|
||||
|
||||
/* Maximum number of steps followed in looking for the ultimate
|
||||
referent of a renaming. This prevents certain infinite loops that
|
||||
can otherwise result. */
|
||||
#define MAX_RENAMING_CHAIN_LENGTH 10
|
||||
|
||||
struct block;
|
||||
|
||||
/* Corresponding encoded/decoded names and opcodes for Ada user-definable
|
||||
operators. */
|
||||
struct ada_opname_map
|
||||
{
|
||||
const char *encoded;
|
||||
const char *decoded;
|
||||
enum exp_opcode op;
|
||||
};
|
||||
|
||||
/* Table of Ada operators in encoded and decoded forms. */
|
||||
/* Defined in ada-lang.c */
|
||||
extern const struct ada_opname_map ada_opname_table[];
|
||||
|
||||
/* A tuple representing one instance of a symbol-lookup operation. */
|
||||
|
||||
struct ada_symbol_info
|
||||
{
|
||||
/* The symbol that was found. */
|
||||
struct symbol *sym;
|
||||
|
||||
/* The block where the symbol was found. */
|
||||
const struct block *block;
|
||||
};
|
||||
|
||||
/* Denotes a type of renaming symbol (see ada_parse_renaming). */
|
||||
enum ada_renaming_category
|
||||
{
|
||||
/* Indicates a symbol that does not encode a renaming. */
|
||||
ADA_NOT_RENAMING,
|
||||
|
||||
/* For symbols declared
|
||||
Foo : TYPE renamed OBJECT; */
|
||||
ADA_OBJECT_RENAMING,
|
||||
|
||||
/* For symbols declared
|
||||
Foo : exception renames EXCEPTION; */
|
||||
ADA_EXCEPTION_RENAMING,
|
||||
/* For packages declared
|
||||
package Foo renames PACKAGE; */
|
||||
ADA_PACKAGE_RENAMING,
|
||||
/* For subprograms declared
|
||||
SUBPROGRAM_SPEC renames SUBPROGRAM;
|
||||
(Currently not used). */
|
||||
ADA_SUBPROGRAM_RENAMING
|
||||
};
|
||||
|
||||
/* Ada task structures. */
|
||||
|
||||
struct ada_task_info
|
||||
{
|
||||
/* The PTID of the thread that this task runs on. This ptid is computed
|
||||
in a target-dependent way from the associated Task Control Block. */
|
||||
ptid_t ptid;
|
||||
|
||||
/* The ID of the task. */
|
||||
CORE_ADDR task_id;
|
||||
|
||||
/* The name of the task. */
|
||||
char name[257];
|
||||
|
||||
/* The current state of the task. */
|
||||
int state;
|
||||
|
||||
/* The priority associated to the task. */
|
||||
int priority;
|
||||
|
||||
/* If non-zero, the task ID of the parent task. */
|
||||
CORE_ADDR parent;
|
||||
|
||||
/* If the task is waiting on a task entry, this field contains
|
||||
the ID of the other task. Zero otherwise. */
|
||||
CORE_ADDR called_task;
|
||||
|
||||
/* If the task is accepting a rendezvous with another task, this field
|
||||
contains the ID of the calling task. Zero otherwise. */
|
||||
CORE_ADDR caller_task;
|
||||
};
|
||||
|
||||
/* Assuming V points to an array of S objects, make sure that it contains at
|
||||
least M objects, updating V and S as necessary. */
|
||||
|
||||
#define GROW_VECT(v, s, m) \
|
||||
if ((s) < (m)) (v) = grow_vect (v, &(s), m, sizeof *(v));
|
||||
|
||||
extern void *grow_vect (void *, size_t *, size_t, int);
|
||||
|
||||
extern int ada_get_field_index (const struct type *type,
|
||||
const char *field_name,
|
||||
int maybe_missing);
|
||||
|
||||
extern int ada_parse (void); /* Defined in ada-exp.y */
|
||||
|
||||
extern void ada_error (char *); /* Defined in ada-exp.y */
|
||||
|
||||
/* Defined in ada-typeprint.c */
|
||||
extern void ada_print_type (struct type *, const char *, struct ui_file *, int,
|
||||
int, const struct type_print_options *);
|
||||
|
||||
extern void ada_print_typedef (struct type *type, struct symbol *new_symbol,
|
||||
struct ui_file *stream);
|
||||
|
||||
extern void ada_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
|
||||
struct ui_file *, int,
|
||||
const struct value *,
|
||||
const struct value_print_options *);
|
||||
|
||||
extern void ada_value_print (struct value *, struct ui_file *,
|
||||
const struct value_print_options *);
|
||||
|
||||
/* Defined in ada-lang.c */
|
||||
|
||||
extern void ada_emit_char (int, struct type *, struct ui_file *, int, int);
|
||||
|
||||
extern void ada_printchar (int, struct type *, struct ui_file *);
|
||||
|
||||
extern void ada_printstr (struct ui_file *, struct type *, const gdb_byte *,
|
||||
unsigned int, const char *, int,
|
||||
const struct value_print_options *);
|
||||
|
||||
struct value *ada_convert_actual (struct value *actual,
|
||||
struct type *formal_type0);
|
||||
|
||||
extern struct value *ada_value_subscript (struct value *, int,
|
||||
struct value **);
|
||||
|
||||
extern void ada_fixup_array_indexes_type (struct type *index_desc_type);
|
||||
|
||||
extern struct type *ada_array_element_type (struct type *, int);
|
||||
|
||||
extern int ada_array_arity (struct type *);
|
||||
|
||||
struct type *ada_type_of_array (struct value *, int);
|
||||
|
||||
extern struct value *ada_coerce_to_simple_array_ptr (struct value *);
|
||||
|
||||
struct value *ada_coerce_to_simple_array (struct value *);
|
||||
|
||||
extern int ada_is_simple_array_type (struct type *);
|
||||
|
||||
extern int ada_is_array_descriptor_type (struct type *);
|
||||
|
||||
extern int ada_is_bogus_array_descriptor (struct type *);
|
||||
|
||||
extern LONGEST ada_discrete_type_low_bound (struct type *);
|
||||
|
||||
extern LONGEST ada_discrete_type_high_bound (struct type *);
|
||||
|
||||
extern struct value *ada_get_decoded_value (struct value *value);
|
||||
|
||||
extern struct type *ada_get_decoded_type (struct type *type);
|
||||
|
||||
extern const char *ada_decode_symbol (const struct general_symbol_info *);
|
||||
|
||||
extern const char *ada_decode (const char*);
|
||||
|
||||
extern enum language ada_update_initial_language (enum language);
|
||||
|
||||
extern void clear_ada_sym_cache (void);
|
||||
|
||||
extern int ada_lookup_symbol_list (const char *, const struct block *,
|
||||
domain_enum, struct ada_symbol_info**);
|
||||
|
||||
extern char *ada_fold_name (const char *);
|
||||
|
||||
extern struct symbol *ada_lookup_symbol (const char *, const struct block *,
|
||||
domain_enum, int *);
|
||||
|
||||
extern void ada_lookup_encoded_symbol
|
||||
(const char *name, const struct block *block, domain_enum namespace,
|
||||
struct ada_symbol_info *symbol_info);
|
||||
|
||||
extern struct bound_minimal_symbol ada_lookup_simple_minsym (const char *);
|
||||
|
||||
extern void ada_fill_in_ada_prototype (struct symbol *);
|
||||
|
||||
extern int user_select_syms (struct ada_symbol_info *, int, int);
|
||||
|
||||
extern int get_selections (int *, int, int, int, char *);
|
||||
|
||||
extern int ada_scan_number (const char *, int, LONGEST *, int *);
|
||||
|
||||
extern struct type *ada_parent_type (struct type *);
|
||||
|
||||
extern int ada_is_ignored_field (struct type *, int);
|
||||
|
||||
extern int ada_is_constrained_packed_array_type (struct type *);
|
||||
|
||||
extern struct value *ada_value_primitive_packed_val (struct value *,
|
||||
const gdb_byte *,
|
||||
long, int, int,
|
||||
struct type *);
|
||||
|
||||
extern struct type *ada_coerce_to_simple_array_type (struct type *);
|
||||
|
||||
extern int ada_is_character_type (struct type *);
|
||||
|
||||
extern int ada_is_string_type (struct type *);
|
||||
|
||||
extern int ada_is_tagged_type (struct type *, int);
|
||||
|
||||
extern int ada_is_tag_type (struct type *);
|
||||
|
||||
extern struct type *ada_tag_type (struct value *);
|
||||
|
||||
extern struct value *ada_value_tag (struct value *);
|
||||
|
||||
extern const char *ada_tag_name (struct value *);
|
||||
|
||||
extern struct value *ada_tag_value_at_base_address (struct value *obj);
|
||||
|
||||
extern int ada_is_parent_field (struct type *, int);
|
||||
|
||||
extern int ada_is_wrapper_field (struct type *, int);
|
||||
|
||||
extern int ada_is_variant_part (struct type *, int);
|
||||
|
||||
extern struct type *ada_variant_discrim_type (struct type *, struct type *);
|
||||
|
||||
extern int ada_is_others_clause (struct type *, int);
|
||||
|
||||
extern int ada_in_variant (LONGEST, struct type *, int);
|
||||
|
||||
extern char *ada_variant_discrim_name (struct type *);
|
||||
|
||||
extern struct value *ada_value_struct_elt (struct value *, char *, int);
|
||||
|
||||
extern int ada_is_aligner_type (struct type *);
|
||||
|
||||
extern struct type *ada_aligned_type (struct type *);
|
||||
|
||||
extern const gdb_byte *ada_aligned_value_addr (struct type *,
|
||||
const gdb_byte *);
|
||||
|
||||
extern const char *ada_attribute_name (enum exp_opcode);
|
||||
|
||||
extern int ada_is_fixed_point_type (struct type *);
|
||||
|
||||
extern int ada_is_system_address_type (struct type *);
|
||||
|
||||
extern DOUBLEST ada_delta (struct type *);
|
||||
|
||||
extern DOUBLEST ada_fixed_to_float (struct type *, LONGEST);
|
||||
|
||||
extern LONGEST ada_float_to_fixed (struct type *, DOUBLEST);
|
||||
|
||||
extern struct type *ada_system_address_type (void);
|
||||
|
||||
extern int ada_which_variant_applies (struct type *, struct type *,
|
||||
const gdb_byte *);
|
||||
|
||||
extern struct type *ada_to_fixed_type (struct type *, const gdb_byte *,
|
||||
CORE_ADDR, struct value *,
|
||||
int check_tag);
|
||||
|
||||
extern struct value *ada_to_fixed_value (struct value *val);
|
||||
|
||||
extern struct type *ada_template_to_fixed_record_type_1 (struct type *type,
|
||||
const gdb_byte *valaddr,
|
||||
CORE_ADDR address,
|
||||
struct value *dval0,
|
||||
int keep_dynamic_fields);
|
||||
|
||||
extern int ada_name_prefix_len (const char *);
|
||||
|
||||
extern const char *ada_type_name (struct type *);
|
||||
|
||||
extern struct type *ada_find_parallel_type (struct type *,
|
||||
const char *suffix);
|
||||
|
||||
extern LONGEST get_int_var_value (char *, int *);
|
||||
|
||||
extern struct symbol *ada_find_renaming_symbol (struct symbol *name_sym,
|
||||
const struct block *block);
|
||||
|
||||
extern int ada_prefer_type (struct type *, struct type *);
|
||||
|
||||
extern struct type *ada_get_base_type (struct type *);
|
||||
|
||||
extern struct type *ada_check_typedef (struct type *);
|
||||
|
||||
extern char *ada_encode (const char *);
|
||||
|
||||
extern const char *ada_enum_name (const char *);
|
||||
|
||||
extern int ada_is_modular_type (struct type *);
|
||||
|
||||
extern ULONGEST ada_modulus (struct type *);
|
||||
|
||||
extern struct value *ada_value_ind (struct value *);
|
||||
|
||||
extern void ada_print_scalar (struct type *, LONGEST, struct ui_file *);
|
||||
|
||||
extern int ada_is_range_type_name (const char *);
|
||||
|
||||
extern enum ada_renaming_category ada_parse_renaming (struct symbol *,
|
||||
const char **,
|
||||
int *, const char **);
|
||||
|
||||
extern void ada_find_printable_frame (struct frame_info *fi);
|
||||
|
||||
extern char *ada_breakpoint_rewrite (char *, int *);
|
||||
|
||||
extern char *ada_main_name (void);
|
||||
|
||||
extern char *ada_name_for_lookup (const char *name);
|
||||
|
||||
/* Tasking-related: ada-tasks.c */
|
||||
|
||||
extern int valid_task_id (int);
|
||||
|
||||
extern int ada_get_task_number (ptid_t);
|
||||
|
||||
typedef void (ada_task_list_iterator_ftype) (struct ada_task_info *task);
|
||||
extern void iterate_over_live_ada_tasks
|
||||
(ada_task_list_iterator_ftype *iterator);
|
||||
|
||||
extern int ada_build_task_list (void);
|
||||
|
||||
extern void print_ada_task_info (struct ui_out *uiout,
|
||||
char *taskno_str,
|
||||
struct inferior *inf);
|
||||
|
||||
#endif
|
||||
646
gdb/ada-lex.l
646
gdb/ada-lex.l
@@ -1,646 +0,0 @@
|
||||
/* FLEX lexer for Ada expressions, for GDB.
|
||||
Copyright (C) 1994-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* The converted version of this file is to be included in ada-exp.y, */
|
||||
/* the Ada parser for gdb. The function yylex obtains characters from */
|
||||
/* the global pointer lexptr. It returns a syntactic category for */
|
||||
/* each successive token and places a semantic value into yylval */
|
||||
/* (ada-lval), defined by the parser. */
|
||||
|
||||
DIG [0-9]
|
||||
NUM10 ({DIG}({DIG}|_)*)
|
||||
HEXDIG [0-9a-f]
|
||||
NUM16 ({HEXDIG}({HEXDIG}|_)*)
|
||||
OCTDIG [0-7]
|
||||
LETTER [a-z_]
|
||||
ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
|
||||
WHITE [ \t\n]
|
||||
TICK ("'"{WHITE}*)
|
||||
GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
|
||||
OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
|
||||
|
||||
EXP (e[+-]{NUM10})
|
||||
POSEXP (e"+"?{NUM10})
|
||||
|
||||
%{
|
||||
|
||||
#define NUMERAL_WIDTH 256
|
||||
#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
|
||||
|
||||
/* Temporary staging for numeric literals. */
|
||||
static char numbuf[NUMERAL_WIDTH];
|
||||
static void canonicalizeNumeral (char *s1, const char *);
|
||||
static struct stoken processString (const char*, int);
|
||||
static int processInt (const char *, const char *, const char *);
|
||||
static int processReal (const char *);
|
||||
static struct stoken processId (const char *, int);
|
||||
static int processAttribute (const char *);
|
||||
static int find_dot_all (const char *);
|
||||
static void rewind_to_char (int);
|
||||
|
||||
#undef YY_DECL
|
||||
#define YY_DECL static int yylex ( void )
|
||||
|
||||
/* Flex generates a static function "input" which is not used.
|
||||
Defining YY_NO_INPUT comments it out. */
|
||||
#define YY_NO_INPUT
|
||||
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
|
||||
if ( *lexptr == '\000' ) \
|
||||
(RESULT) = YY_NULL; \
|
||||
else \
|
||||
{ \
|
||||
*(BUF) = *lexptr; \
|
||||
(RESULT) = 1; \
|
||||
lexptr += 1; \
|
||||
}
|
||||
|
||||
static int find_dot_all (const char *);
|
||||
|
||||
%}
|
||||
|
||||
%option case-insensitive interactive nodefault
|
||||
|
||||
%s BEFORE_QUAL_QUOTE
|
||||
|
||||
%%
|
||||
|
||||
{WHITE} { }
|
||||
|
||||
"--".* { yyterminate(); }
|
||||
|
||||
{NUM10}{POSEXP} {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
|
||||
}
|
||||
|
||||
{NUM10} {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processInt (NULL, numbuf, NULL);
|
||||
}
|
||||
|
||||
{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processInt (numbuf,
|
||||
strchr (numbuf, '#') + 1,
|
||||
strrchr(numbuf, '#') + 1);
|
||||
}
|
||||
|
||||
{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
|
||||
}
|
||||
|
||||
"0x"{HEXDIG}+ {
|
||||
canonicalizeNumeral (numbuf, yytext+2);
|
||||
return processInt ("16#", numbuf, NULL);
|
||||
}
|
||||
|
||||
|
||||
{NUM10}"."{NUM10}{EXP} {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processReal (numbuf);
|
||||
}
|
||||
|
||||
{NUM10}"."{NUM10} {
|
||||
canonicalizeNumeral (numbuf, yytext);
|
||||
return processReal (numbuf);
|
||||
}
|
||||
|
||||
{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
|
||||
error (_("Based real literals not implemented yet."));
|
||||
}
|
||||
|
||||
{NUM10}"#"{NUM16}"."{NUM16}"#" {
|
||||
error (_("Based real literals not implemented yet."));
|
||||
}
|
||||
|
||||
<INITIAL>"'"({GRAPHIC}|\")"'" {
|
||||
yylval.typed_val.type = type_char ();
|
||||
yylval.typed_val.val = yytext[1];
|
||||
return CHARLIT;
|
||||
}
|
||||
|
||||
<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
|
||||
int v;
|
||||
yylval.typed_val.type = type_char ();
|
||||
sscanf (yytext+3, "%2x", &v);
|
||||
yylval.typed_val.val = v;
|
||||
return CHARLIT;
|
||||
}
|
||||
|
||||
\"({GRAPHIC}|"[\""({HEXDIG}{2}|\")"\"]")*\" {
|
||||
yylval.sval = processString (yytext+1, yyleng-2);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
\" {
|
||||
error (_("ill-formed or non-terminated string literal"));
|
||||
}
|
||||
|
||||
|
||||
if {
|
||||
rewind_to_char ('i');
|
||||
return 0;
|
||||
}
|
||||
|
||||
task {
|
||||
rewind_to_char ('t');
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread{WHITE}+{DIG} {
|
||||
/* This keyword signals the end of the expression and
|
||||
will be processed separately. */
|
||||
rewind_to_char ('t');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ADA KEYWORDS */
|
||||
|
||||
abs { return ABS; }
|
||||
and { return _AND_; }
|
||||
else { return ELSE; }
|
||||
in { return IN; }
|
||||
mod { return MOD; }
|
||||
new { return NEW; }
|
||||
not { return NOT; }
|
||||
null { return NULL_PTR; }
|
||||
or { return OR; }
|
||||
others { return OTHERS; }
|
||||
rem { return REM; }
|
||||
then { return THEN; }
|
||||
xor { return XOR; }
|
||||
|
||||
/* BOOLEAN "KEYWORDS" */
|
||||
|
||||
/* True and False are not keywords in Ada, but rather enumeration constants.
|
||||
However, the boolean type is no longer represented as an enum, so True
|
||||
and False are no longer defined in symbol tables. We compromise by
|
||||
making them keywords (when bare). */
|
||||
|
||||
true { return TRUEKEYWORD; }
|
||||
false { return FALSEKEYWORD; }
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
|
||||
|
||||
/* PUNCTUATION */
|
||||
|
||||
"=>" { return ARROW; }
|
||||
".." { return DOTDOT; }
|
||||
"**" { return STARSTAR; }
|
||||
":=" { return ASSIGN; }
|
||||
"/=" { return NOTEQUAL; }
|
||||
"<=" { return LEQ; }
|
||||
">=" { return GEQ; }
|
||||
|
||||
<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
|
||||
|
||||
[-&*+./:<>=|;\[\]] { return yytext[0]; }
|
||||
|
||||
"," { if (paren_depth == 0 && comma_terminates)
|
||||
{
|
||||
rewind_to_char (',');
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return ',';
|
||||
}
|
||||
|
||||
"(" { paren_depth += 1; return '('; }
|
||||
")" { if (paren_depth == 0)
|
||||
{
|
||||
rewind_to_char (')');
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
paren_depth -= 1;
|
||||
return ')';
|
||||
}
|
||||
}
|
||||
|
||||
"."{WHITE}*all { return DOT_ALL; }
|
||||
|
||||
"."{WHITE}*{ID} {
|
||||
yylval.sval = processId (yytext+1, yyleng-1);
|
||||
return DOT_ID;
|
||||
}
|
||||
|
||||
{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
|
||||
int all_posn = find_dot_all (yytext);
|
||||
|
||||
if (all_posn == -1 && yytext[yyleng-1] == '\'')
|
||||
{
|
||||
BEGIN BEFORE_QUAL_QUOTE;
|
||||
yyless (yyleng-1);
|
||||
}
|
||||
else if (all_posn >= 0)
|
||||
yyless (all_posn);
|
||||
yylval.sval = processId (yytext, yyleng);
|
||||
return NAME;
|
||||
}
|
||||
|
||||
|
||||
/* GDB EXPRESSION CONSTRUCTS */
|
||||
|
||||
"'"[^']+"'"{WHITE}*:: {
|
||||
yyless (yyleng - 2);
|
||||
yylval.sval = processId (yytext, yyleng);
|
||||
return NAME;
|
||||
}
|
||||
|
||||
"::" { return COLONCOLON; }
|
||||
|
||||
[{}@] { return yytext[0]; }
|
||||
|
||||
/* REGISTERS AND GDB CONVENIENCE VARIABLES */
|
||||
|
||||
"$"({LETTER}|{DIG}|"$")* {
|
||||
yylval.sval.ptr = yytext;
|
||||
yylval.sval.length = yyleng;
|
||||
return SPECIAL_VARIABLE;
|
||||
}
|
||||
|
||||
/* CATCH-ALL ERROR CASE */
|
||||
|
||||
. { error (_("Invalid character '%s' in expression."), yytext); }
|
||||
%%
|
||||
|
||||
#include <ctype.h>
|
||||
#include "gdb_string.h"
|
||||
|
||||
/* Initialize the lexer for processing new expression. */
|
||||
|
||||
static void
|
||||
lexer_init (FILE *inp)
|
||||
{
|
||||
BEGIN INITIAL;
|
||||
yyrestart (inp);
|
||||
}
|
||||
|
||||
|
||||
/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
|
||||
|
||||
static void
|
||||
canonicalizeNumeral (char *s1, const char *s2)
|
||||
{
|
||||
for (; *s2 != '\000'; s2 += 1)
|
||||
{
|
||||
if (*s2 != '_')
|
||||
{
|
||||
*s1 = tolower(*s2);
|
||||
s1 += 1;
|
||||
}
|
||||
}
|
||||
s1[0] = '\000';
|
||||
}
|
||||
|
||||
/* Interprets the prefix of NUM that consists of digits of the given BASE
|
||||
as an integer of that BASE, with the string EXP as an exponent.
|
||||
Puts value in yylval, and returns INT, if the string is valid. Causes
|
||||
an error if the number is improperly formated. BASE, if NULL, defaults
|
||||
to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'.
|
||||
*/
|
||||
|
||||
static int
|
||||
processInt (const char *base0, const char *num0, const char *exp0)
|
||||
{
|
||||
ULONGEST result;
|
||||
long exp;
|
||||
int base;
|
||||
const char *trailer;
|
||||
|
||||
if (base0 == NULL)
|
||||
base = 10;
|
||||
else
|
||||
{
|
||||
base = strtol (base0, (char **) NULL, 10);
|
||||
if (base < 2 || base > 16)
|
||||
error (_("Invalid base: %d."), base);
|
||||
}
|
||||
|
||||
if (exp0 == NULL)
|
||||
exp = 0;
|
||||
else
|
||||
exp = strtol(exp0, (char **) NULL, 10);
|
||||
|
||||
errno = 0;
|
||||
result = strtoulst (num0, &trailer, base);
|
||||
if (errno == ERANGE)
|
||||
error (_("Integer literal out of range"));
|
||||
if (isxdigit(*trailer))
|
||||
error (_("Invalid digit `%c' in based literal"), *trailer);
|
||||
|
||||
while (exp > 0)
|
||||
{
|
||||
if (result > (ULONG_MAX / base))
|
||||
error (_("Integer literal out of range"));
|
||||
result *= base;
|
||||
exp -= 1;
|
||||
}
|
||||
|
||||
if ((result >> (gdbarch_int_bit (parse_gdbarch)-1)) == 0)
|
||||
yylval.typed_val.type = type_int ();
|
||||
else if ((result >> (gdbarch_long_bit (parse_gdbarch)-1)) == 0)
|
||||
yylval.typed_val.type = type_long ();
|
||||
else if (((result >> (gdbarch_long_bit (parse_gdbarch)-1)) >> 1) == 0)
|
||||
{
|
||||
/* We have a number representable as an unsigned integer quantity.
|
||||
For consistency with the C treatment, we will treat it as an
|
||||
anonymous modular (unsigned) quantity. Alas, the types are such
|
||||
that we need to store .val as a signed quantity. Sorry
|
||||
for the mess, but C doesn't officially guarantee that a simple
|
||||
assignment does the trick (no, it doesn't; read the reference manual).
|
||||
*/
|
||||
yylval.typed_val.type
|
||||
= builtin_type (parse_gdbarch)->builtin_unsigned_long;
|
||||
if (result & LONGEST_SIGN)
|
||||
yylval.typed_val.val =
|
||||
(LONGEST) (result & ~LONGEST_SIGN)
|
||||
- (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
|
||||
else
|
||||
yylval.typed_val.val = (LONGEST) result;
|
||||
return INT;
|
||||
}
|
||||
else
|
||||
yylval.typed_val.type = type_long_long ();
|
||||
|
||||
yylval.typed_val.val = (LONGEST) result;
|
||||
return INT;
|
||||
}
|
||||
|
||||
static int
|
||||
processReal (const char *num0)
|
||||
{
|
||||
sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval);
|
||||
|
||||
yylval.typed_val_float.type = type_float ();
|
||||
if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch)
|
||||
/ TARGET_CHAR_BIT)
|
||||
yylval.typed_val_float.type = type_double ();
|
||||
if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch)
|
||||
/ TARGET_CHAR_BIT)
|
||||
yylval.typed_val_float.type = type_long_double ();
|
||||
|
||||
return FLOAT;
|
||||
}
|
||||
|
||||
|
||||
/* Store a canonicalized version of NAME0[0..LEN-1] in yylval.ssym. The
|
||||
resulting string is valid until the next call to ada_parse. If
|
||||
NAME0 contains the substring "___", it is assumed to be already
|
||||
encoded and the resulting name is equal to it. Otherwise, it differs
|
||||
from NAME0 in that:
|
||||
+ Characters between '...' or <...> are transfered verbatim to
|
||||
yylval.ssym.
|
||||
+ <, >, and trailing "'" characters in quoted sequences are removed
|
||||
(a leading quote is preserved to indicate that the name is not to be
|
||||
GNAT-encoded).
|
||||
+ Unquoted whitespace is removed.
|
||||
+ Unquoted alphabetic characters are mapped to lower case.
|
||||
Result is returned as a struct stoken, but for convenience, the string
|
||||
is also null-terminated. Result string valid until the next call of
|
||||
ada_parse.
|
||||
*/
|
||||
static struct stoken
|
||||
processId (const char *name0, int len)
|
||||
{
|
||||
char *name = obstack_alloc (&temp_parse_space, len + 11);
|
||||
int i0, i;
|
||||
struct stoken result;
|
||||
|
||||
result.ptr = name;
|
||||
while (len > 0 && isspace (name0[len-1]))
|
||||
len -= 1;
|
||||
|
||||
if (strstr (name0, "___") != NULL)
|
||||
{
|
||||
strncpy (name, name0, len);
|
||||
name[len] = '\000';
|
||||
result.length = len;
|
||||
return result;
|
||||
}
|
||||
|
||||
i = i0 = 0;
|
||||
while (i0 < len)
|
||||
{
|
||||
if (isalnum (name0[i0]))
|
||||
{
|
||||
name[i] = tolower (name0[i0]);
|
||||
i += 1; i0 += 1;
|
||||
}
|
||||
else switch (name0[i0])
|
||||
{
|
||||
default:
|
||||
name[i] = name0[i0];
|
||||
i += 1; i0 += 1;
|
||||
break;
|
||||
case ' ': case '\t':
|
||||
i0 += 1;
|
||||
break;
|
||||
case '\'':
|
||||
do
|
||||
{
|
||||
name[i] = name0[i0];
|
||||
i += 1; i0 += 1;
|
||||
}
|
||||
while (i0 < len && name0[i0] != '\'');
|
||||
i0 += 1;
|
||||
break;
|
||||
case '<':
|
||||
i0 += 1;
|
||||
while (i0 < len && name0[i0] != '>')
|
||||
{
|
||||
name[i] = name0[i0];
|
||||
i += 1; i0 += 1;
|
||||
}
|
||||
i0 += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
name[i] = '\000';
|
||||
|
||||
result.length = i;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return TEXT[0..LEN-1], a string literal without surrounding quotes,
|
||||
with special hex character notations replaced with characters.
|
||||
Result valid until the next call to ada_parse. */
|
||||
|
||||
static struct stoken
|
||||
processString (const char *text, int len)
|
||||
{
|
||||
const char *p;
|
||||
char *q;
|
||||
const char *lim = text + len;
|
||||
struct stoken result;
|
||||
|
||||
q = result.ptr = obstack_alloc (&temp_parse_space, len);
|
||||
p = text;
|
||||
while (p < lim)
|
||||
{
|
||||
if (p[0] == '[' && p[1] == '"' && p+2 < lim)
|
||||
{
|
||||
if (p[2] == '"') /* "...["""]... */
|
||||
{
|
||||
*q = '"';
|
||||
p += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
int chr;
|
||||
sscanf (p+2, "%2x", &chr);
|
||||
*q = (char) chr;
|
||||
p += 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
*q = *p;
|
||||
q += 1;
|
||||
p += 1;
|
||||
}
|
||||
result.length = q - result.ptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns the position within STR of the '.' in a
|
||||
'.{WHITE}*all' component of a dotted name, or -1 if there is none.
|
||||
Note: we actually don't need this routine, since 'all' can never be an
|
||||
Ada identifier. Thus, looking up foo.all or foo.all.x as a name
|
||||
must fail, and will eventually be interpreted as (foo).all or
|
||||
(foo).all.x. However, this does avoid an extraneous lookup. */
|
||||
|
||||
static int
|
||||
find_dot_all (const char *str)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; str[i] != '\000'; i += 1)
|
||||
{
|
||||
if (str[i] == '.')
|
||||
{
|
||||
int i0 = i;
|
||||
do
|
||||
i += 1;
|
||||
while (isspace (str[i]));
|
||||
if (strncmp (str+i, "all", 3) == 0
|
||||
&& ! isalnum (str[i+3]) && str[i+3] != '_')
|
||||
return i0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
|
||||
case. */
|
||||
|
||||
static int
|
||||
subseqMatch (const char *subseq, const char *str)
|
||||
{
|
||||
if (subseq[0] == '\0')
|
||||
return 1;
|
||||
else if (str[0] == '\0')
|
||||
return 0;
|
||||
else if (tolower (subseq[0]) == tolower (str[0]))
|
||||
return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
|
||||
else
|
||||
return subseqMatch (subseq, str+1);
|
||||
}
|
||||
|
||||
|
||||
static struct { const char *name; int code; }
|
||||
attributes[] = {
|
||||
{ "address", TICK_ADDRESS },
|
||||
{ "unchecked_access", TICK_ACCESS },
|
||||
{ "unrestricted_access", TICK_ACCESS },
|
||||
{ "access", TICK_ACCESS },
|
||||
{ "first", TICK_FIRST },
|
||||
{ "last", TICK_LAST },
|
||||
{ "length", TICK_LENGTH },
|
||||
{ "max", TICK_MAX },
|
||||
{ "min", TICK_MIN },
|
||||
{ "modulus", TICK_MODULUS },
|
||||
{ "pos", TICK_POS },
|
||||
{ "range", TICK_RANGE },
|
||||
{ "size", TICK_SIZE },
|
||||
{ "tag", TICK_TAG },
|
||||
{ "val", TICK_VAL },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
|
||||
/* Return the syntactic code corresponding to the attribute name or
|
||||
abbreviation STR. */
|
||||
|
||||
static int
|
||||
processAttribute (const char *str)
|
||||
{
|
||||
int i, k;
|
||||
|
||||
for (i = 0; attributes[i].code != -1; i += 1)
|
||||
if (strcasecmp (str, attributes[i].name) == 0)
|
||||
return attributes[i].code;
|
||||
|
||||
for (i = 0, k = -1; attributes[i].code != -1; i += 1)
|
||||
if (subseqMatch (str, attributes[i].name))
|
||||
{
|
||||
if (k == -1)
|
||||
k = i;
|
||||
else
|
||||
error (_("ambiguous attribute name: `%s'"), str);
|
||||
}
|
||||
if (k == -1)
|
||||
error (_("unrecognized attribute: `%s'"), str);
|
||||
|
||||
return attributes[k].code;
|
||||
}
|
||||
|
||||
/* Back up lexptr by yyleng and then to the rightmost occurrence of
|
||||
character CH, case-folded (there must be one). WARNING: since
|
||||
lexptr points to the next input character that Flex has not yet
|
||||
transferred to its internal buffer, the use of this function
|
||||
depends on the assumption that Flex calls YY_INPUT only when it is
|
||||
logically necessary to do so (thus, there is no reading ahead
|
||||
farther than needed to identify the next token.) */
|
||||
|
||||
static void
|
||||
rewind_to_char (int ch)
|
||||
{
|
||||
lexptr -= yyleng;
|
||||
while (toupper (*lexptr) != toupper (ch))
|
||||
lexptr -= 1;
|
||||
yyrestart (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Dummy definition to suppress warnings about unused static definitions. */
|
||||
typedef void (*dummy_function) ();
|
||||
dummy_function ada_flex_use[] =
|
||||
{
|
||||
(dummy_function) yyunput
|
||||
};
|
||||
@@ -1,98 +0,0 @@
|
||||
/* Ada language operator definitions for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1992-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* X IN A'RANGE(N). N is an immediate operand, surrounded by
|
||||
BINOP_IN_BOUNDS before and after. A is an array, X an index
|
||||
value. Evaluates to true iff X is within range of the Nth
|
||||
dimension (1-based) of A. (A multi-dimensional array
|
||||
type is represented as array of array of ...) */
|
||||
OP (BINOP_IN_BOUNDS)
|
||||
|
||||
/* X IN L .. U. True iff L <= X <= U. */
|
||||
OP (TERNOP_IN_RANGE)
|
||||
|
||||
/* Ada attributes ('Foo). */
|
||||
OP (OP_ATR_FIRST)
|
||||
OP (OP_ATR_LAST)
|
||||
OP (OP_ATR_LENGTH)
|
||||
OP (OP_ATR_IMAGE)
|
||||
OP (OP_ATR_MAX)
|
||||
OP (OP_ATR_MIN)
|
||||
OP (OP_ATR_MODULUS)
|
||||
OP (OP_ATR_POS)
|
||||
OP (OP_ATR_SIZE)
|
||||
OP (OP_ATR_TAG)
|
||||
OP (OP_ATR_VAL)
|
||||
|
||||
/* Ada type qualification. It is encoded as for UNOP_CAST, above,
|
||||
and denotes the TYPE'(EXPR) construct. */
|
||||
OP (UNOP_QUAL)
|
||||
|
||||
/* X IN TYPE. The `TYPE' argument is immediate, with
|
||||
UNOP_IN_RANGE before and after it. True iff X is a member of
|
||||
type TYPE (typically a subrange). */
|
||||
OP (UNOP_IN_RANGE)
|
||||
|
||||
/* An aggregate. A single immediate operand, N>0, gives
|
||||
the number of component specifications that follow. The
|
||||
immediate operand is followed by a second OP_AGGREGATE.
|
||||
Next come N component specifications. A component
|
||||
specification is either an OP_OTHERS (others=>...), an
|
||||
OP_CHOICES (for named associations), or other expression (for
|
||||
positional aggregates only). Aggregates currently
|
||||
occur only as the right sides of assignments. */
|
||||
OP (OP_AGGREGATE)
|
||||
|
||||
/* An others clause. Followed by a single expression. */
|
||||
OP (OP_OTHERS)
|
||||
|
||||
/* An aggregate component association. A single immediate operand, N,
|
||||
gives the number of choices that follow. This is followed by a second
|
||||
OP_CHOICES operator. Next come N operands, each of which is an
|
||||
expression, an OP_DISCRETE_RANGE, or an OP_NAME---the latter
|
||||
for a simple name that must be a record component name and does
|
||||
not correspond to a single existing symbol. After the N choice
|
||||
indicators comes an expression giving the value.
|
||||
|
||||
In an aggregate such as (X => E1, ...), where X is a simple
|
||||
name, X could syntactically be either a component_selector_name
|
||||
or an expression used as a discrete_choice, depending on the
|
||||
aggregate's type context. Since this is not known at parsing
|
||||
time, we don't attempt to disambiguate X if it has multiple
|
||||
definitions, but instead supply an OP_NAME. If X has a single
|
||||
definition, we represent it with an OP_VAR_VALUE, even though
|
||||
it may turn out to be within a record aggregate. Aggregate
|
||||
evaluation can use either OP_NAMEs or OP_VAR_VALUEs to get a
|
||||
record field name, and can evaluate OP_VAR_VALUE normally to
|
||||
get its value as an expression. Unfortunately, we lose out in
|
||||
cases where X has multiple meanings and is part of an array
|
||||
aggregate. I hope these are not common enough to annoy users,
|
||||
who can work around the problem in any case by putting
|
||||
parentheses around X. */
|
||||
OP (OP_CHOICES)
|
||||
|
||||
/* A positional aggregate component association. The operator is
|
||||
followed by a single integer indicating the position in the
|
||||
aggregate (0-based), followed by a second OP_POSITIONAL. Next
|
||||
follows a single expression giving the component value. */
|
||||
OP (OP_POSITIONAL)
|
||||
|
||||
/* A range of values. Followed by two expressions giving the
|
||||
upper and lower bounds of the range. */
|
||||
OP (OP_DISCRETE_RANGE)
|
||||
1452
gdb/ada-tasks.c
1452
gdb/ada-tasks.c
File diff suppressed because it is too large
Load Diff
@@ -1,889 +0,0 @@
|
||||
/* Support for printing Ada types for GDB, the GNU debugger.
|
||||
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "bfd.h" /* Binary File Description */
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "expression.h"
|
||||
#include "value.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "command.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "language.h"
|
||||
#include "demangle.h"
|
||||
#include "c-lang.h"
|
||||
#include "typeprint.h"
|
||||
#include "ada-lang.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "gdb_string.h"
|
||||
#include <errno.h>
|
||||
|
||||
static int print_selected_record_field_types (struct type *, struct type *,
|
||||
int, int,
|
||||
struct ui_file *, int, int,
|
||||
const struct type_print_options *);
|
||||
|
||||
static int print_record_field_types (struct type *, struct type *,
|
||||
struct ui_file *, int, int,
|
||||
const struct type_print_options *);
|
||||
|
||||
static void print_array_type (struct type *, struct ui_file *, int, int,
|
||||
const struct type_print_options *);
|
||||
|
||||
static int print_choices (struct type *, int, struct ui_file *,
|
||||
struct type *);
|
||||
|
||||
static void print_range (struct type *, struct ui_file *);
|
||||
|
||||
static void print_range_bound (struct type *, char *, int *,
|
||||
struct ui_file *);
|
||||
|
||||
static void
|
||||
print_dynamic_range_bound (struct type *, const char *, int,
|
||||
const char *, struct ui_file *);
|
||||
|
||||
static void print_range_type (struct type *, struct ui_file *);
|
||||
|
||||
|
||||
|
||||
static char *name_buffer;
|
||||
static int name_buffer_len;
|
||||
|
||||
/* The (decoded) Ada name of TYPE. This value persists until the
|
||||
next call. */
|
||||
|
||||
static char *
|
||||
decoded_type_name (struct type *type)
|
||||
{
|
||||
if (ada_type_name (type) == NULL)
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
const char *raw_name = ada_type_name (type);
|
||||
char *s, *q;
|
||||
|
||||
if (name_buffer == NULL || name_buffer_len <= strlen (raw_name))
|
||||
{
|
||||
name_buffer_len = 16 + 2 * strlen (raw_name);
|
||||
name_buffer = xrealloc (name_buffer, name_buffer_len);
|
||||
}
|
||||
strcpy (name_buffer, raw_name);
|
||||
|
||||
s = (char *) strstr (name_buffer, "___");
|
||||
if (s != NULL)
|
||||
*s = '\0';
|
||||
|
||||
s = name_buffer + strlen (name_buffer) - 1;
|
||||
while (s > name_buffer && (s[0] != '_' || s[-1] != '_'))
|
||||
s -= 1;
|
||||
|
||||
if (s == name_buffer)
|
||||
return name_buffer;
|
||||
|
||||
if (!islower (s[1]))
|
||||
return NULL;
|
||||
|
||||
for (s = q = name_buffer; *s != '\0'; q += 1)
|
||||
{
|
||||
if (s[0] == '_' && s[1] == '_')
|
||||
{
|
||||
*q = '.';
|
||||
s += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*q = *s;
|
||||
s += 1;
|
||||
}
|
||||
}
|
||||
*q = '\0';
|
||||
return name_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print TYPE on STREAM, preferably as a range. */
|
||||
|
||||
static void
|
||||
print_range (struct type *type, struct ui_file *stream)
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_RANGE:
|
||||
case TYPE_CODE_ENUM:
|
||||
{
|
||||
struct type *target_type;
|
||||
target_type = TYPE_TARGET_TYPE (type);
|
||||
if (target_type == NULL)
|
||||
target_type = type;
|
||||
ada_print_scalar (target_type, ada_discrete_type_low_bound (type),
|
||||
stream);
|
||||
fprintf_filtered (stream, " .. ");
|
||||
ada_print_scalar (target_type, ada_discrete_type_high_bound (type),
|
||||
stream);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf_filtered (stream, "%.*s",
|
||||
ada_name_prefix_len (TYPE_NAME (type)),
|
||||
TYPE_NAME (type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the number or discriminant bound at BOUNDS+*N on STREAM, and
|
||||
set *N past the bound and its delimiter, if any. */
|
||||
|
||||
static void
|
||||
print_range_bound (struct type *type, char *bounds, int *n,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
LONGEST B;
|
||||
|
||||
if (ada_scan_number (bounds, *n, &B, n))
|
||||
{
|
||||
/* STABS decodes all range types which bounds are 0 .. -1 as
|
||||
unsigned integers (ie. the type code is TYPE_CODE_INT, not
|
||||
TYPE_CODE_RANGE). Unfortunately, ada_print_scalar() relies
|
||||
on the unsigned flag to determine whether the bound should
|
||||
be printed as a signed or an unsigned value. This causes
|
||||
the upper bound of the 0 .. -1 range types to be printed as
|
||||
a very large unsigned number instead of -1.
|
||||
To workaround this stabs deficiency, we replace the TYPE by NULL
|
||||
to indicate default output when we detect that the bound is negative,
|
||||
and the type is a TYPE_CODE_INT. The bound is negative when
|
||||
'm' is the last character of the number scanned in BOUNDS. */
|
||||
if (bounds[*n - 1] == 'm' && TYPE_CODE (type) == TYPE_CODE_INT)
|
||||
type = NULL;
|
||||
ada_print_scalar (type, B, stream);
|
||||
if (bounds[*n] == '_')
|
||||
*n += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bound_len;
|
||||
char *bound = bounds + *n;
|
||||
char *pend;
|
||||
|
||||
pend = strstr (bound, "__");
|
||||
if (pend == NULL)
|
||||
*n += bound_len = strlen (bound);
|
||||
else
|
||||
{
|
||||
bound_len = pend - bound;
|
||||
*n += bound_len + 2;
|
||||
}
|
||||
fprintf_filtered (stream, "%.*s", bound_len, bound);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assuming NAME[0 .. NAME_LEN-1] is the name of a range type, print
|
||||
the value (if found) of the bound indicated by SUFFIX ("___L" or
|
||||
"___U") according to the ___XD conventions. */
|
||||
|
||||
static void
|
||||
print_dynamic_range_bound (struct type *type, const char *name, int name_len,
|
||||
const char *suffix, struct ui_file *stream)
|
||||
{
|
||||
static char *name_buf = NULL;
|
||||
static size_t name_buf_len = 0;
|
||||
LONGEST B;
|
||||
int OK;
|
||||
|
||||
GROW_VECT (name_buf, name_buf_len, name_len + strlen (suffix) + 1);
|
||||
strncpy (name_buf, name, name_len);
|
||||
strcpy (name_buf + name_len, suffix);
|
||||
|
||||
B = get_int_var_value (name_buf, &OK);
|
||||
if (OK)
|
||||
ada_print_scalar (type, B, stream);
|
||||
else
|
||||
fprintf_filtered (stream, "?");
|
||||
}
|
||||
|
||||
/* Print RAW_TYPE as a range type, using any bound information
|
||||
following the GNAT encoding (if available). */
|
||||
|
||||
static void
|
||||
print_range_type (struct type *raw_type, struct ui_file *stream)
|
||||
{
|
||||
const char *name;
|
||||
struct type *base_type;
|
||||
const char *subtype_info;
|
||||
|
||||
gdb_assert (raw_type != NULL);
|
||||
name = TYPE_NAME (raw_type);
|
||||
gdb_assert (name != NULL);
|
||||
|
||||
if (TYPE_CODE (raw_type) == TYPE_CODE_RANGE)
|
||||
base_type = TYPE_TARGET_TYPE (raw_type);
|
||||
else
|
||||
base_type = raw_type;
|
||||
|
||||
subtype_info = strstr (name, "___XD");
|
||||
if (subtype_info == NULL)
|
||||
print_range (raw_type, stream);
|
||||
else
|
||||
{
|
||||
int prefix_len = subtype_info - name;
|
||||
char *bounds_str;
|
||||
int n;
|
||||
|
||||
subtype_info += 5;
|
||||
bounds_str = strchr (subtype_info, '_');
|
||||
n = 1;
|
||||
|
||||
if (*subtype_info == 'L')
|
||||
{
|
||||
print_range_bound (base_type, bounds_str, &n, stream);
|
||||
subtype_info += 1;
|
||||
}
|
||||
else
|
||||
print_dynamic_range_bound (base_type, name, prefix_len, "___L",
|
||||
stream);
|
||||
|
||||
fprintf_filtered (stream, " .. ");
|
||||
|
||||
if (*subtype_info == 'U')
|
||||
print_range_bound (base_type, bounds_str, &n, stream);
|
||||
else
|
||||
print_dynamic_range_bound (base_type, name, prefix_len, "___U",
|
||||
stream);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print enumerated type TYPE on STREAM. */
|
||||
|
||||
static void
|
||||
print_enum_type (struct type *type, struct ui_file *stream)
|
||||
{
|
||||
int len = TYPE_NFIELDS (type);
|
||||
int i;
|
||||
LONGEST lastval;
|
||||
|
||||
fprintf_filtered (stream, "(");
|
||||
wrap_here (" ");
|
||||
|
||||
lastval = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
QUIT;
|
||||
if (i)
|
||||
fprintf_filtered (stream, ", ");
|
||||
wrap_here (" ");
|
||||
fputs_filtered (ada_enum_name (TYPE_FIELD_NAME (type, i)), stream);
|
||||
if (lastval != TYPE_FIELD_ENUMVAL (type, i))
|
||||
{
|
||||
fprintf_filtered (stream, " => %s",
|
||||
plongest (TYPE_FIELD_ENUMVAL (type, i)));
|
||||
lastval = TYPE_FIELD_ENUMVAL (type, i);
|
||||
}
|
||||
lastval += 1;
|
||||
}
|
||||
fprintf_filtered (stream, ")");
|
||||
}
|
||||
|
||||
/* Print representation of Ada fixed-point type TYPE on STREAM. */
|
||||
|
||||
static void
|
||||
print_fixed_point_type (struct type *type, struct ui_file *stream)
|
||||
{
|
||||
DOUBLEST delta = ada_delta (type);
|
||||
DOUBLEST small = ada_fixed_to_float (type, 1.0);
|
||||
|
||||
if (delta < 0.0)
|
||||
fprintf_filtered (stream, "delta ??");
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "delta %g", (double) delta);
|
||||
if (delta != small)
|
||||
fprintf_filtered (stream, " <'small = %g>", (double) small);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print simple (constrained) array type TYPE on STREAM. LEVEL is the
|
||||
recursion (indentation) level, in case the element type itself has
|
||||
nested structure, and SHOW is the number of levels of internal
|
||||
structure to show (see ada_print_type). */
|
||||
|
||||
static void
|
||||
print_array_type (struct type *type, struct ui_file *stream, int show,
|
||||
int level, const struct type_print_options *flags)
|
||||
{
|
||||
int bitsize;
|
||||
int n_indices;
|
||||
|
||||
if (ada_is_constrained_packed_array_type (type))
|
||||
type = ada_coerce_to_simple_array_type (type);
|
||||
|
||||
bitsize = 0;
|
||||
fprintf_filtered (stream, "array (");
|
||||
|
||||
if (type == NULL)
|
||||
{
|
||||
fprintf_filtered (stream, _("<undecipherable array type>"));
|
||||
return;
|
||||
}
|
||||
|
||||
n_indices = -1;
|
||||
if (ada_is_simple_array_type (type))
|
||||
{
|
||||
struct type *range_desc_type;
|
||||
struct type *arr_type;
|
||||
|
||||
range_desc_type = ada_find_parallel_type (type, "___XA");
|
||||
ada_fixup_array_indexes_type (range_desc_type);
|
||||
|
||||
bitsize = 0;
|
||||
if (range_desc_type == NULL)
|
||||
{
|
||||
for (arr_type = type; TYPE_CODE (arr_type) == TYPE_CODE_ARRAY;
|
||||
arr_type = TYPE_TARGET_TYPE (arr_type))
|
||||
{
|
||||
if (arr_type != type)
|
||||
fprintf_filtered (stream, ", ");
|
||||
print_range (TYPE_INDEX_TYPE (arr_type), stream);
|
||||
if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
|
||||
bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int k;
|
||||
|
||||
n_indices = TYPE_NFIELDS (range_desc_type);
|
||||
for (k = 0, arr_type = type;
|
||||
k < n_indices;
|
||||
k += 1, arr_type = TYPE_TARGET_TYPE (arr_type))
|
||||
{
|
||||
if (k > 0)
|
||||
fprintf_filtered (stream, ", ");
|
||||
print_range_type (TYPE_FIELD_TYPE (range_desc_type, k),
|
||||
stream);
|
||||
if (TYPE_FIELD_BITSIZE (arr_type, 0) > 0)
|
||||
bitsize = TYPE_FIELD_BITSIZE (arr_type, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, i0;
|
||||
|
||||
for (i = i0 = ada_array_arity (type); i > 0; i -= 1)
|
||||
fprintf_filtered (stream, "%s<>", i == i0 ? "" : ", ");
|
||||
}
|
||||
|
||||
fprintf_filtered (stream, ") of ");
|
||||
wrap_here ("");
|
||||
ada_print_type (ada_array_element_type (type, n_indices), "", stream,
|
||||
show == 0 ? 0 : show - 1, level + 1, flags);
|
||||
if (bitsize > 0)
|
||||
fprintf_filtered (stream, " <packed: %d-bit elements>", bitsize);
|
||||
}
|
||||
|
||||
/* Print the choices encoded by field FIELD_NUM of variant-part TYPE on
|
||||
STREAM, assuming that VAL_TYPE (if non-NULL) is the type of the
|
||||
values. Return non-zero if the field is an encoding of
|
||||
discriminant values, as in a standard variant record, and 0 if the
|
||||
field is not so encoded (as happens with single-component variants
|
||||
in types annotated with pragma Unchecked_Variant). */
|
||||
|
||||
static int
|
||||
print_choices (struct type *type, int field_num, struct ui_file *stream,
|
||||
struct type *val_type)
|
||||
{
|
||||
int have_output;
|
||||
int p;
|
||||
const char *name = TYPE_FIELD_NAME (type, field_num);
|
||||
|
||||
have_output = 0;
|
||||
|
||||
/* Skip over leading 'V': NOTE soon to be obsolete. */
|
||||
if (name[0] == 'V')
|
||||
{
|
||||
if (!ada_scan_number (name, 1, NULL, &p))
|
||||
goto Huh;
|
||||
}
|
||||
else
|
||||
p = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (name[p])
|
||||
{
|
||||
default:
|
||||
goto Huh;
|
||||
case '_':
|
||||
case '\0':
|
||||
fprintf_filtered (stream, " =>");
|
||||
return 1;
|
||||
case 'S':
|
||||
case 'R':
|
||||
case 'O':
|
||||
if (have_output)
|
||||
fprintf_filtered (stream, " | ");
|
||||
have_output = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (name[p])
|
||||
{
|
||||
case 'S':
|
||||
{
|
||||
LONGEST W;
|
||||
|
||||
if (!ada_scan_number (name, p + 1, &W, &p))
|
||||
goto Huh;
|
||||
ada_print_scalar (val_type, W, stream);
|
||||
break;
|
||||
}
|
||||
case 'R':
|
||||
{
|
||||
LONGEST L, U;
|
||||
|
||||
if (!ada_scan_number (name, p + 1, &L, &p)
|
||||
|| name[p] != 'T' || !ada_scan_number (name, p + 1, &U, &p))
|
||||
goto Huh;
|
||||
ada_print_scalar (val_type, L, stream);
|
||||
fprintf_filtered (stream, " .. ");
|
||||
ada_print_scalar (val_type, U, stream);
|
||||
break;
|
||||
}
|
||||
case 'O':
|
||||
fprintf_filtered (stream, "others");
|
||||
p += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Huh:
|
||||
fprintf_filtered (stream, "?? =>");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Assuming that field FIELD_NUM of TYPE represents variants whose
|
||||
discriminant is contained in OUTER_TYPE, print its components on STREAM.
|
||||
LEVEL is the recursion (indentation) level, in case any of the fields
|
||||
themselves have nested structure, and SHOW is the number of levels of
|
||||
internal structure to show (see ada_print_type). For this purpose,
|
||||
fields nested in a variant part are taken to be at the same level as
|
||||
the fields immediately outside the variant part. */
|
||||
|
||||
static void
|
||||
print_variant_clauses (struct type *type, int field_num,
|
||||
struct type *outer_type, struct ui_file *stream,
|
||||
int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
int i;
|
||||
struct type *var_type, *par_type;
|
||||
struct type *discr_type;
|
||||
|
||||
var_type = TYPE_FIELD_TYPE (type, field_num);
|
||||
discr_type = ada_variant_discrim_type (var_type, outer_type);
|
||||
|
||||
if (TYPE_CODE (var_type) == TYPE_CODE_PTR)
|
||||
{
|
||||
var_type = TYPE_TARGET_TYPE (var_type);
|
||||
if (var_type == NULL || TYPE_CODE (var_type) != TYPE_CODE_UNION)
|
||||
return;
|
||||
}
|
||||
|
||||
par_type = ada_find_parallel_type (var_type, "___XVU");
|
||||
if (par_type != NULL)
|
||||
var_type = par_type;
|
||||
|
||||
for (i = 0; i < TYPE_NFIELDS (var_type); i += 1)
|
||||
{
|
||||
fprintf_filtered (stream, "\n%*swhen ", level + 4, "");
|
||||
if (print_choices (var_type, i, stream, discr_type))
|
||||
{
|
||||
if (print_record_field_types (TYPE_FIELD_TYPE (var_type, i),
|
||||
outer_type, stream, show, level + 4,
|
||||
flags)
|
||||
<= 0)
|
||||
fprintf_filtered (stream, " null;");
|
||||
}
|
||||
else
|
||||
print_selected_record_field_types (var_type, outer_type, i, i,
|
||||
stream, show, level + 4, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assuming that field FIELD_NUM of TYPE is a variant part whose
|
||||
discriminants are contained in OUTER_TYPE, print a description of it
|
||||
on STREAM. LEVEL is the recursion (indentation) level, in case any of
|
||||
the fields themselves have nested structure, and SHOW is the number of
|
||||
levels of internal structure to show (see ada_print_type). For this
|
||||
purpose, fields nested in a variant part are taken to be at the same
|
||||
level as the fields immediately outside the variant part. */
|
||||
|
||||
static void
|
||||
print_variant_part (struct type *type, int field_num, struct type *outer_type,
|
||||
struct ui_file *stream, int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
fprintf_filtered (stream, "\n%*scase %s is", level + 4, "",
|
||||
ada_variant_discrim_name
|
||||
(TYPE_FIELD_TYPE (type, field_num)));
|
||||
print_variant_clauses (type, field_num, outer_type, stream, show,
|
||||
level + 4, flags);
|
||||
fprintf_filtered (stream, "\n%*send case;", level + 4, "");
|
||||
}
|
||||
|
||||
/* Print a description on STREAM of the fields FLD0 through FLD1 in
|
||||
record or union type TYPE, whose discriminants are in OUTER_TYPE.
|
||||
LEVEL is the recursion (indentation) level, in case any of the
|
||||
fields themselves have nested structure, and SHOW is the number of
|
||||
levels of internal structure to show (see ada_print_type). Does
|
||||
not print parent type information of TYPE. Returns 0 if no fields
|
||||
printed, -1 for an incomplete type, else > 0. Prints each field
|
||||
beginning on a new line, but does not put a new line at end. */
|
||||
|
||||
static int
|
||||
print_selected_record_field_types (struct type *type, struct type *outer_type,
|
||||
int fld0, int fld1,
|
||||
struct ui_file *stream, int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
int i, flds;
|
||||
|
||||
flds = 0;
|
||||
|
||||
if (fld0 > fld1 && TYPE_STUB (type))
|
||||
return -1;
|
||||
|
||||
for (i = fld0; i <= fld1; i += 1)
|
||||
{
|
||||
QUIT;
|
||||
|
||||
if (ada_is_parent_field (type, i) || ada_is_ignored_field (type, i))
|
||||
;
|
||||
else if (ada_is_wrapper_field (type, i))
|
||||
flds += print_record_field_types (TYPE_FIELD_TYPE (type, i), type,
|
||||
stream, show, level, flags);
|
||||
else if (ada_is_variant_part (type, i))
|
||||
{
|
||||
print_variant_part (type, i, outer_type, stream, show, level, flags);
|
||||
flds = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flds += 1;
|
||||
fprintf_filtered (stream, "\n%*s", level + 4, "");
|
||||
ada_print_type (TYPE_FIELD_TYPE (type, i),
|
||||
TYPE_FIELD_NAME (type, i),
|
||||
stream, show - 1, level + 4, flags);
|
||||
fprintf_filtered (stream, ";");
|
||||
}
|
||||
}
|
||||
|
||||
return flds;
|
||||
}
|
||||
|
||||
/* Print a description on STREAM of all fields of record or union type
|
||||
TYPE, as for print_selected_record_field_types, above. */
|
||||
|
||||
static int
|
||||
print_record_field_types (struct type *type, struct type *outer_type,
|
||||
struct ui_file *stream, int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
return print_selected_record_field_types (type, outer_type,
|
||||
0, TYPE_NFIELDS (type) - 1,
|
||||
stream, show, level, flags);
|
||||
}
|
||||
|
||||
|
||||
/* Print record type TYPE on STREAM. LEVEL is the recursion (indentation)
|
||||
level, in case the element type itself has nested structure, and SHOW is
|
||||
the number of levels of internal structure to show (see ada_print_type). */
|
||||
|
||||
static void
|
||||
print_record_type (struct type *type0, struct ui_file *stream, int show,
|
||||
int level, const struct type_print_options *flags)
|
||||
{
|
||||
struct type *parent_type;
|
||||
struct type *type;
|
||||
|
||||
type = ada_find_parallel_type (type0, "___XVE");
|
||||
if (type == NULL)
|
||||
type = type0;
|
||||
|
||||
parent_type = ada_parent_type (type);
|
||||
if (ada_type_name (parent_type) != NULL)
|
||||
{
|
||||
const char *parent_name = decoded_type_name (parent_type);
|
||||
|
||||
/* If we fail to decode the parent type name, then use the parent
|
||||
type name as is. Not pretty, but should never happen except
|
||||
when the debugging info is incomplete or incorrect. This
|
||||
prevents a crash trying to print a NULL pointer. */
|
||||
if (parent_name == NULL)
|
||||
parent_name = ada_type_name (parent_type);
|
||||
fprintf_filtered (stream, "new %s with record", parent_name);
|
||||
}
|
||||
else if (parent_type == NULL && ada_is_tagged_type (type, 0))
|
||||
fprintf_filtered (stream, "tagged record");
|
||||
else
|
||||
fprintf_filtered (stream, "record");
|
||||
|
||||
if (show < 0)
|
||||
fprintf_filtered (stream, " ... end record");
|
||||
else
|
||||
{
|
||||
int flds;
|
||||
|
||||
flds = 0;
|
||||
if (parent_type != NULL && ada_type_name (parent_type) == NULL)
|
||||
flds += print_record_field_types (parent_type, parent_type,
|
||||
stream, show, level, flags);
|
||||
flds += print_record_field_types (type, type, stream, show, level,
|
||||
flags);
|
||||
|
||||
if (flds > 0)
|
||||
fprintf_filtered (stream, "\n%*send record", level, "");
|
||||
else if (flds < 0)
|
||||
fprintf_filtered (stream, _(" <incomplete type> end record"));
|
||||
else
|
||||
fprintf_filtered (stream, " null; end record");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the unchecked union type TYPE in something resembling Ada
|
||||
format on STREAM. LEVEL is the recursion (indentation) level
|
||||
in case the element type itself has nested structure, and SHOW is the
|
||||
number of levels of internal structure to show (see ada_print_type). */
|
||||
static void
|
||||
print_unchecked_union_type (struct type *type, struct ui_file *stream,
|
||||
int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
if (show < 0)
|
||||
fprintf_filtered (stream, "record (?) is ... end record");
|
||||
else if (TYPE_NFIELDS (type) == 0)
|
||||
fprintf_filtered (stream, "record (?) is null; end record");
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, "");
|
||||
|
||||
for (i = 0; i < TYPE_NFIELDS (type); i += 1)
|
||||
{
|
||||
fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level + 8, "",
|
||||
level + 12, "");
|
||||
ada_print_type (TYPE_FIELD_TYPE (type, i),
|
||||
TYPE_FIELD_NAME (type, i),
|
||||
stream, show - 1, level + 12, flags);
|
||||
fprintf_filtered (stream, ";");
|
||||
}
|
||||
|
||||
fprintf_filtered (stream, "\n%*send case;\n%*send record",
|
||||
level + 4, "", level, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print function or procedure type TYPE on STREAM. Make it a header
|
||||
for function or procedure NAME if NAME is not null. */
|
||||
|
||||
static void
|
||||
print_func_type (struct type *type, struct ui_file *stream, const char *name,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
int i, len = TYPE_NFIELDS (type);
|
||||
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
|
||||
fprintf_filtered (stream, "procedure");
|
||||
else
|
||||
fprintf_filtered (stream, "function");
|
||||
|
||||
if (name != NULL && name[0] != '\0')
|
||||
fprintf_filtered (stream, " %s", name);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
fprintf_filtered (stream, " (");
|
||||
for (i = 0; i < len; i += 1)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
fputs_filtered ("; ", stream);
|
||||
wrap_here (" ");
|
||||
}
|
||||
fprintf_filtered (stream, "a%d: ", i + 1);
|
||||
ada_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0,
|
||||
flags);
|
||||
}
|
||||
fprintf_filtered (stream, ")");
|
||||
}
|
||||
|
||||
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
|
||||
{
|
||||
fprintf_filtered (stream, " return ");
|
||||
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, 0, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Print a description of a type TYPE0.
|
||||
Output goes to STREAM (via stdio).
|
||||
If VARSTRING is a non-empty string, print as an Ada variable/field
|
||||
declaration.
|
||||
SHOW+1 is the maximum number of levels of internal type structure
|
||||
to show (this applies to record types, enumerated types, and
|
||||
array types).
|
||||
SHOW is the number of levels of internal type structure to show
|
||||
when there is a type name for the SHOWth deepest level (0th is
|
||||
outer level).
|
||||
When SHOW<0, no inner structure is shown.
|
||||
LEVEL indicates level of recursion (for nested definitions). */
|
||||
|
||||
void
|
||||
ada_print_type (struct type *type0, const char *varstring,
|
||||
struct ui_file *stream, int show, int level,
|
||||
const struct type_print_options *flags)
|
||||
{
|
||||
struct type *type = ada_check_typedef (ada_get_base_type (type0));
|
||||
char *type_name = decoded_type_name (type0);
|
||||
int is_var_decl = (varstring != NULL && varstring[0] != '\0');
|
||||
|
||||
if (type == NULL)
|
||||
{
|
||||
if (is_var_decl)
|
||||
fprintf_filtered (stream, "%.*s: ",
|
||||
ada_name_prefix_len (varstring), varstring);
|
||||
fprintf_filtered (stream, "<null type?>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (show > 0)
|
||||
type = ada_check_typedef (type);
|
||||
|
||||
if (is_var_decl && TYPE_CODE (type) != TYPE_CODE_FUNC)
|
||||
fprintf_filtered (stream, "%.*s: ",
|
||||
ada_name_prefix_len (varstring), varstring);
|
||||
|
||||
if (type_name != NULL && show <= 0 && !ada_is_aligner_type (type))
|
||||
{
|
||||
fprintf_filtered (stream, "%.*s",
|
||||
ada_name_prefix_len (type_name), type_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ada_is_aligner_type (type))
|
||||
ada_print_type (ada_aligned_type (type), "", stream, show, level, flags);
|
||||
else if (ada_is_constrained_packed_array_type (type)
|
||||
&& TYPE_CODE (type) != TYPE_CODE_PTR)
|
||||
print_array_type (type, stream, show, level, flags);
|
||||
else
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
default:
|
||||
fprintf_filtered (stream, "<");
|
||||
c_print_type (type, "", stream, show, level, flags);
|
||||
fprintf_filtered (stream, ">");
|
||||
break;
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
fprintf_filtered (stream, "access ");
|
||||
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
|
||||
flags);
|
||||
break;
|
||||
case TYPE_CODE_REF:
|
||||
fprintf_filtered (stream, "<ref> ");
|
||||
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level,
|
||||
flags);
|
||||
break;
|
||||
case TYPE_CODE_ARRAY:
|
||||
print_array_type (type, stream, show, level, flags);
|
||||
break;
|
||||
case TYPE_CODE_BOOL:
|
||||
fprintf_filtered (stream, "(false, true)");
|
||||
break;
|
||||
case TYPE_CODE_INT:
|
||||
if (ada_is_fixed_point_type (type))
|
||||
print_fixed_point_type (type, stream);
|
||||
else
|
||||
{
|
||||
const char *name = ada_type_name (type);
|
||||
|
||||
if (!ada_is_range_type_name (name))
|
||||
fprintf_filtered (stream, _("<%d-byte integer>"),
|
||||
TYPE_LENGTH (type));
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "range ");
|
||||
print_range_type (type, stream);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_RANGE:
|
||||
if (ada_is_fixed_point_type (type))
|
||||
print_fixed_point_type (type, stream);
|
||||
else if (ada_is_modular_type (type))
|
||||
fprintf_filtered (stream, "mod %s",
|
||||
int_string (ada_modulus (type), 10, 0, 0, 1));
|
||||
else
|
||||
{
|
||||
fprintf_filtered (stream, "range ");
|
||||
print_range (type, stream);
|
||||
}
|
||||
break;
|
||||
case TYPE_CODE_FLT:
|
||||
fprintf_filtered (stream, _("<%d-byte float>"), TYPE_LENGTH (type));
|
||||
break;
|
||||
case TYPE_CODE_ENUM:
|
||||
if (show < 0)
|
||||
fprintf_filtered (stream, "(...)");
|
||||
else
|
||||
print_enum_type (type, stream);
|
||||
break;
|
||||
case TYPE_CODE_STRUCT:
|
||||
if (ada_is_array_descriptor_type (type))
|
||||
print_array_type (type, stream, show, level, flags);
|
||||
else if (ada_is_bogus_array_descriptor (type))
|
||||
fprintf_filtered (stream,
|
||||
_("array (?) of ? (<mal-formed descriptor>)"));
|
||||
else
|
||||
print_record_type (type, stream, show, level, flags);
|
||||
break;
|
||||
case TYPE_CODE_UNION:
|
||||
print_unchecked_union_type (type, stream, show, level, flags);
|
||||
break;
|
||||
case TYPE_CODE_FUNC:
|
||||
print_func_type (type, stream, varstring, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement the la_print_typedef language method for Ada. */
|
||||
|
||||
void
|
||||
ada_print_typedef (struct type *type, struct symbol *new_symbol,
|
||||
struct ui_file *stream)
|
||||
{
|
||||
type = ada_check_typedef (type);
|
||||
ada_print_type (type, "", stream, 0, 0, &type_print_raw_options);
|
||||
fprintf_filtered (stream, "\n");
|
||||
}
|
||||
1134
gdb/ada-valprint.c
1134
gdb/ada-valprint.c
File diff suppressed because it is too large
Load Diff
888
gdb/ada-varobj.c
888
gdb/ada-varobj.c
@@ -1,888 +0,0 @@
|
||||
/* varobj support for Ada.
|
||||
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "ada-varobj.h"
|
||||
#include "ada-lang.h"
|
||||
#include "language.h"
|
||||
#include "valprint.h"
|
||||
|
||||
/* Implementation principle used in this unit:
|
||||
|
||||
For our purposes, the meat of the varobj object is made of two
|
||||
elements: The varobj's (struct) value, and the varobj's (struct)
|
||||
type. In most situations, the varobj has a non-NULL value, and
|
||||
the type becomes redundant, as it can be directly derived from
|
||||
the value. In the initial implementation of this unit, most
|
||||
routines would only take a value, and return a value.
|
||||
|
||||
But there are many situations where it is possible for a varobj
|
||||
to have a NULL value. For instance, if the varobj becomes out of
|
||||
scope. Or better yet, when the varobj is the child of another
|
||||
NULL pointer varobj. In that situation, we must rely on the type
|
||||
instead of the value to create the child varobj.
|
||||
|
||||
That's why most functions below work with a (value, type) pair.
|
||||
The value may or may not be NULL. But the type is always expected
|
||||
to be set. When the value is NULL, then we work with the type
|
||||
alone, and keep the value NULL. But when the value is not NULL,
|
||||
then we work using the value, because it provides more information.
|
||||
But we still always set the type as well, even if that type could
|
||||
easily be derived from the value. The reason behind this is that
|
||||
it allows the code to use the type without having to worry about
|
||||
it being set or not. It makes the code clearer. */
|
||||
|
||||
/* A convenience function that decodes the VALUE_PTR/TYPE_PTR couple:
|
||||
If there is a value (*VALUE_PTR not NULL), then perform the decoding
|
||||
using it, and compute the associated type from the resulting value.
|
||||
Otherwise, compute a static approximation of *TYPE_PTR, leaving
|
||||
*VALUE_PTR unchanged.
|
||||
|
||||
The results are written in place. */
|
||||
|
||||
static void
|
||||
ada_varobj_decode_var (struct value **value_ptr, struct type **type_ptr)
|
||||
{
|
||||
if (*value_ptr)
|
||||
{
|
||||
*value_ptr = ada_get_decoded_value (*value_ptr);
|
||||
*type_ptr = ada_check_typedef (value_type (*value_ptr));
|
||||
}
|
||||
else
|
||||
*type_ptr = ada_get_decoded_type (*type_ptr);
|
||||
}
|
||||
|
||||
/* Return a string containing an image of the given scalar value.
|
||||
VAL is the numeric value, while TYPE is the value's type.
|
||||
This is useful for plain integers, of course, but even more
|
||||
so for enumerated types.
|
||||
|
||||
The result should be deallocated by xfree after use. */
|
||||
|
||||
static char *
|
||||
ada_varobj_scalar_image (struct type *type, LONGEST val)
|
||||
{
|
||||
struct ui_file *buf = mem_fileopen ();
|
||||
struct cleanup *cleanups = make_cleanup_ui_file_delete (buf);
|
||||
char *result;
|
||||
|
||||
ada_print_scalar (type, val, buf);
|
||||
result = ui_file_xstrdup (buf, NULL);
|
||||
do_cleanups (cleanups);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair designates
|
||||
a struct or union, compute the (CHILD_VALUE, CHILD_TYPE) couple
|
||||
corresponding to the field number FIELDNO. */
|
||||
|
||||
static void
|
||||
ada_varobj_struct_elt (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
int fieldno,
|
||||
struct value **child_value,
|
||||
struct type **child_type)
|
||||
{
|
||||
struct value *value = NULL;
|
||||
struct type *type = NULL;
|
||||
|
||||
if (parent_value)
|
||||
{
|
||||
value = value_field (parent_value, fieldno);
|
||||
type = value_type (value);
|
||||
}
|
||||
else
|
||||
type = TYPE_FIELD_TYPE (parent_type, fieldno);
|
||||
|
||||
if (child_value)
|
||||
*child_value = value;
|
||||
if (child_type)
|
||||
*child_type = type;
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a pointer or
|
||||
reference, return a (CHILD_VALUE, CHILD_TYPE) couple corresponding
|
||||
to the dereferenced value. */
|
||||
|
||||
static void
|
||||
ada_varobj_ind (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
struct value **child_value,
|
||||
struct type **child_type)
|
||||
{
|
||||
struct value *value = NULL;
|
||||
struct type *type = NULL;
|
||||
|
||||
if (ada_is_array_descriptor_type (parent_type))
|
||||
{
|
||||
/* This can only happen when PARENT_VALUE is NULL. Otherwise,
|
||||
ada_get_decoded_value would have transformed our parent_type
|
||||
into a simple array pointer type. */
|
||||
gdb_assert (parent_value == NULL);
|
||||
gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF);
|
||||
|
||||
/* Decode parent_type by the equivalent pointer to (decoded)
|
||||
array. */
|
||||
while (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
|
||||
parent_type = TYPE_TARGET_TYPE (parent_type);
|
||||
parent_type = ada_coerce_to_simple_array_type (parent_type);
|
||||
parent_type = lookup_pointer_type (parent_type);
|
||||
}
|
||||
|
||||
/* If parent_value is a null pointer, then only perform static
|
||||
dereferencing. We cannot dereference null pointers. */
|
||||
if (parent_value && value_as_address (parent_value) == 0)
|
||||
parent_value = NULL;
|
||||
|
||||
if (parent_value)
|
||||
{
|
||||
value = ada_value_ind (parent_value);
|
||||
type = value_type (value);
|
||||
}
|
||||
else
|
||||
type = TYPE_TARGET_TYPE (parent_type);
|
||||
|
||||
if (child_value)
|
||||
*child_value = value;
|
||||
if (child_type)
|
||||
*child_type = type;
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a simple
|
||||
array (TYPE_CODE_ARRAY), return the (CHILD_VALUE, CHILD_TYPE)
|
||||
pair corresponding to the element at ELT_INDEX. */
|
||||
|
||||
static void
|
||||
ada_varobj_simple_array_elt (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
int elt_index,
|
||||
struct value **child_value,
|
||||
struct type **child_type)
|
||||
{
|
||||
struct value *value = NULL;
|
||||
struct type *type = NULL;
|
||||
|
||||
if (parent_value)
|
||||
{
|
||||
struct value *index_value =
|
||||
value_from_longest (TYPE_INDEX_TYPE (parent_type), elt_index);
|
||||
|
||||
value = ada_value_subscript (parent_value, 1, &index_value);
|
||||
type = value_type (value);
|
||||
}
|
||||
else
|
||||
type = TYPE_TARGET_TYPE (parent_type);
|
||||
|
||||
if (child_value)
|
||||
*child_value = value;
|
||||
if (child_type)
|
||||
*child_type = type;
|
||||
}
|
||||
|
||||
/* Given the decoded value and decoded type of a variable object,
|
||||
adjust the value and type to those necessary for getting children
|
||||
of the variable object.
|
||||
|
||||
The replacement is performed in place. */
|
||||
|
||||
static void
|
||||
ada_varobj_adjust_for_child_access (struct value **value,
|
||||
struct type **type)
|
||||
{
|
||||
/* Pointers to struct/union types are special: Instead of having
|
||||
one child (the struct), their children are the components of
|
||||
the struct/union type. We handle this situation by dereferencing
|
||||
the (value, type) couple. */
|
||||
if (TYPE_CODE (*type) == TYPE_CODE_PTR
|
||||
&& (TYPE_CODE (TYPE_TARGET_TYPE (*type)) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (TYPE_TARGET_TYPE (*type)) == TYPE_CODE_UNION)
|
||||
&& !ada_is_array_descriptor_type (TYPE_TARGET_TYPE (*type))
|
||||
&& !ada_is_constrained_packed_array_type (TYPE_TARGET_TYPE (*type)))
|
||||
ada_varobj_ind (*value, *type, value, type);
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is an array
|
||||
(any type of array, "simple" or not), return the number of children
|
||||
that this array contains. */
|
||||
|
||||
static int
|
||||
ada_varobj_get_array_number_of_children (struct value *parent_value,
|
||||
struct type *parent_type)
|
||||
{
|
||||
LONGEST lo, hi;
|
||||
|
||||
if (!get_array_bounds (parent_type, &lo, &hi))
|
||||
{
|
||||
/* Could not get the array bounds. Pretend this is an empty array. */
|
||||
warning (_("unable to get bounds of array, assuming null array"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ada allows the upper bound to be less than the lower bound,
|
||||
in order to specify empty arrays... */
|
||||
if (hi < lo)
|
||||
return 0;
|
||||
|
||||
return hi - lo + 1;
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair is a struct or
|
||||
union, return the number of children this struct contains. */
|
||||
|
||||
static int
|
||||
ada_varobj_get_struct_number_of_children (struct value *parent_value,
|
||||
struct type *parent_type)
|
||||
{
|
||||
int n_children = 0;
|
||||
int i;
|
||||
|
||||
gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (parent_type) == TYPE_CODE_UNION);
|
||||
|
||||
for (i = 0; i < TYPE_NFIELDS (parent_type); i++)
|
||||
{
|
||||
if (ada_is_ignored_field (parent_type, i))
|
||||
continue;
|
||||
|
||||
if (ada_is_wrapper_field (parent_type, i))
|
||||
{
|
||||
struct value *elt_value;
|
||||
struct type *elt_type;
|
||||
|
||||
ada_varobj_struct_elt (parent_value, parent_type, i,
|
||||
&elt_value, &elt_type);
|
||||
if (ada_is_tagged_type (elt_type, 0))
|
||||
{
|
||||
/* We must not use ada_varobj_get_number_of_children
|
||||
to determine is element's number of children, because
|
||||
this function first calls ada_varobj_decode_var,
|
||||
which "fixes" the element. For tagged types, this
|
||||
includes reading the object's tag to determine its
|
||||
real type, which happens to be the parent_type, and
|
||||
leads to an infinite loop (because the element gets
|
||||
fixed back into the parent). */
|
||||
n_children += ada_varobj_get_struct_number_of_children
|
||||
(elt_value, elt_type);
|
||||
}
|
||||
else
|
||||
n_children += ada_varobj_get_number_of_children (elt_value, elt_type);
|
||||
}
|
||||
else if (ada_is_variant_part (parent_type, i))
|
||||
{
|
||||
/* In normal situations, the variant part of the record should
|
||||
have been "fixed". Or, in other words, it should have been
|
||||
replaced by the branch of the variant part that is relevant
|
||||
for our value. But there are still situations where this
|
||||
can happen, however (Eg. when our parent is a NULL pointer).
|
||||
We do not support showing this part of the record for now,
|
||||
so just pretend this field does not exist. */
|
||||
}
|
||||
else
|
||||
n_children++;
|
||||
}
|
||||
|
||||
return n_children;
|
||||
}
|
||||
|
||||
/* Assuming that the (PARENT_VALUE, PARENT_TYPE) pair designates
|
||||
a pointer, return the number of children this pointer has. */
|
||||
|
||||
static int
|
||||
ada_varobj_get_ptr_number_of_children (struct value *parent_value,
|
||||
struct type *parent_type)
|
||||
{
|
||||
struct type *child_type = TYPE_TARGET_TYPE (parent_type);
|
||||
|
||||
/* Pointer to functions and to void do not have a child, since
|
||||
you cannot print what they point to. */
|
||||
if (TYPE_CODE (child_type) == TYPE_CODE_FUNC
|
||||
|| TYPE_CODE (child_type) == TYPE_CODE_VOID)
|
||||
return 0;
|
||||
|
||||
/* All other types have 1 child. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the number of children for the (PARENT_VALUE, PARENT_TYPE)
|
||||
pair. */
|
||||
|
||||
int
|
||||
ada_varobj_get_number_of_children (struct value *parent_value,
|
||||
struct type *parent_type)
|
||||
{
|
||||
ada_varobj_decode_var (&parent_value, &parent_type);
|
||||
ada_varobj_adjust_for_child_access (&parent_value, &parent_type);
|
||||
|
||||
/* A typedef to an array descriptor in fact represents a pointer
|
||||
to an unconstrained array. These types always have one child
|
||||
(the unconstrained array). */
|
||||
if (ada_is_array_descriptor_type (parent_type)
|
||||
&& TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
|
||||
return 1;
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY)
|
||||
return ada_varobj_get_array_number_of_children (parent_value,
|
||||
parent_type);
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT
|
||||
|| TYPE_CODE (parent_type) == TYPE_CODE_UNION)
|
||||
return ada_varobj_get_struct_number_of_children (parent_value,
|
||||
parent_type);
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_PTR)
|
||||
return ada_varobj_get_ptr_number_of_children (parent_value,
|
||||
parent_type);
|
||||
|
||||
/* All other types have no child. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Describe the child of the (PARENT_VALUE, PARENT_TYPE) pair
|
||||
whose index is CHILD_INDEX:
|
||||
|
||||
- If CHILD_NAME is not NULL, then a copy of the child's name
|
||||
is saved in *CHILD_NAME. This copy must be deallocated
|
||||
with xfree after use.
|
||||
|
||||
- If CHILD_VALUE is not NULL, then save the child's value
|
||||
in *CHILD_VALUE. Same thing for the child's type with
|
||||
CHILD_TYPE if not NULL.
|
||||
|
||||
- If CHILD_PATH_EXPR is not NULL, then compute the child's
|
||||
path expression. The resulting string must be deallocated
|
||||
after use with xfree.
|
||||
|
||||
Computing the child's path expression requires the PARENT_PATH_EXPR
|
||||
to be non-NULL. Otherwise, PARENT_PATH_EXPR may be null if
|
||||
CHILD_PATH_EXPR is NULL.
|
||||
|
||||
PARENT_NAME is the name of the parent, and should never be NULL. */
|
||||
|
||||
static void ada_varobj_describe_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index,
|
||||
char **child_name,
|
||||
struct value **child_value,
|
||||
struct type **child_type,
|
||||
char **child_path_expr);
|
||||
|
||||
/* Same as ada_varobj_describe_child, but limited to struct/union
|
||||
objects. */
|
||||
|
||||
static void
|
||||
ada_varobj_describe_struct_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index,
|
||||
char **child_name,
|
||||
struct value **child_value,
|
||||
struct type **child_type,
|
||||
char **child_path_expr)
|
||||
{
|
||||
int fieldno;
|
||||
int childno = 0;
|
||||
|
||||
gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT);
|
||||
|
||||
for (fieldno = 0; fieldno < TYPE_NFIELDS (parent_type); fieldno++)
|
||||
{
|
||||
if (ada_is_ignored_field (parent_type, fieldno))
|
||||
continue;
|
||||
|
||||
if (ada_is_wrapper_field (parent_type, fieldno))
|
||||
{
|
||||
struct value *elt_value;
|
||||
struct type *elt_type;
|
||||
int elt_n_children;
|
||||
|
||||
ada_varobj_struct_elt (parent_value, parent_type, fieldno,
|
||||
&elt_value, &elt_type);
|
||||
if (ada_is_tagged_type (elt_type, 0))
|
||||
{
|
||||
/* Same as in ada_varobj_get_struct_number_of_children:
|
||||
For tagged types, we must be careful to not call
|
||||
ada_varobj_get_number_of_children, to prevent our
|
||||
element from being fixed back into the parent. */
|
||||
elt_n_children = ada_varobj_get_struct_number_of_children
|
||||
(elt_value, elt_type);
|
||||
}
|
||||
else
|
||||
elt_n_children =
|
||||
ada_varobj_get_number_of_children (elt_value, elt_type);
|
||||
|
||||
/* Is the child we're looking for one of the children
|
||||
of this wrapper field? */
|
||||
if (child_index - childno < elt_n_children)
|
||||
{
|
||||
if (ada_is_tagged_type (elt_type, 0))
|
||||
{
|
||||
/* Same as in ada_varobj_get_struct_number_of_children:
|
||||
For tagged types, we must be careful to not call
|
||||
ada_varobj_describe_child, to prevent our element
|
||||
from being fixed back into the parent. */
|
||||
ada_varobj_describe_struct_child
|
||||
(elt_value, elt_type, parent_name, parent_path_expr,
|
||||
child_index - childno, child_name, child_value,
|
||||
child_type, child_path_expr);
|
||||
}
|
||||
else
|
||||
ada_varobj_describe_child (elt_value, elt_type,
|
||||
parent_name, parent_path_expr,
|
||||
child_index - childno,
|
||||
child_name, child_value,
|
||||
child_type, child_path_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The child we're looking for is beyond this wrapper
|
||||
field, so skip all its children. */
|
||||
childno += elt_n_children;
|
||||
continue;
|
||||
}
|
||||
else if (ada_is_variant_part (parent_type, fieldno))
|
||||
{
|
||||
/* In normal situations, the variant part of the record should
|
||||
have been "fixed". Or, in other words, it should have been
|
||||
replaced by the branch of the variant part that is relevant
|
||||
for our value. But there are still situations where this
|
||||
can happen, however (Eg. when our parent is a NULL pointer).
|
||||
We do not support showing this part of the record for now,
|
||||
so just pretend this field does not exist. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (childno == child_index)
|
||||
{
|
||||
if (child_name)
|
||||
{
|
||||
/* The name of the child is none other than the field's
|
||||
name, except that we need to strip suffixes from it.
|
||||
For instance, fields with alignment constraints will
|
||||
have an __XVA suffix added to them. */
|
||||
const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno);
|
||||
int child_name_len = ada_name_prefix_len (field_name);
|
||||
|
||||
*child_name = xstrprintf ("%.*s", child_name_len, field_name);
|
||||
}
|
||||
|
||||
if (child_value && parent_value)
|
||||
ada_varobj_struct_elt (parent_value, parent_type, fieldno,
|
||||
child_value, NULL);
|
||||
|
||||
if (child_type)
|
||||
ada_varobj_struct_elt (parent_value, parent_type, fieldno,
|
||||
NULL, child_type);
|
||||
|
||||
if (child_path_expr)
|
||||
{
|
||||
/* The name of the child is none other than the field's
|
||||
name, except that we need to strip suffixes from it.
|
||||
For instance, fields with alignment constraints will
|
||||
have an __XVA suffix added to them. */
|
||||
const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno);
|
||||
int child_name_len = ada_name_prefix_len (field_name);
|
||||
|
||||
*child_path_expr =
|
||||
xstrprintf ("(%s).%.*s", parent_path_expr,
|
||||
child_name_len, field_name);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
childno++;
|
||||
}
|
||||
|
||||
/* Something went wrong. Either we miscounted the number of
|
||||
children, or CHILD_INDEX was too high. But we should never
|
||||
reach here. We don't have enough information to recover
|
||||
nicely, so just raise an assertion failure. */
|
||||
gdb_assert_not_reached ("unexpected code path");
|
||||
}
|
||||
|
||||
/* Same as ada_varobj_describe_child, but limited to pointer objects.
|
||||
|
||||
Note that CHILD_INDEX is unused in this situation, but still provided
|
||||
for consistency of interface with other routines describing an object's
|
||||
child. */
|
||||
|
||||
static void
|
||||
ada_varobj_describe_ptr_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index,
|
||||
char **child_name,
|
||||
struct value **child_value,
|
||||
struct type **child_type,
|
||||
char **child_path_expr)
|
||||
{
|
||||
if (child_name)
|
||||
*child_name = xstrprintf ("%s.all", parent_name);
|
||||
|
||||
if (child_value && parent_value)
|
||||
ada_varobj_ind (parent_value, parent_type, child_value, NULL);
|
||||
|
||||
if (child_type)
|
||||
ada_varobj_ind (parent_value, parent_type, NULL, child_type);
|
||||
|
||||
if (child_path_expr)
|
||||
*child_path_expr = xstrprintf ("(%s).all", parent_path_expr);
|
||||
}
|
||||
|
||||
/* Same as ada_varobj_describe_child, limited to simple array objects
|
||||
(TYPE_CODE_ARRAY only).
|
||||
|
||||
Assumes that the (PARENT_VALUE, PARENT_TYPE) pair is properly decoded.
|
||||
This is done by ada_varobj_describe_child before calling us. */
|
||||
|
||||
static void
|
||||
ada_varobj_describe_simple_array_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index,
|
||||
char **child_name,
|
||||
struct value **child_value,
|
||||
struct type **child_type,
|
||||
char **child_path_expr)
|
||||
{
|
||||
struct type *index_desc_type;
|
||||
struct type *index_type;
|
||||
int real_index;
|
||||
|
||||
gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY);
|
||||
|
||||
index_desc_type = ada_find_parallel_type (parent_type, "___XA");
|
||||
ada_fixup_array_indexes_type (index_desc_type);
|
||||
if (index_desc_type)
|
||||
index_type = TYPE_FIELD_TYPE (index_desc_type, 0);
|
||||
else
|
||||
index_type = TYPE_INDEX_TYPE (parent_type);
|
||||
real_index = child_index + ada_discrete_type_low_bound (index_type);
|
||||
|
||||
if (child_name)
|
||||
*child_name = ada_varobj_scalar_image (index_type, real_index);
|
||||
|
||||
if (child_value && parent_value)
|
||||
ada_varobj_simple_array_elt (parent_value, parent_type, real_index,
|
||||
child_value, NULL);
|
||||
|
||||
if (child_type)
|
||||
ada_varobj_simple_array_elt (parent_value, parent_type, real_index,
|
||||
NULL, child_type);
|
||||
|
||||
if (child_path_expr)
|
||||
{
|
||||
char *index_img = ada_varobj_scalar_image (index_type, real_index);
|
||||
struct cleanup *cleanups = make_cleanup (xfree, index_img);
|
||||
|
||||
/* Enumeration litterals by themselves are potentially ambiguous.
|
||||
For instance, consider the following package spec:
|
||||
|
||||
package Pck is
|
||||
type Color is (Red, Green, Blue, White);
|
||||
type Blood_Cells is (White, Red);
|
||||
end Pck;
|
||||
|
||||
In this case, the litteral "red" for instance, or even
|
||||
the fully-qualified litteral "pck.red" cannot be resolved
|
||||
by itself. Type qualification is needed to determine which
|
||||
enumeration litterals should be used.
|
||||
|
||||
The following variable will be used to contain the name
|
||||
of the array index type when such type qualification is
|
||||
needed. */
|
||||
const char *index_type_name = NULL;
|
||||
|
||||
/* If the index type is a range type, find the base type. */
|
||||
while (TYPE_CODE (index_type) == TYPE_CODE_RANGE)
|
||||
index_type = TYPE_TARGET_TYPE (index_type);
|
||||
|
||||
if (TYPE_CODE (index_type) == TYPE_CODE_ENUM
|
||||
|| TYPE_CODE (index_type) == TYPE_CODE_BOOL)
|
||||
{
|
||||
index_type_name = ada_type_name (index_type);
|
||||
if (index_type_name)
|
||||
index_type_name = ada_decode (index_type_name);
|
||||
}
|
||||
|
||||
if (index_type_name != NULL)
|
||||
*child_path_expr =
|
||||
xstrprintf ("(%s)(%.*s'(%s))", parent_path_expr,
|
||||
ada_name_prefix_len (index_type_name),
|
||||
index_type_name, index_img);
|
||||
else
|
||||
*child_path_expr =
|
||||
xstrprintf ("(%s)(%s)", parent_path_expr, index_img);
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
}
|
||||
|
||||
/* See description at declaration above. */
|
||||
|
||||
static void
|
||||
ada_varobj_describe_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index,
|
||||
char **child_name,
|
||||
struct value **child_value,
|
||||
struct type **child_type,
|
||||
char **child_path_expr)
|
||||
{
|
||||
/* We cannot compute the child's path expression without
|
||||
the parent's path expression. This is a pre-condition
|
||||
for calling this function. */
|
||||
if (child_path_expr)
|
||||
gdb_assert (parent_path_expr != NULL);
|
||||
|
||||
ada_varobj_decode_var (&parent_value, &parent_type);
|
||||
ada_varobj_adjust_for_child_access (&parent_value, &parent_type);
|
||||
|
||||
if (child_name)
|
||||
*child_name = NULL;
|
||||
if (child_value)
|
||||
*child_value = NULL;
|
||||
if (child_type)
|
||||
*child_type = NULL;
|
||||
if (child_path_expr)
|
||||
*child_path_expr = NULL;
|
||||
|
||||
if (ada_is_array_descriptor_type (parent_type)
|
||||
&& TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
|
||||
{
|
||||
ada_varobj_describe_ptr_child (parent_value, parent_type,
|
||||
parent_name, parent_path_expr,
|
||||
child_index, child_name,
|
||||
child_value, child_type,
|
||||
child_path_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
ada_varobj_describe_simple_array_child
|
||||
(parent_value, parent_type, parent_name, parent_path_expr,
|
||||
child_index, child_name, child_value, child_type,
|
||||
child_path_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_STRUCT)
|
||||
{
|
||||
ada_varobj_describe_struct_child (parent_value, parent_type,
|
||||
parent_name, parent_path_expr,
|
||||
child_index, child_name,
|
||||
child_value, child_type,
|
||||
child_path_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TYPE_CODE (parent_type) == TYPE_CODE_PTR)
|
||||
{
|
||||
ada_varobj_describe_ptr_child (parent_value, parent_type,
|
||||
parent_name, parent_path_expr,
|
||||
child_index, child_name,
|
||||
child_value, child_type,
|
||||
child_path_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* It should never happen. But rather than crash, report dummy names
|
||||
and return a NULL child_value. */
|
||||
if (child_name)
|
||||
*child_name = xstrdup ("???");
|
||||
}
|
||||
|
||||
/* Return the name of the child number CHILD_INDEX of the (PARENT_VALUE,
|
||||
PARENT_TYPE) pair. PARENT_NAME is the name of the PARENT.
|
||||
|
||||
The result should be deallocated after use with xfree. */
|
||||
|
||||
char *
|
||||
ada_varobj_get_name_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name, int child_index)
|
||||
{
|
||||
char *child_name;
|
||||
|
||||
ada_varobj_describe_child (parent_value, parent_type, parent_name,
|
||||
NULL, child_index, &child_name, NULL,
|
||||
NULL, NULL);
|
||||
return child_name;
|
||||
}
|
||||
|
||||
/* Return the path expression of the child number CHILD_INDEX of
|
||||
the (PARENT_VALUE, PARENT_TYPE) pair. PARENT_NAME is the name
|
||||
of the parent, and PARENT_PATH_EXPR is the parent's path expression.
|
||||
Both must be non-NULL.
|
||||
|
||||
The result must be deallocated after use with xfree. */
|
||||
|
||||
char *
|
||||
ada_varobj_get_path_expr_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index)
|
||||
{
|
||||
char *child_path_expr;
|
||||
|
||||
ada_varobj_describe_child (parent_value, parent_type, parent_name,
|
||||
parent_path_expr, child_index, NULL,
|
||||
NULL, NULL, &child_path_expr);
|
||||
|
||||
return child_path_expr;
|
||||
}
|
||||
|
||||
/* Return the value of child number CHILD_INDEX of the (PARENT_VALUE,
|
||||
PARENT_TYPE) pair. PARENT_NAME is the name of the parent. */
|
||||
|
||||
struct value *
|
||||
ada_varobj_get_value_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name, int child_index)
|
||||
{
|
||||
struct value *child_value;
|
||||
|
||||
ada_varobj_describe_child (parent_value, parent_type, parent_name,
|
||||
NULL, child_index, NULL, &child_value,
|
||||
NULL, NULL);
|
||||
|
||||
return child_value;
|
||||
}
|
||||
|
||||
/* Return the type of child number CHILD_INDEX of the (PARENT_VALUE,
|
||||
PARENT_TYPE) pair. */
|
||||
|
||||
struct type *
|
||||
ada_varobj_get_type_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
int child_index)
|
||||
{
|
||||
struct type *child_type;
|
||||
|
||||
ada_varobj_describe_child (parent_value, parent_type, NULL, NULL,
|
||||
child_index, NULL, NULL, &child_type, NULL);
|
||||
|
||||
return child_type;
|
||||
}
|
||||
|
||||
/* Return a string that contains the image of the given VALUE, using
|
||||
the print options OPTS as the options for formatting the result.
|
||||
|
||||
The resulting string must be deallocated after use with xfree. */
|
||||
|
||||
static char *
|
||||
ada_varobj_get_value_image (struct value *value,
|
||||
struct value_print_options *opts)
|
||||
{
|
||||
char *result;
|
||||
struct ui_file *buffer;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
buffer = mem_fileopen ();
|
||||
old_chain = make_cleanup_ui_file_delete (buffer);
|
||||
|
||||
common_val_print (value, buffer, 0, opts, current_language);
|
||||
result = ui_file_xstrdup (buffer, NULL);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Assuming that the (VALUE, TYPE) pair designates an array varobj,
|
||||
return a string that is suitable for use in the "value" field of
|
||||
the varobj output. Most of the time, this is the number of elements
|
||||
in the array inside square brackets, but there are situations where
|
||||
it's useful to add more info.
|
||||
|
||||
OPTS are the print options used when formatting the result.
|
||||
|
||||
The result should be deallocated after use using xfree. */
|
||||
|
||||
static char *
|
||||
ada_varobj_get_value_of_array_variable (struct value *value,
|
||||
struct type *type,
|
||||
struct value_print_options *opts)
|
||||
{
|
||||
char *result;
|
||||
const int numchild = ada_varobj_get_array_number_of_children (value, type);
|
||||
|
||||
/* If we have a string, provide its contents in the "value" field.
|
||||
Otherwise, the only other way to inspect the contents of the string
|
||||
is by looking at the value of each element, as in any other array,
|
||||
which is not very convenient... */
|
||||
if (value
|
||||
&& ada_is_string_type (type)
|
||||
&& (opts->format == 0 || opts->format == 's'))
|
||||
{
|
||||
char *str;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
str = ada_varobj_get_value_image (value, opts);
|
||||
old_chain = make_cleanup (xfree, str);
|
||||
result = xstrprintf ("[%d] %s", numchild, str);
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
else
|
||||
result = xstrprintf ("[%d]", numchild);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a string representation of the (VALUE, TYPE) pair, using
|
||||
the given print options OPTS as our formatting options. */
|
||||
|
||||
char *
|
||||
ada_varobj_get_value_of_variable (struct value *value,
|
||||
struct type *type,
|
||||
struct value_print_options *opts)
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
ada_varobj_decode_var (&value, &type);
|
||||
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
result = xstrdup ("{...}");
|
||||
break;
|
||||
case TYPE_CODE_ARRAY:
|
||||
result = ada_varobj_get_value_of_array_variable (value, type, opts);
|
||||
break;
|
||||
default:
|
||||
if (!value)
|
||||
result = xstrdup ("");
|
||||
else
|
||||
result = ada_varobj_get_value_image (value, opts);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/* varobj support for Ada.
|
||||
|
||||
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ADA_VAROBJ_H
|
||||
#define ADA_VAROBJ_H
|
||||
|
||||
#include "varobj.h"
|
||||
|
||||
struct value;
|
||||
struct value_print_options;
|
||||
|
||||
extern int ada_varobj_get_number_of_children (struct value *parent_value,
|
||||
struct type *parent_type);
|
||||
|
||||
extern char *ada_varobj_get_name_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
int child_index);
|
||||
|
||||
extern char *ada_varobj_get_path_expr_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
const char *parent_path_expr,
|
||||
int child_index);
|
||||
|
||||
extern struct value *ada_varobj_get_value_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
const char *parent_name,
|
||||
int child_index);
|
||||
|
||||
extern struct type *ada_varobj_get_type_of_child (struct value *parent_value,
|
||||
struct type *parent_type,
|
||||
int child_index);
|
||||
|
||||
extern char *ada_varobj_get_value_of_variable
|
||||
(struct value *value, struct type *type,
|
||||
struct value_print_options *opts);
|
||||
|
||||
#endif /* ADA_VAROBJ_H */
|
||||
609
gdb/addrmap.c
609
gdb/addrmap.c
@@ -1,609 +0,0 @@
|
||||
/* addrmap.c --- implementation of address map data structure.
|
||||
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "splay-tree.h"
|
||||
#include "gdb_obstack.h"
|
||||
#include "addrmap.h"
|
||||
#include "gdb_assert.h"
|
||||
|
||||
|
||||
|
||||
/* The "abstract class". */
|
||||
|
||||
/* Functions implementing the addrmap functions for a particular
|
||||
implementation. */
|
||||
struct addrmap_funcs
|
||||
{
|
||||
void (*set_empty) (struct addrmap *this,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive,
|
||||
void *obj);
|
||||
void *(*find) (struct addrmap *this, CORE_ADDR addr);
|
||||
struct addrmap *(*create_fixed) (struct addrmap *this,
|
||||
struct obstack *obstack);
|
||||
void (*relocate) (struct addrmap *this, CORE_ADDR offset);
|
||||
int (*foreach) (struct addrmap *this, addrmap_foreach_fn fn, void *data);
|
||||
};
|
||||
|
||||
|
||||
struct addrmap
|
||||
{
|
||||
const struct addrmap_funcs *funcs;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
addrmap_set_empty (struct addrmap *map,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive,
|
||||
void *obj)
|
||||
{
|
||||
map->funcs->set_empty (map, start, end_inclusive, obj);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
addrmap_find (struct addrmap *map, CORE_ADDR addr)
|
||||
{
|
||||
return map->funcs->find (map, addr);
|
||||
}
|
||||
|
||||
|
||||
struct addrmap *
|
||||
addrmap_create_fixed (struct addrmap *original, struct obstack *obstack)
|
||||
{
|
||||
return original->funcs->create_fixed (original, obstack);
|
||||
}
|
||||
|
||||
|
||||
/* Relocate all the addresses in MAP by OFFSET. (This can be applied
|
||||
to either mutable or immutable maps.) */
|
||||
void
|
||||
addrmap_relocate (struct addrmap *map, CORE_ADDR offset)
|
||||
{
|
||||
map->funcs->relocate (map, offset);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data)
|
||||
{
|
||||
return map->funcs->foreach (map, fn, data);
|
||||
}
|
||||
|
||||
/* Fixed address maps. */
|
||||
|
||||
/* A transition: a point in an address map where the value changes.
|
||||
The map maps ADDR to VALUE, but if ADDR > 0, it maps ADDR-1 to
|
||||
something else. */
|
||||
struct addrmap_transition
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
void *value;
|
||||
};
|
||||
|
||||
|
||||
struct addrmap_fixed
|
||||
{
|
||||
struct addrmap addrmap;
|
||||
|
||||
/* The number of transitions in TRANSITIONS. */
|
||||
size_t num_transitions;
|
||||
|
||||
/* An array of transitions, sorted by address. For every point in
|
||||
the map where either ADDR == 0 or ADDR is mapped to one value and
|
||||
ADDR - 1 is mapped to something different, we have an entry here
|
||||
containing ADDR and VALUE. (Note that this means we always have
|
||||
an entry for address 0). */
|
||||
struct addrmap_transition transitions[1];
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
addrmap_fixed_set_empty (struct addrmap *this,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive,
|
||||
void *obj)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
"addrmap_fixed_set_empty: "
|
||||
"fixed addrmaps can't be changed\n");
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
addrmap_fixed_find (struct addrmap *this, CORE_ADDR addr)
|
||||
{
|
||||
struct addrmap_fixed *map = (struct addrmap_fixed *) this;
|
||||
struct addrmap_transition *bottom = &map->transitions[0];
|
||||
struct addrmap_transition *top = &map->transitions[map->num_transitions - 1];
|
||||
|
||||
while (bottom < top)
|
||||
{
|
||||
/* This needs to round towards top, or else when top = bottom +
|
||||
1 (i.e., two entries are under consideration), then mid ==
|
||||
bottom, and then we may not narrow the range when (mid->addr
|
||||
< addr). */
|
||||
struct addrmap_transition *mid = top - (top - bottom) / 2;
|
||||
|
||||
if (mid->addr == addr)
|
||||
{
|
||||
bottom = mid;
|
||||
break;
|
||||
}
|
||||
else if (mid->addr < addr)
|
||||
/* We don't eliminate mid itself here, since each transition
|
||||
covers all subsequent addresses until the next. This is why
|
||||
we must round up in computing the midpoint. */
|
||||
bottom = mid;
|
||||
else
|
||||
top = mid - 1;
|
||||
}
|
||||
|
||||
return bottom->value;
|
||||
}
|
||||
|
||||
|
||||
static struct addrmap *
|
||||
addrmap_fixed_create_fixed (struct addrmap *this, struct obstack *obstack)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("addrmap_create_fixed is not implemented yet "
|
||||
"for fixed addrmaps"));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_fixed_relocate (struct addrmap *this, CORE_ADDR offset)
|
||||
{
|
||||
struct addrmap_fixed *map = (struct addrmap_fixed *) this;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->num_transitions; i++)
|
||||
map->transitions[i].addr += offset;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
addrmap_fixed_foreach (struct addrmap *this, addrmap_foreach_fn fn,
|
||||
void *data)
|
||||
{
|
||||
struct addrmap_fixed *map = (struct addrmap_fixed *) this;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < map->num_transitions; i++)
|
||||
{
|
||||
int res = fn (data, map->transitions[i].addr, map->transitions[i].value);
|
||||
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct addrmap_funcs addrmap_fixed_funcs =
|
||||
{
|
||||
addrmap_fixed_set_empty,
|
||||
addrmap_fixed_find,
|
||||
addrmap_fixed_create_fixed,
|
||||
addrmap_fixed_relocate,
|
||||
addrmap_fixed_foreach
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Mutable address maps. */
|
||||
|
||||
struct addrmap_mutable
|
||||
{
|
||||
struct addrmap addrmap;
|
||||
|
||||
/* The obstack to use for allocations for this map. */
|
||||
struct obstack *obstack;
|
||||
|
||||
/* A splay tree, with a node for each transition; there is a
|
||||
transition at address T if T-1 and T map to different objects.
|
||||
|
||||
Any addresses below the first node map to NULL. (Unlike
|
||||
fixed maps, we have no entry at (CORE_ADDR) 0; it doesn't
|
||||
simplify enough.)
|
||||
|
||||
The last region is assumed to end at CORE_ADDR_MAX.
|
||||
|
||||
Since we can't know whether CORE_ADDR is larger or smaller than
|
||||
splay_tree_key (unsigned long) --- I think both are possible,
|
||||
given all combinations of 32- and 64-bit hosts and targets ---
|
||||
our keys are pointers to CORE_ADDR values. Since the splay tree
|
||||
library doesn't pass any closure pointer to the key free
|
||||
function, we can't keep a freelist for keys. Since mutable
|
||||
addrmaps are only used temporarily right now, we just leak keys
|
||||
from deleted nodes; they'll be freed when the obstack is freed. */
|
||||
splay_tree tree;
|
||||
|
||||
/* A freelist for splay tree nodes, allocated on obstack, and
|
||||
chained together by their 'right' pointers. */
|
||||
splay_tree_node free_nodes;
|
||||
};
|
||||
|
||||
|
||||
/* Allocate a copy of CORE_ADDR in MAP's obstack. */
|
||||
static splay_tree_key
|
||||
allocate_key (struct addrmap_mutable *map, CORE_ADDR addr)
|
||||
{
|
||||
CORE_ADDR *key = obstack_alloc (map->obstack, sizeof (*key));
|
||||
|
||||
*key = addr;
|
||||
return (splay_tree_key) key;
|
||||
}
|
||||
|
||||
|
||||
/* Type-correct wrappers for splay tree access. */
|
||||
static splay_tree_node
|
||||
addrmap_splay_tree_lookup (struct addrmap_mutable *map, CORE_ADDR addr)
|
||||
{
|
||||
return splay_tree_lookup (map->tree, (splay_tree_key) &addr);
|
||||
}
|
||||
|
||||
|
||||
static splay_tree_node
|
||||
addrmap_splay_tree_predecessor (struct addrmap_mutable *map, CORE_ADDR addr)
|
||||
{
|
||||
return splay_tree_predecessor (map->tree, (splay_tree_key) &addr);
|
||||
}
|
||||
|
||||
|
||||
static splay_tree_node
|
||||
addrmap_splay_tree_successor (struct addrmap_mutable *map, CORE_ADDR addr)
|
||||
{
|
||||
return splay_tree_successor (map->tree, (splay_tree_key) &addr);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_splay_tree_remove (struct addrmap_mutable *map, CORE_ADDR addr)
|
||||
{
|
||||
splay_tree_remove (map->tree, (splay_tree_key) &addr);
|
||||
}
|
||||
|
||||
|
||||
static CORE_ADDR
|
||||
addrmap_node_key (splay_tree_node node)
|
||||
{
|
||||
return * (CORE_ADDR *) node->key;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
addrmap_node_value (splay_tree_node node)
|
||||
{
|
||||
return (void *) node->value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_node_set_value (splay_tree_node node, void *value)
|
||||
{
|
||||
node->value = (splay_tree_value) value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_splay_tree_insert (struct addrmap_mutable *map,
|
||||
CORE_ADDR key, void *value)
|
||||
{
|
||||
splay_tree_insert (map->tree,
|
||||
allocate_key (map, key),
|
||||
(splay_tree_value) value);
|
||||
}
|
||||
|
||||
|
||||
/* Without changing the mapping of any address, ensure that there is a
|
||||
tree node at ADDR, even if it would represent a "transition" from
|
||||
one value to the same value. */
|
||||
static void
|
||||
force_transition (struct addrmap_mutable *this, CORE_ADDR addr)
|
||||
{
|
||||
splay_tree_node n
|
||||
= addrmap_splay_tree_lookup (this, addr);
|
||||
|
||||
if (! n)
|
||||
{
|
||||
n = addrmap_splay_tree_predecessor (this, addr);
|
||||
addrmap_splay_tree_insert (this, addr,
|
||||
n ? addrmap_node_value (n) : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_mutable_set_empty (struct addrmap *this,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive,
|
||||
void *obj)
|
||||
{
|
||||
struct addrmap_mutable *map = (struct addrmap_mutable *) this;
|
||||
splay_tree_node n, next;
|
||||
void *prior_value;
|
||||
|
||||
/* If we're being asked to set all empty portions of the given
|
||||
address range to empty, then probably the caller is confused.
|
||||
(If that turns out to be useful in some cases, then we can change
|
||||
this to simply return, since overriding NULL with NULL is a
|
||||
no-op.) */
|
||||
gdb_assert (obj);
|
||||
|
||||
/* We take a two-pass approach, for simplicity.
|
||||
- Establish transitions where we think we might need them.
|
||||
- First pass: change all NULL regions to OBJ.
|
||||
- Second pass: remove any unnecessary transitions. */
|
||||
|
||||
/* Establish transitions at the start and end. */
|
||||
force_transition (map, start);
|
||||
if (end_inclusive < CORE_ADDR_MAX)
|
||||
force_transition (map, end_inclusive + 1);
|
||||
|
||||
/* Walk the area, changing all NULL regions to OBJ. */
|
||||
for (n = addrmap_splay_tree_lookup (map, start), gdb_assert (n);
|
||||
n && addrmap_node_key (n) <= end_inclusive;
|
||||
n = addrmap_splay_tree_successor (map, addrmap_node_key (n)))
|
||||
{
|
||||
if (! addrmap_node_value (n))
|
||||
addrmap_node_set_value (n, obj);
|
||||
}
|
||||
|
||||
/* Walk the area again, removing transitions from any value to
|
||||
itself. Be sure to visit both the transitions we forced
|
||||
above. */
|
||||
n = addrmap_splay_tree_predecessor (map, start);
|
||||
prior_value = n ? addrmap_node_value (n) : NULL;
|
||||
for (n = addrmap_splay_tree_lookup (map, start), gdb_assert (n);
|
||||
n && (end_inclusive == CORE_ADDR_MAX
|
||||
|| addrmap_node_key (n) <= end_inclusive + 1);
|
||||
n = next)
|
||||
{
|
||||
next = addrmap_splay_tree_successor (map, addrmap_node_key (n));
|
||||
if (addrmap_node_value (n) == prior_value)
|
||||
addrmap_splay_tree_remove (map, addrmap_node_key (n));
|
||||
else
|
||||
prior_value = addrmap_node_value (n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
addrmap_mutable_find (struct addrmap *this, CORE_ADDR addr)
|
||||
{
|
||||
/* Not needed yet. */
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("addrmap_find is not implemented yet "
|
||||
"for mutable addrmaps"));
|
||||
}
|
||||
|
||||
|
||||
/* A function to pass to splay_tree_foreach to count the number of nodes
|
||||
in the tree. */
|
||||
static int
|
||||
splay_foreach_count (splay_tree_node n, void *closure)
|
||||
{
|
||||
size_t *count = (size_t *) closure;
|
||||
|
||||
(*count)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* A function to pass to splay_tree_foreach to copy entries into a
|
||||
fixed address map. */
|
||||
static int
|
||||
splay_foreach_copy (splay_tree_node n, void *closure)
|
||||
{
|
||||
struct addrmap_fixed *fixed = (struct addrmap_fixed *) closure;
|
||||
struct addrmap_transition *t = &fixed->transitions[fixed->num_transitions];
|
||||
|
||||
t->addr = addrmap_node_key (n);
|
||||
t->value = addrmap_node_value (n);
|
||||
fixed->num_transitions++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct addrmap *
|
||||
addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
|
||||
{
|
||||
struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
|
||||
struct addrmap_fixed *fixed;
|
||||
size_t num_transitions;
|
||||
|
||||
/* Count the number of transitions in the tree. */
|
||||
num_transitions = 0;
|
||||
splay_tree_foreach (mutable->tree, splay_foreach_count, &num_transitions);
|
||||
|
||||
/* Include an extra entry for the transition at zero (which fixed
|
||||
maps have, but mutable maps do not.) */
|
||||
num_transitions++;
|
||||
|
||||
fixed = obstack_alloc (obstack,
|
||||
(sizeof (*fixed)
|
||||
+ (num_transitions
|
||||
* sizeof (fixed->transitions[0]))));
|
||||
fixed->addrmap.funcs = &addrmap_fixed_funcs;
|
||||
fixed->num_transitions = 1;
|
||||
fixed->transitions[0].addr = 0;
|
||||
fixed->transitions[0].value = NULL;
|
||||
|
||||
/* Copy all entries from the splay tree to the array, in order
|
||||
of increasing address. */
|
||||
splay_tree_foreach (mutable->tree, splay_foreach_copy, fixed);
|
||||
|
||||
/* We should have filled the array. */
|
||||
gdb_assert (fixed->num_transitions == num_transitions);
|
||||
|
||||
return (struct addrmap *) fixed;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
addrmap_mutable_relocate (struct addrmap *this, CORE_ADDR offset)
|
||||
{
|
||||
/* Not needed yet. */
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("addrmap_relocate is not implemented yet "
|
||||
"for mutable addrmaps"));
|
||||
}
|
||||
|
||||
|
||||
/* Struct to map addrmap's foreach function to splay_tree's version. */
|
||||
struct mutable_foreach_data
|
||||
{
|
||||
addrmap_foreach_fn fn;
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
/* This is a splay_tree_foreach_fn. */
|
||||
|
||||
static int
|
||||
addrmap_mutable_foreach_worker (splay_tree_node node, void *data)
|
||||
{
|
||||
struct mutable_foreach_data *foreach_data = data;
|
||||
|
||||
return foreach_data->fn (foreach_data->data,
|
||||
addrmap_node_key (node),
|
||||
addrmap_node_value (node));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
addrmap_mutable_foreach (struct addrmap *this, addrmap_foreach_fn fn,
|
||||
void *data)
|
||||
{
|
||||
struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
|
||||
struct mutable_foreach_data foreach_data;
|
||||
|
||||
foreach_data.fn = fn;
|
||||
foreach_data.data = data;
|
||||
return splay_tree_foreach (mutable->tree, addrmap_mutable_foreach_worker,
|
||||
&foreach_data);
|
||||
}
|
||||
|
||||
|
||||
static const struct addrmap_funcs addrmap_mutable_funcs =
|
||||
{
|
||||
addrmap_mutable_set_empty,
|
||||
addrmap_mutable_find,
|
||||
addrmap_mutable_create_fixed,
|
||||
addrmap_mutable_relocate,
|
||||
addrmap_mutable_foreach
|
||||
};
|
||||
|
||||
|
||||
static void *
|
||||
splay_obstack_alloc (int size, void *closure)
|
||||
{
|
||||
struct addrmap_mutable *map = closure;
|
||||
splay_tree_node n;
|
||||
|
||||
/* We should only be asked to allocate nodes and larger things.
|
||||
(If, at some point in the future, this is no longer true, we can
|
||||
just round up the size to sizeof (*n).) */
|
||||
gdb_assert (size >= sizeof (*n));
|
||||
|
||||
if (map->free_nodes)
|
||||
{
|
||||
n = map->free_nodes;
|
||||
map->free_nodes = n->right;
|
||||
return n;
|
||||
}
|
||||
else
|
||||
return obstack_alloc (map->obstack, size);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
splay_obstack_free (void *obj, void *closure)
|
||||
{
|
||||
struct addrmap_mutable *map = closure;
|
||||
splay_tree_node n = obj;
|
||||
|
||||
/* We've asserted in the allocation function that we only allocate
|
||||
nodes or larger things, so it should be safe to put whatever
|
||||
we get passed back on the free list. */
|
||||
n->right = map->free_nodes;
|
||||
map->free_nodes = n;
|
||||
}
|
||||
|
||||
|
||||
/* Compare keys as CORE_ADDR * values. */
|
||||
static int
|
||||
splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
|
||||
{
|
||||
CORE_ADDR a = * (CORE_ADDR *) ak;
|
||||
CORE_ADDR b = * (CORE_ADDR *) bk;
|
||||
|
||||
/* We can't just return a-b here, because of over/underflow. */
|
||||
if (a < b)
|
||||
return -1;
|
||||
else if (a == b)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct addrmap *
|
||||
addrmap_create_mutable (struct obstack *obstack)
|
||||
{
|
||||
struct addrmap_mutable *map = obstack_alloc (obstack, sizeof (*map));
|
||||
|
||||
map->addrmap.funcs = &addrmap_mutable_funcs;
|
||||
map->obstack = obstack;
|
||||
|
||||
/* splay_tree_new_with_allocator uses the provided allocation
|
||||
function to allocate the main splay_tree structure itself, so our
|
||||
free list has to be initialized before we create the tree. */
|
||||
map->free_nodes = NULL;
|
||||
|
||||
map->tree = splay_tree_new_with_allocator (splay_compare_CORE_ADDR_ptr,
|
||||
NULL, /* no delete key */
|
||||
NULL, /* no delete value */
|
||||
splay_obstack_alloc,
|
||||
splay_obstack_free,
|
||||
map);
|
||||
|
||||
return (struct addrmap *) map;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialization. */
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_addrmap;
|
||||
|
||||
void
|
||||
_initialize_addrmap (void)
|
||||
{
|
||||
/* Make sure splay trees can actually hold the values we want to
|
||||
store in them. */
|
||||
gdb_assert (sizeof (splay_tree_key) >= sizeof (CORE_ADDR *));
|
||||
gdb_assert (sizeof (splay_tree_value) >= sizeof (void *));
|
||||
}
|
||||
105
gdb/addrmap.h
105
gdb/addrmap.h
@@ -1,105 +0,0 @@
|
||||
/* addrmap.h --- interface to address map data structure.
|
||||
|
||||
Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ADDRMAP_H
|
||||
#define ADDRMAP_H
|
||||
|
||||
/* An address map is essentially a table mapping CORE_ADDRs onto GDB
|
||||
data structures, like blocks, symtabs, partial symtabs, and so on.
|
||||
An address map uses memory proportional to the number of
|
||||
transitions in the map, where a CORE_ADDR N is mapped to one
|
||||
object, and N+1 is mapped to a different object.
|
||||
|
||||
Address maps come in two flavors: fixed, and mutable. Mutable
|
||||
address maps consume more memory, but can be changed and extended.
|
||||
A fixed address map, once constructed (from a mutable address map),
|
||||
can't be edited. Both kinds of map are allocated in obstacks. */
|
||||
|
||||
/* The opaque type representing address maps. */
|
||||
struct addrmap;
|
||||
|
||||
/* Create a mutable address map which maps every address to NULL.
|
||||
Allocate entries in OBSTACK. */
|
||||
struct addrmap *addrmap_create_mutable (struct obstack *obstack);
|
||||
|
||||
/* In the mutable address map MAP, associate the addresses from START
|
||||
to END_INCLUSIVE that are currently associated with NULL with OBJ
|
||||
instead. Addresses mapped to an object other than NULL are left
|
||||
unchanged.
|
||||
|
||||
As the name suggests, END_INCLUSIVE is also mapped to OBJ. This
|
||||
convention is unusual, but it allows callers to accurately specify
|
||||
ranges that abut the top of the address space, and ranges that
|
||||
cover the entire address space.
|
||||
|
||||
This operation seems a bit complicated for a primitive: if it's
|
||||
needed, why not just have a simpler primitive operation that sets a
|
||||
range to a value, wiping out whatever was there before, and then
|
||||
let the caller construct more complicated operations from that,
|
||||
along with some others for traversal?
|
||||
|
||||
It turns out this is the mutation operation we want to use all the
|
||||
time, at least for now. Our immediate use for address maps is to
|
||||
represent lexical blocks whose address ranges are not contiguous.
|
||||
We walk the tree of lexical blocks present in the debug info, and
|
||||
only create 'struct block' objects after we've traversed all a
|
||||
block's children. If a lexical block declares no local variables
|
||||
(and isn't the lexical block for a function's body), we omit it
|
||||
from GDB's data structures entirely.
|
||||
|
||||
However, this means that we don't decide to create a block (and
|
||||
thus record it in the address map) until after we've traversed its
|
||||
children. If we do decide to create the block, we do so at a time
|
||||
when all its children have already been recorded in the map. So
|
||||
this operation --- change only those addresses left unset --- is
|
||||
actually the operation we want to use every time.
|
||||
|
||||
It seems simpler to let the code which operates on the
|
||||
representation directly deal with the hair of implementing these
|
||||
semantics than to provide an interface which allows it to be
|
||||
implemented efficiently, but doesn't reveal too much of the
|
||||
representation. */
|
||||
void addrmap_set_empty (struct addrmap *map,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive,
|
||||
void *obj);
|
||||
|
||||
/* Return the object associated with ADDR in MAP. */
|
||||
void *addrmap_find (struct addrmap *map, CORE_ADDR addr);
|
||||
|
||||
/* Create a fixed address map which is a copy of the mutable address
|
||||
map ORIGINAL. Allocate entries in OBSTACK. */
|
||||
struct addrmap *addrmap_create_fixed (struct addrmap *original,
|
||||
struct obstack *obstack);
|
||||
|
||||
/* Relocate all the addresses in MAP by OFFSET. (This can be applied
|
||||
to either mutable or immutable maps.) */
|
||||
void addrmap_relocate (struct addrmap *map, CORE_ADDR offset);
|
||||
|
||||
/* The type of a function used to iterate over the map.
|
||||
OBJ is NULL for unmapped regions. */
|
||||
typedef int (*addrmap_foreach_fn) (void *data, CORE_ADDR start_addr,
|
||||
void *obj);
|
||||
|
||||
/* Call FN, passing it DATA, for every address in MAP, following an
|
||||
in-order traversal. If FN ever returns a non-zero value, the
|
||||
iteration ceases immediately, and the value is returned.
|
||||
Otherwise, this function returns 0. */
|
||||
int addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data);
|
||||
|
||||
#endif /* ADDRMAP_H */
|
||||
87
gdb/agent.c
87
gdb/agent.c
@@ -1,87 +0,0 @@
|
||||
/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "target.h"
|
||||
#include "agent.h"
|
||||
|
||||
/* Enum strings for "set|show agent". */
|
||||
|
||||
static const char can_use_agent_on[] = "on";
|
||||
static const char can_use_agent_off[] = "off";
|
||||
static const char *can_use_agent_enum[] =
|
||||
{
|
||||
can_use_agent_on,
|
||||
can_use_agent_off,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *can_use_agent = can_use_agent_off;
|
||||
|
||||
static void
|
||||
show_can_use_agent (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
{
|
||||
fprintf_filtered (file,
|
||||
_("Debugger's willingness to use agent in inferior "
|
||||
"as a helper is %s.\n"), value);
|
||||
}
|
||||
|
||||
static void
|
||||
set_can_use_agent (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
if (target_use_agent (can_use_agent == can_use_agent_on) == 0)
|
||||
/* Something wrong during setting, set flag to default value. */
|
||||
can_use_agent = can_use_agent_off;
|
||||
}
|
||||
|
||||
/* -Wmissing-prototypes */
|
||||
extern initialize_file_ftype _initialize_agent;
|
||||
|
||||
#include "observer.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
static void
|
||||
agent_new_objfile (struct objfile *objfile)
|
||||
{
|
||||
if (objfile == NULL || agent_loaded_p ())
|
||||
return;
|
||||
|
||||
agent_look_up_symbols (objfile);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_agent (void)
|
||||
{
|
||||
observer_attach_new_objfile (agent_new_objfile);
|
||||
|
||||
add_setshow_enum_cmd ("agent", class_run,
|
||||
can_use_agent_enum,
|
||||
&can_use_agent, _("\
|
||||
Set debugger's willingness to use agent as a helper."), _("\
|
||||
Show debugger's willingness to use agent as a helper."), _("\
|
||||
If on, GDB will delegate some of the debugging operations to the\n\
|
||||
agent, if the target supports it. This will speed up those\n\
|
||||
operations that are supported by the agent.\n\
|
||||
If off, GDB will not use agent, even if such is supported by the\n\
|
||||
target."),
|
||||
set_can_use_agent,
|
||||
show_can_use_agent,
|
||||
&setlist, &showlist);
|
||||
}
|
||||
1870
gdb/aix-thread.c
1870
gdb/aix-thread.c
File diff suppressed because it is too large
Load Diff
@@ -1,100 +0,0 @@
|
||||
/* Low level Alpha GNU/Linux interface, for GDB when running native.
|
||||
Copyright (C) 2005-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "target.h"
|
||||
#include "regcache.h"
|
||||
#include "linux-nat.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <alpha/ptrace.h>
|
||||
|
||||
#include <sys/procfs.h>
|
||||
#include "gregset.h"
|
||||
|
||||
/* The address of UNIQUE for ptrace. */
|
||||
#define ALPHA_UNIQUE_PTRACE_ADDR 65
|
||||
|
||||
|
||||
/* See the comment in m68k-tdep.c regarding the utility of these
|
||||
functions. */
|
||||
|
||||
void
|
||||
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
|
||||
{
|
||||
const long *regp = (const long *)gregsetp;
|
||||
|
||||
/* PC is in slot 32, UNIQUE is in slot 33. */
|
||||
alpha_supply_int_regs (regcache, -1, regp, regp + 31, regp + 32);
|
||||
}
|
||||
|
||||
void
|
||||
fill_gregset (const struct regcache *regcache,
|
||||
gdb_gregset_t *gregsetp, int regno)
|
||||
{
|
||||
long *regp = (long *)gregsetp;
|
||||
|
||||
/* PC is in slot 32, UNIQUE is in slot 33. */
|
||||
alpha_fill_int_regs (regcache, regno, regp, regp + 31, regp + 32);
|
||||
}
|
||||
|
||||
/* Now we do the same thing for floating-point registers.
|
||||
Again, see the comments in m68k-tdep.c. */
|
||||
|
||||
void
|
||||
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
|
||||
{
|
||||
const long *regp = (const long *)fpregsetp;
|
||||
|
||||
/* FPCR is in slot 32. */
|
||||
alpha_supply_fp_regs (regcache, -1, regp, regp + 31);
|
||||
}
|
||||
|
||||
void
|
||||
fill_fpregset (const struct regcache *regcache,
|
||||
gdb_fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
long *regp = (long *)fpregsetp;
|
||||
|
||||
/* FPCR is in slot 32. */
|
||||
alpha_fill_fp_regs (regcache, regno, regp, regp + 31);
|
||||
}
|
||||
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
|
||||
{
|
||||
if (regno == gdbarch_pc_regnum (gdbarch))
|
||||
return PC;
|
||||
if (regno == ALPHA_UNIQUE_REGNUM)
|
||||
return ALPHA_UNIQUE_PTRACE_ADDR;
|
||||
if (regno < gdbarch_fp0_regnum (gdbarch))
|
||||
return GPR_BASE + regno;
|
||||
else
|
||||
return FPR_BASE + regno - gdbarch_fp0_regnum (gdbarch);
|
||||
}
|
||||
|
||||
void _initialialize_alpha_linux_nat (void);
|
||||
|
||||
void
|
||||
_initialize_alpha_linux_nat (void)
|
||||
{
|
||||
linux_nat_add_target (linux_trad_target (alpha_linux_register_u_offset));
|
||||
}
|
||||
@@ -1,391 +0,0 @@
|
||||
/* Target-dependent code for GNU/Linux on Alpha.
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
#include "osabi.h"
|
||||
#include "solib-svr4.h"
|
||||
#include "symtab.h"
|
||||
#include "regset.h"
|
||||
#include "regcache.h"
|
||||
#include "linux-tdep.h"
|
||||
#include "alpha-tdep.h"
|
||||
|
||||
/* This enum represents the signals' numbers on the Alpha
|
||||
architecture. It just contains the signal definitions which are
|
||||
different from the generic implementation.
|
||||
|
||||
It is derived from the file <arch/alpha/include/uapi/asm/signal.h>,
|
||||
from the Linux kernel tree. */
|
||||
|
||||
enum
|
||||
{
|
||||
/* SIGABRT is the same as in the generic implementation, but is
|
||||
defined here because SIGIOT depends on it. */
|
||||
ALPHA_LINUX_SIGABRT = 6,
|
||||
ALPHA_LINUX_SIGEMT = 7,
|
||||
ALPHA_LINUX_SIGBUS = 10,
|
||||
ALPHA_LINUX_SIGSYS = 12,
|
||||
ALPHA_LINUX_SIGURG = 16,
|
||||
ALPHA_LINUX_SIGSTOP = 17,
|
||||
ALPHA_LINUX_SIGTSTP = 18,
|
||||
ALPHA_LINUX_SIGCONT = 19,
|
||||
ALPHA_LINUX_SIGCHLD = 20,
|
||||
ALPHA_LINUX_SIGIO = 23,
|
||||
ALPHA_LINUX_SIGINFO = 29,
|
||||
ALPHA_LINUX_SIGUSR1 = 30,
|
||||
ALPHA_LINUX_SIGUSR2 = 31,
|
||||
ALPHA_LINUX_SIGPOLL = ALPHA_LINUX_SIGIO,
|
||||
ALPHA_LINUX_SIGPWR = ALPHA_LINUX_SIGINFO,
|
||||
ALPHA_LINUX_SIGIOT = ALPHA_LINUX_SIGABRT,
|
||||
};
|
||||
|
||||
/* Under GNU/Linux, signal handler invocations can be identified by
|
||||
the designated code sequence that is used to return from a signal
|
||||
handler. In particular, the return address of a signal handler
|
||||
points to a sequence that copies $sp to $16, loads $0 with the
|
||||
appropriate syscall number, and finally enters the kernel.
|
||||
|
||||
This is somewhat complicated in that:
|
||||
(1) the expansion of the "mov" assembler macro has changed over
|
||||
time, from "bis src,src,dst" to "bis zero,src,dst",
|
||||
(2) the kernel has changed from using "addq" to "lda" to load the
|
||||
syscall number,
|
||||
(3) there is a "normal" sigreturn and an "rt" sigreturn which
|
||||
has a different stack layout. */
|
||||
|
||||
static long
|
||||
alpha_linux_sigtramp_offset_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
switch (alpha_read_insn (gdbarch, pc))
|
||||
{
|
||||
case 0x47de0410: /* bis $30,$30,$16 */
|
||||
case 0x47fe0410: /* bis $31,$30,$16 */
|
||||
return 0;
|
||||
|
||||
case 0x43ecf400: /* addq $31,103,$0 */
|
||||
case 0x201f0067: /* lda $0,103($31) */
|
||||
case 0x201f015f: /* lda $0,351($31) */
|
||||
return 4;
|
||||
|
||||
case 0x00000083: /* call_pal callsys */
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static LONGEST
|
||||
alpha_linux_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
long i, off;
|
||||
|
||||
if (pc & 3)
|
||||
return -1;
|
||||
|
||||
/* Guess where we might be in the sequence. */
|
||||
off = alpha_linux_sigtramp_offset_1 (gdbarch, pc);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
|
||||
/* Verify that the other two insns of the sequence are as we expect. */
|
||||
pc -= off;
|
||||
for (i = 0; i < 12; i += 4)
|
||||
{
|
||||
if (i == off)
|
||||
continue;
|
||||
if (alpha_linux_sigtramp_offset_1 (gdbarch, pc + i) != i)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
static int
|
||||
alpha_linux_pc_in_sigtramp (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *func_name)
|
||||
{
|
||||
return alpha_linux_sigtramp_offset (gdbarch, pc) >= 0;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_linux_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
CORE_ADDR pc;
|
||||
ULONGEST sp;
|
||||
long off;
|
||||
|
||||
pc = get_frame_pc (this_frame);
|
||||
sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
|
||||
|
||||
off = alpha_linux_sigtramp_offset (gdbarch, pc);
|
||||
gdb_assert (off >= 0);
|
||||
|
||||
/* __NR_rt_sigreturn has a couple of structures on the stack. This is:
|
||||
|
||||
struct rt_sigframe {
|
||||
struct siginfo info;
|
||||
struct ucontext uc;
|
||||
};
|
||||
|
||||
offsetof (struct rt_sigframe, uc.uc_mcontext); */
|
||||
|
||||
if (alpha_read_insn (gdbarch, pc - off + 4) == 0x201f015f)
|
||||
return sp + 176;
|
||||
|
||||
/* __NR_sigreturn has the sigcontext structure at the top of the stack. */
|
||||
return sp;
|
||||
}
|
||||
|
||||
/* Supply register REGNUM from the buffer specified by GREGS and LEN
|
||||
in the general-purpose register set REGSET to register cache
|
||||
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
|
||||
|
||||
static void
|
||||
alpha_linux_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs, size_t len)
|
||||
{
|
||||
const gdb_byte *regs = gregs;
|
||||
int i;
|
||||
gdb_assert (len >= 32 * 8);
|
||||
|
||||
for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + i * 8);
|
||||
}
|
||||
|
||||
if (regnum == ALPHA_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
|
||||
|
||||
if (regnum == ALPHA_UNIQUE_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_UNIQUE_REGNUM,
|
||||
len >= 33 * 8 ? regs + 32 * 8 : NULL);
|
||||
}
|
||||
|
||||
/* Supply register REGNUM from the buffer specified by FPREGS and LEN
|
||||
in the floating-point register set REGSET to register cache
|
||||
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
|
||||
|
||||
static void
|
||||
alpha_linux_supply_fpregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *fpregs, size_t len)
|
||||
{
|
||||
const gdb_byte *regs = fpregs;
|
||||
int i;
|
||||
gdb_assert (len >= 32 * 8);
|
||||
|
||||
for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8);
|
||||
}
|
||||
|
||||
if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 31 * 8);
|
||||
}
|
||||
|
||||
static struct regset alpha_linux_gregset =
|
||||
{
|
||||
NULL,
|
||||
alpha_linux_supply_gregset
|
||||
};
|
||||
|
||||
static struct regset alpha_linux_fpregset =
|
||||
{
|
||||
NULL,
|
||||
alpha_linux_supply_fpregset
|
||||
};
|
||||
|
||||
/* Return the appropriate register set for the core section identified
|
||||
by SECT_NAME and SECT_SIZE. */
|
||||
|
||||
static const struct regset *
|
||||
alpha_linux_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t sect_size)
|
||||
{
|
||||
if (strcmp (sect_name, ".reg") == 0 && sect_size >= 32 * 8)
|
||||
return &alpha_linux_gregset;
|
||||
|
||||
if (strcmp (sect_name, ".reg2") == 0 && sect_size >= 32 * 8)
|
||||
return &alpha_linux_fpregset;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Implementation of `gdbarch_gdb_signal_from_target', as defined in
|
||||
gdbarch.h. */
|
||||
|
||||
static enum gdb_signal
|
||||
alpha_linux_gdb_signal_from_target (struct gdbarch *gdbarch,
|
||||
int signal)
|
||||
{
|
||||
switch (signal)
|
||||
{
|
||||
case ALPHA_LINUX_SIGEMT:
|
||||
return GDB_SIGNAL_EMT;
|
||||
|
||||
case ALPHA_LINUX_SIGBUS:
|
||||
return GDB_SIGNAL_BUS;
|
||||
|
||||
case ALPHA_LINUX_SIGSYS:
|
||||
return GDB_SIGNAL_SYS;
|
||||
|
||||
case ALPHA_LINUX_SIGURG:
|
||||
return GDB_SIGNAL_URG;
|
||||
|
||||
case ALPHA_LINUX_SIGSTOP:
|
||||
return GDB_SIGNAL_STOP;
|
||||
|
||||
case ALPHA_LINUX_SIGTSTP:
|
||||
return GDB_SIGNAL_TSTP;
|
||||
|
||||
case ALPHA_LINUX_SIGCONT:
|
||||
return GDB_SIGNAL_CONT;
|
||||
|
||||
case ALPHA_LINUX_SIGCHLD:
|
||||
return GDB_SIGNAL_CHLD;
|
||||
|
||||
/* No way to differentiate between SIGIO and SIGPOLL.
|
||||
Therefore, we just handle the first one. */
|
||||
case ALPHA_LINUX_SIGIO:
|
||||
return GDB_SIGNAL_IO;
|
||||
|
||||
/* No way to differentiate between SIGINFO and SIGPWR.
|
||||
Therefore, we just handle the first one. */
|
||||
case ALPHA_LINUX_SIGINFO:
|
||||
return GDB_SIGNAL_INFO;
|
||||
|
||||
case ALPHA_LINUX_SIGUSR1:
|
||||
return GDB_SIGNAL_USR1;
|
||||
|
||||
case ALPHA_LINUX_SIGUSR2:
|
||||
return GDB_SIGNAL_USR2;
|
||||
}
|
||||
|
||||
return linux_gdb_signal_from_target (gdbarch, signal);
|
||||
}
|
||||
|
||||
/* Implementation of `gdbarch_gdb_signal_to_target', as defined in
|
||||
gdbarch.h. */
|
||||
|
||||
static int
|
||||
alpha_linux_gdb_signal_to_target (struct gdbarch *gdbarch,
|
||||
enum gdb_signal signal)
|
||||
{
|
||||
switch (signal)
|
||||
{
|
||||
case GDB_SIGNAL_EMT:
|
||||
return ALPHA_LINUX_SIGEMT;
|
||||
|
||||
case GDB_SIGNAL_BUS:
|
||||
return ALPHA_LINUX_SIGBUS;
|
||||
|
||||
case GDB_SIGNAL_SYS:
|
||||
return ALPHA_LINUX_SIGSYS;
|
||||
|
||||
case GDB_SIGNAL_URG:
|
||||
return ALPHA_LINUX_SIGURG;
|
||||
|
||||
case GDB_SIGNAL_STOP:
|
||||
return ALPHA_LINUX_SIGSTOP;
|
||||
|
||||
case GDB_SIGNAL_TSTP:
|
||||
return ALPHA_LINUX_SIGTSTP;
|
||||
|
||||
case GDB_SIGNAL_CONT:
|
||||
return ALPHA_LINUX_SIGCONT;
|
||||
|
||||
case GDB_SIGNAL_CHLD:
|
||||
return ALPHA_LINUX_SIGCHLD;
|
||||
|
||||
case GDB_SIGNAL_IO:
|
||||
return ALPHA_LINUX_SIGIO;
|
||||
|
||||
case GDB_SIGNAL_INFO:
|
||||
return ALPHA_LINUX_SIGINFO;
|
||||
|
||||
case GDB_SIGNAL_USR1:
|
||||
return ALPHA_LINUX_SIGUSR1;
|
||||
|
||||
case GDB_SIGNAL_USR2:
|
||||
return ALPHA_LINUX_SIGUSR2;
|
||||
|
||||
case GDB_SIGNAL_POLL:
|
||||
return ALPHA_LINUX_SIGPOLL;
|
||||
|
||||
case GDB_SIGNAL_PWR:
|
||||
return ALPHA_LINUX_SIGPWR;
|
||||
}
|
||||
|
||||
return linux_gdb_signal_to_target (gdbarch, signal);
|
||||
}
|
||||
|
||||
static void
|
||||
alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep;
|
||||
|
||||
linux_init_abi (info, gdbarch);
|
||||
|
||||
/* Hook into the DWARF CFI frame unwinder. */
|
||||
alpha_dwarf2_init_abi (info, gdbarch);
|
||||
|
||||
/* Hook into the MDEBUG frame unwinder. */
|
||||
alpha_mdebug_init_abi (info, gdbarch);
|
||||
|
||||
tdep = gdbarch_tdep (gdbarch);
|
||||
tdep->dynamic_sigtramp_offset = alpha_linux_sigtramp_offset;
|
||||
tdep->sigcontext_addr = alpha_linux_sigcontext_addr;
|
||||
tdep->pc_in_sigtramp = alpha_linux_pc_in_sigtramp;
|
||||
tdep->jb_pc = 2;
|
||||
tdep->jb_elt_size = 8;
|
||||
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
|
||||
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
/* Enable TLS support. */
|
||||
set_gdbarch_fetch_tls_load_module_address (gdbarch,
|
||||
svr4_fetch_objfile_link_map);
|
||||
|
||||
set_gdbarch_regset_from_core_section
|
||||
(gdbarch, alpha_linux_regset_from_core_section);
|
||||
|
||||
set_gdbarch_gdb_signal_from_target (gdbarch,
|
||||
alpha_linux_gdb_signal_from_target);
|
||||
set_gdbarch_gdb_signal_to_target (gdbarch,
|
||||
alpha_linux_gdb_signal_to_target);
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_alpha_linux_tdep;
|
||||
|
||||
void
|
||||
_initialize_alpha_linux_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_LINUX,
|
||||
alpha_linux_init_abi);
|
||||
}
|
||||
@@ -1,410 +0,0 @@
|
||||
/* Target-dependent mdebug code for the ALPHA architecture.
|
||||
Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "frame-unwind.h"
|
||||
#include "frame-base.h"
|
||||
#include "symtab.h"
|
||||
#include "gdbcore.h"
|
||||
#include "block.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
#include "trad-frame.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
#include "mdebugread.h"
|
||||
|
||||
/* FIXME: Some of this code should perhaps be merged with mips. */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* Layout of a stack frame on the alpha:
|
||||
|
||||
| |
|
||||
pdr members: | 7th ... nth arg, |
|
||||
| `pushed' by caller. |
|
||||
| |
|
||||
----------------|-------------------------------|<-- old_sp == vfp
|
||||
^ ^ ^ ^ | |
|
||||
| | | | | |
|
||||
| |localoff | Copies of 1st .. 6th |
|
||||
| | | | | argument if necessary. |
|
||||
| | | v | |
|
||||
| | | --- |-------------------------------|<-- LOCALS_ADDRESS
|
||||
| | | | |
|
||||
| | | | Locals and temporaries. |
|
||||
| | | | |
|
||||
| | | |-------------------------------|
|
||||
| | | | |
|
||||
|-fregoffset | Saved float registers. |
|
||||
| | | | F9 |
|
||||
| | | | . |
|
||||
| | | | . |
|
||||
| | | | F2 |
|
||||
| | v | |
|
||||
| | -------|-------------------------------|
|
||||
| | | |
|
||||
| | | Saved registers. |
|
||||
| | | S6 |
|
||||
|-regoffset | . |
|
||||
| | | . |
|
||||
| | | S0 |
|
||||
| | | pdr.pcreg |
|
||||
| v | |
|
||||
| ----------|-------------------------------|
|
||||
| | |
|
||||
frameoffset | Argument build area, gets |
|
||||
| | 7th ... nth arg for any |
|
||||
| | called procedure. |
|
||||
v | |
|
||||
-------------|-------------------------------|<-- sp
|
||||
| |
|
||||
*/
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)
|
||||
#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
|
||||
#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
|
||||
#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
|
||||
#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
|
||||
#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
|
||||
#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
|
||||
#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
|
||||
#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
|
||||
|
||||
/* Locate the mdebug PDR for the given PC. Return null if one can't
|
||||
be found; you'll have to fall back to other methods in that case. */
|
||||
|
||||
static struct mdebug_extra_func_info *
|
||||
find_proc_desc (CORE_ADDR pc)
|
||||
{
|
||||
struct block *b = block_for_pc (pc);
|
||||
struct mdebug_extra_func_info *proc_desc = NULL;
|
||||
struct symbol *sym = NULL;
|
||||
const char *sh_name = NULL;
|
||||
|
||||
if (b)
|
||||
{
|
||||
CORE_ADDR startaddr;
|
||||
find_pc_partial_function (pc, &sh_name, &startaddr, NULL);
|
||||
|
||||
if (startaddr > BLOCK_START (b))
|
||||
/* This is the "pathological" case referred to in a comment in
|
||||
print_frame_info. It might be better to move this check into
|
||||
symbol reading. */
|
||||
sym = NULL;
|
||||
else
|
||||
sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0);
|
||||
}
|
||||
|
||||
if (sym)
|
||||
{
|
||||
proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym);
|
||||
|
||||
/* Correct incorrect setjmp procedure descriptor from the library
|
||||
to make backtrace through setjmp work. */
|
||||
if (proc_desc->pdr.pcreg == 0
|
||||
&& strcmp (sh_name, "setjmp") == 0)
|
||||
{
|
||||
proc_desc->pdr.pcreg = ALPHA_RA_REGNUM;
|
||||
proc_desc->pdr.regmask = 0x80000000;
|
||||
proc_desc->pdr.regoffset = -4;
|
||||
}
|
||||
|
||||
/* If we never found a PDR for this function in symbol reading,
|
||||
then examine prologues to find the information. */
|
||||
if (proc_desc->pdr.framereg == -1)
|
||||
proc_desc = NULL;
|
||||
}
|
||||
|
||||
return proc_desc;
|
||||
}
|
||||
|
||||
/* Return a non-zero result if the function is frameless; zero otherwise. */
|
||||
|
||||
static int
|
||||
alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc)
|
||||
{
|
||||
return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
|
||||
&& PROC_FRAME_OFFSET (proc_desc) == 0);
|
||||
}
|
||||
|
||||
/* This returns the PC of the first inst after the prologue. If we can't
|
||||
find the prologue, then return 0. */
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_mdebug_after_prologue (CORE_ADDR pc,
|
||||
struct mdebug_extra_func_info *proc_desc)
|
||||
{
|
||||
if (proc_desc)
|
||||
{
|
||||
/* If function is frameless, then we need to do it the hard way. I
|
||||
strongly suspect that frameless always means prologueless... */
|
||||
if (alpha_mdebug_frameless (proc_desc))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return alpha_after_prologue (pc);
|
||||
}
|
||||
|
||||
/* Return non-zero if we *might* be in a function prologue. Return zero
|
||||
if we are definitively *not* in a function prologue. */
|
||||
|
||||
static int
|
||||
alpha_mdebug_in_prologue (CORE_ADDR pc,
|
||||
struct mdebug_extra_func_info *proc_desc)
|
||||
{
|
||||
CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
|
||||
return (after_prologue_pc == 0 || pc < after_prologue_pc);
|
||||
}
|
||||
|
||||
|
||||
/* Frame unwinder that reads mdebug PDRs. */
|
||||
|
||||
struct alpha_mdebug_unwind_cache
|
||||
{
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
CORE_ADDR vfp;
|
||||
struct trad_frame_saved_reg *saved_regs;
|
||||
};
|
||||
|
||||
/* Extract all of the information about the frame from PROC_DESC
|
||||
and store the resulting register save locations in the structure. */
|
||||
|
||||
static struct alpha_mdebug_unwind_cache *
|
||||
alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info;
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
ULONGEST vfp;
|
||||
CORE_ADDR pc, reg_position;
|
||||
unsigned long mask;
|
||||
int ireg, returnreg;
|
||||
|
||||
if (*this_prologue_cache)
|
||||
return *this_prologue_cache;
|
||||
|
||||
info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
|
||||
*this_prologue_cache = info;
|
||||
pc = get_frame_address_in_block (this_frame);
|
||||
|
||||
/* ??? We don't seem to be able to cache the lookup of the PDR
|
||||
from alpha_mdebug_frame_p. It'd be nice if we could change
|
||||
the arguments to that function. Oh well. */
|
||||
proc_desc = find_proc_desc (pc);
|
||||
info->proc_desc = proc_desc;
|
||||
gdb_assert (proc_desc != NULL);
|
||||
|
||||
info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
|
||||
|
||||
/* The VFP of the frame is at FRAME_REG+FRAME_OFFSET. */
|
||||
vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc));
|
||||
vfp += PROC_FRAME_OFFSET (info->proc_desc);
|
||||
info->vfp = vfp;
|
||||
|
||||
/* Fill in the offsets for the registers which gen_mask says were saved. */
|
||||
|
||||
reg_position = vfp + PROC_REG_OFFSET (proc_desc);
|
||||
mask = PROC_REG_MASK (proc_desc);
|
||||
returnreg = PROC_PC_REG (proc_desc);
|
||||
|
||||
/* Note that RA is always saved first, regardless of its actual
|
||||
register number. */
|
||||
if (mask & (1 << returnreg))
|
||||
{
|
||||
/* Clear bit for RA so we don't save it again later. */
|
||||
mask &= ~(1 << returnreg);
|
||||
|
||||
info->saved_regs[returnreg].addr = reg_position;
|
||||
reg_position += 8;
|
||||
}
|
||||
|
||||
for (ireg = 0; ireg <= 31; ++ireg)
|
||||
if (mask & (1 << ireg))
|
||||
{
|
||||
info->saved_regs[ireg].addr = reg_position;
|
||||
reg_position += 8;
|
||||
}
|
||||
|
||||
reg_position = vfp + PROC_FREG_OFFSET (proc_desc);
|
||||
mask = PROC_FREG_MASK (proc_desc);
|
||||
|
||||
for (ireg = 0; ireg <= 31; ++ireg)
|
||||
if (mask & (1 << ireg))
|
||||
{
|
||||
info->saved_regs[ALPHA_FP0_REGNUM + ireg].addr = reg_position;
|
||||
reg_position += 8;
|
||||
}
|
||||
|
||||
/* The stack pointer of the previous frame is computed by popping
|
||||
the current stack frame. */
|
||||
if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
|
||||
trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, vfp);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/* Given a GDB frame, determine the address of the calling function's
|
||||
frame. This will be used to create a new GDB frame struct. */
|
||||
|
||||
static void
|
||||
alpha_mdebug_frame_this_id (struct frame_info *this_frame,
|
||||
void **this_prologue_cache,
|
||||
struct frame_id *this_id)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info
|
||||
= alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
|
||||
|
||||
*this_id = frame_id_build (info->vfp, get_frame_func (this_frame));
|
||||
}
|
||||
|
||||
/* Retrieve the value of REGNUM in FRAME. Don't give up! */
|
||||
|
||||
static struct value *
|
||||
alpha_mdebug_frame_prev_register (struct frame_info *this_frame,
|
||||
void **this_prologue_cache, int regnum)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info
|
||||
= alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
|
||||
|
||||
/* The PC of the previous frame is stored in the link register of
|
||||
the current frame. Frob regnum so that we pull the value from
|
||||
the correct place. */
|
||||
if (regnum == ALPHA_PC_REGNUM)
|
||||
regnum = PROC_PC_REG (info->proc_desc);
|
||||
|
||||
return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
|
||||
}
|
||||
|
||||
/* Return a non-zero result if the size of the stack frame exceeds the
|
||||
maximum debuggable frame size (512 Kbytes); zero otherwise. */
|
||||
|
||||
static int
|
||||
alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
|
||||
{
|
||||
/* If frame offset is null, we can be in two cases: either the
|
||||
function is frameless (the stack frame is null) or its
|
||||
frame exceeds the maximum debuggable frame size (512 Kbytes). */
|
||||
|
||||
return (PROC_FRAME_OFFSET (proc_desc) == 0
|
||||
&& !alpha_mdebug_frameless (proc_desc));
|
||||
}
|
||||
|
||||
static int
|
||||
alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
|
||||
struct frame_info *this_frame,
|
||||
void **this_cache)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_address_in_block (this_frame);
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
|
||||
/* If this PC does not map to a PDR, then clearly this isn't an
|
||||
mdebug frame. */
|
||||
proc_desc = find_proc_desc (pc);
|
||||
if (proc_desc == NULL)
|
||||
return 0;
|
||||
|
||||
/* If we're in the prologue, the PDR for this frame is not yet valid.
|
||||
Say no here and we'll fall back on the heuristic unwinder. */
|
||||
if (alpha_mdebug_in_prologue (pc, proc_desc))
|
||||
return 0;
|
||||
|
||||
/* If the maximum debuggable frame size has been exceeded, the
|
||||
proc desc is bogus. Fall back on the heuristic unwinder. */
|
||||
if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct frame_unwind alpha_mdebug_frame_unwind = {
|
||||
NORMAL_FRAME,
|
||||
default_frame_unwind_stop_reason,
|
||||
alpha_mdebug_frame_this_id,
|
||||
alpha_mdebug_frame_prev_register,
|
||||
NULL,
|
||||
alpha_mdebug_frame_sniffer
|
||||
};
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_mdebug_frame_base_address (struct frame_info *this_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info
|
||||
= alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
|
||||
|
||||
return info->vfp;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info
|
||||
= alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
|
||||
|
||||
return info->vfp - PROC_LOCALOFF (info->proc_desc);
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_mdebug_frame_args_address (struct frame_info *this_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
struct alpha_mdebug_unwind_cache *info
|
||||
= alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
|
||||
|
||||
return info->vfp - ALPHA_NUM_ARG_REGS * 8;
|
||||
}
|
||||
|
||||
static const struct frame_base alpha_mdebug_frame_base = {
|
||||
&alpha_mdebug_frame_unwind,
|
||||
alpha_mdebug_frame_base_address,
|
||||
alpha_mdebug_frame_locals_address,
|
||||
alpha_mdebug_frame_args_address
|
||||
};
|
||||
|
||||
static const struct frame_base *
|
||||
alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_address_in_block (this_frame);
|
||||
struct mdebug_extra_func_info *proc_desc;
|
||||
|
||||
/* If this PC does not map to a PDR, then clearly this isn't an
|
||||
mdebug frame. */
|
||||
proc_desc = find_proc_desc (pc);
|
||||
if (proc_desc == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If the maximum debuggable frame size has been exceeded, the
|
||||
proc desc is bogus. Fall back on the heuristic unwinder. */
|
||||
if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
|
||||
return 0;
|
||||
|
||||
return &alpha_mdebug_frame_base;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind);
|
||||
frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
|
||||
}
|
||||
211
gdb/alpha-nat.c
211
gdb/alpha-nat.c
@@ -1,211 +0,0 @@
|
||||
/* Low level Alpha interface, for GDB when running native.
|
||||
Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_string.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "procfs.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <alpha/coreregs.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
|
||||
/* Extract the register values out of the core file and store
|
||||
them into REGCACHE.
|
||||
|
||||
CORE_REG_SECT points to the register values themselves, read into memory.
|
||||
CORE_REG_SIZE is the size of that area.
|
||||
WHICH says which set of registers we are handling (0 = int, 2 = float
|
||||
on machines where they are discontiguous).
|
||||
REG_ADDR is the offset from u.u_ar0 to the register values relative to
|
||||
core_reg_sect. This is used with old-fashioned core files to
|
||||
locate the registers in a large upage-plus-stack ".reg" section.
|
||||
Original upage address X is at location core_reg_sect+x+reg_addr. */
|
||||
|
||||
static void
|
||||
fetch_osf_core_registers (struct regcache *regcache,
|
||||
char *core_reg_sect, unsigned core_reg_size,
|
||||
int which, CORE_ADDR reg_addr)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
int regno;
|
||||
int addr;
|
||||
int bad_reg = -1;
|
||||
|
||||
/* Table to map a gdb regnum to an index in the core register
|
||||
section. The floating point register values are garbage in
|
||||
OSF/1.2 core files. OSF5 uses different names for the register
|
||||
enum list, need to handle two cases. The actual values are the
|
||||
same. */
|
||||
static int const core_reg_mapping[ALPHA_NUM_REGS] =
|
||||
{
|
||||
#ifdef NCF_REGS
|
||||
#define EFL NCF_REGS
|
||||
CF_V0, CF_T0, CF_T1, CF_T2, CF_T3, CF_T4, CF_T5, CF_T6,
|
||||
CF_T7, CF_S0, CF_S1, CF_S2, CF_S3, CF_S4, CF_S5, CF_S6,
|
||||
CF_A0, CF_A1, CF_A2, CF_A3, CF_A4, CF_A5, CF_T8, CF_T9,
|
||||
CF_T10, CF_T11, CF_RA, CF_T12, CF_AT, CF_GP, CF_SP, -1,
|
||||
EFL + 0, EFL + 1, EFL + 2, EFL + 3,
|
||||
EFL + 4, EFL + 5, EFL + 6, EFL + 7,
|
||||
EFL + 8, EFL + 9, EFL + 10, EFL + 11,
|
||||
EFL + 12, EFL + 13, EFL + 14, EFL + 15,
|
||||
EFL + 16, EFL + 17, EFL + 18, EFL + 19,
|
||||
EFL + 20, EFL + 21, EFL + 22, EFL + 23,
|
||||
EFL + 24, EFL + 25, EFL + 26, EFL + 27,
|
||||
EFL + 28, EFL + 29, EFL + 30, EFL + 31,
|
||||
CF_PC, -1, -1
|
||||
#else
|
||||
#define EFL (EF_SIZE / 8)
|
||||
EF_V0, EF_T0, EF_T1, EF_T2, EF_T3, EF_T4, EF_T5, EF_T6,
|
||||
EF_T7, EF_S0, EF_S1, EF_S2, EF_S3, EF_S4, EF_S5, EF_S6,
|
||||
EF_A0, EF_A1, EF_A2, EF_A3, EF_A4, EF_A5, EF_T8, EF_T9,
|
||||
EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1,
|
||||
EFL + 0, EFL + 1, EFL + 2, EFL + 3,
|
||||
EFL + 4, EFL + 5, EFL + 6, EFL + 7,
|
||||
EFL + 8, EFL + 9, EFL + 10, EFL + 11,
|
||||
EFL + 12, EFL + 13, EFL + 14, EFL + 15,
|
||||
EFL + 16, EFL + 17, EFL + 18, EFL + 19,
|
||||
EFL + 20, EFL + 21, EFL + 22, EFL + 23,
|
||||
EFL + 24, EFL + 25, EFL + 26, EFL + 27,
|
||||
EFL + 28, EFL + 29, EFL + 30, EFL + 31,
|
||||
EF_PC, -1, -1
|
||||
#endif
|
||||
};
|
||||
|
||||
for (regno = 0; regno < ALPHA_NUM_REGS; regno++)
|
||||
{
|
||||
if (gdbarch_cannot_fetch_register (gdbarch, regno))
|
||||
{
|
||||
regcache_raw_supply (regcache, regno, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (regno == ALPHA_ZERO_REGNUM)
|
||||
{
|
||||
const gdb_byte zero[8] = { 0 };
|
||||
|
||||
regcache_raw_supply (regcache, regno, zero);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = 8 * core_reg_mapping[regno];
|
||||
if (addr < 0 || addr >= core_reg_size)
|
||||
{
|
||||
/* ??? UNIQUE is a new addition. Don't generate an error. */
|
||||
if (regno == ALPHA_UNIQUE_REGNUM)
|
||||
{
|
||||
regcache_raw_supply (regcache, regno, NULL);
|
||||
continue;
|
||||
}
|
||||
if (bad_reg < 0)
|
||||
bad_reg = regno;
|
||||
}
|
||||
else
|
||||
{
|
||||
regcache_raw_supply (regcache, regno, core_reg_sect + addr);
|
||||
}
|
||||
}
|
||||
if (bad_reg >= 0)
|
||||
{
|
||||
error (_("Register %s not found in core file."),
|
||||
gdbarch_register_name (gdbarch, bad_reg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <sys/procfs.h>
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
#include "gregset.h"
|
||||
|
||||
/* See the comment in m68k-tdep.c regarding the utility of these
|
||||
functions. */
|
||||
|
||||
void
|
||||
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
|
||||
{
|
||||
const long *regp = gregsetp->regs;
|
||||
|
||||
/* PC is in slot 32. */
|
||||
alpha_supply_int_regs (regcache, -1, regp, regp + 31, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
fill_gregset (const struct regcache *regcache,
|
||||
gdb_gregset_t *gregsetp, int regno)
|
||||
{
|
||||
long *regp = gregsetp->regs;
|
||||
|
||||
/* PC is in slot 32. */
|
||||
alpha_fill_int_regs (regcache, regno, regp, regp + 31, NULL);
|
||||
}
|
||||
|
||||
/* Now we do the same thing for floating-point registers.
|
||||
Again, see the comments in m68k-tdep.c. */
|
||||
|
||||
void
|
||||
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
|
||||
{
|
||||
const long *regp = fpregsetp->regs;
|
||||
|
||||
/* FPCR is in slot 32. */
|
||||
alpha_supply_fp_regs (regcache, -1, regp, regp + 31);
|
||||
}
|
||||
|
||||
void
|
||||
fill_fpregset (const struct regcache *regcache,
|
||||
gdb_fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
long *regp = fpregsetp->regs;
|
||||
|
||||
/* FPCR is in slot 32. */
|
||||
alpha_fill_fp_regs (regcache, regno, regp, regp + 31);
|
||||
}
|
||||
|
||||
|
||||
/* Register that we are able to handle alpha core file formats. */
|
||||
|
||||
static struct core_fns alpha_osf_core_fns =
|
||||
{
|
||||
/* This really is bfd_target_unknown_flavour. */
|
||||
|
||||
bfd_target_unknown_flavour, /* core_flavour */
|
||||
default_check_format, /* check_format */
|
||||
default_core_sniffer, /* core_sniffer */
|
||||
fetch_osf_core_registers, /* core_read_registers */
|
||||
NULL /* next */
|
||||
};
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_alpha_nat;
|
||||
|
||||
void
|
||||
_initialize_alpha_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = procfs_target ();
|
||||
add_target (t);
|
||||
|
||||
deprecated_add_core_fns (&alpha_osf_core_fns);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/* Target-dependent code for OSF/1 on Alpha.
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "value.h"
|
||||
#include "osabi.h"
|
||||
#include "gdb_string.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
|
||||
static int
|
||||
alpha_osf1_pc_in_sigtramp (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *func_name)
|
||||
{
|
||||
return (func_name != NULL && strcmp ("__sigtramp", func_name) == 0);
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alpha_osf1_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
struct frame_info *next_frame = get_next_frame (this_frame);
|
||||
struct frame_id next_id = null_frame_id;
|
||||
|
||||
if (next_frame != NULL)
|
||||
next_id = get_frame_id (next_frame);
|
||||
|
||||
return (read_memory_integer (next_id.stack_addr, 8, byte_order));
|
||||
}
|
||||
|
||||
static void
|
||||
alpha_osf1_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Hook into the MDEBUG frame unwinder. */
|
||||
alpha_mdebug_init_abi (info, gdbarch);
|
||||
|
||||
/* The next/step support via procfs on OSF1 is broken when running
|
||||
on multi-processor machines. We need to use software single
|
||||
stepping instead. */
|
||||
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
|
||||
|
||||
tdep->sigcontext_addr = alpha_osf1_sigcontext_addr;
|
||||
tdep->pc_in_sigtramp = alpha_osf1_pc_in_sigtramp;
|
||||
|
||||
tdep->jb_pc = 2;
|
||||
tdep->jb_elt_size = 8;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_alpha_osf1_tdep;
|
||||
|
||||
void
|
||||
_initialize_alpha_osf1_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OSF1,
|
||||
alpha_osf1_init_abi);
|
||||
}
|
||||
1891
gdb/alpha-tdep.c
1891
gdb/alpha-tdep.c
File diff suppressed because it is too large
Load Diff
121
gdb/alpha-tdep.h
121
gdb/alpha-tdep.h
@@ -1,121 +0,0 @@
|
||||
/* Common target dependent code for GDB on Alpha systems.
|
||||
Copyright (C) 1993-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ALPHA_TDEP_H
|
||||
#define ALPHA_TDEP_H
|
||||
|
||||
struct regcache;
|
||||
|
||||
/* Say how long (ordinary) registers are. This is a piece of bogosity
|
||||
used in push_word and a few other places; register_size() is the
|
||||
real way to know how big a register is. */
|
||||
#define ALPHA_REGISTER_SIZE 8
|
||||
|
||||
/* Number of machine registers. */
|
||||
#define ALPHA_NUM_REGS 67
|
||||
|
||||
/* Register numbers of various important registers. Note that most of
|
||||
these values are "real" register numbers, and correspond to the
|
||||
general registers of the machine. */
|
||||
|
||||
#define ALPHA_V0_REGNUM 0 /* Function integer return value */
|
||||
#define ALPHA_T7_REGNUM 8 /* Return address register for OSF/1 __add* */
|
||||
#define ALPHA_S0_REGNUM 9 /* First saved register */
|
||||
#define ALPHA_GCC_FP_REGNUM 15 /* Used by gcc as frame register */
|
||||
#define ALPHA_A0_REGNUM 16 /* Loc of first arg during a subr call */
|
||||
#define ALPHA_T9_REGNUM 23 /* Return address register for OSF/1 __div* */
|
||||
#define ALPHA_RA_REGNUM 26 /* Contains return address value */
|
||||
#define ALPHA_T12_REGNUM 27 /* Contains start addr of current proc */
|
||||
#define ALPHA_GP_REGNUM 29 /* Contains the global pointer */
|
||||
#define ALPHA_SP_REGNUM 30 /* Contains address of top of stack */
|
||||
#define ALPHA_ZERO_REGNUM 31 /* Read-only register, always 0 */
|
||||
#define ALPHA_FP0_REGNUM 32 /* Floating point register 0 */
|
||||
#define ALPHA_FPA0_REGNUM 48 /* First float arg during a subr call */
|
||||
#define ALPHA_FPCR_REGNUM 63 /* Floating point control register */
|
||||
#define ALPHA_PC_REGNUM 64 /* Contains program counter */
|
||||
#define ALPHA_UNIQUE_REGNUM 66 /* PAL_rduniq value */
|
||||
|
||||
/* Instruction size. */
|
||||
#define ALPHA_INSN_SIZE 4
|
||||
|
||||
/* The alpha has two different virtual pointers for arguments and locals.
|
||||
|
||||
The virtual argument pointer is pointing to the bottom of the argument
|
||||
transfer area, which is located immediately below the virtual frame
|
||||
pointer. Its size is fixed for the native compiler, it is either zero
|
||||
(for the no arguments case) or large enough to hold all argument registers.
|
||||
gcc uses a variable sized argument transfer area. As it has
|
||||
to stay compatible with the native debugging tools it has to use the same
|
||||
virtual argument pointer and adjust the argument offsets accordingly.
|
||||
|
||||
The virtual local pointer is localoff bytes below the virtual frame
|
||||
pointer, the value of localoff is obtained from the PDR. */
|
||||
#define ALPHA_NUM_ARG_REGS 6
|
||||
|
||||
/* Target-dependent structure in gdbarch. */
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
CORE_ADDR vm_min_address; /* Used by alpha_heuristic_proc_start. */
|
||||
|
||||
/* If PC is inside a dynamically-generated signal trampoline function
|
||||
(i.e. one copied onto the user stack at run-time), return how many
|
||||
bytes PC is beyond the start of that function. Otherwise, return -1. */
|
||||
LONGEST (*dynamic_sigtramp_offset) (struct gdbarch *, CORE_ADDR);
|
||||
|
||||
/* Translate a signal handler stack base address into the address of
|
||||
the sigcontext structure for that signal handler. */
|
||||
CORE_ADDR (*sigcontext_addr) (struct frame_info *);
|
||||
|
||||
/* Does the PC fall in a signal trampoline. */
|
||||
/* NOTE: cagney/2004-04-30: Do not copy/clone this code. Instead
|
||||
look at tramp-frame.h and other simplier per-architecture
|
||||
sigtramp unwinders. */
|
||||
int (*pc_in_sigtramp) (struct gdbarch *gdbarch, CORE_ADDR pc,
|
||||
const char *name);
|
||||
|
||||
/* If TYPE will be returned in memory, return true. */
|
||||
int (*return_in_memory) (struct type *type);
|
||||
|
||||
/* Offset of registers in `struct sigcontext'. */
|
||||
int sc_pc_offset;
|
||||
int sc_regs_offset;
|
||||
int sc_fpregs_offset;
|
||||
|
||||
int jb_pc; /* Offset to PC value in jump buffer.
|
||||
If htis is negative, longjmp support
|
||||
will be disabled. */
|
||||
size_t jb_elt_size; /* And the size of each entry in the buf. */
|
||||
};
|
||||
|
||||
extern unsigned int alpha_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc);
|
||||
extern int alpha_software_single_step (struct frame_info *frame);
|
||||
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
|
||||
|
||||
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);
|
||||
extern void alpha_dwarf2_init_abi (struct gdbarch_info, struct gdbarch *);
|
||||
|
||||
extern void alpha_supply_int_regs (struct regcache *, int, const void *,
|
||||
const void *, const void *);
|
||||
extern void alpha_fill_int_regs (const struct regcache *, int,
|
||||
void *, void *, void *);
|
||||
extern void alpha_supply_fp_regs (struct regcache *, int,
|
||||
const void *, const void *);
|
||||
extern void alpha_fill_fp_regs (const struct regcache *,
|
||||
int, void *, void *);
|
||||
|
||||
#endif /* ALPHA_TDEP_H */
|
||||
@@ -1,206 +0,0 @@
|
||||
/* Native-dependent code for Alpha BSD's.
|
||||
|
||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
#include "alphabsd-tdep.h"
|
||||
#include "inf-ptrace.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#ifdef HAVE_SYS_PROCFS_H
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GREGSET_T
|
||||
typedef struct reg gregset_t;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPREGSET_T
|
||||
typedef struct fpreg fpregset_t;
|
||||
#endif
|
||||
|
||||
#include "gregset.h"
|
||||
|
||||
/* Provide *regset() wrappers around the generic Alpha BSD register
|
||||
supply/fill routines. */
|
||||
|
||||
void
|
||||
supply_gregset (struct regcache *regcache, const gregset_t *gregsetp)
|
||||
{
|
||||
alphabsd_supply_reg (regcache, (const char *) gregsetp, -1);
|
||||
}
|
||||
|
||||
void
|
||||
fill_gregset (const struct regcache *regcache, gregset_t *gregsetp, int regno)
|
||||
{
|
||||
alphabsd_fill_reg (regcache, (char *) gregsetp, regno);
|
||||
}
|
||||
|
||||
void
|
||||
supply_fpregset (struct regcache *regcache, const fpregset_t *fpregsetp)
|
||||
{
|
||||
alphabsd_supply_fpreg (regcache, (const char *) fpregsetp, -1);
|
||||
}
|
||||
|
||||
void
|
||||
fill_fpregset (const struct regcache *regcache,
|
||||
fpregset_t *fpregsetp, int regno)
|
||||
{
|
||||
alphabsd_fill_fpreg (regcache, (char *) fpregsetp, regno);
|
||||
}
|
||||
|
||||
/* Determine if PT_GETREGS fetches this register. */
|
||||
|
||||
static int
|
||||
getregs_supplies (int regno)
|
||||
{
|
||||
return ((regno >= ALPHA_V0_REGNUM && regno <= ALPHA_ZERO_REGNUM)
|
||||
|| regno >= ALPHA_PC_REGNUM);
|
||||
}
|
||||
|
||||
/* Fetch register REGNO from the inferior. If REGNO is -1, do this
|
||||
for all registers (including the floating point registers). */
|
||||
|
||||
static void
|
||||
alphabsd_fetch_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regno)
|
||||
{
|
||||
if (regno == -1 || getregs_supplies (regno))
|
||||
{
|
||||
struct reg gregs;
|
||||
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &gregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get registers"));
|
||||
|
||||
alphabsd_supply_reg (regcache, (char *) &gregs, regno);
|
||||
if (regno != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno == -1
|
||||
|| regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
|
||||
{
|
||||
struct fpreg fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
alphabsd_supply_fpreg (regcache, (char *) &fpregs, regno);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store register REGNO back into the inferior. If REGNO is -1, do
|
||||
this for all registers (including the floating point registers). */
|
||||
|
||||
static void
|
||||
alphabsd_store_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regno)
|
||||
{
|
||||
if (regno == -1 || getregs_supplies (regno))
|
||||
{
|
||||
struct reg gregs;
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &gregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get registers"));
|
||||
|
||||
alphabsd_fill_reg (regcache, (char *) &gregs, regno);
|
||||
|
||||
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &gregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write registers"));
|
||||
|
||||
if (regno != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regno == -1
|
||||
|| regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
|
||||
{
|
||||
struct fpreg fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);
|
||||
|
||||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write floating point status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Support for debugging kernel virtual memory images. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/signal.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
#include "bsd-kvm.h"
|
||||
|
||||
static int
|
||||
alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
|
||||
{
|
||||
int regnum;
|
||||
|
||||
/* The following is true for OpenBSD 3.9:
|
||||
|
||||
The pcb contains the register state at the context switch inside
|
||||
cpu_switch(). */
|
||||
|
||||
/* The stack pointer shouldn't be zero. */
|
||||
if (pcb->pcb_hw.apcb_ksp == 0)
|
||||
return 0;
|
||||
|
||||
regcache_raw_supply (regcache, ALPHA_SP_REGNUM, &pcb->pcb_hw.apcb_ksp);
|
||||
|
||||
for (regnum = ALPHA_S0_REGNUM; regnum < ALPHA_A0_REGNUM; regnum++)
|
||||
regcache_raw_supply (regcache, regnum,
|
||||
&pcb->pcb_context[regnum - ALPHA_S0_REGNUM]);
|
||||
regcache_raw_supply (regcache, ALPHA_RA_REGNUM, &pcb->pcb_context[7]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_alphabsd_nat (void);
|
||||
|
||||
void
|
||||
_initialize_alphabsd_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
t->to_fetch_registers = alphabsd_fetch_inferior_registers;
|
||||
t->to_store_registers = alphabsd_store_inferior_registers;
|
||||
add_target (t);
|
||||
|
||||
/* Support debugging kernel virtual memory images. */
|
||||
bsd_kvm_add_target (alphabsd_supply_pcb);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/* Common target dependent code Alpha BSD's.
|
||||
|
||||
Copyright (C) 2000-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
#include "alphabsd-tdep.h"
|
||||
|
||||
/* Conviently, GDB uses the same register numbering as the
|
||||
ptrace register structure used by BSD on Alpha. */
|
||||
|
||||
void
|
||||
alphabsd_supply_reg (struct regcache *regcache, const char *regs, int regno)
|
||||
{
|
||||
/* PC is at slot 32; UNIQUE not present. */
|
||||
alpha_supply_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
alphabsd_fill_reg (const struct regcache *regcache, char *regs, int regno)
|
||||
{
|
||||
/* PC is at slot 32; UNIQUE not present. */
|
||||
alpha_fill_int_regs (regcache, regno, regs, regs + 31 * 8, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
alphabsd_supply_fpreg (struct regcache *regcache,
|
||||
const char *fpregs, int regno)
|
||||
{
|
||||
/* FPCR is at slot 33; slot 32 unused. */
|
||||
alpha_supply_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
|
||||
}
|
||||
|
||||
void
|
||||
alphabsd_fill_fpreg (const struct regcache *regcache, char *fpregs, int regno)
|
||||
{
|
||||
/* FPCR is at slot 33; slot 32 unused. */
|
||||
alpha_fill_fp_regs (regcache, regno, fpregs, fpregs + 32 * 8);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/* Common target dependent code for Alpha BSD's.
|
||||
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef ALPHABSD_TDEP_H
|
||||
#define ALPHABSD_TDEP_H
|
||||
|
||||
struct regcache;
|
||||
|
||||
void alphabsd_supply_reg (struct regcache *, const char *, int);
|
||||
void alphabsd_fill_reg (const struct regcache *, char *, int);
|
||||
|
||||
void alphabsd_supply_fpreg (struct regcache *, const char *, int);
|
||||
void alphabsd_fill_fpreg (const struct regcache *, char *, int);
|
||||
|
||||
|
||||
/* Functions exported from alphanbsd-tdep.c. */
|
||||
|
||||
/* Return the appropriate register set for the core section identified
|
||||
by SECT_NAME and SECT_SIZE. */
|
||||
extern const struct regset *
|
||||
alphanbsd_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t len);
|
||||
|
||||
#endif /* alphabsd-tdep.h */
|
||||
@@ -1,127 +0,0 @@
|
||||
/* Target-dependent code for FreeBSD/alpha.
|
||||
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "value.h"
|
||||
#include "osabi.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
static int
|
||||
alphafbsd_return_in_memory (struct type *type)
|
||||
{
|
||||
enum type_code code;
|
||||
int i;
|
||||
|
||||
/* All aggregate types that won't fit in a register must be returned
|
||||
in memory. */
|
||||
if (TYPE_LENGTH (type) > ALPHA_REGISTER_SIZE)
|
||||
return 1;
|
||||
|
||||
/* The only aggregate types that can be returned in a register are
|
||||
structs and unions. Arrays must be returned in memory. */
|
||||
code = TYPE_CODE (type);
|
||||
if (code != TYPE_CODE_STRUCT && code != TYPE_CODE_UNION)
|
||||
return 1;
|
||||
|
||||
/* We need to check if this struct/union is "integer" like. For
|
||||
this to be true, the offset of each adressable subfield must be
|
||||
zero. Note that bit fields are not addressable. */
|
||||
for (i = 0; i < TYPE_NFIELDS (type); i++)
|
||||
{
|
||||
/* If the field bitsize is non-zero, it isn't adressable. */
|
||||
if (TYPE_FIELD_BITPOS (type, i) != 0
|
||||
&& TYPE_FIELD_BITSIZE (type, i) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Support for signal handlers. */
|
||||
|
||||
/* Return whether PC is in a BSD sigtramp routine. */
|
||||
|
||||
CORE_ADDR alphafbsd_sigtramp_start = 0x11ffff68;
|
||||
CORE_ADDR alphafbsd_sigtramp_end = 0x11ffffe0;
|
||||
|
||||
static int
|
||||
alphafbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *func_name)
|
||||
{
|
||||
return (pc >= alphafbsd_sigtramp_start && pc < alphafbsd_sigtramp_end);
|
||||
}
|
||||
|
||||
static LONGEST
|
||||
alphafbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
return pc - alphafbsd_sigtramp_start;
|
||||
}
|
||||
|
||||
/* Assuming THIS_FRAME is the frame of a BSD sigtramp routine,
|
||||
return the address of the associated sigcontext structure. */
|
||||
|
||||
static CORE_ADDR
|
||||
alphafbsd_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
return get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM) + 24;
|
||||
}
|
||||
|
||||
/* FreeBSD 5.0-RELEASE or later. */
|
||||
|
||||
static void
|
||||
alphafbsd_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Hook into the DWARF CFI frame unwinder. */
|
||||
alpha_dwarf2_init_abi (info, gdbarch);
|
||||
|
||||
/* Hook into the MDEBUG frame unwinder. */
|
||||
alpha_mdebug_init_abi (info, gdbarch);
|
||||
|
||||
/* FreeBSD/alpha has SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
tdep->dynamic_sigtramp_offset = alphafbsd_sigtramp_offset;
|
||||
tdep->sigcontext_addr = alphafbsd_sigcontext_addr;
|
||||
tdep->pc_in_sigtramp = alphafbsd_pc_in_sigtramp;
|
||||
tdep->return_in_memory = alphafbsd_return_in_memory;
|
||||
tdep->sc_pc_offset = 288;
|
||||
tdep->sc_regs_offset = 24;
|
||||
tdep->sc_fpregs_offset = 320;
|
||||
|
||||
tdep->jb_pc = 2;
|
||||
tdep->jb_elt_size = 8;
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_alphafbsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_alphafbsd_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_FREEBSD_ELF,
|
||||
alphafbsd_init_abi);
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/* Target-dependent code for NetBSD/alpha.
|
||||
|
||||
Copyright (C) 2002-2013 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Wasabi Systems, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "osabi.h"
|
||||
#include "regcache.h"
|
||||
#include "regset.h"
|
||||
#include "value.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "alpha-tdep.h"
|
||||
#include "alphabsd-tdep.h"
|
||||
#include "nbsd-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Core file support. */
|
||||
|
||||
/* Even though NetBSD/alpha used ELF since day one, it used the
|
||||
traditional a.out-style core dump format before NetBSD 1.6. */
|
||||
|
||||
/* Sizeof `struct reg' in <machine/reg.h>. */
|
||||
#define ALPHANBSD_SIZEOF_GREGS (32 * 8)
|
||||
|
||||
/* Sizeof `struct fpreg' in <machine/reg.h. */
|
||||
#define ALPHANBSD_SIZEOF_FPREGS ((32 * 8) + 8)
|
||||
|
||||
/* Supply register REGNUM from the buffer specified by FPREGS and LEN
|
||||
in the floating-point register set REGSET to register cache
|
||||
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
|
||||
|
||||
static void
|
||||
alphanbsd_supply_fpregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *fpregs, size_t len)
|
||||
{
|
||||
const gdb_byte *regs = fpregs;
|
||||
int i;
|
||||
|
||||
gdb_assert (len >= ALPHANBSD_SIZEOF_FPREGS);
|
||||
|
||||
for (i = ALPHA_FP0_REGNUM; i < ALPHA_FP0_REGNUM + 31; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + (i - ALPHA_FP0_REGNUM) * 8);
|
||||
}
|
||||
|
||||
if (regnum == ALPHA_FPCR_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_FPCR_REGNUM, regs + 32 * 8);
|
||||
}
|
||||
|
||||
/* Supply register REGNUM from the buffer specified by GREGS and LEN
|
||||
in the general-purpose register set REGSET to register cache
|
||||
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
|
||||
|
||||
static void
|
||||
alphanbsd_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs, size_t len)
|
||||
{
|
||||
const gdb_byte *regs = gregs;
|
||||
int i;
|
||||
|
||||
gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
|
||||
|
||||
for (i = 0; i < ALPHA_ZERO_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + i * 8);
|
||||
}
|
||||
|
||||
if (regnum == ALPHA_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
|
||||
}
|
||||
|
||||
/* Supply register REGNUM from the buffer specified by GREGS and LEN
|
||||
in the general-purpose register set REGSET to register cache
|
||||
REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
|
||||
|
||||
static void
|
||||
alphanbsd_aout_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs, size_t len)
|
||||
{
|
||||
const gdb_byte *regs = gregs;
|
||||
int i;
|
||||
|
||||
/* Table to map a GDB register number to a trapframe register index. */
|
||||
static const int regmap[] =
|
||||
{
|
||||
0, 1, 2, 3,
|
||||
4, 5, 6, 7,
|
||||
8, 9, 10, 11,
|
||||
12, 13, 14, 15,
|
||||
30, 31, 32, 16,
|
||||
17, 18, 19, 20,
|
||||
21, 22, 23, 24,
|
||||
25, 29, 26
|
||||
};
|
||||
|
||||
gdb_assert (len >= ALPHANBSD_SIZEOF_GREGS);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regmap); i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + regmap[i] * 8);
|
||||
}
|
||||
|
||||
if (regnum == ALPHA_PC_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, ALPHA_PC_REGNUM, regs + 31 * 8);
|
||||
|
||||
if (len >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
|
||||
{
|
||||
regs += ALPHANBSD_SIZEOF_GREGS;
|
||||
len -= ALPHANBSD_SIZEOF_GREGS;
|
||||
alphanbsd_supply_fpregset (regset, regcache, regnum, regs, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* NetBSD/alpha register sets. */
|
||||
|
||||
static struct regset alphanbsd_gregset =
|
||||
{
|
||||
NULL,
|
||||
alphanbsd_supply_gregset
|
||||
};
|
||||
|
||||
static struct regset alphanbsd_fpregset =
|
||||
{
|
||||
NULL,
|
||||
alphanbsd_supply_fpregset
|
||||
};
|
||||
|
||||
static struct regset alphanbsd_aout_gregset =
|
||||
{
|
||||
NULL,
|
||||
alphanbsd_aout_supply_gregset
|
||||
};
|
||||
|
||||
/* Return the appropriate register set for the core section identified
|
||||
by SECT_NAME and SECT_SIZE. */
|
||||
|
||||
const struct regset *
|
||||
alphanbsd_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t sect_size)
|
||||
{
|
||||
if (strcmp (sect_name, ".reg") == 0 && sect_size >= ALPHANBSD_SIZEOF_GREGS)
|
||||
{
|
||||
if (sect_size >= ALPHANBSD_SIZEOF_GREGS + ALPHANBSD_SIZEOF_FPREGS)
|
||||
return &alphanbsd_aout_gregset;
|
||||
else
|
||||
return &alphanbsd_gregset;
|
||||
}
|
||||
|
||||
if (strcmp (sect_name, ".reg2") == 0 && sect_size >= ALPHANBSD_SIZEOF_FPREGS)
|
||||
return &alphanbsd_fpregset;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Signal trampolines. */
|
||||
|
||||
/* Under NetBSD/alpha, signal handler invocations can be identified by the
|
||||
designated code sequence that is used to return from a signal handler.
|
||||
In particular, the return address of a signal handler points to the
|
||||
following code sequence:
|
||||
|
||||
ldq a0, 0(sp)
|
||||
lda sp, 16(sp)
|
||||
lda v0, 295(zero) # __sigreturn14
|
||||
call_pal callsys
|
||||
|
||||
Each instruction has a unique encoding, so we simply attempt to match
|
||||
the instruction the PC is pointing to with any of the above instructions.
|
||||
If there is a hit, we know the offset to the start of the designated
|
||||
sequence and can then check whether we really are executing in the
|
||||
signal trampoline. If not, -1 is returned, otherwise the offset from the
|
||||
start of the return sequence is returned. */
|
||||
static const gdb_byte sigtramp_retcode[] =
|
||||
{
|
||||
0x00, 0x00, 0x1e, 0xa6, /* ldq a0, 0(sp) */
|
||||
0x10, 0x00, 0xde, 0x23, /* lda sp, 16(sp) */
|
||||
0x27, 0x01, 0x1f, 0x20, /* lda v0, 295(zero) */
|
||||
0x83, 0x00, 0x00, 0x00, /* call_pal callsys */
|
||||
};
|
||||
#define RETCODE_NWORDS 4
|
||||
#define RETCODE_SIZE (RETCODE_NWORDS * 4)
|
||||
|
||||
static LONGEST
|
||||
alphanbsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
gdb_byte ret[RETCODE_SIZE], w[4];
|
||||
LONGEST off;
|
||||
int i;
|
||||
|
||||
if (target_read_memory (pc, w, 4) != 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < RETCODE_NWORDS; i++)
|
||||
{
|
||||
if (memcmp (w, sigtramp_retcode + (i * 4), 4) == 0)
|
||||
break;
|
||||
}
|
||||
if (i == RETCODE_NWORDS)
|
||||
return (-1);
|
||||
|
||||
off = i * 4;
|
||||
pc -= off;
|
||||
|
||||
if (target_read_memory (pc, ret, sizeof (ret)) != 0)
|
||||
return -1;
|
||||
|
||||
if (memcmp (ret, sigtramp_retcode, RETCODE_SIZE) == 0)
|
||||
return off;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
alphanbsd_pc_in_sigtramp (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *func_name)
|
||||
{
|
||||
return (nbsd_pc_in_sigtramp (pc, func_name)
|
||||
|| alphanbsd_sigtramp_offset (gdbarch, pc) >= 0);
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alphanbsd_sigcontext_addr (struct frame_info *frame)
|
||||
{
|
||||
/* FIXME: This is not correct for all versions of NetBSD/alpha.
|
||||
We will probably need to disassemble the trampoline to figure
|
||||
out which trampoline frame type we have. */
|
||||
if (!get_next_frame (frame))
|
||||
return 0;
|
||||
return get_frame_base (get_next_frame (frame));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
alphanbsd_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Hook into the DWARF CFI frame unwinder. */
|
||||
alpha_dwarf2_init_abi (info, gdbarch);
|
||||
|
||||
/* Hook into the MDEBUG frame unwinder. */
|
||||
alpha_mdebug_init_abi (info, gdbarch);
|
||||
|
||||
/* NetBSD/alpha does not provide single step support via ptrace(2); we
|
||||
must use software single-stepping. */
|
||||
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
|
||||
|
||||
/* NetBSD/alpha has SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
|
||||
tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
|
||||
tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
|
||||
|
||||
tdep->jb_pc = 2;
|
||||
tdep->jb_elt_size = 8;
|
||||
|
||||
set_gdbarch_regset_from_core_section
|
||||
(gdbarch, alphanbsd_regset_from_core_section);
|
||||
}
|
||||
|
||||
|
||||
static enum gdb_osabi
|
||||
alphanbsd_core_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
|
||||
return GDB_OSABI_NETBSD_ELF;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_alphanbsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_alphanbsd_tdep (void)
|
||||
{
|
||||
/* BFD doesn't set a flavour for NetBSD style a.out core files. */
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_alpha, bfd_target_unknown_flavour,
|
||||
alphanbsd_core_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_NETBSD_ELF,
|
||||
alphanbsd_init_abi);
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/* Target-dependent code for OpenBSD/alpha.
|
||||
|
||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "osabi.h"
|
||||
|
||||
#include "obsd-tdep.h"
|
||||
#include "alpha-tdep.h"
|
||||
#include "alphabsd-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Signal trampolines. */
|
||||
|
||||
/* The OpenBSD kernel maps the signal trampoline at some random
|
||||
location in user space, which means that the traditional BSD way of
|
||||
detecting it won't work.
|
||||
|
||||
The signal trampoline will be mapped at an address that is page
|
||||
aligned. We recognize the signal trampoline by looking for the
|
||||
sigreturn system call. */
|
||||
|
||||
static const int alphaobsd_page_size = 8192;
|
||||
|
||||
static LONGEST
|
||||
alphaobsd_sigtramp_offset (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
return (pc & (alphaobsd_page_size - 1));
|
||||
}
|
||||
|
||||
static int
|
||||
alphaobsd_pc_in_sigtramp (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *name)
|
||||
{
|
||||
CORE_ADDR start_pc = (pc & ~(alphaobsd_page_size - 1));
|
||||
unsigned insn;
|
||||
|
||||
if (name)
|
||||
return 0;
|
||||
|
||||
/* Check for "". */
|
||||
insn = alpha_read_insn (gdbarch, start_pc + 5 * ALPHA_INSN_SIZE);
|
||||
if (insn != 0x201f0067)
|
||||
return 0;
|
||||
|
||||
/* Check for "". */
|
||||
insn = alpha_read_insn (gdbarch, start_pc + 6 * ALPHA_INSN_SIZE);
|
||||
if (insn != 0x00000083)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
alphaobsd_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
|
||||
if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
|
||||
{
|
||||
/* On entry, a pointer the `struct sigcontext' is passed in %a2. */
|
||||
return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
|
||||
}
|
||||
else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
|
||||
{
|
||||
/* It is stored on the stack Before calling the signal handler. */
|
||||
CORE_ADDR sp;
|
||||
sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
|
||||
return get_frame_memory_unsigned (this_frame, sp, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is reloaded into %a0 for the sigreturn(2) call. */
|
||||
return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Hook into the DWARF CFI frame unwinder. */
|
||||
alpha_dwarf2_init_abi (info, gdbarch);
|
||||
|
||||
/* Hook into the MDEBUG frame unwinder. */
|
||||
alpha_mdebug_init_abi (info, gdbarch);
|
||||
|
||||
/* OpenBSD/alpha 3.0 and earlier does not provide single step
|
||||
support via ptrace(2); use software single-stepping for now. */
|
||||
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
|
||||
|
||||
/* OpenBSD/alpha has SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
|
||||
|
||||
tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
|
||||
tdep->pc_in_sigtramp = alphaobsd_pc_in_sigtramp;
|
||||
tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
|
||||
|
||||
tdep->jb_pc = 2;
|
||||
tdep->jb_elt_size = 8;
|
||||
|
||||
set_gdbarch_regset_from_core_section
|
||||
(gdbarch, alphanbsd_regset_from_core_section);
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_alphaobsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_alphaobsd_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_alpha, 0, GDB_OSABI_OPENBSD_ELF,
|
||||
alphaobsd_init_abi);
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/* Darwin support for GDB, the GNU debugger.
|
||||
Copyright (C) 1997-2013 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Apple Computer, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "floatformat.h"
|
||||
#include "symtab.h"
|
||||
#include "regcache.h"
|
||||
#include "libbfd.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
#include "i387-tdep.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "osabi.h"
|
||||
#include "ui-out.h"
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
#include "amd64-darwin-tdep.h"
|
||||
#include "i386-darwin-tdep.h"
|
||||
#include "solib.h"
|
||||
#include "solib-darwin.h"
|
||||
#include "dwarf2-frame.h"
|
||||
|
||||
/* Offsets into the struct x86_thread_state64 where we'll find the saved regs.
|
||||
From <mach/i386/thread_status.h> and amd64-tdep.h. */
|
||||
int amd64_darwin_thread_state_reg_offset[] =
|
||||
{
|
||||
0 * 8, /* %rax */
|
||||
1 * 8, /* %rbx */
|
||||
2 * 8, /* %rcx */
|
||||
3 * 8, /* %rdx */
|
||||
5 * 8, /* %rsi */
|
||||
4 * 8, /* %rdi */
|
||||
6 * 8, /* %rbp */
|
||||
7 * 8, /* %rsp */
|
||||
8 * 8, /* %r8 ... */
|
||||
9 * 8,
|
||||
10 * 8,
|
||||
11 * 8,
|
||||
12 * 8,
|
||||
13 * 8,
|
||||
14 * 8,
|
||||
15 * 8, /* ... %r15 */
|
||||
16 * 8, /* %rip */
|
||||
17 * 8, /* %rflags */
|
||||
18 * 8, /* %cs */
|
||||
-1, /* %ss */
|
||||
-1, /* %ds */
|
||||
-1, /* %es */
|
||||
19 * 8, /* %fs */
|
||||
20 * 8 /* %gs */
|
||||
};
|
||||
|
||||
const int amd64_darwin_thread_state_num_regs =
|
||||
ARRAY_SIZE (amd64_darwin_thread_state_reg_offset);
|
||||
|
||||
/* Assuming THIS_FRAME is a Darwin sigtramp routine, return the
|
||||
address of the associated sigcontext structure. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64_darwin_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
CORE_ADDR rbx;
|
||||
gdb_byte buf[8];
|
||||
|
||||
/* A pointer to the ucontext is passed as the fourth argument
|
||||
to the signal handler, which is saved in rbx. */
|
||||
get_frame_register (this_frame, AMD64_RBX_REGNUM, buf);
|
||||
rbx = extract_unsigned_integer (buf, 8, byte_order);
|
||||
|
||||
/* The pointer to mcontext is at offset 48. */
|
||||
read_memory (rbx + 48, buf, 8);
|
||||
|
||||
/* First register (rax) is at offset 16. */
|
||||
return extract_unsigned_integer (buf, 8, byte_order) + 16;
|
||||
}
|
||||
|
||||
static void
|
||||
x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
tdep->struct_return = reg_struct_return;
|
||||
|
||||
dwarf2_frame_set_signal_frame_p (gdbarch, darwin_dwarf_signal_frame_p);
|
||||
|
||||
tdep->sigtramp_p = i386_sigtramp_p;
|
||||
tdep->sigcontext_addr = amd64_darwin_sigcontext_addr;
|
||||
tdep->sc_reg_offset = amd64_darwin_thread_state_reg_offset;
|
||||
tdep->sc_num_regs = amd64_darwin_thread_state_num_regs;
|
||||
|
||||
tdep->jb_pc_offset = 56;
|
||||
|
||||
set_solib_ops (gdbarch, &darwin_so_ops);
|
||||
}
|
||||
|
||||
/* -Wmissing-prototypes */
|
||||
extern initialize_file_ftype _initialize_amd64_darwin_tdep;
|
||||
|
||||
void
|
||||
_initialize_amd64_darwin_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_DARWIN, x86_darwin_init_abi_64);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/* Target-dependent code for Darwin x86-64.
|
||||
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
#ifndef __AMD64_DARWIN_TDEP_H__
|
||||
#define __AMD64_DARWIN_TDEP_H__
|
||||
|
||||
/* Mapping between the general-purpose registers in Darwin x86-64 thread
|
||||
state and GDB's register cache layout.
|
||||
Indexed by amd64_regnum. */
|
||||
extern int amd64_darwin_thread_state_reg_offset[];
|
||||
extern const int amd64_darwin_thread_state_num_regs;
|
||||
|
||||
#endif /* __AMD64_DARWIN_TDEP_H__ */
|
||||
@@ -1,62 +0,0 @@
|
||||
/* Target-dependent code for DICOS running on x86-64's, for GDB.
|
||||
|
||||
Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "osabi.h"
|
||||
#include "gdb_string.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "dicos-tdep.h"
|
||||
|
||||
static void
|
||||
amd64_dicos_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
dicos_init_abi (gdbarch);
|
||||
}
|
||||
|
||||
static enum gdb_osabi
|
||||
amd64_dicos_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
char *target_name = bfd_get_target (abfd);
|
||||
|
||||
/* On amd64-DICOS, the Load Module's "header" section is 72
|
||||
bytes. */
|
||||
if (strcmp (target_name, "elf64-x86-64") == 0
|
||||
&& dicos_load_module_p (abfd, 72))
|
||||
return GDB_OSABI_DICOS;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64_dicos_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_amd64_dicos_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
|
||||
amd64_dicos_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_DICOS,
|
||||
amd64_dicos_init_abi);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,313 +0,0 @@
|
||||
/* Target-dependent code for GNU/Linux AMD64.
|
||||
|
||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef AMD64_LINUX_TDEP_H
|
||||
#define AMD64_LINUX_TDEP_H
|
||||
|
||||
/* Like for i386 GNU/Linux, there is an extra "register"
|
||||
used to control syscall restarting. */
|
||||
|
||||
/* Register number for the "orig_rax" register. If this register
|
||||
contains a value >= 0 it is interpreted as the system call number
|
||||
that the kernel is supposed to restart. */
|
||||
#define AMD64_LINUX_ORIG_RAX_REGNUM (AMD64_YMM15H_REGNUM + 1)
|
||||
|
||||
/* Total number of registers for GNU/Linux. */
|
||||
#define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1)
|
||||
|
||||
/* Linux target description. */
|
||||
extern struct target_desc *tdesc_amd64_linux;
|
||||
extern struct target_desc *tdesc_amd64_avx_linux;
|
||||
extern struct target_desc *tdesc_x32_linux;
|
||||
extern struct target_desc *tdesc_x32_avx_linux;
|
||||
|
||||
/* Enum that defines the syscall identifiers for amd64 linux.
|
||||
Used for process record/replay, these will be translated into
|
||||
a gdb-canonical set of syscall ids in linux-record.c. */
|
||||
|
||||
enum amd64_syscall {
|
||||
amd64_sys_read = 0,
|
||||
amd64_sys_write = 1,
|
||||
amd64_sys_open = 2,
|
||||
amd64_sys_close = 3,
|
||||
amd64_sys_newstat = 4,
|
||||
amd64_sys_newfstat = 5,
|
||||
amd64_sys_newlstat = 6,
|
||||
amd64_sys_poll = 7,
|
||||
amd64_sys_lseek = 8,
|
||||
amd64_sys_mmap = 9,
|
||||
amd64_sys_mprotect = 10,
|
||||
amd64_sys_munmap = 11,
|
||||
amd64_sys_brk = 12,
|
||||
amd64_sys_rt_sigaction = 13,
|
||||
amd64_sys_rt_sigprocmask = 14,
|
||||
amd64_sys_rt_sigreturn = 15,
|
||||
amd64_sys_ioctl = 16,
|
||||
amd64_sys_pread64 = 17,
|
||||
amd64_sys_pwrite64 = 18,
|
||||
amd64_sys_readv = 19,
|
||||
amd64_sys_writev = 20,
|
||||
amd64_sys_access = 21,
|
||||
amd64_sys_pipe = 22,
|
||||
amd64_sys_select = 23,
|
||||
amd64_sys_sched_yield = 24,
|
||||
amd64_sys_mremap = 25,
|
||||
amd64_sys_msync = 26,
|
||||
amd64_sys_mincore = 27,
|
||||
amd64_sys_madvise = 28,
|
||||
amd64_sys_shmget = 29,
|
||||
amd64_sys_shmat = 30,
|
||||
amd64_sys_shmctl = 31,
|
||||
amd64_sys_dup = 32,
|
||||
amd64_sys_dup2 = 33,
|
||||
amd64_sys_pause = 34,
|
||||
amd64_sys_nanosleep = 35,
|
||||
amd64_sys_getitimer = 36,
|
||||
amd64_sys_alarm = 37,
|
||||
amd64_sys_setitimer = 38,
|
||||
amd64_sys_getpid = 39,
|
||||
amd64_sys_sendfile64 = 40,
|
||||
amd64_sys_socket = 41,
|
||||
amd64_sys_connect = 42,
|
||||
amd64_sys_accept = 43,
|
||||
amd64_sys_sendto = 44,
|
||||
amd64_sys_recvfrom = 45,
|
||||
amd64_sys_sendmsg = 46,
|
||||
amd64_sys_recvmsg = 47,
|
||||
amd64_sys_shutdown = 48,
|
||||
amd64_sys_bind = 49,
|
||||
amd64_sys_listen = 50,
|
||||
amd64_sys_getsockname = 51,
|
||||
amd64_sys_getpeername = 52,
|
||||
amd64_sys_socketpair = 53,
|
||||
amd64_sys_setsockopt = 54,
|
||||
amd64_sys_getsockopt = 55,
|
||||
amd64_sys_clone = 56,
|
||||
amd64_sys_fork = 57,
|
||||
amd64_sys_vfork = 58,
|
||||
amd64_sys_execve = 59,
|
||||
amd64_sys_exit = 60,
|
||||
amd64_sys_wait4 = 61,
|
||||
amd64_sys_kill = 62,
|
||||
amd64_sys_uname = 63,
|
||||
amd64_sys_semget = 64,
|
||||
amd64_sys_semop = 65,
|
||||
amd64_sys_semctl = 66,
|
||||
amd64_sys_shmdt = 67,
|
||||
amd64_sys_msgget = 68,
|
||||
amd64_sys_msgsnd = 69,
|
||||
amd64_sys_msgrcv = 70,
|
||||
amd64_sys_msgctl = 71,
|
||||
amd64_sys_fcntl = 72,
|
||||
amd64_sys_flock = 73,
|
||||
amd64_sys_fsync = 74,
|
||||
amd64_sys_fdatasync = 75,
|
||||
amd64_sys_truncate = 76,
|
||||
amd64_sys_ftruncate = 77,
|
||||
amd64_sys_getdents = 78,
|
||||
amd64_sys_getcwd = 79,
|
||||
amd64_sys_chdir = 80,
|
||||
amd64_sys_fchdir = 81,
|
||||
amd64_sys_rename = 82,
|
||||
amd64_sys_mkdir = 83,
|
||||
amd64_sys_rmdir = 84,
|
||||
amd64_sys_creat = 85,
|
||||
amd64_sys_link = 86,
|
||||
amd64_sys_unlink = 87,
|
||||
amd64_sys_symlink = 88,
|
||||
amd64_sys_readlink = 89,
|
||||
amd64_sys_chmod = 90,
|
||||
amd64_sys_fchmod = 91,
|
||||
amd64_sys_chown = 92,
|
||||
amd64_sys_fchown = 93,
|
||||
amd64_sys_lchown = 94,
|
||||
amd64_sys_umask = 95,
|
||||
amd64_sys_gettimeofday = 96,
|
||||
amd64_sys_getrlimit = 97,
|
||||
amd64_sys_getrusage = 98,
|
||||
amd64_sys_sysinfo = 99,
|
||||
amd64_sys_times = 100,
|
||||
amd64_sys_ptrace = 101,
|
||||
amd64_sys_getuid = 102,
|
||||
amd64_sys_syslog = 103,
|
||||
amd64_sys_getgid = 104,
|
||||
amd64_sys_setuid = 105,
|
||||
amd64_sys_setgid = 106,
|
||||
amd64_sys_geteuid = 107,
|
||||
amd64_sys_getegid = 108,
|
||||
amd64_sys_setpgid = 109,
|
||||
amd64_sys_getppid = 110,
|
||||
amd64_sys_getpgrp = 111,
|
||||
amd64_sys_setsid = 112,
|
||||
amd64_sys_setreuid = 113,
|
||||
amd64_sys_setregid = 114,
|
||||
amd64_sys_getgroups = 115,
|
||||
amd64_sys_setgroups = 116,
|
||||
amd64_sys_setresuid = 117,
|
||||
amd64_sys_getresuid = 118,
|
||||
amd64_sys_setresgid = 119,
|
||||
amd64_sys_getresgid = 120,
|
||||
amd64_sys_getpgid = 121,
|
||||
amd64_sys_setfsuid = 122,
|
||||
amd64_sys_setfsgid = 123,
|
||||
amd64_sys_getsid = 124,
|
||||
amd64_sys_capget = 125,
|
||||
amd64_sys_capset = 126,
|
||||
amd64_sys_rt_sigpending = 127,
|
||||
amd64_sys_rt_sigtimedwait = 128,
|
||||
amd64_sys_rt_sigqueueinfo = 129,
|
||||
amd64_sys_rt_sigsuspend = 130,
|
||||
amd64_sys_sigaltstack = 131,
|
||||
amd64_sys_utime = 132,
|
||||
amd64_sys_mknod = 133,
|
||||
amd64_sys_personality = 135,
|
||||
amd64_sys_ustat = 136,
|
||||
amd64_sys_statfs = 137,
|
||||
amd64_sys_fstatfs = 138,
|
||||
amd64_sys_sysfs = 139,
|
||||
amd64_sys_getpriority = 140,
|
||||
amd64_sys_setpriority = 141,
|
||||
amd64_sys_sched_setparam = 142,
|
||||
amd64_sys_sched_getparam = 143,
|
||||
amd64_sys_sched_setscheduler = 144,
|
||||
amd64_sys_sched_getscheduler = 145,
|
||||
amd64_sys_sched_get_priority_max = 146,
|
||||
amd64_sys_sched_get_priority_min = 147,
|
||||
amd64_sys_sched_rr_get_interval = 148,
|
||||
amd64_sys_mlock = 149,
|
||||
amd64_sys_munlock = 150,
|
||||
amd64_sys_mlockall = 151,
|
||||
amd64_sys_munlockall = 152,
|
||||
amd64_sys_vhangup = 153,
|
||||
amd64_sys_modify_ldt = 154,
|
||||
amd64_sys_pivot_root = 155,
|
||||
amd64_sys_sysctl = 156,
|
||||
amd64_sys_prctl = 157,
|
||||
amd64_sys_arch_prctl = 158,
|
||||
amd64_sys_adjtimex = 159,
|
||||
amd64_sys_setrlimit = 160,
|
||||
amd64_sys_chroot = 161,
|
||||
amd64_sys_sync = 162,
|
||||
amd64_sys_acct = 163,
|
||||
amd64_sys_settimeofday = 164,
|
||||
amd64_sys_mount = 165,
|
||||
amd64_sys_umount = 166,
|
||||
amd64_sys_swapon = 167,
|
||||
amd64_sys_swapoff = 168,
|
||||
amd64_sys_reboot = 169,
|
||||
amd64_sys_sethostname = 170,
|
||||
amd64_sys_setdomainname = 171,
|
||||
amd64_sys_iopl = 172,
|
||||
amd64_sys_ioperm = 173,
|
||||
amd64_sys_init_module = 175,
|
||||
amd64_sys_delete_module = 176,
|
||||
amd64_sys_quotactl = 179,
|
||||
amd64_sys_nfsservctl = 180,
|
||||
amd64_sys_gettid = 186,
|
||||
amd64_sys_readahead = 187,
|
||||
amd64_sys_setxattr = 188,
|
||||
amd64_sys_lsetxattr = 189,
|
||||
amd64_sys_fsetxattr = 190,
|
||||
amd64_sys_getxattr = 191,
|
||||
amd64_sys_lgetxattr = 192,
|
||||
amd64_sys_fgetxattr = 193,
|
||||
amd64_sys_listxattr = 194,
|
||||
amd64_sys_llistxattr = 195,
|
||||
amd64_sys_flistxattr = 196,
|
||||
amd64_sys_removexattr = 197,
|
||||
amd64_sys_lremovexattr = 198,
|
||||
amd64_sys_fremovexattr = 199,
|
||||
amd64_sys_tkill = 200,
|
||||
amd64_sys_time = 201,
|
||||
amd64_sys_futex = 202,
|
||||
amd64_sys_sched_setaffinity = 203,
|
||||
amd64_sys_sched_getaffinity = 204,
|
||||
amd64_sys_io_setup = 206,
|
||||
amd64_sys_io_destroy = 207,
|
||||
amd64_sys_io_getevents = 208,
|
||||
amd64_sys_io_submit = 209,
|
||||
amd64_sys_io_cancel = 210,
|
||||
amd64_sys_lookup_dcookie = 212,
|
||||
amd64_sys_epoll_create = 213,
|
||||
amd64_sys_remap_file_pages = 216,
|
||||
amd64_sys_getdents64 = 217,
|
||||
amd64_sys_set_tid_address = 218,
|
||||
amd64_sys_restart_syscall = 219,
|
||||
amd64_sys_semtimedop = 220,
|
||||
amd64_sys_fadvise64 = 221,
|
||||
amd64_sys_timer_create = 222,
|
||||
amd64_sys_timer_settime = 223,
|
||||
amd64_sys_timer_gettime = 224,
|
||||
amd64_sys_timer_getoverrun = 225,
|
||||
amd64_sys_timer_delete = 226,
|
||||
amd64_sys_clock_settime = 227,
|
||||
amd64_sys_clock_gettime = 228,
|
||||
amd64_sys_clock_getres = 229,
|
||||
amd64_sys_clock_nanosleep = 230,
|
||||
amd64_sys_exit_group = 231,
|
||||
amd64_sys_epoll_wait = 232,
|
||||
amd64_sys_epoll_ctl = 233,
|
||||
amd64_sys_tgkill = 234,
|
||||
amd64_sys_utimes = 235,
|
||||
amd64_sys_mbind = 237,
|
||||
amd64_sys_set_mempolicy = 238,
|
||||
amd64_sys_get_mempolicy = 239,
|
||||
amd64_sys_mq_open = 240,
|
||||
amd64_sys_mq_unlink = 241,
|
||||
amd64_sys_mq_timedsend = 242,
|
||||
amd64_sys_mq_timedreceive = 243,
|
||||
amd64_sys_mq_notify = 244,
|
||||
amd64_sys_mq_getsetattr = 245,
|
||||
amd64_sys_kexec_load = 246,
|
||||
amd64_sys_waitid = 247,
|
||||
amd64_sys_add_key = 248,
|
||||
amd64_sys_request_key = 249,
|
||||
amd64_sys_keyctl = 250,
|
||||
amd64_sys_ioprio_set = 251,
|
||||
amd64_sys_ioprio_get = 252,
|
||||
amd64_sys_inotify_init = 253,
|
||||
amd64_sys_inotify_add_watch = 254,
|
||||
amd64_sys_inotify_rm_watch = 255,
|
||||
amd64_sys_migrate_pages = 256,
|
||||
amd64_sys_openat = 257,
|
||||
amd64_sys_mkdirat = 258,
|
||||
amd64_sys_mknodat = 259,
|
||||
amd64_sys_fchownat = 260,
|
||||
amd64_sys_futimesat = 261,
|
||||
amd64_sys_newfstatat = 262,
|
||||
amd64_sys_unlinkat = 263,
|
||||
amd64_sys_renameat = 264,
|
||||
amd64_sys_linkat = 265,
|
||||
amd64_sys_symlinkat = 266,
|
||||
amd64_sys_readlinkat = 267,
|
||||
amd64_sys_fchmodat = 268,
|
||||
amd64_sys_faccessat = 269,
|
||||
amd64_sys_pselect6 = 270,
|
||||
amd64_sys_ppoll = 271,
|
||||
amd64_sys_unshare = 272,
|
||||
amd64_sys_set_robust_list = 273,
|
||||
amd64_sys_get_robust_list = 274,
|
||||
amd64_sys_splice = 275,
|
||||
amd64_sys_tee = 276,
|
||||
amd64_sys_sync_file_range = 277,
|
||||
amd64_sys_vmsplice = 278,
|
||||
amd64_sys_move_pages = 279,
|
||||
};
|
||||
|
||||
#endif /* amd64-linux-tdep.h */
|
||||
162
gdb/amd64-nat.c
162
gdb/amd64-nat.c
@@ -1,162 +0,0 @@
|
||||
/* Native-dependent code for AMD64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbarch.h"
|
||||
#include "regcache.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "i386-tdep.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
|
||||
/* The following bits of code help with implementing debugging 32-bit
|
||||
code natively on AMD64. The idea is to define two mappings between
|
||||
the register number as used by GDB and the register set used by the
|
||||
host to represent the general-purpose registers; one for 32-bit
|
||||
code and one for 64-bit code. The mappings are specified by the
|
||||
follwing variables and consist of an array of offsets within the
|
||||
register set indexed by register number, and the number of
|
||||
registers supported by the mapping. We don't need mappings for the
|
||||
floating-point and SSE registers, since the difference between
|
||||
64-bit and 32-bit variants are negligable. The difference in the
|
||||
number of SSE registers is already handled by the target code. */
|
||||
|
||||
/* General-purpose register mapping for native 32-bit code. */
|
||||
int *amd64_native_gregset32_reg_offset;
|
||||
int amd64_native_gregset32_num_regs = I386_NUM_GREGS;
|
||||
|
||||
/* General-purpose register mapping for native 64-bit code. */
|
||||
int *amd64_native_gregset64_reg_offset;
|
||||
int amd64_native_gregset64_num_regs = AMD64_NUM_GREGS;
|
||||
|
||||
/* Return the offset of REGNUM within the appropriate native
|
||||
general-purpose register set. */
|
||||
|
||||
static int
|
||||
amd64_native_gregset_reg_offset (struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
int *reg_offset = amd64_native_gregset64_reg_offset;
|
||||
int num_regs = amd64_native_gregset64_num_regs;
|
||||
|
||||
gdb_assert (regnum >= 0);
|
||||
|
||||
if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
|
||||
{
|
||||
reg_offset = amd64_native_gregset32_reg_offset;
|
||||
num_regs = amd64_native_gregset32_num_regs;
|
||||
}
|
||||
|
||||
if (num_regs > gdbarch_num_regs (gdbarch))
|
||||
num_regs = gdbarch_num_regs (gdbarch);
|
||||
|
||||
if (regnum < num_regs && regnum < gdbarch_num_regs (gdbarch))
|
||||
return reg_offset[regnum];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return whether the native general-purpose register set supplies
|
||||
register REGNUM. */
|
||||
|
||||
int
|
||||
amd64_native_gregset_supplies_p (struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
return (amd64_native_gregset_reg_offset (gdbarch, regnum) != -1);
|
||||
}
|
||||
|
||||
|
||||
/* Supply register REGNUM, whose contents are stored in GREGS, to
|
||||
REGCACHE. If REGNUM is -1, supply all appropriate registers. */
|
||||
|
||||
void
|
||||
amd64_supply_native_gregset (struct regcache *regcache,
|
||||
const void *gregs, int regnum)
|
||||
{
|
||||
const char *regs = gregs;
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
int num_regs = amd64_native_gregset64_num_regs;
|
||||
int i;
|
||||
|
||||
if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
|
||||
num_regs = amd64_native_gregset32_num_regs;
|
||||
|
||||
if (num_regs > gdbarch_num_regs (gdbarch))
|
||||
num_regs = gdbarch_num_regs (gdbarch);
|
||||
|
||||
for (i = 0; i < num_regs; i++)
|
||||
{
|
||||
if (regnum == -1 || regnum == i)
|
||||
{
|
||||
int offset = amd64_native_gregset_reg_offset (gdbarch, i);
|
||||
|
||||
if (offset != -1)
|
||||
regcache_raw_supply (regcache, i, regs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Collect register REGNUM from REGCACHE and store its contents in
|
||||
GREGS. If REGNUM is -1, collect and store all appropriate
|
||||
registers. */
|
||||
|
||||
void
|
||||
amd64_collect_native_gregset (const struct regcache *regcache,
|
||||
void *gregs, int regnum)
|
||||
{
|
||||
char *regs = gregs;
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
int num_regs = amd64_native_gregset64_num_regs;
|
||||
int i;
|
||||
|
||||
if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
|
||||
{
|
||||
num_regs = amd64_native_gregset32_num_regs;
|
||||
|
||||
/* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and
|
||||
%eip get zero-extended to 64 bits. */
|
||||
for (i = 0; i <= I386_EIP_REGNUM; i++)
|
||||
{
|
||||
if (regnum == -1 || regnum == i)
|
||||
memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);
|
||||
}
|
||||
/* Ditto for %cs, %ss, %ds, %es, %fs, and %gs. */
|
||||
for (i = I386_CS_REGNUM; i <= I386_GS_REGNUM; i++)
|
||||
{
|
||||
if (regnum == -1 || regnum == i)
|
||||
memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_regs > gdbarch_num_regs (gdbarch))
|
||||
num_regs = gdbarch_num_regs (gdbarch);
|
||||
|
||||
for (i = 0; i < num_regs; i++)
|
||||
{
|
||||
if (regnum == -1 || regnum == i)
|
||||
{
|
||||
int offset = amd64_native_gregset_reg_offset (gdbarch, i);
|
||||
|
||||
if (offset != -1)
|
||||
regcache_raw_collect (regcache, i, regs + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* Native-dependent code for AMD64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef AMD64_NAT_H
|
||||
#define AMD64_NAT_H 1
|
||||
|
||||
struct regcache;
|
||||
|
||||
/* General-purpose register set description for native 32-bit code. */
|
||||
extern int *amd64_native_gregset32_reg_offset;
|
||||
extern int amd64_native_gregset32_num_regs;
|
||||
|
||||
/* General-purpose register set description for native 64-bit code. */
|
||||
extern int *amd64_native_gregset64_reg_offset;
|
||||
extern int amd64_native_gregset64_num_regs;
|
||||
|
||||
/* Return whether the native general-purpose register set supplies
|
||||
register REGNUM. */
|
||||
|
||||
extern int amd64_native_gregset_supplies_p (struct gdbarch *gdbarch,
|
||||
int regnum);
|
||||
|
||||
/* Supply register REGNUM, whose contents are store in BUF, to
|
||||
REGCACHE. If REGNUM is -1, supply all appropriate registers. */
|
||||
|
||||
extern void amd64_supply_native_gregset (struct regcache *regcache,
|
||||
const void *gregs, int regnum);
|
||||
|
||||
/* Collect register REGNUM from REGCACHE and store its contents in
|
||||
GREGS. If REGNUM is -1, collect and store all appropriate
|
||||
registers. */
|
||||
|
||||
extern void amd64_collect_native_gregset (const struct regcache *regcache,
|
||||
void *gregs, int regnum);
|
||||
|
||||
/* Create a prototype *BSD/amd64 target. The client can override it
|
||||
with local methods. */
|
||||
|
||||
extern struct target_ops *amd64bsd_target (void);
|
||||
|
||||
#endif /* amd64-nat.h */
|
||||
@@ -1,129 +0,0 @@
|
||||
/* Target-dependent code for AMD64 Solaris.
|
||||
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Joseph Myers, CodeSourcery, LLC.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
#include "osabi.h"
|
||||
#include "symtab.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "sol2-tdep.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Mapping between the general-purpose registers in gregset_t format
|
||||
and GDB's register cache layout. */
|
||||
|
||||
/* From <sys/regset.h>. */
|
||||
static int amd64_sol2_gregset_reg_offset[] = {
|
||||
14 * 8, /* %rax */
|
||||
11 * 8, /* %rbx */
|
||||
13 * 8, /* %rcx */
|
||||
12 * 8, /* %rdx */
|
||||
9 * 8, /* %rsi */
|
||||
8 * 8, /* %rdi */
|
||||
10 * 8, /* %rbp */
|
||||
20 * 8, /* %rsp */
|
||||
7 * 8, /* %r8 ... */
|
||||
6 * 8,
|
||||
5 * 8,
|
||||
4 * 8,
|
||||
3 * 8,
|
||||
2 * 8,
|
||||
1 * 8,
|
||||
0 * 8, /* ... %r15 */
|
||||
17 * 8, /* %rip */
|
||||
19 * 8, /* %eflags */
|
||||
18 * 8, /* %cs */
|
||||
21 * 8, /* %ss */
|
||||
25 * 8, /* %ds */
|
||||
24 * 8, /* %es */
|
||||
22 * 8, /* %fs */
|
||||
23 * 8 /* %gs */
|
||||
};
|
||||
|
||||
|
||||
/* Return whether THIS_FRAME corresponds to a Solaris sigtramp
|
||||
routine. */
|
||||
|
||||
static int
|
||||
amd64_sol2_sigtramp_p (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
const char *name;
|
||||
|
||||
find_pc_partial_function (pc, &name, NULL, NULL);
|
||||
return (name && (strcmp ("sigacthandler", name) == 0
|
||||
|| strcmp (name, "ucbsigvechandler") == 0));
|
||||
}
|
||||
|
||||
/* Solaris doesn't have a 'struct sigcontext', but it does have a
|
||||
'mcontext_t' that contains the saved set of machine registers. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64_sol2_mcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR sp, ucontext_addr;
|
||||
|
||||
sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
||||
ucontext_addr = get_frame_memory_unsigned (this_frame, sp + 8, 8);
|
||||
|
||||
return ucontext_addr + 72;
|
||||
}
|
||||
|
||||
static void
|
||||
amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
tdep->gregset_reg_offset = amd64_sol2_gregset_reg_offset;
|
||||
tdep->gregset_num_regs = ARRAY_SIZE (amd64_sol2_gregset_reg_offset);
|
||||
tdep->sizeof_gregset = 28 * 8;
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
tdep->sigtramp_p = amd64_sol2_sigtramp_p;
|
||||
tdep->sigcontext_addr = amd64_sol2_mcontext_addr;
|
||||
tdep->sc_reg_offset = tdep->gregset_reg_offset;
|
||||
tdep->sc_num_regs = tdep->gregset_num_regs;
|
||||
|
||||
/* Solaris uses SVR4-style shared libraries. */
|
||||
set_gdbarch_skip_solib_resolver (gdbarch, sol2_skip_solib_resolver);
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
/* How to print LWP PTIDs from core files. */
|
||||
set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern void _initialize_amd64_sol2_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_amd64_sol2_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_SOLARIS, amd64_sol2_init_abi);
|
||||
}
|
||||
3126
gdb/amd64-tdep.c
3126
gdb/amd64-tdep.c
File diff suppressed because it is too large
Load Diff
129
gdb/amd64-tdep.h
129
gdb/amd64-tdep.h
@@ -1,129 +0,0 @@
|
||||
/* Target-dependent definitions for AMD64.
|
||||
|
||||
Copyright (C) 2001-2013 Free Software Foundation, Inc.
|
||||
Contributed by Jiri Smid, SuSE Labs.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef AMD64_TDEP_H
|
||||
#define AMD64_TDEP_H
|
||||
|
||||
struct gdbarch;
|
||||
struct frame_info;
|
||||
struct regcache;
|
||||
|
||||
#include "i386-tdep.h"
|
||||
|
||||
/* Register numbers of various important registers. */
|
||||
|
||||
enum amd64_regnum
|
||||
{
|
||||
AMD64_RAX_REGNUM, /* %rax */
|
||||
AMD64_RBX_REGNUM, /* %rbx */
|
||||
AMD64_RCX_REGNUM, /* %rcx */
|
||||
AMD64_RDX_REGNUM, /* %rdx */
|
||||
AMD64_RSI_REGNUM, /* %rsi */
|
||||
AMD64_RDI_REGNUM, /* %rdi */
|
||||
AMD64_RBP_REGNUM, /* %rbp */
|
||||
AMD64_RSP_REGNUM, /* %rsp */
|
||||
AMD64_R8_REGNUM, /* %r8 */
|
||||
AMD64_R9_REGNUM, /* %r9 */
|
||||
AMD64_R10_REGNUM, /* %r10 */
|
||||
AMD64_R11_REGNUM, /* %r11 */
|
||||
AMD64_R12_REGNUM, /* %r12 */
|
||||
AMD64_R13_REGNUM, /* %r13 */
|
||||
AMD64_R14_REGNUM, /* %r14 */
|
||||
AMD64_R15_REGNUM, /* %r15 */
|
||||
AMD64_RIP_REGNUM, /* %rip */
|
||||
AMD64_EFLAGS_REGNUM, /* %eflags */
|
||||
AMD64_CS_REGNUM, /* %cs */
|
||||
AMD64_SS_REGNUM, /* %ss */
|
||||
AMD64_DS_REGNUM, /* %ds */
|
||||
AMD64_ES_REGNUM, /* %es */
|
||||
AMD64_FS_REGNUM, /* %fs */
|
||||
AMD64_GS_REGNUM, /* %gs */
|
||||
AMD64_ST0_REGNUM = 24, /* %st0 */
|
||||
AMD64_ST1_REGNUM, /* %st1 */
|
||||
AMD64_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8,
|
||||
AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9,
|
||||
AMD64_FTAG_REGNUM = AMD64_ST0_REGNUM + 10,
|
||||
AMD64_XMM0_REGNUM = 40, /* %xmm0 */
|
||||
AMD64_XMM1_REGNUM, /* %xmm1 */
|
||||
AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16,
|
||||
AMD64_YMM0H_REGNUM, /* %ymm0h */
|
||||
AMD64_YMM15H_REGNUM = AMD64_YMM0H_REGNUM + 15
|
||||
};
|
||||
|
||||
/* Number of general purpose registers. */
|
||||
#define AMD64_NUM_GREGS 24
|
||||
|
||||
#define AMD64_NUM_REGS (AMD64_YMM15H_REGNUM + 1)
|
||||
|
||||
extern struct displaced_step_closure *amd64_displaced_step_copy_insn
|
||||
(struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to,
|
||||
struct regcache *regs);
|
||||
extern void amd64_displaced_step_fixup (struct gdbarch *gdbarch,
|
||||
struct displaced_step_closure *closure,
|
||||
CORE_ADDR from, CORE_ADDR to,
|
||||
struct regcache *regs);
|
||||
|
||||
extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
|
||||
extern void amd64_x32_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch);
|
||||
|
||||
/* Fill register REGNUM in REGCACHE with the appropriate
|
||||
floating-point or SSE register value from *FXSAVE. If REGNUM is
|
||||
-1, do this for all registers. This function masks off any of the
|
||||
reserved bits in *FXSAVE. */
|
||||
|
||||
extern void amd64_supply_fxsave (struct regcache *regcache, int regnum,
|
||||
const void *fxsave);
|
||||
|
||||
/* Similar to amd64_supply_fxsave, but use XSAVE extended state. */
|
||||
extern void amd64_supply_xsave (struct regcache *regcache, int regnum,
|
||||
const void *xsave);
|
||||
|
||||
/* Fill register REGNUM (if it is a floating-point or SSE register) in
|
||||
*FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
|
||||
all registers. This function doesn't touch any of the reserved
|
||||
bits in *FXSAVE. */
|
||||
|
||||
extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum,
|
||||
void *fxsave);
|
||||
|
||||
/* Similar to amd64_collect_fxsave, but use XSAVE extended state. */
|
||||
extern void amd64_collect_xsave (const struct regcache *regcache,
|
||||
int regnum, void *xsave, int gcore);
|
||||
|
||||
void amd64_classify (struct type *type, enum amd64_reg_class class[2]);
|
||||
|
||||
|
||||
|
||||
/* Variables exported from amd64-linux-tdep.c. */
|
||||
extern int amd64_linux_gregset_reg_offset[];
|
||||
|
||||
/* Variables exported from amd64nbsd-tdep.c. */
|
||||
extern int amd64nbsd_r_reg_offset[];
|
||||
|
||||
/* Variables exported from amd64obsd-tdep.c. */
|
||||
extern int amd64obsd_r_reg_offset[];
|
||||
|
||||
/* Variables exported from amd64fbsd-tdep.c. */
|
||||
extern CORE_ADDR amd64fbsd_sigtramp_start_addr;
|
||||
extern CORE_ADDR amd64fbsd_sigtramp_end_addr;
|
||||
extern int amd64fbsd_sc_reg_offset[];
|
||||
|
||||
#endif /* amd64-tdep.h */
|
||||
@@ -1,107 +0,0 @@
|
||||
/* Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "windows-nat.h"
|
||||
#include "i386-nat.h"
|
||||
#include "amd64-tdep.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define context_offset(x) (offsetof (CONTEXT, x))
|
||||
static const int mappings[] =
|
||||
{
|
||||
context_offset (Rax),
|
||||
context_offset (Rbx),
|
||||
context_offset (Rcx),
|
||||
context_offset (Rdx),
|
||||
context_offset (Rsi),
|
||||
context_offset (Rdi),
|
||||
context_offset (Rbp),
|
||||
context_offset (Rsp),
|
||||
context_offset (R8),
|
||||
context_offset (R9),
|
||||
context_offset (R10),
|
||||
context_offset (R11),
|
||||
context_offset (R12),
|
||||
context_offset (R13),
|
||||
context_offset (R14),
|
||||
context_offset (R15),
|
||||
context_offset (Rip),
|
||||
context_offset (EFlags),
|
||||
context_offset (SegCs),
|
||||
context_offset (SegSs),
|
||||
context_offset (SegDs),
|
||||
context_offset (SegEs),
|
||||
context_offset (SegFs),
|
||||
context_offset (SegGs),
|
||||
context_offset (FloatSave.FloatRegisters[0]),
|
||||
context_offset (FloatSave.FloatRegisters[1]),
|
||||
context_offset (FloatSave.FloatRegisters[2]),
|
||||
context_offset (FloatSave.FloatRegisters[3]),
|
||||
context_offset (FloatSave.FloatRegisters[4]),
|
||||
context_offset (FloatSave.FloatRegisters[5]),
|
||||
context_offset (FloatSave.FloatRegisters[6]),
|
||||
context_offset (FloatSave.FloatRegisters[7]),
|
||||
context_offset (FloatSave.ControlWord),
|
||||
context_offset (FloatSave.StatusWord),
|
||||
context_offset (FloatSave.TagWord),
|
||||
context_offset (FloatSave.ErrorSelector),
|
||||
context_offset (FloatSave.ErrorOffset),
|
||||
context_offset (FloatSave.DataSelector),
|
||||
context_offset (FloatSave.DataOffset),
|
||||
context_offset (FloatSave.ErrorSelector)
|
||||
/* XMM0-7 */ ,
|
||||
context_offset (Xmm0),
|
||||
context_offset (Xmm1),
|
||||
context_offset (Xmm2),
|
||||
context_offset (Xmm3),
|
||||
context_offset (Xmm4),
|
||||
context_offset (Xmm5),
|
||||
context_offset (Xmm6),
|
||||
context_offset (Xmm7),
|
||||
context_offset (Xmm8),
|
||||
context_offset (Xmm9),
|
||||
context_offset (Xmm10),
|
||||
context_offset (Xmm11),
|
||||
context_offset (Xmm12),
|
||||
context_offset (Xmm13),
|
||||
context_offset (Xmm14),
|
||||
context_offset (Xmm15),
|
||||
/* MXCSR */
|
||||
context_offset (FloatSave.MxCsr)
|
||||
};
|
||||
#undef context_offset
|
||||
|
||||
/* segment_register_p_ftype implementation for amd64. */
|
||||
|
||||
static int
|
||||
amd64_windows_segment_register_p (int regnum)
|
||||
{
|
||||
return regnum >= AMD64_CS_REGNUM && regnum <= AMD64_GS_REGNUM;
|
||||
}
|
||||
|
||||
/* -Wmissing-prototypes */
|
||||
extern initialize_file_ftype _initialize_amd64_windows_nat;
|
||||
|
||||
void
|
||||
_initialize_amd64_windows_nat (void)
|
||||
{
|
||||
windows_set_context_register_offsets (mappings);
|
||||
windows_set_segment_register_p (amd64_windows_segment_register_p);
|
||||
i386_set_debug_register_length (8);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,200 +0,0 @@
|
||||
/* Native-dependent code for AMD64 BSD's.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
#include "target.h"
|
||||
|
||||
/* We include <signal.h> to make sure `struct fxsave64' is defined on
|
||||
NetBSD, since NetBSD's <machine/reg.h> needs it. */
|
||||
#include "gdb_assert.h"
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
#include "amd64bsd-nat.h"
|
||||
#include "inf-ptrace.h"
|
||||
|
||||
|
||||
/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
|
||||
for all registers (including the floating-point registers). */
|
||||
|
||||
static void
|
||||
amd64bsd_fetch_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
|
||||
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
struct reg regs;
|
||||
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
|
||||
perror_with_name (_("Couldn't get registers"));
|
||||
|
||||
amd64_supply_native_gregset (regcache, ®s, -1);
|
||||
if (regnum != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
struct fpreg fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
amd64_supply_fxsave (regcache, -1, &fpregs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
|
||||
this for all registers (including the floating-point registers). */
|
||||
|
||||
static void
|
||||
amd64bsd_store_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
|
||||
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
struct reg regs;
|
||||
|
||||
if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
|
||||
perror_with_name (_("Couldn't get registers"));
|
||||
|
||||
amd64_collect_native_gregset (regcache, ®s, regnum);
|
||||
|
||||
if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) ®s, 0) == -1)
|
||||
perror_with_name (_("Couldn't write registers"));
|
||||
|
||||
if (regnum != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
struct fpreg fpregs;
|
||||
|
||||
if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
amd64_collect_fxsave (regcache, regnum, &fpregs);
|
||||
|
||||
if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write floating point status"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a prototype *BSD/amd64 target. The client can override it
|
||||
with local methods. */
|
||||
|
||||
struct target_ops *
|
||||
amd64bsd_target (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
|
||||
t->to_store_registers = amd64bsd_store_inferior_registers;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/* Support for debug registers. */
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
|
||||
static unsigned long
|
||||
amd64bsd_dr_get (ptid_t ptid, int regnum)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't read debug registers"));
|
||||
|
||||
return DBREG_DRX ((&dbregs), regnum);
|
||||
}
|
||||
|
||||
static void
|
||||
amd64bsd_dr_set (int regnum, unsigned long value)
|
||||
{
|
||||
struct dbreg dbregs;
|
||||
|
||||
if (ptrace (PT_GETDBREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't get debug registers"));
|
||||
|
||||
/* For some mysterious reason, some of the reserved bits in the
|
||||
debug control register get set. Mask these off, otherwise the
|
||||
ptrace call below will fail. */
|
||||
DBREG_DRX ((&dbregs), 7) &= ~(0xffffffff0000fc00);
|
||||
|
||||
DBREG_DRX ((&dbregs), regnum) = value;
|
||||
|
||||
if (ptrace (PT_SETDBREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
|
||||
perror_with_name (_("Couldn't write debug registers"));
|
||||
}
|
||||
|
||||
void
|
||||
amd64bsd_dr_set_control (unsigned long control)
|
||||
{
|
||||
amd64bsd_dr_set (7, control);
|
||||
}
|
||||
|
||||
void
|
||||
amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr)
|
||||
{
|
||||
gdb_assert (regnum >= 0 && regnum <= 4);
|
||||
|
||||
amd64bsd_dr_set (regnum, addr);
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
amd64bsd_dr_get_addr (int regnum)
|
||||
{
|
||||
return amd64bsd_dr_get (inferior_ptid, regnum);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
amd64bsd_dr_get_status (void)
|
||||
{
|
||||
return amd64bsd_dr_get (inferior_ptid, 6);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
amd64bsd_dr_get_control (void)
|
||||
{
|
||||
return amd64bsd_dr_get (inferior_ptid, 7);
|
||||
}
|
||||
|
||||
#endif /* PT_GETDBREGS */
|
||||
@@ -1,35 +0,0 @@
|
||||
/* Native-dependent code for AMD64 BSD's.
|
||||
|
||||
Copyright (C) 2011-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef AMD64BSD_NAT_H
|
||||
#define AMD64BSD_NAT_H
|
||||
|
||||
/* Low level amd64 debug register functions. */
|
||||
|
||||
extern void amd64bsd_dr_set_control (unsigned long control);
|
||||
|
||||
extern void amd64bsd_dr_set_addr (int regnum, CORE_ADDR addr);
|
||||
|
||||
extern CORE_ADDR amd64bsd_dr_get_addr (int regnum);
|
||||
|
||||
extern unsigned long amd64bsd_dr_get_status (void);
|
||||
|
||||
extern unsigned long amd64bsd_dr_get_control (void);
|
||||
|
||||
#endif /* amd64bsd-nat.h */
|
||||
@@ -1,271 +0,0 @@
|
||||
/* Native-dependent code for FreeBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#include "fbsd-nat.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
#include "amd64bsd-nat.h"
|
||||
#include "i386-nat.h"
|
||||
|
||||
|
||||
/* Offset in `struct reg' where MEMBER is stored. */
|
||||
#define REG_OFFSET(member) offsetof (struct reg, member)
|
||||
|
||||
/* At amd64fbsd64_r_reg_offset[REGNUM] you'll find the offset in
|
||||
`struct reg' location where the GDB register REGNUM is stored.
|
||||
Unsupported registers are marked with `-1'. */
|
||||
static int amd64fbsd64_r_reg_offset[] =
|
||||
{
|
||||
REG_OFFSET (r_rax),
|
||||
REG_OFFSET (r_rbx),
|
||||
REG_OFFSET (r_rcx),
|
||||
REG_OFFSET (r_rdx),
|
||||
REG_OFFSET (r_rsi),
|
||||
REG_OFFSET (r_rdi),
|
||||
REG_OFFSET (r_rbp),
|
||||
REG_OFFSET (r_rsp),
|
||||
REG_OFFSET (r_r8),
|
||||
REG_OFFSET (r_r9),
|
||||
REG_OFFSET (r_r10),
|
||||
REG_OFFSET (r_r11),
|
||||
REG_OFFSET (r_r12),
|
||||
REG_OFFSET (r_r13),
|
||||
REG_OFFSET (r_r14),
|
||||
REG_OFFSET (r_r15),
|
||||
REG_OFFSET (r_rip),
|
||||
REG_OFFSET (r_rflags),
|
||||
REG_OFFSET (r_cs),
|
||||
REG_OFFSET (r_ss),
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1
|
||||
};
|
||||
|
||||
|
||||
/* Mapping between the general-purpose registers in FreeBSD/amd64
|
||||
`struct reg' format and GDB's register cache layout for
|
||||
FreeBSD/i386.
|
||||
|
||||
Note that most FreeBSD/amd64 registers are 64-bit, while the
|
||||
FreeBSD/i386 registers are all 32-bit, but since we're
|
||||
little-endian we get away with that. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
|
||||
{
|
||||
14 * 8, 13 * 8, /* %eax, %ecx */
|
||||
12 * 8, 11 * 8, /* %edx, %ebx */
|
||||
20 * 8, 10 * 8, /* %esp, %ebp */
|
||||
9 * 8, 8 * 8, /* %esi, %edi */
|
||||
17 * 8, 19 * 8, /* %eip, %eflags */
|
||||
18 * 8, 21 * 8, /* %cs, %ss */
|
||||
-1, -1, -1, -1 /* %ds, %es, %fs, %gs */
|
||||
};
|
||||
|
||||
|
||||
/* Support for debugging kernel virtual memory images. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <osreldate.h>
|
||||
|
||||
#include "bsd-kvm.h"
|
||||
|
||||
static int
|
||||
amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
|
||||
{
|
||||
/* The following is true for FreeBSD 5.2:
|
||||
|
||||
The pcb contains %rip, %rbx, %rsp, %rbp, %r12, %r13, %r14, %r15,
|
||||
%ds, %es, %fs and %gs. This accounts for all callee-saved
|
||||
registers specified by the psABI and then some. Here %esp
|
||||
contains the stack pointer at the point just after the call to
|
||||
cpu_switch(). From this information we reconstruct the register
|
||||
state as it would like when we just returned from cpu_switch(). */
|
||||
|
||||
/* The stack pointer shouldn't be zero. */
|
||||
if (pcb->pcb_rsp == 0)
|
||||
return 0;
|
||||
|
||||
pcb->pcb_rsp += 8;
|
||||
regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &pcb->pcb_rip);
|
||||
regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &pcb->pcb_rbx);
|
||||
regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
|
||||
regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
|
||||
regcache_raw_supply (regcache, 12, &pcb->pcb_r12);
|
||||
regcache_raw_supply (regcache, 13, &pcb->pcb_r13);
|
||||
regcache_raw_supply (regcache, 14, &pcb->pcb_r14);
|
||||
regcache_raw_supply (regcache, 15, &pcb->pcb_r15);
|
||||
#if (__FreeBSD_version < 800075) && (__FreeBSD_kernel_version < 800075)
|
||||
/* struct pcb provides the pcb_ds/pcb_es/pcb_fs/pcb_gs fields only
|
||||
up until __FreeBSD_version 800074: The removal of these fields
|
||||
occurred on 2009-04-01 while the __FreeBSD_version number was
|
||||
bumped to 800075 on 2009-04-06. So 800075 is the closest version
|
||||
number where we should not try to access these fields. */
|
||||
regcache_raw_supply (regcache, AMD64_DS_REGNUM, &pcb->pcb_ds);
|
||||
regcache_raw_supply (regcache, AMD64_ES_REGNUM, &pcb->pcb_es);
|
||||
regcache_raw_supply (regcache, AMD64_FS_REGNUM, &pcb->pcb_fs);
|
||||
regcache_raw_supply (regcache, AMD64_GS_REGNUM, &pcb->pcb_gs);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void (*super_mourn_inferior) (struct target_ops *ops);
|
||||
|
||||
static void
|
||||
amd64fbsd_mourn_inferior (struct target_ops *ops)
|
||||
{
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
i386_cleanup_dregs ();
|
||||
#endif
|
||||
super_mourn_inferior (ops);
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64fbsd_nat (void);
|
||||
|
||||
void
|
||||
_initialize_amd64fbsd_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
int offset;
|
||||
|
||||
amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
|
||||
amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
|
||||
|
||||
/* Add some extra features to the common *BSD/i386 target. */
|
||||
t = amd64bsd_target ();
|
||||
|
||||
#ifdef HAVE_PT_GETDBREGS
|
||||
|
||||
i386_use_watchpoints (t);
|
||||
|
||||
i386_dr_low.set_control = amd64bsd_dr_set_control;
|
||||
i386_dr_low.set_addr = amd64bsd_dr_set_addr;
|
||||
i386_dr_low.get_addr = amd64bsd_dr_get_addr;
|
||||
i386_dr_low.get_status = amd64bsd_dr_get_status;
|
||||
i386_dr_low.get_control = amd64bsd_dr_get_control;
|
||||
i386_set_debug_register_length (8);
|
||||
|
||||
#endif /* HAVE_PT_GETDBREGS */
|
||||
|
||||
super_mourn_inferior = t->to_mourn_inferior;
|
||||
t->to_mourn_inferior = amd64fbsd_mourn_inferior;
|
||||
|
||||
t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
|
||||
t->to_find_memory_regions = fbsd_find_memory_regions;
|
||||
t->to_make_corefile_notes = fbsd_make_corefile_notes;
|
||||
add_target (t);
|
||||
|
||||
/* Support debugging kernel virtual memory images. */
|
||||
bsd_kvm_add_target (amd64fbsd_supply_pcb);
|
||||
|
||||
/* To support the recognition of signal handlers, i386bsd-tdep.c
|
||||
hardcodes some constants. Inclusion of this file means that we
|
||||
are compiling a native debugger, which means that we can use the
|
||||
system header files and sysctl(3) to get at the relevant
|
||||
information. */
|
||||
|
||||
#define SC_REG_OFFSET amd64fbsd_sc_reg_offset
|
||||
|
||||
/* We only check the program counter, stack pointer and frame
|
||||
pointer since these members of `struct sigcontext' are essential
|
||||
for providing backtraces. */
|
||||
|
||||
#define SC_RIP_OFFSET SC_REG_OFFSET[AMD64_RIP_REGNUM]
|
||||
#define SC_RSP_OFFSET SC_REG_OFFSET[AMD64_RSP_REGNUM]
|
||||
#define SC_RBP_OFFSET SC_REG_OFFSET[AMD64_RBP_REGNUM]
|
||||
|
||||
/* Override the default value for the offset of the program counter
|
||||
in the sigcontext structure. */
|
||||
offset = offsetof (struct sigcontext, sc_rip);
|
||||
|
||||
if (SC_RIP_OFFSET != offset)
|
||||
{
|
||||
warning (_("\
|
||||
offsetof (struct sigcontext, sc_rip) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>."),
|
||||
offset, SC_RIP_OFFSET);
|
||||
}
|
||||
|
||||
SC_RIP_OFFSET = offset;
|
||||
|
||||
/* Likewise for the stack pointer. */
|
||||
offset = offsetof (struct sigcontext, sc_rsp);
|
||||
|
||||
if (SC_RSP_OFFSET != offset)
|
||||
{
|
||||
warning (_("\
|
||||
offsetof (struct sigcontext, sc_rsp) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>."),
|
||||
offset, SC_RSP_OFFSET);
|
||||
}
|
||||
|
||||
SC_RSP_OFFSET = offset;
|
||||
|
||||
/* And the frame pointer. */
|
||||
offset = offsetof (struct sigcontext, sc_rbp);
|
||||
|
||||
if (SC_RBP_OFFSET != offset)
|
||||
{
|
||||
warning (_("\
|
||||
offsetof (struct sigcontext, sc_rbp) yields %d instead of %d.\n\
|
||||
Please report this to <bug-gdb@gnu.org>."),
|
||||
offset, SC_RBP_OFFSET);
|
||||
}
|
||||
|
||||
SC_RBP_OFFSET = offset;
|
||||
|
||||
/* FreeBSD provides a kern.ps_strings sysctl that we can use to
|
||||
locate the sigtramp. That way we can still recognize a sigtramp
|
||||
if its location is changed in a new kernel. Of course this is
|
||||
still based on the assumption that the sigtramp is placed
|
||||
directly under the location where the program arguments and
|
||||
environment can be found. */
|
||||
{
|
||||
int mib[2];
|
||||
long ps_strings;
|
||||
size_t len;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PS_STRINGS;
|
||||
len = sizeof (ps_strings);
|
||||
if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
|
||||
{
|
||||
amd64fbsd_sigtramp_start_addr = ps_strings - 32;
|
||||
amd64fbsd_sigtramp_end_addr = ps_strings;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/* Target-dependent code for FreeBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "arch-utils.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
#include "osabi.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "bsd-uthread.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Support for signal handlers. */
|
||||
|
||||
/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
|
||||
address of the associated sigcontext structure. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64fbsd_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR sp;
|
||||
|
||||
/* The `struct sigcontext' (which really is an `ucontext_t' on
|
||||
FreeBSD/amd64) lives at a fixed offset in the signal frame. See
|
||||
<machine/sigframe.h>. */
|
||||
sp = frame_unwind_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
||||
return sp + 16;
|
||||
}
|
||||
|
||||
/* FreeBSD 5.1-RELEASE or later. */
|
||||
|
||||
/* Mapping between the general-purpose registers in `struct reg'
|
||||
format and GDB's register cache layout.
|
||||
|
||||
Note that some registers are 32-bit, but since we're little-endian
|
||||
we get away with that. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
static int amd64fbsd_r_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %rax */
|
||||
11 * 8, /* %rbx */
|
||||
13 * 8, /* %rcx */
|
||||
12 * 8, /* %rdx */
|
||||
9 * 8, /* %rsi */
|
||||
8 * 8, /* %rdi */
|
||||
10 * 8, /* %rbp */
|
||||
20 * 8, /* %rsp */
|
||||
7 * 8, /* %r8 ... */
|
||||
6 * 8,
|
||||
5 * 8,
|
||||
4 * 8,
|
||||
3 * 8,
|
||||
2 * 8,
|
||||
1 * 8,
|
||||
0 * 8, /* ... %r15 */
|
||||
17 * 8, /* %rip */
|
||||
19 * 8, /* %eflags */
|
||||
18 * 8, /* %cs */
|
||||
21 * 8, /* %ss */
|
||||
-1, /* %ds */
|
||||
-1, /* %es */
|
||||
-1, /* %fs */
|
||||
-1 /* %gs */
|
||||
};
|
||||
|
||||
/* Location of the signal trampoline. */
|
||||
CORE_ADDR amd64fbsd_sigtramp_start_addr = 0x7fffffffffc0ULL;
|
||||
CORE_ADDR amd64fbsd_sigtramp_end_addr = 0x7fffffffffe0ULL;
|
||||
|
||||
/* From <machine/signal.h>. */
|
||||
int amd64fbsd_sc_reg_offset[] =
|
||||
{
|
||||
24 + 6 * 8, /* %rax */
|
||||
24 + 7 * 8, /* %rbx */
|
||||
24 + 3 * 8, /* %rcx */
|
||||
24 + 2 * 8, /* %rdx */
|
||||
24 + 1 * 8, /* %rsi */
|
||||
24 + 0 * 8, /* %rdi */
|
||||
24 + 8 * 8, /* %rbp */
|
||||
24 + 22 * 8, /* %rsp */
|
||||
24 + 4 * 8, /* %r8 ... */
|
||||
24 + 5 * 8,
|
||||
24 + 9 * 8,
|
||||
24 + 10 * 8,
|
||||
24 + 11 * 8,
|
||||
24 + 12 * 8,
|
||||
24 + 13 * 8,
|
||||
24 + 14 * 8, /* ... %r15 */
|
||||
24 + 19 * 8, /* %rip */
|
||||
24 + 21 * 8, /* %eflags */
|
||||
24 + 20 * 8, /* %cs */
|
||||
24 + 23 * 8, /* %ss */
|
||||
-1, /* %ds */
|
||||
-1, /* %es */
|
||||
-1, /* %fs */
|
||||
-1 /* %gs */
|
||||
};
|
||||
|
||||
/* From /usr/src/lib/libc/amd64/gen/_setjmp.S. */
|
||||
static int amd64fbsd_jmp_buf_reg_offset[] =
|
||||
{
|
||||
-1, /* %rax */
|
||||
1 * 8, /* %rbx */
|
||||
-1, /* %rcx */
|
||||
-1, /* %rdx */
|
||||
-1, /* %rsi */
|
||||
-1, /* %rdi */
|
||||
3 * 8, /* %rbp */
|
||||
2 * 8, /* %rsp */
|
||||
-1, /* %r8 ... */
|
||||
-1,
|
||||
-1,
|
||||
-1, /* ... %r11 */
|
||||
4 * 8, /* %r12 ... */
|
||||
5 * 8,
|
||||
6 * 8,
|
||||
7 * 8, /* ... %r15 */
|
||||
0 * 8 /* %rip */
|
||||
};
|
||||
|
||||
static void
|
||||
amd64fbsd_supply_uthread (struct regcache *regcache,
|
||||
int regnum, CORE_ADDR addr)
|
||||
{
|
||||
gdb_byte buf[8];
|
||||
int i;
|
||||
|
||||
gdb_assert (regnum >= -1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
|
||||
{
|
||||
if (amd64fbsd_jmp_buf_reg_offset[i] != -1
|
||||
&& (regnum == -1 || regnum == i))
|
||||
{
|
||||
read_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
|
||||
regcache_raw_supply (regcache, i, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
amd64fbsd_collect_uthread (const struct regcache *regcache,
|
||||
int regnum, CORE_ADDR addr)
|
||||
{
|
||||
gdb_byte buf[8];
|
||||
int i;
|
||||
|
||||
gdb_assert (regnum >= -1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (amd64fbsd_jmp_buf_reg_offset); i++)
|
||||
{
|
||||
if (amd64fbsd_jmp_buf_reg_offset[i] != -1
|
||||
&& (regnum == -1 || regnum == i))
|
||||
{
|
||||
regcache_raw_collect (regcache, i, buf);
|
||||
write_memory (addr + amd64fbsd_jmp_buf_reg_offset[i], buf, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Obviously FreeBSD is BSD-based. */
|
||||
i386bsd_init_abi (info, gdbarch);
|
||||
|
||||
tdep->gregset_reg_offset = amd64fbsd_r_reg_offset;
|
||||
tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
|
||||
tdep->sizeof_gregset = 22 * 8;
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
|
||||
tdep->sigtramp_end = amd64fbsd_sigtramp_end_addr;
|
||||
tdep->sigcontext_addr = amd64fbsd_sigcontext_addr;
|
||||
tdep->sc_reg_offset = amd64fbsd_sc_reg_offset;
|
||||
tdep->sc_num_regs = ARRAY_SIZE (amd64fbsd_sc_reg_offset);
|
||||
|
||||
/* FreeBSD provides a user-level threads implementation. */
|
||||
bsd_uthread_set_supply_uthread (gdbarch, amd64fbsd_supply_uthread);
|
||||
bsd_uthread_set_collect_uthread (gdbarch, amd64fbsd_collect_uthread);
|
||||
|
||||
/* FreeBSD uses SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64fbsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_amd64fbsd_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_FREEBSD_ELF, amd64fbsd_init_abi);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/* Native-dependent code for NetBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
|
||||
#include "nbsd-nat.h"
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
|
||||
/* Mapping between the general-purpose registers in NetBSD/amd64
|
||||
`struct reg' format and GDB's register cache layout for
|
||||
NetBSD/i386.
|
||||
|
||||
Note that most (if not all) NetBSD/amd64 registers are 64-bit,
|
||||
while the NetBSD/i386 registers are all 32-bit, but since we're
|
||||
little-endian we get away with that. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
static int amd64nbsd32_r_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %eax */
|
||||
3 * 8, /* %ecx */
|
||||
2 * 8, /* %edx */
|
||||
13 * 8, /* %ebx */
|
||||
24 * 8, /* %esp */
|
||||
12 * 8, /* %ebp */
|
||||
1 * 8, /* %esi */
|
||||
0 * 8, /* %edi */
|
||||
21 * 8, /* %eip */
|
||||
23 * 8, /* %eflags */
|
||||
22 * 8, /* %cs */
|
||||
25 * 8, /* %ss */
|
||||
18 * 8, /* %ds */
|
||||
17 * 8, /* %es */
|
||||
16 * 8, /* %fs */
|
||||
15 * 8 /* %gs */
|
||||
};
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64nbsd_nat (void);
|
||||
|
||||
void
|
||||
_initialize_amd64nbsd_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
|
||||
amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
|
||||
amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
|
||||
|
||||
/* Add some extra features to the common *BSD/amd64 target. */
|
||||
t = amd64bsd_target ();
|
||||
t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
|
||||
add_target (t);
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/* Target-dependent code for NetBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "arch-utils.h"
|
||||
#include "frame.h"
|
||||
#include "gdbcore.h"
|
||||
#include "osabi.h"
|
||||
#include "symtab.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "nbsd-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Support for signal handlers. */
|
||||
|
||||
/* Return whether THIS_FRAME corresponds to a NetBSD sigtramp
|
||||
routine. */
|
||||
|
||||
static int
|
||||
amd64nbsd_sigtramp_p (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
const char *name;
|
||||
|
||||
find_pc_partial_function (pc, &name, NULL, NULL);
|
||||
return nbsd_pc_in_sigtramp (pc, name);
|
||||
}
|
||||
|
||||
/* Assuming THIS_FRAME corresponds to a NetBSD sigtramp routine,
|
||||
return the address of the associated mcontext structure. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64nbsd_mcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
||||
/* The register %r15 points at `struct ucontext' upon entry of a
|
||||
signal trampoline. */
|
||||
addr = get_frame_register_unsigned (this_frame, AMD64_R15_REGNUM);
|
||||
|
||||
/* The mcontext structure lives as offset 56 in `struct ucontext'. */
|
||||
return addr + 56;
|
||||
}
|
||||
|
||||
/* NetBSD 2.0 or later. */
|
||||
|
||||
/* Mapping between the general-purpose registers in `struct reg'
|
||||
format and GDB's register cache layout. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
int amd64nbsd_r_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %rax */
|
||||
13 * 8, /* %rbx */
|
||||
3 * 8, /* %rcx */
|
||||
2 * 8, /* %rdx */
|
||||
1 * 8, /* %rsi */
|
||||
0 * 8, /* %rdi */
|
||||
12 * 8, /* %rbp */
|
||||
24 * 8, /* %rsp */
|
||||
4 * 8, /* %r8 .. */
|
||||
5 * 8,
|
||||
6 * 8,
|
||||
7 * 8,
|
||||
8 * 8,
|
||||
9 * 8,
|
||||
10 * 8,
|
||||
11 * 8, /* ... %r15 */
|
||||
21 * 8, /* %rip */
|
||||
23 * 8, /* %eflags */
|
||||
22 * 8, /* %cs */
|
||||
25 * 8, /* %ss */
|
||||
18 * 8, /* %ds */
|
||||
17 * 8, /* %es */
|
||||
16 * 8, /* %fs */
|
||||
15 * 8 /* %gs */
|
||||
};
|
||||
|
||||
static void
|
||||
amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Initialize general-purpose register set details first. */
|
||||
tdep->gregset_reg_offset = amd64nbsd_r_reg_offset;
|
||||
tdep->gregset_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
|
||||
tdep->sizeof_gregset = 26 * 8;
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
tdep->jb_pc_offset = 7 * 8;
|
||||
|
||||
/* NetBSD has its own convention for signal trampolines. */
|
||||
tdep->sigtramp_p = amd64nbsd_sigtramp_p;
|
||||
tdep->sigcontext_addr = amd64nbsd_mcontext_addr;
|
||||
tdep->sc_reg_offset = amd64nbsd_r_reg_offset;
|
||||
tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
|
||||
|
||||
/* NetBSD uses SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64nbsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_amd64nbsd_tdep (void)
|
||||
{
|
||||
/* The NetBSD/amd64 native dependent code makes this assumption. */
|
||||
gdb_assert (ARRAY_SIZE (amd64nbsd_r_reg_offset) == AMD64_NUM_GREGS);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_NETBSD_ELF, amd64nbsd_init_abi);
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/* Native-dependent code for OpenBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
|
||||
/* Mapping between the general-purpose registers in OpenBSD/amd64
|
||||
`struct reg' format and GDB's register cache layout for
|
||||
OpenBSD/i386.
|
||||
|
||||
Note that most (if not all) OpenBSD/amd64 registers are 64-bit,
|
||||
while the OpenBSD/i386 registers are all 32-bit, but since we're
|
||||
little-endian we get away with that. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
static int amd64obsd32_r_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %eax */
|
||||
3 * 8, /* %ecx */
|
||||
2 * 8, /* %edx */
|
||||
13 * 8, /* %ebx */
|
||||
15 * 8, /* %esp */
|
||||
12 * 8, /* %ebp */
|
||||
1 * 8, /* %esi */
|
||||
0 * 8, /* %edi */
|
||||
16 * 8, /* %eip */
|
||||
17 * 8, /* %eflags */
|
||||
18 * 8, /* %cs */
|
||||
19 * 8, /* %ss */
|
||||
20 * 8, /* %ds */
|
||||
21 * 8, /* %es */
|
||||
22 * 8, /* %fs */
|
||||
23 * 8 /* %gs */
|
||||
};
|
||||
|
||||
|
||||
/* Support for debugging kernel virtual memory images. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
#include "bsd-kvm.h"
|
||||
|
||||
static int
|
||||
amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
|
||||
{
|
||||
struct switchframe sf;
|
||||
int regnum;
|
||||
|
||||
/* The following is true for OpenBSD 3.5:
|
||||
|
||||
The pcb contains the stack pointer at the point of the context
|
||||
switch in cpu_switch(). At that point we have a stack frame as
|
||||
described by `struct switchframe', which for OpenBSD 3.5 has the
|
||||
following layout:
|
||||
|
||||
interrupt level
|
||||
%r15
|
||||
%r14
|
||||
%r13
|
||||
%r12
|
||||
%rbp
|
||||
%rbx
|
||||
return address
|
||||
|
||||
Together with %rsp in the pcb, this accounts for all callee-saved
|
||||
registers specified by the psABI. From this information we
|
||||
reconstruct the register state as it would look when we just
|
||||
returned from cpu_switch().
|
||||
|
||||
For core dumps the pcb is saved by savectx(). In that case the
|
||||
stack frame only contains the return address, and there is no way
|
||||
to recover the other registers. */
|
||||
|
||||
/* The stack pointer shouldn't be zero. */
|
||||
if (pcb->pcb_rsp == 0)
|
||||
return 0;
|
||||
|
||||
/* Read the stack frame, and check its validity. */
|
||||
read_memory (pcb->pcb_rsp, (gdb_byte *) &sf, sizeof sf);
|
||||
if (sf.sf_rbp == pcb->pcb_rbp)
|
||||
{
|
||||
/* Yes, we have a frame that matches cpu_switch(). */
|
||||
pcb->pcb_rsp += sizeof (struct switchframe);
|
||||
regcache_raw_supply (regcache, 12, &sf.sf_r12);
|
||||
regcache_raw_supply (regcache, 13, &sf.sf_r13);
|
||||
regcache_raw_supply (regcache, 14, &sf.sf_r14);
|
||||
regcache_raw_supply (regcache, 15, &sf.sf_r15);
|
||||
regcache_raw_supply (regcache, AMD64_RBX_REGNUM, &sf.sf_rbx);
|
||||
regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf.sf_rip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No, the pcb must have been last updated by savectx(). */
|
||||
pcb->pcb_rsp += 8;
|
||||
regcache_raw_supply (regcache, AMD64_RIP_REGNUM, &sf);
|
||||
}
|
||||
|
||||
regcache_raw_supply (regcache, AMD64_RSP_REGNUM, &pcb->pcb_rsp);
|
||||
regcache_raw_supply (regcache, AMD64_RBP_REGNUM, &pcb->pcb_rbp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64obsd_nat (void);
|
||||
|
||||
void
|
||||
_initialize_amd64obsd_nat (void)
|
||||
{
|
||||
amd64_native_gregset32_reg_offset = amd64obsd32_r_reg_offset;
|
||||
amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
|
||||
amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
|
||||
|
||||
/* We've got nothing to add to the common *BSD/amd64 target. */
|
||||
add_target (amd64bsd_target ());
|
||||
|
||||
/* Support debugging kernel virtual memory images. */
|
||||
bsd_kvm_add_target (amd64obsd_supply_pcb);
|
||||
}
|
||||
@@ -1,514 +0,0 @@
|
||||
/* Target-dependent code for OpenBSD/amd64.
|
||||
|
||||
Copyright (C) 2003-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "frame-unwind.h"
|
||||
#include "gdbcore.h"
|
||||
#include "symtab.h"
|
||||
#include "objfiles.h"
|
||||
#include "osabi.h"
|
||||
#include "regcache.h"
|
||||
#include "regset.h"
|
||||
#include "target.h"
|
||||
#include "trad-frame.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "i387-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
#include "bsd-uthread.h"
|
||||
|
||||
/* Support for core dumps. */
|
||||
|
||||
static void
|
||||
amd64obsd_supply_regset (const struct regset *regset,
|
||||
struct regcache *regcache, int regnum,
|
||||
const void *regs, size_t len)
|
||||
{
|
||||
const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
|
||||
|
||||
gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE);
|
||||
|
||||
i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
|
||||
amd64_supply_fxsave (regcache, regnum,
|
||||
((const gdb_byte *)regs) + tdep->sizeof_gregset);
|
||||
}
|
||||
|
||||
static const struct regset *
|
||||
amd64obsd_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t sect_size)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* OpenBSD core dumps don't use seperate register sets for the
|
||||
general-purpose and floating-point registers. */
|
||||
|
||||
if (strcmp (sect_name, ".reg") == 0
|
||||
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE)
|
||||
{
|
||||
if (tdep->gregset == NULL)
|
||||
tdep->gregset = regset_alloc (gdbarch, amd64obsd_supply_regset, NULL);
|
||||
return tdep->gregset;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Support for signal handlers. */
|
||||
|
||||
/* Default page size. */
|
||||
static const int amd64obsd_page_size = 4096;
|
||||
|
||||
/* Return whether THIS_FRAME corresponds to an OpenBSD sigtramp
|
||||
routine. */
|
||||
|
||||
static int
|
||||
amd64obsd_sigtramp_p (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
|
||||
const gdb_byte osigreturn[] =
|
||||
{
|
||||
0x48, 0xc7, 0xc0,
|
||||
0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
|
||||
0xcd, 0x80 /* int $0x80 */
|
||||
};
|
||||
const gdb_byte sigreturn[] =
|
||||
{
|
||||
0x48, 0xc7, 0xc0,
|
||||
0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
|
||||
0x0f, 0x05 /* syscall */
|
||||
};
|
||||
size_t buflen = (sizeof sigreturn) + 1;
|
||||
gdb_byte *buf;
|
||||
const char *name;
|
||||
|
||||
/* If the function has a valid symbol name, it isn't a
|
||||
trampoline. */
|
||||
find_pc_partial_function (pc, &name, NULL, NULL);
|
||||
if (name != NULL)
|
||||
return 0;
|
||||
|
||||
/* If the function lives in a valid section (even without a starting
|
||||
point) it isn't a trampoline. */
|
||||
if (find_pc_section (pc) != NULL)
|
||||
return 0;
|
||||
|
||||
/* If we can't read the instructions at START_PC, return zero. */
|
||||
buf = alloca ((sizeof sigreturn) + 1);
|
||||
if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen))
|
||||
return 0;
|
||||
|
||||
/* Check for sigreturn(2). Depending on how the assembler encoded
|
||||
the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
|
||||
7. OpenBSD 5.0 and later use the `syscall' instruction. Older
|
||||
versions use `int $0x80'. Check for both. */
|
||||
if (memcmp (buf, sigreturn, sizeof sigreturn)
|
||||
&& memcmp (buf + 1, sigreturn, sizeof sigreturn)
|
||||
&& memcmp (buf, osigreturn, sizeof osigreturn)
|
||||
&& memcmp (buf + 1, osigreturn, sizeof osigreturn))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Assuming THIS_FRAME is for a BSD sigtramp routine, return the
|
||||
address of the associated sigcontext structure. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64obsd_sigcontext_addr (struct frame_info *this_frame)
|
||||
{
|
||||
CORE_ADDR pc = get_frame_pc (this_frame);
|
||||
ULONGEST offset = (pc & (amd64obsd_page_size - 1));
|
||||
|
||||
/* The %rsp register points at `struct sigcontext' upon entry of a
|
||||
signal trampoline. The relevant part of the trampoline is
|
||||
|
||||
call *%rax
|
||||
movq %rsp, %rdi
|
||||
pushq %rdi
|
||||
movq $SYS_sigreturn,%rax
|
||||
int $0x80
|
||||
|
||||
(see /usr/src/sys/arch/amd64/amd64/locore.S). The `pushq'
|
||||
instruction clobbers %rsp, but its value is saved in `%rdi'. */
|
||||
|
||||
if (offset > 5)
|
||||
return get_frame_register_unsigned (this_frame, AMD64_RDI_REGNUM);
|
||||
else
|
||||
return get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
||||
}
|
||||
|
||||
/* OpenBSD 3.5 or later. */
|
||||
|
||||
/* Mapping between the general-purpose registers in `struct reg'
|
||||
format and GDB's register cache layout. */
|
||||
|
||||
/* From <machine/reg.h>. */
|
||||
int amd64obsd_r_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %rax */
|
||||
13 * 8, /* %rbx */
|
||||
3 * 8, /* %rcx */
|
||||
2 * 8, /* %rdx */
|
||||
1 * 8, /* %rsi */
|
||||
0 * 8, /* %rdi */
|
||||
12 * 8, /* %rbp */
|
||||
15 * 8, /* %rsp */
|
||||
4 * 8, /* %r8 .. */
|
||||
5 * 8,
|
||||
6 * 8,
|
||||
7 * 8,
|
||||
8 * 8,
|
||||
9 * 8,
|
||||
10 * 8,
|
||||
11 * 8, /* ... %r15 */
|
||||
16 * 8, /* %rip */
|
||||
17 * 8, /* %eflags */
|
||||
18 * 8, /* %cs */
|
||||
19 * 8, /* %ss */
|
||||
20 * 8, /* %ds */
|
||||
21 * 8, /* %es */
|
||||
22 * 8, /* %fs */
|
||||
23 * 8 /* %gs */
|
||||
};
|
||||
|
||||
/* From <machine/signal.h>. */
|
||||
static int amd64obsd_sc_reg_offset[] =
|
||||
{
|
||||
14 * 8, /* %rax */
|
||||
13 * 8, /* %rbx */
|
||||
3 * 8, /* %rcx */
|
||||
2 * 8, /* %rdx */
|
||||
1 * 8, /* %rsi */
|
||||
0 * 8, /* %rdi */
|
||||
12 * 8, /* %rbp */
|
||||
24 * 8, /* %rsp */
|
||||
4 * 8, /* %r8 ... */
|
||||
5 * 8,
|
||||
6 * 8,
|
||||
7 * 8,
|
||||
8 * 8,
|
||||
9 * 8,
|
||||
10 * 8,
|
||||
11 * 8, /* ... %r15 */
|
||||
21 * 8, /* %rip */
|
||||
23 * 8, /* %eflags */
|
||||
22 * 8, /* %cs */
|
||||
25 * 8, /* %ss */
|
||||
18 * 8, /* %ds */
|
||||
17 * 8, /* %es */
|
||||
16 * 8, /* %fs */
|
||||
15 * 8 /* %gs */
|
||||
};
|
||||
|
||||
/* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c. */
|
||||
static int amd64obsd_uthread_reg_offset[] =
|
||||
{
|
||||
19 * 8, /* %rax */
|
||||
16 * 8, /* %rbx */
|
||||
18 * 8, /* %rcx */
|
||||
17 * 8, /* %rdx */
|
||||
14 * 8, /* %rsi */
|
||||
13 * 8, /* %rdi */
|
||||
15 * 8, /* %rbp */
|
||||
-1, /* %rsp */
|
||||
12 * 8, /* %r8 ... */
|
||||
11 * 8,
|
||||
10 * 8,
|
||||
9 * 8,
|
||||
8 * 8,
|
||||
7 * 8,
|
||||
6 * 8,
|
||||
5 * 8, /* ... %r15 */
|
||||
20 * 8, /* %rip */
|
||||
4 * 8, /* %eflags */
|
||||
21 * 8, /* %cs */
|
||||
-1, /* %ss */
|
||||
3 * 8, /* %ds */
|
||||
2 * 8, /* %es */
|
||||
1 * 8, /* %fs */
|
||||
0 * 8 /* %gs */
|
||||
};
|
||||
|
||||
/* Offset within the thread structure where we can find the saved
|
||||
stack pointer (%esp). */
|
||||
#define AMD64OBSD_UTHREAD_RSP_OFFSET 400
|
||||
|
||||
static void
|
||||
amd64obsd_supply_uthread (struct regcache *regcache,
|
||||
int regnum, CORE_ADDR addr)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
|
||||
CORE_ADDR sp = 0;
|
||||
gdb_byte buf[8];
|
||||
int i;
|
||||
|
||||
gdb_assert (regnum >= -1);
|
||||
|
||||
if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
|
||||
{
|
||||
int offset;
|
||||
|
||||
/* Fetch stack pointer from thread structure. */
|
||||
sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
|
||||
|
||||
/* Adjust the stack pointer such that it looks as if we just
|
||||
returned from _thread_machdep_switch. */
|
||||
offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
|
||||
store_unsigned_integer (buf, 8, byte_order, sp + offset);
|
||||
regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
|
||||
{
|
||||
if (amd64obsd_uthread_reg_offset[i] != -1
|
||||
&& (regnum == -1 || regnum == i))
|
||||
{
|
||||
/* Fetch stack pointer from thread structure (if we didn't
|
||||
do so already). */
|
||||
if (sp == 0)
|
||||
sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
|
||||
|
||||
/* Read the saved register from the stack frame. */
|
||||
read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
|
||||
regcache_raw_supply (regcache, i, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
amd64obsd_collect_uthread (const struct regcache *regcache,
|
||||
int regnum, CORE_ADDR addr)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
|
||||
CORE_ADDR sp = 0;
|
||||
gdb_byte buf[8];
|
||||
int i;
|
||||
|
||||
gdb_assert (regnum >= -1);
|
||||
|
||||
if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
|
||||
{
|
||||
int offset;
|
||||
|
||||
/* Calculate the stack pointer (frame pointer) that will be
|
||||
stored into the thread structure. */
|
||||
offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
|
||||
regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
|
||||
sp = extract_unsigned_integer (buf, 8, byte_order) - offset;
|
||||
|
||||
/* Store the stack pointer. */
|
||||
write_memory_unsigned_integer (sp_addr, 8, byte_order, sp);
|
||||
|
||||
/* The stack pointer was (potentially) modified. Make sure we
|
||||
build a proper stack frame. */
|
||||
regnum = -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
|
||||
{
|
||||
if (amd64obsd_uthread_reg_offset[i] != -1
|
||||
&& (regnum == -1 || regnum == i))
|
||||
{
|
||||
/* Fetch stack pointer from thread structure (if we didn't
|
||||
calculate it already). */
|
||||
if (sp == 0)
|
||||
sp = read_memory_unsigned_integer (sp_addr, 8, byte_order);
|
||||
|
||||
/* Write the register into the stack frame. */
|
||||
regcache_raw_collect (regcache, i, buf);
|
||||
write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Kernel debugging support. */
|
||||
|
||||
/* From <machine/frame.h>. Easy since `struct trapframe' matches
|
||||
`struct sigcontext'. */
|
||||
#define amd64obsd_tf_reg_offset amd64obsd_sc_reg_offset
|
||||
|
||||
static struct trad_frame_cache *
|
||||
amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (this_frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
struct trad_frame_cache *cache;
|
||||
CORE_ADDR func, sp, addr;
|
||||
ULONGEST cs;
|
||||
const char *name;
|
||||
int i;
|
||||
|
||||
if (*this_cache)
|
||||
return *this_cache;
|
||||
|
||||
cache = trad_frame_cache_zalloc (this_frame);
|
||||
*this_cache = cache;
|
||||
|
||||
func = get_frame_func (this_frame);
|
||||
sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
|
||||
|
||||
find_pc_partial_function (func, &name, NULL, NULL);
|
||||
if (name && strncmp (name, "Xintr", 5) == 0)
|
||||
addr = sp + 8; /* It's an interrupt frame. */
|
||||
else
|
||||
addr = sp;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
|
||||
if (amd64obsd_tf_reg_offset[i] != -1)
|
||||
trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);
|
||||
|
||||
/* Read %cs from trap frame. */
|
||||
addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
|
||||
cs = read_memory_unsigned_integer (addr, 8, byte_order);
|
||||
if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
|
||||
{
|
||||
/* Trap from user space; terminate backtrace. */
|
||||
trad_frame_set_id (cache, outer_frame_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Construct the frame ID using the function start. */
|
||||
trad_frame_set_id (cache, frame_id_build (sp + 16, func));
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
static void
|
||||
amd64obsd_trapframe_this_id (struct frame_info *this_frame,
|
||||
void **this_cache, struct frame_id *this_id)
|
||||
{
|
||||
struct trad_frame_cache *cache =
|
||||
amd64obsd_trapframe_cache (this_frame, this_cache);
|
||||
|
||||
trad_frame_get_id (cache, this_id);
|
||||
}
|
||||
|
||||
static struct value *
|
||||
amd64obsd_trapframe_prev_register (struct frame_info *this_frame,
|
||||
void **this_cache, int regnum)
|
||||
{
|
||||
struct trad_frame_cache *cache =
|
||||
amd64obsd_trapframe_cache (this_frame, this_cache);
|
||||
|
||||
return trad_frame_get_register (cache, this_frame, regnum);
|
||||
}
|
||||
|
||||
static int
|
||||
amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
|
||||
struct frame_info *this_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
ULONGEST cs;
|
||||
const char *name;
|
||||
|
||||
/* Check Current Privilege Level and bail out if we're not executing
|
||||
in kernel space. */
|
||||
cs = get_frame_register_unsigned (this_frame, AMD64_CS_REGNUM);
|
||||
if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
|
||||
return 0;
|
||||
|
||||
find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
|
||||
return (name && ((strcmp (name, "calltrap") == 0)
|
||||
|| (strcmp (name, "osyscall1") == 0)
|
||||
|| (strcmp (name, "Xsyscall") == 0)
|
||||
|| (strncmp (name, "Xintr", 5) == 0)));
|
||||
}
|
||||
|
||||
static const struct frame_unwind amd64obsd_trapframe_unwind = {
|
||||
/* FIXME: kettenis/20051219: This really is more like an interrupt
|
||||
frame, but SIGTRAMP_FRAME would print <signal handler called>,
|
||||
which really is not what we want here. */
|
||||
NORMAL_FRAME,
|
||||
default_frame_unwind_stop_reason,
|
||||
amd64obsd_trapframe_this_id,
|
||||
amd64obsd_trapframe_prev_register,
|
||||
NULL,
|
||||
amd64obsd_trapframe_sniffer
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
/* Initialize general-purpose register set details. */
|
||||
tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
|
||||
tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
|
||||
tdep->sizeof_gregset = 24 * 8;
|
||||
|
||||
tdep->jb_pc_offset = 7 * 8;
|
||||
|
||||
tdep->sigtramp_p = amd64obsd_sigtramp_p;
|
||||
tdep->sigcontext_addr = amd64obsd_sigcontext_addr;
|
||||
tdep->sc_reg_offset = amd64obsd_sc_reg_offset;
|
||||
tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);
|
||||
|
||||
/* OpenBSD provides a user-level threads implementation. */
|
||||
bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread);
|
||||
bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
|
||||
|
||||
/* OpenBSD uses SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_lp64_fetch_link_map_offsets);
|
||||
|
||||
/* Unwind kernel trap frames correctly. */
|
||||
frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
|
||||
}
|
||||
|
||||
/* Traditional (a.out) NetBSD-style core dumps. */
|
||||
|
||||
static void
|
||||
amd64obsd_core_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
amd64obsd_init_abi (info, gdbarch);
|
||||
|
||||
set_gdbarch_regset_from_core_section
|
||||
(gdbarch, amd64obsd_regset_from_core_section);
|
||||
}
|
||||
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64obsd_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_amd64obsd_tdep (void)
|
||||
{
|
||||
/* The OpenBSD/amd64 native dependent code makes this assumption. */
|
||||
gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == AMD64_NUM_GREGS);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi);
|
||||
|
||||
/* OpenBSD uses traditional (a.out) NetBSD-style core dumps. */
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
|
||||
GDB_OSABI_NETBSD_AOUT, amd64obsd_core_init_abi);
|
||||
}
|
||||
590
gdb/annotate.c
590
gdb/annotate.c
@@ -1,590 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "annotate.h"
|
||||
#include "value.h"
|
||||
#include "target.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "breakpoint.h"
|
||||
#include "observer.h"
|
||||
#include "inferior.h"
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
extern void _initialize_annotate (void);
|
||||
|
||||
static void print_value_flags (struct type *);
|
||||
|
||||
static void breakpoint_changed (struct breakpoint *b);
|
||||
|
||||
|
||||
void (*deprecated_annotate_signalled_hook) (void);
|
||||
void (*deprecated_annotate_signal_hook) (void);
|
||||
|
||||
/* Booleans indicating whether we've emitted certain notifications.
|
||||
Used to suppress useless repeated notifications until the next time
|
||||
we're ready to accept more commands. Reset whenever a prompt is
|
||||
displayed. */
|
||||
static int frames_invalid_emitted;
|
||||
static int breakpoints_invalid_emitted;
|
||||
|
||||
/* True if the target can async, and a synchronous execution command
|
||||
is not in progress. If true, input is accepted, so don't suppress
|
||||
annotations. */
|
||||
|
||||
static int
|
||||
async_background_execution_p (void)
|
||||
{
|
||||
return (target_can_async_p () && !sync_execution);
|
||||
}
|
||||
|
||||
static void
|
||||
print_value_flags (struct type *t)
|
||||
{
|
||||
if (can_dereference (t))
|
||||
printf_filtered (("*"));
|
||||
else
|
||||
printf_filtered (("-"));
|
||||
}
|
||||
|
||||
static void
|
||||
annotate_breakpoints_invalid (void)
|
||||
{
|
||||
if (annotation_level == 2
|
||||
&& (!breakpoints_invalid_emitted
|
||||
|| async_background_execution_p ()))
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered (("\n\032\032breakpoints-invalid\n"));
|
||||
breakpoints_invalid_emitted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032breakpoint %d\n"), num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_catchpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032catchpoint %d\n"), num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_watchpoint (int num)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032watchpoint %d\n"), num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_starting (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032starting\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_stopped (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032stopped\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_exited (int exitstatus)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032exited %d\n"), exitstatus);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signalled (void)
|
||||
{
|
||||
if (deprecated_annotate_signalled_hook)
|
||||
deprecated_annotate_signalled_hook ();
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032signalled\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_name (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032signal-name\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_name_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032signal-name-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_string (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032signal-string\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_string_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032signal-string-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal (void)
|
||||
{
|
||||
if (deprecated_annotate_signal_hook)
|
||||
deprecated_annotate_signal_hook ();
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032signal\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_headers (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032breakpoints-headers\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field (int num)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032field %d\n"), num);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_table (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032breakpoints-table\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_record (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032record\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_breakpoints_table_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032breakpoints-table-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frames_invalid (void)
|
||||
{
|
||||
if (annotation_level == 2
|
||||
&& (!frames_invalid_emitted
|
||||
|| async_background_execution_p ()))
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered (("\n\032\032frames-invalid\n"));
|
||||
frames_invalid_emitted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_new_thread (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_unfiltered (("\n\032\032new-thread\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_thread_changed (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
{
|
||||
printf_unfiltered (("\n\032\032thread-changed\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_begin (struct type *type)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032field-begin "));
|
||||
print_value_flags (type);
|
||||
printf_filtered (("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_name_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032field-name-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_value (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032field-value\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_field_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032field-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_quit (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032quit\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_error (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032error\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_error_begin (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
fprintf_filtered (gdb_stderr, "\n\032\032error-begin\n");
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_begin (int histindex, struct type *type)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032value-history-begin %d "), histindex);
|
||||
print_value_flags (type);
|
||||
printf_filtered (("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_begin (struct type *type)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032value-begin "));
|
||||
print_value_flags (type);
|
||||
printf_filtered (("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_value (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032value-history-value\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_history_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032value-history-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_value_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032value-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_begin (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-begin\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_number_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-number-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_format (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-format\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_expression (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-expression\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_expression_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-expression-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_value (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-value\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_display_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032display-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_begin (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032arg-begin\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_name_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032arg-name-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_value (struct type *type)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032arg-value "));
|
||||
print_value_flags (type);
|
||||
printf_filtered (("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_arg_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032arg-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_source (char *filename, int line, int character, int mid,
|
||||
struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032source "));
|
||||
else
|
||||
printf_filtered (("\032\032"));
|
||||
|
||||
printf_filtered (("%s:%d:%d:%s:%s\n"), filename, line, character,
|
||||
mid ? "middle" : "beg", paddress (gdbarch, pc));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_begin (int level, struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032frame-begin %d %s\n"),
|
||||
level, paddress (gdbarch, pc));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_function_call (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032function-call\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_signal_handler_caller (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032signal-handler-caller\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_address (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-address\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_address_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-address-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_function_name (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-function-name\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_args (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-args\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_begin (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-source-begin\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_file (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-source-file\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_file_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-source-file-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_line (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-source-line\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_source_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-source-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_where (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-where\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_frame_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032frame-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_array_section_begin (int idx, struct type *elttype)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032array-section-begin %d "), idx);
|
||||
print_value_flags (elttype);
|
||||
printf_filtered (("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt_rep (unsigned int repcount)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032elt-rep %u\n"), repcount);
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt_rep_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032elt-rep-end\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_elt (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032elt\n"));
|
||||
}
|
||||
|
||||
void
|
||||
annotate_array_section_end (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
printf_filtered (("\n\032\032array-section-end\n"));
|
||||
}
|
||||
|
||||
/* Called when GDB is about to display the prompt. Used to reset
|
||||
annotation suppression whenever we're ready to accept new
|
||||
frontend/user commands. */
|
||||
|
||||
void
|
||||
annotate_display_prompt (void)
|
||||
{
|
||||
frames_invalid_emitted = 0;
|
||||
breakpoints_invalid_emitted = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
breakpoint_changed (struct breakpoint *b)
|
||||
{
|
||||
if (b->number <= 0)
|
||||
return;
|
||||
|
||||
annotate_breakpoints_invalid ();
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_annotate (void)
|
||||
{
|
||||
observer_attach_breakpoint_created (breakpoint_changed);
|
||||
observer_attach_breakpoint_deleted (breakpoint_changed);
|
||||
observer_attach_breakpoint_modified (breakpoint_changed);
|
||||
}
|
||||
102
gdb/annotate.h
102
gdb/annotate.h
@@ -1,102 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
|
||||
extern void annotate_breakpoint (int);
|
||||
extern void annotate_catchpoint (int);
|
||||
extern void annotate_watchpoint (int);
|
||||
extern void annotate_starting (void);
|
||||
extern void annotate_stopped (void);
|
||||
extern void annotate_exited (int);
|
||||
extern void annotate_signalled (void);
|
||||
extern void annotate_signal_name (void);
|
||||
extern void annotate_signal_name_end (void);
|
||||
extern void annotate_signal_string (void);
|
||||
extern void annotate_signal_string_end (void);
|
||||
extern void annotate_signal (void);
|
||||
|
||||
extern void annotate_breakpoints_headers (void);
|
||||
extern void annotate_field (int);
|
||||
extern void annotate_breakpoints_table (void);
|
||||
extern void annotate_record (void);
|
||||
extern void annotate_breakpoints_table_end (void);
|
||||
|
||||
extern void annotate_frames_invalid (void);
|
||||
extern void annotate_new_thread (void);
|
||||
extern void annotate_thread_changed (void);
|
||||
|
||||
extern void annotate_display_prompt (void);
|
||||
|
||||
struct type;
|
||||
|
||||
extern void annotate_field_begin (struct type *);
|
||||
extern void annotate_field_name_end (void);
|
||||
extern void annotate_field_value (void);
|
||||
extern void annotate_field_end (void);
|
||||
|
||||
extern void annotate_quit (void);
|
||||
extern void annotate_error (void);
|
||||
extern void annotate_error_begin (void);
|
||||
|
||||
extern void annotate_value_history_begin (int, struct type *);
|
||||
extern void annotate_value_begin (struct type *);
|
||||
extern void annotate_value_history_value (void);
|
||||
extern void annotate_value_history_end (void);
|
||||
extern void annotate_value_end (void);
|
||||
|
||||
extern void annotate_display_begin (void);
|
||||
extern void annotate_display_number_end (void);
|
||||
extern void annotate_display_format (void);
|
||||
extern void annotate_display_expression (void);
|
||||
extern void annotate_display_expression_end (void);
|
||||
extern void annotate_display_value (void);
|
||||
extern void annotate_display_end (void);
|
||||
|
||||
extern void annotate_arg_begin (void);
|
||||
extern void annotate_arg_name_end (void);
|
||||
extern void annotate_arg_value (struct type *);
|
||||
extern void annotate_arg_end (void);
|
||||
|
||||
extern void annotate_source (char *, int, int, int,
|
||||
struct gdbarch *, CORE_ADDR);
|
||||
|
||||
extern void annotate_frame_begin (int, struct gdbarch *, CORE_ADDR);
|
||||
extern void annotate_function_call (void);
|
||||
extern void annotate_signal_handler_caller (void);
|
||||
extern void annotate_frame_address (void);
|
||||
extern void annotate_frame_address_end (void);
|
||||
extern void annotate_frame_function_name (void);
|
||||
extern void annotate_frame_args (void);
|
||||
extern void annotate_frame_source_begin (void);
|
||||
extern void annotate_frame_source_file (void);
|
||||
extern void annotate_frame_source_file_end (void);
|
||||
extern void annotate_frame_source_line (void);
|
||||
extern void annotate_frame_source_end (void);
|
||||
extern void annotate_frame_where (void);
|
||||
extern void annotate_frame_end (void);
|
||||
|
||||
extern void annotate_array_section_begin (int, struct type *);
|
||||
extern void annotate_elt_rep (unsigned int);
|
||||
extern void annotate_elt_rep_end (void);
|
||||
extern void annotate_elt (void);
|
||||
extern void annotate_array_section_end (void);
|
||||
|
||||
extern void (*deprecated_annotate_signalled_hook) (void);
|
||||
extern void (*deprecated_annotate_signal_hook) (void);
|
||||
821
gdb/arch-utils.c
821
gdb/arch-utils.c
@@ -1,821 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#include "arch-utils.h"
|
||||
#include "buildsym.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "inferior.h" /* enum CALL_DUMMY_LOCATION et al. */
|
||||
#include "gdb_string.h"
|
||||
#include "regcache.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "sim-regno.h"
|
||||
#include "gdbcore.h"
|
||||
#include "osabi.h"
|
||||
#include "target-descriptions.h"
|
||||
#include "objfiles.h"
|
||||
#include "language.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "floatformat.h"
|
||||
|
||||
|
||||
struct displaced_step_closure *
|
||||
simple_displaced_step_copy_insn (struct gdbarch *gdbarch,
|
||||
CORE_ADDR from, CORE_ADDR to,
|
||||
struct regcache *regs)
|
||||
{
|
||||
size_t len = gdbarch_max_insn_length (gdbarch);
|
||||
gdb_byte *buf = xmalloc (len);
|
||||
|
||||
read_memory (from, buf, len);
|
||||
write_memory (to, buf, len);
|
||||
|
||||
if (debug_displaced)
|
||||
{
|
||||
fprintf_unfiltered (gdb_stdlog, "displaced: copy %s->%s: ",
|
||||
paddress (gdbarch, from), paddress (gdbarch, to));
|
||||
displaced_step_dump_bytes (gdb_stdlog, buf, len);
|
||||
}
|
||||
|
||||
return (struct displaced_step_closure *) buf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
simple_displaced_step_free_closure (struct gdbarch *gdbarch,
|
||||
struct displaced_step_closure *closure)
|
||||
{
|
||||
xfree (closure);
|
||||
}
|
||||
|
||||
int
|
||||
default_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
|
||||
struct displaced_step_closure *closure)
|
||||
{
|
||||
return !gdbarch_software_single_step_p (gdbarch);
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
displaced_step_at_entry_point (struct gdbarch *gdbarch)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
int bp_len;
|
||||
|
||||
addr = entry_point_address ();
|
||||
|
||||
/* Inferior calls also use the entry point as a breakpoint location.
|
||||
We don't want displaced stepping to interfere with those
|
||||
breakpoints, so leave space. */
|
||||
gdbarch_breakpoint_from_pc (gdbarch, &addr, &bp_len);
|
||||
addr += bp_len * 2;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
int
|
||||
legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
/* Only makes sense to supply raw registers. */
|
||||
gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
|
||||
/* NOTE: cagney/2002-05-13: The old code did it this way and it is
|
||||
suspected that some GDB/SIM combinations may rely on this
|
||||
behavour. The default should be one2one_register_sim_regno
|
||||
(below). */
|
||||
if (gdbarch_register_name (gdbarch, regnum) != NULL
|
||||
&& gdbarch_register_name (gdbarch, regnum)[0] != '\0')
|
||||
return regnum;
|
||||
else
|
||||
return LEGACY_SIM_REGNO_IGNORE;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
generic_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
generic_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_in_solib_return_trampoline (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper functions for gdbarch_inner_than */
|
||||
|
||||
int
|
||||
core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs)
|
||||
{
|
||||
return (lhs < rhs);
|
||||
}
|
||||
|
||||
int
|
||||
core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs)
|
||||
{
|
||||
return (lhs > rhs);
|
||||
}
|
||||
|
||||
/* Misc helper functions for targets. */
|
||||
|
||||
CORE_ADDR
|
||||
core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
convert_from_func_ptr_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr,
|
||||
struct target_ops *targ)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
int
|
||||
no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg)
|
||||
{
|
||||
return reg;
|
||||
}
|
||||
|
||||
void
|
||||
default_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
default_coff_make_msymbol_special (int val, struct minimal_symbol *msym)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
cannot_register_not (struct gdbarch *gdbarch, int regnum)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Legacy version of target_virtual_frame_pointer(). Assumes that
|
||||
there is an gdbarch_deprecated_fp_regnum and that it is the same,
|
||||
cooked or raw. */
|
||||
|
||||
void
|
||||
legacy_virtual_frame_pointer (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc,
|
||||
int *frame_regnum,
|
||||
LONGEST *frame_offset)
|
||||
{
|
||||
/* FIXME: cagney/2002-09-13: This code is used when identifying the
|
||||
frame pointer of the current PC. It is assuming that a single
|
||||
register and an offset can determine this. I think it should
|
||||
instead generate a byte code expression as that would work better
|
||||
with things like Dwarf2's CFI. */
|
||||
if (gdbarch_deprecated_fp_regnum (gdbarch) >= 0
|
||||
&& gdbarch_deprecated_fp_regnum (gdbarch)
|
||||
< gdbarch_num_regs (gdbarch))
|
||||
*frame_regnum = gdbarch_deprecated_fp_regnum (gdbarch);
|
||||
else if (gdbarch_sp_regnum (gdbarch) >= 0
|
||||
&& gdbarch_sp_regnum (gdbarch)
|
||||
< gdbarch_num_regs (gdbarch))
|
||||
*frame_regnum = gdbarch_sp_regnum (gdbarch);
|
||||
else
|
||||
/* Should this be an internal error? I guess so, it is reflecting
|
||||
an architectural limitation in the current design. */
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("No virtual frame pointer available"));
|
||||
*frame_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
|
||||
struct type *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
generic_instruction_nullified (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
default_remote_register_number (struct gdbarch *gdbarch,
|
||||
int regno)
|
||||
{
|
||||
return regno;
|
||||
}
|
||||
|
||||
|
||||
/* Functions to manipulate the endianness of the target. */
|
||||
|
||||
static int target_byte_order_user = BFD_ENDIAN_UNKNOWN;
|
||||
|
||||
static const char endian_big[] = "big";
|
||||
static const char endian_little[] = "little";
|
||||
static const char endian_auto[] = "auto";
|
||||
static const char *const endian_enum[] =
|
||||
{
|
||||
endian_big,
|
||||
endian_little,
|
||||
endian_auto,
|
||||
NULL,
|
||||
};
|
||||
static const char *set_endian_string;
|
||||
|
||||
enum bfd_endian
|
||||
selected_byte_order (void)
|
||||
{
|
||||
return target_byte_order_user;
|
||||
}
|
||||
|
||||
/* Called by ``show endian''. */
|
||||
|
||||
static void
|
||||
show_endian (struct ui_file *file, int from_tty, struct cmd_list_element *c,
|
||||
const char *value)
|
||||
{
|
||||
if (target_byte_order_user == BFD_ENDIAN_UNKNOWN)
|
||||
if (gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG)
|
||||
fprintf_unfiltered (file, _("The target endianness is set automatically "
|
||||
"(currently big endian)\n"));
|
||||
else
|
||||
fprintf_unfiltered (file, _("The target endianness is set automatically "
|
||||
"(currently little endian)\n"));
|
||||
else
|
||||
if (target_byte_order_user == BFD_ENDIAN_BIG)
|
||||
fprintf_unfiltered (file,
|
||||
_("The target is assumed to be big endian\n"));
|
||||
else
|
||||
fprintf_unfiltered (file,
|
||||
_("The target is assumed to be little endian\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
set_endian (char *ignore_args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
|
||||
gdbarch_info_init (&info);
|
||||
|
||||
if (set_endian_string == endian_auto)
|
||||
{
|
||||
target_byte_order_user = BFD_ENDIAN_UNKNOWN;
|
||||
if (! gdbarch_update_p (info))
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("set_endian: architecture update failed"));
|
||||
}
|
||||
else if (set_endian_string == endian_little)
|
||||
{
|
||||
info.byte_order = BFD_ENDIAN_LITTLE;
|
||||
if (! gdbarch_update_p (info))
|
||||
printf_unfiltered (_("Little endian target not supported by GDB\n"));
|
||||
else
|
||||
target_byte_order_user = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
else if (set_endian_string == endian_big)
|
||||
{
|
||||
info.byte_order = BFD_ENDIAN_BIG;
|
||||
if (! gdbarch_update_p (info))
|
||||
printf_unfiltered (_("Big endian target not supported by GDB\n"));
|
||||
else
|
||||
target_byte_order_user = BFD_ENDIAN_BIG;
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("set_endian: bad value"));
|
||||
|
||||
show_endian (gdb_stdout, from_tty, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Given SELECTED, a currently selected BFD architecture, and
|
||||
TARGET_DESC, the current target description, return what
|
||||
architecture to use.
|
||||
|
||||
SELECTED may be NULL, in which case we return the architecture
|
||||
associated with TARGET_DESC. If SELECTED specifies a variant
|
||||
of the architecture associtated with TARGET_DESC, return the
|
||||
more specific of the two.
|
||||
|
||||
If SELECTED is a different architecture, but it is accepted as
|
||||
compatible by the target, we can use the target architecture.
|
||||
|
||||
If SELECTED is obviously incompatible, warn the user. */
|
||||
|
||||
static const struct bfd_arch_info *
|
||||
choose_architecture_for_target (const struct target_desc *target_desc,
|
||||
const struct bfd_arch_info *selected)
|
||||
{
|
||||
const struct bfd_arch_info *from_target = tdesc_architecture (target_desc);
|
||||
const struct bfd_arch_info *compat1, *compat2;
|
||||
|
||||
if (selected == NULL)
|
||||
return from_target;
|
||||
|
||||
if (from_target == NULL)
|
||||
return selected;
|
||||
|
||||
/* struct bfd_arch_info objects are singletons: that is, there's
|
||||
supposed to be exactly one instance for a given machine. So you
|
||||
can tell whether two are equivalent by comparing pointers. */
|
||||
if (from_target == selected)
|
||||
return selected;
|
||||
|
||||
/* BFD's 'A->compatible (A, B)' functions return zero if A and B are
|
||||
incompatible. But if they are compatible, it returns the 'more
|
||||
featureful' of the two arches. That is, if A can run code
|
||||
written for B, but B can't run code written for A, then it'll
|
||||
return A.
|
||||
|
||||
Some targets (e.g. MIPS as of 2006-12-04) don't fully
|
||||
implement this, instead always returning NULL or the first
|
||||
argument. We detect that case by checking both directions. */
|
||||
|
||||
compat1 = selected->compatible (selected, from_target);
|
||||
compat2 = from_target->compatible (from_target, selected);
|
||||
|
||||
if (compat1 == NULL && compat2 == NULL)
|
||||
{
|
||||
/* BFD considers the architectures incompatible. Check our
|
||||
target description whether it accepts SELECTED as compatible
|
||||
anyway. */
|
||||
if (tdesc_compatible_p (target_desc, selected))
|
||||
return from_target;
|
||||
|
||||
warning (_("Selected architecture %s is not compatible "
|
||||
"with reported target architecture %s"),
|
||||
selected->printable_name, from_target->printable_name);
|
||||
return selected;
|
||||
}
|
||||
|
||||
if (compat1 == NULL)
|
||||
return compat2;
|
||||
if (compat2 == NULL)
|
||||
return compat1;
|
||||
if (compat1 == compat2)
|
||||
return compat1;
|
||||
|
||||
/* If the two didn't match, but one of them was a default
|
||||
architecture, assume the more specific one is correct. This
|
||||
handles the case where an executable or target description just
|
||||
says "mips", but the other knows which MIPS variant. */
|
||||
if (compat1->the_default)
|
||||
return compat2;
|
||||
if (compat2->the_default)
|
||||
return compat1;
|
||||
|
||||
/* We have no idea which one is better. This is a bug, but not
|
||||
a critical problem; warn the user. */
|
||||
warning (_("Selected architecture %s is ambiguous with "
|
||||
"reported target architecture %s"),
|
||||
selected->printable_name, from_target->printable_name);
|
||||
return selected;
|
||||
}
|
||||
|
||||
/* Functions to manipulate the architecture of the target. */
|
||||
|
||||
enum set_arch { set_arch_auto, set_arch_manual };
|
||||
|
||||
static const struct bfd_arch_info *target_architecture_user;
|
||||
|
||||
static const char *set_architecture_string;
|
||||
|
||||
const char *
|
||||
selected_architecture_name (void)
|
||||
{
|
||||
if (target_architecture_user == NULL)
|
||||
return NULL;
|
||||
else
|
||||
return set_architecture_string;
|
||||
}
|
||||
|
||||
/* Called if the user enters ``show architecture'' without an
|
||||
argument. */
|
||||
|
||||
static void
|
||||
show_architecture (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
{
|
||||
if (target_architecture_user == NULL)
|
||||
fprintf_filtered (file, _("The target architecture is set "
|
||||
"automatically (currently %s)\n"),
|
||||
gdbarch_bfd_arch_info (get_current_arch ())->printable_name);
|
||||
else
|
||||
fprintf_filtered (file, _("The target architecture is assumed to be %s\n"),
|
||||
set_architecture_string);
|
||||
}
|
||||
|
||||
|
||||
/* Called if the user enters ``set architecture'' with or without an
|
||||
argument. */
|
||||
|
||||
static void
|
||||
set_architecture (char *ignore_args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
|
||||
gdbarch_info_init (&info);
|
||||
|
||||
if (strcmp (set_architecture_string, "auto") == 0)
|
||||
{
|
||||
target_architecture_user = NULL;
|
||||
if (!gdbarch_update_p (info))
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("could not select an architecture automatically"));
|
||||
}
|
||||
else
|
||||
{
|
||||
info.bfd_arch_info = bfd_scan_arch (set_architecture_string);
|
||||
if (info.bfd_arch_info == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("set_architecture: bfd_scan_arch failed"));
|
||||
if (gdbarch_update_p (info))
|
||||
target_architecture_user = info.bfd_arch_info;
|
||||
else
|
||||
printf_unfiltered (_("Architecture `%s' not recognized.\n"),
|
||||
set_architecture_string);
|
||||
}
|
||||
show_architecture (gdb_stdout, from_tty, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Try to select a global architecture that matches "info". Return
|
||||
non-zero if the attempt succeeds. */
|
||||
int
|
||||
gdbarch_update_p (struct gdbarch_info info)
|
||||
{
|
||||
struct gdbarch *new_gdbarch;
|
||||
|
||||
/* Check for the current file. */
|
||||
if (info.abfd == NULL)
|
||||
info.abfd = exec_bfd;
|
||||
if (info.abfd == NULL)
|
||||
info.abfd = core_bfd;
|
||||
|
||||
/* Check for the current target description. */
|
||||
if (info.target_desc == NULL)
|
||||
info.target_desc = target_current_description ();
|
||||
|
||||
new_gdbarch = gdbarch_find_by_info (info);
|
||||
|
||||
/* If there no architecture by that name, reject the request. */
|
||||
if (new_gdbarch == NULL)
|
||||
{
|
||||
if (gdbarch_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
|
||||
"Architecture not found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If it is the same old architecture, accept the request (but don't
|
||||
swap anything). */
|
||||
if (new_gdbarch == target_gdbarch ())
|
||||
{
|
||||
if (gdbarch_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
|
||||
"Architecture %s (%s) unchanged\n",
|
||||
host_address_to_string (new_gdbarch),
|
||||
gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* It's a new architecture, swap it in. */
|
||||
if (gdbarch_debug)
|
||||
fprintf_unfiltered (gdb_stdlog, "gdbarch_update_p: "
|
||||
"New architecture %s (%s) selected\n",
|
||||
host_address_to_string (new_gdbarch),
|
||||
gdbarch_bfd_arch_info (new_gdbarch)->printable_name);
|
||||
set_target_gdbarch (new_gdbarch);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return the architecture for ABFD. If no suitable architecture
|
||||
could be find, return NULL. */
|
||||
|
||||
struct gdbarch *
|
||||
gdbarch_from_bfd (bfd *abfd)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
gdbarch_info_init (&info);
|
||||
|
||||
info.abfd = abfd;
|
||||
return gdbarch_find_by_info (info);
|
||||
}
|
||||
|
||||
/* Set the dynamic target-system-dependent parameters (architecture,
|
||||
byte-order) using information found in the BFD */
|
||||
|
||||
void
|
||||
set_gdbarch_from_file (bfd *abfd)
|
||||
{
|
||||
struct gdbarch_info info;
|
||||
struct gdbarch *gdbarch;
|
||||
|
||||
gdbarch_info_init (&info);
|
||||
info.abfd = abfd;
|
||||
info.target_desc = target_current_description ();
|
||||
gdbarch = gdbarch_find_by_info (info);
|
||||
|
||||
if (gdbarch == NULL)
|
||||
error (_("Architecture of file not recognized."));
|
||||
set_target_gdbarch (gdbarch);
|
||||
}
|
||||
|
||||
/* Initialize the current architecture. Update the ``set
|
||||
architecture'' command so that it specifies a list of valid
|
||||
architectures. */
|
||||
|
||||
#ifdef DEFAULT_BFD_ARCH
|
||||
extern const bfd_arch_info_type DEFAULT_BFD_ARCH;
|
||||
static const bfd_arch_info_type *default_bfd_arch = &DEFAULT_BFD_ARCH;
|
||||
#else
|
||||
static const bfd_arch_info_type *default_bfd_arch;
|
||||
#endif
|
||||
|
||||
#ifdef DEFAULT_BFD_VEC
|
||||
extern const bfd_target DEFAULT_BFD_VEC;
|
||||
static const bfd_target *default_bfd_vec = &DEFAULT_BFD_VEC;
|
||||
#else
|
||||
static const bfd_target *default_bfd_vec;
|
||||
#endif
|
||||
|
||||
static int default_byte_order = BFD_ENDIAN_UNKNOWN;
|
||||
|
||||
void
|
||||
initialize_current_architecture (void)
|
||||
{
|
||||
const char **arches = gdbarch_printable_names ();
|
||||
struct gdbarch_info info;
|
||||
|
||||
/* determine a default architecture and byte order. */
|
||||
gdbarch_info_init (&info);
|
||||
|
||||
/* Find a default architecture. */
|
||||
if (default_bfd_arch == NULL)
|
||||
{
|
||||
/* Choose the architecture by taking the first one
|
||||
alphabetically. */
|
||||
const char *chosen = arches[0];
|
||||
const char **arch;
|
||||
for (arch = arches; *arch != NULL; arch++)
|
||||
{
|
||||
if (strcmp (*arch, chosen) < 0)
|
||||
chosen = *arch;
|
||||
}
|
||||
if (chosen == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("initialize_current_architecture: No arch"));
|
||||
default_bfd_arch = bfd_scan_arch (chosen);
|
||||
if (default_bfd_arch == NULL)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("initialize_current_architecture: Arch not found"));
|
||||
}
|
||||
|
||||
info.bfd_arch_info = default_bfd_arch;
|
||||
|
||||
/* Take several guesses at a byte order. */
|
||||
if (default_byte_order == BFD_ENDIAN_UNKNOWN
|
||||
&& default_bfd_vec != NULL)
|
||||
{
|
||||
/* Extract BFD's default vector's byte order. */
|
||||
switch (default_bfd_vec->byteorder)
|
||||
{
|
||||
case BFD_ENDIAN_BIG:
|
||||
default_byte_order = BFD_ENDIAN_BIG;
|
||||
break;
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
default_byte_order = BFD_ENDIAN_LITTLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (default_byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
{
|
||||
/* look for ``*el-*'' in the target name. */
|
||||
const char *chp;
|
||||
chp = strchr (target_name, '-');
|
||||
if (chp != NULL
|
||||
&& chp - 2 >= target_name
|
||||
&& strncmp (chp - 2, "el", 2) == 0)
|
||||
default_byte_order = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
if (default_byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
{
|
||||
/* Wire it to big-endian!!! */
|
||||
default_byte_order = BFD_ENDIAN_BIG;
|
||||
}
|
||||
|
||||
info.byte_order = default_byte_order;
|
||||
info.byte_order_for_code = info.byte_order;
|
||||
|
||||
if (! gdbarch_update_p (info))
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("initialize_current_architecture: Selection of "
|
||||
"initial architecture failed"));
|
||||
|
||||
/* Create the ``set architecture'' command appending ``auto'' to the
|
||||
list of architectures. */
|
||||
{
|
||||
/* Append ``auto''. */
|
||||
int nr;
|
||||
for (nr = 0; arches[nr] != NULL; nr++);
|
||||
arches = xrealloc (arches, sizeof (char*) * (nr + 2));
|
||||
arches[nr + 0] = "auto";
|
||||
arches[nr + 1] = NULL;
|
||||
add_setshow_enum_cmd ("architecture", class_support,
|
||||
arches, &set_architecture_string,
|
||||
_("Set architecture of target."),
|
||||
_("Show architecture of target."), NULL,
|
||||
set_architecture, show_architecture,
|
||||
&setlist, &showlist);
|
||||
add_alias_cmd ("processor", "architecture", class_support, 1, &setlist);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a gdbarch info to values that will be automatically
|
||||
overridden. Note: Originally, this ``struct info'' was initialized
|
||||
using memset(0). Unfortunately, that ran into problems, namely
|
||||
BFD_ENDIAN_BIG is zero. An explicit initialization function that
|
||||
can explicitly set each field to a well defined value is used. */
|
||||
|
||||
void
|
||||
gdbarch_info_init (struct gdbarch_info *info)
|
||||
{
|
||||
memset (info, 0, sizeof (struct gdbarch_info));
|
||||
info->byte_order = BFD_ENDIAN_UNKNOWN;
|
||||
info->byte_order_for_code = info->byte_order;
|
||||
info->osabi = GDB_OSABI_UNINITIALIZED;
|
||||
}
|
||||
|
||||
/* Similar to init, but this time fill in the blanks. Information is
|
||||
obtained from the global "set ..." options and explicitly
|
||||
initialized INFO fields. */
|
||||
|
||||
void
|
||||
gdbarch_info_fill (struct gdbarch_info *info)
|
||||
{
|
||||
/* "(gdb) set architecture ...". */
|
||||
if (info->bfd_arch_info == NULL
|
||||
&& target_architecture_user)
|
||||
info->bfd_arch_info = target_architecture_user;
|
||||
/* From the file. */
|
||||
if (info->bfd_arch_info == NULL
|
||||
&& info->abfd != NULL
|
||||
&& bfd_get_arch (info->abfd) != bfd_arch_unknown
|
||||
&& bfd_get_arch (info->abfd) != bfd_arch_obscure)
|
||||
info->bfd_arch_info = bfd_get_arch_info (info->abfd);
|
||||
/* From the target. */
|
||||
if (info->target_desc != NULL)
|
||||
info->bfd_arch_info = choose_architecture_for_target
|
||||
(info->target_desc, info->bfd_arch_info);
|
||||
/* From the default. */
|
||||
if (info->bfd_arch_info == NULL)
|
||||
info->bfd_arch_info = default_bfd_arch;
|
||||
|
||||
/* "(gdb) set byte-order ...". */
|
||||
if (info->byte_order == BFD_ENDIAN_UNKNOWN
|
||||
&& target_byte_order_user != BFD_ENDIAN_UNKNOWN)
|
||||
info->byte_order = target_byte_order_user;
|
||||
/* From the INFO struct. */
|
||||
if (info->byte_order == BFD_ENDIAN_UNKNOWN
|
||||
&& info->abfd != NULL)
|
||||
info->byte_order = (bfd_big_endian (info->abfd) ? BFD_ENDIAN_BIG
|
||||
: bfd_little_endian (info->abfd) ? BFD_ENDIAN_LITTLE
|
||||
: BFD_ENDIAN_UNKNOWN);
|
||||
/* From the default. */
|
||||
if (info->byte_order == BFD_ENDIAN_UNKNOWN)
|
||||
info->byte_order = default_byte_order;
|
||||
info->byte_order_for_code = info->byte_order;
|
||||
|
||||
/* "(gdb) set osabi ...". Handled by gdbarch_lookup_osabi. */
|
||||
/* From the manual override, or from file. */
|
||||
if (info->osabi == GDB_OSABI_UNINITIALIZED)
|
||||
info->osabi = gdbarch_lookup_osabi (info->abfd);
|
||||
/* From the target. */
|
||||
if (info->osabi == GDB_OSABI_UNKNOWN && info->target_desc != NULL)
|
||||
info->osabi = tdesc_osabi (info->target_desc);
|
||||
/* From the configured default. */
|
||||
#ifdef GDB_OSABI_DEFAULT
|
||||
if (info->osabi == GDB_OSABI_UNKNOWN)
|
||||
info->osabi = GDB_OSABI_DEFAULT;
|
||||
#endif
|
||||
|
||||
/* Must have at least filled in the architecture. */
|
||||
gdb_assert (info->bfd_arch_info != NULL);
|
||||
}
|
||||
|
||||
/* Return "current" architecture. If the target is running, this is
|
||||
the architecture of the selected frame. Otherwise, the "current"
|
||||
architecture defaults to the target architecture.
|
||||
|
||||
This function should normally be called solely by the command
|
||||
interpreter routines to determine the architecture to execute a
|
||||
command in. */
|
||||
struct gdbarch *
|
||||
get_current_arch (void)
|
||||
{
|
||||
if (has_stack_frames ())
|
||||
return get_frame_arch (get_selected_frame (NULL));
|
||||
else
|
||||
return target_gdbarch ();
|
||||
}
|
||||
|
||||
int
|
||||
default_has_shared_address_space (struct gdbarch *gdbarch)
|
||||
{
|
||||
/* Simply say no. In most unix-like targets each inferior/process
|
||||
has its own address space. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
|
||||
CORE_ADDR addr, int *isize, char **msg)
|
||||
{
|
||||
/* We don't know if maybe the target has some way to do fast
|
||||
tracepoints that doesn't need gdbarch, so always say yes. */
|
||||
if (msg)
|
||||
*msg = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
default_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
|
||||
int *kindptr)
|
||||
{
|
||||
gdbarch_breakpoint_from_pc (gdbarch, pcptr, kindptr);
|
||||
}
|
||||
|
||||
void
|
||||
default_gen_return_address (struct gdbarch *gdbarch,
|
||||
struct agent_expr *ax, struct axs_value *value,
|
||||
CORE_ADDR scope)
|
||||
{
|
||||
error (_("This architecture has no method to collect a return address."));
|
||||
}
|
||||
|
||||
int
|
||||
default_return_in_first_hidden_param_p (struct gdbarch *gdbarch,
|
||||
struct type *type)
|
||||
{
|
||||
/* Usually, the return value's address is stored the in the "first hidden"
|
||||
parameter if the return value should be passed by reference, as
|
||||
specified in ABI. */
|
||||
return language_pass_by_reference (type);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
/* -Wmissing-prototypes */
|
||||
extern initialize_file_ftype _initialize_gdbarch_utils;
|
||||
|
||||
void
|
||||
_initialize_gdbarch_utils (void)
|
||||
{
|
||||
add_setshow_enum_cmd ("endian", class_support,
|
||||
endian_enum, &set_endian_string,
|
||||
_("Set endianness of target."),
|
||||
_("Show endianness of target."),
|
||||
NULL, set_endian, show_endian,
|
||||
&setlist, &showlist);
|
||||
}
|
||||
173
gdb/arch-utils.h
173
gdb/arch-utils.h
@@ -1,173 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1998-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GDBARCH_UTILS_H
|
||||
#define GDBARCH_UTILS_H
|
||||
|
||||
struct gdbarch;
|
||||
struct frame_info;
|
||||
struct minimal_symbol;
|
||||
struct type;
|
||||
struct gdbarch_info;
|
||||
|
||||
/* An implementation of gdbarch_displaced_step_copy_insn for
|
||||
processors that don't need to modify the instruction before
|
||||
single-stepping the displaced copy.
|
||||
|
||||
Simply copy gdbarch_max_insn_length (ARCH) bytes from FROM to TO.
|
||||
The closure is an array of that many bytes containing the
|
||||
instruction's bytes, allocated with xmalloc. */
|
||||
extern struct displaced_step_closure *
|
||||
simple_displaced_step_copy_insn (struct gdbarch *gdbarch,
|
||||
CORE_ADDR from, CORE_ADDR to,
|
||||
struct regcache *regs);
|
||||
|
||||
/* Simple implementation of gdbarch_displaced_step_free_closure: Call
|
||||
xfree.
|
||||
This is appropriate for use with simple_displaced_step_copy_insn. */
|
||||
extern void
|
||||
simple_displaced_step_free_closure (struct gdbarch *gdbarch,
|
||||
struct displaced_step_closure *closure);
|
||||
|
||||
/* Default implementation of gdbarch_displaced_hw_singlestep. */
|
||||
extern int
|
||||
default_displaced_step_hw_singlestep (struct gdbarch *,
|
||||
struct displaced_step_closure *);
|
||||
|
||||
/* Possible value for gdbarch_displaced_step_location:
|
||||
Place displaced instructions at the program's entry point,
|
||||
leaving space for inferior function call return breakpoints. */
|
||||
extern CORE_ADDR displaced_step_at_entry_point (struct gdbarch *gdbarch);
|
||||
|
||||
/* The only possible cases for inner_than. */
|
||||
extern int core_addr_lessthan (CORE_ADDR lhs, CORE_ADDR rhs);
|
||||
extern int core_addr_greaterthan (CORE_ADDR lhs, CORE_ADDR rhs);
|
||||
|
||||
/* Identity functions on a CORE_ADDR. Just return the "addr". */
|
||||
|
||||
extern CORE_ADDR core_addr_identity (struct gdbarch *gdbarch, CORE_ADDR addr);
|
||||
extern gdbarch_convert_from_func_ptr_addr_ftype convert_from_func_ptr_addr_identity;
|
||||
|
||||
/* No-op conversion of reg to regnum. */
|
||||
|
||||
extern int no_op_reg_to_regnum (struct gdbarch *gdbarch, int reg);
|
||||
|
||||
/* Do nothing version of elf_make_msymbol_special. */
|
||||
|
||||
void default_elf_make_msymbol_special (asymbol *sym,
|
||||
struct minimal_symbol *msym);
|
||||
|
||||
/* Do nothing version of coff_make_msymbol_special. */
|
||||
|
||||
void default_coff_make_msymbol_special (int val, struct minimal_symbol *msym);
|
||||
|
||||
/* Version of cannot_fetch_register() / cannot_store_register() that
|
||||
always fails. */
|
||||
|
||||
int cannot_register_not (struct gdbarch *gdbarch, int regnum);
|
||||
|
||||
/* Legacy version of target_virtual_frame_pointer(). Assumes that
|
||||
there is an gdbarch_deprecated_fp_regnum and that it is the same, cooked or
|
||||
raw. */
|
||||
|
||||
extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer;
|
||||
|
||||
extern CORE_ADDR generic_skip_trampoline_code (struct frame_info *frame,
|
||||
CORE_ADDR pc);
|
||||
|
||||
extern CORE_ADDR generic_skip_solib_resolver (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc);
|
||||
|
||||
extern int generic_in_solib_return_trampoline (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, const char *name);
|
||||
|
||||
extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc);
|
||||
|
||||
/* By default, registers are not convertible. */
|
||||
extern int generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
|
||||
struct type *type);
|
||||
|
||||
extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch,
|
||||
struct type *type);
|
||||
|
||||
extern int generic_instruction_nullified (struct gdbarch *gdbarch,
|
||||
struct regcache *regcache);
|
||||
|
||||
int default_remote_register_number (struct gdbarch *gdbarch,
|
||||
int regno);
|
||||
|
||||
/* For compatibility with older architectures, returns
|
||||
(LEGACY_SIM_REGNO_IGNORE) when the register doesn't have a valid
|
||||
name. */
|
||||
|
||||
extern int legacy_register_sim_regno (struct gdbarch *gdbarch, int regnum);
|
||||
|
||||
/* Return the selected byte order, or BFD_ENDIAN_UNKNOWN if no byte
|
||||
order was explicitly selected. */
|
||||
extern enum bfd_endian selected_byte_order (void);
|
||||
|
||||
/* Return the selected architecture's name, or NULL if no architecture
|
||||
was explicitly selected. */
|
||||
extern const char *selected_architecture_name (void);
|
||||
|
||||
/* Initialize a ``struct info''. Can't use memset(0) since some
|
||||
default values are not zero. "fill" takes all available
|
||||
information and fills in any unspecified fields. */
|
||||
|
||||
extern void gdbarch_info_init (struct gdbarch_info *info);
|
||||
|
||||
/* Similar to init, but this time fill in the blanks. Information is
|
||||
obtained from the global "set ..." options and explicitly
|
||||
initialized INFO fields. */
|
||||
extern void gdbarch_info_fill (struct gdbarch_info *info);
|
||||
|
||||
/* Return the architecture for ABFD. If no suitable architecture
|
||||
could be find, return NULL. */
|
||||
|
||||
extern struct gdbarch *gdbarch_from_bfd (bfd *abfd);
|
||||
|
||||
/* Return "current" architecture. If the target is running, this is the
|
||||
architecture of the selected frame. Otherwise, the "current" architecture
|
||||
defaults to the target architecture.
|
||||
|
||||
This function should normally be called solely by the command interpreter
|
||||
routines to determine the architecture to execute a command in. */
|
||||
extern struct gdbarch *get_current_arch (void);
|
||||
|
||||
extern int default_has_shared_address_space (struct gdbarch *);
|
||||
|
||||
extern int default_fast_tracepoint_valid_at (struct gdbarch *gdbarch,
|
||||
CORE_ADDR addr,
|
||||
int *isize, char **msg);
|
||||
|
||||
extern void default_remote_breakpoint_from_pc (struct gdbarch *,
|
||||
CORE_ADDR *pcptr, int *kindptr);
|
||||
|
||||
extern void default_gen_return_address (struct gdbarch *gdbarch,
|
||||
struct agent_expr *ax,
|
||||
struct axs_value *value,
|
||||
CORE_ADDR scope);
|
||||
|
||||
extern const char *default_auto_charset (void);
|
||||
extern const char *default_auto_wide_charset (void);
|
||||
|
||||
extern int default_return_in_first_hidden_param_p (struct gdbarch *,
|
||||
struct type *);
|
||||
#endif
|
||||
1285
gdb/arm-linux-nat.c
1285
gdb/arm-linux-nat.c
File diff suppressed because it is too large
Load Diff
1364
gdb/arm-linux-tdep.c
1364
gdb/arm-linux-tdep.c
File diff suppressed because it is too large
Load Diff
@@ -1,69 +0,0 @@
|
||||
/* GNU/Linux on ARM target support, prototypes.
|
||||
|
||||
Copyright (C) 2006-2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
struct regset;
|
||||
struct regcache;
|
||||
|
||||
#define ARM_LINUX_SIZEOF_NWFPE (8 * FP_REGISTER_SIZE \
|
||||
+ 2 * INT_REGISTER_SIZE \
|
||||
+ 8 + INT_REGISTER_SIZE)
|
||||
|
||||
/* The index to access CSPR in user_regs defined in GLIBC. */
|
||||
#define ARM_CPSR_GREGNUM 16
|
||||
|
||||
/* Support for register format used by the NWFPE FPA emulator. Each
|
||||
register takes three words, where either the first one, two, or
|
||||
three hold a single, double, or extended precision value (depending
|
||||
on the corresponding tag). The register set is eight registers,
|
||||
followed by the fpsr and fpcr, followed by eight tag bytes, and a
|
||||
final word flag which indicates whether NWFPE has been
|
||||
initialized. */
|
||||
|
||||
#define NWFPE_FPSR_OFFSET (8 * FP_REGISTER_SIZE)
|
||||
#define NWFPE_FPCR_OFFSET (NWFPE_FPSR_OFFSET + INT_REGISTER_SIZE)
|
||||
#define NWFPE_TAGS_OFFSET (NWFPE_FPCR_OFFSET + INT_REGISTER_SIZE)
|
||||
#define NWFPE_INITFLAG_OFFSET (NWFPE_TAGS_OFFSET + 8)
|
||||
|
||||
void arm_linux_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs_buf, size_t len);
|
||||
void arm_linux_collect_gregset (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *gregs_buf, size_t len);
|
||||
|
||||
void supply_nwfpe_register (struct regcache *regcache, int regno,
|
||||
const gdb_byte *regs);
|
||||
void collect_nwfpe_register (const struct regcache *regcache, int regno,
|
||||
gdb_byte *regs);
|
||||
|
||||
void arm_linux_supply_nwfpe (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *regs_buf, size_t len);
|
||||
void arm_linux_collect_nwfpe (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *regs_buf, size_t len);
|
||||
|
||||
/* ARM GNU/Linux HWCAP values. These are in defined in
|
||||
<asm/elf.h> in current kernels. */
|
||||
#define HWCAP_VFP 64
|
||||
#define HWCAP_IWMMXT 512
|
||||
#define HWCAP_NEON 4096
|
||||
#define HWCAP_VFPv3 8192
|
||||
#define HWCAP_VFPv3D16 16384
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user