forked from Imagelibrary/binutils-gdb
Compare commits
1 Commits
gdb-8.2-br
...
binutils-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a943440a8 |
40
.gitignore
vendored
40
.gitignore
vendored
@@ -1,40 +0,0 @@
|
||||
*.diff
|
||||
*.patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
*~
|
||||
*.a
|
||||
*.flt
|
||||
*.gdb
|
||||
*.gmo
|
||||
*.info
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.tmp
|
||||
|
||||
.deps
|
||||
.libs
|
||||
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.h
|
||||
config.intl
|
||||
config.log
|
||||
config.status
|
||||
libtool
|
||||
Makefile
|
||||
stamp-*
|
||||
POTFILES
|
||||
*-POTFILES
|
||||
*/po/Makefile.in
|
||||
|
||||
.gdbinit
|
||||
.gdb_history
|
||||
core
|
||||
|
||||
lost+found
|
||||
|
||||
*.log
|
||||
*.sum
|
||||
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=
|
||||
17
gdb/.gitignore
vendored
17
gdb/.gitignore
vendored
@@ -1,17 +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
|
||||
/init.c
|
||||
/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 -cp"; else, use "diff -cp OLD NEW" or
|
||||
"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>.
|
||||
9550
gdb/ChangeLog
9550
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
4838
gdb/ChangeLog-3.x
4838
gdb/ChangeLog-3.x
File diff suppressed because it is too large
Load Diff
686
gdb/MAINTAINERS
686
gdb/MAINTAINERS
@@ -1,686 +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 GDB Steering Committee.
|
||||
|
||||
These are the official (FSF-appointed) maintainers of GDB. They have
|
||||
final and overriding authority for all GDB-related decisions, including
|
||||
anything described in this file. The committee is not generally
|
||||
involved in day-to-day development (although its members may be, as
|
||||
individuals).
|
||||
|
||||
- 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 Steering Committee 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.
|
||||
|
||||
|
||||
GDB Steering Committee
|
||||
----------------------
|
||||
|
||||
The members of the GDB Steering Committee are the FSF-appointed
|
||||
maintainers of the GDB project.
|
||||
|
||||
The Steering Committee has final authority for all GDB-related topics;
|
||||
they may make whatever changes that they deem necessary, or that the FSF
|
||||
requests. However, they are generally not involved in day-to-day
|
||||
development.
|
||||
|
||||
The current members of the steering committee are listed below, in
|
||||
alphabetical order. Their affiliations are provided for reference only -
|
||||
their membership on the Steering Committee is individual and not through
|
||||
their affiliation, and they act on behalf of the GNU project.
|
||||
|
||||
Andrew Cagney (Red Hat)
|
||||
Robert Dewar (AdaCore, NYU)
|
||||
Klee Dienes (Apple)
|
||||
Paul Hilfinger (UC Berkeley)
|
||||
Dan Jacobowitz (Google)
|
||||
Stan Shebs (CodeSourcery)
|
||||
Richard Stallman (FSF)
|
||||
Ian Lance Taylor (Google)
|
||||
Todd Whitesel
|
||||
|
||||
|
||||
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 GDB Steering Committee 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 pedro@codesourcery.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
|
||||
Michael Snyder msnyder@vmware.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
|
||||
Tristan Gingold gingold@adacore.com
|
||||
|
||||
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)
|
||||
Jan Kratochvil jan.kratochvil@redhat.com
|
||||
|
||||
lm32 --target=lm32-elf ,-Werror
|
||||
|
||||
m32c --target=m32c-elf ,-Werror
|
||||
|
||||
m32r --target=m32r-elf ,-Werror
|
||||
|
||||
m68hc11 --target=m68hc11-elf ,-Werror ,
|
||||
Stephane Carrez stcarrez@nerim.fr
|
||||
|
||||
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
|
||||
|
||||
mn10300 --target=mn10300-elf broken
|
||||
(sim/ dies with make -j)
|
||||
Michael Snyder msnyder@vmware.com
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
MS Windows (NT, '00, 9x, Me, XP) host & native
|
||||
Chris Faylor cgf@alum.bu.edu
|
||||
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
|
||||
|
||||
tracing Michael Snyder msnyder@vmware.com
|
||||
threads Michael Snyder msnyder@vmware.com
|
||||
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
|
||||
threads (gdb.threads) Michael Snyder msnyder@vmware.com
|
||||
trace (gdb.trace) Michael Snyder msnyder@vmware.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
|
||||
|
||||
|
||||
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 stcarrez@nerim.fr
|
||||
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
|
||||
Jim Blandy jimb@codesourcery.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 stcarrez@nerim.fr
|
||||
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
|
||||
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@linux.vnet.ibm.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
|
||||
Paul Gilliam pgilliam@us.ibm.com
|
||||
Tristan Gingold gingold@adacore.com
|
||||
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
|
||||
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
|
||||
Jonathan Larmour jifl@ecoscentric.com
|
||||
Jeff Law law@redhat.com
|
||||
David Lecomber david@streamline-computing.com
|
||||
Don Lee don.lee@sunplusct.com
|
||||
Robert Lipe rjl@sco.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
|
||||
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
|
||||
Denis Pilat denis.pilat@st.com
|
||||
Kevin Pouget kevin.pouget@st.com
|
||||
Paul Pluzhnikov ppluzhnikov@google.com
|
||||
Marek Polacek mpolacek@redhat.com
|
||||
Vladimir Prus vladimir@codesourcery.com
|
||||
Yao Qi yao@codesourcery.com
|
||||
Qinwei qinwei@sunnorth.com.cn
|
||||
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
|
||||
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
|
||||
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
|
||||
David Smith dsmith@redhat.com
|
||||
Stephen P. Smith ischis2@cox.net
|
||||
Jackie Smith Cashion jsmith@redhat.com
|
||||
Michael Snyder msnyder@vmware.com
|
||||
Petr Sorfa petrs@caldera.com
|
||||
Andrew Stubbs ams@codesourcery.com
|
||||
Emi Suzuki emi-suzuki@tjsys.co.jp
|
||||
Ian Lance Taylor ian@airs.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
|
||||
Kris Warkentin kewarken@qnx.com
|
||||
Philippe Waroquiers philippe.waroquiers@skynet.be
|
||||
Ulrich Weigand uweigand@de.ibm.com
|
||||
Ken Werner ken.werner@de.ibm.com
|
||||
Nathan Williams nathanw@wasabisystems.com
|
||||
Bob Wilson bob.wilson@acm.org
|
||||
Jim Wilson wilson@tuliptree.org
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
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:
|
||||
2205
gdb/Makefile.in
2205
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.
|
||||
645
gdb/README
645
gdb/README
@@ -1,645 +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'
|
||||
Use the libunwind library for unwinding function call stack. See
|
||||
http://www.nongnu.org/libunwind/index.html fro details.
|
||||
Supported only on some platforms.
|
||||
|
||||
`--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 a lot of information about writing code for GDB in the
|
||||
internals manual, distributed with GDB in gdb/doc/gdbint.texinfo. You
|
||||
can read it by hand, print it by using TeX and texinfo, or process it
|
||||
into an `info' file for use with Emacs' info mode or the standalone
|
||||
`info' program.
|
||||
|
||||
If you are pondering writing anything but a short patch, especially
|
||||
take note of the information about copyrights in the node Submitting
|
||||
Patches. 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.
|
||||
|
||||
|
||||
(this is for editing this file with GNU emacs)
|
||||
Local Variables:
|
||||
mode: text
|
||||
End:
|
||||
448
gdb/acinclude.m4
448
gdb/acinclude.m4
@@ -1,448 +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>
|
||||
|
||||
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 autoconf bugfixes
|
||||
sinclude(../config/override.m4)
|
||||
|
||||
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])
|
||||
|
||||
#
|
||||
# Sometimes the native compiler is a bogus stub for gcc or /usr/ucb/cc. This
|
||||
# makes configure think it's cross compiling. If --target wasn't used, then
|
||||
# we can't configure, so something is wrong. We don't use the cache
|
||||
# here cause if somebody fixes their compiler install, we want this to work.
|
||||
AC_DEFUN([CY_AC_C_WORKS],
|
||||
[# If we cannot compile and link a trivial program, we can't expect anything to work
|
||||
AC_MSG_CHECKING(whether the compiler ($CC) actually works)
|
||||
AC_TRY_COMPILE(, [/* don't need anything here */],
|
||||
c_compiles=yes, c_compiles=no)
|
||||
|
||||
AC_TRY_LINK(, [/* don't need anything here */],
|
||||
c_links=yes, c_links=no)
|
||||
|
||||
if test x"${c_compiles}" = x"no" ; then
|
||||
AC_MSG_ERROR(the native compiler is broken and won't compile.)
|
||||
fi
|
||||
|
||||
if test x"${c_links}" = x"no" ; then
|
||||
AC_MSG_ERROR(the native compiler is broken and won't link.)
|
||||
fi
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
||||
|
||||
## ----------------------------------------- ##
|
||||
## ANSIfy the C compiler whenever possible. ##
|
||||
## From Franc,ois Pinard ##
|
||||
## ----------------------------------------- ##
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2001, 2008, 2009
|
||||
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, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
# 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})
|
||||
])
|
||||
992
gdb/aclocal.m4
vendored
992
gdb/aclocal.m4
vendored
@@ -1,992 +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.
|
||||
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
|
||||
[m4_warning([this file was generated for autoconf 2.64.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically `autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 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.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.11'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.11.1], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.11.1])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 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.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# 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])])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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.
|
||||
|
||||
# serial 10
|
||||
|
||||
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||
# written in clear, in which case automake, when reading aclocal.m4,
|
||||
# will think it sees a *use*, and therefore will trigger all it's
|
||||
# C support machinery. Also note that it means that autoscan, seeing
|
||||
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||
|
||||
|
||||
# _AM_DEPENDENCIES(NAME)
|
||||
# ----------------------
|
||||
# See how the compiler implements dependency checking.
|
||||
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||
# We try a few techniques and use that to set a single cache variable.
|
||||
#
|
||||
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||
# dependency, and given that the user is not expected to run this macro,
|
||||
# just rely on AC_PROG_CC.
|
||||
AC_DEFUN([_AM_DEPENDENCIES],
|
||||
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||
AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||
|
||||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||
[$1], UPC, [depcc="$UPC" am_compiler_list=],
|
||||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||
[depcc="$$1" am_compiler_list=])
|
||||
|
||||
AC_CACHE_CHECK([dependency style of $depcc],
|
||||
[am_cv_$1_dependencies_compiler_type],
|
||||
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||
# We make a subdir and do the tests there. Otherwise we can end up
|
||||
# making bogus files that we don't know about and never remove. For
|
||||
# instance it was reported that on HP-UX the gcc test will end up
|
||||
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||
# in D'.
|
||||
mkdir conftest.dir
|
||||
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||
# using a relative directory.
|
||||
cp "$am_depcomp" conftest.dir
|
||||
cd conftest.dir
|
||||
# We will build objects and dependencies in a subdirectory because
|
||||
# it helps to detect inapplicable dependency modes. For instance
|
||||
# both Tru64's cc and ICC support -MD to output dependencies as a
|
||||
# side effect of compilation, but ICC will put the dependencies in
|
||||
# the current directory while Tru64 will put them in the object
|
||||
# directory.
|
||||
mkdir sub
|
||||
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
if test "$am_compiler_list" = ""; then
|
||||
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||
fi
|
||||
am__universal=false
|
||||
m4_case([$1], [CC],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac],
|
||||
[CXX],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac])
|
||||
|
||||
for depmode in $am_compiler_list; do
|
||||
# Setup a source with many dependencies, because some compilers
|
||||
# like to wrap large dependency lists on column 80 (with \), and
|
||||
# we should not choose a depcomp mode which is confused by this.
|
||||
#
|
||||
# We need to recreate these files for each test, as the compiler may
|
||||
# overwrite some of them when testing with obscure command lines.
|
||||
# This happens at least with the AIX C compiler.
|
||||
: > sub/conftest.c
|
||||
for i in 1 2 3 4 5 6; do
|
||||
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
||||
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
||||
# Solaris 8's {/usr,}/bin/sh.
|
||||
touch sub/conftst$i.h
|
||||
done
|
||||
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
||||
|
||||
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||
# handle `-M -o', and we need to detect this. Also, some Intel
|
||||
# versions had trouble with output in subdirs
|
||||
am__obj=sub/conftest.${OBJEXT-o}
|
||||
am__minus_obj="-o $am__obj"
|
||||
case $depmode in
|
||||
gcc)
|
||||
# This depmode causes a compiler race in universal mode.
|
||||
test "$am__universal" = false || continue
|
||||
;;
|
||||
nosideeffect)
|
||||
# after this tag, mechanisms are not by side-effect, so they'll
|
||||
# only be used when explicitly requested
|
||||
if test "x$enable_dependency_tracking" = xyes; then
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
;;
|
||||
msvisualcpp | msvcmsys)
|
||||
# This compiler won't grok `-c -o', but also, the minuso test has
|
||||
# not run yet. These depmodes are late enough in the game, and
|
||||
# so weak that their functioning should not be impacted.
|
||||
am__obj=conftest.${OBJEXT-o}
|
||||
am__minus_obj=
|
||||
;;
|
||||
none) break ;;
|
||||
esac
|
||||
if depmode=$depmode \
|
||||
source=sub/conftest.c object=$am__obj \
|
||||
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
||||
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
|
||||
>/dev/null 2>conftest.err &&
|
||||
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
|
||||
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||
# icc doesn't choke on unknown options, it will just issue warnings
|
||||
# or remarks (even with -Werror). So we grep stderr for any message
|
||||
# that says an option was ignored or not supported.
|
||||
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
||||
# icc: Command line warning: ignoring option '-M'; no argument required
|
||||
# The diagnosis changed in icc 8.0:
|
||||
# icc: Command line remark: option '-MP' not supported
|
||||
if (grep 'ignoring option' conftest.err ||
|
||||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
||||
am_cv_$1_dependencies_compiler_type=$depmode
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd ..
|
||||
rm -rf conftest.dir
|
||||
else
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
fi
|
||||
])
|
||||
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||
AM_CONDITIONAL([am__fastdep$1], [
|
||||
test "x$enable_dependency_tracking" != xno \
|
||||
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
||||
])
|
||||
|
||||
|
||||
# AM_SET_DEPDIR
|
||||
# -------------
|
||||
# Choose a directory name for dependency files.
|
||||
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||
AC_DEFUN([AM_SET_DEPDIR],
|
||||
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
||||
])
|
||||
|
||||
|
||||
# AM_DEP_TRACK
|
||||
# ------------
|
||||
AC_DEFUN([AM_DEP_TRACK],
|
||||
[AC_ARG_ENABLE(dependency-tracking,
|
||||
[ --disable-dependency-tracking speeds up one-time build
|
||||
--enable-dependency-tracking do not reject slow dependency extractors])
|
||||
if test "x$enable_dependency_tracking" != xno; then
|
||||
am_depcomp="$ac_aux_dir/depcomp"
|
||||
AMDEPBACKSLASH='\'
|
||||
fi
|
||||
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||
AC_SUBST([AMDEPBACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999, 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_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# ------------------------------
|
||||
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[{
|
||||
# Autoconf 2.62 quotes --file arguments for eval, but not when files
|
||||
# are listed without --file. Let's play safe and only enable the eval
|
||||
# if we detect the quoting.
|
||||
case $CONFIG_FILES in
|
||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||
*) set x $CONFIG_FILES ;;
|
||||
esac
|
||||
shift
|
||||
for mf
|
||||
do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named `Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||
dirpart=`AS_DIRNAME("$mf")`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running `make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||
U=`sed -n 's/^U = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`AS_DIRNAME(["$file"])`
|
||||
AS_MKDIR_P([$dirpart/$fdir])
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
done
|
||||
}
|
||||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
|
||||
|
||||
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# -----------------------------
|
||||
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||
#
|
||||
# This code is only required when automatic dependency tracking
|
||||
# is enabled. FIXME. This creates each `.P' file that we will
|
||||
# need in order to bootstrap the dependency handling code.
|
||||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AC_CONFIG_COMMANDS([depfiles],
|
||||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||
])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 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.
|
||||
|
||||
# serial 16
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.62])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
||||
# We need awk for the "check" target. The system "awk" is bad on
|
||||
# some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES(CC)],
|
||||
[define([AC_PROG_CC],
|
||||
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES(CXX)],
|
||||
[define([AC_PROG_CXX],
|
||||
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES(OBJC)],
|
||||
[define([AC_PROG_OBJC],
|
||||
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
|
||||
])
|
||||
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
|
||||
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
|
||||
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
|
||||
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
])
|
||||
|
||||
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001, 2003, 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.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(install_sh)])
|
||||
|
||||
# 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])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005, 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.
|
||||
|
||||
# serial 4
|
||||
|
||||
# AM_MAKE_INCLUDE()
|
||||
# -----------------
|
||||
# Check to see how make treats includes.
|
||||
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||
[am_make=${MAKE-make}
|
||||
cat > confinc << 'END'
|
||||
am__doit:
|
||||
@echo this is the am__doit target
|
||||
.PHONY: am__doit
|
||||
END
|
||||
# If we don't find an include directive, just comment out the code.
|
||||
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||
am__include="#"
|
||||
am__quote=
|
||||
_am_result=none
|
||||
# First try GNU make style include.
|
||||
echo "include confinc" > confmf
|
||||
# Ignore all kinds of additional output from `make'.
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=include
|
||||
am__quote=
|
||||
_am_result=GNU
|
||||
;;
|
||||
esac
|
||||
# Now try BSD make style include.
|
||||
if test "$am__include" = "#"; then
|
||||
echo '.include "confinc"' > confmf
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=.include
|
||||
am__quote="\""
|
||||
_am_result=BSD
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([am__include])
|
||||
AC_SUBST([am__quote])
|
||||
AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 1999, 2000, 2001, 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 6
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it supports --run.
|
||||
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --run true"; then
|
||||
am_missing_run="$MISSING --run "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN([`missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Copyright (C) 2003, 2004, 2005, 2006 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.
|
||||
|
||||
# AM_PROG_MKDIR_P
|
||||
# ---------------
|
||||
# Check for `mkdir -p'.
|
||||
AC_DEFUN([AM_PROG_MKDIR_P],
|
||||
[AC_PREREQ([2.60])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
|
||||
dnl while keeping a definition of mkdir_p for backward compatibility.
|
||||
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
|
||||
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
|
||||
dnl Makefile.ins that do not define MKDIR_P, so we do our own
|
||||
dnl adjustment using top_builddir (which is defined more often than
|
||||
dnl MKDIR_P).
|
||||
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
|
||||
case $mkdir_p in
|
||||
[[\\/$]]* | ?:[[\\/]]*) ;;
|
||||
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
|
||||
esac
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 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 4
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# ------------------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ----------------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 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_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftest.file
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
rm -f conftest.file
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 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.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor `install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in `make install-strip', and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using `strip' when the user
|
||||
# run `make install-strip'. However `strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the `STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# 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($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004, 2005 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_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of `v7', `ustar', or `pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility.
|
||||
AM_MISSING_PROG([AMTAR], [tar])
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
||||
[m4_case([$1], [ustar],, [pax],,
|
||||
[m4_fatal([Unknown tar format])])
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
# Loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
# Do not fold the above two line into one, because Tru64 sh and
|
||||
# Solaris sh will not grok spaces in the rhs of `-'.
|
||||
for _am_tool in $_am_tools
|
||||
do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar;
|
||||
do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([../config/largefile.m4])
|
||||
m4_include([../config/lead-dot.m4])
|
||||
m4_include([../config/plugins.m4])
|
||||
m4_include([gnulib/m4/00gnulib.m4])
|
||||
m4_include([gnulib/m4/extensions.m4])
|
||||
m4_include([gnulib/m4/gnulib-common.m4])
|
||||
m4_include([gnulib/m4/gnulib-comp.m4])
|
||||
m4_include([gnulib/m4/include_next.m4])
|
||||
m4_include([gnulib/m4/longlong.m4])
|
||||
m4_include([gnulib/m4/memchr.m4])
|
||||
m4_include([gnulib/m4/memmem.m4])
|
||||
m4_include([gnulib/m4/mmap-anon.m4])
|
||||
m4_include([gnulib/m4/multiarch.m4])
|
||||
m4_include([gnulib/m4/onceonly.m4])
|
||||
m4_include([gnulib/m4/stddef_h.m4])
|
||||
m4_include([gnulib/m4/stdint.m4])
|
||||
m4_include([gnulib/m4/string_h.m4])
|
||||
m4_include([gnulib/m4/warn-on-use.m4])
|
||||
m4_include([gnulib/m4/wchar_h.m4])
|
||||
m4_include([gnulib/m4/wchar_t.m4])
|
||||
m4_include([gnulib/m4/wint_t.m4])
|
||||
m4_include([acinclude.m4])
|
||||
1541
gdb/ada-exp.y
1541
gdb/ada-exp.y
File diff suppressed because it is too large
Load Diff
12414
gdb/ada-lang.c
12414
gdb/ada-lang.c
File diff suppressed because it is too large
Load Diff
388
gdb/ada-lang.h
388
gdb/ada-lang.h
@@ -1,388 +0,0 @@
|
||||
/* Ada language support definitions for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2007, 2008, 2009, 2010, 2011 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;
|
||||
|
||||
#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 \
|
||||
"^[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, (symbol, block), representing one instance of a
|
||||
* symbol-lookup operation. */
|
||||
struct ada_symbol_info {
|
||||
struct symbol* sym;
|
||||
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);
|
||||
|
||||
extern void ada_print_typedef (struct type *type, struct symbol *new_symbol,
|
||||
struct ui_file *stream);
|
||||
|
||||
extern int ada_val_print (struct type *, const gdb_byte *, int, CORE_ADDR,
|
||||
struct ui_file *, int,
|
||||
const struct value *,
|
||||
const struct value_print_options *);
|
||||
|
||||
extern int 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 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 struct symbol *
|
||||
ada_lookup_encoded_symbol (const char *, const struct block *,
|
||||
domain_enum namespace, struct block **);
|
||||
|
||||
extern struct 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 char *ada_start_decode_line_1 (char *);
|
||||
|
||||
extern struct symtabs_and_lines ada_finish_decode_line_1 (char **,
|
||||
struct symtab *,
|
||||
int, char ***);
|
||||
|
||||
extern struct symtabs_and_lines ada_sals_for_line (const char*, int,
|
||||
int, char***, int);
|
||||
|
||||
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 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 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_any_symbol (const char *name);
|
||||
|
||||
extern struct type *ada_find_any_type (const char *name);
|
||||
|
||||
extern struct symbol *ada_find_renaming_symbol (const char *name,
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
#endif
|
||||
620
gdb/ada-lex.l
620
gdb/ada-lex.l
@@ -1,620 +0,0 @@
|
||||
/* FLEX lexer for Ada expressions, for GDB.
|
||||
Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2007, 2008, 2009,
|
||||
2010, 2011 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 *);
|
||||
|
||||
#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 {
|
||||
while (*lexptr != 'i' && *lexptr != 'I')
|
||||
lexptr -= 1;
|
||||
yyrestart(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(task|thread) {
|
||||
/* This keyword signals the end of the expression and
|
||||
will be processed separately. */
|
||||
while (*lexptr != 't' && *lexptr != 'T')
|
||||
lexptr--;
|
||||
yyrestart(NULL);
|
||||
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)
|
||||
{
|
||||
lexptr -= 1;
|
||||
yyrestart(NULL);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return ',';
|
||||
}
|
||||
|
||||
"(" { paren_depth += 1; return '('; }
|
||||
")" { if (paren_depth == 0)
|
||||
{
|
||||
lexptr -= 1;
|
||||
yyrestart(NULL);
|
||||
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. */
|
||||
|
||||
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;
|
||||
|
||||
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, (const char **) &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. 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;
|
||||
|
||||
while (len > 0 && isspace (name0[len-1]))
|
||||
len -= 1;
|
||||
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.ptr = name;
|
||||
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;
|
||||
}
|
||||
|
||||
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,99 +0,0 @@
|
||||
/* Ada language operator definitions for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2007, 2008, 2009, 2010, 2011 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)
|
||||
1338
gdb/ada-tasks.c
1338
gdb/ada-tasks.c
File diff suppressed because it is too large
Load Diff
@@ -1,873 +0,0 @@
|
||||
/* Support for printing Ada types for GDB, the GNU debugger.
|
||||
Copyright (C) 1986, 1988, 1989, 1991, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
2003, 2004, 2007, 2008, 2009, 2010, 2011 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);
|
||||
|
||||
static int print_record_field_types (struct type *, struct type *,
|
||||
struct ui_file *, int, int);
|
||||
|
||||
static void print_array_type (struct type *, struct ui_file *, int, int);
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
char *name;
|
||||
struct type *base_type;
|
||||
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, 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_BITPOS (type, i))
|
||||
{
|
||||
fprintf_filtered (stream, " => %d", TYPE_FIELD_BITPOS (type, i));
|
||||
lastval = TYPE_FIELD_BITPOS (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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
<= 0)
|
||||
fprintf_filtered (stream, " null;");
|
||||
}
|
||||
else
|
||||
print_selected_record_field_types (var_type, outer_type, i, i,
|
||||
stream, show, level + 4);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
else if (ada_is_variant_part (type, i))
|
||||
{
|
||||
print_variant_part (type, i, outer_type, stream, show, level);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
return print_selected_record_field_types (type, outer_type,
|
||||
0, TYPE_NFIELDS (type) - 1,
|
||||
stream, show, level);
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
flds += print_record_field_types (type, type, stream, show, level);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
else if (ada_is_constrained_packed_array_type (type)
|
||||
&& TYPE_CODE (type) != TYPE_CODE_PTR)
|
||||
print_array_type (type, stream, show, level);
|
||||
else
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
default:
|
||||
fprintf_filtered (stream, "<");
|
||||
c_print_type (type, "", stream, show, level);
|
||||
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);
|
||||
break;
|
||||
case TYPE_CODE_REF:
|
||||
fprintf_filtered (stream, "<ref> ");
|
||||
ada_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
|
||||
break;
|
||||
case TYPE_CODE_ARRAY:
|
||||
print_array_type (type, stream, show, level);
|
||||
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
|
||||
{
|
||||
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);
|
||||
else if (ada_is_bogus_array_descriptor (type))
|
||||
fprintf_filtered (stream,
|
||||
_("array (?) of ? (<mal-formed descriptor>)"));
|
||||
else
|
||||
print_record_type (type, stream, show, level);
|
||||
break;
|
||||
case TYPE_CODE_UNION:
|
||||
print_unchecked_union_type (type, stream, show, level);
|
||||
break;
|
||||
case TYPE_CODE_FUNC:
|
||||
print_func_type (type, stream, varstring);
|
||||
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);
|
||||
fprintf_filtered (stream, "\n");
|
||||
}
|
||||
1162
gdb/ada-valprint.c
1162
gdb/ada-valprint.c
File diff suppressed because it is too large
Load Diff
609
gdb/addrmap.c
609
gdb/addrmap.c
@@ -1,609 +0,0 @@
|
||||
/* addrmap.c --- implementation of address map data structure.
|
||||
|
||||
Copyright (C) 2007, 2008, 2009, 2010, 2011 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, 2008, 2009, 2010, 2011 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 */
|
||||
1849
gdb/aix-thread.c
1849
gdb/aix-thread.c
File diff suppressed because it is too large
Load Diff
@@ -1,101 +0,0 @@
|
||||
/* Low level Alpha GNU/Linux interface, for GDB when running native.
|
||||
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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,250 +0,0 @@
|
||||
/* Target-dependent code for GNU/Linux on Alpha.
|
||||
Copyright (C) 2002, 2003, 2007, 2008, 2009, 2010, 2011
|
||||
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"
|
||||
|
||||
/* 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, 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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,411 +0,0 @@
|
||||
/* Target-dependent mdebug code for the ALPHA architecture.
|
||||
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
2003, 2007, 2008, 2009, 2010, 2011 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;
|
||||
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);
|
||||
}
|
||||
212
gdb/alpha-nat.c
212
gdb/alpha-nat.c
@@ -1,212 +0,0 @@
|
||||
/* Low level Alpha interface, for GDB when running native.
|
||||
Copyright (C) 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2007, 2008,
|
||||
2009, 2010, 2011 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,80 +0,0 @@
|
||||
/* Target-dependent code for OSF/1 on Alpha.
|
||||
Copyright (C) 2002, 2003, 2007, 2008, 2009, 2010, 2011
|
||||
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, 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);
|
||||
}
|
||||
1803
gdb/alpha-tdep.c
1803
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, 1994, 1995, 1996, 1998, 1999, 2000, 2002, 2003, 2007,
|
||||
2008, 2009, 2010, 2011 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, 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,207 +0,0 @@
|
||||
/* Native-dependent code for Alpha BSD's.
|
||||
|
||||
Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011 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,57 +0,0 @@
|
||||
/* Common target dependent code Alpha BSD's.
|
||||
|
||||
Copyright (C) 2000, 2001, 2002, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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,41 +0,0 @@
|
||||
/* Common target dependent code for Alpha BSD's.
|
||||
|
||||
Copyright (C) 2002, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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,128 +0,0 @@
|
||||
/* Target-dependent code for FreeBSD/alpha.
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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, 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,317 +0,0 @@
|
||||
/* Target-dependent code for NetBSD/alpha.
|
||||
|
||||
Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 unsigned char 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)
|
||||
{
|
||||
unsigned char ret[RETCODE_SIZE], w[4];
|
||||
LONGEST off;
|
||||
int i;
|
||||
|
||||
if (target_read_memory (pc, (char *) 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, (char *) 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, 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,138 +0,0 @@
|
||||
/* Target-dependent code for OpenBSD/alpha.
|
||||
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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, 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 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2008, 2009, 2010, 2011
|
||||
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 "gdb_assert.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;
|
||||
CORE_ADDR si;
|
||||
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 = 148;
|
||||
|
||||
set_solib_ops (gdbarch, &darwin_so_ops);
|
||||
}
|
||||
|
||||
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, 2010, 2011 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,82 +0,0 @@
|
||||
/* Target-dependent code for DICOS running on x86-64's, for GDB.
|
||||
|
||||
Copyright (C) 2009, 2010, 2011 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 CORE_ADDR
|
||||
amd64_dicos_push_dummy_code (struct gdbarch *gdbarch,
|
||||
CORE_ADDR sp, CORE_ADDR funaddr,
|
||||
struct value **args, int nargs,
|
||||
struct type *value_type,
|
||||
CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
|
||||
struct regcache *regcache)
|
||||
{
|
||||
int bplen;
|
||||
CORE_ADDR bppc = sp;
|
||||
|
||||
gdbarch_breakpoint_from_pc (gdbarch, &bppc, &bplen);
|
||||
*bp_addr = sp - bplen;
|
||||
*real_pc = funaddr;
|
||||
|
||||
return *bp_addr;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
set_gdbarch_push_dummy_code (gdbarch, amd64_dicos_push_dummy_code);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,819 +0,0 @@
|
||||
/* Native-dependent code for GNU/Linux x86-64.
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011 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/>. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "inferior.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
#include "regset.h"
|
||||
#include "linux-nat.h"
|
||||
#include "amd64-linux-tdep.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
#include "elf/common.h"
|
||||
#include <sys/uio.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/debugreg.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/procfs.h>
|
||||
#include <asm/prctl.h>
|
||||
/* FIXME ezannoni-2003-07-09: we need <sys/reg.h> to be included after
|
||||
<asm/ptrace.h> because the latter redefines FS and GS for no apparent
|
||||
reason, and those definitions don't match the ones that libpthread_db
|
||||
uses, which come from <sys/reg.h>. */
|
||||
/* ezannoni-2003-07-09: I think this is fixed. The extraneous defs have
|
||||
been removed from ptrace.h in the kernel. However, better safe than
|
||||
sorry. */
|
||||
#include <asm/ptrace.h>
|
||||
#include <sys/reg.h>
|
||||
#include "gdb_proc_service.h"
|
||||
|
||||
/* Prototypes for supply_gregset etc. */
|
||||
#include "gregset.h"
|
||||
|
||||
#include "amd64-tdep.h"
|
||||
#include "i386-linux-tdep.h"
|
||||
#include "amd64-nat.h"
|
||||
#include "i386-nat.h"
|
||||
#include "i386-xstate.h"
|
||||
|
||||
#ifndef PTRACE_GETREGSET
|
||||
#define PTRACE_GETREGSET 0x4204
|
||||
#endif
|
||||
|
||||
#ifndef PTRACE_SETREGSET
|
||||
#define PTRACE_SETREGSET 0x4205
|
||||
#endif
|
||||
|
||||
/* Does the current host support PTRACE_GETREGSET? */
|
||||
static int have_ptrace_getregset = -1;
|
||||
|
||||
/* Mapping between the general-purpose registers in GNU/Linux x86-64
|
||||
`struct user' format and GDB's register cache layout for GNU/Linux
|
||||
i386.
|
||||
|
||||
Note that most GNU/Linux x86-64 registers are 64-bit, while the
|
||||
GNU/Linux i386 registers are all 32-bit, but since we're
|
||||
little-endian we get away with that. */
|
||||
|
||||
/* From <sys/reg.h> on GNU/Linux i386. */
|
||||
static int amd64_linux_gregset32_reg_offset[] =
|
||||
{
|
||||
RAX * 8, RCX * 8, /* %eax, %ecx */
|
||||
RDX * 8, RBX * 8, /* %edx, %ebx */
|
||||
RSP * 8, RBP * 8, /* %esp, %ebp */
|
||||
RSI * 8, RDI * 8, /* %esi, %edi */
|
||||
RIP * 8, EFLAGS * 8, /* %eip, %eflags */
|
||||
CS * 8, SS * 8, /* %cs, %ss */
|
||||
DS * 8, ES * 8, /* %ds, %es */
|
||||
FS * 8, GS * 8, /* %fs, %gs */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
ORIG_RAX * 8 /* "orig_eax" */
|
||||
};
|
||||
|
||||
|
||||
/* Transfering the general-purpose registers between GDB, inferiors
|
||||
and core files. */
|
||||
|
||||
/* Fill GDB's register cache with the general-purpose register values
|
||||
in *GREGSETP. */
|
||||
|
||||
void
|
||||
supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
|
||||
{
|
||||
amd64_supply_native_gregset (regcache, gregsetp, -1);
|
||||
}
|
||||
|
||||
/* Fill register REGNUM (if it is a general-purpose register) in
|
||||
*GREGSETP with the value in GDB's register cache. If REGNUM is -1,
|
||||
do this for all registers. */
|
||||
|
||||
void
|
||||
fill_gregset (const struct regcache *regcache,
|
||||
elf_gregset_t *gregsetp, int regnum)
|
||||
{
|
||||
amd64_collect_native_gregset (regcache, gregsetp, regnum);
|
||||
}
|
||||
|
||||
/* Transfering floating-point registers between GDB, inferiors and cores. */
|
||||
|
||||
/* Fill GDB's register cache with the floating-point and SSE register
|
||||
values in *FPREGSETP. */
|
||||
|
||||
void
|
||||
supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
|
||||
{
|
||||
amd64_supply_fxsave (regcache, -1, fpregsetp);
|
||||
}
|
||||
|
||||
/* Fill register REGNUM (if it is a floating-point or SSE register) in
|
||||
*FPREGSETP with the value in GDB's register cache. If REGNUM is
|
||||
-1, do this for all registers. */
|
||||
|
||||
void
|
||||
fill_fpregset (const struct regcache *regcache,
|
||||
elf_fpregset_t *fpregsetp, int regnum)
|
||||
{
|
||||
amd64_collect_fxsave (regcache, regnum, fpregsetp);
|
||||
}
|
||||
|
||||
|
||||
/* Transferring arbitrary registers between GDB and inferior. */
|
||||
|
||||
/* Fetch register REGNUM from the child process. If REGNUM is -1, do
|
||||
this for all registers (including the floating point and SSE
|
||||
registers). */
|
||||
|
||||
static void
|
||||
amd64_linux_fetch_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
int tid;
|
||||
|
||||
/* GNU/Linux LWP ID's are process ID's. */
|
||||
tid = TIDGET (inferior_ptid);
|
||||
if (tid == 0)
|
||||
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
|
||||
|
||||
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
elf_gregset_t regs;
|
||||
|
||||
if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0)
|
||||
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))
|
||||
{
|
||||
elf_fpregset_t fpregs;
|
||||
|
||||
if (have_ptrace_getregset)
|
||||
{
|
||||
char xstateregs[I386_XSTATE_MAX_SIZE];
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = xstateregs;
|
||||
iov.iov_len = sizeof (xstateregs);
|
||||
if (ptrace (PTRACE_GETREGSET, tid,
|
||||
(unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
||||
amd64_supply_xsave (regcache, -1, xstateregs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
amd64_supply_fxsave (regcache, -1, &fpregs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Store register REGNUM back into the child process. If REGNUM is
|
||||
-1, do this for all registers (including the floating-point and SSE
|
||||
registers). */
|
||||
|
||||
static void
|
||||
amd64_linux_store_inferior_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regnum)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
int tid;
|
||||
|
||||
/* GNU/Linux LWP ID's are process ID's. */
|
||||
tid = TIDGET (inferior_ptid);
|
||||
if (tid == 0)
|
||||
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
|
||||
|
||||
if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
elf_gregset_t regs;
|
||||
|
||||
if (ptrace (PTRACE_GETREGS, tid, 0, (long) ®s) < 0)
|
||||
perror_with_name (_("Couldn't get registers"));
|
||||
|
||||
amd64_collect_native_gregset (regcache, ®s, regnum);
|
||||
|
||||
if (ptrace (PTRACE_SETREGS, tid, 0, (long) ®s) < 0)
|
||||
perror_with_name (_("Couldn't write registers"));
|
||||
|
||||
if (regnum != -1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
|
||||
{
|
||||
elf_fpregset_t fpregs;
|
||||
|
||||
if (have_ptrace_getregset)
|
||||
{
|
||||
char xstateregs[I386_XSTATE_MAX_SIZE];
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = xstateregs;
|
||||
iov.iov_len = sizeof (xstateregs);
|
||||
if (ptrace (PTRACE_GETREGSET, tid,
|
||||
(unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
|
||||
perror_with_name (_("Couldn't get extended state status"));
|
||||
|
||||
amd64_collect_xsave (regcache, regnum, xstateregs, 0);
|
||||
|
||||
if (ptrace (PTRACE_SETREGSET, tid,
|
||||
(unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
|
||||
perror_with_name (_("Couldn't write extended state status"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
|
||||
perror_with_name (_("Couldn't get floating point status"));
|
||||
|
||||
amd64_collect_fxsave (regcache, regnum, &fpregs);
|
||||
|
||||
if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
|
||||
perror_with_name (_("Couldn't write floating point status"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for debug registers. */
|
||||
|
||||
static unsigned long amd64_linux_dr[DR_CONTROL + 1];
|
||||
|
||||
static unsigned long
|
||||
amd64_linux_dr_get (ptid_t ptid, int regnum)
|
||||
{
|
||||
int tid;
|
||||
unsigned long value;
|
||||
|
||||
tid = TIDGET (ptid);
|
||||
if (tid == 0)
|
||||
tid = PIDGET (ptid);
|
||||
|
||||
/* FIXME: kettenis/2001-03-27: Calling perror_with_name if the
|
||||
ptrace call fails breaks debugging remote targets. The correct
|
||||
way to fix this is to add the hardware breakpoint and watchpoint
|
||||
stuff to the target vector. For now, just return zero if the
|
||||
ptrace call fails. */
|
||||
errno = 0;
|
||||
value = ptrace (PTRACE_PEEKUSER, tid,
|
||||
offsetof (struct user, u_debugreg[regnum]), 0);
|
||||
if (errno != 0)
|
||||
#if 0
|
||||
perror_with_name (_("Couldn't read debug register"));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Set debug register REGNUM to VALUE in only the one LWP of PTID. */
|
||||
|
||||
static void
|
||||
amd64_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
|
||||
{
|
||||
int tid;
|
||||
|
||||
tid = TIDGET (ptid);
|
||||
if (tid == 0)
|
||||
tid = PIDGET (ptid);
|
||||
|
||||
errno = 0;
|
||||
ptrace (PTRACE_POKEUSER, tid,
|
||||
offsetof (struct user, u_debugreg[regnum]), value);
|
||||
if (errno != 0)
|
||||
perror_with_name (_("Couldn't write debug register"));
|
||||
}
|
||||
|
||||
/* Set DR_CONTROL to ADDR in all LWPs of LWP_LIST. */
|
||||
|
||||
static void
|
||||
amd64_linux_dr_set_control (unsigned long control)
|
||||
{
|
||||
struct lwp_info *lp;
|
||||
ptid_t ptid;
|
||||
|
||||
amd64_linux_dr[DR_CONTROL] = control;
|
||||
ALL_LWPS (lp, ptid)
|
||||
amd64_linux_dr_set (ptid, DR_CONTROL, control);
|
||||
}
|
||||
|
||||
/* Set address REGNUM (zero based) to ADDR in all LWPs of LWP_LIST. */
|
||||
|
||||
static void
|
||||
amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
|
||||
{
|
||||
struct lwp_info *lp;
|
||||
ptid_t ptid;
|
||||
|
||||
gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
|
||||
|
||||
amd64_linux_dr[DR_FIRSTADDR + regnum] = addr;
|
||||
ALL_LWPS (lp, ptid)
|
||||
amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
|
||||
}
|
||||
|
||||
/* Set address REGNUM (zero based) to zero in all LWPs of LWP_LIST. */
|
||||
|
||||
static void
|
||||
amd64_linux_dr_reset_addr (int regnum)
|
||||
{
|
||||
amd64_linux_dr_set_addr (regnum, 0);
|
||||
}
|
||||
|
||||
/* Get DR_STATUS from only the one LWP of INFERIOR_PTID. */
|
||||
|
||||
static unsigned long
|
||||
amd64_linux_dr_get_status (void)
|
||||
{
|
||||
return amd64_linux_dr_get (inferior_ptid, DR_STATUS);
|
||||
}
|
||||
|
||||
/* Unset MASK bits in DR_STATUS in all LWPs of LWP_LIST. */
|
||||
|
||||
static void
|
||||
amd64_linux_dr_unset_status (unsigned long mask)
|
||||
{
|
||||
struct lwp_info *lp;
|
||||
ptid_t ptid;
|
||||
|
||||
ALL_LWPS (lp, ptid)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
value = amd64_linux_dr_get (ptid, DR_STATUS);
|
||||
value &= ~mask;
|
||||
amd64_linux_dr_set (ptid, DR_STATUS, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
amd64_linux_new_thread (ptid_t ptid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
|
||||
amd64_linux_dr_set (ptid, i, amd64_linux_dr[i]);
|
||||
|
||||
amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
|
||||
}
|
||||
|
||||
|
||||
/* This function is called by libthread_db as part of its handling of
|
||||
a request for a thread's local storage address. */
|
||||
|
||||
ps_err_e
|
||||
ps_get_thread_area (const struct ps_prochandle *ph,
|
||||
lwpid_t lwpid, int idx, void **base)
|
||||
{
|
||||
if (gdbarch_ptr_bit (target_gdbarch) == 32)
|
||||
{
|
||||
/* The full structure is found in <asm-i386/ldt.h>. The second
|
||||
integer is the LDT's base_address and that is used to locate
|
||||
the thread's local storage. See i386-linux-nat.c more
|
||||
info. */
|
||||
unsigned int desc[4];
|
||||
|
||||
/* This code assumes that "int" is 32 bits and that
|
||||
GET_THREAD_AREA returns no more than 4 int values. */
|
||||
gdb_assert (sizeof (int) == 4);
|
||||
#ifndef PTRACE_GET_THREAD_AREA
|
||||
#define PTRACE_GET_THREAD_AREA 25
|
||||
#endif
|
||||
if (ptrace (PTRACE_GET_THREAD_AREA,
|
||||
lwpid, (void *) (long) idx, (unsigned long) &desc) < 0)
|
||||
return PS_ERR;
|
||||
|
||||
/* Extend the value to 64 bits. Here it's assumed that a "long"
|
||||
and a "void *" are the same. */
|
||||
(*base) = (void *) (long) desc[1];
|
||||
return PS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This definition comes from prctl.h, but some kernels may not
|
||||
have it. */
|
||||
#ifndef PTRACE_ARCH_PRCTL
|
||||
#define PTRACE_ARCH_PRCTL 30
|
||||
#endif
|
||||
/* FIXME: ezannoni-2003-07-09 see comment above about include
|
||||
file order. We could be getting bogus values for these two. */
|
||||
gdb_assert (FS < ELF_NGREG);
|
||||
gdb_assert (GS < ELF_NGREG);
|
||||
switch (idx)
|
||||
{
|
||||
case FS:
|
||||
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
|
||||
return PS_OK;
|
||||
break;
|
||||
case GS:
|
||||
if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
|
||||
return PS_OK;
|
||||
break;
|
||||
default: /* Should not happen. */
|
||||
return PS_BADADDR;
|
||||
}
|
||||
}
|
||||
return PS_ERR; /* ptrace failed. */
|
||||
}
|
||||
|
||||
|
||||
static void (*super_post_startup_inferior) (ptid_t ptid);
|
||||
|
||||
static void
|
||||
amd64_linux_child_post_startup_inferior (ptid_t ptid)
|
||||
{
|
||||
i386_cleanup_dregs ();
|
||||
super_post_startup_inferior (ptid);
|
||||
}
|
||||
|
||||
|
||||
/* When GDB is built as a 64-bit application on linux, the
|
||||
PTRACE_GETSIGINFO data is always presented in 64-bit layout. Since
|
||||
debugging a 32-bit inferior with a 64-bit GDB should look the same
|
||||
as debugging it with a 32-bit GDB, we do the 32-bit <-> 64-bit
|
||||
conversion in-place ourselves. */
|
||||
|
||||
/* These types below (compat_*) define a siginfo type that is layout
|
||||
compatible with the siginfo type exported by the 32-bit userspace
|
||||
support. */
|
||||
|
||||
typedef int compat_int_t;
|
||||
typedef unsigned int compat_uptr_t;
|
||||
|
||||
typedef int compat_time_t;
|
||||
typedef int compat_timer_t;
|
||||
typedef int compat_clock_t;
|
||||
|
||||
struct compat_timeval
|
||||
{
|
||||
compat_time_t tv_sec;
|
||||
int tv_usec;
|
||||
};
|
||||
|
||||
typedef union compat_sigval
|
||||
{
|
||||
compat_int_t sival_int;
|
||||
compat_uptr_t sival_ptr;
|
||||
} compat_sigval_t;
|
||||
|
||||
typedef struct compat_siginfo
|
||||
{
|
||||
int si_signo;
|
||||
int si_errno;
|
||||
int si_code;
|
||||
|
||||
union
|
||||
{
|
||||
int _pad[((128 / sizeof (int)) - 3)];
|
||||
|
||||
/* kill() */
|
||||
struct
|
||||
{
|
||||
unsigned int _pid;
|
||||
unsigned int _uid;
|
||||
} _kill;
|
||||
|
||||
/* POSIX.1b timers */
|
||||
struct
|
||||
{
|
||||
compat_timer_t _tid;
|
||||
int _overrun;
|
||||
compat_sigval_t _sigval;
|
||||
} _timer;
|
||||
|
||||
/* POSIX.1b signals */
|
||||
struct
|
||||
{
|
||||
unsigned int _pid;
|
||||
unsigned int _uid;
|
||||
compat_sigval_t _sigval;
|
||||
} _rt;
|
||||
|
||||
/* SIGCHLD */
|
||||
struct
|
||||
{
|
||||
unsigned int _pid;
|
||||
unsigned int _uid;
|
||||
int _status;
|
||||
compat_clock_t _utime;
|
||||
compat_clock_t _stime;
|
||||
} _sigchld;
|
||||
|
||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||
struct
|
||||
{
|
||||
unsigned int _addr;
|
||||
} _sigfault;
|
||||
|
||||
/* SIGPOLL */
|
||||
struct
|
||||
{
|
||||
int _band;
|
||||
int _fd;
|
||||
} _sigpoll;
|
||||
} _sifields;
|
||||
} compat_siginfo_t;
|
||||
|
||||
#define cpt_si_pid _sifields._kill._pid
|
||||
#define cpt_si_uid _sifields._kill._uid
|
||||
#define cpt_si_timerid _sifields._timer._tid
|
||||
#define cpt_si_overrun _sifields._timer._overrun
|
||||
#define cpt_si_status _sifields._sigchld._status
|
||||
#define cpt_si_utime _sifields._sigchld._utime
|
||||
#define cpt_si_stime _sifields._sigchld._stime
|
||||
#define cpt_si_ptr _sifields._rt._sigval.sival_ptr
|
||||
#define cpt_si_addr _sifields._sigfault._addr
|
||||
#define cpt_si_band _sifields._sigpoll._band
|
||||
#define cpt_si_fd _sifields._sigpoll._fd
|
||||
|
||||
/* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun.
|
||||
In their place is si_timer1,si_timer2. */
|
||||
#ifndef si_timerid
|
||||
#define si_timerid si_timer1
|
||||
#endif
|
||||
#ifndef si_overrun
|
||||
#define si_overrun si_timer2
|
||||
#endif
|
||||
|
||||
static void
|
||||
compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from)
|
||||
{
|
||||
memset (to, 0, sizeof (*to));
|
||||
|
||||
to->si_signo = from->si_signo;
|
||||
to->si_errno = from->si_errno;
|
||||
to->si_code = from->si_code;
|
||||
|
||||
if (to->si_code == SI_TIMER)
|
||||
{
|
||||
to->cpt_si_timerid = from->si_timerid;
|
||||
to->cpt_si_overrun = from->si_overrun;
|
||||
to->cpt_si_ptr = (intptr_t) from->si_ptr;
|
||||
}
|
||||
else if (to->si_code == SI_USER)
|
||||
{
|
||||
to->cpt_si_pid = from->si_pid;
|
||||
to->cpt_si_uid = from->si_uid;
|
||||
}
|
||||
else if (to->si_code < 0)
|
||||
{
|
||||
to->cpt_si_pid = from->si_pid;
|
||||
to->cpt_si_uid = from->si_uid;
|
||||
to->cpt_si_ptr = (intptr_t) from->si_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (to->si_signo)
|
||||
{
|
||||
case SIGCHLD:
|
||||
to->cpt_si_pid = from->si_pid;
|
||||
to->cpt_si_uid = from->si_uid;
|
||||
to->cpt_si_status = from->si_status;
|
||||
to->cpt_si_utime = from->si_utime;
|
||||
to->cpt_si_stime = from->si_stime;
|
||||
break;
|
||||
case SIGILL:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGBUS:
|
||||
to->cpt_si_addr = (intptr_t) from->si_addr;
|
||||
break;
|
||||
case SIGPOLL:
|
||||
to->cpt_si_band = from->si_band;
|
||||
to->cpt_si_fd = from->si_fd;
|
||||
break;
|
||||
default:
|
||||
to->cpt_si_pid = from->si_pid;
|
||||
to->cpt_si_uid = from->si_uid;
|
||||
to->cpt_si_ptr = (intptr_t) from->si_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
siginfo_from_compat_siginfo (siginfo_t *to, compat_siginfo_t *from)
|
||||
{
|
||||
memset (to, 0, sizeof (*to));
|
||||
|
||||
to->si_signo = from->si_signo;
|
||||
to->si_errno = from->si_errno;
|
||||
to->si_code = from->si_code;
|
||||
|
||||
if (to->si_code == SI_TIMER)
|
||||
{
|
||||
to->si_timerid = from->cpt_si_timerid;
|
||||
to->si_overrun = from->cpt_si_overrun;
|
||||
to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
|
||||
}
|
||||
else if (to->si_code == SI_USER)
|
||||
{
|
||||
to->si_pid = from->cpt_si_pid;
|
||||
to->si_uid = from->cpt_si_uid;
|
||||
}
|
||||
if (to->si_code < 0)
|
||||
{
|
||||
to->si_pid = from->cpt_si_pid;
|
||||
to->si_uid = from->cpt_si_uid;
|
||||
to->si_ptr = (void *) (intptr_t) from->cpt_si_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (to->si_signo)
|
||||
{
|
||||
case SIGCHLD:
|
||||
to->si_pid = from->cpt_si_pid;
|
||||
to->si_uid = from->cpt_si_uid;
|
||||
to->si_status = from->cpt_si_status;
|
||||
to->si_utime = from->cpt_si_utime;
|
||||
to->si_stime = from->cpt_si_stime;
|
||||
break;
|
||||
case SIGILL:
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGBUS:
|
||||
to->si_addr = (void *) (intptr_t) from->cpt_si_addr;
|
||||
break;
|
||||
case SIGPOLL:
|
||||
to->si_band = from->cpt_si_band;
|
||||
to->si_fd = from->cpt_si_fd;
|
||||
break;
|
||||
default:
|
||||
to->si_pid = from->cpt_si_pid;
|
||||
to->si_uid = from->cpt_si_uid;
|
||||
to->si_ptr = (void* ) (intptr_t) from->cpt_si_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert a native/host siginfo object, into/from the siginfo in the
|
||||
layout of the inferiors' architecture. Returns true if any
|
||||
conversion was done; false otherwise. If DIRECTION is 1, then copy
|
||||
from INF to NATIVE. If DIRECTION is 0, copy from NATIVE to
|
||||
INF. */
|
||||
|
||||
static int
|
||||
amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction)
|
||||
{
|
||||
/* Is the inferior 32-bit? If so, then do fixup the siginfo
|
||||
object. */
|
||||
if (gdbarch_addr_bit (get_frame_arch (get_current_frame ())) == 32)
|
||||
{
|
||||
gdb_assert (sizeof (struct siginfo) == sizeof (compat_siginfo_t));
|
||||
|
||||
if (direction == 0)
|
||||
compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, native);
|
||||
else
|
||||
siginfo_from_compat_siginfo (native, (struct compat_siginfo *) inf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get Linux/x86 target description from running target.
|
||||
|
||||
Value of CS segment register:
|
||||
1. 64bit process: 0x33.
|
||||
2. 32bit process: 0x23.
|
||||
*/
|
||||
|
||||
#define AMD64_LINUX_USER64_CS 0x33
|
||||
|
||||
static const struct target_desc *
|
||||
amd64_linux_read_description (struct target_ops *ops)
|
||||
{
|
||||
unsigned long cs;
|
||||
int tid;
|
||||
int is_64bit;
|
||||
static uint64_t xcr0;
|
||||
|
||||
/* GNU/Linux LWP ID's are process ID's. */
|
||||
tid = TIDGET (inferior_ptid);
|
||||
if (tid == 0)
|
||||
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
|
||||
|
||||
/* Get CS register. */
|
||||
errno = 0;
|
||||
cs = ptrace (PTRACE_PEEKUSER, tid,
|
||||
offsetof (struct user_regs_struct, cs), 0);
|
||||
if (errno != 0)
|
||||
perror_with_name (_("Couldn't get CS register"));
|
||||
|
||||
is_64bit = cs == AMD64_LINUX_USER64_CS;
|
||||
|
||||
if (have_ptrace_getregset == -1)
|
||||
{
|
||||
uint64_t xstateregs[(I386_XSTATE_SSE_SIZE / sizeof (uint64_t))];
|
||||
struct iovec iov;
|
||||
|
||||
iov.iov_base = xstateregs;
|
||||
iov.iov_len = sizeof (xstateregs);
|
||||
|
||||
/* Check if PTRACE_GETREGSET works. */
|
||||
if (ptrace (PTRACE_GETREGSET, tid,
|
||||
(unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
|
||||
have_ptrace_getregset = 0;
|
||||
else
|
||||
{
|
||||
have_ptrace_getregset = 1;
|
||||
|
||||
/* Get XCR0 from XSAVE extended state. */
|
||||
xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
|
||||
/ sizeof (uint64_t))];
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the native XCR0 only if PTRACE_GETREGSET is available. */
|
||||
if (have_ptrace_getregset
|
||||
&& (xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK)
|
||||
{
|
||||
if (is_64bit)
|
||||
return tdesc_amd64_avx_linux;
|
||||
else
|
||||
return tdesc_i386_avx_linux;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_64bit)
|
||||
return tdesc_amd64_linux;
|
||||
else
|
||||
return tdesc_i386_linux;
|
||||
}
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_amd64_linux_nat (void);
|
||||
|
||||
void
|
||||
_initialize_amd64_linux_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
|
||||
amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
|
||||
amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
|
||||
amd64_native_gregset64_num_regs = AMD64_LINUX_NUM_REGS;
|
||||
|
||||
gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
|
||||
== amd64_native_gregset32_num_regs);
|
||||
|
||||
/* Fill in the generic GNU/Linux methods. */
|
||||
t = linux_target ();
|
||||
|
||||
i386_use_watchpoints (t);
|
||||
|
||||
i386_dr_low.set_control = amd64_linux_dr_set_control;
|
||||
i386_dr_low.set_addr = amd64_linux_dr_set_addr;
|
||||
i386_dr_low.reset_addr = amd64_linux_dr_reset_addr;
|
||||
i386_dr_low.get_status = amd64_linux_dr_get_status;
|
||||
i386_dr_low.unset_status = amd64_linux_dr_unset_status;
|
||||
i386_set_debug_register_length (8);
|
||||
|
||||
/* Override the GNU/Linux inferior startup hook. */
|
||||
super_post_startup_inferior = t->to_post_startup_inferior;
|
||||
t->to_post_startup_inferior = amd64_linux_child_post_startup_inferior;
|
||||
|
||||
/* Add our register access methods. */
|
||||
t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
|
||||
t->to_store_registers = amd64_linux_store_inferior_registers;
|
||||
|
||||
t->to_read_description = amd64_linux_read_description;
|
||||
|
||||
/* Register the target. */
|
||||
linux_nat_add_target (t);
|
||||
linux_nat_set_new_thread (t, amd64_linux_new_thread);
|
||||
linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,312 +0,0 @@
|
||||
/* Target-dependent code for GNU/Linux AMD64.
|
||||
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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;
|
||||
|
||||
/* 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 */
|
||||
163
gdb/amd64-nat.c
163
gdb/amd64-nat.c
@@ -1,163 +0,0 @@
|
||||
/* Native-dependent code for AMD64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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_ptr_bit (gdbarch) == 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_ptr_bit (gdbarch) == 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_ptr_bit (gdbarch) == 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,58 +0,0 @@
|
||||
/* Native-dependent code for AMD64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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,130 +0,0 @@
|
||||
/* Target-dependent code for AMD64 Solaris.
|
||||
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 */
|
||||
16 * 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);
|
||||
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);
|
||||
}
|
||||
2786
gdb/amd64-tdep.c
2786
gdb/amd64-tdep.c
File diff suppressed because it is too large
Load Diff
126
gdb/amd64-tdep.h
126
gdb/amd64-tdep.h
@@ -1,126 +0,0 @@
|
||||
/* Target-dependent definitions for AMD64.
|
||||
|
||||
Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8,
|
||||
AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9,
|
||||
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);
|
||||
|
||||
/* 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,93 +0,0 @@
|
||||
/* Copyright (C) 2008, 2009, 2010, 2011 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 <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
|
||||
|
||||
void
|
||||
_initialize_amd64_windows_nat (void)
|
||||
{
|
||||
windows_set_context_register_offsets (mappings);
|
||||
i386_set_debug_register_length (8);
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
/* Copyright (C) 2009, 2010, 2011 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 "amd64-tdep.h"
|
||||
#include "solib.h"
|
||||
#include "solib-target.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "gdbcore.h"
|
||||
#include "regcache.h"
|
||||
|
||||
/* The registers used to pass integer arguments during a function call. */
|
||||
static int amd64_windows_dummy_call_integer_regs[] =
|
||||
{
|
||||
AMD64_RCX_REGNUM, /* %rcx */
|
||||
AMD64_RDX_REGNUM, /* %rdx */
|
||||
8, /* %r8 */
|
||||
9 /* %r9 */
|
||||
};
|
||||
|
||||
/* Implement the "classify" method in the gdbarch_tdep structure
|
||||
for amd64-windows. */
|
||||
|
||||
static void
|
||||
amd64_windows_classify (struct type *type, enum amd64_reg_class class[2])
|
||||
{
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
/* Arrays are always passed by memory. */
|
||||
class[0] = class[1] = AMD64_MEMORY;
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
case TYPE_CODE_UNION:
|
||||
/* Struct/Union types whose size is 1, 2, 4, or 8 bytes
|
||||
are passed as if they were integers of the same size.
|
||||
Types of different sizes are passed by memory. */
|
||||
if (TYPE_LENGTH (type) == 1
|
||||
|| TYPE_LENGTH (type) == 2
|
||||
|| TYPE_LENGTH (type) == 4
|
||||
|| TYPE_LENGTH (type) == 8)
|
||||
{
|
||||
class[0] = AMD64_INTEGER;
|
||||
class[1] = AMD64_NO_CLASS;
|
||||
}
|
||||
else
|
||||
class[0] = class[1] = AMD64_MEMORY;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For all the other types, the conventions are the same as
|
||||
with the System V ABI. */
|
||||
amd64_classify (type, class);
|
||||
}
|
||||
}
|
||||
|
||||
/* Implement the "return_value" gdbarch method for amd64-windows. */
|
||||
|
||||
static enum return_value_convention
|
||||
amd64_windows_return_value (struct gdbarch *gdbarch, struct type *func_type,
|
||||
struct type *type, struct regcache *regcache,
|
||||
gdb_byte *readbuf, const gdb_byte *writebuf)
|
||||
{
|
||||
int len = TYPE_LENGTH (type);
|
||||
int regnum = -1;
|
||||
|
||||
/* See if our value is returned through a register. If it is, then
|
||||
store the associated register number in REGNUM. */
|
||||
switch (TYPE_CODE (type))
|
||||
{
|
||||
case TYPE_CODE_FLT:
|
||||
case TYPE_CODE_DECFLOAT:
|
||||
/* __m128, __m128i, __m128d, floats, and doubles are returned
|
||||
via XMM0. */
|
||||
if (len == 4 || len == 8 || len == 16)
|
||||
regnum = AMD64_XMM0_REGNUM;
|
||||
break;
|
||||
default:
|
||||
/* All other values that are 1, 2, 4 or 8 bytes long are returned
|
||||
via RAX. */
|
||||
if (len == 1 || len == 2 || len == 4 || len == 8)
|
||||
regnum = AMD64_RAX_REGNUM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (regnum < 0)
|
||||
{
|
||||
/* RAX contains the address where the return value has been stored. */
|
||||
if (readbuf)
|
||||
{
|
||||
ULONGEST addr;
|
||||
|
||||
regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
|
||||
read_memory (addr, readbuf, TYPE_LENGTH (type));
|
||||
}
|
||||
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Extract the return value from the register where it was stored. */
|
||||
if (readbuf)
|
||||
regcache_raw_read_part (regcache, regnum, 0, len, readbuf);
|
||||
if (writebuf)
|
||||
regcache_raw_write_part (regcache, regnum, 0, len, writebuf);
|
||||
return RETURN_VALUE_REGISTER_CONVENTION;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the code pointed to by PC corresponds to a call to
|
||||
__main, skip it if so. Return PC otherwise. */
|
||||
|
||||
static CORE_ADDR
|
||||
amd64_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
gdb_byte op;
|
||||
|
||||
target_read_memory (pc, &op, 1);
|
||||
if (op == 0xe8)
|
||||
{
|
||||
gdb_byte buf[4];
|
||||
|
||||
if (target_read_memory (pc + 1, buf, sizeof buf) == 0)
|
||||
{
|
||||
struct minimal_symbol *s;
|
||||
CORE_ADDR call_dest;
|
||||
|
||||
call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
|
||||
s = lookup_minimal_symbol_by_pc (call_dest);
|
||||
if (s != NULL
|
||||
&& SYMBOL_LINKAGE_NAME (s) != NULL
|
||||
&& strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0)
|
||||
pc += 5;
|
||||
}
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
amd64_init_abi (info, gdbarch);
|
||||
|
||||
/* On Windows, "long"s are only 32bit. */
|
||||
set_gdbarch_long_bit (gdbarch, 32);
|
||||
|
||||
/* Function calls. */
|
||||
tdep->call_dummy_num_integer_regs =
|
||||
ARRAY_SIZE (amd64_windows_dummy_call_integer_regs);
|
||||
tdep->call_dummy_integer_regs = amd64_windows_dummy_call_integer_regs;
|
||||
tdep->classify = amd64_windows_classify;
|
||||
tdep->memory_args_by_pointer = 1;
|
||||
tdep->integer_param_regs_saved_in_caller_frame = 1;
|
||||
set_gdbarch_return_value (gdbarch, amd64_windows_return_value);
|
||||
set_gdbarch_skip_main_prologue (gdbarch, amd64_skip_main_prologue);
|
||||
|
||||
set_solib_ops (gdbarch, &solib_target_so_ops);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_amd64_windows_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_CYGWIN,
|
||||
amd64_windows_init_abi);
|
||||
}
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
/* Native-dependent code for AMD64 BSD's.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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 "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;
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/* Native-dependent code for FreeBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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"
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* 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 ();
|
||||
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,222 +0,0 @@
|
||||
/* Target-dependent code for FreeBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
|
||||
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,76 +0,0 @@
|
||||
/* Native-dependent code for NetBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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,136 +0,0 @@
|
||||
/* Target-dependent code for NetBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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);
|
||||
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,146 +0,0 @@
|
||||
/* Native-dependent code for OpenBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
|
||||
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,498 +0,0 @@
|
||||
/* Target-dependent code for OpenBSD/amd64.
|
||||
|
||||
Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
|
||||
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 sigreturn[] =
|
||||
{
|
||||
0x48, 0xc7, 0xc0,
|
||||
0x67, 0x00, 0x00, 0x00, /* movq $SYS_sigreturn, %rax */
|
||||
0xcd, 0x80 /* int $0x80 */
|
||||
};
|
||||
size_t buflen = (sizeof sigreturn) + 1;
|
||||
gdb_byte *buf;
|
||||
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. */
|
||||
if (memcmp (buf, sigreturn, sizeof sigreturn)
|
||||
&& memcpy (buf + 1, sigreturn, sizeof sigreturn))
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
set_gdbarch_regset_from_core_section (gdbarch,
|
||||
amd64obsd_regset_from_core_section);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* 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_init_abi);
|
||||
}
|
||||
577
gdb/annotate.c
577
gdb/annotate.c
@@ -1,577 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright (C) 1986, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1998, 1999,
|
||||
2000, 2007, 2008, 2009, 2010, 2011 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"
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
static int ignore_count_changed = 0;
|
||||
|
||||
static void
|
||||
print_value_flags (struct type *t)
|
||||
{
|
||||
if (can_dereference (t))
|
||||
printf_filtered (("*"));
|
||||
else
|
||||
printf_filtered (("-"));
|
||||
}
|
||||
|
||||
void
|
||||
breakpoints_changed (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered (("\n\032\032breakpoints-invalid\n"));
|
||||
if (ignore_count_changed)
|
||||
ignore_count_changed = 0; /* Avoid multiple break annotations. */
|
||||
}
|
||||
}
|
||||
|
||||
/* The GUI needs to be informed of ignore_count changes, but we don't
|
||||
want to provide successive multiple breakpoints-invalid messages
|
||||
that are all caused by the fact that the ignore count is changing
|
||||
(which could keep the GUI very busy). One is enough, after the
|
||||
target actually "stops". */
|
||||
|
||||
void
|
||||
annotate_ignore_count_change (void)
|
||||
{
|
||||
if (annotation_level > 1)
|
||||
ignore_count_changed = 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"));
|
||||
if (annotation_level > 1 && ignore_count_changed)
|
||||
{
|
||||
ignore_count_changed = 0;
|
||||
breakpoints_changed ();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
target_terminal_ours ();
|
||||
printf_unfiltered (("\n\032\032frames-invalid\n"));
|
||||
}
|
||||
}
|
||||
|
||||
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 index, struct type *elttype)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
printf_filtered (("\n\032\032array-section-begin %d "), index);
|
||||
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"));
|
||||
}
|
||||
|
||||
static void
|
||||
breakpoint_changed (struct breakpoint *b)
|
||||
{
|
||||
breakpoints_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_annotate (void)
|
||||
{
|
||||
if (annotation_level == 2)
|
||||
{
|
||||
observer_attach_breakpoint_deleted (breakpoint_changed);
|
||||
observer_attach_breakpoint_modified (breakpoint_changed);
|
||||
}
|
||||
}
|
||||
104
gdb/annotate.h
104
gdb/annotate.h
@@ -1,104 +0,0 @@
|
||||
/* Annotation routines for GDB.
|
||||
Copyright (C) 1986, 1989, 1990, 1991, 1992, 1994, 1998, 1999, 2000, 2007,
|
||||
2008, 2009, 2010, 2011 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 breakpoints_changed (void);
|
||||
|
||||
extern void annotate_ignore_count_change (void);
|
||||
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);
|
||||
|
||||
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);
|
||||
803
gdb/arch-utils.c
803
gdb/arch-utils.c
@@ -1,803 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
2008, 2009, 2010, 2011 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 "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, 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 *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 succeds. */
|
||||
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);
|
||||
deprecated_target_gdbarch_select_hack (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."));
|
||||
deprecated_target_gdbarch_select_hack (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);
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
/* -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);
|
||||
}
|
||||
170
gdb/arch-utils.h
170
gdb/arch-utils.h
@@ -1,170 +0,0 @@
|
||||
/* Dynamic architecture support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2007, 2008, 2009, 2010,
|
||||
2011 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;
|
||||
|
||||
/* gdbarch trace variable */
|
||||
extern int gdbarch_debug;
|
||||
|
||||
/* 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, 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 const char *default_auto_charset (void);
|
||||
extern const char *default_auto_wide_charset (void);
|
||||
|
||||
#endif
|
||||
1322
gdb/arm-linux-nat.c
1322
gdb/arm-linux-nat.c
File diff suppressed because it is too large
Load Diff
1163
gdb/arm-linux-tdep.c
1163
gdb/arm-linux-tdep.c
File diff suppressed because it is too large
Load Diff
@@ -1,70 +0,0 @@
|
||||
/* GNU/Linux on ARM target support, prototypes.
|
||||
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/* ARM Symbian OS target support.
|
||||
|
||||
Copyright (C) 2008, 2009, 2010, 2011 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 "objfiles.h"
|
||||
#include "osabi.h"
|
||||
#include "solib.h"
|
||||
#include "solib-target.h"
|
||||
#include "target.h"
|
||||
#include "elf-bfd.h"
|
||||
|
||||
/* If PC is in a DLL import stub, return the address of the `real'
|
||||
function belonging to the stub. */
|
||||
|
||||
CORE_ADDR
|
||||
arm_symbian_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
struct gdbarch *gdbarch;
|
||||
enum bfd_endian byte_order;
|
||||
ULONGEST insn;
|
||||
CORE_ADDR dest;
|
||||
gdb_byte buf[4];
|
||||
|
||||
if (!in_plt_section (pc, NULL))
|
||||
return 0;
|
||||
|
||||
if (target_read_memory (pc, buf, 4) != 0)
|
||||
return 0;
|
||||
|
||||
gdbarch = get_frame_arch (frame);
|
||||
byte_order = gdbarch_byte_order (gdbarch);
|
||||
|
||||
/* ldr pc, [pc, #-4]. */
|
||||
insn = extract_unsigned_integer (buf, 4, byte_order);
|
||||
if (insn != 0xe51ff004)
|
||||
return 0;
|
||||
|
||||
if (target_read_memory (pc + 4, buf, 4) != 0)
|
||||
return 0;
|
||||
|
||||
dest = extract_unsigned_integer (buf, 4, byte_order);
|
||||
return gdbarch_addr_bits_remove (gdbarch, dest);
|
||||
}
|
||||
|
||||
static void
|
||||
arm_symbian_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
/* Shared library handling. */
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, arm_symbian_skip_trampoline_code);
|
||||
|
||||
/* On this target, the toolchain outputs ELF files, with `sym' for
|
||||
filename extension (e.g., `FOO.sym'); these are post-linker
|
||||
processed into PE-ish DLLs (e.g., `FOO.dll'), and it's these that
|
||||
are actually copied to and run on the target. Naturally, when
|
||||
listing shared libraries, Symbian stubs report the DLL filenames.
|
||||
Setting this makes it so that GDB automatically looks for the
|
||||
corresponding ELF files on the host's filesystem. */
|
||||
set_gdbarch_solib_symbols_extension (gdbarch, "sym");
|
||||
|
||||
/* Canonical paths on this target look like `c:\sys\bin\bar.dll',
|
||||
for example. */
|
||||
set_gdbarch_has_dos_based_file_system (gdbarch, 1);
|
||||
|
||||
set_solib_ops (gdbarch, &solib_target_so_ops);
|
||||
}
|
||||
|
||||
/* Recognize Symbian object files. */
|
||||
|
||||
static enum gdb_osabi
|
||||
arm_symbian_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
Elf_Internal_Phdr *phdrs, **segments;
|
||||
long phdrs_size;
|
||||
int num_phdrs, i;
|
||||
|
||||
/* Symbian executables are always shared objects (ET_DYN). */
|
||||
if (elf_elfheader (abfd)->e_type == ET_EXEC)
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
|
||||
if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_NONE)
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
|
||||
/* Check for the ELF headers not being part of any PT_LOAD segment.
|
||||
Symbian is the only GDB supported (or GNU binutils supported) ARM
|
||||
target which uses a postlinker to flatten ELF files, dropping the
|
||||
ELF dynamic info in the process. */
|
||||
phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
|
||||
if (phdrs_size == -1)
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
|
||||
phdrs = alloca (phdrs_size);
|
||||
num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
|
||||
if (num_phdrs == -1)
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
|
||||
for (i = 0; i < num_phdrs; i++)
|
||||
if (phdrs[i].p_type == PT_LOAD && phdrs[i].p_offset == 0)
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
|
||||
/* Looks like a Symbian binary. */
|
||||
return GDB_OSABI_SYMBIAN;
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_arm_symbian_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm,
|
||||
bfd_target_elf_flavour,
|
||||
arm_symbian_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_SYMBIAN,
|
||||
arm_symbian_init_abi);
|
||||
}
|
||||
10193
gdb/arm-tdep.c
10193
gdb/arm-tdep.c
File diff suppressed because it is too large
Load Diff
349
gdb/arm-tdep.h
349
gdb/arm-tdep.h
@@ -1,349 +0,0 @@
|
||||
/* Common target dependent code for GDB on ARM systems.
|
||||
Copyright (C) 2002, 2003, 2007, 2008, 2009, 2010, 2011
|
||||
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 ARM_TDEP_H
|
||||
#define ARM_TDEP_H
|
||||
|
||||
/* Forward declarations. */
|
||||
struct gdbarch;
|
||||
struct regset;
|
||||
struct address_space;
|
||||
|
||||
/* Register numbers of various important registers. */
|
||||
|
||||
enum gdb_regnum {
|
||||
ARM_A1_REGNUM = 0, /* first integer-like argument */
|
||||
ARM_A4_REGNUM = 3, /* last integer-like argument */
|
||||
ARM_AP_REGNUM = 11,
|
||||
ARM_IP_REGNUM = 12,
|
||||
ARM_SP_REGNUM = 13, /* Contains address of top of stack */
|
||||
ARM_LR_REGNUM = 14, /* address to return to from a function call */
|
||||
ARM_PC_REGNUM = 15, /* Contains program counter */
|
||||
ARM_F0_REGNUM = 16, /* first floating point register */
|
||||
ARM_F3_REGNUM = 19, /* last floating point argument register */
|
||||
ARM_F7_REGNUM = 23, /* last floating point register */
|
||||
ARM_FPS_REGNUM = 24, /* floating point status register */
|
||||
ARM_PS_REGNUM = 25, /* Contains processor status */
|
||||
ARM_WR0_REGNUM, /* WMMX data registers. */
|
||||
ARM_WR15_REGNUM = ARM_WR0_REGNUM + 15,
|
||||
ARM_WC0_REGNUM, /* WMMX control registers. */
|
||||
ARM_WCSSF_REGNUM = ARM_WC0_REGNUM + 2,
|
||||
ARM_WCASF_REGNUM = ARM_WC0_REGNUM + 3,
|
||||
ARM_WC7_REGNUM = ARM_WC0_REGNUM + 7,
|
||||
ARM_WCGR0_REGNUM, /* WMMX general purpose registers. */
|
||||
ARM_WCGR3_REGNUM = ARM_WCGR0_REGNUM + 3,
|
||||
ARM_WCGR7_REGNUM = ARM_WCGR0_REGNUM + 7,
|
||||
ARM_D0_REGNUM, /* VFP double-precision registers. */
|
||||
ARM_D31_REGNUM = ARM_D0_REGNUM + 31,
|
||||
ARM_FPSCR_REGNUM,
|
||||
|
||||
ARM_NUM_REGS,
|
||||
|
||||
/* Other useful registers. */
|
||||
ARM_FP_REGNUM = 11, /* Frame register in ARM code, if used. */
|
||||
THUMB_FP_REGNUM = 7, /* Frame register in Thumb code, if used. */
|
||||
ARM_NUM_ARG_REGS = 4,
|
||||
ARM_LAST_ARG_REGNUM = ARM_A4_REGNUM,
|
||||
ARM_NUM_FP_ARG_REGS = 4,
|
||||
ARM_LAST_FP_ARG_REGNUM = ARM_F3_REGNUM
|
||||
};
|
||||
|
||||
/* Size of integer registers. */
|
||||
#define INT_REGISTER_SIZE 4
|
||||
|
||||
/* Say how long FP registers are. Used for documentation purposes and
|
||||
code readability in this header. IEEE extended doubles are 80
|
||||
bits. DWORD aligned they use 96 bits. */
|
||||
#define FP_REGISTER_SIZE 12
|
||||
|
||||
/* Number of machine registers. The only define actually required
|
||||
is gdbarch_num_regs. The other definitions are used for documentation
|
||||
purposes and code readability. */
|
||||
/* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS)
|
||||
(and called PS for processor status) so the status bits can be cleared
|
||||
from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed
|
||||
in PS. */
|
||||
#define NUM_FREGS 8 /* Number of floating point registers. */
|
||||
#define NUM_SREGS 2 /* Number of status registers. */
|
||||
#define NUM_GREGS 16 /* Number of general purpose registers. */
|
||||
|
||||
|
||||
/* Instruction condition field values. */
|
||||
#define INST_EQ 0x0
|
||||
#define INST_NE 0x1
|
||||
#define INST_CS 0x2
|
||||
#define INST_CC 0x3
|
||||
#define INST_MI 0x4
|
||||
#define INST_PL 0x5
|
||||
#define INST_VS 0x6
|
||||
#define INST_VC 0x7
|
||||
#define INST_HI 0x8
|
||||
#define INST_LS 0x9
|
||||
#define INST_GE 0xa
|
||||
#define INST_LT 0xb
|
||||
#define INST_GT 0xc
|
||||
#define INST_LE 0xd
|
||||
#define INST_AL 0xe
|
||||
#define INST_NV 0xf
|
||||
|
||||
#define FLAG_N 0x80000000
|
||||
#define FLAG_Z 0x40000000
|
||||
#define FLAG_C 0x20000000
|
||||
#define FLAG_V 0x10000000
|
||||
|
||||
#define CPSR_T 0x20
|
||||
|
||||
#define XPSR_T 0x01000000
|
||||
|
||||
/* Type of floating-point code in use by inferior. There are really 3 models
|
||||
that are traditionally supported (plus the endianness issue), but gcc can
|
||||
only generate 2 of those. The third is APCS_FLOAT, where arguments to
|
||||
functions are passed in floating-point registers.
|
||||
|
||||
In addition to the traditional models, VFP adds two more.
|
||||
|
||||
If you update this enum, don't forget to update fp_model_strings in
|
||||
arm-tdep.c. */
|
||||
|
||||
enum arm_float_model
|
||||
{
|
||||
ARM_FLOAT_AUTO, /* Automatic detection. Do not set in tdep. */
|
||||
ARM_FLOAT_SOFT_FPA, /* Traditional soft-float (mixed-endian on LE ARM). */
|
||||
ARM_FLOAT_FPA, /* FPA co-processor. GCC calling convention. */
|
||||
ARM_FLOAT_SOFT_VFP, /* Soft-float with pure-endian doubles. */
|
||||
ARM_FLOAT_VFP, /* Full VFP calling convention. */
|
||||
ARM_FLOAT_LAST /* Keep at end. */
|
||||
};
|
||||
|
||||
/* ABI used by the inferior. */
|
||||
enum arm_abi_kind
|
||||
{
|
||||
ARM_ABI_AUTO,
|
||||
ARM_ABI_APCS,
|
||||
ARM_ABI_AAPCS,
|
||||
ARM_ABI_LAST
|
||||
};
|
||||
|
||||
/* Convention for returning structures. */
|
||||
|
||||
enum struct_return
|
||||
{
|
||||
pcc_struct_return, /* Return "short" structures in memory. */
|
||||
reg_struct_return /* Return "short" structures in registers. */
|
||||
};
|
||||
|
||||
/* Target-dependent structure in gdbarch. */
|
||||
struct gdbarch_tdep
|
||||
{
|
||||
/* The ABI for this architecture. It should never be set to
|
||||
ARM_ABI_AUTO. */
|
||||
enum arm_abi_kind arm_abi;
|
||||
|
||||
enum arm_float_model fp_model; /* Floating point calling conventions. */
|
||||
|
||||
int have_fpa_registers; /* Does the target report the FPA registers? */
|
||||
int have_vfp_registers; /* Does the target report the VFP registers? */
|
||||
int have_vfp_pseudos; /* Are we synthesizing the single precision
|
||||
VFP registers? */
|
||||
int have_neon_pseudos; /* Are we synthesizing the quad precision
|
||||
NEON registers? Requires
|
||||
have_vfp_pseudos. */
|
||||
int have_neon; /* Do we have a NEON unit? */
|
||||
|
||||
int is_m; /* Does the target follow the "M" profile. */
|
||||
CORE_ADDR lowest_pc; /* Lowest address at which instructions
|
||||
will appear. */
|
||||
|
||||
const char *arm_breakpoint; /* Breakpoint pattern for an ARM insn. */
|
||||
int arm_breakpoint_size; /* And its size. */
|
||||
const char *thumb_breakpoint; /* Breakpoint pattern for a Thumb insn. */
|
||||
int thumb_breakpoint_size; /* And its size. */
|
||||
|
||||
/* If the Thumb breakpoint is an undefined instruction (which is
|
||||
affected by IT blocks) rather than a BKPT instruction (which is
|
||||
not), then we need a 32-bit Thumb breakpoint to preserve the
|
||||
instruction count in IT blocks. */
|
||||
const char *thumb2_breakpoint;
|
||||
int thumb2_breakpoint_size;
|
||||
|
||||
int jb_pc; /* Offset to PC value in jump buffer.
|
||||
If this is negative, longjmp support
|
||||
will be disabled. */
|
||||
size_t jb_elt_size; /* And the size of each entry in the buf. */
|
||||
|
||||
/* Convention for returning structures. */
|
||||
enum struct_return struct_return;
|
||||
|
||||
/* Cached core file helpers. */
|
||||
struct regset *gregset, *fpregset, *vfpregset;
|
||||
|
||||
/* ISA-specific data types. */
|
||||
struct type *arm_ext_type;
|
||||
struct type *neon_double_type;
|
||||
struct type *neon_quad_type;
|
||||
|
||||
/* Return the expected next PC if FRAME is stopped at a syscall
|
||||
instruction. */
|
||||
CORE_ADDR (*syscall_next_pc) (struct frame_info *frame);
|
||||
};
|
||||
|
||||
/* Structures used for displaced stepping. */
|
||||
|
||||
/* The maximum number of temporaries available for displaced instructions. */
|
||||
#define DISPLACED_TEMPS 16
|
||||
/* The maximum number of modified instructions generated for one single-stepped
|
||||
instruction, including the breakpoint (usually at the end of the instruction
|
||||
sequence) and any scratch words, etc. */
|
||||
#define DISPLACED_MODIFIED_INSNS 8
|
||||
|
||||
struct displaced_step_closure
|
||||
{
|
||||
ULONGEST tmp[DISPLACED_TEMPS];
|
||||
int rd;
|
||||
int wrote_to_pc;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
int xfersize;
|
||||
int rn; /* Writeback register. */
|
||||
unsigned int immed : 1; /* Offset is immediate. */
|
||||
unsigned int writeback : 1; /* Perform base-register writeback. */
|
||||
unsigned int restore_r4 : 1; /* Used r4 as scratch. */
|
||||
} ldst;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned long dest;
|
||||
unsigned int link : 1;
|
||||
unsigned int exchange : 1;
|
||||
unsigned int cond : 4;
|
||||
} branch;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int regmask;
|
||||
int rn;
|
||||
CORE_ADDR xfer_addr;
|
||||
unsigned int load : 1;
|
||||
unsigned int user : 1;
|
||||
unsigned int increment : 1;
|
||||
unsigned int before : 1;
|
||||
unsigned int writeback : 1;
|
||||
unsigned int cond : 4;
|
||||
} block;
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned int immed : 1;
|
||||
} preload;
|
||||
|
||||
struct
|
||||
{
|
||||
/* If non-NULL, override generic SVC handling (e.g. for a particular
|
||||
OS). */
|
||||
int (*copy_svc_os) (struct gdbarch *gdbarch, struct regcache *regs,
|
||||
struct displaced_step_closure *dsc);
|
||||
} svc;
|
||||
} u;
|
||||
|
||||
/* The size of original instruction, 2 or 4. */
|
||||
unsigned int insn_size;
|
||||
/* True if the original insn (and thus all replacement insns) are Thumb
|
||||
instead of ARM. */
|
||||
unsigned int is_thumb;
|
||||
|
||||
/* The slots in the array is used in this way below,
|
||||
- ARM instruction occupies one slot,
|
||||
- Thumb 16 bit instruction occupies one slot,
|
||||
- Thumb 32-bit instruction occupies *two* slots, one part for each. */
|
||||
unsigned long modinsn[DISPLACED_MODIFIED_INSNS];
|
||||
int numinsns;
|
||||
CORE_ADDR insn_addr;
|
||||
CORE_ADDR scratch_base;
|
||||
void (*cleanup) (struct gdbarch *, struct regcache *,
|
||||
struct displaced_step_closure *);
|
||||
};
|
||||
|
||||
/* Values for the WRITE_PC argument to displaced_write_reg. If the register
|
||||
write may write to the PC, specifies the way the CPSR T bit, etc. is
|
||||
modified by the instruction. */
|
||||
|
||||
enum pc_write_style
|
||||
{
|
||||
BRANCH_WRITE_PC,
|
||||
BX_WRITE_PC,
|
||||
LOAD_WRITE_PC,
|
||||
ALU_WRITE_PC,
|
||||
CANNOT_WRITE_PC
|
||||
};
|
||||
|
||||
extern void
|
||||
arm_process_displaced_insn (struct gdbarch *gdbarch, CORE_ADDR from,
|
||||
CORE_ADDR to, struct regcache *regs,
|
||||
struct displaced_step_closure *dsc);
|
||||
extern void
|
||||
arm_displaced_init_closure (struct gdbarch *gdbarch, CORE_ADDR from,
|
||||
CORE_ADDR to, struct displaced_step_closure *dsc);
|
||||
extern ULONGEST
|
||||
displaced_read_reg (struct regcache *regs, struct displaced_step_closure *dsc,
|
||||
int regno);
|
||||
extern void
|
||||
displaced_write_reg (struct regcache *regs,
|
||||
struct displaced_step_closure *dsc, int regno,
|
||||
ULONGEST val, enum pc_write_style write_pc);
|
||||
|
||||
CORE_ADDR arm_skip_stub (struct frame_info *, CORE_ADDR);
|
||||
CORE_ADDR arm_get_next_pc (struct frame_info *, CORE_ADDR);
|
||||
void arm_insert_single_step_breakpoint (struct gdbarch *,
|
||||
struct address_space *, CORE_ADDR);
|
||||
int arm_software_single_step (struct frame_info *);
|
||||
int arm_frame_is_thumb (struct frame_info *frame);
|
||||
|
||||
extern struct displaced_step_closure *
|
||||
arm_displaced_step_copy_insn (struct gdbarch *, CORE_ADDR, CORE_ADDR,
|
||||
struct regcache *);
|
||||
extern void arm_displaced_step_fixup (struct gdbarch *,
|
||||
struct displaced_step_closure *,
|
||||
CORE_ADDR, CORE_ADDR, struct regcache *);
|
||||
|
||||
/* Return the bit mask in ARM_PS_REGNUM that indicates Thumb mode. */
|
||||
extern int arm_psr_thumb_bit (struct gdbarch *);
|
||||
|
||||
/* Is the instruction at the given memory address a Thumb or ARM
|
||||
instruction? */
|
||||
extern int arm_pc_is_thumb (struct gdbarch *, CORE_ADDR);
|
||||
|
||||
/* Functions exported from armbsd-tdep.h. */
|
||||
|
||||
/* Return the appropriate register set for the core section identified
|
||||
by SECT_NAME and SECT_SIZE. */
|
||||
|
||||
extern const struct regset *
|
||||
armbsd_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t sect_size);
|
||||
|
||||
/* Target descriptions. */
|
||||
extern struct target_desc *tdesc_arm_with_m;
|
||||
extern struct target_desc *tdesc_arm_with_iwmmxt;
|
||||
extern struct target_desc *tdesc_arm_with_vfpv2;
|
||||
extern struct target_desc *tdesc_arm_with_vfpv3;
|
||||
extern struct target_desc *tdesc_arm_with_neon;
|
||||
|
||||
#endif /* arm-tdep.h */
|
||||
@@ -1,170 +0,0 @@
|
||||
/* Target-dependent code for Windows CE running on ARM processors,
|
||||
for GDB.
|
||||
|
||||
Copyright (C) 2007, 2008, 2009, 2010, 2011 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 "gdbcore.h"
|
||||
#include "target.h"
|
||||
#include "solib.h"
|
||||
#include "solib-target.h"
|
||||
#include "frame.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
|
||||
static const char arm_wince_le_breakpoint[] = { 0x10, 0x00, 0x00, 0xe6 };
|
||||
static const char arm_wince_thumb_le_breakpoint[] = { 0xfe, 0xdf };
|
||||
|
||||
/* Description of the longjmp buffer. */
|
||||
#define ARM_WINCE_JB_ELEMENT_SIZE INT_REGISTER_SIZE
|
||||
#define ARM_WINCE_JB_PC 10
|
||||
|
||||
static CORE_ADDR
|
||||
arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
ULONGEST indirect;
|
||||
struct minimal_symbol *indsym;
|
||||
char *symname;
|
||||
CORE_ADDR next_pc;
|
||||
|
||||
/* The format of an ARM DLL trampoline is:
|
||||
ldr ip, [pc]
|
||||
ldr pc, [ip]
|
||||
.dw __imp_<func> */
|
||||
|
||||
if (pc == 0
|
||||
|| read_memory_unsigned_integer (pc + 0, 4, byte_order) != 0xe59fc000
|
||||
|| read_memory_unsigned_integer (pc + 4, 4, byte_order) != 0xe59cf000)
|
||||
return 0;
|
||||
|
||||
indirect = read_memory_unsigned_integer (pc + 8, 4, byte_order);
|
||||
if (indirect == 0)
|
||||
return 0;
|
||||
|
||||
indsym = lookup_minimal_symbol_by_pc (indirect);
|
||||
if (indsym == NULL)
|
||||
return 0;
|
||||
|
||||
symname = SYMBOL_LINKAGE_NAME (indsym);
|
||||
if (symname == NULL || strncmp (symname, "__imp_", 6) != 0)
|
||||
return 0;
|
||||
|
||||
next_pc = read_memory_unsigned_integer (indirect, 4, byte_order);
|
||||
if (next_pc != 0)
|
||||
return next_pc;
|
||||
|
||||
/* Check with the default arm gdbarch_skip_trampoline. */
|
||||
return arm_skip_stub (frame, pc);
|
||||
}
|
||||
|
||||
/* GCC emits a call to __gccmain in the prologue of main.
|
||||
|
||||
The function below examines the code pointed at by PC and checks to
|
||||
see if it corresponds to a call to __gccmain. If so, it returns
|
||||
the address of the instruction following that call. Otherwise, it
|
||||
simply returns PC. */
|
||||
|
||||
CORE_ADDR
|
||||
arm_wince_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
|
||||
ULONGEST this_instr;
|
||||
|
||||
this_instr = read_memory_unsigned_integer (pc, 4, byte_order);
|
||||
|
||||
/* bl offset <__gccmain> */
|
||||
if ((this_instr & 0xfff00000) == 0xeb000000)
|
||||
{
|
||||
#define sign_extend(V, N) \
|
||||
(((long) (V) ^ (1L << ((N) - 1))) - (1L << ((N) - 1)))
|
||||
|
||||
long offset = sign_extend (this_instr & 0x000fffff, 23) << 2;
|
||||
CORE_ADDR call_dest = (pc + 8 + offset) & 0xffffffffU;
|
||||
struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
|
||||
|
||||
if (s != NULL
|
||||
&& SYMBOL_LINKAGE_NAME (s) != NULL
|
||||
&& strcmp (SYMBOL_LINKAGE_NAME (s), "__gccmain") == 0)
|
||||
pc += 4;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
static void
|
||||
arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
tdep->arm_breakpoint = arm_wince_le_breakpoint;
|
||||
tdep->arm_breakpoint_size = sizeof (arm_wince_le_breakpoint);
|
||||
tdep->thumb_breakpoint = arm_wince_thumb_le_breakpoint;
|
||||
tdep->thumb_breakpoint_size = sizeof (arm_wince_thumb_le_breakpoint);
|
||||
tdep->struct_return = pcc_struct_return;
|
||||
|
||||
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
|
||||
|
||||
tdep->jb_pc = ARM_WINCE_JB_PC;
|
||||
tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE;
|
||||
|
||||
/* On ARM WinCE char defaults to signed. */
|
||||
set_gdbarch_char_signed (gdbarch, 1);
|
||||
|
||||
/* Shared library handling. */
|
||||
set_solib_ops (gdbarch, &solib_target_so_ops);
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, arm_pe_skip_trampoline_code);
|
||||
|
||||
/* Single stepping. */
|
||||
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
|
||||
|
||||
/* Skip call to __gccmain that gcc places in main. */
|
||||
set_gdbarch_skip_main_prologue (gdbarch, arm_wince_skip_main_prologue);
|
||||
|
||||
/* Canonical paths on this target look like `\Windows\coredll.dll',
|
||||
for example. */
|
||||
set_gdbarch_has_dos_based_file_system (gdbarch, 1);
|
||||
}
|
||||
|
||||
static enum gdb_osabi
|
||||
arm_wince_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
const char *target_name = bfd_get_target (abfd);
|
||||
|
||||
if (strcmp (target_name, "pei-arm-wince-little") == 0)
|
||||
return GDB_OSABI_WINCE;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
void _initialize_arm_wince_tdep (void);
|
||||
|
||||
void
|
||||
_initialize_arm_wince_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_coff_flavour,
|
||||
arm_wince_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_WINCE,
|
||||
arm_wince_init_abi);
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/* Target-dependent code for ARM BSD's.
|
||||
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 "regcache.h"
|
||||
#include "regset.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
|
||||
/* Core file support. */
|
||||
|
||||
/* Sizeof `struct reg' in <machine/reg.h>. */
|
||||
#define ARMBSD_SIZEOF_GREGS (17 * 4)
|
||||
|
||||
/* Sizeof `struct fpreg' in <machine/reg.h. */
|
||||
#define ARMBSD_SIZEOF_FPREGS ((1 + (8 * 3)) * 4)
|
||||
|
||||
static int
|
||||
armbsd_fpreg_offset (int regnum)
|
||||
{
|
||||
if (regnum == ARM_FPS_REGNUM)
|
||||
return 0;
|
||||
|
||||
return 4 + (regnum - ARM_F0_REGNUM) * 12;
|
||||
}
|
||||
|
||||
/* 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
|
||||
armbsd_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 >= ARMBSD_SIZEOF_FPREGS);
|
||||
|
||||
for (i = ARM_F0_REGNUM; i <= ARM_FPS_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + armbsd_fpreg_offset (i));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
armbsd_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 >= ARMBSD_SIZEOF_GREGS);
|
||||
|
||||
for (i = ARM_A1_REGNUM; i <= ARM_PC_REGNUM; i++)
|
||||
{
|
||||
if (regnum == i || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + i * 4);
|
||||
}
|
||||
|
||||
if (regnum == ARM_PS_REGNUM || regnum == -1)
|
||||
regcache_raw_supply (regcache, i, regs + 16 * 4);
|
||||
|
||||
if (len >= ARMBSD_SIZEOF_GREGS + ARMBSD_SIZEOF_FPREGS)
|
||||
{
|
||||
regs += ARMBSD_SIZEOF_GREGS;
|
||||
len -= ARMBSD_SIZEOF_GREGS;
|
||||
armbsd_supply_fpregset (regset, regcache, regnum, regs, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* ARM register sets. */
|
||||
|
||||
static struct regset armbsd_gregset =
|
||||
{
|
||||
NULL,
|
||||
armbsd_supply_gregset
|
||||
};
|
||||
|
||||
static struct regset armbsd_fpregset =
|
||||
{
|
||||
NULL,
|
||||
armbsd_supply_fpregset
|
||||
};
|
||||
|
||||
/* Return the appropriate register set for the core section identified
|
||||
by SECT_NAME and SECT_SIZE. */
|
||||
|
||||
const struct regset *
|
||||
armbsd_regset_from_core_section (struct gdbarch *gdbarch,
|
||||
const char *sect_name, size_t sect_size)
|
||||
{
|
||||
if (strcmp (sect_name, ".reg") == 0 && sect_size >= ARMBSD_SIZEOF_GREGS)
|
||||
return &armbsd_gregset;
|
||||
|
||||
if (strcmp (sect_name, ".reg2") == 0 && sect_size >= ARMBSD_SIZEOF_FPREGS)
|
||||
return &armbsd_fpregset;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,504 +0,0 @@
|
||||
/* Native-dependent code for BSD Unix running on ARM's, for GDB.
|
||||
|
||||
Copyright (C) 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002, 2004, 2007,
|
||||
2008, 2009, 2010, 2011 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 "inferior.h"
|
||||
#include "regcache.h"
|
||||
#include "target.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
#include "arm-tdep.h"
|
||||
#include "inf-ptrace.h"
|
||||
|
||||
extern int arm_apcs_32;
|
||||
|
||||
static void
|
||||
arm_supply_gregset (struct regcache *regcache, struct reg *gregset)
|
||||
{
|
||||
int regno;
|
||||
CORE_ADDR r_pc;
|
||||
|
||||
/* Integer registers. */
|
||||
for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
|
||||
regcache_raw_supply (regcache, regno, (char *) &gregset->r[regno]);
|
||||
|
||||
regcache_raw_supply (regcache, ARM_SP_REGNUM,
|
||||
(char *) &gregset->r_sp);
|
||||
regcache_raw_supply (regcache, ARM_LR_REGNUM,
|
||||
(char *) &gregset->r_lr);
|
||||
/* This is ok: we're running native... */
|
||||
r_pc = gdbarch_addr_bits_remove (get_regcache_arch (regcache), gregset->r_pc);
|
||||
regcache_raw_supply (regcache, ARM_PC_REGNUM, (char *) &r_pc);
|
||||
|
||||
if (arm_apcs_32)
|
||||
regcache_raw_supply (regcache, ARM_PS_REGNUM,
|
||||
(char *) &gregset->r_cpsr);
|
||||
else
|
||||
regcache_raw_supply (regcache, ARM_PS_REGNUM,
|
||||
(char *) &gregset->r_pc);
|
||||
}
|
||||
|
||||
static void
|
||||
arm_supply_fparegset (struct regcache *regcache, struct fpreg *fparegset)
|
||||
{
|
||||
int regno;
|
||||
|
||||
for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
|
||||
regcache_raw_supply (regcache, regno,
|
||||
(char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
|
||||
|
||||
regcache_raw_supply (regcache, ARM_FPS_REGNUM,
|
||||
(char *) &fparegset->fpr_fpsr);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_register (struct regcache *regcache, int regno)
|
||||
{
|
||||
struct reg inferior_registers;
|
||||
int ret;
|
||||
|
||||
ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch general register"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case ARM_SP_REGNUM:
|
||||
regcache_raw_supply (regcache, ARM_SP_REGNUM,
|
||||
(char *) &inferior_registers.r_sp);
|
||||
break;
|
||||
|
||||
case ARM_LR_REGNUM:
|
||||
regcache_raw_supply (regcache, ARM_LR_REGNUM,
|
||||
(char *) &inferior_registers.r_lr);
|
||||
break;
|
||||
|
||||
case ARM_PC_REGNUM:
|
||||
/* This is ok: we're running native... */
|
||||
inferior_registers.r_pc = gdbarch_addr_bits_remove
|
||||
(get_regcache_arch (regcache),
|
||||
inferior_registers.r_pc);
|
||||
regcache_raw_supply (regcache, ARM_PC_REGNUM,
|
||||
(char *) &inferior_registers.r_pc);
|
||||
break;
|
||||
|
||||
case ARM_PS_REGNUM:
|
||||
if (arm_apcs_32)
|
||||
regcache_raw_supply (regcache, ARM_PS_REGNUM,
|
||||
(char *) &inferior_registers.r_cpsr);
|
||||
else
|
||||
regcache_raw_supply (regcache, ARM_PS_REGNUM,
|
||||
(char *) &inferior_registers.r_pc);
|
||||
break;
|
||||
|
||||
default:
|
||||
regcache_raw_supply (regcache, regno,
|
||||
(char *) &inferior_registers.r[regno]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_regs (struct regcache *regcache)
|
||||
{
|
||||
struct reg inferior_registers;
|
||||
int ret;
|
||||
int regno;
|
||||
|
||||
ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch general registers"));
|
||||
return;
|
||||
}
|
||||
|
||||
arm_supply_gregset (regcache, &inferior_registers);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_fp_register (struct regcache *regcache, int regno)
|
||||
{
|
||||
struct fpreg inferior_fp_registers;
|
||||
int ret;
|
||||
|
||||
ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch floating-point register"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case ARM_FPS_REGNUM:
|
||||
regcache_raw_supply (regcache, ARM_FPS_REGNUM,
|
||||
(char *) &inferior_fp_registers.fpr_fpsr);
|
||||
break;
|
||||
|
||||
default:
|
||||
regcache_raw_supply (regcache, regno,
|
||||
(char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_fp_regs (struct regcache *regcache)
|
||||
{
|
||||
struct fpreg inferior_fp_registers;
|
||||
int ret;
|
||||
int regno;
|
||||
|
||||
ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch general registers"));
|
||||
return;
|
||||
}
|
||||
|
||||
arm_supply_fparegset (regcache, &inferior_fp_registers);
|
||||
}
|
||||
|
||||
static void
|
||||
armnbsd_fetch_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regno)
|
||||
{
|
||||
if (regno >= 0)
|
||||
{
|
||||
if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
|
||||
fetch_register (regcache, regno);
|
||||
else
|
||||
fetch_fp_register (regcache, regno);
|
||||
}
|
||||
else
|
||||
{
|
||||
fetch_regs (regcache);
|
||||
fetch_fp_regs (regcache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
store_register (const struct regcache *regcache, int regno)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
struct reg inferior_registers;
|
||||
int ret;
|
||||
|
||||
ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch general registers"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case ARM_SP_REGNUM:
|
||||
regcache_raw_collect (regcache, ARM_SP_REGNUM,
|
||||
(char *) &inferior_registers.r_sp);
|
||||
break;
|
||||
|
||||
case ARM_LR_REGNUM:
|
||||
regcache_raw_collect (regcache, ARM_LR_REGNUM,
|
||||
(char *) &inferior_registers.r_lr);
|
||||
break;
|
||||
|
||||
case ARM_PC_REGNUM:
|
||||
if (arm_apcs_32)
|
||||
regcache_raw_collect (regcache, ARM_PC_REGNUM,
|
||||
(char *) &inferior_registers.r_pc);
|
||||
else
|
||||
{
|
||||
unsigned pc_val;
|
||||
|
||||
regcache_raw_collect (regcache, ARM_PC_REGNUM,
|
||||
(char *) &pc_val);
|
||||
|
||||
pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
|
||||
inferior_registers.r_pc ^= gdbarch_addr_bits_remove
|
||||
(gdbarch, inferior_registers.r_pc);
|
||||
inferior_registers.r_pc |= pc_val;
|
||||
}
|
||||
break;
|
||||
|
||||
case ARM_PS_REGNUM:
|
||||
if (arm_apcs_32)
|
||||
regcache_raw_collect (regcache, ARM_PS_REGNUM,
|
||||
(char *) &inferior_registers.r_cpsr);
|
||||
else
|
||||
{
|
||||
unsigned psr_val;
|
||||
|
||||
regcache_raw_collect (regcache, ARM_PS_REGNUM,
|
||||
(char *) &psr_val);
|
||||
|
||||
psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
|
||||
inferior_registers.r_pc = gdbarch_addr_bits_remove
|
||||
(gdbarch, inferior_registers.r_pc);
|
||||
inferior_registers.r_pc |= psr_val;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
regcache_raw_collect (regcache, regno,
|
||||
(char *) &inferior_registers.r[regno]);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
warning (_("unable to write register %d to inferior"), regno);
|
||||
}
|
||||
|
||||
static void
|
||||
store_regs (const struct regcache *regcache)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
struct reg inferior_registers;
|
||||
int ret;
|
||||
int regno;
|
||||
|
||||
|
||||
for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
|
||||
regcache_raw_collect (regcache, regno,
|
||||
(char *) &inferior_registers.r[regno]);
|
||||
|
||||
regcache_raw_collect (regcache, ARM_SP_REGNUM,
|
||||
(char *) &inferior_registers.r_sp);
|
||||
regcache_raw_collect (regcache, ARM_LR_REGNUM,
|
||||
(char *) &inferior_registers.r_lr);
|
||||
|
||||
if (arm_apcs_32)
|
||||
{
|
||||
regcache_raw_collect (regcache, ARM_PC_REGNUM,
|
||||
(char *) &inferior_registers.r_pc);
|
||||
regcache_raw_collect (regcache, ARM_PS_REGNUM,
|
||||
(char *) &inferior_registers.r_cpsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned pc_val;
|
||||
unsigned psr_val;
|
||||
|
||||
regcache_raw_collect (regcache, ARM_PC_REGNUM,
|
||||
(char *) &pc_val);
|
||||
regcache_raw_collect (regcache, ARM_PS_REGNUM,
|
||||
(char *) &psr_val);
|
||||
|
||||
pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
|
||||
psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
|
||||
|
||||
inferior_registers.r_pc = pc_val | psr_val;
|
||||
}
|
||||
|
||||
ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
warning (_("unable to store general registers"));
|
||||
}
|
||||
|
||||
static void
|
||||
store_fp_register (const struct regcache *regcache, int regno)
|
||||
{
|
||||
struct fpreg inferior_fp_registers;
|
||||
int ret;
|
||||
|
||||
ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
warning (_("unable to fetch floating-point registers"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case ARM_FPS_REGNUM:
|
||||
regcache_raw_collect (regcache, ARM_FPS_REGNUM,
|
||||
(char *) &inferior_fp_registers.fpr_fpsr);
|
||||
break;
|
||||
|
||||
default:
|
||||
regcache_raw_collect (regcache, regno,
|
||||
(char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
warning (_("unable to write register %d to inferior"), regno);
|
||||
}
|
||||
|
||||
static void
|
||||
store_fp_regs (const struct regcache *regcache)
|
||||
{
|
||||
struct fpreg inferior_fp_registers;
|
||||
int ret;
|
||||
int regno;
|
||||
|
||||
|
||||
for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
|
||||
regcache_raw_collect (regcache, regno,
|
||||
(char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
|
||||
|
||||
regcache_raw_collect (regcache, ARM_FPS_REGNUM,
|
||||
(char *) &inferior_fp_registers.fpr_fpsr);
|
||||
|
||||
ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_TYPE_ARG3) &inferior_fp_registers, 0);
|
||||
|
||||
if (ret < 0)
|
||||
warning (_("unable to store floating-point registers"));
|
||||
}
|
||||
|
||||
static void
|
||||
armnbsd_store_registers (struct target_ops *ops,
|
||||
struct regcache *regcache, int regno)
|
||||
{
|
||||
if (regno >= 0)
|
||||
{
|
||||
if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
|
||||
store_register (regcache, regno);
|
||||
else
|
||||
store_fp_register (regcache, regno);
|
||||
}
|
||||
else
|
||||
{
|
||||
store_regs (regcache);
|
||||
store_fp_regs (regcache);
|
||||
}
|
||||
}
|
||||
|
||||
struct md_core
|
||||
{
|
||||
struct reg intreg;
|
||||
struct fpreg freg;
|
||||
};
|
||||
|
||||
static void
|
||||
fetch_core_registers (struct regcache *regcache,
|
||||
char *core_reg_sect, unsigned core_reg_size,
|
||||
int which, CORE_ADDR ignore)
|
||||
{
|
||||
struct md_core *core_reg = (struct md_core *) core_reg_sect;
|
||||
int regno;
|
||||
CORE_ADDR r_pc;
|
||||
|
||||
arm_supply_gregset (regcache, &core_reg->intreg);
|
||||
arm_supply_fparegset (regcache, &core_reg->freg);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_elfcore_registers (struct regcache *regcache,
|
||||
char *core_reg_sect, unsigned core_reg_size,
|
||||
int which, CORE_ADDR ignore)
|
||||
{
|
||||
struct reg gregset;
|
||||
struct fpreg fparegset;
|
||||
|
||||
switch (which)
|
||||
{
|
||||
case 0: /* Integer registers. */
|
||||
if (core_reg_size != sizeof (struct reg))
|
||||
warning (_("wrong size of register set in core file"));
|
||||
else
|
||||
{
|
||||
/* The memcpy may be unnecessary, but we can't really be sure
|
||||
of the alignment of the data in the core file. */
|
||||
memcpy (&gregset, core_reg_sect, sizeof (gregset));
|
||||
arm_supply_gregset (regcache, &gregset);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (core_reg_size != sizeof (struct fpreg))
|
||||
warning (_("wrong size of FPA register set in core file"));
|
||||
else
|
||||
{
|
||||
/* The memcpy may be unnecessary, but we can't really be sure
|
||||
of the alignment of the data in the core file. */
|
||||
memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
|
||||
arm_supply_fparegset (regcache, &fparegset);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Don't know what kind of register request this is; just ignore it. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct core_fns arm_netbsd_core_fns =
|
||||
{
|
||||
bfd_target_unknown_flavour, /* core_flovour. */
|
||||
default_check_format, /* check_format. */
|
||||
default_core_sniffer, /* core_sniffer. */
|
||||
fetch_core_registers, /* core_read_registers. */
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct core_fns arm_netbsd_elfcore_fns =
|
||||
{
|
||||
bfd_target_elf_flavour, /* core_flovour. */
|
||||
default_check_format, /* check_format. */
|
||||
default_core_sniffer, /* core_sniffer. */
|
||||
fetch_elfcore_registers, /* core_read_registers. */
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_arm_netbsd_nat (void)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
t = inf_ptrace_target ();
|
||||
t->to_fetch_registers = armnbsd_fetch_registers;
|
||||
t->to_store_registers = armnbsd_store_registers;
|
||||
add_target (t);
|
||||
|
||||
deprecated_add_core_fns (&arm_netbsd_core_fns);
|
||||
deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/* Target-dependent code for NetBSD/arm.
|
||||
|
||||
Copyright (C) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 "arm-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Description of the longjmp buffer. */
|
||||
#define ARM_NBSD_JB_PC 24
|
||||
#define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE
|
||||
|
||||
/* For compatibility with previous implemenations of GDB on arm/NetBSD,
|
||||
override the default little-endian breakpoint. */
|
||||
static const char arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
|
||||
static const char arm_nbsd_arm_be_breakpoint[] = {0xe6, 0x00, 0x00, 0x11};
|
||||
static const char arm_nbsd_thumb_le_breakpoint[] = {0xfe, 0xde};
|
||||
static const char arm_nbsd_thumb_be_breakpoint[] = {0xde, 0xfe};
|
||||
|
||||
static void
|
||||
arm_netbsd_init_abi_common (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
tdep->lowest_pc = 0x8000;
|
||||
switch (info.byte_order)
|
||||
{
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
|
||||
tdep->thumb_breakpoint = arm_nbsd_thumb_le_breakpoint;
|
||||
tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
|
||||
tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_le_breakpoint);
|
||||
break;
|
||||
|
||||
case BFD_ENDIAN_BIG:
|
||||
tdep->arm_breakpoint = arm_nbsd_arm_be_breakpoint;
|
||||
tdep->thumb_breakpoint = arm_nbsd_thumb_be_breakpoint;
|
||||
tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_be_breakpoint);
|
||||
tdep->thumb_breakpoint_size = sizeof (arm_nbsd_thumb_be_breakpoint);
|
||||
break;
|
||||
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("arm_gdbarch_init: bad byte order for float format"));
|
||||
}
|
||||
|
||||
tdep->jb_pc = ARM_NBSD_JB_PC;
|
||||
tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
|
||||
|
||||
/* Single stepping. */
|
||||
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
|
||||
}
|
||||
|
||||
static void
|
||||
arm_netbsd_aout_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
arm_netbsd_init_abi_common (info, gdbarch);
|
||||
if (tdep->fp_model == ARM_FLOAT_AUTO)
|
||||
tdep->fp_model = ARM_FLOAT_SOFT_FPA;
|
||||
}
|
||||
|
||||
static void
|
||||
arm_netbsd_elf_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
arm_netbsd_init_abi_common (info, gdbarch);
|
||||
if (tdep->fp_model == ARM_FLOAT_AUTO)
|
||||
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
|
||||
|
||||
/* NetBSD ELF uses SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
||||
}
|
||||
|
||||
static enum gdb_osabi
|
||||
arm_netbsd_aout_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
if (strcmp (bfd_get_target (abfd), "a.out-arm-netbsd") == 0)
|
||||
return GDB_OSABI_NETBSD_AOUT;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_arm_netbsd_tdep;
|
||||
|
||||
void
|
||||
_initialize_arm_netbsd_tdep (void)
|
||||
{
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_aout_flavour,
|
||||
arm_netbsd_aout_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_AOUT,
|
||||
arm_netbsd_aout_init_abi);
|
||||
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_NETBSD_ELF,
|
||||
arm_netbsd_elf_init_abi);
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/* Target-dependent code for OpenBSD/arm.
|
||||
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 "trad-frame.h"
|
||||
#include "tramp-frame.h"
|
||||
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "obsd-tdep.h"
|
||||
#include "arm-tdep.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
/* Signal trampolines. */
|
||||
|
||||
static void
|
||||
armobsd_sigframe_init (const struct tramp_frame *self,
|
||||
struct frame_info *this_frame,
|
||||
struct trad_frame_cache *cache,
|
||||
CORE_ADDR func)
|
||||
{
|
||||
CORE_ADDR sp, sigcontext_addr, addr;
|
||||
int regnum;
|
||||
|
||||
/* We find the appropriate instance of `struct sigcontext' at a
|
||||
fixed offset in the signal frame. */
|
||||
sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM);
|
||||
sigcontext_addr = sp + 16;
|
||||
|
||||
/* PC. */
|
||||
trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76);
|
||||
|
||||
/* GPRs. */
|
||||
for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12;
|
||||
regnum <= ARM_LR_REGNUM; regnum++, addr += 4)
|
||||
trad_frame_set_reg_addr (cache, regnum, addr);
|
||||
|
||||
trad_frame_set_id (cache, frame_id_build (sp, func));
|
||||
}
|
||||
|
||||
static const struct tramp_frame armobsd_sigframe =
|
||||
{
|
||||
SIGTRAMP_FRAME,
|
||||
4,
|
||||
{
|
||||
{ 0xe28d0010, -1 }, /* add r0, sp, #16 */
|
||||
{ 0xef000067, -1 }, /* swi SYS_sigreturn */
|
||||
{ 0xef000001, -1 }, /* swi SYS_exit */
|
||||
{ 0xeafffffc, -1 }, /* b . - 8 */
|
||||
{ TRAMP_SENTINEL_INSN, -1 }
|
||||
},
|
||||
armobsd_sigframe_init
|
||||
};
|
||||
|
||||
|
||||
/* Override default thumb breakpoints. */
|
||||
static const char arm_obsd_thumb_le_breakpoint[] = {0xfe, 0xdf};
|
||||
static const char arm_obsd_thumb_be_breakpoint[] = {0xdf, 0xfe};
|
||||
|
||||
static void
|
||||
armobsd_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
|
||||
if (tdep->fp_model == ARM_FLOAT_AUTO)
|
||||
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
|
||||
|
||||
tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
|
||||
|
||||
/* OpenBSD/arm uses SVR4-style shared libraries. */
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
|
||||
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
|
||||
|
||||
tdep->jb_pc = 24;
|
||||
tdep->jb_elt_size = 4;
|
||||
|
||||
set_gdbarch_regset_from_core_section
|
||||
(gdbarch, armbsd_regset_from_core_section);
|
||||
|
||||
/* OpenBSD/arm uses -fpcc-struct-return by default. */
|
||||
tdep->struct_return = pcc_struct_return;
|
||||
|
||||
/* Single stepping. */
|
||||
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
|
||||
|
||||
/* Breakpoints. */
|
||||
switch (info.byte_order)
|
||||
{
|
||||
case BFD_ENDIAN_BIG:
|
||||
tdep->thumb_breakpoint = arm_obsd_thumb_be_breakpoint;
|
||||
tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_be_breakpoint);
|
||||
break;
|
||||
|
||||
case BFD_ENDIAN_LITTLE:
|
||||
tdep->thumb_breakpoint = arm_obsd_thumb_le_breakpoint;
|
||||
tdep->thumb_breakpoint_size = sizeof (arm_obsd_thumb_le_breakpoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum gdb_osabi
|
||||
armobsd_core_osabi_sniffer (bfd *abfd)
|
||||
{
|
||||
if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
|
||||
return GDB_OSABI_OPENBSD_ELF;
|
||||
|
||||
return GDB_OSABI_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Provide a prototype to silence -Wmissing-prototypes. */
|
||||
extern initialize_file_ftype _initialize_armobsd_tdep;
|
||||
|
||||
void
|
||||
_initialize_armobsd_tdep (void)
|
||||
{
|
||||
/* BFD doesn't set a flavour for NetBSD style a.out core files. */
|
||||
gdbarch_register_osabi_sniffer (bfd_arch_arm, bfd_target_unknown_flavour,
|
||||
armobsd_core_osabi_sniffer);
|
||||
|
||||
gdbarch_register_osabi (bfd_arch_arm, 0, GDB_OSABI_OPENBSD_ELF,
|
||||
armobsd_init_abi);
|
||||
}
|
||||
451
gdb/auxv.c
451
gdb/auxv.c
@@ -1,451 +0,0 @@
|
||||
/* Auxiliary vector support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 "gdbtypes.h"
|
||||
#include "command.h"
|
||||
#include "inferior.h"
|
||||
#include "valprint.h"
|
||||
#include "gdb_assert.h"
|
||||
#include "gdbcore.h"
|
||||
|
||||
#include "auxv.h"
|
||||
#include "elf/common.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
/* This function handles access via /proc/PID/auxv, which is a common
|
||||
method for native targets. */
|
||||
|
||||
static LONGEST
|
||||
procfs_xfer_auxv (gdb_byte *readbuf,
|
||||
const gdb_byte *writebuf,
|
||||
ULONGEST offset,
|
||||
LONGEST len)
|
||||
{
|
||||
char *pathname;
|
||||
int fd;
|
||||
LONGEST n;
|
||||
|
||||
pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
|
||||
fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
|
||||
xfree (pathname);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
if (offset != (ULONGEST) 0
|
||||
&& lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
|
||||
n = -1;
|
||||
else if (readbuf != NULL)
|
||||
n = read (fd, readbuf, len);
|
||||
else
|
||||
n = write (fd, writebuf, len);
|
||||
|
||||
(void) close (fd);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* This function handles access via ld.so's symbol `_dl_auxv'. */
|
||||
|
||||
static LONGEST
|
||||
ld_so_xfer_auxv (gdb_byte *readbuf,
|
||||
const gdb_byte *writebuf,
|
||||
ULONGEST offset,
|
||||
LONGEST len)
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
CORE_ADDR data_address, pointer_address;
|
||||
struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
|
||||
size_t ptr_size = TYPE_LENGTH (ptr_type);
|
||||
size_t auxv_pair_size = 2 * ptr_size;
|
||||
gdb_byte *ptr_buf = alloca (ptr_size);
|
||||
LONGEST retval;
|
||||
size_t block;
|
||||
|
||||
msym = lookup_minimal_symbol ("_dl_auxv", NULL, NULL);
|
||||
if (msym == NULL)
|
||||
return -1;
|
||||
|
||||
if (MSYMBOL_SIZE (msym) != ptr_size)
|
||||
return -1;
|
||||
|
||||
/* POINTER_ADDRESS is a location where the `_dl_auxv' variable
|
||||
resides. DATA_ADDRESS is the inferior value present in
|
||||
`_dl_auxv', therefore the real inferior AUXV address. */
|
||||
|
||||
pointer_address = SYMBOL_VALUE_ADDRESS (msym);
|
||||
|
||||
/* The location of the _dl_auxv symbol may no longer be correct if
|
||||
ld.so runs at a different address than the one present in the
|
||||
file. This is very common case - for unprelinked ld.so or with a
|
||||
PIE executable. PIE executable forces random address even for
|
||||
libraries already being prelinked to some address. PIE
|
||||
executables themselves are never prelinked even on prelinked
|
||||
systems. Prelinking of a PIE executable would block their
|
||||
purpose of randomizing load of everything including the
|
||||
executable.
|
||||
|
||||
If the memory read fails, return -1 to fallback on another
|
||||
mechanism for retrieving the AUXV.
|
||||
|
||||
In most cases of a PIE running under valgrind there is no way to
|
||||
find out the base addresses of any of ld.so, executable or AUXV
|
||||
as everything is randomized and /proc information is not relevant
|
||||
for the virtual executable running under valgrind. We think that
|
||||
we might need a valgrind extension to make it work. This is PR
|
||||
11440. */
|
||||
|
||||
if (target_read_memory (pointer_address, ptr_buf, ptr_size) != 0)
|
||||
return -1;
|
||||
|
||||
data_address = extract_typed_address (ptr_buf, ptr_type);
|
||||
|
||||
/* Possibly still not initialized such as during an inferior
|
||||
startup. */
|
||||
if (data_address == 0)
|
||||
return -1;
|
||||
|
||||
data_address += offset;
|
||||
|
||||
if (writebuf != NULL)
|
||||
{
|
||||
if (target_write_memory (data_address, writebuf, len) == 0)
|
||||
return len;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Stop if trying to read past the existing AUXV block. The final
|
||||
AT_NULL was already returned before. */
|
||||
|
||||
if (offset >= auxv_pair_size)
|
||||
{
|
||||
if (target_read_memory (data_address - auxv_pair_size, ptr_buf,
|
||||
ptr_size) != 0)
|
||||
return -1;
|
||||
|
||||
if (extract_typed_address (ptr_buf, ptr_type) == AT_NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
block = 0x400;
|
||||
gdb_assert (block % auxv_pair_size == 0);
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
if (block > len)
|
||||
block = len;
|
||||
|
||||
/* Reading sizes smaller than AUXV_PAIR_SIZE is not supported.
|
||||
Tails unaligned to AUXV_PAIR_SIZE will not be read during a
|
||||
call (they should be completed during next read with
|
||||
new/extended buffer). */
|
||||
|
||||
block &= -auxv_pair_size;
|
||||
if (block == 0)
|
||||
return retval;
|
||||
|
||||
if (target_read_memory (data_address, readbuf, block) != 0)
|
||||
{
|
||||
if (block <= auxv_pair_size)
|
||||
return retval;
|
||||
|
||||
block = auxv_pair_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
data_address += block;
|
||||
len -= block;
|
||||
|
||||
/* Check terminal AT_NULL. This function is being called
|
||||
indefinitely being extended its READBUF until it returns EOF
|
||||
(0). */
|
||||
|
||||
while (block >= auxv_pair_size)
|
||||
{
|
||||
retval += auxv_pair_size;
|
||||
|
||||
if (extract_typed_address (readbuf, ptr_type) == AT_NULL)
|
||||
return retval;
|
||||
|
||||
readbuf += auxv_pair_size;
|
||||
block -= auxv_pair_size;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* This function is called like a to_xfer_partial hook, but must be
|
||||
called with TARGET_OBJECT_AUXV. It handles access to AUXV. */
|
||||
|
||||
LONGEST
|
||||
memory_xfer_auxv (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex,
|
||||
gdb_byte *readbuf,
|
||||
const gdb_byte *writebuf,
|
||||
ULONGEST offset,
|
||||
LONGEST len)
|
||||
{
|
||||
gdb_assert (object == TARGET_OBJECT_AUXV);
|
||||
gdb_assert (readbuf || writebuf);
|
||||
|
||||
/* ld_so_xfer_auxv is the only function safe for virtual
|
||||
executables being executed by valgrind's memcheck. Using
|
||||
ld_so_xfer_auxv during inferior startup is problematic, because
|
||||
ld.so symbol tables have not yet been relocated. So GDB uses
|
||||
this function only when attaching to a process.
|
||||
*/
|
||||
|
||||
if (current_inferior ()->attach_flag != 0)
|
||||
{
|
||||
LONGEST retval;
|
||||
|
||||
retval = ld_so_xfer_auxv (readbuf, writebuf, offset, len);
|
||||
if (retval != -1)
|
||||
return retval;
|
||||
}
|
||||
|
||||
return procfs_xfer_auxv (readbuf, writebuf, offset, len);
|
||||
}
|
||||
|
||||
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
|
||||
Return 0 if *READPTR is already at the end of the buffer.
|
||||
Return -1 if there is insufficient buffer for a whole entry.
|
||||
Return 1 if an entry was read into *TYPEP and *VALP. */
|
||||
static int
|
||||
default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
|
||||
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
|
||||
{
|
||||
const int sizeof_auxv_field = gdbarch_ptr_bit (target_gdbarch)
|
||||
/ TARGET_CHAR_BIT;
|
||||
const enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
|
||||
gdb_byte *ptr = *readptr;
|
||||
|
||||
if (endptr == ptr)
|
||||
return 0;
|
||||
|
||||
if (endptr - ptr < sizeof_auxv_field * 2)
|
||||
return -1;
|
||||
|
||||
*typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
|
||||
ptr += sizeof_auxv_field;
|
||||
*valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
|
||||
ptr += sizeof_auxv_field;
|
||||
|
||||
*readptr = ptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
|
||||
Return 0 if *READPTR is already at the end of the buffer.
|
||||
Return -1 if there is insufficient buffer for a whole entry.
|
||||
Return 1 if an entry was read into *TYPEP and *VALP. */
|
||||
int
|
||||
target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
|
||||
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
|
||||
{
|
||||
struct target_ops *t;
|
||||
|
||||
for (t = ops; t != NULL; t = t->beneath)
|
||||
if (t->to_auxv_parse != NULL)
|
||||
return t->to_auxv_parse (t, readptr, endptr, typep, valp);
|
||||
|
||||
return default_auxv_parse (ops, readptr, endptr, typep, valp);
|
||||
}
|
||||
|
||||
/* Extract the auxiliary vector entry with a_type matching MATCH.
|
||||
Return zero if no such entry was found, or -1 if there was
|
||||
an error getting the information. On success, return 1 after
|
||||
storing the entry's value field in *VALP. */
|
||||
int
|
||||
target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
|
||||
{
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
|
||||
gdb_byte *ptr = data;
|
||||
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
while (1)
|
||||
switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
|
||||
{
|
||||
case 1: /* Here's an entry, check it. */
|
||||
if (type == match)
|
||||
{
|
||||
xfree (data);
|
||||
*valp = val;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 0: /* End of the vector. */
|
||||
xfree (data);
|
||||
return 0;
|
||||
default: /* Bogosity. */
|
||||
xfree (data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
/* Print the contents of the target's AUXV on the specified file. */
|
||||
int
|
||||
fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
|
||||
{
|
||||
CORE_ADDR type, val;
|
||||
gdb_byte *data;
|
||||
LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
|
||||
&data);
|
||||
gdb_byte *ptr = data;
|
||||
int ents = 0;
|
||||
|
||||
if (len <= 0)
|
||||
return len;
|
||||
|
||||
while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
|
||||
{
|
||||
const char *name = "???";
|
||||
const char *description = "";
|
||||
enum { dec, hex, str } flavor = hex;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#define TAG(tag, text, kind) \
|
||||
case tag: name = #tag; description = text; flavor = kind; break
|
||||
TAG (AT_NULL, _("End of vector"), hex);
|
||||
TAG (AT_IGNORE, _("Entry should be ignored"), hex);
|
||||
TAG (AT_EXECFD, _("File descriptor of program"), dec);
|
||||
TAG (AT_PHDR, _("Program headers for program"), hex);
|
||||
TAG (AT_PHENT, _("Size of program header entry"), dec);
|
||||
TAG (AT_PHNUM, _("Number of program headers"), dec);
|
||||
TAG (AT_PAGESZ, _("System page size"), dec);
|
||||
TAG (AT_BASE, _("Base address of interpreter"), hex);
|
||||
TAG (AT_FLAGS, _("Flags"), hex);
|
||||
TAG (AT_ENTRY, _("Entry point of program"), hex);
|
||||
TAG (AT_NOTELF, _("Program is not ELF"), dec);
|
||||
TAG (AT_UID, _("Real user ID"), dec);
|
||||
TAG (AT_EUID, _("Effective user ID"), dec);
|
||||
TAG (AT_GID, _("Real group ID"), dec);
|
||||
TAG (AT_EGID, _("Effective group ID"), dec);
|
||||
TAG (AT_CLKTCK, _("Frequency of times()"), dec);
|
||||
TAG (AT_PLATFORM, _("String identifying platform"), str);
|
||||
TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
|
||||
TAG (AT_FPUCW, _("Used FPU control word"), dec);
|
||||
TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
|
||||
TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
|
||||
TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
|
||||
TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
|
||||
TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
|
||||
TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
|
||||
TAG (AT_EXECFN, _("File name of executable"), str);
|
||||
TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
|
||||
TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
|
||||
TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
|
||||
TAG (AT_SUN_UID, _("Effective user ID"), dec);
|
||||
TAG (AT_SUN_RUID, _("Real user ID"), dec);
|
||||
TAG (AT_SUN_GID, _("Effective group ID"), dec);
|
||||
TAG (AT_SUN_RGID, _("Real group ID"), dec);
|
||||
TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
|
||||
TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
|
||||
TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
|
||||
TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
|
||||
TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
|
||||
TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
|
||||
TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
|
||||
TAG (AT_SUN_CPU, _("CPU name string"), str);
|
||||
TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
|
||||
TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
|
||||
TAG (AT_SUN_EXECNAME,
|
||||
_("Canonicalized file name given to execve"), str);
|
||||
TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
|
||||
TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
|
||||
TAG (AT_SUN_AUXFLAGS,
|
||||
_("AF_SUN_ flags passed from the kernel"), hex);
|
||||
}
|
||||
|
||||
fprintf_filtered (file, "%-4s %-20s %-30s ",
|
||||
plongest (type), name, description);
|
||||
switch (flavor)
|
||||
{
|
||||
case dec:
|
||||
fprintf_filtered (file, "%s\n", plongest (val));
|
||||
break;
|
||||
case hex:
|
||||
fprintf_filtered (file, "%s\n", paddress (target_gdbarch, val));
|
||||
break;
|
||||
case str:
|
||||
{
|
||||
struct value_print_options opts;
|
||||
|
||||
get_user_print_options (&opts);
|
||||
if (opts.addressprint)
|
||||
fprintf_filtered (file, "%s", paddress (target_gdbarch, val));
|
||||
val_print_string (builtin_type (target_gdbarch)->builtin_char,
|
||||
NULL, val, -1, file, &opts);
|
||||
fprintf_filtered (file, "\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
++ents;
|
||||
if (type == AT_NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
xfree (data);
|
||||
|
||||
return ents;
|
||||
}
|
||||
|
||||
static void
|
||||
info_auxv_command (char *cmd, int from_tty)
|
||||
{
|
||||
if (! target_has_stack)
|
||||
error (_("The program has no auxiliary information now."));
|
||||
else
|
||||
{
|
||||
int ents = fprint_target_auxv (gdb_stdout, ¤t_target);
|
||||
|
||||
if (ents < 0)
|
||||
error (_("No auxiliary vector found, or failed reading it."));
|
||||
else if (ents == 0)
|
||||
error (_("Auxiliary vector is empty."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
|
||||
|
||||
void
|
||||
_initialize_auxv (void)
|
||||
{
|
||||
add_info ("auxv", info_auxv_command,
|
||||
_("Display the inferior's auxiliary vector.\n\
|
||||
This is information provided by the operating system at program startup."));
|
||||
}
|
||||
55
gdb/auxv.h
55
gdb/auxv.h
@@ -1,55 +0,0 @@
|
||||
/* Auxiliary vector support for GDB, the GNU debugger.
|
||||
|
||||
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
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 AUXV_H
|
||||
#define AUXV_H
|
||||
|
||||
#include "target.h"
|
||||
|
||||
/* See "include/elf/common.h" for the definition of valid AT_* values. */
|
||||
|
||||
/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
|
||||
Return 0 if *READPTR is already at the end of the buffer.
|
||||
Return -1 if there is insufficient buffer for a whole entry.
|
||||
Return 1 if an entry was read into *TYPEP and *VALP. */
|
||||
extern int target_auxv_parse (struct target_ops *ops,
|
||||
gdb_byte **readptr, gdb_byte *endptr,
|
||||
CORE_ADDR *typep, CORE_ADDR *valp);
|
||||
|
||||
/* Extract the auxiliary vector entry with a_type matching MATCH.
|
||||
Return zero if no such entry was found, or -1 if there was
|
||||
an error getting the information. On success, return 1 after
|
||||
storing the entry's value field in *VALP. */
|
||||
extern int target_auxv_search (struct target_ops *ops,
|
||||
CORE_ADDR match, CORE_ADDR *valp);
|
||||
|
||||
/* Print the contents of the target's AUXV on the specified file. */
|
||||
extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops);
|
||||
|
||||
extern LONGEST memory_xfer_auxv (struct target_ops *ops,
|
||||
enum target_object object,
|
||||
const char *annex,
|
||||
gdb_byte *readbuf,
|
||||
const gdb_byte *writebuf,
|
||||
ULONGEST offset,
|
||||
LONGEST len);
|
||||
|
||||
|
||||
#endif
|
||||
1554
gdb/avr-tdep.c
1554
gdb/avr-tdep.c
File diff suppressed because it is too large
Load Diff
2531
gdb/ax-gdb.c
2531
gdb/ax-gdb.c
File diff suppressed because it is too large
Load Diff
113
gdb/ax-gdb.h
113
gdb/ax-gdb.h
@@ -1,113 +0,0 @@
|
||||
/* GDB-specific functions for operating on agent expressions
|
||||
Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
|
||||
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 AX_GDB_H
|
||||
#define AX_GDB_H
|
||||
|
||||
struct expression;
|
||||
|
||||
/* Types and enums */
|
||||
|
||||
/* GDB stores expressions in the form of a flattened tree (struct
|
||||
expression), so we just walk that tree and generate agent bytecodes
|
||||
as we go along.
|
||||
|
||||
GDB's normal evaluation uses struct value, which contains the
|
||||
expression's value as well as its address or the register it came
|
||||
from. The `+' operator uses the value, whereas the unary `&'
|
||||
operator will use the address portion. The `=' operator will use
|
||||
the address or register number of its left hand side.
|
||||
|
||||
The issues are different when generating agent bytecode. Given a
|
||||
variable reference expression, we should not necessarily generate
|
||||
code to fetch its value, because the next operator may be `=' or
|
||||
unary `&'. Instead, when we recurse on a subexpression, we
|
||||
indicate whether we want that expression to produce an lvalue or an
|
||||
rvalue. If we requested an lvalue, then the recursive call tells
|
||||
us whether it generated code to compute an address on the stack, or
|
||||
whether the lvalue lives in a register.
|
||||
|
||||
The `axs' prefix here means `agent expression, static', because
|
||||
this is all static analysis of the expression, i.e. analysis which
|
||||
doesn't depend on the contents of memory and registers. */
|
||||
|
||||
|
||||
/* Different kinds of agent expression static values. */
|
||||
enum axs_lvalue_kind
|
||||
{
|
||||
/* We generated code to compute the subexpression's value.
|
||||
Constants and arithmetic operators yield this. */
|
||||
axs_rvalue,
|
||||
|
||||
/* We generated code to yield the subexpression's value's address on
|
||||
the top of the stack. If the caller needs an rvalue, it should
|
||||
call require_rvalue to produce the rvalue from this address. */
|
||||
axs_lvalue_memory,
|
||||
|
||||
/* We didn't generate any code, and the stack is undisturbed,
|
||||
because the subexpression's value lives in a register; u.reg is
|
||||
the register number. If the caller needs an rvalue, it should
|
||||
call require_rvalue to produce the rvalue from this register
|
||||
number. */
|
||||
axs_lvalue_register
|
||||
};
|
||||
|
||||
/* Structure describing what we got from a subexpression. Think of
|
||||
this as parallel to value.h's enum lval_type, except that we're
|
||||
describing a value which will exist when the expression is
|
||||
evaluated in the future, not a value we have in our hand. */
|
||||
struct axs_value
|
||||
{
|
||||
enum axs_lvalue_kind kind; /* see above */
|
||||
|
||||
/* The type of the subexpression. Even if lvalue == axs_lvalue_memory,
|
||||
this is the type of the value itself; the value on the stack is a
|
||||
"pointer to" an object of this type. */
|
||||
struct type *type;
|
||||
|
||||
/* If nonzero, this is a variable which does not actually exist in
|
||||
the program. */
|
||||
char optimized_out;
|
||||
|
||||
union
|
||||
{
|
||||
/* if kind == axs_lvalue_register, this is the register number */
|
||||
int reg;
|
||||
}
|
||||
u;
|
||||
};
|
||||
|
||||
|
||||
/* Translating GDB expressions into agent expressions. */
|
||||
|
||||
/* Given a GDB expression EXPR, return bytecode to trace its value.
|
||||
The result will use the `trace' and `trace_quick' bytecodes to
|
||||
record the value of all memory touched by the expression, and leave
|
||||
no values on the stack. The caller can then use the ax_reqs
|
||||
function to discover which registers the expression uses. */
|
||||
extern struct agent_expr *gen_trace_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
extern struct agent_expr *gen_trace_for_var (CORE_ADDR, struct gdbarch *,
|
||||
struct symbol *);
|
||||
|
||||
extern struct agent_expr *gen_eval_for_expr (CORE_ADDR, struct expression *);
|
||||
|
||||
extern int trace_kludge;
|
||||
|
||||
#endif /* AX_GDB_H */
|
||||
576
gdb/ax-general.c
576
gdb/ax-general.c
@@ -1,576 +0,0 @@
|
||||
/* Functions for manipulating expressions designed to be executed on the agent
|
||||
Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009, 2010, 2011
|
||||
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/>. */
|
||||
|
||||
/* Despite what the above comment says about this file being part of
|
||||
GDB, we would like to keep these functions free of GDB
|
||||
dependencies, since we want to be able to use them in contexts
|
||||
outside of GDB (test suites, the stub, etc.) */
|
||||
|
||||
#include "defs.h"
|
||||
#include "ax.h"
|
||||
|
||||
#include "value.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
#include "user-regs.h"
|
||||
|
||||
static void grow_expr (struct agent_expr *x, int n);
|
||||
|
||||
static void append_const (struct agent_expr *x, LONGEST val, int n);
|
||||
|
||||
static LONGEST read_const (struct agent_expr *x, int o, int n);
|
||||
|
||||
static void generic_ext (struct agent_expr *x, enum agent_op op, int n);
|
||||
|
||||
/* Functions for building expressions. */
|
||||
|
||||
/* Allocate a new, empty agent expression. */
|
||||
struct agent_expr *
|
||||
new_agent_expr (struct gdbarch *gdbarch, CORE_ADDR scope)
|
||||
{
|
||||
struct agent_expr *x = xmalloc (sizeof (*x));
|
||||
|
||||
x->len = 0;
|
||||
x->size = 1; /* Change this to a larger value once
|
||||
reallocation code is tested. */
|
||||
x->buf = xmalloc (x->size);
|
||||
|
||||
x->gdbarch = gdbarch;
|
||||
x->scope = scope;
|
||||
|
||||
/* Bit vector for registers used. */
|
||||
x->reg_mask_len = 1;
|
||||
x->reg_mask = xmalloc (x->reg_mask_len * sizeof (x->reg_mask[0]));
|
||||
memset (x->reg_mask, 0, x->reg_mask_len * sizeof (x->reg_mask[0]));
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Free a agent expression. */
|
||||
void
|
||||
free_agent_expr (struct agent_expr *x)
|
||||
{
|
||||
xfree (x->buf);
|
||||
xfree (x->reg_mask);
|
||||
xfree (x);
|
||||
}
|
||||
|
||||
static void
|
||||
do_free_agent_expr_cleanup (void *x)
|
||||
{
|
||||
free_agent_expr (x);
|
||||
}
|
||||
|
||||
struct cleanup *
|
||||
make_cleanup_free_agent_expr (struct agent_expr *x)
|
||||
{
|
||||
return make_cleanup (do_free_agent_expr_cleanup, x);
|
||||
}
|
||||
|
||||
|
||||
/* Make sure that X has room for at least N more bytes. This doesn't
|
||||
affect the length, just the allocated size. */
|
||||
static void
|
||||
grow_expr (struct agent_expr *x, int n)
|
||||
{
|
||||
if (x->len + n > x->size)
|
||||
{
|
||||
x->size *= 2;
|
||||
if (x->size < x->len + n)
|
||||
x->size = x->len + n + 10;
|
||||
x->buf = xrealloc (x->buf, x->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Append the low N bytes of VAL as an N-byte integer to the
|
||||
expression X, in big-endian order. */
|
||||
static void
|
||||
append_const (struct agent_expr *x, LONGEST val, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
grow_expr (x, n);
|
||||
for (i = n - 1; i >= 0; i--)
|
||||
{
|
||||
x->buf[x->len + i] = val & 0xff;
|
||||
val >>= 8;
|
||||
}
|
||||
x->len += n;
|
||||
}
|
||||
|
||||
|
||||
/* Extract an N-byte big-endian unsigned integer from expression X at
|
||||
offset O. */
|
||||
static LONGEST
|
||||
read_const (struct agent_expr *x, int o, int n)
|
||||
{
|
||||
int i;
|
||||
LONGEST accum = 0;
|
||||
|
||||
/* Make sure we're not reading off the end of the expression. */
|
||||
if (o + n > x->len)
|
||||
error (_("GDB bug: ax-general.c (read_const): incomplete constant"));
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
accum = (accum << 8) | x->buf[o + i];
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
|
||||
/* Append a simple operator OP to EXPR. */
|
||||
void
|
||||
ax_simple (struct agent_expr *x, enum agent_op op)
|
||||
{
|
||||
grow_expr (x, 1);
|
||||
x->buf[x->len++] = op;
|
||||
}
|
||||
|
||||
/* Append a pick operator to EXPR. DEPTH is the stack item to pick,
|
||||
with 0 being top of stack. */
|
||||
|
||||
void
|
||||
ax_pick (struct agent_expr *x, int depth)
|
||||
{
|
||||
if (depth < 0 || depth > 255)
|
||||
error (_("GDB bug: ax-general.c (ax_pick): stack depth out of range"));
|
||||
ax_simple (x, aop_pick);
|
||||
append_const (x, 1, depth);
|
||||
}
|
||||
|
||||
|
||||
/* Append a sign-extension or zero-extension instruction to EXPR, to
|
||||
extend an N-bit value. */
|
||||
static void
|
||||
generic_ext (struct agent_expr *x, enum agent_op op, int n)
|
||||
{
|
||||
/* N must fit in a byte. */
|
||||
if (n < 0 || n > 255)
|
||||
error (_("GDB bug: ax-general.c (generic_ext): bit count out of range"));
|
||||
/* That had better be enough range. */
|
||||
if (sizeof (LONGEST) * 8 > 255)
|
||||
error (_("GDB bug: ax-general.c (generic_ext): "
|
||||
"opcode has inadequate range"));
|
||||
|
||||
grow_expr (x, 2);
|
||||
x->buf[x->len++] = op;
|
||||
x->buf[x->len++] = n;
|
||||
}
|
||||
|
||||
|
||||
/* Append a sign-extension instruction to EXPR, to extend an N-bit value. */
|
||||
void
|
||||
ax_ext (struct agent_expr *x, int n)
|
||||
{
|
||||
generic_ext (x, aop_ext, n);
|
||||
}
|
||||
|
||||
|
||||
/* Append a zero-extension instruction to EXPR, to extend an N-bit value. */
|
||||
void
|
||||
ax_zero_ext (struct agent_expr *x, int n)
|
||||
{
|
||||
generic_ext (x, aop_zero_ext, n);
|
||||
}
|
||||
|
||||
|
||||
/* Append a trace_quick instruction to EXPR, to record N bytes. */
|
||||
void
|
||||
ax_trace_quick (struct agent_expr *x, int n)
|
||||
{
|
||||
/* N must fit in a byte. */
|
||||
if (n < 0 || n > 255)
|
||||
error (_("GDB bug: ax-general.c (ax_trace_quick): "
|
||||
"size out of range for trace_quick"));
|
||||
|
||||
grow_expr (x, 2);
|
||||
x->buf[x->len++] = aop_trace_quick;
|
||||
x->buf[x->len++] = n;
|
||||
}
|
||||
|
||||
|
||||
/* Append a goto op to EXPR. OP is the actual op (must be aop_goto or
|
||||
aop_if_goto). We assume we don't know the target offset yet,
|
||||
because it's probably a forward branch, so we leave space in EXPR
|
||||
for the target, and return the offset in EXPR of that space, so we
|
||||
can backpatch it once we do know the target offset. Use ax_label
|
||||
to do the backpatching. */
|
||||
int
|
||||
ax_goto (struct agent_expr *x, enum agent_op op)
|
||||
{
|
||||
grow_expr (x, 3);
|
||||
x->buf[x->len + 0] = op;
|
||||
x->buf[x->len + 1] = 0xff;
|
||||
x->buf[x->len + 2] = 0xff;
|
||||
x->len += 3;
|
||||
return x->len - 2;
|
||||
}
|
||||
|
||||
/* Suppose a given call to ax_goto returns some value PATCH. When you
|
||||
know the offset TARGET that goto should jump to, call
|
||||
ax_label (EXPR, PATCH, TARGET)
|
||||
to patch TARGET into the ax_goto instruction. */
|
||||
void
|
||||
ax_label (struct agent_expr *x, int patch, int target)
|
||||
{
|
||||
/* Make sure the value is in range. Don't accept 0xffff as an
|
||||
offset; that's our magic sentinel value for unpatched branches. */
|
||||
if (target < 0 || target >= 0xffff)
|
||||
error (_("GDB bug: ax-general.c (ax_label): label target out of range"));
|
||||
|
||||
x->buf[patch] = (target >> 8) & 0xff;
|
||||
x->buf[patch + 1] = target & 0xff;
|
||||
}
|
||||
|
||||
|
||||
/* Assemble code to push a constant on the stack. */
|
||||
void
|
||||
ax_const_l (struct agent_expr *x, LONGEST l)
|
||||
{
|
||||
static enum agent_op ops[]
|
||||
=
|
||||
{aop_const8, aop_const16, aop_const32, aop_const64};
|
||||
int size;
|
||||
int op;
|
||||
|
||||
/* How big is the number? 'op' keeps track of which opcode to use.
|
||||
Notice that we don't really care whether the original number was
|
||||
signed or unsigned; we always reproduce the value exactly, and
|
||||
use the shortest representation. */
|
||||
for (op = 0, size = 8; size < 64; size *= 2, op++)
|
||||
{
|
||||
LONGEST lim = ((LONGEST) 1) << (size - 1);
|
||||
|
||||
if (-lim <= l && l <= lim - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Emit the right opcode... */
|
||||
ax_simple (x, ops[op]);
|
||||
|
||||
/* Emit the low SIZE bytes as an unsigned number. We know that
|
||||
sign-extending this will yield l. */
|
||||
append_const (x, l, size / 8);
|
||||
|
||||
/* Now, if it was negative, and not full-sized, sign-extend it. */
|
||||
if (l < 0 && size < 64)
|
||||
ax_ext (x, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ax_const_d (struct agent_expr *x, LONGEST d)
|
||||
{
|
||||
/* FIXME: floating-point support not present yet. */
|
||||
error (_("GDB bug: ax-general.c (ax_const_d): "
|
||||
"floating point not supported yet"));
|
||||
}
|
||||
|
||||
|
||||
/* Assemble code to push the value of register number REG on the
|
||||
stack. */
|
||||
void
|
||||
ax_reg (struct agent_expr *x, int reg)
|
||||
{
|
||||
if (reg >= gdbarch_num_regs (x->gdbarch))
|
||||
{
|
||||
/* This is a pseudo-register. */
|
||||
if (!gdbarch_ax_pseudo_register_push_stack_p (x->gdbarch))
|
||||
error (_("'%s' is a pseudo-register; "
|
||||
"GDB cannot yet trace its contents."),
|
||||
user_reg_map_regnum_to_name (x->gdbarch, reg));
|
||||
if (gdbarch_ax_pseudo_register_push_stack (x->gdbarch, x, reg))
|
||||
error (_("Trace '%s' failed."),
|
||||
user_reg_map_regnum_to_name (x->gdbarch, reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make sure the register number is in range. */
|
||||
if (reg < 0 || reg > 0xffff)
|
||||
error (_("GDB bug: ax-general.c (ax_reg): "
|
||||
"register number out of range"));
|
||||
grow_expr (x, 3);
|
||||
x->buf[x->len] = aop_reg;
|
||||
x->buf[x->len + 1] = (reg >> 8) & 0xff;
|
||||
x->buf[x->len + 2] = (reg) & 0xff;
|
||||
x->len += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assemble code to operate on a trace state variable. */
|
||||
|
||||
void
|
||||
ax_tsv (struct agent_expr *x, enum agent_op op, int num)
|
||||
{
|
||||
/* Make sure the tsv number is in range. */
|
||||
if (num < 0 || num > 0xffff)
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("ax-general.c (ax_tsv): variable "
|
||||
"number is %d, out of range"), num);
|
||||
|
||||
grow_expr (x, 3);
|
||||
x->buf[x->len] = op;
|
||||
x->buf[x->len + 1] = (num >> 8) & 0xff;
|
||||
x->buf[x->len + 2] = (num) & 0xff;
|
||||
x->len += 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Functions for disassembling agent expressions, and otherwise
|
||||
debugging the expression compiler. */
|
||||
|
||||
struct aop_map aop_map[] =
|
||||
{
|
||||
{0, 0, 0, 0, 0}
|
||||
#define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \
|
||||
, { # NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED }
|
||||
#include "ax.def"
|
||||
#undef DEFOP
|
||||
};
|
||||
|
||||
|
||||
/* Disassemble the expression EXPR, writing to F. */
|
||||
void
|
||||
ax_print (struct ui_file *f, struct agent_expr *x)
|
||||
{
|
||||
int i;
|
||||
int is_float = 0;
|
||||
|
||||
fprintf_filtered (f, _("Scope: %s\n"), paddress (x->gdbarch, x->scope));
|
||||
fprintf_filtered (f, _("Reg mask:"));
|
||||
for (i = 0; i < x->reg_mask_len; ++i)
|
||||
fprintf_filtered (f, _(" %02x"), x->reg_mask[i]);
|
||||
fprintf_filtered (f, _("\n"));
|
||||
|
||||
/* Check the size of the name array against the number of entries in
|
||||
the enum, to catch additions that people didn't sync. */
|
||||
if ((sizeof (aop_map) / sizeof (aop_map[0]))
|
||||
!= aop_last)
|
||||
error (_("GDB bug: ax-general.c (ax_print): opcode map out of sync"));
|
||||
|
||||
for (i = 0; i < x->len;)
|
||||
{
|
||||
enum agent_op op = x->buf[i];
|
||||
|
||||
if (op >= (sizeof (aop_map) / sizeof (aop_map[0]))
|
||||
|| !aop_map[op].name)
|
||||
{
|
||||
fprintf_filtered (f, _("%3d <bad opcode %02x>\n"), i, op);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (i + 1 + aop_map[op].op_size > x->len)
|
||||
{
|
||||
fprintf_filtered (f, _("%3d <incomplete opcode %s>\n"),
|
||||
i, aop_map[op].name);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf_filtered (f, "%3d %s", i, aop_map[op].name);
|
||||
if (aop_map[op].op_size > 0)
|
||||
{
|
||||
fputs_filtered (" ", f);
|
||||
|
||||
print_longest (f, 'd', 0,
|
||||
read_const (x, i + 1, aop_map[op].op_size));
|
||||
}
|
||||
fprintf_filtered (f, "\n");
|
||||
i += 1 + aop_map[op].op_size;
|
||||
|
||||
is_float = (op == aop_float);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add register REG to the register mask for expression AX. */
|
||||
void
|
||||
ax_reg_mask (struct agent_expr *ax, int reg)
|
||||
{
|
||||
if (reg >= gdbarch_num_regs (ax->gdbarch))
|
||||
{
|
||||
/* This is a pseudo-register. */
|
||||
if (!gdbarch_ax_pseudo_register_collect_p (ax->gdbarch))
|
||||
error (_("'%s' is a pseudo-register; "
|
||||
"GDB cannot yet trace its contents."),
|
||||
user_reg_map_regnum_to_name (ax->gdbarch, reg));
|
||||
if (gdbarch_ax_pseudo_register_collect (ax->gdbarch, ax, reg))
|
||||
error (_("Trace '%s' failed."),
|
||||
user_reg_map_regnum_to_name (ax->gdbarch, reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
int byte = reg / 8;
|
||||
|
||||
/* Grow the bit mask if necessary. */
|
||||
if (byte >= ax->reg_mask_len)
|
||||
{
|
||||
/* It's not appropriate to double here. This isn't a
|
||||
string buffer. */
|
||||
int new_len = byte + 1;
|
||||
unsigned char *new_reg_mask = xrealloc (ax->reg_mask,
|
||||
new_len
|
||||
* sizeof (ax->reg_mask[0]));
|
||||
memset (new_reg_mask + ax->reg_mask_len, 0,
|
||||
(new_len - ax->reg_mask_len) * sizeof (ax->reg_mask[0]));
|
||||
ax->reg_mask_len = new_len;
|
||||
ax->reg_mask = new_reg_mask;
|
||||
}
|
||||
|
||||
ax->reg_mask[byte] |= 1 << (reg % 8);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an agent expression AX, fill in requirements and other descriptive
|
||||
bits. */
|
||||
void
|
||||
ax_reqs (struct agent_expr *ax)
|
||||
{
|
||||
int i;
|
||||
int height;
|
||||
|
||||
/* Jump target table. targets[i] is non-zero iff we have found a
|
||||
jump to offset i. */
|
||||
char *targets = (char *) alloca (ax->len * sizeof (targets[0]));
|
||||
|
||||
/* Instruction boundary table. boundary[i] is non-zero iff our scan
|
||||
has reached an instruction starting at offset i. */
|
||||
char *boundary = (char *) alloca (ax->len * sizeof (boundary[0]));
|
||||
|
||||
/* Stack height record. If either targets[i] or boundary[i] is
|
||||
non-zero, heights[i] is the height the stack should have before
|
||||
executing the bytecode at that point. */
|
||||
int *heights = (int *) alloca (ax->len * sizeof (heights[0]));
|
||||
|
||||
/* Pointer to a description of the present op. */
|
||||
struct aop_map *op;
|
||||
|
||||
memset (targets, 0, ax->len * sizeof (targets[0]));
|
||||
memset (boundary, 0, ax->len * sizeof (boundary[0]));
|
||||
|
||||
ax->max_height = ax->min_height = height = 0;
|
||||
ax->flaw = agent_flaw_none;
|
||||
ax->max_data_size = 0;
|
||||
|
||||
for (i = 0; i < ax->len; i += 1 + op->op_size)
|
||||
{
|
||||
if (ax->buf[i] > (sizeof (aop_map) / sizeof (aop_map[0])))
|
||||
{
|
||||
ax->flaw = agent_flaw_bad_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
op = &aop_map[ax->buf[i]];
|
||||
|
||||
if (!op->name)
|
||||
{
|
||||
ax->flaw = agent_flaw_bad_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
if (i + 1 + op->op_size > ax->len)
|
||||
{
|
||||
ax->flaw = agent_flaw_incomplete_instruction;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this instruction is a forward jump target, does the
|
||||
current stack height match the stack height at the jump
|
||||
source? */
|
||||
if (targets[i] && (heights[i] != height))
|
||||
{
|
||||
ax->flaw = agent_flaw_height_mismatch;
|
||||
return;
|
||||
}
|
||||
|
||||
boundary[i] = 1;
|
||||
heights[i] = height;
|
||||
|
||||
height -= op->consumed;
|
||||
if (height < ax->min_height)
|
||||
ax->min_height = height;
|
||||
height += op->produced;
|
||||
if (height > ax->max_height)
|
||||
ax->max_height = height;
|
||||
|
||||
if (op->data_size > ax->max_data_size)
|
||||
ax->max_data_size = op->data_size;
|
||||
|
||||
/* For jump instructions, check that the target is a valid
|
||||
offset. If it is, record the fact that that location is a
|
||||
jump target, and record the height we expect there. */
|
||||
if (aop_goto == op - aop_map
|
||||
|| aop_if_goto == op - aop_map)
|
||||
{
|
||||
int target = read_const (ax, i + 1, 2);
|
||||
if (target < 0 || target >= ax->len)
|
||||
{
|
||||
ax->flaw = agent_flaw_bad_jump;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Do we have any information about what the stack height
|
||||
should be at the target? */
|
||||
if (targets[target] || boundary[target])
|
||||
{
|
||||
if (heights[target] != height)
|
||||
{
|
||||
ax->flaw = agent_flaw_height_mismatch;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Record the target, along with the stack height we expect. */
|
||||
targets[target] = 1;
|
||||
heights[target] = height;
|
||||
}
|
||||
|
||||
/* For unconditional jumps with a successor, check that the
|
||||
successor is a target, and pick up its stack height. */
|
||||
if (aop_goto == op - aop_map
|
||||
&& i + 3 < ax->len)
|
||||
{
|
||||
if (!targets[i + 3])
|
||||
{
|
||||
ax->flaw = agent_flaw_hole;
|
||||
return;
|
||||
}
|
||||
|
||||
height = heights[i + 3];
|
||||
}
|
||||
|
||||
/* For reg instructions, record the register in the bit mask. */
|
||||
if (aop_reg == op - aop_map)
|
||||
{
|
||||
int reg = read_const (ax, i + 1, 2);
|
||||
|
||||
ax_reg_mask (ax, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that all the targets are on boundaries. */
|
||||
for (i = 0; i < ax->len; i++)
|
||||
if (targets[i] && !boundary[i])
|
||||
{
|
||||
ax->flaw = agent_flaw_bad_jump;
|
||||
return;
|
||||
}
|
||||
|
||||
ax->final_height = height;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user