]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
This commit was manufactured by cvs2svn to create branch
authornobody <>
Mon, 30 Sep 2002 15:57:27 +0000 (15:57 +0000)
committernobody <>
Mon, 30 Sep 2002 15:57:27 +0000 (15:57 +0000)
'kseitz_interps-20020528-branch'.

Cherrypick from master 2002-09-30 15:57:26 UTC Fernando Nasser <fnasser@redhat.com> ' * disasm.c: New file.':
    bfd/elf32-i386-fbsd.c
    bfd/elf64-alpha-fbsd.c
    bfd/po/da.po
    gdb/charset.c
    gdb/charset.h
    gdb/config/i386/nbsd.mt
    gdb/cp-support.c
    gdb/cp-support.h
    gdb/disasm.c
    gdb/disasm.h
    gdb/gdb.c
    gdb/gdb_mbuild.sh
    gdb/main.h
    gdb/objc-exp.y
    gdb/objc-lang.c
    gdb/objc-lang.h
    gdb/testsuite/gdb.base/charset.c
    gdb/testsuite/gdb.base/charset.exp
    gdb/testsuite/gdb.base/pc-fp.c
    gdb/testsuite/gdb.base/pc-fp.exp
    gdb/testsuite/gdb.c++/m-static.h
    gdb/testsuite/gdb.c++/m-static1.cc
    gdb/testsuite/gdb.c++/pr-574.cc
    gdb/testsuite/gdb.c++/pr-574.exp
    gdb/testsuite/gdb.c++/printmethod.cc
    gdb/testsuite/gdb.c++/printmethod.exp
    gdb/testsuite/gdb.gdb/complaints.exp
    gdb/testsuite/gdb.mi/gdb669.exp
    gdb/testsuite/gdb.mi/gdb680.exp
    gdb/testsuite/gdb.mi/gdb701.c
    gdb/testsuite/gdb.mi/gdb701.exp
    gdb/testsuite/gdb.threads/killed.c
    gdb/testsuite/gdb.threads/killed.exp
    libiberty/testsuite/test-demangle.c

34 files changed:
bfd/elf32-i386-fbsd.c [new file with mode: 0644]
bfd/elf64-alpha-fbsd.c [new file with mode: 0644]
bfd/po/da.po [new file with mode: 0644]
gdb/charset.c [new file with mode: 0644]
gdb/charset.h [new file with mode: 0644]
gdb/config/i386/nbsd.mt [new file with mode: 0644]
gdb/cp-support.c [new file with mode: 0644]
gdb/cp-support.h [new file with mode: 0644]
gdb/disasm.c [new file with mode: 0644]
gdb/disasm.h [new file with mode: 0644]
gdb/gdb.c [new file with mode: 0644]
gdb/gdb_mbuild.sh [new file with mode: 0755]
gdb/main.h [new file with mode: 0644]
gdb/objc-exp.y [new file with mode: 0644]
gdb/objc-lang.c [new file with mode: 0644]
gdb/objc-lang.h [new file with mode: 0644]
gdb/testsuite/gdb.base/charset.c [new file with mode: 0644]
gdb/testsuite/gdb.base/charset.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/pc-fp.c [new file with mode: 0644]
gdb/testsuite/gdb.base/pc-fp.exp [new file with mode: 0644]
gdb/testsuite/gdb.c++/m-static.h [new file with mode: 0644]
gdb/testsuite/gdb.c++/m-static1.cc [new file with mode: 0644]
gdb/testsuite/gdb.c++/pr-574.cc [new file with mode: 0644]
gdb/testsuite/gdb.c++/pr-574.exp [new file with mode: 0644]
gdb/testsuite/gdb.c++/printmethod.cc [new file with mode: 0644]
gdb/testsuite/gdb.c++/printmethod.exp [new file with mode: 0644]
gdb/testsuite/gdb.gdb/complaints.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/gdb669.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/gdb680.exp [new file with mode: 0644]
gdb/testsuite/gdb.mi/gdb701.c [new file with mode: 0644]
gdb/testsuite/gdb.mi/gdb701.exp [new file with mode: 0644]
gdb/testsuite/gdb.threads/killed.c [new file with mode: 0644]
gdb/testsuite/gdb.threads/killed.exp [new file with mode: 0644]
libiberty/testsuite/test-demangle.c [new file with mode: 0644]

diff --git a/bfd/elf32-i386-fbsd.c b/bfd/elf32-i386-fbsd.c
new file mode 100644 (file)
index 0000000..500e0eb
--- /dev/null
@@ -0,0 +1,56 @@
+/* Intel IA-32 specific support for 32-bit ELF on FreeBSD.
+   Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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 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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define TARGET_LITTLE_SYM      bfd_elf32_i386_freebsd_vec
+#define TARGET_LITTLE_NAME     "elf32-i386-freebsd"
+#define ELF_ARCH               bfd_arch_i386
+#define ELF_MACHINE_CODE       EM_386
+#define ELF_MAXPAGESIZE                0x1000
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "elf-bfd.h"
+
+/* The kernel recognizes executables as valid only if they carry a
+   "FreeBSD" label in the ELF header.  So we put this label on all
+   executables and (for simplicity) also all other object files.  */
+
+static void elf_i386_post_process_headers
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+static void
+elf_i386_post_process_headers (abfd, link_info)
+     bfd * abfd;
+     struct bfd_link_info * link_info ATTRIBUTE_UNUSED;
+{
+  Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
+
+  i_ehdrp = elf_elfheader (abfd);
+
+  /* Put an ABI label supported by FreeBSD >= 4.1.  */
+  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#ifdef OLD_FREEBSD_ABI_LABEL
+  /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
+  memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
+#endif
+}
+
+#define elf_backend_post_process_headers       elf_i386_post_process_headers
+
+#include "elf32-i386.c"
diff --git a/bfd/elf64-alpha-fbsd.c b/bfd/elf64-alpha-fbsd.c
new file mode 100644 (file)
index 0000000..061b0b8
--- /dev/null
@@ -0,0 +1,56 @@
+/* Alpha specific support for 64-bit ELF on FreeBSD.
+   Copyright 2002 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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 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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define TARGET_LITTLE_SYM      bfd_elf64_alpha_freebsd_vec
+#define TARGET_LITTLE_NAME     "elf64-alpha-freebsd"
+#define ELF_ARCH               bfd_arch_alpha
+#define ELF_MACHINE_CODE       EM_ALPHA
+#define ELF_MAXPAGESIZE                0x10000
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "elf-bfd.h"
+
+/* The kernel recognizes executables as valid only if they carry a
+   "FreeBSD" label in the ELF header.  So we put this label on all
+   executables and (for simplicity) also all other object files.  */
+
+static void elf_alpha_post_process_headers
+  PARAMS ((bfd *, struct bfd_link_info *));
+
+static void
+elf_alpha_post_process_headers (abfd, link_info)
+     bfd * abfd;
+     struct bfd_link_info * link_info ATTRIBUTE_UNUSED;
+{
+  Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
+
+  i_ehdrp = elf_elfheader (abfd);
+
+  /* Put an ABI label supported by FreeBSD >= 4.1.  */
+  i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#ifdef OLD_FREEBSD_ABI_LABEL
+  /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard.  */
+  memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
+#endif
+}
+
+#define elf_backend_post_process_headers       elf_alpha_post_process_headers
+
+#include "elf64-alpha.c"
diff --git a/bfd/po/da.po b/bfd/po/da.po
new file mode 100644 (file)
index 0000000..6f18484
--- /dev/null
@@ -0,0 +1,2745 @@
+# Danish messages for bfd.
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+# Keld Simonsen <keld@dkuug.dk>, 2002
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: bfd 2.12.91\n"
+"POT-Creation-Date: 2002-07-23 15:55-0400\n"
+"PO-Revision-Date: 2002-09-07 21:55+0200\n"
+"Last-Translator: Keld Simonsen <keld@dkuug.dk>\n"
+"Language-Team: Danish <dansk@klid.dk>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: aout-adobe.c:197
+#, c-format
+msgid "%s: Unknown section type in a.out.adobe file: %x\n"
+msgstr "%s: Ukendt sektionstype i a.out.adobe-fil: %x\n"
+
+#: aout-cris.c:208
+#, c-format
+msgid "%s: Invalid relocation type exported: %d"
+msgstr "%s: Ugyldig relokaliseringstype eksporteret: %d"
+
+#: aout-cris.c:252
+#, c-format
+msgid "%s: Invalid relocation type imported: %d"
+msgstr "%s: Ugyldig relokaliseringstype importeret: %d"
+
+#: aout-cris.c:263
+#, c-format
+msgid "%s: Bad relocation record imported: %d"
+msgstr "%s: Fejlagtig relokaliseringstype importeret: %d"
+
+#: aoutx.h:1282 aoutx.h:1699
+#, c-format
+msgid "%s: can not represent section `%s' in a.out object file format"
+msgstr "%s: kan ikke representere sektionen \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1669
+#, c-format
+msgid "%s: can not represent section for symbol `%s' in a.out object file format"
+msgstr "%s: kan ikke representere sektion for symbolet \"%s\" i a.out-objektfilformat"
+
+#: aoutx.h:1671
+msgid "*unknown*"
+msgstr "*ukendt*"
+
+#: aoutx.h:3732
+#, c-format
+msgid "%s: relocateable link from %s to %s not supported"
+msgstr "%s: relokaliseringsbar lænke fra %s til %s understøttes inte"
+
+#: archive.c:1826
+msgid "Warning: writing archive was slow: rewriting timestamp\n"
+msgstr "Advarsel: arkivskrivning var langsom: genskriver tidsstempel\n"
+
+#: archive.c:2093
+msgid "Reading archive file mod timestamp"
+msgstr "Læser arkivfilens ændringstidsstempel"
+
+#. FIXME: bfd can't call perror.
+#: archive.c:2120
+msgid "Writing updated armap timestamp"
+msgstr "Skriver opdateret armap-tidsstempel"
+
+#: bfd.c:274
+msgid "No error"
+msgstr "Ingen fejl"
+
+#: bfd.c:275
+msgid "System call error"
+msgstr "Systemkaldsfejl"
+
+#: bfd.c:276
+msgid "Invalid bfd target"
+msgstr "Ugyldigt bfd-mål"
+
+#: bfd.c:277
+msgid "File in wrong format"
+msgstr "Filen er i forkert format"
+
+#: bfd.c:278
+msgid "Archive object file in wrong format"
+msgstr "Arkivobjektfil er i forkert format"
+
+#: bfd.c:279
+msgid "Invalid operation"
+msgstr "Ugyldig handling"
+
+#: bfd.c:280
+msgid "Memory exhausted"
+msgstr "Hukommelsen er opbrugt"
+
+#: bfd.c:281
+msgid "No symbols"
+msgstr "Ingen symboler"
+
+#: bfd.c:282
+msgid "Archive has no index; run ranlib to add one"
+msgstr "Arkivet har intet index; kør ranlib for at tilføje ét"
+
+#: bfd.c:283
+msgid "No more archived files"
+msgstr "Ikke flere arkiverede filer"
+
+#: bfd.c:284
+msgid "Malformed archive"
+msgstr "Forvansket arkiv"
+
+#: bfd.c:285
+msgid "File format not recognized"
+msgstr "Filformatet ikke genkendt"
+
+#: bfd.c:286
+msgid "File format is ambiguous"
+msgstr "Filformatet er flertydigt"
+
+#: bfd.c:287
+msgid "Section has no contents"
+msgstr "Sektionen har intet indhold"
+
+#: bfd.c:288
+msgid "Nonrepresentable section on output"
+msgstr "Ikkerepræsenterbar sektion i uddata"
+
+#: bfd.c:289
+msgid "Symbol needs debug section which does not exist"
+msgstr "Symbolet kræver fejlsøgningssektion som ikke eksisterer"
+
+#: bfd.c:290
+msgid "Bad value"
+msgstr "Fejlagtigt værdi"
+
+#: bfd.c:291
+msgid "File truncated"
+msgstr "Filen trunkeret"
+
+#: bfd.c:292
+msgid "File too big"
+msgstr "Filen er for stor"
+
+#: bfd.c:293
+msgid "#<Invalid error code>"
+msgstr "#<Ugyldig fejlkode>"
+
+#: bfd.c:700
+#, c-format
+msgid "BFD %s assertion fail %s:%d"
+msgstr "BFD %s-forsikring mislykkedes %s:%d"
+
+#: bfd.c:719
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d in %s\n"
+msgstr "Intern BFD %s-fejl, afbryder ved %s linje %d i %s\n"
+
+#: bfd.c:723
+#, c-format
+msgid "BFD %s internal error, aborting at %s line %d\n"
+msgstr "Internt BFD %s-fejl, afbryder ved %s linje %d\n"
+
+#: bfd.c:725
+msgid "Please report this bug.\n"
+msgstr "Rapportér gerne denne fejl.\n"
+
+#: binary.c:306
+#, c-format
+msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
+msgstr "Advarsel: Skrivning af sektionen \"%s\" til enorm (dvs negativ) afsætsbyte 0x%lx."
+
+# src/menus.c:341
+#: coff-a29k.c:119
+msgid "Missing IHCONST"
+msgstr "IHCONST mangler"
+
+# src/menus.c:341
+#: coff-a29k.c:180
+msgid "Missing IHIHALF"
+msgstr "IHIHALF mangler"
+
+#: coff-a29k.c:212 coff-or32.c:229
+msgid "Unrecognized reloc"
+msgstr "Ukendt relokalisering"
+
+#: coff-a29k.c:408
+msgid "missing IHCONST reloc"
+msgstr "IHCONST-relokalisering mangler"
+
+#: coff-a29k.c:498
+msgid "missing IHIHALF reloc"
+msgstr "IHIHALF-relokalisering mangler"
+
+#: coff-alpha.c:881 coff-alpha.c:918 coff-alpha.c:1989 coff-mips.c:1432
+msgid "GP relative relocation used when GP not defined"
+msgstr "GP-relativ relokalisering bruges når GP ikke er defineret"
+
+#: coff-alpha.c:1485
+msgid "using multiple gp values"
+msgstr "bruger flere gp-værdier"
+
+#: coff-arm.c:1066 elf32-arm.h:285
+#, c-format
+msgid "%s: unable to find THUMB glue '%s' for `%s'"
+msgstr "%s: kunne ikke finde THUMB-klistret \"%s\" til \"%s\""
+
+#: coff-arm.c:1096 elf32-arm.h:320
+#, c-format
+msgid "%s: unable to find ARM glue '%s' for `%s'"
+msgstr "%s: kunne ikke finde ARM-klistret \"%s\" til \"%s\""
+
+#: coff-arm.c:1391 coff-arm.c:1486 elf32-arm.h:887 elf32-arm.h:991
+#, c-format
+msgid "%s(%s): warning: interworking not enabled."
+msgstr "%s(%s): advarsel: samvirken er ikke aktiveret."
+
+#: coff-arm.c:1395 elf32-arm.h:994
+#, c-format
+msgid "  first occurrence: %s: arm call to thumb"
+msgstr "  første forekomst: %s: arm-kald til thumb"
+
+#: coff-arm.c:1490 elf32-arm.h:890
+#, c-format
+msgid "  first occurrence: %s: thumb call to arm"
+msgstr "  første forekomst: %s: thumb-kald til arm"
+
+#: coff-arm.c:1493
+msgid "  consider relinking with --support-old-code enabled"
+msgstr "  overvej omlænkning med --support-old-code aktiveret"
+
+#: coff-arm.c:1785 coff-tic80.c:686 cofflink.c:3031
+#, c-format
+msgid "%s: bad reloc address 0x%lx in section `%s'"
+msgstr "%s: fejlagtig relokaliseringsadresse 0x%lx i sektionen \"%s\""
+
+#: coff-arm.c:2127
+#, c-format
+msgid "%s: illegal symbol index in reloc: %d"
+msgstr "%s: utilladt symbolindex i relokalisering: %d"
+
+#: coff-arm.c:2255
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
+msgstr "FEJL: %s kompileret for APCS-%d, mens %s er kompileret for APCS-%d"
+
+#: coff-arm.c:2270 elf32-arm.h:2297
+#, c-format
+msgid "ERROR: %s passes floats in float registers, whereas %s passes them in integer registers"
+msgstr "FEJL: %s overfører flydende tal i flydende talsregister, mens %s overfører dem i heltalsregister"
+
+#: coff-arm.c:2273 elf32-arm.h:2302
+#, c-format
+msgid "ERROR: %s passes floats in integer registers, whereas %s passes them in float registers"
+msgstr "FEJL: %s overfører flydende tal i heltalsregister, mens %s overfører dem i flydendetalsregister"
+
+#: coff-arm.c:2288
+#, c-format
+msgid "ERROR: %s is compiled as position independent code, whereas target %s is absolute position"
+msgstr "FEJL: %s er kompileret som positionsuafhængig kode, mens målet %s har absolut position"
+
+#: coff-arm.c:2291
+#, c-format
+msgid "ERROR: %s is compiled as absolute position code, whereas target %s is position independent"
+msgstr "FEJL: %s er kompileret som kode med absolut position, mens målet %s er positionsuafhængigt"
+
+#: coff-arm.c:2320 elf32-arm.h:2358
+#, c-format
+msgid "Warning: %s supports interworking, whereas %s does not"
+msgstr "Advarsel: %s understøtter samvirken, mens %s derimod ikke gør det"
+
+#: coff-arm.c:2323 elf32-arm.h:2365
+#, c-format
+msgid "Warning: %s does not support interworking, whereas %s does"
+msgstr "Advarsel: %s understøtter ikke samvirken, mens %s derimod gør det"
+
+#: coff-arm.c:2350
+#, c-format
+msgid "private flags = %x:"
+msgstr "private flag = %x:"
+
+#: coff-arm.c:2358 elf32-arm.h:2418
+msgid " [floats passed in float registers]"
+msgstr " [flydende tal overført i flydendetalsregistre]"
+
+#: coff-arm.c:2360
+msgid " [floats passed in integer registers]"
+msgstr " [flydende tal overført i heltalsregistre]"
+
+#: coff-arm.c:2363 elf32-arm.h:2421
+msgid " [position independent]"
+msgstr " [positionsuafhængigt]"
+
+#: coff-arm.c:2365
+msgid " [absolute position]"
+msgstr " [absolut position]"
+
+#: coff-arm.c:2369
+msgid " [interworking flag not initialised]"
+msgstr " [samvirkendeflag er ikke initieret]"
+
+#: coff-arm.c:2371
+msgid " [interworking supported]"
+msgstr " [samvirken understøttes]"
+
+#: coff-arm.c:2373
+msgid " [interworking not supported]"
+msgstr " [samvirken understøttes ikke]"
+
+#: coff-arm.c:2421 elf32-arm.h:2124
+#, c-format
+msgid "Warning: Not setting interworking flag of %s since it has already been specified as non-interworking"
+msgstr "Advarsel: Sætter ikke samvirkeflaget for %s da den allerede er angivet som ikke-samvirkende"
+
+#: coff-arm.c:2425 elf32-arm.h:2128
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s due to outside request"
+msgstr "Advarsel: Fjerner samvirkeflaget for %s på grund af anmodning udefra"
+
+#: coff-i960.c:136 coff-i960.c:485
+msgid "uncertain calling convention for non-COFF symbol"
+msgstr "usikker kaldskonvention for ikke-COFF-symbol"
+
+#: coff-m68k.c:481 coff-mips.c:2429 elf32-m68k.c:2157 elf32-mips.c:1844
+msgid "unsupported reloc type"
+msgstr "relokaliseringstypen understøttes ikke"
+
+#: coff-mips.c:874 elf32-mips.c:1062 elf64-mips.c:1609
+msgid "GP relative relocation when _gp not defined"
+msgstr "GP-relativ relokalisering når _gp ikke var defineret"
+
+#. No other sections should appear in -membedded-pic
+#. code.
+#: coff-mips.c:2466
+msgid "reloc against unsupported section"
+msgstr "relokalisering mod sektion som ikke understøttes"
+
+#: coff-mips.c:2474
+msgid "reloc not properly aligned"
+msgstr "relokalisering ikke på lige grænse"
+
+#: coff-rs6000.c:2766
+#, c-format
+msgid "%s: unsupported relocation type 0x%02x"
+msgstr "%s: relokaliseringstypen 0x%02x understøttes ikke"
+
+#: coff-rs6000.c:2859
+#, c-format
+msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
+msgstr "%s: TOC-relokalisering ved 0x%x til symbolet \"%s\" uden nogen TOC-post"
+
+#: coff-rs6000.c:3590 coff64-rs6000.c:2091
+#, c-format
+msgid "%s: symbol `%s' has unrecognized smclas %d"
+msgstr "%s: symbolet \"%s\" har ukendt smclas %d"
+
+#: coff-tic54x.c:279 coff-tic80.c:449
+#, c-format
+msgid "Unrecognized reloc type 0x%x"
+msgstr "Ukendt relokaliseringstype 0x%x"
+
+#: coff-tic54x.c:390 coffcode.h:4974
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in relocs"
+msgstr "%s: advarsel: utilladt symbolindex %ld i relokaliseringerne"
+
+#: coff-w65.c:363
+#, c-format
+msgid "ignoring reloc %s\n"
+msgstr "ignorerer relokalisering %s\n"
+
+#: coffcode.h:1086
+#, c-format
+msgid "%s (%s): Section flag %s (0x%x) ignored"
+msgstr "%s (%s): Sektionsflaget %s (0x%x) ignoreredes"
+
+#: coffcode.h:2143
+#, c-format
+msgid "Unrecognized TI COFF target id '0x%x'"
+msgstr "Ukendt TI COFF-mål-id \"0x%x\""
+
+#: coffcode.h:4365
+#, c-format
+msgid "%s: warning: illegal symbol index %ld in line numbers"
+msgstr "%s: advarsel: utilladt symbolindex %ld i linjenummer"
+
+#: coffcode.h:4379
+#, c-format
+msgid "%s: warning: duplicate line number information for `%s'"
+msgstr "%s: advarsel: dobbelt linjenummersinformation for \"%s\""
+
+#: coffcode.h:4736
+#, c-format
+msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
+msgstr "%s: Ukendt lagringsklasse %d for %s-symbolet \"%s\""
+
+#: coffcode.h:4867
+#, c-format
+msgid "warning: %s: local symbol `%s' has no section"
+msgstr "advarsel: %s: lokalt symbol \"%s\" har ingen sektion"
+
+#: coffcode.h:5012
+#, c-format
+msgid "%s: illegal relocation type %d at address 0x%lx"
+msgstr "%s: utilladt relokaliseringstype %d på adresse 0x%lx"
+
+#: coffgen.c:1661
+#, c-format
+msgid "%s: bad string table size %lu"
+msgstr "%s: fejlagtig strengtabelstørrelse %lu"
+
+#: cofflink.c:534 elflink.h:1912
+#, c-format
+msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
+msgstr "Advarsel: typen på symbol \"%s\" ændredes fra %d til %d i %s"
+
+#: cofflink.c:2321
+#, c-format
+msgid "%s: relocs in section `%s', but it has no contents"
+msgstr "%s: relokaliseringer i sektionen \"%s\", men den har intet indhold"
+
+#: cofflink.c:2664 coffswap.h:877
+#, c-format
+msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
+msgstr "%s: %s: relokalisering giver overløb: 0x%lx > 0xffff"
+
+#: cofflink.c:2673 coffswap.h:864
+#, c-format
+msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: advarsel: %s: linjenummer giver overløb: 0x%lx > 0xffff"
+
+#: dwarf2.c:382
+msgid "Dwarf Error: Can't find .debug_str section."
+msgstr "Dwarf-fejl: Kan ikke finde sektionen .debug_str."
+
+#: dwarf2.c:399
+#, c-format
+msgid "Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."
+msgstr "Dwarf-fejl: DW_FORM_strp-afstanden (%lu) større end eller lig med størrelsen på .debug_str (%lu)."
+
+#: dwarf2.c:543
+msgid "Dwarf Error: Can't find .debug_abbrev section."
+msgstr "Dwarf-fejl: Kan ikke finde sektionen .debug_abbrev."
+
+#: dwarf2.c:560
+#, c-format
+msgid "Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."
+msgstr "Dwarf-fejl: Forkortningsafstanden (%lu) større end eller lig med størrelsen .debug_abbrev (%lu)."
+
+#: dwarf2.c:757
+#, c-format
+msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
+msgstr "Dwarf-fejl: Ugyldig eller ubehandlet FORM-værdi: %u."
+
+#: dwarf2.c:852
+msgid "Dwarf Error: mangled line number section (bad file number)."
+msgstr "Dwarf-fejl: vanskabt linjenummerssektion (fejlagtigt filnummer)."
+
+#: dwarf2.c:938
+msgid "Dwarf Error: Can't find .debug_line section."
+msgstr "Dwarf-fejl: Kan ikke finde sektionen .debug_line."
+
+#: dwarf2.c:961
+#, c-format
+msgid "Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."
+msgstr "Dwarf-fejl: Linjeafstanden (%lu) større end eller lig med størrelsen .debug_line (%lu)."
+
+#: dwarf2.c:1159
+msgid "Dwarf Error: mangled line number section."
+msgstr "Dwarf-fejl: vanskabt linjenummerssektion."
+
+#: dwarf2.c:1355 dwarf2.c:1566
+#, c-format
+msgid "Dwarf Error: Could not find abbrev number %u."
+msgstr "Dwarf-fejl: Kunne ikke finde forkortningsnumret %u."
+
+#: dwarf2.c:1527
+#, c-format
+msgid "Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."
+msgstr "Dwarf-fejl: fandt dwarf version \"%u\", denne læser håndterer kun information fra version 2."
+
+#: dwarf2.c:1534
+#, c-format
+msgid "Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."
+msgstr "Dwarf-fejl: fandt adressestørrelsen \"%u\", denne læser kan ikke håndtere størrelser større end \"%u\"."
+
+#: dwarf2.c:1557
+#, c-format
+msgid "Dwarf Error: Bad abbrev number: %u."
+msgstr "Dwarf-fejl: Fejlagtigt forkortningsnummer: %u."
+
+#: ecoff.c:1318
+#, c-format
+msgid "Unknown basic type %d"
+msgstr "Ukendt grundtype %d"
+
+#: ecoff.c:1578
+#, c-format
+msgid ""
+"\n"
+"      End+1 symbol: %ld"
+msgstr ""
+"\n"
+"      Symbol slut+1: %ld"
+
+#: ecoff.c:1585 ecoff.c:1588
+#, c-format
+msgid ""
+"\n"
+"      First symbol: %ld"
+msgstr ""
+"\n"
+"      Første symbol: %ld"
+
+#: ecoff.c:1600
+#, c-format
+msgid ""
+"\n"
+"      End+1 symbol: %-7ld   Type:  %s"
+msgstr ""
+"\n"
+"      Symbol slut+1: %-7ld  Typ:  %s"
+
+#: ecoff.c:1607
+#, c-format
+msgid ""
+"\n"
+"      Local symbol: %ld"
+msgstr ""
+"\n"
+"      Lokalt symbol: %ld"
+
+#: ecoff.c:1615
+#, c-format
+msgid ""
+"\n"
+"      struct; End+1 symbol: %ld"
+msgstr ""
+"\n"
+"      struct; symbol slut+1: %ld"
+
+#: ecoff.c:1620
+#, c-format
+msgid ""
+"\n"
+"      union; End+1 symbol: %ld"
+msgstr ""
+"\n"
+"      union; symbol slut+1: %ld"
+
+#: ecoff.c:1625
+#, c-format
+msgid ""
+"\n"
+"      enum; End+1 symbol: %ld"
+msgstr ""
+"\n"
+"      enum; symbol slut+1: %ld"
+
+#: ecoff.c:1631
+#, c-format
+msgid ""
+"\n"
+"      Type: %s"
+msgstr ""
+"\n"
+"      Type: %s"
+
+#: elf-hppa.h:1476 elf-hppa.h:1509 elf32-ppc.c:3091 elf32-sh.c:4213
+#: elf64-sh64.c:1659
+#, c-format
+msgid "%s: warning: unresolvable relocation against symbol `%s' from %s section"
+msgstr "%s: advarsel: uløselig relokalisering mod symbol \"%s\" fra sektionen %s"
+
+#: elf-m10200.c:446 elf-m10300.c:656 elf32-arm.h:2084 elf32-avr.c:833
+#: elf32-cris.c:1403 elf32-d10v.c:481 elf32-fr30.c:635 elf32-frv.c:809
+#: elf32-h8300.c:548 elf32-i860.c:1031 elf32-m32r.c:1278 elf32-openrisc.c:439
+#: elf32-v850.c:1691 elf32-xstormy16.c:933 elf64-mmix.c:1302
+msgid "internal error: out of range error"
+msgstr "intern fejl: udenfor intervallet"
+
+#: elf-m10200.c:450 elf-m10300.c:660 elf32-arm.h:2088 elf32-avr.c:837
+#: elf32-cris.c:1407 elf32-d10v.c:485 elf32-fr30.c:639 elf32-frv.c:813
+#: elf32-h8300.c:552 elf32-i860.c:1035 elf32-m32r.c:1282 elf32-openrisc.c:443
+#: elf32-v850.c:1695 elf32-xstormy16.c:937 elf64-mmix.c:1306 elfxx-mips.c:5264
+msgid "internal error: unsupported relocation error"
+msgstr "intern fejl: relokaliseringen understøttes ikke"
+
+#: elf-m10200.c:454 elf-m10300.c:664 elf32-arm.h:2092 elf32-d10v.c:489
+#: elf32-h8300.c:556 elf32-m32r.c:1286
+msgid "internal error: dangerous error"
+msgstr "intern fejl: farlig fejl"
+
+#: elf-m10200.c:458 elf-m10300.c:668 elf32-arm.h:2096 elf32-avr.c:845
+#: elf32-cris.c:1415 elf32-d10v.c:493 elf32-fr30.c:647 elf32-frv.c:821
+#: elf32-h8300.c:560 elf32-i860.c:1043 elf32-m32r.c:1290 elf32-openrisc.c:451
+#: elf32-v850.c:1715 elf32-xstormy16.c:945 elf64-mmix.c:1314
+msgid "internal error: unknown error"
+msgstr "intern fejl: ukendt fejl"
+
+#: elf.c:343
+#, c-format
+msgid "%s: invalid string offset %u >= %lu for section `%s'"
+msgstr "%s: ugyldig strengafstand %u >= %lu for sektionen \"%s\""
+
+#: elf.c:589
+#, c-format
+msgid "%s: invalid SHT_GROUP entry"
+msgstr "%s: ugyldig SHT_GROUP-post"
+
+#: elf.c:660
+#, c-format
+msgid "%s: no group info for section %s"
+msgstr "%s: ingen gruppeinformation for sektionen %s"
+
+#: elf.c:1023
+msgid ""
+"\n"
+"Program Header:\n"
+msgstr ""
+"\n"
+"Programhoved:\n"
+
+#: elf.c:1073
+msgid ""
+"\n"
+"Dynamic Section:\n"
+msgstr ""
+"\n"
+"Dynamisk sektion:\n"
+
+#: elf.c:1202
+msgid ""
+"\n"
+"Version definitions:\n"
+msgstr ""
+"\n"
+"Versionsdefinitioner:\n"
+
+#: elf.c:1225
+msgid ""
+"\n"
+"Version References:\n"
+msgstr ""
+"\n"
+"Versionsreferencer:\n"
+
+#: elf.c:1230
+#, c-format
+msgid "  required from %s:\n"
+msgstr "  kræves fra %s:\n"
+
+#: elf.c:1902
+#, c-format
+msgid "%s: invalid link %lu for reloc section %s (index %u)"
+msgstr "%s: ugyldig lænke %lu for relokaliseringssektion %s (index %u)"
+
+#: elf.c:3603
+#, c-format
+msgid "%s: Not enough room for program headers (allocated %u, need %u)"
+msgstr "%s: Ikke tilstrækkeligt med plads for programhoveder (allokerede %u, behøver %u)"
+
+#: elf.c:3708
+#, c-format
+msgid "%s: Not enough room for program headers, try linking with -N"
+msgstr "%s: Ikke tilstrækkeligt med plads for programhoveder, forsøg at lænke med -N"
+
+#: elf.c:3833
+#, c-format
+msgid "Error: First section in segment (%s) starts at 0x%x whereas the segment starts at 0x%x"
+msgstr "Fejl: Første sektion i segmentet (%s) begynder ved 0x%x mens segmentet begynder ved 0x%x"
+
+#: elf.c:4148
+#, c-format
+msgid "%s: warning: allocated section `%s' not in segment"
+msgstr "%s: advarsel: allokeret sektion \"%s\" ikke i segment"
+
+#: elf.c:4472
+#, c-format
+msgid "%s: symbol `%s' required but not present"
+msgstr "%s: symbol \"%s\" kræves men er ikke tilstede"
+
+#: elf.c:4749
+#, c-format
+msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
+msgstr "%s: advarsel: Tomt indlæsningsbart segment opdaget, er dette meningen?\n"
+
+#: elf.c:6193
+#, c-format
+msgid "%s: unsupported relocation type %s"
+msgstr "%s: relokaliseringstypen %s understøttes ikke"
+
+#: elf32-arm.h:1221
+#, c-format
+msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
+msgstr "%s: Advarsel: Arm BLX-instruktion bruger Arm-funktionen \"%s\" som mål."
+
+#: elf32-arm.h:1417
+#, c-format
+msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
+msgstr "%s: Advarsel: Thumb BLX-instruktionen bruger thumb-funktionen \"%s\" som mål."
+
+#: elf32-arm.h:1914 elf32-sh.c:4125
+#, c-format
+msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section"
+msgstr "%s(%s+0x%lx): %s relokalisering mod SEC_MERGE-sektion"
+
+#: elf32-arm.h:2008
+#, c-format
+msgid "%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
+msgstr "%s: advarsel: uløselig relokalisering %d mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-arm.h:2176
+#, c-format
+msgid "Warning: Clearing the interworking flag of %s because non-interworking code in %s has been linked with it"
+msgstr "Advarsel: Fjerner samvirkendeflaget i %s eftersom ikke-samvirkende kode i %s er lænket med det"
+
+#: elf32-arm.h:2271
+#, c-format
+msgid "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for version %d"
+msgstr "FEJL: %s er kompileret for EABI version %d, mens %s er kompileret for version %d"
+
+#: elf32-arm.h:2285
+#, c-format
+msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
+msgstr "FEJL: %s er kompileret for APCS-%d, mens målet %s bruger APCS-%d"
+
+#: elf32-arm.h:2313
+#, c-format
+msgid "ERROR: %s uses VFP instructions, whereas %s uses FPA instructions"
+msgstr "FEJL: %s bruger VFP-instruktioner, mens %s bruger FPA-instruktioner"
+
+#: elf32-arm.h:2318
+#, c-format
+msgid "ERROR: %s uses FPA instructions, whereas %s uses VFP instructions"
+msgstr "FEJL: %s bruger FPA-instruktioner, mens %s bruger VFP-instruktioner"
+
+#: elf32-arm.h:2338
+#, c-format
+msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
+msgstr "FEJL: %s bruger programmeret flydende tal, mens %s bruger maskinens flydende tal"
+
+#: elf32-arm.h:2343
+#, c-format
+msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
+msgstr "FEJL: %s bruger maskinens flydende tal, mens %s bruger programmeret flydende tal"
+
+#. Ignore init flag - it may not be set, despite the flags field
+#. containing valid data.
+#: elf32-arm.h:2396 elf32-cris.c:2988 elf32-m68k.c:410 elf32-vax.c:543
+#: elfxx-mips.c:7756
+#, c-format
+msgid "private flags = %lx:"
+msgstr "private flag = %lx:"
+
+#: elf32-arm.h:2405
+msgid " [interworking enabled]"
+msgstr " [samvirkende er aktiveret]"
+
+#: elf32-arm.h:2413
+msgid " [VFP float format]"
+msgstr " [VFP-flydende talsformat]"
+
+#: elf32-arm.h:2415
+msgid " [FPA float format]"
+msgstr " [FPA-flydende talsformat]"
+
+#: elf32-arm.h:2424
+msgid " [new ABI]"
+msgstr " [nyt ABI]"
+
+#: elf32-arm.h:2427
+msgid " [old ABI]"
+msgstr " [gammelt ABI]"
+
+#: elf32-arm.h:2430
+msgid " [software FP]"
+msgstr " [programmeret FP]"
+
+#: elf32-arm.h:2438
+msgid " [Version1 EABI]"
+msgstr " [Version1 EABI]"
+
+#: elf32-arm.h:2441 elf32-arm.h:2452
+msgid " [sorted symbol table]"
+msgstr " [sorteret symboltabel]"
+
+#: elf32-arm.h:2443 elf32-arm.h:2454
+msgid " [unsorted symbol table]"
+msgstr " [usorteret symboltabel]"
+
+#: elf32-arm.h:2449
+msgid " [Version2 EABI]"
+msgstr " [Version2 EABI]"
+
+#: elf32-arm.h:2457
+msgid " [dynamic symbols use segment index]"
+msgstr " [dynamiske symboler bruger segmentindex]"
+
+#: elf32-arm.h:2460
+msgid " [mapping symbols precede others]"
+msgstr " [mapningssymboler foretrækkes frem for andre]"
+
+#: elf32-arm.h:2467
+msgid " <EABI version unrecognised>"
+msgstr " <EABI-version genkendes ikke>"
+
+#: elf32-arm.h:2474
+msgid " [relocatable executable]"
+msgstr " [relokaliseringsbar kørbar fil]"
+
+#: elf32-arm.h:2477
+msgid " [has entry point]"
+msgstr " [har startpunkt]"
+
+#: elf32-arm.h:2482
+msgid "<Unrecognised flag bits set>"
+msgstr "<Ukendte flagbit er sat>"
+
+#: elf32-avr.c:841 elf32-cris.c:1411 elf32-fr30.c:643 elf32-frv.c:817
+#: elf32-i860.c:1039 elf32-openrisc.c:447 elf32-v850.c:1699
+#: elf32-xstormy16.c:941 elf64-mmix.c:1310
+msgid "internal error: dangerous relocation"
+msgstr "intern fejl: farlig relokalisering"
+
+#: elf32-cris.c:949
+#, c-format
+msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
+msgstr "%s: uløselig relokalisering %s mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-cris.c:1012
+#, c-format
+msgid "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"
+msgstr "%s: Hverken nogen PLT eller GOT for relokalisering %s  mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-cris.c:1015 elf32-cris.c:1141
+msgid "[whose name is lost]"
+msgstr "[hvis navn er tabt]"
+
+#: elf32-cris.c:1130
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against local symbol from %s section"
+msgstr "%s: relokalisering %s med ikke-tomt addendum %d mod lokalt symbol fra sektionen %s"
+
+#: elf32-cris.c:1137
+#, c-format
+msgid "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section"
+msgstr "%s: relokalisering %s med ikke-tomt addendum %d mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-cris.c:1155
+#, c-format
+msgid "%s: relocation %s is not allowed for global symbol: `%s' from %s section"
+msgstr "%s: relokaliseringen %s er ikke tilladt for globalt symbol: \"%s\" fra sektionen %s"
+
+#: elf32-cris.c:1170
+#, c-format
+msgid "%s: relocation %s in section %s with no GOT created"
+msgstr "%s: relokalisering %s i sektionen %s uden GOT oprettet"
+
+#: elf32-cris.c:1288
+#, c-format
+msgid "%s: Internal inconsistency; no relocation section %s"
+msgstr "%s: Intern inkonsistens; ingen relokaliseringssektion %s"
+
+#: elf32-cris.c:2514
+#, c-format
+msgid ""
+"%s, section %s:\n"
+"  relocation %s should not be used in a shared object; recompile with -fPIC"
+msgstr ""
+"%s, sektion %s:\n"
+"  relokaliseringen %s bør ikke bruges i et delt objekt; genoversæt med -fPIC"
+
+#: elf32-cris.c:2991
+msgid " [symbols have a _ prefix]"
+msgstr " [symboler har et _-prefix]"
+
+#: elf32-cris.c:3030
+#, c-format
+msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
+msgstr "%s: bruger symboler med _-prefix, men skriver fil med symboler uden prefix"
+
+#: elf32-cris.c:3031
+#, c-format
+msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
+msgstr "%s: bruger symboler uden prefix, men skriver fil med symboler med _-prefix"
+
+#: elf32-frv.c:1217
+#, c-format
+msgid "%s: compiled with %s and linked with modules that use non-pic relocations"
+msgstr "%s: kompileret med %s og lænket med moduler som bruger ikke-pic-relokalisering"
+
+#: elf32-frv.c:1267
+#, c-format
+msgid "%s: compiled with %s and linked with modules compiled with %s"
+msgstr "%s: kompileret med %s og lænket med moduler som kompileredes med %s"
+
+#: elf32-frv.c:1279
+#, c-format
+msgid "%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: bruger andre ukendte e_flags-felter (0x%lx) end tidligere moduler (0x%lx)"
+
+#: elf32-frv.c:1315
+#, c-format
+msgid "private flags = 0x%lx:"
+msgstr "private flag = 0x%lx:"
+
+#: elf32-gen.c:82 elf64-gen.c:82
+#, c-format
+msgid "%s: Relocations in generic ELF (EM: %d)"
+msgstr "%s: Relokalisering i generisk ELF (EM: %d)"
+
+#: elf32-hppa.c:671 elf64-ppc.c:2323
+#, c-format
+msgid "%s: cannot create stub entry %s"
+msgstr "%s: kan ikke oprette stubstarten %s"
+
+#: elf32-hppa.c:956 elf32-hppa.c:3555
+#, c-format
+msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"
+msgstr "%s(%s+0x%lx): kan ikke nå %s, genoversæt med -ffunction-sections"
+
+#: elf32-hppa.c:1338 elf64-x86-64.c:673
+#, c-format
+msgid "%s: relocation %s can not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: relokaliseringen %s kan ikke bruges når et delt objekt oprettes; genoversæt med -fPIC"
+
+#: elf32-hppa.c:1358
+#, c-format
+msgid "%s: relocation %s should not be used when making a shared object; recompile with -fPIC"
+msgstr "%s: relokaliseringen %s bør ikke bruges når et delt objekt oprettes; genoversæt med -fPIC"
+
+#: elf32-hppa.c:1551
+#, c-format
+msgid "Could not find relocation section for %s"
+msgstr "Kunne ikke finde relokaliseringssektion for %s"
+
+#: elf32-hppa.c:2855
+#, c-format
+msgid "%s: duplicate export stub %s"
+msgstr "%s: dobbelt eksportstub %s"
+
+#: elf32-hppa.c:3433
+#, c-format
+msgid "%s(%s+0x%lx): fixing %s"
+msgstr "%s(%s+0x%lx): retter %s"
+
+#: elf32-hppa.c:4080
+#, c-format
+msgid "%s(%s+0x%lx): cannot handle %s for %s"
+msgstr "%s(%s+0x%lx): kan ikke håndtere %s for %s"
+
+#: elf32-hppa.c:4393
+msgid ".got section not immediately after .plt section"
+msgstr ".got-sektionen følger ikke umiddelbart efter .plt-sektion"
+
+#: elf32-i386.c:379
+#, c-format
+msgid "%s: invalid relocation type %d"
+msgstr "%s: ugyldig relokaliseringstype %d"
+
+#: elf32-i386.c:876 elf32-s390.c:649 elf64-s390.c:595 elf64-x86-64.c:591
+#, c-format
+msgid "%s: bad symbol index: %d"
+msgstr "%s: fejlagtigt symbolindex: %d"
+
+#: elf32-i386.c:948
+#, c-format
+msgid "%s: `%s' accessed both as normal and thread local symbol"
+msgstr "%s: \"%s\" kaldt både som lokalt normalt symbol og lokalt trådsymbol"
+
+#: elf32-i386.c:1072 elf32-s390.c:808 elf64-ppc.c:2827 elf64-s390.c:759
+#: elf64-x86-64.c:761
+#, c-format
+msgid "%s: bad relocation section name `%s'"
+msgstr "%s: fejlagtig relokaliseringssektionsnavn \"%s\""
+
+#: elf32-i386.c:1159 elf64-alpha.c:4768
+#, c-format
+msgid "%s: TLS local exec code cannot be linked into shared objects"
+msgstr "%s: lokal TLS-eksekveringskode kan ikke lænkes ind i delte objekter"
+
+#: elf32-i386.c:2747 elf32-s390.c:1981 elf32-sparc.c:1571 elf64-ppc.c:5918
+#: elf64-s390.c:1945 elf64-sparc.c:2578 elf64-x86-64.c:1948
+#, c-format
+msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'"
+msgstr "%s(%s+0x%lx): uløselig relokalisering mod symbol \"%s\""
+
+#: elf32-i386.c:2784 elf32-s390.c:2019 elf64-ppc.c:5977 elf64-s390.c:1983
+#: elf64-x86-64.c:1986
+#, c-format
+msgid "%s(%s+0x%lx): reloc against `%s': error %d"
+msgstr "%s(%s+0x%lx): relokalisering mod \"%s\": fejl %d"
+
+#: elf32-m32r.c:924
+msgid "SDA relocation when _SDA_BASE_ not defined"
+msgstr "SDA-relokalisering når _SDA_BASE_ ikke er defineret"
+
+#: elf32-ia64.c:3687 elf32-m32r.c:1013 elf32-ppc.c:2987 elf64-alpha.c:4185
+#: elf64-alpha.c:4313 elf64-ia64.c:3687
+#, c-format
+msgid "%s: unknown relocation type %d"
+msgstr "%s: ukendt relokaliseringstype %d"
+
+#: elf32-m32r.c:1221
+#, c-format
+msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
+msgstr "%s: Målet (%s) for en %s-relokalisering er i forkert sektion (%s)"
+
+#: elf32-m32r.c:1947
+#, c-format
+msgid "%s: Instruction set mismatch with previous modules"
+msgstr "%s: Instruktionsopsætning passer ikke med tidligere moduler"
+
+#: elf32-m32r.c:1970
+#, c-format
+msgid "private flags = %lx"
+msgstr "private flag = %lx"
+
+#: elf32-m32r.c:1975
+msgid ": m32r instructions"
+msgstr ": m32r-instruktioner"
+
+#: elf32-m32r.c:1976
+msgid ": m32rx instructions"
+msgstr ": m32rx-instruktioner"
+
+#: elf32-m68k.c:413
+msgid " [cpu32]"
+msgstr " [cpu32]"
+
+#: elf32-m68k.c:416
+msgid " [m68000]"
+msgstr " [m68000]"
+
+#: elf32-mcore.c:354 elf32-mcore.c:457
+#, c-format
+msgid "%s: Relocation %s (%d) is not currently supported.\n"
+msgstr "%s: Relokalisering %s (%d) understøttes ikke i øjeblikket.\n"
+
+#: elf32-mcore.c:442
+#, c-format
+msgid "%s: Unknown relocation type %d\n"
+msgstr "%s: Ukendt relokaliseringstype %d\n"
+
+#: elf32-mips.c:1152 elf64-mips.c:1783
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr "32-bit gp-relativ relokalisering forekom for et eksternt symbol"
+
+#: elf32-mips.c:1301
+#, c-format
+msgid "Linking mips16 objects into %s format is not supported"
+msgstr "Lænkning af mips16-objekter til %s-format understøttes ikke"
+
+#: elf32-ppc.c:1460
+#, c-format
+msgid "%s: compiled with -mrelocatable and linked with modules compiled normally"
+msgstr "%s: kompileret med -mrelocatable og lænket med moduler som kompileredes normalt"
+
+#: elf32-ppc.c:1468
+#, c-format
+msgid "%s: compiled normally and linked with modules compiled with -mrelocatable"
+msgstr "%s: kompileret normalt og lænket med moduler som kompileredes med -mrelocatable"
+
+#: elf32-ppc.c:1494 elf64-sparc.c:2989 elfxx-mips.c:7713
+#, c-format
+msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"
+msgstr "%s: bruger andre e_flags-felter (0x%lx) end tidligere moduler (0x%lx)"
+
+#: elf32-ppc.c:1592
+#, c-format
+msgid "%s: Unknown special linker type %d"
+msgstr "%s: Ukendt speciallænkertype %d"
+
+#: elf32-ppc.c:2273 elf32-ppc.c:2307 elf32-ppc.c:2342
+#, c-format
+msgid "%s: relocation %s cannot be used when making a shared object"
+msgstr "%s: relokaliseringen %s kan ikke bruges når et delt objekt oprettes"
+
+#: elf32-ppc.c:3126 elf64-ppc.c:5473
+#, c-format
+msgid "%s: unknown relocation type %d for symbol %s"
+msgstr "%s: ukendt relokaliseringstype %d for symbol %s"
+
+#: elf32-ppc.c:3482 elf32-ppc.c:3503 elf32-ppc.c:3553
+#, c-format
+msgid "%s: The target (%s) of a %s relocation is in the wrong output section (%s)"
+msgstr "%s: Målet (%s) for en %s-relokalisering er i forkert uddatasektion (%s)"
+
+#: elf32-ppc.c:3619
+#, c-format
+msgid "%s: Relocation %s is not yet supported for symbol %s."
+msgstr "%s: Relokaliseringen %s understøttes ikke endnu for symbol %s."
+
+#: elf32-sh.c:1964
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
+msgstr "%s: 0x%lx: advarsel: fejlagtig R_SH_USES-afstand"
+
+#: elf32-sh.c:1976
+#, c-format
+msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
+msgstr "%s: 0x%lx: advarsel: R_SH_USES peger til ukendt instruktion 0x%x"
+
+#: elf32-sh.c:1993
+#, c-format
+msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
+msgstr "%s: 0x%lx: advarsel: fejlagtig R_SH_USES-indlæsningsafstand"
+
+#: elf32-sh.c:2008
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected reloc"
+msgstr "%s: 0x%lx: advarsel: kunne ikke finde forventet relokalisering"
+
+#: elf32-sh.c:2036
+#, c-format
+msgid "%s: 0x%lx: warning: symbol in unexpected section"
+msgstr "%s: 0x%lx: advarsel: symbol i uventet sektion"
+
+#: elf32-sh.c:2153
+#, c-format
+msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
+msgstr "%s: 0x%lx: advarsel: kunne ikke finde forventet COUNT-relokalisering"
+
+#: elf32-sh.c:2162
+#, c-format
+msgid "%s: 0x%lx: warning: bad count"
+msgstr "%s: 0x%lx: advarsel: fejlagtigt antal"
+
+#: elf32-sh.c:2550 elf32-sh.c:2926
+#, c-format
+msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
+msgstr "%s: 0x%lx: fatalt: relokalisering giver overløb ved forenklingen"
+
+#: elf32-sh.c:4073 elf64-sh64.c:1576
+msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
+msgstr "Uventet STO_SH5_ISA32 på lokalt symbol håndteres ikke"
+
+#: elf32-sh.c:4284
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
+msgstr "%s: 0x%lx: fatalt: ujusteret grenmål for relokalisering for forenklingsunderstøttelse"
+
+#: elf32-sh64.c:203 elf64-sh64.c:2364
+#, c-format
+msgid "%s: compiled as 32-bit object and %s is 64-bit"
+msgstr "%s: kompileret som 32-bitsobjekt og %s er 64-bit"
+
+#: elf32-sh64.c:206 elf64-sh64.c:2367
+#, c-format
+msgid "%s: compiled as 64-bit object and %s is 32-bit"
+msgstr "%s: kompileret som 64-bitsobjekt og %s er 32-bit"
+
+#: elf32-sh64.c:208 elf64-sh64.c:2369
+#, c-format
+msgid "%s: object size does not match that of target %s"
+msgstr "%s: objektstørrelsen stemmer ikke overens med den hos målet %s"
+
+#: elf32-sh64.c:440 elf64-sh64.c:2941
+#, c-format
+msgid "%s: encountered datalabel symbol in input"
+msgstr "%s: mødte dataetikettesymbol i inddata"
+
+#: elf32-sh64.c:523
+msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
+msgstr "PTB passer ikke: en SHmedia-adresse (bit 0 == 1)"
+
+#: elf32-sh64.c:526
+msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
+msgstr "PTA passer ikke: en SHcompact-adresse (bit 0 == 0)"
+
+#: elf32-sh64.c:544
+#, c-format
+msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
+msgstr "%s: GAS-fejl: uventet PTB-instruktion med R_SH_PT_16"
+
+#: elf32-sh64.c:593 elf64-sh64.c:1703
+#, c-format
+msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
+msgstr "%s: fejl: ojusteret relokaliseringstype %d på %08x relokalisering %08x\n"
+
+#: elf32-sh64.c:677
+#, c-format
+msgid "%s: could not write out added .cranges entries"
+msgstr "%s: kunne ikke udskrive tilføjede .cranges-poster"
+
+#: elf32-sh64.c:739
+#, c-format
+msgid "%s: could not write out sorted .cranges entries"
+msgstr "%s: kunne ikke udskrive sorterede cranges-poster"
+
+#: elf32-sparc.c:1535 elf64-sparc.c:2224
+#, c-format
+msgid "%s: probably compiled without -fPIC?"
+msgstr "%s: nok kompileret uden -fPIC?"
+
+#: elf32-sparc.c:2002
+#, c-format
+msgid "%s: compiled for a 64 bit system and target is 32 bit"
+msgstr "%s: kompileret for et 64-bitssystem og målet er 32-bit"
+
+#: elf32-sparc.c:2016
+#, c-format
+msgid "%s: linking little endian files with big endian files"
+msgstr "%s: lænker little endian-filer med big endian-filer"
+
+#: elf32-v850.c:682
+#, c-format
+msgid "Variable `%s' cannot occupy in multiple small data regions"
+msgstr "Variabel \"%s\" kan ikke befinde sig i flere små dataområder"
+
+#: elf32-v850.c:685
+#, c-format
+msgid "Variable `%s' can only be in one of the small, zero, and tiny data regions"
+msgstr "Variabel \"%s\" kan kun være i et af de små, tomme og bittesmå dataområder"
+
+#: elf32-v850.c:688
+#, c-format
+msgid "Variable `%s' cannot be in both small and zero data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både små og tomme dataområder samtidigt"
+
+#: elf32-v850.c:691
+#, c-format
+msgid "Variable `%s' cannot be in both small and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både små og bittesmå dataområder samtidigt"
+
+#: elf32-v850.c:694
+#, c-format
+msgid "Variable `%s' cannot be in both zero and tiny data regions simultaneously"
+msgstr "Variabel \"%s\" kan ikke være i både tomme og bittesmå dataområder samtidigt"
+
+#: elf32-v850.c:1072
+msgid "FAILED to find previous HI16 reloc\n"
+msgstr "MISLYKKEDES med at finde tidligere HI16-relokalisering\n"
+
+#: elf32-v850.c:1703
+msgid "could not locate special linker symbol __gp"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __gp"
+
+#: elf32-v850.c:1707
+msgid "could not locate special linker symbol __ep"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __ep"
+
+#: elf32-v850.c:1711
+msgid "could not locate special linker symbol __ctbp"
+msgstr "kunne ikke lokalisere specielt lænkersymbol __ctbp"
+
+#: elf32-v850.c:1875
+#, c-format
+msgid "%s: Architecture mismatch with previous modules"
+msgstr "%s: Arkitekturen passer ikke sammen med tidligere moduler"
+
+#: elf32-v850.c:1895
+#, c-format
+msgid "private flags = %lx: "
+msgstr "private flag = %lx: "
+
+#: elf32-v850.c:1900
+msgid "v850 architecture"
+msgstr "v850-arkitektur"
+
+#: elf32-v850.c:1901
+msgid "v850e architecture"
+msgstr "v850e-arkitektur"
+
+#: elf32-v850.c:1902
+msgid "v850ea architecture"
+msgstr "v850ea-arkitektur"
+
+#: elf32-vax.c:546
+msgid " [nonpic]"
+msgstr " [ikke-pic]"
+
+#: elf32-vax.c:549
+msgid " [d-float]"
+msgstr " [d-flydende tal]"
+
+#: elf32-vax.c:552
+msgid " [g-float]"
+msgstr " [g-flydende tal]"
+
+#: elf32-vax.c:674
+#, c-format
+msgid "%s: warning: GOT addend of %ld to `%s' does not match previous GOT addend of %ld"
+msgstr "%s: advarsel: GOT-addendum %ld til \"%s\" stemmer ikke overens med tidligere GOT-addendum %ld"
+
+#: elf32-vax.c:1679
+#, c-format
+msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
+msgstr "%s: advarsel: PLT-addendum %d til \"%s\" fra sektionen %s ignoreredes"
+
+#: elf32-vax.c:1814
+#, c-format
+msgid "%s: warning: %s relocation against symbol `%s' from %s section"
+msgstr "%s: advarsel: %s-relokalisering mod symbol \"%s\" fra sektionen %s"
+
+#: elf32-vax.c:1820
+#, c-format
+msgid "%s: warning: %s relocation to 0x%x from %s section"
+msgstr "%s: advarsel: %s-relokalisering til 0x%x fra sektionen %s"
+
+#: elf32-ia64.c:2280 elf32-xstormy16.c:414 elf64-ia64.c:2280
+msgid "non-zero addend in @fptr reloc"
+msgstr "ikke-tomt addendum i @fptr-relokalisering"
+
+#: elf64-alpha.c:1097
+msgid "GPDISP relocation did not find ldah and lda instructions"
+msgstr "GPDISP-relokalisering fandt ingen ldah- og lda-instruktioner"
+
+#: elf64-alpha.c:3675
+#, c-format
+msgid "%s: .got subsegment exceeds 64K (size %d)"
+msgstr "%s: .got-subsegment overskrider 64 kB (størrelse %d)"
+
+#: elf64-alpha.c:4498 elf64-alpha.c:4510
+#, c-format
+msgid "%s: gp-relative relocation against dynamic symbol %s"
+msgstr "%s: gp-relativ relokalisering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4536 elf64-alpha.c:4676
+#, c-format
+msgid "%s: pc-relative relocation against dynamic symbol %s"
+msgstr "%s: pc-relativ relokalisering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4564
+#, c-format
+msgid "%s: change in gp: BRSGP %s"
+msgstr "%s: ændring i gp: BRSGP %s"
+
+#: elf64-alpha.c:4589
+msgid "<unknown>"
+msgstr "<ukendt>"
+
+#: elf64-alpha.c:4594
+#, c-format
+msgid "%s: !samegp reloc against symbol without .prologue: %s"
+msgstr "%s: !samegp-relokalisering mod symbol uden .prologue: %s"
+
+#: elf64-alpha.c:4639
+#, c-format
+msgid "%s: unhandled dynamic relocation against %s"
+msgstr "%s: uhåndteret dynamisk relokalisering mod %s"
+
+#: elf64-alpha.c:4752
+#, c-format
+msgid "%s: dtp-relative relocation against dynamic symbol %s"
+msgstr "%s: dtp-relativ relokalisering mod dynamisk symbol %s"
+
+#: elf64-alpha.c:4775
+#, c-format
+msgid "%s: tp-relative relocation against dynamic symbol %s"
+msgstr "%s: tp-relativ relokalisering mod dynamisk symbol %s"
+
+#: elf64-hppa.c:2080
+#, c-format
+msgid "stub entry for %s cannot load .plt, dp offset = %ld"
+msgstr "stubpost for %s kan ikke læse in .plt, dp-afstand = %ld"
+
+#: elf64-mmix.c:1002
+#, c-format
+msgid ""
+"%s: Internal inconsistency error for value for\n"
+" linker-allocated global register: linked: 0x%lx%08lx != relaxed: 0x%lx%08lx\n"
+msgstr ""
+"%s: Intern inkkonsistensfejl for værdien for\n"
+" lænkerallokeret globalt register: lænket: 0x%lx%08lx != afslappet: 0x%lx%08lx\n"
+
+#: elf64-mmix.c:1386
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: (unknown) in %s"
+msgstr "%s: base-plus-afstandsrelokalisering mod registersymbol: (ukendt) i %s"
+
+#: elf64-mmix.c:1391
+#, c-format
+msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
+msgstr "%s: base-plus-afstandsrelokalisering mod registersymbol: %s i %s"
+
+#: elf64-mmix.c:1435
+#, c-format
+msgid "%s: register relocation against non-register symbol: (unknown) in %s"
+msgstr "%s: registerrelokalisering mod ikke-registersymbol: (ukendt) i %s"
+
+#: elf64-mmix.c:1440
+#, c-format
+msgid "%s: register relocation against non-register symbol: %s in %s"
+msgstr "%s: registerrelokalisering mod ikke-registersymbol: %s i %s"
+
+#: elf64-mmix.c:1477
+#, c-format
+msgid "%s: directive LOCAL valid only with a register or absolute value"
+msgstr "%s: LOCAL-direktivet er kun gyldigt med et register eller en absolutværdi"
+
+#: elf64-mmix.c:1505
+#, c-format
+msgid "%s: LOCAL directive: Register $%ld is not a local register.  First global register is $%ld."
+msgstr "%s: LOCAL-direktiv: Register $%ld er ikke et lokalt register. Første globale register er $%ld."
+
+#: elf64-mmix.c:1965
+#, c-format
+msgid "%s: Error: multiple definition of `%s'; start of %s is set in a earlier linked file\n"
+msgstr "%s: Fejl: flere definitioner af \"%s\"; begyndelsen på %s er sat i en tidligere lænket fil\n"
+
+#: elf64-mmix.c:2024
+msgid "Register section has contents\n"
+msgstr "Registersektion har indhold\n"
+
+#: elf64-mmix.c:2186
+#, c-format
+msgid ""
+"Internal inconsistency: remaining %u != max %u.\n"
+"  Please report this bug."
+msgstr ""
+"Intern inkonsekvens: genstående %u != max %u.\n"
+"  Rapportér gerne denne fejl."
+
+#: elf64-ppc.c:1669 libbfd.c:1435
+#, c-format
+msgid "%s: compiled for a big endian system and target is little endian"
+msgstr "%s: kompileret for et big endian-system og målet er little endian"
+
+#: elf64-ppc.c:1671 libbfd.c:1437
+#, c-format
+msgid "%s: compiled for a little endian system and target is big endian"
+msgstr "%s: kompileret for et little endian-system og målet er big endian"
+
+#: elf64-ppc.c:3610
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr "%s: uventet relokaliseringstype %u i .opd-sektion"
+
+#: elf64-ppc.c:3630
+#, c-format
+msgid "%s: .opd is not a regular array of opd entries"
+msgstr "%s: .opd er ikke en almindelig vektor med opd-poster"
+
+#: elf64-ppc.c:3672
+#, c-format
+msgid "%s: undefined sym `%s' in .opd section"
+msgstr "%s: udefineret symbol \"%s\" i .opd-sektion"
+
+#: elf64-ppc.c:4397
+#, c-format
+msgid "can't find branch stub `%s'"
+msgstr "kan ikke finde grenstub \"%s\""
+
+#: elf64-ppc.c:4436 elf64-ppc.c:4501
+#, c-format
+msgid "linkage table error against `%s'"
+msgstr "lænketabelsfejl mod \"%s\""
+
+#: elf64-ppc.c:4573
+#, c-format
+msgid "can't build branch stub `%s'"
+msgstr "kan ikke bygge grenstub \"%s\""
+
+#: elf64-ppc.c:5179
+msgid "stubs don't match calculated size"
+msgstr "stubbe stemmer ikke overens med beregnet størrelse"
+
+#: elf64-ppc.c:5828
+#, c-format
+msgid "%s: Relocation %s is not supported for symbol %s."
+msgstr "%s: Relokaliseringen %s understøttes ikke for symbol %s."
+
+#: elf64-ppc.c:5872
+#, c-format
+msgid "%s: error: relocation %s not a multiple of 4"
+msgstr "%s: fejl: relokaliseringen %s er ikke en multipel af 4"
+
+#: elf64-sparc.c:1280
+#, c-format
+msgid "%s: check_relocs: unhandled reloc type %d"
+msgstr "%s: check_relocs: uhåndteret relokaliseringstype %d"
+
+#: elf64-sparc.c:1317
+#, c-format
+msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
+msgstr "%s: Kun register %%g[2367] kan deklareres med STT_REGISTER"
+
+#: elf64-sparc.c:1337
+#, c-format
+msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
+msgstr "Register %%g%d brugt inkompatibelt: %s i %s, tidligere %s i %s"
+
+#: elf64-sparc.c:1360
+#, c-format
+msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
+msgstr "Symbol \"%s\" har forskellige typer: REGISTER i %s, tidligere %s i %s"
+
+#: elf64-sparc.c:1406
+#, c-format
+msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
+msgstr "Symbol \"%s\" har forskellige typer: %s i %s, tidligere REGISTER i %s"
+
+#: elf64-sparc.c:2970
+#, c-format
+msgid "%s: linking UltraSPARC specific with HAL specific code"
+msgstr "%s: lænker UltraSPARC-specifik med HAL-specifik kode"
+
+#: elfcode.h:1198
+#, c-format
+msgid "%s: version count (%ld) does not match symbol count (%ld)"
+msgstr "%s: versionsantal (%ld) stemmer ikke med symbolantal (%ld)"
+
+#: elflink.c:440
+#, c-format
+msgid "%s: Section %s is too large to add hole of %ld bytes"
+msgstr "%s: Sektionen %s er for stor til at stoppa hul med %ld byte i"
+
+#: elflink.h:1090
+#, c-format
+msgid "%s: warning: unexpected redefinition of `%s'"
+msgstr "%s: advarsel: uventet omdefinition af \"%s\""
+
+#: elflink.h:1727
+#, c-format
+msgid "%s: %s: invalid version %u (max %d)"
+msgstr "%s: %s: ugyldig version %u (max %d)"
+
+#: elflink.h:1768
+#, c-format
+msgid "%s: %s: invalid needed version %d"
+msgstr "%s: %s: ugyldig krævet version %d"
+
+#: elflink.h:1890
+#, c-format
+msgid "Warning: size of symbol `%s' changed from %lu to %lu in %s"
+msgstr "Advarsel: størrelsen på symbol \"%s\" ændredes fra %lu til %lu i %s"
+
+#: elflink.h:3174
+#, c-format
+msgid "%s: .preinit_array section is not allowed in DSO"
+msgstr "%s: .preinit_array-sektionen er ikke tilladt i DSO"
+
+#: elflink.h:4030
+#, c-format
+msgid "warning: type and size of dynamic symbol `%s' are not defined"
+msgstr "advarsel: typen og størrelsen på dynamisk symbol \"%s\" er ikke defineret"
+
+#: elflink.h:4345
+#, c-format
+msgid "%s: undefined versioned symbol name %s"
+msgstr "%s: udefineret symbolnavn med version %s"
+
+#: elflink.h:4611 elflink.h:4619 elflink.h:6508 elflink.h:7600
+msgid "Error: out of memory"
+msgstr "Fejl: ikke mere hukommelse"
+
+#: elflink.h:4781
+msgid "Not enough memory to sort relocations"
+msgstr "Ikke nok hukommelse til at sortere relokaliseringer"
+
+#: elflink.h:5682 elflink.h:5725
+#, c-format
+msgid "%s: could not find output section %s"
+msgstr "%s: kunne ikke finde uddatasektionen %s"
+
+#: elflink.h:5688
+#, c-format
+msgid "warning: %s section has zero size"
+msgstr "advarsel: %s-sektionen har nulstørrelse"
+
+#: elflink.h:6275
+#, c-format
+msgid "%s: could not find output section %s for input section %s"
+msgstr "%s: kunne ikke finde uddatasektionen %s for inddatasektionen %s"
+
+#: elflink.h:6486
+#, c-format
+msgid "%s: relocation size mismatch in %s section %s"
+msgstr "%s: relokaliseringsstørrelsen stemmer ikke overens i %s-sektionen %s"
+
+#: elflink.h:6849
+msgid "warning: relocation against removed section; zeroing"
+msgstr "advarsel: relokalisering mod fjernet sektion; nulstiller"
+
+#: elflink.h:6879
+msgid "warning: relocation against removed section"
+msgstr "advarsel: relokalisering mod fjernet sektion"
+
+#: elflink.h:6892
+#, c-format
+msgid "local symbols in discarded section %s"
+msgstr "lokale symboler i bortkastet sektion %s"
+
+#: elfxx-mips.c:734
+msgid "static procedure (no name)"
+msgstr "statisk procedure (intet navn)"
+
+#: elfxx-mips.c:1601
+msgid "not enough GOT space for local GOT entries"
+msgstr "ikke nok med GOT-plads for lokale GOT-poster"
+
+#: elfxx-mips.c:2750
+#, c-format
+msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
+msgstr "%s: %s+0x%lx: hop til stubrutine som ikke er jal"
+
+#: elfxx-mips.c:4270
+#, c-format
+msgid "%s: Malformed reloc detected for section %s"
+msgstr "%s: Fejlagtig relokalisering for sektion %s opdaget"
+
+#: elfxx-mips.c:4348
+#, c-format
+msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
+msgstr "%s: CALL16-relokalisering ved 0x%lx er ikke mod globalt symbol"
+
+#: elfxx-mips.c:7301
+#, c-format
+msgid "%s: illegal section name `%s'"
+msgstr "%s: ugyldigt sektionsnavn \"%s\""
+
+#: elfxx-mips.c:7615
+#, c-format
+msgid "%s: linking PIC files with non-PIC files"
+msgstr "%s: lænker PIC-filer med ikke-PIC-filer"
+
+#: elfxx-mips.c:7625
+#, c-format
+msgid "%s: linking abicalls files with non-abicalls files"
+msgstr "%s: lænker abicalls-filer med ikke-abicalls-filer"
+
+#: elfxx-mips.c:7654
+#, c-format
+msgid "%s: ISA mismatch (-mips%d) with previous modules (-mips%d)"
+msgstr "%s: ISA (-mips%d) passer ikke med tidligere moduler (-mips%d)"
+
+#: elfxx-mips.c:7676
+#, c-format
+msgid "%s: ISA mismatch (%d) with previous modules (%d)"
+msgstr "%s: ISA (%d) passer ikke med tidligere moduler (%d)"
+
+#: elfxx-mips.c:7699
+#, c-format
+msgid "%s: ABI mismatch: linking %s module with previous %s modules"
+msgstr "%s: ABI passer ikke: lænker %s-modul med tidligere %s-moduler"
+
+#: elfxx-mips.c:7759
+msgid " [abi=O32]"
+msgstr " [abi=O32]"
+
+#: elfxx-mips.c:7761
+msgid " [abi=O64]"
+msgstr " [abi=O64]"
+
+#: elfxx-mips.c:7763
+msgid " [abi=EABI32]"
+msgstr " [abi=EABI32]"
+
+#: elfxx-mips.c:7765
+msgid " [abi=EABI64]"
+msgstr " [abi=EABI64]"
+
+#: elfxx-mips.c:7767
+msgid " [abi unknown]"
+msgstr " [ukendt abi]"
+
+#: elfxx-mips.c:7769
+msgid " [abi=N32]"
+msgstr " [abi=N32]"
+
+#: elfxx-mips.c:7771
+msgid " [abi=64]"
+msgstr " [abi=64]"
+
+#: elfxx-mips.c:7773
+msgid " [no abi set]"
+msgstr " [intet abi sat]"
+
+#: elfxx-mips.c:7776
+msgid " [mips1]"
+msgstr " [mips1]"
+
+#: elfxx-mips.c:7778
+msgid " [mips2]"
+msgstr " [mips2]"
+
+#: elfxx-mips.c:7780
+msgid " [mips3]"
+msgstr " [mips3]"
+
+#: elfxx-mips.c:7782
+msgid " [mips4]"
+msgstr " [mips4]"
+
+#: elfxx-mips.c:7784
+msgid " [mips5]"
+msgstr " [mips5]"
+
+#: elfxx-mips.c:7786
+msgid " [mips32]"
+msgstr " [mips32]"
+
+#: elfxx-mips.c:7788
+msgid " [mips64]"
+msgstr " [mips64]"
+
+#: elfxx-mips.c:7790
+msgid " [unknown ISA]"
+msgstr " [ukendt ISA]"
+
+#: elfxx-mips.c:7793
+msgid " [mdmx]"
+msgstr " [mdmx]"
+
+#: elfxx-mips.c:7796
+msgid " [mips16]"
+msgstr " [mips16]"
+
+#: elfxx-mips.c:7799
+msgid " [32bitmode]"
+msgstr " [32-bittilstand]"
+
+#: elfxx-mips.c:7801
+msgid " [not 32bitmode]"
+msgstr " [ikke 32-bittilstand]"
+
+#: i386linux.c:458 m68klinux.c:462 sparclinux.c:459
+#, c-format
+msgid "Output file requires shared library `%s'\n"
+msgstr "Uddatafilen kræver delt bibliotek \"%s\"\n"
+
+#: i386linux.c:466 m68klinux.c:470 sparclinux.c:467
+#, c-format
+msgid "Output file requires shared library `%s.so.%s'\n"
+msgstr "Uddatafilen kræver delt bibliotek \"%s.so.%s\"\n"
+
+#: i386linux.c:655 i386linux.c:705 m68klinux.c:662 m68klinux.c:710
+#: sparclinux.c:657 sparclinux.c:707
+#, c-format
+msgid "Symbol %s not defined for fixups\n"
+msgstr "Symbol %s er ikke defineret for rettelser\n"
+
+#: i386linux.c:729 m68klinux.c:734 sparclinux.c:731
+msgid "Warning: fixup count mismatch\n"
+msgstr "Advarsel: antal rettelser stemmer ikke\n"
+
+#: ieee.c:235
+#, c-format
+msgid "%s: string too long (%d chars, max 65535)"
+msgstr "%s: strengen er for lang (%d tegn, max 65535)"
+
+#: ieee.c:365
+#, c-format
+msgid "%s: unrecognized symbol `%s' flags 0x%x"
+msgstr "%s: ukendt symbol \"%s\" flag 0x%x"
+
+#: ieee.c:877
+#, c-format
+msgid "%s: unimplemented ATI record %u for symbol %u"
+msgstr "%s: ikke implementeret ATI-post %u for symbol %u"
+
+#: ieee.c:902
+#, c-format
+msgid "%s: unexpected ATN type %d in external part"
+msgstr "%s: uventet ATN-type %d i ekstern del"
+
+#: ieee.c:924
+#, c-format
+msgid "%s: unexpected type after ATN"
+msgstr "%s: uventet type efter ATN"
+
+#: ihex.c:258
+#, c-format
+msgid "%s:%d: unexpected character `%s' in Intel Hex file\n"
+msgstr "%s:%d: uventet tegn \"%s\" i hexadecimal Intel-fil\n"
+
+#: ihex.c:366
+#, c-format
+msgid "%s:%u: bad checksum in Intel Hex file (expected %u, found %u)"
+msgstr "%s:%u: fejlagtig kontrolsum i hexadecimal Intel-fil (forventede %u, fandt %u)"
+
+#: ihex.c:420
+#, c-format
+msgid "%s:%u: bad extended address record length in Intel Hex file"
+msgstr "%s:%u: fejlagtig længde på post for udvidet adresse i hexadecimal Intel-fil"
+
+#: ihex.c:437
+#, c-format
+msgid "%s:%u: bad extended start address length in Intel Hex file"
+msgstr "%s:%u: fejlagtig længde på udvidet startadresse i hexadecimal Intel-fil"
+
+#: ihex.c:454
+#, c-format
+msgid "%s:%u: bad extended linear address record length in Intel Hex file"
+msgstr "%s:%u: fejlagtig længde på post for udvidet lineær adresse i hexadecimal Intel-fil"
+
+#: ihex.c:471
+#, c-format
+msgid "%s:%u: bad extended linear start address length in Intel Hex file"
+msgstr "%s:%u: fejlagtig længde på post for udvidet lineær startadresse i hexadecimal Intel-fil"
+
+#: ihex.c:488
+#, c-format
+msgid "%s:%u: unrecognized ihex type %u in Intel Hex file\n"
+msgstr "%s:%u: ukendt ihex-type %u i hexadecimal Intel-fil\n"
+
+#: ihex.c:607
+#, c-format
+msgid "%s: internal error in ihex_read_section"
+msgstr "%s: intern fejl i ihex_read_section"
+
+#: ihex.c:642
+#, c-format
+msgid "%s: bad section length in ihex_read_section"
+msgstr "%s: fejlagtig sektionslængde i ihex_read_sektion"
+
+#: ihex.c:860
+#, c-format
+msgid "%s: address 0x%s out of range for Intel Hex file"
+msgstr "%s: adressen 0x%s er udenfor intervallet for hexadecimal Intel-fil"
+
+#: libbfd.c:492
+#, c-format
+msgid "not mapping: data=%lx mapped=%d\n"
+msgstr "mapper ikke: data=%lx mappet=%d\n"
+
+#: libbfd.c:495
+msgid "not mapping: env var not set\n"
+msgstr "mapper ikke: miljøvariabel er ikke sat\n"
+
+#: libbfd.c:1466
+#, c-format
+msgid "Deprecated %s called at %s line %d in %s\n"
+msgstr "Forældet %s kaldt ved %s linje %d i %s\n"
+
+#: libbfd.c:1469
+#, c-format
+msgid "Deprecated %s called\n"
+msgstr "Forældet %s kaldt\n"
+
+#: linker.c:1873
+#, c-format
+msgid "%s: indirect symbol `%s' to `%s' is a loop"
+msgstr "%s: indirekte symbol \"%s\" til \"%s\" er en løkke"
+
+#: linker.c:2776
+#, c-format
+msgid "Attempt to do relocateable link with %s input and %s output"
+msgstr "Forsøg at lave en relokaliseringsbar lænke med %s-inddata og %s-uddata"
+
+#: merge.c:892
+#, c-format
+msgid "%s: access beyond end of merged section (%ld + %ld)"
+msgstr "%s: adgang udover slutningen på sammenslagt sektion (%ld + %ld)"
+
+#: mmo.c:460
+#, c-format
+msgid "%s: No core to allocate section name %s\n"
+msgstr "%s: Ingen kerne til at allokere sektionsnavn %s\n"
+
+#: mmo.c:536
+#, c-format
+msgid "%s: No core to allocate a symbol %d bytes long\n"
+msgstr "%s: Ingen kerne for at allokere et %d byte langt symbol\n"
+
+#: mmo.c:1245
+#, c-format
+msgid "%s: invalid mmo file: initialization value for $255 is not `Main'\n"
+msgstr "%s: ugyldig mmo-fil: initieringsværdi for $255 er ikke \"Main\"\n"
+
+#: mmo.c:1391
+#, c-format
+msgid "%s: unsupported wide character sequence 0x%02X 0x%02X after symbol name starting with `%s'\n"
+msgstr "%s: bred tegnsekvens som ikke understøttes 0x%02X 0x%02X efter symbolnavnet som begynder med \"%s\"\n"
+
+#: mmo.c:1633
+#, c-format
+msgid "%s: invalid mmo file: unsupported lopcode `%d'\n"
+msgstr "%s: ugyldig mmo-fil: lopkod \"%d\" understøttes ikke\n"
+
+#: mmo.c:1643
+#, c-format
+msgid "%s: invalid mmo file: expected YZ = 1 got YZ = %d for lop_quote\n"
+msgstr "%s: ugyldig mmo-fil: forventede YZ = 1 fik YZ = %d for lop_quote\n"
+
+#: mmo.c:1679
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_loc\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 1 eller z = 2, fik z = %d for lop_loc\n"
+
+#: mmo.c:1725
+#, c-format
+msgid "%s: invalid mmo file: expected z = 1 or z = 2, got z = %d for lop_fixo\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 1 eller z = 2, fik z = %d for lop_fixo\n"
+
+#: mmo.c:1764
+#, c-format
+msgid "%s: invalid mmo file: expected y = 0, got y = %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: forventede y = 0, fik y = %d for lop_fixrx\n"
+
+#: mmo.c:1773
+#, c-format
+msgid "%s: invalid mmo file: expected z = 16 or z = 24, got z = %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: forventede z = 16 eller z = 24, fik z = %d for lop_fixr\n"
+
+#: mmo.c:1796
+#, c-format
+msgid "%s: invalid mmo file: leading byte of operand word must be 0 or 1, got %d for lop_fixrx\n"
+msgstr "%s: ugyldig mmo-fil: indledende byte i operandord skal være 0 eller 1, fik %d for lop_fixrx\n"
+
+#: mmo.c:1819
+#, c-format
+msgid "%s: cannot allocate file name for file number %d, %d bytes\n"
+msgstr "%s: kan ikke allokere filnavn for fil nummer %d, %d byte\n"
+
+#: mmo.c:1839
+#, c-format
+msgid "%s: invalid mmo file: file number %d `%s', was already entered as `%s'\n"
+msgstr "%s: ugyldig mmo-fil: fil nummer %d \"%s\", var allerede angivet som \"%s\"\n"
+
+#: mmo.c:1852
+#, c-format
+msgid "%s: invalid mmo file: file name for number %d was not specified before use\n"
+msgstr "%s: ugyldig mmo-fil: filnavnet for nummer %d blev ikke angivet inden brug\n"
+
+#: mmo.c:1958
+#, c-format
+msgid "%s: invalid mmo file: fields y and z of lop_stab non-zero, y: %d, z: %d\n"
+msgstr "%s: ugyldig mmo-fil: felter y og z i lop_stab er ikke-tomme, y: %d, z: %d\n"
+
+#: mmo.c:1994
+#, c-format
+msgid "%s: invalid mmo file: lop_end not last item in file\n"
+msgstr "%s: ugyldig mmo-fil: lop_end er ikke sidste objekt i fil\n"
+
+#: mmo.c:2007
+#, c-format
+msgid "%s: invalid mmo file: YZ of lop_end (%ld) not equal to the number of tetras to the preceding lop_stab (%ld)\n"
+msgstr "%s: ugyldig mmo-fil: YZ i lop_end (%ld) er ikke lig med antal af tetraer til den foregående lop_stab (%ld)\n"
+
+#: mmo.c:2670
+#, c-format
+msgid "%s: invalid symbol table: duplicate symbol `%s'\n"
+msgstr "%s: ugyldig symboltabel: dubletsymbol \"%s\"\n"
+
+#: mmo.c:2921
+#, c-format
+msgid "%s: Bad symbol definition: `Main' set to %s rather than the start address %s\n"
+msgstr "%s: Fejlagtig symboldefinition: \"Main\" er sat til %s i stedet for startadressen %s\n"
+
+#: mmo.c:3011
+#, c-format
+msgid "%s: warning: symbol table too large for mmo, larger than 65535 32-bit words: %d.  Only `Main' will be emitted.\n"
+msgstr "%s: advarsel: symboltabellen er for stor for mmo, større end 65535 32-bit ord: %d. Kun \"Main\" vil blive sendt.\n"
+
+#: mmo.c:3056
+#, c-format
+msgid "%s: internal error, symbol table changed size from %d to %d words\n"
+msgstr "%s: intern fejl, symboltabellen ændrede størrelse fra %d til %d ord\n"
+
+#: mmo.c:3111
+#, c-format
+msgid "%s: internal error, internal register section %s had contents\n"
+msgstr "%s: intern fejl, den interne registersektion %s havde indhold\n"
+
+#: mmo.c:3163
+#, c-format
+msgid "%s: no initialized registers; section length 0\n"
+msgstr "%s: ingen initierede registre; sektionslængde 0\n"
+
+#: mmo.c:3169
+#, c-format
+msgid "%s: too many initialized registers; section length %ld\n"
+msgstr "%s: for mange initierede registre; sektionslængde %ld\n"
+
+#: mmo.c:3174
+#, c-format
+msgid "%s: invalid start address for initialized registers of length %ld: 0x%lx%08lx\n"
+msgstr "%s: ugyldig startadresse for initierede registre med længden %ld: 0x%lx%08lx\n"
+
+#: oasys.c:1029
+#, c-format
+msgid "%s: can not represent section `%s' in oasys"
+msgstr "%s: kan ikke repræsentere sektionen \"%s\" i oasys"
+
+#: osf-core.c:132
+#, c-format
+msgid "Unhandled OSF/1 core file section type %d\n"
+msgstr "Uhåndteret sektionstype %d for OSF/1-hukommelsesfil\n"
+
+#: pe-mips.c:658
+#, c-format
+msgid "%s: `ld -r' not supported with PE MIPS objects\n"
+msgstr "%s: \"ld -r\" understøttes ikke med PE MIPS-objekt\n"
+
+#. OK, at this point the following variables are set up:
+#. src = VMA of the memory we're fixing up
+#. mem = pointer to memory we're fixing up
+#. val = VMA of what we need to refer to
+#.
+#: pe-mips.c:794
+#, c-format
+msgid "%s: unimplemented %s\n"
+msgstr "%s: uimplementeret %s\n"
+
+#: pe-mips.c:820
+#, c-format
+msgid "%s: jump too far away\n"
+msgstr "%s: hop for langt bort\n"
+
+#: pe-mips.c:847
+#, c-format
+msgid "%s: bad pair/reflo after refhi\n"
+msgstr "%s: fejlagtigt par/reflo efter refhi\n"
+
+#. XXX code yet to be written.
+#: peicode.h:785
+#, c-format
+msgid "%s: Unhandled import type; %x"
+msgstr "%s: Uhåndteret importtype; %x"
+
+#: peicode.h:790
+#, c-format
+msgid "%s: Unrecognised import type; %x"
+msgstr "%s: Ukendt importtype; %x"
+
+#: peicode.h:804
+#, c-format
+msgid "%s: Unrecognised import name type; %x"
+msgstr "%s: Ukendt importnavnstype; %x"
+
+#: peicode.h:1162
+#, c-format
+msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Ukendt maskintype (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1174
+#, c-format
+msgid "%s: Recognised but unhandled machine type (0x%x) in Import Library Format archive"
+msgstr "%s: Kendt men uhåndteret maskintype (0x%x) i Import Library Format-arkiv"
+
+#: peicode.h:1191
+#, c-format
+msgid "%s: size field is zero in Import Library Format header"
+msgstr "%s: størrelsesfeltet er nul i Import Library Format-hoved"
+
+#: peicode.h:1219
+#, c-format
+msgid "%s: string not null terminated in ILF object file."
+msgstr "%s: streng ikke nultermineret i ILF-objektfil."
+
+#: ppcboot.c:416
+msgid ""
+"\n"
+"ppcboot header:\n"
+msgstr ""
+"\n"
+"ppcboot-hoved:\n"
+
+#: ppcboot.c:417
+#, c-format
+msgid "Entry offset        = 0x%.8lx (%ld)\n"
+msgstr "Startafstand        = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:418
+#, c-format
+msgid "Length              = 0x%.8lx (%ld)\n"
+msgstr "Længde              = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:421
+#, c-format
+msgid "Flag field          = 0x%.2x\n"
+msgstr "Flagfelt            = 0x%.2x\n"
+
+#: ppcboot.c:427
+#, c-format
+msgid "Partition name      = \"%s\"\n"
+msgstr "Partitionsnavn      = \"%s\"\n"
+
+#: ppcboot.c:446
+#, c-format
+msgid ""
+"\n"
+"Partition[%d] start  = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr ""
+"\n"
+"Start på partition[%d]  = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:452
+#, c-format
+msgid "Partition[%d] end    = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+msgstr "Slut på partition[%d]    = { 0x%.2x, 0x%.2x, 0x%.2x, 0x%.2x }\n"
+
+#: ppcboot.c:458
+#, c-format
+msgid "Partition[%d] sector = 0x%.8lx (%ld)\n"
+msgstr "Sektor for partition[%d] = 0x%.8lx (%ld)\n"
+
+#: ppcboot.c:459
+#, c-format
+msgid "Partition[%d] length = 0x%.8lx (%ld)\n"
+msgstr "Længde på partition[%d] = 0x%.8lx (%ld)\n"
+
+#: som.c:5398
+msgid "som_sizeof_headers unimplemented"
+msgstr "som_sizeof_headers er ikke implementeret"
+
+#: srec.c:301
+#, c-format
+msgid "%s:%d: Unexpected character `%s' in S-record file\n"
+msgstr "%s:%d: Uventet tegn \"%s\" i S-postfil\n"
+
+# Vad er stabs?
+#: stabs.c:319
+#, c-format
+msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
+msgstr "%s(%s+0x%lx): Stabpost har ugyldigt strengindex."
+
+#: syms.c:1044
+msgid "Unsupported .stab relocation"
+msgstr ".stab-relokalisering som ikke understøttes"
+
+#: vms-gsd.c:356
+#, c-format
+msgid "bfd_make_section (%s) failed"
+msgstr "bfd_make_section (%s) mislykkedes"
+
+#: vms-gsd.c:371
+#, c-format
+msgid "bfd_set_section_flags (%s, %x) failed"
+msgstr "bfd_set_section_flags (%s, %x) mislykkedes"
+
+#: vms-gsd.c:407
+#, c-format
+msgid "Size mismatch section %s=%lx, %s=%lx"
+msgstr "Størrelsen passer ikke på sektion %s=%lx, %s=%lx"
+
+#: vms-gsd.c:702
+#, c-format
+msgid "unknown gsd/egsd subtype %d"
+msgstr "ukendt gsd/egsd-undertype %d"
+
+#: vms-hdr.c:406
+msgid "Object module NOT error-free !\n"
+msgstr "Objektmodulet IKKE fejlfri!\n"
+
+#: vms-misc.c:543
+#, c-format
+msgid "Stack overflow (%d) in _bfd_vms_push"
+msgstr "Stakken giver overløb (%d) i _bfd_vms_push"
+
+#: vms-misc.c:561
+msgid "Stack underflow in _bfd_vms_pop"
+msgstr "Stakken giver underløb i _bfd_vms_pop"
+
+#: vms-misc.c:919
+msgid "_bfd_vms_output_counted called with zero bytes"
+msgstr "_bfd_vms_output_counted kaldt med nul byte"
+
+#: vms-misc.c:924
+msgid "_bfd_vms_output_counted called with too many bytes"
+msgstr "_bfd_vms_output_counted called kaldt med for mange byte"
+
+#: vms-misc.c:1055
+#, c-format
+msgid "Symbol %s replaced by %s\n"
+msgstr "Symbol %s erstattet med %s\n"
+
+#: vms-misc.c:1117
+#, c-format
+msgid "failed to enter %s"
+msgstr "mislykkedes med at gå ind i %s"
+
+#: vms-tir.c:81
+msgid "No Mem !"
+msgstr "Ingen hukommelse!"
+
+#: vms-tir.c:362
+#, c-format
+msgid "bad section index in %s"
+msgstr "fejlagtigt sektionsindex i %s"
+
+#: vms-tir.c:375
+#, c-format
+msgid "unsupported STA cmd %s"
+msgstr "STA-kommando %s understøttes ikke"
+
+#: vms-tir.c:380 vms-tir.c:1240
+#, c-format
+msgid "reserved STA cmd %d"
+msgstr "reserveret STA-kommando %d"
+
+#: vms-tir.c:491 vms-tir.c:514
+#, c-format
+msgid "%s: no symbol \"%s\""
+msgstr "%s: intet symbol \"%s\""
+
+#. unsigned shift
+#. rotate
+#. Redefine symbol to current location.
+#. Define a literal.
+#: vms-tir.c:581 vms-tir.c:693 vms-tir.c:803 vms-tir.c:821 vms-tir.c:829
+#: vms-tir.c:838 vms-tir.c:1563
+#, c-format
+msgid "%s: not supported"
+msgstr "%s: understøttes ikke"
+
+#: vms-tir.c:586 vms-tir.c:1418
+#, c-format
+msgid "%s: not implemented"
+msgstr "%s: ikke implementeret"
+
+#: vms-tir.c:590 vms-tir.c:1422
+#, c-format
+msgid "reserved STO cmd %d"
+msgstr "reserveret STO-kommando %d"
+
+#: vms-tir.c:708 vms-tir.c:1568
+#, c-format
+msgid "reserved OPR cmd %d"
+msgstr "reserveret OPR-kommando %d"
+
+#: vms-tir.c:776 vms-tir.c:1632
+#, c-format
+msgid "reserved CTL cmd %d"
+msgstr "reserveret CTL-kommando %d"
+
+#. stack byte from image
+#. arg: none.
+#: vms-tir.c:1148
+msgid "stack-from-image not implemented"
+msgstr "stack-from-image er ikke implementeret"
+
+#: vms-tir.c:1166
+msgid "stack-entry-mask not fully implemented"
+msgstr "stack-entry-mask er ikke helt implementeret"
+
+#. compare procedure argument
+#. arg: cs     symbol name
+#. by  argument index
+#. da  argument descriptor
+#.
+#. compare argument descriptor with symbol argument (ARG$V_PASSMECH)
+#. and stack TRUE (args match) or FALSE (args dont match) value.
+#: vms-tir.c:1180
+msgid "PASSMECH not fully implemented"
+msgstr "PASSMECH er ikke helt implementeret"
+
+#: vms-tir.c:1199
+msgid "stack-local-symbol not fully implemented"
+msgstr "stack-local-symbol er ikke helt implementeret"
+
+#: vms-tir.c:1212
+msgid "stack-literal not fully implemented"
+msgstr "stack-literal er ikke helt implementeret"
+
+#: vms-tir.c:1233
+msgid "stack-local-symbol-entry-point-mask not fully implemented"
+msgstr "stack-local-symbol-entry-point-mask er ikke helt implementeret"
+
+#: vms-tir.c:1510 vms-tir.c:1522 vms-tir.c:1534 vms-tir.c:1546 vms-tir.c:1611
+#: vms-tir.c:1619 vms-tir.c:1627
+#, c-format
+msgid "%s: not fully implemented"
+msgstr "%s: ikke helt implementeret"
+
+#: vms-tir.c:1684
+#, c-format
+msgid "obj code %d not found"
+msgstr "objektkode %d kunne ikke findes"
+
+#: vms-tir.c:2019
+#, c-format
+msgid "SEC_RELOC with no relocs in section %s"
+msgstr "SEC_RELOC uden relokaliseringer i sektion %s"
+
+#: vms-tir.c:2307
+#, c-format
+msgid "Unhandled relocation %s"
+msgstr "Uhåndteret relokalisering %s"
+
+#: xcofflink.c:1243
+#, c-format
+msgid "%s: `%s' has line numbers but no enclosing section"
+msgstr "%s: \"%s\" har linjenumre men ingen omsluttende sektion"
+
+#: xcofflink.c:1296
+#, c-format
+msgid "%s: class %d symbol `%s' has no aux entries"
+msgstr "%s: klasse %d-symbol \"%s\" har ingen ydre poster"
+
+#: xcofflink.c:1319
+#, c-format
+msgid "%s: symbol `%s' has unrecognized csect type %d"
+msgstr "%s: symbol \"%s\" har ukendt csect-type %d"
+
+#: xcofflink.c:1331
+#, c-format
+msgid "%s: bad XTY_ER symbol `%s': class %d scnum %d scnlen %d"
+msgstr "%s: fejlagtig XTY_ER-symbol \"%s\": klasse %d scnum %d scnlen %d"
+
+#: xcofflink.c:1367
+#, c-format
+msgid "%s: XMC_TC0 symbol `%s' is class %d scnlen %d"
+msgstr "%s: XMC_TC0-symbol \"%s\" er klasse %d scnlen %d"
+
+#: xcofflink.c:1519
+#, c-format
+msgid "%s: csect `%s' not in enclosing section"
+msgstr "%s: csect \"%s\" er ikke i omsluttende sektion"
+
+#: xcofflink.c:1626
+#, c-format
+msgid "%s: misplaced XTY_LD `%s'"
+msgstr "%s: fejlagtigt placeret XTY_LD \"%s\""
+
+#: xcofflink.c:1957
+#, c-format
+msgid "%s: reloc %s:%d not in csect"
+msgstr "%s: relokaliseringen %s:%d er ikke i csect"
+
+#: xcofflink.c:2092
+#, c-format
+msgid "%s: XCOFF shared object when not producing XCOFF output"
+msgstr "%s: XCOFF delt objekt når ikke XCOFF-uddata produceres"
+
+#: xcofflink.c:2113
+#, c-format
+msgid "%s: dynamic object with no .loader section"
+msgstr "%s: dynamisk objekt uden nogen .loader-sektion"
+
+#: xcofflink.c:2758
+#, c-format
+msgid "%s: no such symbol"
+msgstr "%s: intet sådant symbol"
+
+#: xcofflink.c:2891
+msgid "error: undefined symbol __rtinit"
+msgstr "fejl: udefineret symbol __rtinit"
+
+#: xcofflink.c:3453
+#, c-format
+msgid "warning: attempt to export undefined symbol `%s'"
+msgstr "advarsel: forsøg på at eksportere udefineret symbol \"%s\""
+
+#: xcofflink.c:4447
+#, c-format
+msgid "TOC overflow: 0x%lx > 0x10000; try -mminimal-toc when compiling"
+msgstr "TOC giver overløb: 0x%lx > 0x10000; prøv -mminimal-toc ved kompilering"
+
+#: xcofflink.c:5287 xcofflink.c:5756 xcofflink.c:5818 xcofflink.c:6119
+#, c-format
+msgid "%s: loader reloc in unrecognized section `%s'"
+msgstr "%s: indlæserrelokalisering i ukendt sektion \"%s\""
+
+#: xcofflink.c:5309 xcofflink.c:6130
+#, c-format
+msgid "%s: `%s' in loader reloc but not loader sym"
+msgstr "%s: \"%s\" i indlæserrelokalisering men ikke indlæsersym"
+
+#: xcofflink.c:5324
+#, c-format
+msgid "%s: loader reloc in read-only section %s"
+msgstr "%s: indlæserrelokalisering i skrivebeskyttet sektion %s"
+
+#: elf32-ia64.c:2222 elf64-ia64.c:2222
+msgid "@pltoff reloc against local symbol"
+msgstr "@pltoff-relokalisering mod lokalt symbol"
+
+#: elf32-ia64.c:3562 elf64-ia64.c:3562
+#, c-format
+msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
+msgstr "%s: kort datasegment løb over (0x%lx >= 0x400000)"
+
+#: elf32-ia64.c:3573 elf64-ia64.c:3573
+#, c-format
+msgid "%s: __gp does not cover short data segment"
+msgstr "%s: __gp dækker ikke kort datasegment"
+
+#: elf32-ia64.c:3858 elf64-ia64.c:3858
+#, c-format
+msgid "%s: linking non-pic code in a shared library"
+msgstr "%s: lænker ikke-pic-kode i delt bibliotek"
+
+#: elf32-ia64.c:3891 elf64-ia64.c:3891
+#, c-format
+msgid "%s: @gprel relocation against dynamic symbol %s"
+msgstr "%s: @gprel-relokalisering mod dynamisk symbol %s"
+
+#: elf32-ia64.c:4030 elf64-ia64.c:4030
+#, c-format
+msgid "%s: dynamic relocation against speculation fixup"
+msgstr "%s: dynamisk relokalisering uden spekulationsrettelser"
+
+#: elf32-ia64.c:4038 elf64-ia64.c:4038
+#, c-format
+msgid "%s: speculation fixup against undefined weak symbol"
+msgstr "%s: spekulationsfix mod udefineret svagt symbol"
+
+#: elf32-ia64.c:4271 elf64-ia64.c:4271
+msgid "unsupported reloc"
+msgstr "relokaliseringen understøttes ikke"
+
+#: elf32-ia64.c:4551 elf64-ia64.c:4551
+#, c-format
+msgid "%s: linking trap-on-NULL-dereference with non-trapping files"
+msgstr "%s: lænker fang-ved-NULL-dereference med ikkefangende filer"
+
+#: elf32-ia64.c:4560 elf64-ia64.c:4560
+#, c-format
+msgid "%s: linking big-endian files with little-endian files"
+msgstr "%s: lænker big endian-filer med little endian-filer"
+
+#: elf32-ia64.c:4569 elf64-ia64.c:4569
+#, c-format
+msgid "%s: linking 64-bit files with 32-bit files"
+msgstr "%s: lænker 64-bitfiler med 32-bitfiler"
+
+#: elf32-ia64.c:4578 elf64-ia64.c:4578
+#, c-format
+msgid "%s: linking constant-gp files with non-constant-gp files"
+msgstr "%s: lænker konstant-gp-filer med ikke-konstant-gp-filer"
+
+#: elf32-ia64.c:4588 elf64-ia64.c:4588
+#, c-format
+msgid "%s: linking auto-pic files with non-auto-pic files"
+msgstr "%s: lænker auto-pic-filer med ikke-auto-pic-filer"
+
+#: peigen.c:962 pepigen.c:962
+#, c-format
+msgid "%s: line number overflow: 0x%lx > 0xffff"
+msgstr "%s: linjenummer giver overløb: 0x%lx > 0xffff"
+
+#: peigen.c:979 pepigen.c:979
+#, c-format
+msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
+msgstr "%s: relokalisering giver overløb 1: 0x%lx > 0xffff"
+
+#: peigen.c:993 pepigen.c:993
+msgid "Export Directory [.edata (or where ever we found it)]"
+msgstr "Exportkatalog [.edata (eller hvor vi fandt det)]"
+
+#: peigen.c:994 pepigen.c:994
+msgid "Import Directory [parts of .idata]"
+msgstr "Importkatalog [dele af .idata]"
+
+#: peigen.c:995 pepigen.c:995
+msgid "Resource Directory [.rsrc]"
+msgstr "Resursekatalog [.rsrc]"
+
+#: peigen.c:996 pepigen.c:996
+msgid "Exception Directory [.pdata]"
+msgstr "Undtagelseskatalog [.pdata]"
+
+#: peigen.c:997 pepigen.c:997
+msgid "Security Directory"
+msgstr "Sikkerhedskatalog"
+
+#: peigen.c:998 pepigen.c:998
+msgid "Base Relocation Directory [.reloc]"
+msgstr "Baserelokaliseringskatalog [.reloc]"
+
+#: peigen.c:999 pepigen.c:999
+msgid "Debug Directory"
+msgstr "Fejlsøgningskatalog"
+
+#: peigen.c:1000 pepigen.c:1000
+msgid "Description Directory"
+msgstr "Beskrivelseskatalog"
+
+#: peigen.c:1001 pepigen.c:1001
+msgid "Special Directory"
+msgstr "Specialkatalog"
+
+#: peigen.c:1002 pepigen.c:1002
+msgid "Thread Storage Directory [.tls]"
+msgstr "Trådlagringskatalog [.tls]"
+
+#: peigen.c:1003 pepigen.c:1003
+msgid "Load Configuration Directory"
+msgstr "Indlæsningskonfigurationskatalog"
+
+#: peigen.c:1004 pepigen.c:1004
+msgid "Bound Import Directory"
+msgstr "Katalog over bundne importer"
+
+#: peigen.c:1005 pepigen.c:1005
+msgid "Import Address Table Directory"
+msgstr "Importadressetabelkatalog"
+
+#: peigen.c:1006 pepigen.c:1006
+msgid "Delay Import Directory"
+msgstr "Katalog over forskinkede importer"
+
+#: peigen.c:1007 peigen.c:1008 pepigen.c:1007 pepigen.c:1008
+msgid "Reserved"
+msgstr "Reserveret"
+
+#: peigen.c:1071 pepigen.c:1071
+msgid ""
+"\n"
+"There is an import table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en importtabel, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1076 pepigen.c:1076
+#, c-format
+msgid ""
+"\n"
+"There is an import table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Der findes en importtabel i %s på 0x%lx\n"
+
+#: peigen.c:1113 pepigen.c:1113
+#, c-format
+msgid ""
+"\n"
+"Function descriptor located at the start address: %04lx\n"
+msgstr ""
+"\n"
+"Funktionsidentifikatorer fundet på startadressen: %04lx\n"
+
+#: peigen.c:1116 pepigen.c:1116
+#, c-format
+msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
+msgstr "\tkodebase %08lx toc (indlæsningsbar/reelt) %08lx/%08lx\n"
+
+#: peigen.c:1122 pepigen.c:1122
+msgid ""
+"\n"
+"No reldata section! Function descriptor not decoded.\n"
+msgstr ""
+"\n"
+"Ingen reldata-sektion! Funktionsidentifikatorer afkodedes ikke.\n"
+
+#: peigen.c:1127 pepigen.c:1127
+#, c-format
+msgid ""
+"\n"
+"The Import Tables (interpreted %s section contents)\n"
+msgstr ""
+"\n"
+"Importtabellerne (tolket indhold i %s-sektion)\n"
+
+# Vad er thunk?
+#: peigen.c:1130 pepigen.c:1130
+msgid ""
+" vma:            Hint    Time      Forward  DLL       First\n"
+"                 Table   Stamp     Chain    Name      Thunk\n"
+msgstr ""
+" vma:            Tips-   Tids-     Fremad-  DLL-      Første\n"
+"                 tabel   stempel   kæde     navn      thunk\n"
+
+#: peigen.c:1181 pepigen.c:1181
+#, c-format
+msgid ""
+"\n"
+"\tDLL Name: %s\n"
+msgstr ""
+"\n"
+"\tDLL-navn: %s\n"
+
+#: peigen.c:1192 pepigen.c:1192
+msgid "\tvma:  Hint/Ord Member-Name Bound-To\n"
+msgstr "\tvma: Tips/Ordn Medlemsnavn Bundet till\n"
+
+#: peigen.c:1217 pepigen.c:1217
+msgid ""
+"\n"
+"There is a first thunk, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en første thunk, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1357 pepigen.c:1357
+msgid ""
+"\n"
+"There is an export table, but the section containing it could not be found\n"
+msgstr ""
+"\n"
+"Der findes en eksporttabel, men sektionen som indeholder den kunne ikke findes\n"
+
+#: peigen.c:1362 pepigen.c:1362
+#, c-format
+msgid ""
+"\n"
+"There is an export table in %s at 0x%lx\n"
+msgstr ""
+"\n"
+"Det findes en eksporttabel i %s ved 0x%lx\n"
+
+#: peigen.c:1393 pepigen.c:1393
+#, c-format
+msgid ""
+"\n"
+"The Export Tables (interpreted %s section contents)\n"
+"\n"
+msgstr ""
+"\n"
+"Eksporttabellerne (tolket indhold i %s-sektion)\n"
+
+#: peigen.c:1397 pepigen.c:1397
+#, c-format
+msgid "Export Flags \t\t\t%lx\n"
+msgstr "Eksportflag \t\t\t%lx\n"
+
+#: peigen.c:1400 pepigen.c:1400
+#, c-format
+msgid "Time/Date stamp \t\t%lx\n"
+msgstr "Tids/datostempel \t\t%lx\n"
+
+#: peigen.c:1403 pepigen.c:1403
+#, c-format
+msgid "Major/Minor \t\t\t%d/%d\n"
+msgstr "Større/mindre \t\t\t%d/%d\n"
+
+#: peigen.c:1406 pepigen.c:1406
+msgid "Name \t\t\t\t"
+msgstr "Navn \t\t\t\t"
+
+#: peigen.c:1412 pepigen.c:1412
+#, c-format
+msgid "Ordinal Base \t\t\t%ld\n"
+msgstr "Ordningsbase \t\t\t%ld\n"
+
+#: peigen.c:1415 pepigen.c:1415
+msgid "Number in:\n"
+msgstr "Tal i:\n"
+
+#: peigen.c:1418 pepigen.c:1418
+#, c-format
+msgid "\tExport Address Table \t\t%08lx\n"
+msgstr "\tEksportadressetabel \t\t%08lx\n"
+
+#: peigen.c:1422 pepigen.c:1422
+#, c-format
+msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
+msgstr "\t[Navnepeger/Ordningstal]-tabel\t%08lx\n"
+
+#: peigen.c:1425 pepigen.c:1425
+msgid "Table Addresses\n"
+msgstr "Tabeladresser\n"
+
+#: peigen.c:1428 pepigen.c:1428
+msgid "\tExport Address Table \t\t"
+msgstr "\tEksportadressetabel \t\t"
+
+#: peigen.c:1433 pepigen.c:1433
+msgid "\tName Pointer Table \t\t"
+msgstr "\tNavnepegertabel \t\t"
+
+#: peigen.c:1438 pepigen.c:1438
+msgid "\tOrdinal Table \t\t\t"
+msgstr "\tOrdningstalstabel \t\t\t"
+
+#: peigen.c:1453 pepigen.c:1453
+#, c-format
+msgid ""
+"\n"
+"Export Address Table -- Ordinal Base %ld\n"
+msgstr ""
+"\n"
+"Eksportadressetabel -- Ordningsbase %ld\n"
+
+#: peigen.c:1472 pepigen.c:1472
+msgid "Forwarder RVA"
+msgstr "Videresender-RVA"
+
+#: peigen.c:1483 pepigen.c:1483
+msgid "Export RVA"
+msgstr "Eksport-RVA"
+
+#: peigen.c:1490 pepigen.c:1490
+msgid ""
+"\n"
+"[Ordinal/Name Pointer] Table\n"
+msgstr ""
+"\n"
+"[Ordningstals-/Navnepeger-]tabel\n"
+
+#: peigen.c:1545 pepigen.c:1545
+#, c-format
+msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
+msgstr "Advarsel, størrelsen på .pdata-sektionen (%ld) er ikke en multipel af %d\n"
+
+#: peigen.c:1549 pepigen.c:1549
+msgid ""
+"\n"
+"The Function Table (interpreted .pdata section contents)\n"
+msgstr ""
+"\n"
+"Funktionstabellen (tolket indhold fra .pdata-sektionen)\n"
+
+#: peigen.c:1552 pepigen.c:1552
+msgid " vma:\t\t\tBegin Address    End Address      Unwind Info\n"
+msgstr " vma:\t\t\tStartadresse      Slutadresse       Tilbagespolings-information\n"
+
+#: peigen.c:1554 pepigen.c:1554
+msgid ""
+" vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n"
+"     \t\tAddress  Address  Handler  Data     Address    Mask\n"
+msgstr ""
+" vma:\t\tStart-    Slut-     EH-        EH-    Prologsluts-  Undtagelses-\n"
+"     \t\tadresse   adresse   håndterere data   adresse       maske\n"
+
+#: peigen.c:1624 pepigen.c:1624
+msgid " Register save millicode"
+msgstr " Registergemnings millikode"
+
+#: peigen.c:1627 pepigen.c:1627
+msgid " Register restore millicode"
+msgstr " Registergenskabnings millikode"
+
+#: peigen.c:1630 pepigen.c:1630
+msgid " Glue code sequence"
+msgstr " Klisterkodesekvens"
+
+#: peigen.c:1682 pepigen.c:1682
+msgid ""
+"\n"
+"\n"
+"PE File Base Relocations (interpreted .reloc section contents)\n"
+msgstr ""
+"\n"
+"\n"
+"PE-filbaserelokaliseringer (tolket indhold i .reloc-sektionen)\n"
+
+#: peigen.c:1712 pepigen.c:1712
+#, c-format
+msgid ""
+"\n"
+"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
+msgstr ""
+"\n"
+"Virtuel adresse: %08lx Områdesstørrelse %ld (0x%lx) Antal rettelser %ld\n"
+
+#: peigen.c:1725 pepigen.c:1725
+#, c-format
+msgid "\treloc %4d offset %4x [%4lx] %s"
+msgstr "\trelokalisering %4d afstand %4x [%4lx] %s"
+
+#. The MS dumpbin program reportedly ands with 0xff0f before
+#. printing the characteristics field.  Not sure why.  No reason to
+#. emulate it here.
+#: peigen.c:1765 pepigen.c:1765
+#, c-format
+msgid ""
+"\n"
+"Characteristics 0x%x\n"
+msgstr ""
+"\n"
+"Karakteristik 0x%x\n"
diff --git a/gdb/charset.c b/gdb/charset.c
new file mode 100644 (file)
index 0000000..00e1065
--- /dev/null
@@ -0,0 +1,1274 @@
+/* Character set conversion support for GDB.
+   Copyright 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "charset.h"
+#include "gdbcmd.h"
+#include "gdb_assert.h"
+
+#include <stddef.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
+
+\f
+/* How GDB's character set support works
+
+   GDB has two global settings:
+
+   - The `current host character set' is the character set GDB should
+     use in talking to the user, and which (hopefully) the user's
+     terminal knows how to display properly.
+
+   - The `current target character set' is the character set the
+     program being debugged uses.
+
+   There are commands to set each of these, and mechanisms for
+   choosing reasonable default values.  GDB has a global list of
+   character sets that it can use as its host or target character
+   sets.
+
+   The header file `charset.h' declares various functions that
+   different pieces of GDB need to perform tasks like:
+
+   - printing target strings and characters to the user's terminal
+     (mostly target->host conversions),
+
+   - building target-appropriate representations of strings and
+     characters the user enters in expressions (mostly host->target
+     conversions),
+
+   and so on.
+
+   Now, many of these operations are specific to a particular
+   host/target character set pair.  If GDB supports N character sets,
+   there are N^2 possible pairs.  This means that, the larger GDB's
+   repertoire of character sets gets, the more expensive it gets to add
+   new character sets.
+
+   To make sure that GDB can do the right thing for every possible
+   pairing of host and target character set, while still allowing
+   GDB's repertoire to scale, we use a two-tiered approach:
+
+   - We maintain a global table of "translations" --- groups of
+     functions specific to a particular pair of character sets.
+
+   - However, a translation can be incomplete: some functions can be
+     omitted.  Where there is not a translation to specify exactly
+     what function to use, we provide reasonable defaults.  The
+     default behaviors try to use the "iconv" library functions, which
+     support a wide range of character sets.  However, even if iconv
+     is not available, there are fallbacks to support trivial
+     translations: when the host and target character sets are the
+     same.  */
+
+\f
+/* The character set and translation structures.  */
+
+
+/* A character set GDB knows about.  GDB only supports character sets
+   with stateless encodings, in which every character is one byte
+   long.  */
+struct charset {
+
+  /* A singly-linked list of all known charsets.  */
+  struct charset *next;
+
+  /* The name of the character set.  Comparisons on character set
+     names are case-insensitive.  */
+  const char *name;
+
+  /* Non-zero iff this character set can be used as a host character
+     set.  At present, GDB basically assumes that the host character
+     set is a superset of ASCII.  */
+  int valid_host_charset;
+
+  /* Pointers to charset-specific functions that depend only on a
+     single character set, and data pointers to pass to them.  */
+  int (*host_char_print_literally) (void *baton,
+                                    int host_char);
+  void *host_char_print_literally_baton;
+
+  int (*target_char_to_control_char) (void *baton,
+                                      int target_char,
+                                      int *target_ctrl_char);
+  void *target_char_to_control_char_baton;
+};
+
+
+/* A translation from one character set to another.  */
+struct translation {
+
+  /* A singly-linked list of all known translations.  */
+  struct translation *next;
+
+  /* This structure describes functions going from the FROM character
+     set to the TO character set.  Comparisons on character set names
+     are case-insensitive.  */
+  const char *from, *to;
+
+  /* Pointers to translation-specific functions, and data pointers to
+     pass to them.  These pointers can be zero, indicating that GDB
+     should fall back on the default behavior.  We hope the default
+     behavior will be correct for many from/to pairs, reducing the
+     number of translations that need to be registered explicitly.  */
+  
+  /* TARGET_CHAR is in the `from' charset.
+     Returns a string in the `to' charset.  */
+  const char *(*c_target_char_has_backslash_escape) (void *baton,
+                                                     int target_char);
+  void *c_target_char_has_backslash_escape_baton;
+
+  /* HOST_CHAR is in the `from' charset.
+     TARGET_CHAR points to a char in the `to' charset.  */
+  int (*c_parse_backslash) (void *baton, int host_char, int *target_char);
+  void *c_parse_backslash_baton;
+
+  /* This is used for the host_char_to_target and target_char_to_host
+     functions.  */
+  int (*convert_char) (void *baton, int from, int *to);
+  void *convert_char_baton;
+};
+
+
+\f
+/* The global lists of character sets and translations.  */
+
+
+/* Character set names are always compared ignoring case.  */
+static int
+strcmp_case_insensitive (const char *p, const char *q)
+{
+  while (*p && *q && tolower (*p) == tolower (*q))
+    p++, q++;
+
+  return tolower (*p) - tolower (*q);
+}
+
+
+/* The global list of all the charsets GDB knows about.  */
+static struct charset *all_charsets;
+
+
+static void
+register_charset (struct charset *cs)
+{
+  struct charset **ptr;
+
+  /* Put the new charset on the end, so that the list ends up in the
+     same order as the registrations in the _initialize function.  */
+  for (ptr = &all_charsets; *ptr; ptr = &(*ptr)->next)
+    ;
+
+  cs->next = 0;
+  *ptr = cs;
+}
+
+
+static struct charset *
+lookup_charset (const char *name)
+{
+  struct charset *cs;
+
+  for (cs = all_charsets; cs; cs = cs->next)
+    if (! strcmp_case_insensitive (name, cs->name))
+      return cs;
+
+  return NULL;
+}
+
+
+/* The global list of translations.  */
+static struct translation *all_translations;
+
+
+static void
+register_translation (struct translation *t)
+{
+  t->next = all_translations;
+  all_translations = t;
+}
+
+
+static struct translation *
+lookup_translation (const char *from, const char *to)
+{
+  struct translation *t;
+
+  for (t = all_translations; t; t = t->next)
+    if (! strcmp_case_insensitive (from, t->from)
+        && ! strcmp_case_insensitive (to, t->to))
+      return t;
+
+  return 0;
+}
+
+
+\f
+/* Constructing charsets.  */
+
+/* Allocate, initialize and return a straightforward charset.
+   Use this function, rather than creating the structures yourself,
+   so that we can add new fields to the structure in the future without
+   having to tweak all the old charset descriptions.  */
+static struct charset *
+simple_charset (const char *name,
+                int valid_host_charset,
+                int (*host_char_print_literally) (void *baton, int host_char),
+                void *host_char_print_literally_baton,
+                int (*target_char_to_control_char) (void *baton,
+                                                    int target_char,
+                                                    int *target_ctrl_char),
+                void *target_char_to_control_char_baton)
+{
+  struct charset *cs = xmalloc (sizeof (*cs));
+
+  memset (cs, 0, sizeof (*cs));
+  cs->name = name;
+  cs->valid_host_charset = valid_host_charset;
+  cs->host_char_print_literally = host_char_print_literally;
+  cs->host_char_print_literally_baton = host_char_print_literally_baton;
+  cs->target_char_to_control_char = target_char_to_control_char;
+  cs->target_char_to_control_char_baton = target_char_to_control_char_baton;
+
+  return cs;
+}
+
+
+\f
+/* ASCII functions.  */
+
+static int
+ascii_print_literally (void *baton, int c)
+{
+  c &= 0xff;
+
+  return (0x20 <= c && c <= 0x7e);
+}
+
+
+static int
+ascii_to_control (void *baton, int c, int *ctrl_char)
+{
+  *ctrl_char = (c & 037);
+  return 1;
+}
+
+\f
+/* ISO-8859 family functions.  */
+
+
+static int
+iso_8859_print_literally (void *baton, int c)
+{
+  c &= 0xff;
+
+  return ((0x20 <= c && c <= 0x7e) /* ascii printables */
+          || (! sevenbit_strings && 0xA0 <= c)); /* iso 8859 printables */
+}
+
+
+static int
+iso_8859_to_control (void *baton, int c, int *ctrl_char)
+{
+  *ctrl_char = (c & 0200) | (c & 037);
+  return 1;
+}
+
+
+/* Construct an ISO-8859-like character set.  */
+static struct charset *
+iso_8859_family_charset (const char *name)
+{
+  return simple_charset (name, 1,
+                         iso_8859_print_literally, 0,
+                         iso_8859_to_control, 0);
+}
+
+
+\f
+/* EBCDIC family functions.  */
+
+
+static int
+ebcdic_print_literally (void *baton, int c)
+{
+  c &= 0xff;
+
+  return (64 <= c && c <= 254);
+}
+
+
+static int
+ebcdic_to_control (void *baton, int c, int *ctrl_char)
+{
+  /* There are no control character equivalents in EBCDIC.  Use
+     numeric escapes.  */
+  return 0;
+}
+
+
+/* Construct an EBCDIC-like character set.  */
+static struct charset *
+ebcdic_family_charset (const char *name)
+{
+  return simple_charset (name, 0,
+                         ebcdic_print_literally, 0,
+                         ebcdic_to_control, 0);
+}
+                
+
+
+
+\f
+/* Fallback functions using iconv.  */
+
+#if defined(HAVE_ICONV)
+
+struct cached_iconv {
+  struct charset *from, *to;
+  iconv_t i;
+};
+
+
+/* Make sure the iconv cache *CI contains an iconv descriptor
+   translating from FROM to TO.  If it already does, fine; otherwise,
+   close any existing descriptor, and open up a new one.  On success,
+   return zero; on failure, return -1 and set errno.  */
+static int
+check_iconv_cache (struct cached_iconv *ci,
+                   struct charset *from,
+                   struct charset *to)
+{
+  iconv_t i;
+
+  /* Does the cached iconv descriptor match the conversion we're trying
+     to do now?  */
+  if (ci->from == from
+      && ci->to == to
+      && ci->i != (iconv_t) 0)
+    return 0;
+
+  /* It doesn't.  If we actually had any iconv descriptor open at
+     all, close it now.  */
+  if (ci->i != (iconv_t) 0)
+    {
+      i = ci->i;
+      ci->i = (iconv_t) 0;
+      
+      if (iconv_close (i) == -1)
+        error ("Error closing `iconv' descriptor for "
+               "`%s'-to-`%s' character conversion: %s",
+               ci->from->name, ci->to->name, safe_strerror (errno));
+    }
+
+  /* Open a new iconv descriptor for the required conversion.  */
+  i = iconv_open (to->name, from->name);
+  if (i == (iconv_t) -1)
+    return -1;
+
+  ci->i = i;
+  ci->from = from;
+  ci->to = to;
+
+  return 0;
+}
+
+
+/* Convert FROM_CHAR using the cached iconv conversion *CI.  Return
+   non-zero if the conversion was successful, zero otherwise.  */
+static int
+cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
+{
+  char from;
+  ICONV_CONST char *from_ptr = &from;
+  char to, *to_ptr = &to;
+  size_t from_left = sizeof (from), to_left = sizeof (to);
+
+  gdb_assert (ci->i != (iconv_t) 0);
+
+  from = from_char;
+  if (iconv (ci->i, &from_ptr, &from_left, &to_ptr, &to_left)
+      == (size_t) -1)
+    {
+      /* These all suggest that the input or output character sets
+         have multi-byte encodings of some characters, which means
+         it's unsuitable for use as a GDB character set.  We should
+         never have selected it.  */
+      gdb_assert (errno != E2BIG && errno != EINVAL);
+
+      /* This suggests a bug in the code managing *CI.  */
+      gdb_assert (errno != EBADF);
+
+      /* This seems to mean that there is no equivalent character in
+         the `to' character set.  */
+      if (errno == EILSEQ)
+        return 0;
+
+      /* Anything else is mysterious.  */
+      internal_error ("Error converting character `%d' from `%s' to `%s' "
+                      "character set: %s",
+                      from_char, ci->from->name, ci->to->name,
+                      safe_strerror (errno));
+    }
+
+  /* If the pointers weren't advanced across the input, that also
+     suggests something was wrong.  */
+  gdb_assert (from_left == 0 && to_left == 0);
+
+  *to_char = (unsigned char) to;
+  return 1;
+}
+
+
+static void
+register_iconv_charsets ()
+{
+  /* Here we should check whether various character sets were
+     recognized by the local iconv implementation.
+
+     The first implementation registered a bunch of character sets
+     recognized by iconv, but then we discovered that iconv on Solaris
+     and iconv on GNU/Linux had no character sets in common.  So we
+     replaced them with the hard-coded tables that appear later in the
+     file.  */
+}
+
+#endif /* defined (HAVE_ICONV) */
+
+\f
+/* Fallback routines for systems without iconv.  */
+
+#if ! defined (HAVE_ICONV) 
+struct cached_iconv { char nothing; };
+
+static int
+check_iconv_cache (struct cached_iconv *ci,
+                   struct charset *from,
+                   struct charset *to)
+{
+  errno = EINVAL;
+  return -1;
+}
+
+static int
+cached_iconv_convert (struct cached_iconv *ci, int from_char, int *to_char)
+{
+  /* This function should never be called.  */
+  gdb_assert (0);
+}
+
+static void
+register_iconv_charsets ()
+{
+}
+
+#endif /* ! defined(HAVE_ICONV) */
+
+\f
+/* Default trivial conversion functions.  */
+
+static int
+identity_either_char_to_other (void *baton, int either_char, int *other_char)
+{
+  *other_char = either_char;
+  return 1;
+}
+
+
+\f
+/* Default non-trivial conversion functions.  */
+
+
+static char backslashable[] = "abefnrtv";
+static char *backslashed[] = {"a", "b", "e", "f", "n", "r", "t", "v", "0"};
+static char represented[] = "\a\b\e\f\n\r\t\v";
+
+
+/* Translate TARGET_CHAR into the host character set, and see if it
+   matches any of our standard escape sequences.  */
+static const char *
+default_c_target_char_has_backslash_escape (void *baton, int target_char)
+{
+  int host_char;
+  const char *ix;
+
+  /* If target_char has no equivalent in the host character set,
+     assume it doesn't have a backslashed form.  */
+  if (! target_char_to_host (target_char, &host_char))
+    return NULL;
+
+  ix = strchr (represented, host_char);
+  if (ix)
+    return backslashed[ix - represented];
+  else
+    return NULL;
+}
+
+
+/* Translate the backslash the way we would in the host character set,
+   and then try to translate that into the target character set.  */
+static int
+default_c_parse_backslash (void *baton, int host_char, int *target_char)
+{
+  const char *ix;
+
+  ix = strchr (backslashable, host_char);
+
+  if (! ix)
+    return 0;
+  else
+    return host_char_to_target (represented[ix - backslashable],
+                                target_char);
+}
+
+
+/* Convert using a cached iconv descriptor.  */
+static int
+iconv_convert (void *baton, int from_char, int *to_char)
+{
+  struct cached_iconv *ci = baton;
+  return cached_iconv_convert (ci, from_char, to_char);
+}
+
+
+\f
+/* Conversion tables.  */
+
+
+/* I'd much rather fall back on iconv whenever possible.  But the
+   character set names you use with iconv aren't standardized at all,
+   a lot of platforms have really meager character set coverage, etc.
+   I wanted to have at least something we could use to exercise the
+   test suite on all platforms.
+
+   In the long run, we should have a configure-time process explore
+   somehow which character sets the host platform supports, and some
+   arrangement that allows GDB users to use platform-indepedent names
+   for character sets.  */
+
+
+/* We generated these tables using iconv on a GNU/Linux machine.  */
+
+
+static int ascii_to_iso_8859_1_table[] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
+   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
+   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
+   96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
+  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int ascii_to_ebcdic_us_table[] = {
+    0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
+   64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
+  240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
+  124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
+  215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
+  121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
+  151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int ascii_to_ibm1047_table[] = {
+    0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
+   64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
+  240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
+  124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
+  215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
+  121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
+  151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int iso_8859_1_to_ascii_table[] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
+   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 80 */
+   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 96 */
+   96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 112 */
+  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 128 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int iso_8859_1_to_ebcdic_us_table[] = {
+    0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
+   64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
+  240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
+  124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
+  215,216,217,226,227,228,229,230,231,232,233, -1,224, -1, -1,109, /* 96 */
+  121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
+  151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
+   32, 33, 34, 35, 36, 21,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27, /* 144 */
+   48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255, /* 160 */
+   -1, -1, 74, -1, -1, -1,106, -1, -1, -1, -1, -1, 95, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 208 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 224 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 240 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int iso_8859_1_to_ibm1047_table[] = {
+    0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 37, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, /* 32 */
+   64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97, /* 48 */
+  240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111, /* 64 */
+  124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214, /* 80 */
+  215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109, /* 96 */
+  121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150, /* 112 */
+  151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7, /* 128 */
+   32, 33, 34, 35, 36, 21,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27, /* 144 */
+   48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255, /* 160 */
+   65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188, /* 176 */
+  144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171, /* 192 */
+  100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119, /* 208 */
+  172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89, /* 224 */
+   68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87, /* 240 */
+  140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223  /* 256 */
+};
+
+
+static int ebcdic_us_to_ascii_table[] = {
+    0,  1,  2,  3, -1,  9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, -1, -1,  8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
+   -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1,  5,  6,  7, /* 48 */
+   -1, -1, 22, -1, -1, -1, -1,  4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
+   32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
+   38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, -1, /* 96 */
+   45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
+   -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+  123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
+  125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
+   92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int ebcdic_us_to_iso_8859_1_table[] = {
+    0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19,157,133,  8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
+  128,129,130,131,132, 10, 23, 27,136,137,138,139,140,  5,  6,  7, /* 48 */
+  144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26, /* 64 */
+   32, -1, -1, -1, -1, -1, -1, -1, -1, -1,162, 46, 60, 40, 43,124, /* 80 */
+   38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59,172, /* 96 */
+   45, 47, -1, -1, -1, -1, -1, -1, -1, -1,166, 44, 37, 95, 62, 63, /* 112 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
+   -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+  123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
+  125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
+   92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,159  /* 256 */
+};
+
+
+static int ebcdic_us_to_ibm1047_table[] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
+   64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
+   80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94,176, /* 96 */
+   96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
+   -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+  192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
+  208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
+  224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
+  240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255  /* 256 */
+};
+
+
+static int ibm1047_to_ascii_table[] = {
+    0,  1,  2,  3, -1,  9, -1,127, -1, -1, -1, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, -1, -1,  8, -1, 24, 25, -1, -1, 28, 29, 30, 31, /* 32 */
+   -1, -1, -1, -1, -1, 10, 23, 27, -1, -1, -1, -1, -1,  5,  6,  7, /* 48 */
+   -1, -1, 22, -1, -1, -1, -1,  4, -1, -1, -1, -1, 20, 21, -1, 26, /* 64 */
+   32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 46, 60, 40, 43,124, /* 80 */
+   38, -1, -1, -1, -1, -1, -1, -1, -1, -1, 33, 36, 42, 41, 59, 94, /* 96 */
+   45, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 44, 37, 95, 62, 63, /* 112 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, 96, 58, 35, 64, 39, 61, 34, /* 128 */
+   -1, 97, 98, 99,100,101,102,103,104,105, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1,106,107,108,109,110,111,112,113,114, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1,126,115,116,117,118,119,120,121,122, -1, -1, -1, 91, -1, -1, /* 176 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, /* 192 */
+  123, 65, 66, 67, 68, 69, 70, 71, 72, 73, -1, -1, -1, -1, -1, -1, /* 208 */
+  125, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, -1, -1, -1, -1, /* 224 */
+   92, -1, 83, 84, 85, 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, -1, /* 240 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1  /* 256 */
+};
+
+
+static int ibm1047_to_iso_8859_1_table[] = {
+    0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19,157,133,  8,135, 24, 25,146,143, 28, 29, 30, 31, /* 32 */
+  128,129,130,131,132, 10, 23, 27,136,137,138,139,140,  5,  6,  7, /* 48 */
+  144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26, /* 64 */
+   32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124, /* 80 */
+   38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94, /* 96 */
+   45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63, /* 112 */
+  248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34, /* 128 */
+  216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177, /* 144 */
+  176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164, /* 160 */
+  181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174, /* 176 */
+  172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215, /* 192 */
+  123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245, /* 208 */
+  125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255, /* 224 */
+   92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213, /* 240 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159  /* 256 */
+};
+
+
+static int ibm1047_to_ebcdic_us_table[] = {
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 16 */
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 32 */
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 48 */
+   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 64 */
+   64, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74, 75, 76, 77, 78, 79, /* 80 */
+   80, -1, -1, -1, -1, -1, -1, -1, -1, -1, 90, 91, 92, 93, 94, -1, /* 96 */
+   96, 97, -1, -1, -1, -1, -1, -1, -1, -1,106,107,108,109,110,111, /* 112 */
+   -1, -1, -1, -1, -1, -1, -1, -1, -1,121,122,123,124,125,126,127, /* 128 */
+   -1,129,130,131,132,133,134,135,136,137, -1, -1, -1, -1, -1, -1, /* 144 */
+   -1,145,146,147,148,149,150,151,152,153, -1, -1, -1, -1, -1, -1, /* 160 */
+   -1,161,162,163,164,165,166,167,168,169, -1, -1, -1, -1, -1, -1, /* 176 */
+   95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 192 */
+  192,193,194,195,196,197,198,199,200,201, -1, -1, -1, -1, -1, -1, /* 208 */
+  208,209,210,211,212,213,214,215,216,217, -1, -1, -1, -1, -1, -1, /* 224 */
+  224, -1,226,227,228,229,230,231,232,233, -1, -1, -1, -1, -1, -1, /* 240 */
+  240,241,242,243,244,245,246,247,248,249, -1, -1, -1, -1, -1,255  /* 256 */
+};
+
+
+static int
+table_convert_char (void *baton, int from, int *to)
+{
+  int *table = (int *) baton;
+
+  if (0 <= from && from <= 255
+      && table[from] != -1)
+    {
+      *to = table[from];
+      return 1;
+    }
+  else
+    return 0;
+}
+
+
+static struct translation *
+table_translation (const char *from, const char *to, int *table,
+                   const char *(*c_target_char_has_backslash_escape)
+                   (void *baton, int target_char),
+                   void *c_target_char_has_backslash_escape_baton,
+                   int (*c_parse_backslash) (void *baton,
+                                             int host_char,
+                                             int *target_char),
+                   void *c_parse_backslash_baton)
+{
+  struct translation *t = xmalloc (sizeof (*t));
+
+  memset (t, 0, sizeof (*t));
+  t->from = from;
+  t->to = to;
+  t->c_target_char_has_backslash_escape = c_target_char_has_backslash_escape;
+  t->c_target_char_has_backslash_escape_baton
+    = c_target_char_has_backslash_escape_baton;
+  t->c_parse_backslash = c_parse_backslash;
+  t->c_parse_backslash_baton = c_parse_backslash_baton;
+  t->convert_char = table_convert_char;
+  t->convert_char_baton = (void *) table;
+
+  return t;
+}
+
+
+static struct translation *
+simple_table_translation (const char *from, const char *to, int *table)
+{
+  return table_translation (from, to, table, 0, 0, 0, 0);
+}
+
+
+\f
+/* Setting and retrieving the host and target charsets.  */
+
+
+/* The current host and target character sets.  */
+static struct charset *current_host_charset, *current_target_charset;
+
+/* The current functions and batons we should use for the functions in
+   charset.h.  */
+
+static const char *(*c_target_char_has_backslash_escape_func)
+     (void *baton, int target_char);
+static void *c_target_char_has_backslash_escape_baton;
+
+static int (*c_parse_backslash_func) (void *baton,
+                                      int host_char,
+                                      int *target_char);
+static void *c_parse_backslash_baton;
+
+static int (*host_char_to_target_func) (void *baton,
+                                        int host_char,
+                                        int *target_char);
+static void *host_char_to_target_baton;
+
+static int (*target_char_to_host_func) (void *baton,
+                                        int target_char,
+                                        int *host_char);
+static void *target_char_to_host_baton;
+
+
+/* Cached iconv conversions, that might be useful to fallback
+   routines.  */
+static struct cached_iconv cached_iconv_host_to_target;
+static struct cached_iconv cached_iconv_target_to_host;
+
+
+/* Set the host and target character sets to HOST and TARGET.  */
+static void
+set_host_and_target_charsets (struct charset *host, struct charset *target)
+{
+  struct translation *h2t, *t2h;
+
+  /* If they're not both initialized yet, then just do nothing for
+     now.  As soon as we're done running our initialize function,
+     everything will be initialized.  */
+  if (! host || ! target)
+    {
+      current_host_charset = host;
+      current_target_charset = target;
+      return;
+    }
+
+  h2t = lookup_translation (host->name, target->name);
+  t2h = lookup_translation (target->name, host->name);
+
+  /* If the translations don't provide conversion functions, make sure
+     iconv can back them up.  Do this *before* modifying any state.  */
+  if (host != target)
+    {
+      if (! h2t || ! h2t->convert_char)
+        {
+          if (check_iconv_cache (&cached_iconv_host_to_target, host, target)
+              < 0)
+            error ("GDB can't convert from the `%s' character set to `%s'.",
+                   host->name, target->name);
+        }
+      if (! t2h || ! t2h->convert_char)
+        {
+          if (check_iconv_cache (&cached_iconv_target_to_host, target, host)
+              < 0)
+            error ("GDB can't convert from the `%s' character set to `%s'.",
+                   target->name, host->name);
+        }
+    }
+
+  if (t2h && t2h->c_target_char_has_backslash_escape)
+    {
+      c_target_char_has_backslash_escape_func
+        = t2h->c_target_char_has_backslash_escape;
+      c_target_char_has_backslash_escape_baton
+        = t2h->c_target_char_has_backslash_escape_baton;
+    }
+  else
+    c_target_char_has_backslash_escape_func
+      = default_c_target_char_has_backslash_escape;
+
+  if (h2t && h2t->c_parse_backslash)
+    {
+      c_parse_backslash_func = h2t->c_parse_backslash;
+      c_parse_backslash_baton = h2t->c_parse_backslash_baton;
+    }
+  else
+    c_parse_backslash_func = default_c_parse_backslash;
+
+  if (h2t && h2t->convert_char)
+    {
+      host_char_to_target_func = h2t->convert_char;
+      host_char_to_target_baton = h2t->convert_char_baton;
+    }
+  else if (host == target)
+    host_char_to_target_func = identity_either_char_to_other;
+  else
+    {
+      host_char_to_target_func = iconv_convert;
+      host_char_to_target_baton = &cached_iconv_host_to_target;
+    }
+
+  if (t2h && t2h->convert_char)
+    {
+      target_char_to_host_func = t2h->convert_char;
+      target_char_to_host_baton = t2h->convert_char_baton;
+    }
+  else if (host == target)
+    target_char_to_host_func = identity_either_char_to_other;
+  else
+    {
+      target_char_to_host_func = iconv_convert;
+      target_char_to_host_baton = &cached_iconv_target_to_host;
+    }
+
+  current_host_charset = host;
+  current_target_charset = target;
+}
+
+
+static struct charset *
+lookup_charset_or_error (const char *name)
+{
+  struct charset *cs = lookup_charset (name);
+
+  if (! cs)
+    error ("GDB doesn't know of any character set named `%s'.", name);
+
+  return cs;
+}
+    
+
+static void
+check_valid_host_charset (struct charset *cs)
+{
+  if (! cs->valid_host_charset)
+    error ("GDB can't use `%s' as its host character set.", cs->name);
+}
+
+
+void
+set_host_charset (const char *charset)
+{
+  struct charset *cs = lookup_charset_or_error (charset);
+  check_valid_host_charset (cs);
+  set_host_and_target_charsets (cs, current_target_charset);
+}
+
+
+const char *
+host_charset ()
+{
+  return current_host_charset->name;
+}
+
+
+void
+set_target_charset (const char *charset)
+{
+  struct charset *cs = lookup_charset_or_error (charset);
+
+  set_host_and_target_charsets (current_host_charset, cs);
+}
+
+
+const char *
+target_charset ()
+{
+  return current_target_charset->name;
+}
+
+
+\f
+/* Public character management functions.  */
+
+
+const char *
+c_target_char_has_backslash_escape (int target_char)
+{
+  return ((*c_target_char_has_backslash_escape_func)
+          (c_target_char_has_backslash_escape_baton, target_char));
+}
+
+
+int
+c_parse_backslash (int host_char, int *target_char)
+{
+  return (*c_parse_backslash_func) (c_parse_backslash_baton,
+                                    host_char, target_char);
+}
+
+
+int
+host_char_print_literally (int host_char)
+{
+  return ((*current_host_charset->host_char_print_literally)
+          (current_host_charset->host_char_print_literally_baton,
+           host_char));
+}
+
+
+int
+target_char_to_control_char (int target_char, int *target_ctrl_char)
+{
+  return ((*current_target_charset->target_char_to_control_char)
+          (current_target_charset->target_char_to_control_char_baton,
+           target_char, target_ctrl_char));
+}
+
+
+int
+host_char_to_target (int host_char, int *target_char)
+{
+  return ((*host_char_to_target_func)
+          (host_char_to_target_baton, host_char, target_char));
+}
+
+
+int
+target_char_to_host (int target_char, int *host_char)
+{
+  return ((*target_char_to_host_func)
+          (target_char_to_host_baton, target_char, host_char));
+}
+
+
+\f
+/* Commands.  */
+
+
+/* List the valid character sets.  If HOST_ONLY is non-zero, list only
+   those character sets which can be used as GDB's host character set.  */
+static void
+list_charsets (int host_only)
+{
+  struct charset *cs;
+
+  printf_filtered ("Valid character sets are:\n");
+
+  for (cs = all_charsets; cs; cs = cs->next)
+    if (host_only && cs->valid_host_charset)
+      printf_filtered ("  %s\n", cs->name);
+    else
+      printf_filtered ("  %s %s\n",
+                       cs->name,
+                       cs->valid_host_charset ? "*" : " ");
+
+  if (! host_only)
+    printf_filtered ("* - can be used as a host character set\n");
+}
+
+
+static void
+set_charset_command (char *arg, int from_tty)
+{
+  if (! arg || arg[0] == '\0')
+    list_charsets (0);
+  else
+    {
+      struct charset *cs = lookup_charset_or_error (arg);
+      check_valid_host_charset (cs);
+      set_host_and_target_charsets (cs, cs); 
+    }
+}
+
+
+static void
+set_host_charset_command (char *arg, int from_tty)
+{
+  if (! arg || arg[0] == '\0')
+    list_charsets (1);
+  else
+    {
+      struct charset *cs = lookup_charset_or_error (arg);
+      check_valid_host_charset (cs);
+      set_host_and_target_charsets (cs, current_target_charset);
+    }
+}
+
+
+static void
+set_target_charset_command (char *arg, int from_tty)
+{
+  if (! arg || arg[0] == '\0')
+    list_charsets (0);
+  else
+    {
+      struct charset *cs = lookup_charset_or_error (arg);
+      set_host_and_target_charsets (current_host_charset, cs);
+    }
+}
+
+
+static void
+show_charset_command (char *arg, int from_tty)
+{
+  if (current_host_charset == current_target_charset)
+    {
+      printf_filtered ("The current host and target character set is `%s'.\n",
+                       host_charset ());
+    }
+  else
+    {
+      printf_filtered ("The current host character set is `%s'.\n",
+                       host_charset ());
+      printf_filtered ("The current target character set is `%s'.\n",
+                       target_charset ());
+    }
+}
+
+
+\f
+/* The charset.c module initialization function.  */
+
+#ifndef GDB_DEFAULT_HOST_CHARSET
+#define GDB_DEFAULT_HOST_CHARSET "ISO-8859-1"
+#endif
+
+#ifndef GDB_DEFAULT_TARGET_CHARSET
+#define GDB_DEFAULT_TARGET_CHARSET "ISO-8859-1"
+#endif
+
+void
+_initialize_charset (void)
+{
+  /* Register all the character set GDB knows about.
+
+     You should use the same names that iconv does, where possible, to
+     take advantage of the iconv-based default behaviors.
+
+     CAUTION: if you register a character set, you must also register
+     as many translations as are necessary to make that character set
+     interoperate correctly with all the other character sets.  We do
+     provide default behaviors when no translation is available, or
+     when a translation's function pointer for a particular operation
+     is zero.  Hopefully, these defaults will be correct often enough
+     that we won't need to provide too many translations.  */
+  register_charset (simple_charset ("ascii", 1,
+                                    ascii_print_literally, 0,
+                                    ascii_to_control, 0));
+  register_charset (iso_8859_family_charset ("iso-8859-1"));
+  register_charset (ebcdic_family_charset ("ebcdic-us"));
+  register_charset (ebcdic_family_charset ("ibm1047"));
+  register_iconv_charsets ();
+
+  {
+    struct { char *from; char *to; int *table; } tlist[] = {
+      { "ascii",      "iso-8859-1", ascii_to_iso_8859_1_table },
+      { "ascii",      "ebcdic-us",  ascii_to_ebcdic_us_table },
+      { "ascii",      "ibm1047",    ascii_to_ibm1047_table },
+      { "iso-8859-1", "ascii",      iso_8859_1_to_ascii_table },
+      { "iso-8859-1", "ebcdic-us",  iso_8859_1_to_ebcdic_us_table },
+      { "iso-8859-1", "ibm1047",    iso_8859_1_to_ibm1047_table },
+      { "ebcdic-us",  "ascii",      ebcdic_us_to_ascii_table },
+      { "ebcdic-us",  "iso-8859-1", ebcdic_us_to_iso_8859_1_table },
+      { "ebcdic-us",  "ibm1047",    ebcdic_us_to_ibm1047_table },
+      { "ibm1047",    "ascii",      ibm1047_to_ascii_table },
+      { "ibm1047",    "iso-8859-1", ibm1047_to_iso_8859_1_table },
+      { "ibm1047",    "ebcdic-us",  ibm1047_to_ebcdic_us_table }
+    };
+
+    int i;
+
+    for (i = 0; i < (sizeof (tlist) / sizeof (tlist[0])); i++)
+      register_translation (simple_table_translation (tlist[i].from,
+                                                      tlist[i].to,
+                                                      tlist[i].table));
+  }
+
+  set_host_charset (GDB_DEFAULT_HOST_CHARSET);
+  set_target_charset (GDB_DEFAULT_TARGET_CHARSET);
+
+  add_cmd ("charset", class_support, set_charset_command,
+           "Use CHARSET as the host and target character set.\n"
+           "The `host character set' is the one used by the system GDB is running on.\n"
+           "The `target character set' is the one used by the program being debugged.\n"
+           "You may only use supersets of ASCII for your host character set; GDB does\n"
+           "not support any others.\n"
+           "To see a list of the character sets GDB supports, type `set charset'\n"
+           "with no argument.",
+           &setlist);
+
+  add_cmd ("host-charset", class_support, set_host_charset_command,
+           "Use CHARSET as the host character set.\n"
+           "The `host character set' is the one used by the system GDB is running on.\n"
+           "You may only use supersets of ASCII for your host character set; GDB does\n"
+           "not support any others.\n"
+           "To see a list of the character sets GDB supports, type `set host-charset'\n"
+           "with no argument.",
+           &setlist);
+
+  add_cmd ("target-charset", class_support, set_target_charset_command,
+           "Use CHARSET as the target character set.\n"
+           "The `target character set' is the one used by the program being debugged.\n"
+           "GDB translates characters and strings between the host and target\n"
+           "character sets as needed.\n"
+           "To see a list of the character sets GDB supports, type `set target-charset'\n"
+           "with no argument.",
+           &setlist);
+
+  add_cmd ("charset", class_support, show_charset_command,
+           "Show the current host and target character sets.",
+           &showlist);
+  add_alias_cmd ("host-charset", "charset", class_alias, 1, &showlist);
+  add_alias_cmd ("target-charset", "charset", class_alias, 1, &showlist);
+}
diff --git a/gdb/charset.h b/gdb/charset.h
new file mode 100644 (file)
index 0000000..10578cb
--- /dev/null
@@ -0,0 +1,120 @@
+/* Character set conversion support for GDB.
+   Copyright 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef CHARSET_H
+#define CHARSET_H
+
+
+/* If the target program uses a different character set than the host,
+   GDB has some support for translating between the two; GDB converts
+   characters and strings to the host character set before displaying
+   them, and converts characters and strings appearing in expressions
+   entered by the user to the target character set.
+
+   At the moment, GDB only supports single-byte, stateless character
+   sets.  This includes the ISO-8859 family (ASCII extended with
+   accented characters, and (I think) Cyrillic, for European
+   languages), and the EBCDIC family (used on IBM's mainframes).
+   Unfortunately, it excludes many Asian scripts, the fixed- and
+   variable-width Unicode encodings, and other desireable things.
+   Patches are welcome!  (For example, it would be nice if the Java
+   string support could simply get absorbed into some more general
+   multi-byte encoding support.)
+
+   Furthermore, GDB's code pretty much assumes that the host character
+   set is some superset of ASCII; there are plenty if ('0' + n)
+   expressions and the like.
+
+   When the `iconv' library routine supports a character set meeting
+   the requirements above, it's easy to plug an entry into GDB's table
+   that uses iconv to handle the details.  */
+
+
+/* Set the host character set to CHARSET.  CHARSET must be a superset
+   of ASCII, since GDB's code assumes this.  */
+void set_host_charset (const char *charset);
+
+
+/* Set the target character set to CHARSET.  */
+void set_target_charset (const char *charset);
+
+
+/* Return the name of the current host/target character set.  The
+   result is owned by the charset module; the caller should not free
+   it.  */
+const char *host_charset (void);
+const char *target_charset (void);
+
+
+/* In general, the set of C backslash escapes (\n, \f) is specific to
+   the character set.  Not all character sets will have form feed
+   characters, for example.
+
+   The following functions allow GDB to parse and print control
+   characters in a character-set-independent way.  They are both
+   language-specific (to C and C++) and character-set-specific.
+   Putting them here is a compromise.  */
+
+
+/* If the target character TARGET_CHAR have a backslash escape in the
+   C language (i.e., a character like 'n' or 't'), return the host
+   character string that should follow the backslash.  Otherwise,
+   return zero.
+
+   When this function returns non-zero, the string it returns is
+   statically allocated; the caller is not responsible for freeing it.  */
+const char *c_target_char_has_backslash_escape (int target_char);
+
+
+/* If the host character HOST_CHAR is a valid backslash escape in the
+   C language for the target character set, return non-zero, and set
+   *TARGET_CHAR to the target character the backslash escape represents.
+   Otherwise, return zero.  */
+int c_parse_backslash (int host_char, int *target_char);
+
+
+/* Return non-zero if the host character HOST_CHAR can be printed
+   literally --- that is, if it can be readably printed as itself in a
+   character or string constant.  Return zero if it should be printed
+   using some kind of numeric escape, like '\031' in C, '^(25)' in
+   Chill, or #25 in Pascal.  */
+int host_char_print_literally (int host_char);
+
+
+/* If the host character HOST_CHAR has an equivalent in the target
+   character set, set *TARGET_CHAR to that equivalent, and return
+   non-zero.  Otherwise, return zero.  */
+int host_char_to_target (int host_char, int *target_char);
+
+
+/* If the target character TARGET_CHAR has an equivalent in the host
+   character set, set *HOST_CHAR to that equivalent, and return
+   non-zero.  Otherwise, return zero.  */
+int target_char_to_host (int target_char, int *host_char);
+
+
+/* If the target character TARGET_CHAR has a corresponding control
+   character (also in the target character set), set *TARGET_CTRL_CHAR
+   to the control character, and return non-zero.  Otherwise, return
+   zero.  */
+int target_char_to_control_char (int target_char, int *target_ctrl_char);
+
+
+#endif /* CHARSET_H */
diff --git a/gdb/config/i386/nbsd.mt b/gdb/config/i386/nbsd.mt
new file mode 100644 (file)
index 0000000..f7f8cd6
--- /dev/null
@@ -0,0 +1,4 @@
+# Target: Intel 386 running NetBSD
+TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386nbsd-tdep.o corelow.o \
+       nbsd-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
new file mode 100644 (file)
index 0000000..46363a8
--- /dev/null
@@ -0,0 +1,141 @@
+/* Helper routines for C++ support in GDB.
+   Copyright 2002 Free Software Foundation, Inc.
+
+   Contributed by MontaVista Software.
+
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "cp-support.h"
+#include "gdb_string.h"
+#include "demangle.h"
+
+/* Find the last component of the demangled C++ name NAME.  NAME
+   must be a method name including arguments, in order to correctly
+   locate the last component.
+
+   This function return a pointer to the first colon before the
+   last component, or NULL if the name had only one component.  */
+
+static const char *
+find_last_component (const char *name)
+{
+  const char *p;
+  int depth;
+
+  /* Functions can have local classes, so we need to find the
+     beginning of the last argument list, not the end of the first
+     one.  */
+  p = name + strlen (name) - 1;
+  while (p > name && *p != ')')
+    p--;
+
+  if (p == name)
+    return NULL;
+
+  /* P now points at the `)' at the end of the argument list.  Walk
+     back to the beginning.  */
+  p--;
+  depth = 1;
+  while (p > name && depth > 0)
+    {
+      if (*p == '<' || *p == '(')
+       depth--;
+      else if (*p == '>' || *p == ')')
+       depth++;
+      p--;
+    }
+
+  if (p == name)
+    return NULL;
+
+  while (p > name && *p != ':')
+    p--;
+
+  if (p == name || p == name + 1 || p[-1] != ':')
+    return NULL;
+
+  return p - 1;
+}
+
+/* Return the name of the class containing method PHYSNAME.  */
+
+char *
+class_name_from_physname (const char *physname)
+{
+  char *ret = NULL;
+  const char *end;
+  int depth = 0;
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  end = find_last_component (demangled_name);
+  if (end != NULL)
+    {
+      ret = xmalloc (end - demangled_name + 1);
+      memcpy (ret, demangled_name, end - demangled_name);
+      ret[end - demangled_name] = '\0';
+    }
+
+  xfree (demangled_name);
+  return ret;
+}
+
+/* Return the name of the method whose linkage name is PHYSNAME.  */
+
+char *
+method_name_from_physname (const char *physname)
+{
+  char *ret = NULL;
+  const char *end;
+  int depth = 0;
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+
+  if (demangled_name == NULL)
+    return NULL;
+
+  end = find_last_component (demangled_name);
+  if (end != NULL)
+    {
+      char *args;
+      int len;
+
+      /* Skip "::".  */
+      end = end + 2;
+
+      /* Find the argument list, if any.  */
+      args = strchr (end, '(');
+      if (args == NULL)
+       len = strlen (end + 2);
+      else
+       {
+         args --;
+         while (*args == ' ')
+           args --;
+         len = args - end + 1;
+       }
+      ret = xmalloc (len + 1);
+      memcpy (ret, end, len);
+      ret[len] = 0;
+    }
+
+  xfree (demangled_name);
+  return ret;
+}
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
new file mode 100644 (file)
index 0000000..a7d333f
--- /dev/null
@@ -0,0 +1,25 @@
+/* Helper routines for C++ support in GDB.
+   Copyright 2002 Free Software Foundation, Inc.
+
+   Contributed by MontaVista Software.
+
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+extern char *class_name_from_physname (const char *physname);
+
+extern char *method_name_from_physname (const char *physname);
diff --git a/gdb/disasm.c b/gdb/disasm.c
new file mode 100644 (file)
index 0000000..8ce9a15
--- /dev/null
@@ -0,0 +1,374 @@
+/* Disassemble support for GDB.
+   Copyright 2000, 2001, 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "target.h"
+#include "value.h"
+#include "ui-out.h"
+#include "gdb_string.h"
+
+#include "disasm.h"
+
+/* Disassemble functions.
+   FIXME: We should get rid of all the duplicate code in gdb that does
+   the same thing: disassemble_command() and the gdbtk variation. */
+
+/* This Structure is used to store line number information.
+   We need a different sort of line table from the normal one cuz we can't
+   depend upon implicit line-end pc's for lines to do the
+   reordering in this function.  */
+
+struct dis_line_entry
+{
+  int line;
+  CORE_ADDR start_pc;
+  CORE_ADDR end_pc;
+};
+
+/* This variable determines where memory used for disassembly is read from. */
+int gdb_disassemble_from_exec = -1;
+
+/* This is the memory_read_func for gdb_disassemble when we are
+   disassembling from the exec file. */
+static int
+gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
+                        unsigned int len, disassemble_info * info)
+{
+  extern struct target_ops exec_ops;
+  int res;
+
+  errno = 0;
+  res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
+
+  if (res == len)
+    return 0;
+  else if (errno == 0)
+    return EIO;
+  else
+    return errno;
+}
+
+static int
+compare_lines (const PTR mle1p, const PTR mle2p)
+{
+  struct dis_line_entry *mle1, *mle2;
+  int val;
+
+  mle1 = (struct dis_line_entry *) mle1p;
+  mle2 = (struct dis_line_entry *) mle2p;
+
+  val = mle1->line - mle2->line;
+
+  if (val != 0)
+    return val;
+
+  return mle1->start_pc - mle2->start_pc;
+}
+
+static int
+dump_insns (struct ui_out *uiout, disassemble_info * di,
+           CORE_ADDR low, CORE_ADDR high,
+           int how_many, struct ui_stream *stb)
+{
+  int num_displayed = 0;
+  CORE_ADDR pc;
+
+  /* parts of the symbolic representation of the address */
+  int unmapped;
+  char *filename = NULL;
+  char *name = NULL;
+  int offset;
+  int line;
+
+  for (pc = low; pc < high;)
+    {
+      QUIT;
+      if (how_many >= 0)
+       {
+         if (num_displayed >= how_many)
+           break;
+         else
+           num_displayed++;
+       }
+      ui_out_tuple_begin (uiout, NULL);
+      ui_out_field_core_addr (uiout, "address", pc);
+
+      if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
+                                  &line, &unmapped))
+       {
+         /* We don't care now about line, filename and
+            unmapped. But we might in the future. */
+         ui_out_text (uiout, " <");
+         ui_out_field_string (uiout, "func-name", name);
+         ui_out_text (uiout, "+");
+         ui_out_field_int (uiout, "offset", offset);
+         ui_out_text (uiout, ">:\t");
+       }
+      if (filename != NULL)
+       xfree (filename);
+      if (name != NULL)
+       xfree (name);
+
+      ui_file_rewind (stb->stream);
+      pc += TARGET_PRINT_INSN (pc, di);
+      ui_out_field_stream (uiout, "inst", stb);
+      ui_file_rewind (stb->stream);
+      ui_out_tuple_end (uiout);
+      ui_out_text (uiout, "\n");
+    }
+  return num_displayed;
+}
+
+/* The idea here is to present a source-O-centric view of a
+   function to the user.  This means that things are presented
+   in source order, with (possibly) out of order assembly
+   immediately following.  */
+static void
+do_mixed_source_and_assembly (struct ui_out *uiout,
+                             struct disassemble_info *di, int nlines,
+                             struct linetable_entry *le,
+                             CORE_ADDR low, CORE_ADDR high,
+                             struct symtab *symtab,
+                             int how_many, struct ui_stream *stb)
+{
+  int newlines = 0;
+  struct dis_line_entry *mle;
+  struct symtab_and_line sal;
+  int i;
+  int out_of_order = 0;
+  int next_line = 0;
+  CORE_ADDR pc;
+  int num_displayed = 0;
+
+  mle = (struct dis_line_entry *) alloca (nlines
+                                         * sizeof (struct dis_line_entry));
+
+  /* Copy linetable entries for this function into our data
+     structure, creating end_pc's and setting out_of_order as
+     appropriate.  */
+
+  /* First, skip all the preceding functions.  */
+
+  for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+
+  /* Now, copy all entries before the end of this function.  */
+
+  for (; i < nlines - 1 && le[i].pc < high; i++)
+    {
+      if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+       continue;               /* Ignore duplicates */
+
+      /* Skip any end-of-function markers.  */
+      if (le[i].line == 0)
+       continue;
+
+      mle[newlines].line = le[i].line;
+      if (le[i].line > le[i + 1].line)
+       out_of_order = 1;
+      mle[newlines].start_pc = le[i].pc;
+      mle[newlines].end_pc = le[i + 1].pc;
+      newlines++;
+    }
+
+  /* If we're on the last line, and it's part of the function,
+     then we need to get the end pc in a special way.  */
+
+  if (i == nlines - 1 && le[i].pc < high)
+    {
+      mle[newlines].line = le[i].line;
+      mle[newlines].start_pc = le[i].pc;
+      sal = find_pc_line (le[i].pc, 0);
+      mle[newlines].end_pc = sal.end;
+      newlines++;
+    }
+
+  /* Now, sort mle by line #s (and, then by addresses within
+     lines). */
+
+  if (out_of_order)
+    qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
+
+  /* Now, for each line entry, emit the specified lines (unless
+     they have been emitted before), followed by the assembly code
+     for that line.  */
+
+  ui_out_list_begin (uiout, "asm_insns");
+
+  for (i = 0; i < newlines; i++)
+    {
+      int close_list = 1;
+      /* Print out everything from next_line to the current line.  */
+      if (mle[i].line >= next_line)
+       {
+         if (next_line != 0)
+           {
+             /* Just one line to print. */
+             if (next_line == mle[i].line)
+               {
+                 ui_out_tuple_begin (uiout, "src_and_asm_line");
+                 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+               }
+             else
+               {
+                 /* Several source lines w/o asm instructions associated. */
+                 for (; next_line < mle[i].line; next_line++)
+                   {
+                     ui_out_tuple_begin (uiout, "src_and_asm_line");
+                     print_source_lines (symtab, next_line, next_line + 1,
+                                         0);
+                     ui_out_list_begin (uiout, "line_asm_insn");
+                     ui_out_list_end (uiout);
+                     ui_out_tuple_end (uiout);
+                   }
+                 /* Print the last line and leave list open for
+                    asm instructions to be added. */
+                 ui_out_tuple_begin (uiout, "src_and_asm_line");
+                 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+               }
+           }
+         else
+           {
+             ui_out_tuple_begin (uiout, "src_and_asm_line");
+             print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+           }
+
+         next_line = mle[i].line + 1;
+         ui_out_list_begin (uiout, "line_asm_insn");
+         /* Don't close the list if the lines are not in order. */
+         if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
+           close_list = 0;
+       }
+
+      num_displayed += dump_insns (uiout, di, mle[i].start_pc, mle[i].end_pc,
+                                  how_many, stb);
+      if (close_list)
+       {
+         ui_out_list_end (uiout);
+         ui_out_tuple_end (uiout);
+         ui_out_text (uiout, "\n");
+         close_list = 0;
+       }
+      if (how_many >= 0)
+       if (num_displayed >= how_many)
+         break;
+    }
+  ui_out_list_end (uiout);
+}
+
+
+static void
+do_assembly_only (struct ui_out *uiout, disassemble_info * di,
+                 CORE_ADDR low, CORE_ADDR high,
+                 int how_many, struct ui_stream *stb)
+{
+  int num_displayed = 0;
+
+  ui_out_list_begin (uiout, "asm_insns");
+
+  num_displayed = dump_insns (uiout, di, low, high, how_many, stb);
+
+  ui_out_list_end (uiout);
+}
+
+void
+gdb_disassembly (struct ui_out *uiout,
+               char *file_string,
+               int line_num,
+               int mixed_source_and_assembly,
+               int how_many, CORE_ADDR low, CORE_ADDR high)
+{
+  static disassemble_info di;
+  static int di_initialized;
+  /* To collect the instruction outputted from opcodes. */
+  static struct ui_stream *stb = NULL;
+  struct symtab *symtab = NULL;
+  struct linetable_entry *le = NULL;
+  int nlines = -1;
+
+  if (!di_initialized)
+    {
+      /* We don't add a cleanup for this, because the allocation of
+         the stream is done once only for each gdb run, and we need to
+         keep it around until the end. Hopefully there won't be any
+         errors in the init code below, that make this function bail
+         out. */
+      stb = ui_out_stream_new (uiout);
+      INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
+                                    (fprintf_ftype) fprintf_unfiltered);
+      di.flavour = bfd_target_unknown_flavour;
+      di.memory_error_func = dis_asm_memory_error;
+      di.print_address_func = dis_asm_print_address;
+      di_initialized = 1;
+    }
+
+  di.mach = TARGET_PRINT_INSN_INFO->mach;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    di.endian = BFD_ENDIAN_BIG;
+  else
+    di.endian = BFD_ENDIAN_LITTLE;
+
+  /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
+     determine whether or not to do disassembly from target memory or from the
+     exec file:
+
+     If we're debugging a local process, read target memory, instead of the
+     exec file.  This makes disassembly of functions in shared libs work
+     correctly.  Also, read target memory if we are debugging native threads.
+
+     Else, we're debugging a remote process, and should disassemble from the
+     exec file for speed.  However, this is no good if the target modifies its
+     code (for relocation, or whatever).  */
+
+  if (gdb_disassemble_from_exec == -1)
+    {
+      if (strcmp (target_shortname, "child") == 0
+         || strcmp (target_shortname, "procfs") == 0
+         || strcmp (target_shortname, "vxprocess") == 0
+         || strstr (target_shortname, "-threads") != NULL)
+       gdb_disassemble_from_exec = 0;  /* It's a child process, read inferior mem */
+      else
+       gdb_disassemble_from_exec = 1;  /* It's remote, read the exec file */
+    }
+
+  if (gdb_disassemble_from_exec)
+    di.read_memory_func = gdb_dis_asm_read_memory;
+  else
+    di.read_memory_func = dis_asm_read_memory;
+
+  /* Assume symtab is valid for whole PC range */
+  symtab = find_pc_symtab (low);
+
+  if (symtab != NULL && symtab->linetable != NULL)
+    {
+      /* Convert the linetable to a bunch of my_line_entry's.  */
+      le = symtab->linetable->item;
+      nlines = symtab->linetable->nitems;
+    }
+
+  if (!mixed_source_and_assembly || nlines <= 0
+      || symtab == NULL || symtab->linetable == NULL)
+    do_assembly_only (uiout, &di, low, high, how_many, stb);
+
+  else if (mixed_source_and_assembly)
+    do_mixed_source_and_assembly (uiout, &di, nlines, le, low,
+                                 high, symtab, how_many, stb);
+
+  gdb_flush (gdb_stdout);
+}
diff --git a/gdb/disasm.h b/gdb/disasm.h
new file mode 100644 (file)
index 0000000..beaaf4a
--- /dev/null
@@ -0,0 +1,29 @@
+/* Disassemble support for GDB.
+   Copyright 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef DISASM_H
+#define DISASM_H
+
+extern void gdb_disassembly (struct ui_out *uiout,
+                            char *file_string,
+                            int line_num,
+                            int mixed_source_and_assembly,
+                            int how_many, CORE_ADDR low, CORE_ADDR high);
+#endif
diff --git a/gdb/gdb.c b/gdb/gdb.c
new file mode 100644 (file)
index 0000000..c0bc487
--- /dev/null
+++ b/gdb/gdb.c
@@ -0,0 +1,34 @@
+/* Main function for CLI gdb.  
+   Copyright 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "main.h"
+#include "gdb_string.h"
+
+int
+main (int argc, char **argv)
+{
+  struct captured_main_args args;
+  memset (&args, 0, sizeof args);
+  args.argc = argc;
+  args.argv = argv;
+  args.use_windows = 0;
+  return gdb_main (&args);
+}
diff --git a/gdb/gdb_mbuild.sh b/gdb/gdb_mbuild.sh
new file mode 100755 (executable)
index 0000000..ae40b02
--- /dev/null
@@ -0,0 +1,153 @@
+#!/bin/sh
+
+#  Multi-build script for testing compilation of all maintained configs of GDB.
+#  Copyright (C) 2002  Free Software Foundation, Inc.
+#  Contributed by Richard Earnshaw  (rearnsha@arm.com)
+
+#  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 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, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+usage() {
+    echo "Usage: gdb_mbuild.sh <srcdir> <builddir> [<parjobs>]"
+    echo " Environment variables examined (with default if not defined):"
+    echo "  AWK (awk) -- must be GNU awk"
+    echo "  MAKE (make)"
+    echo
+    echo " Note: Everything in <builddir>/gdb-allcross will be blown away."
+    exit 1;
+}
+
+if [ $# -ne 2 -a $# -ne 3 ] ; then
+    usage
+fi
+
+### COMMAND LINE PARAMETERS
+
+# Where the sources live
+srcdir=$1
+
+# Where the builds occur
+buildbase=$2
+
+# Number of parallel make jobs (you probably want about 2 jobs per cpu for
+# maximum throughput)
+if [ $# -eq 3 ]; then
+    par=$3
+else
+    par="1"
+fi
+
+### ENVIRONMENT PARAMETERS
+# Must be GNU awk
+awk=${AWK:-awk}
+
+# Version of make to use
+make=${MAKE:-make}
+
+
+# Where builds will live
+builddir=${buildbase}/gdb-allcross
+
+# Where logs will go.  NB. Must not be a sub-dir of builddir or you will loose
+# them.
+logdir=${buildbase}/gdb-logdir
+
+# Where to look for the list of targets to test
+maintainers=${srcdir}/gdb/MAINTAINERS
+
+# Get the list of targets and the build options
+alltarg=`${awk} < "${maintainers}" '
+  $2 ~ /--target=.*/ {
+    targets = gensub (/^.*--target=/, "", 1, $2)
+    warnings = gensub (/[)]*$/, "", 1, $3)
+    split (targets, targ, /,/)
+    for (i in targ) {
+        print targ[i], warnings
+    }
+  }'`
+
+# Back up the log files
+cd ${logdir}
+
+if [ -f build.out ]
+then
+       mv build.out build.old
+fi
+if [ -f config.out ]
+then
+       mv config.out config.old
+fi
+if [ -f fail.sum ]
+then
+       mv fail.sum fail.old
+fi
+
+if [ ! -d ${builddir} ]
+then
+       echo ${builddir} does not exist
+       exit 1
+fi
+
+cd ${builddir}
+rm -rf *
+
+MAKE=${make}
+export MAKE
+
+jobs=1
+# For each target, configure and build it.
+while read targ opts
+do
+       if [ ${opts} != "broken" ]
+       then
+               trap 'echo cleaning up ...; rm -rf ${builddir}/*; exit 1' 1 2 15
+               echo ${targ}
+               mkdir ${targ}
+               cd ${targ}
+               ${srcdir}/configure --target=$targ \
+                 --enable-gdb-build-warnings=$opts \
+                 >> ${logdir}/config.tout.$targ 2>&1 &
+               cd ..
+               jobs=`expr ${jobs} + 1`
+               if [ ${jobs} -gt ${par} ]
+               then
+                       wait
+                       jobs=1
+               fi
+       fi
+done << EOF
+$alltarg
+EOF
+
+wait
+
+cat ${logdir}/config.tout.* > ${logdir}/config.out
+rm -f ${logdir}/config.tout.*
+
+for targ in *
+do
+       cd $targ
+       if  ${make} -j ${par} all-gdb >> ${logdir}/build.out 2>&1
+       then
+               true
+       else
+               echo ">>>>>>>>>>>>>" >> ${logdir}/fail.sum
+               echo "$targ (${opts})" >> ${logdir}/fail.sum 
+               tail -20 ${logdir}/build.out >> ${logdir}/fail.sum
+               echo >> ${logdir}/fail.sum
+               echo $targ build failed
+       fi
+       rm -rf *
+       cd ..
+done
diff --git a/gdb/main.h b/gdb/main.h
new file mode 100644 (file)
index 0000000..8ee189e
--- /dev/null
@@ -0,0 +1,34 @@
+/* Main interface for GDB, the GNU debugger.
+
+   Copyright 2002 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef MAIN_H
+#define MAIN_H
+
+struct captured_main_args
+{
+  int argc;
+  char **argv;
+  int use_windows;
+};
+
+extern int gdb_main (struct captured_main_args *);
+
+#endif
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
new file mode 100644 (file)
index 0000000..54b99b0
--- /dev/null
@@ -0,0 +1,1841 @@
+/* YACC parser for C expressions, for GDB.
+
+   Copyright 1986, 1989, 1990, 1991, 1993, 1994, 2002 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 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Parse a C expression from text in a string, and return the result
+   as a struct expression pointer.  That structure contains arithmetic
+   operations in reverse polish, with constants represented by
+   operations that are followed by special data.  See expression.h for
+   the details of the format.  What is important here is that it can
+   be built up sequentially during the process of parsing; the lower
+   levels of the tree always come first in the result.
+
+   Note that malloc's and realloc's in this file are transformed to
+   xmalloc and xrealloc respectively by the same sed command in the
+   makefile that remaps any other malloc/realloc inserted by the
+   parser generator.  Doing this with #defines and trying to control
+   the interaction with include files (<malloc.h> and <stdlib.h> for
+   example) just became too messy, particularly when such includes can
+   be inserted at random times by the parser generator.  */
+   
+%{
+
+#include "defs.h"
+#include "gdb_string.h"
+#include <ctype.h>
+#include "expression.h"
+
+#include "objc-lang.h" /* For objc language constructs.  */
+
+#include "value.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "bfd.h" /* Required by objfiles.h.  */
+#include "symfile.h" /* Required by objfiles.h.  */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols.  */
+#include "top.h"
+#include "completer.h" /* For skip_quoted().  */
+
+/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
+   etc), as well as gratuitiously global symbol names, so we can have
+   multiple yacc generated parsers in gdb.  Note that these are only
+   the variables produced by yacc.  If other parser generators (bison,
+   byacc, etc) produce additional global names that conflict at link
+   time, then those parser generators need to be fixed instead of
+   adding those names to this list.  */
+
+#define        yymaxdepth      objc_maxdepth
+#define        yyparse         objc_parse
+#define        yylex           objc_lex
+#define        yyerror         objc_error
+#define        yylval          objc_lval
+#define        yychar          objc_char
+#define        yydebug         objc_debug
+#define        yypact          objc_pact       
+#define        yyr1            objc_r1                 
+#define        yyr2            objc_r2                 
+#define        yydef           objc_def                
+#define        yychk           objc_chk                
+#define        yypgo           objc_pgo                
+#define        yyact           objc_act                
+#define        yyexca          objc_exca
+#define yyerrflag      objc_errflag
+#define yynerrs                objc_nerrs
+#define        yyps            objc_ps
+#define        yypv            objc_pv
+#define        yys             objc_s
+#define        yy_yys          objc_yys
+#define        yystate         objc_state
+#define        yytmp           objc_tmp
+#define        yyv             objc_v
+#define        yy_yyv          objc_yyv
+#define        yyval           objc_val
+#define        yylloc          objc_lloc
+#define yyreds         objc_reds               /* With YYDEBUG defined */
+#define yytoks         objc_toks               /* With YYDEBUG defined */
+#define yyname         objc_name               /* With YYDEBUG defined */
+#define yyrule         objc_rule               /* With YYDEBUG defined */
+#define yylhs          objc_yylhs
+#define yylen          objc_yylen
+#define yydefred       objc_yydefred
+#define yydgoto                objc_yydgoto
+#define yysindex       objc_yysindex
+#define yyrindex       objc_yyrindex
+#define yygindex       objc_yygindex
+#define yytable                objc_yytable
+#define yycheck                objc_yycheck
+
+#ifndef YYDEBUG
+#define        YYDEBUG 0               /* Default to no yydebug support.  */
+#endif
+
+int
+yyparse PARAMS ((void));
+
+static int
+yylex PARAMS ((void));
+
+void
+yyerror PARAMS ((char *));
+
+%}
+
+/* Although the yacc "value" of an expression is not used,
+   since the result is stored in the structure being created,
+   other node types do have values.  */
+
+%union
+  {
+    LONGEST lval;
+    struct {
+      LONGEST val;
+      struct type *type;
+    } typed_val_int;
+    struct {
+      DOUBLEST dval;
+      struct type *type;
+    } typed_val_float;
+    struct symbol *sym;
+    struct type *tval;
+    struct stoken sval;
+    struct ttype tsym;
+    struct symtoken ssym;
+    int voidval;
+    struct block *bval;
+    enum exp_opcode opcode;
+    struct internalvar *ivar;
+    struct objc_class_str class;
+
+    struct type **tvec;
+    int *ivec;
+  }
+
+%{
+/* YYSTYPE gets defined by %union.  */
+static int
+parse_number PARAMS ((char *, int, int, YYSTYPE *));
+%}
+
+%type <voidval> exp exp1 type_exp start variable qualified_name lcurly
+%type <lval> rcurly
+%type <tval> type typebase
+%type <tvec> nonempty_typelist
+/* %type <bval> block */
+
+/* Fancy type parsing.  */
+%type <voidval> func_mod direct_abs_decl abs_decl
+%type <tval> ptype
+%type <lval> array_mod
+
+%token <typed_val_int> INT
+%token <typed_val_float> FLOAT
+
+/* Both NAME and TYPENAME tokens represent symbols in the input, and
+   both convey their data as strings.  But a TYPENAME is a string that
+   happens to be defined as a typedef or builtin type name (such as
+   int or char) and a NAME is any other symbol.  Contexts where this
+   distinction is not important can use the nonterminal "name", which
+   matches either NAME or TYPENAME.  */
+
+%token <sval> STRING
+%token <sval> NSSTRING         /* ObjC Foundation "NSString" literal */
+%token <sval> SELECTOR         /* ObjC "@selector" pseudo-operator   */
+%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <tsym> TYPENAME
+%token <class> CLASSNAME       /* ObjC Class name */
+%type <sval> name
+%type <ssym> name_not_typename
+%type <tsym> typename
+
+/* A NAME_OR_INT is a symbol which is not known in the symbol table,
+   but which would parse as a valid number in the current input radix.
+   E.g. "c" when input_radix==16.  Depending on the parse, it will be
+   turned into a name or into a number.  */
+
+%token <ssym> NAME_OR_INT 
+
+%token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON 
+%token TEMPLATE
+%token ERROR
+
+/* Special type cases, put in to allow the parser to distinguish
+   different legal basetypes.  */
+%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD
+
+%token <voidval> VARIABLE
+
+%token <opcode> ASSIGN_MODIFY
+
+/* C++ */
+%token THIS
+
+%left ','
+%left ABOVE_COMMA
+%right '=' ASSIGN_MODIFY
+%right '?'
+%left OROR
+%left ANDAND
+%left '|'
+%left '^'
+%left '&'
+%left EQUAL NOTEQUAL
+%left '<' '>' LEQ GEQ
+%left LSH RSH
+%left '@'
+%left '+' '-'
+%left '*' '/' '%'
+%right UNARY INCREMENT DECREMENT
+%right ARROW '.' '[' '('
+%token <ssym> BLOCKNAME 
+%type <bval> block
+%left COLONCOLON
+
+\f
+%%
+
+start   :      exp1
+       |       type_exp
+       ;
+
+type_exp:      type
+                       { write_exp_elt_opcode(OP_TYPE);
+                         write_exp_elt_type($1);
+                         write_exp_elt_opcode(OP_TYPE);}
+       ;
+
+/* Expressions, including the comma operator.  */
+exp1   :       exp
+       |       exp1 ',' exp
+                       { write_exp_elt_opcode (BINOP_COMMA); }
+       ;
+
+/* Expressions, not including the comma operator.  */
+exp    :       '*' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_IND); }
+
+exp    :       '&' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_ADDR); }
+
+exp    :       '-' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_NEG); }
+       ;
+
+exp    :       '!' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+       ;
+
+exp    :       '~' exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+       ;
+
+exp    :       INCREMENT exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+       ;
+
+exp    :       DECREMENT exp    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+       ;
+
+exp    :       exp INCREMENT    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+       ;
+
+exp    :       exp DECREMENT    %prec UNARY
+                       { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+       ;
+
+exp    :       SIZEOF exp       %prec UNARY
+                       { write_exp_elt_opcode (UNOP_SIZEOF); }
+       ;
+
+exp    :       exp ARROW name
+                       { write_exp_elt_opcode (STRUCTOP_PTR);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (STRUCTOP_PTR); }
+       ;
+
+exp    :       exp ARROW qualified_name
+                       { /* exp->type::name becomes exp->*(&type::name) */
+                         /* Note: this doesn't work if name is a
+                            static member!  FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
+                         write_exp_elt_opcode (STRUCTOP_MPTR); }
+       ;
+exp    :       exp ARROW '*' exp
+                       { write_exp_elt_opcode (STRUCTOP_MPTR); }
+       ;
+
+exp    :       exp '.' name
+                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+       ;
+
+
+exp    :       exp '.' qualified_name
+                       { /* exp.type::name becomes exp.*(&type::name) */
+                         /* Note: this doesn't work if name is a
+                            static member!  FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
+                         write_exp_elt_opcode (STRUCTOP_MEMBER); }
+       ;
+
+exp    :       exp '.' '*' exp
+                       { write_exp_elt_opcode (STRUCTOP_MEMBER); }
+       ;
+
+exp    :       exp '[' exp1 ']'
+                       { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+       ;
+/*
+ * The rules below parse ObjC message calls of the form:
+ *     '[' target selector {':' argument}* ']'
+ */
+
+exp    :       '[' TYPENAME
+                       {
+                         CORE_ADDR class;
+
+                         class = lookup_objc_class (copy_name ($2.stoken));
+                         if (class == 0)
+                           error ("%s is not an ObjC Class", 
+                                  copy_name ($2.stoken));
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) class);
+                         write_exp_elt_opcode (OP_LONG);
+                         start_msglist();
+                       }
+               msglist ']'
+                       { write_exp_elt_opcode (OP_MSGCALL);
+                         end_msglist();
+                         write_exp_elt_opcode (OP_MSGCALL); 
+                       }
+       ;
+
+exp    :       '[' CLASSNAME
+                       {
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) $2.class);
+                         write_exp_elt_opcode (OP_LONG);
+                         start_msglist();
+                       }
+               msglist ']'
+                       { write_exp_elt_opcode (OP_MSGCALL);
+                         end_msglist();
+                         write_exp_elt_opcode (OP_MSGCALL); 
+                       }
+       ;
+
+exp    :       '[' exp
+                       { start_msglist(); }
+               msglist ']'
+                       { write_exp_elt_opcode (OP_MSGCALL);
+                         end_msglist();
+                         write_exp_elt_opcode (OP_MSGCALL); 
+                       }
+       ;
+
+msglist :      name
+                       { add_msglist(&$1, 0); }
+       |       msgarglist
+       ;
+
+msgarglist :   msgarg
+       |       msgarglist msgarg
+       ;
+
+msgarg :       name ':' exp
+                       { add_msglist(&$1, 1); }
+       |       ':' exp /* Unnamed arg.  */
+                       { add_msglist(0, 1);   }
+       |       ',' exp /* Variable number of args.  */
+                       { add_msglist(0, 0);   }
+       ;
+
+exp    :       exp '(' 
+                       /* This is to save the value of arglist_len
+                          being accumulated by an outer function call.  */
+                       { start_arglist (); }
+               arglist ')'     %prec ARROW
+                       { write_exp_elt_opcode (OP_FUNCALL);
+                         write_exp_elt_longcst ((LONGEST) end_arglist ());
+                         write_exp_elt_opcode (OP_FUNCALL); }
+       ;
+
+lcurly :       '{'
+                       { start_arglist (); }
+       ;
+
+arglist        :
+       ;
+
+arglist        :       exp
+                       { arglist_len = 1; }
+       ;
+
+arglist        :       arglist ',' exp   %prec ABOVE_COMMA
+                       { arglist_len++; }
+       ;
+
+rcurly :       '}'
+                       { $$ = end_arglist () - 1; }
+       ;
+exp    :       lcurly arglist rcurly   %prec ARROW
+                       { write_exp_elt_opcode (OP_ARRAY);
+                         write_exp_elt_longcst ((LONGEST) 0);
+                         write_exp_elt_longcst ((LONGEST) $3);
+                         write_exp_elt_opcode (OP_ARRAY); }
+       ;
+
+exp    :       lcurly type rcurly exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_MEMVAL);
+                         write_exp_elt_type ($2);
+                         write_exp_elt_opcode (UNOP_MEMVAL); }
+       ;
+
+exp    :       '(' type ')' exp  %prec UNARY
+                       { write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type ($2);
+                         write_exp_elt_opcode (UNOP_CAST); }
+       ;
+
+exp    :       '(' exp1 ')'
+                       { }
+       ;
+
+/* Binary operators in order of decreasing precedence.  */
+
+exp    :       exp '@' exp
+                       { write_exp_elt_opcode (BINOP_REPEAT); }
+       ;
+
+exp    :       exp '*' exp
+                       { write_exp_elt_opcode (BINOP_MUL); }
+       ;
+
+exp    :       exp '/' exp
+                       { write_exp_elt_opcode (BINOP_DIV); }
+       ;
+
+exp    :       exp '%' exp
+                       { write_exp_elt_opcode (BINOP_REM); }
+       ;
+
+exp    :       exp '+' exp
+                       { write_exp_elt_opcode (BINOP_ADD); }
+       ;
+
+exp    :       exp '-' exp
+                       { write_exp_elt_opcode (BINOP_SUB); }
+       ;
+
+exp    :       exp LSH exp
+                       { write_exp_elt_opcode (BINOP_LSH); }
+       ;
+
+exp    :       exp RSH exp
+                       { write_exp_elt_opcode (BINOP_RSH); }
+       ;
+
+exp    :       exp EQUAL exp
+                       { write_exp_elt_opcode (BINOP_EQUAL); }
+       ;
+
+exp    :       exp NOTEQUAL exp
+                       { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+       ;
+
+exp    :       exp LEQ exp
+                       { write_exp_elt_opcode (BINOP_LEQ); }
+       ;
+
+exp    :       exp GEQ exp
+                       { write_exp_elt_opcode (BINOP_GEQ); }
+       ;
+
+exp    :       exp '<' exp
+                       { write_exp_elt_opcode (BINOP_LESS); }
+       ;
+
+exp    :       exp '>' exp
+                       { write_exp_elt_opcode (BINOP_GTR); }
+       ;
+
+exp    :       exp '&' exp
+                       { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+       ;
+
+exp    :       exp '^' exp
+                       { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+       ;
+
+exp    :       exp '|' exp
+                       { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+       ;
+
+exp    :       exp ANDAND exp
+                       { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+       ;
+
+exp    :       exp OROR exp
+                       { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+       ;
+
+exp    :       exp '?' exp ':' exp     %prec '?'
+                       { write_exp_elt_opcode (TERNOP_COND); }
+       ;
+                         
+exp    :       exp '=' exp
+                       { write_exp_elt_opcode (BINOP_ASSIGN); }
+       ;
+
+exp    :       exp ASSIGN_MODIFY exp
+                       { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
+                         write_exp_elt_opcode ($2);
+                         write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+       ;
+
+exp    :       INT
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_longcst ((LONGEST)($1.val));
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       NAME_OR_INT
+                       { YYSTYPE val;
+                         parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (val.typed_val_int.type);
+                         write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
+                         write_exp_elt_opcode (OP_LONG);
+                       }
+       ;
+
+
+exp    :       FLOAT
+                       { write_exp_elt_opcode (OP_DOUBLE);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_dblcst ($1.dval);
+                         write_exp_elt_opcode (OP_DOUBLE); }
+       ;
+
+exp    :       variable
+       ;
+
+exp    :       VARIABLE
+                       /* Already written by write_dollar_variable.  */
+       ;
+
+exp    :       SELECTOR 
+                       {
+                         write_exp_elt_opcode (OP_SELECTOR);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_SELECTOR); }
+
+exp    :       SIZEOF '(' type ')'     %prec UNARY
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         CHECK_TYPEDEF ($3);
+                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+                         write_exp_elt_opcode (OP_LONG); }
+       ;
+
+exp    :       STRING
+                       { /* C strings are converted into array
+                            constants with an explicit null byte
+                            added at the end.  Thus the array upper
+                            bound is the string length.  There is no
+                            such thing in C as a completely empty
+                            string.  */
+                         char *sp = $1.ptr; int count = $1.length;
+                         while (count-- > 0)
+                           {
+                             write_exp_elt_opcode (OP_LONG);
+                             write_exp_elt_type (builtin_type_char);
+                             write_exp_elt_longcst ((LONGEST)(*sp++));
+                             write_exp_elt_opcode (OP_LONG);
+                           }
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_char);
+                         write_exp_elt_longcst ((LONGEST)'\0');
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_opcode (OP_ARRAY);
+                         write_exp_elt_longcst ((LONGEST) 0);
+                         write_exp_elt_longcst ((LONGEST) ($1.length));
+                         write_exp_elt_opcode (OP_ARRAY); }
+       ;
+
+exp     :      NSSTRING        /* ObjC NextStep NSString constant
+                                * of the form '@' '"' string '"'.
+                                */
+                       { write_exp_elt_opcode (OP_NSSTRING);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_NSSTRING); }
+       ;
+
+/* C++.  */
+exp    :       THIS
+                       { write_exp_elt_opcode (OP_THIS);
+                         write_exp_elt_opcode (OP_THIS); }
+       ;
+
+/* end of C++.  */
+
+block  :       BLOCKNAME
+                       {
+                         if ($1.sym != 0)
+                             $$ = SYMBOL_BLOCK_VALUE ($1.sym);
+                         else
+                           {
+                             struct symtab *tem =
+                                 lookup_symtab (copy_name ($1.stoken));
+                             if (tem)
+                               $$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK);
+                             else
+                               error ("No file or function \"%s\".",
+                                      copy_name ($1.stoken));
+                           }
+                       }
+       ;
+
+block  :       block COLONCOLON name
+                       { struct symbol *tem
+                           = lookup_symbol (copy_name ($3), $1,
+                                            VAR_NAMESPACE, (int *) NULL,
+                                            (struct symtab **) NULL);
+                         if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
+                           error ("No function \"%s\" in specified context.",
+                                  copy_name ($3));
+                         $$ = SYMBOL_BLOCK_VALUE (tem); }
+       ;
+
+variable:      block COLONCOLON name
+                       { struct symbol *sym;
+                         sym = lookup_symbol (copy_name ($3), $1,
+                                              VAR_NAMESPACE, (int *) NULL,
+                                              (struct symtab **) NULL);
+                         if (sym == 0)
+                           error ("No symbol \"%s\" in specified context.",
+                                  copy_name ($3));
+
+                         write_exp_elt_opcode (OP_VAR_VALUE);
+                         /* block_found is set by lookup_symbol.  */
+                         write_exp_elt_block (block_found);
+                         write_exp_elt_sym (sym);
+                         write_exp_elt_opcode (OP_VAR_VALUE); }
+       ;
+
+qualified_name:        typebase COLONCOLON name
+                       {
+                         struct type *type = $1;
+                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+                             && TYPE_CODE (type) != TYPE_CODE_UNION)
+                           error ("`%s' is not defined as an aggregate type.",
+                                  TYPE_NAME (type));
+
+                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_type (type);
+                         write_exp_string ($3);
+                         write_exp_elt_opcode (OP_SCOPE);
+                       }
+       |       typebase COLONCOLON '~' name
+                       {
+                         struct type *type = $1;
+                         struct stoken tmp_token;
+                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+                             && TYPE_CODE (type) != TYPE_CODE_UNION)
+                           error ("`%s' is not defined as an aggregate type.",
+                                  TYPE_NAME (type));
+
+                         if (!STREQ (type_name_no_tag (type), $4.ptr))
+                           error ("invalid destructor `%s::~%s'",
+                                  type_name_no_tag (type), $4.ptr);
+
+                         tmp_token.ptr = (char*) alloca ($4.length + 2);
+                         tmp_token.length = $4.length + 1;
+                         tmp_token.ptr[0] = '~';
+                         memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
+                         tmp_token.ptr[tmp_token.length] = 0;
+                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_type (type);
+                         write_exp_string (tmp_token);
+                         write_exp_elt_opcode (OP_SCOPE);
+                       }
+       ;
+
+variable:      qualified_name
+       |       COLONCOLON name
+                       {
+                         char *name = copy_name ($2);
+                         struct symbol *sym;
+                         struct minimal_symbol *msymbol;
+
+                         sym =
+                           lookup_symbol (name, (const struct block *) NULL,
+                                          VAR_NAMESPACE, (int *) NULL,
+                                          (struct symtab **) NULL);
+                         if (sym)
+                           {
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_block (NULL);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             break;
+                           }
+
+                         msymbol = lookup_minimal_symbol (name, NULL, NULL);
+                         if (msymbol != NULL)
+                           {
+                             write_exp_msymbol (msymbol,
+                                                lookup_function_type (builtin_type_int),
+                                                builtin_type_int);
+                           }
+                         else
+                           if (!have_full_symbols () && !have_partial_symbols ())
+                             error ("No symbol table is loaded.  Use the \"file\" command.");
+                           else
+                             error ("No symbol \"%s\" in current context.", name);
+                       }
+       ;
+
+variable:      name_not_typename
+                       { struct symbol *sym = $1.sym;
+
+                         if (sym)
+                           {
+                             if (symbol_read_needs_frame (sym))
+                               {
+                                 if (innermost_block == 0 ||
+                                     contained_in (block_found, 
+                                                   innermost_block))
+                                   innermost_block = block_found;
+                               }
+
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             /* We want to use the selected frame, not
+                                another more inner frame which happens to
+                                be in the same block.  */
+                             write_exp_elt_block (NULL);
+                             write_exp_elt_sym (sym);
+                             write_exp_elt_opcode (OP_VAR_VALUE);
+                           }
+                         else if ($1.is_a_field_of_this)
+                           {
+                             /* C++/ObjC: it hangs off of `this'/'self'.  
+                                Must not inadvertently convert from a 
+                                method call to data ref.  */
+                             if (innermost_block == 0 || 
+                                 contained_in (block_found, innermost_block))
+                               innermost_block = block_found;
+                             write_exp_elt_opcode (OP_SELF);
+                             write_exp_elt_opcode (OP_SELF);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                             write_exp_string ($1.stoken);
+                             write_exp_elt_opcode (STRUCTOP_PTR);
+                           }
+                         else
+                           {
+                             struct minimal_symbol *msymbol;
+                             register char *arg = copy_name ($1.stoken);
+
+                             msymbol =
+                               lookup_minimal_symbol (arg, NULL, NULL);
+                             if (msymbol != NULL)
+                               {
+                                 write_exp_msymbol (msymbol,
+                                                    lookup_function_type (builtin_type_int),
+                                                    builtin_type_int);
+                               }
+                             else if (!have_full_symbols () && 
+                                      !have_partial_symbols ())
+                               error ("No symbol table is loaded.  Use the \"file\" command.");
+                             else
+                               error ("No symbol \"%s\" in current context.",
+                                      copy_name ($1.stoken));
+                           }
+                       }
+       ;
+
+
+ptype  :       typebase
+       /* "const" and "volatile" are curently ignored.  A type
+          qualifier before the type is currently handled in the
+          typebase rule.  The reason for recognizing these here
+          (shift/reduce conflicts) might be obsolete now that some
+          pointer to member rules have been deleted.  */
+       |       typebase CONST_KEYWORD
+       |       typebase VOLATILE_KEYWORD
+       |       typebase abs_decl
+               { $$ = follow_types ($1); }
+       |       typebase CONST_KEYWORD abs_decl
+               { $$ = follow_types ($1); }
+       |       typebase VOLATILE_KEYWORD abs_decl
+               { $$ = follow_types ($1); }
+       ;
+
+abs_decl:      '*'
+                       { push_type (tp_pointer); $$ = 0; }
+       |       '*' abs_decl
+                       { push_type (tp_pointer); $$ = $2; }
+       |       '&'
+                       { push_type (tp_reference); $$ = 0; }
+       |       '&' abs_decl
+                       { push_type (tp_reference); $$ = $2; }
+       |       direct_abs_decl
+       ;
+
+direct_abs_decl: '(' abs_decl ')'
+                       { $$ = $2; }
+       |       direct_abs_decl array_mod
+                       {
+                         push_type_int ($2);
+                         push_type (tp_array);
+                       }
+       |       array_mod
+                       {
+                         push_type_int ($1);
+                         push_type (tp_array);
+                         $$ = 0;
+                       }
+
+       |       direct_abs_decl func_mod
+                       { push_type (tp_function); }
+       |       func_mod
+                       { push_type (tp_function); }
+       ;
+
+array_mod:     '[' ']'
+                       { $$ = -1; }
+       |       '[' INT ']'
+                       { $$ = $2.val; }
+       ;
+
+func_mod:      '(' ')'
+                       { $$ = 0; }
+       |       '(' nonempty_typelist ')'
+                       { free ((PTR)$2); $$ = 0; }
+       ;
+
+/* We used to try to recognize more pointer to member types here, but
+   that didn't work (shift/reduce conflicts meant that these rules
+   never got executed).  The problem is that
+     int (foo::bar::baz::bizzle)
+   is a function type but
+     int (foo::bar::baz::bizzle::*)
+   is a pointer to member type.  Stroustrup loses again!  */
+
+type   :       ptype
+       |       typebase COLONCOLON '*'
+                       { $$ = lookup_member_type (builtin_type_int, $1); }
+       ;
+
+typebase  /* Implements (approximately): (type-qualifier)* type-specifier.  */
+       :       TYPENAME
+                       { $$ = $1.type; }
+       |       CLASSNAME
+                       {
+                         if ($1.type == NULL)
+                           error ("No symbol \"%s\" in current context.", 
+                                  copy_name($1.stoken));
+                         else
+                           $$ = $1.type;
+                       }
+       |       INT_KEYWORD
+                       { $$ = builtin_type_int; }
+       |       LONG
+                       { $$ = builtin_type_long; }
+       |       SHORT
+                       { $$ = builtin_type_short; }
+       |       LONG INT_KEYWORD
+                       { $$ = builtin_type_long; }
+       |       UNSIGNED LONG INT_KEYWORD
+                       { $$ = builtin_type_unsigned_long; }
+       |       LONG LONG
+                       { $$ = builtin_type_long_long; }
+       |       LONG LONG INT_KEYWORD
+                       { $$ = builtin_type_long_long; }
+       |       UNSIGNED LONG LONG
+                       { $$ = builtin_type_unsigned_long_long; }
+       |       UNSIGNED LONG LONG INT_KEYWORD
+                       { $$ = builtin_type_unsigned_long_long; }
+       |       SHORT INT_KEYWORD
+                       { $$ = builtin_type_short; }
+       |       UNSIGNED SHORT INT_KEYWORD
+                       { $$ = builtin_type_unsigned_short; }
+       |       DOUBLE_KEYWORD
+                       { $$ = builtin_type_double; }
+       |       LONG DOUBLE_KEYWORD
+                       { $$ = builtin_type_long_double; }
+       |       STRUCT name
+                       { $$ = lookup_struct (copy_name ($2),
+                                             expression_context_block); }
+       |       CLASS name
+                       { $$ = lookup_struct (copy_name ($2),
+                                             expression_context_block); }
+       |       UNION name
+                       { $$ = lookup_union (copy_name ($2),
+                                            expression_context_block); }
+       |       ENUM name
+                       { $$ = lookup_enum (copy_name ($2),
+                                           expression_context_block); }
+       |       UNSIGNED typename
+                       { $$ = lookup_unsigned_typename (TYPE_NAME($2.type)); }
+       |       UNSIGNED
+                       { $$ = builtin_type_unsigned_int; }
+       |       SIGNED_KEYWORD typename
+                       { $$ = lookup_signed_typename (TYPE_NAME($2.type)); }
+       |       SIGNED_KEYWORD
+                       { $$ = builtin_type_int; }
+       |       TEMPLATE name '<' type '>'
+                       { $$ = lookup_template_type(copy_name($2), $4,
+                                                   expression_context_block);
+                       }
+       /* "const" and "volatile" are curently ignored.  A type
+          qualifier after the type is handled in the ptype rule.  I
+          think these could be too.  */
+       |       CONST_KEYWORD typebase { $$ = $2; }
+       |       VOLATILE_KEYWORD typebase { $$ = $2; }
+       ;
+
+typename:      TYPENAME
+       |       INT_KEYWORD
+               {
+                 $$.stoken.ptr = "int";
+                 $$.stoken.length = 3;
+                 $$.type = builtin_type_int;
+               }
+       |       LONG
+               {
+                 $$.stoken.ptr = "long";
+                 $$.stoken.length = 4;
+                 $$.type = builtin_type_long;
+               }
+       |       SHORT
+               {
+                 $$.stoken.ptr = "short";
+                 $$.stoken.length = 5;
+                 $$.type = builtin_type_short;
+               }
+       ;
+
+nonempty_typelist
+       :       type
+               { $$ = (struct type **) malloc (sizeof (struct type *) * 2);
+                 $<ivec>$[0] = 1;      /* Number of types in vector.  */
+                 $$[1] = $1;
+               }
+       |       nonempty_typelist ',' type
+               { int len = sizeof (struct type *) * (++($<ivec>1[0]) + 1);
+                 $$ = (struct type **) realloc ((char *) $1, len);
+                 $$[$<ivec>$[0]] = $3;
+               }
+       ;
+
+name   :       NAME        { $$ = $1.stoken; }
+       |       BLOCKNAME   { $$ = $1.stoken; }
+       |       TYPENAME    { $$ = $1.stoken; }
+       |       CLASSNAME   { $$ = $1.stoken; }
+       |       NAME_OR_INT { $$ = $1.stoken; }
+       ;
+
+name_not_typename :    NAME
+       |       BLOCKNAME
+/* These would be useful if name_not_typename was useful, but it is
+   just a fake for "variable", so these cause reduce/reduce conflicts
+   because the parser can't tell whether NAME_OR_INT is a
+   name_not_typename (=variable, =exp) or just an exp.  If
+   name_not_typename was ever used in an lvalue context where only a
+   name could occur, this might be useful.  */
+       | NAME_OR_INT */
+       ;
+
+%%
+
+/* Take care of parsing a number (anything that starts with a digit).
+   Set yylval and return the token type; update lexptr.  LEN is the
+   number of characters in it.  */
+
+/*** Needs some error checking for the float case.  ***/
+
+static int
+parse_number (p, len, parsed_float, putithere)
+     register char *p;
+     register int len;
+     int parsed_float;
+     YYSTYPE *putithere;
+{
+  /* FIXME: Shouldn't these be unsigned?  We don't deal with negative
+     values here, and we do kind of silly things like cast to
+     unsigned.  */
+  register LONGEST n = 0;
+  register LONGEST prevn = 0;
+  unsigned LONGEST un;
+
+  register int i = 0;
+  register int c;
+  register int base = input_radix;
+  int unsigned_p = 0;
+
+  /* Number of "L" suffixes encountered.  */
+  int long_p = 0;
+
+  /* We have found a "L" or "U" suffix.  */
+  int found_suffix = 0;
+
+  unsigned LONGEST high_bit;
+  struct type *signed_type;
+  struct type *unsigned_type;
+
+  if (parsed_float)
+    {
+      char c;
+
+      /* It's a float since it contains a point or an exponent.  */
+
+      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
+       sscanf (p, "%g", &putithere->typed_val_float.dval);
+      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
+       sscanf (p, "%lg", &putithere->typed_val_float.dval);
+      else
+       {
+#ifdef PRINTF_HAS_LONG_DOUBLE
+         sscanf (p, "%Lg", &putithere->typed_val_float.dval);
+#else
+         /* Scan it into a double, then assign it to the long double.
+            This at least wins with values representable in the range
+            of doubles.  */
+         double temp;
+         sscanf (p, "%lg", &temp);
+         putithere->typed_val_float.dval = temp;
+#endif
+       }
+
+      /* See if it has `f' or `l' suffix (float or long double).  */
+
+      c = tolower (p[len - 1]);
+
+      if (c == 'f')
+       putithere->typed_val_float.type = builtin_type_float;
+      else if (c == 'l')
+       putithere->typed_val_float.type = builtin_type_long_double;
+      else if (isdigit (c) || c == '.')
+       putithere->typed_val_float.type = builtin_type_double;
+      else
+       return ERROR;
+
+      return FLOAT;
+    }
+
+  /* Handle base-switching prefixes 0x, 0t, 0d, and 0.  */
+  if (p[0] == '0')
+    switch (p[1])
+      {
+      case 'x':
+      case 'X':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 16;
+           len -= 2;
+         }
+       break;
+
+      case 't':
+      case 'T':
+      case 'd':
+      case 'D':
+       if (len >= 3)
+         {
+           p += 2;
+           base = 10;
+           len -= 2;
+         }
+       break;
+
+      default:
+       base = 8;
+       break;
+      }
+
+  while (len-- > 0)
+    {
+      c = *p++;
+      if (c >= 'A' && c <= 'Z')
+       c += 'a' - 'A';
+      if (c != 'l' && c != 'u')
+       n *= base;
+      if (c >= '0' && c <= '9')
+       {
+         if (found_suffix)
+           return ERROR;
+         n += i = c - '0';
+       }
+      else
+       {
+         if (base > 10 && c >= 'a' && c <= 'f')
+           {
+             if (found_suffix)
+               return ERROR;
+             n += i = c - 'a' + 10;
+           }
+         else if (c == 'l')
+           {
+             ++long_p;
+             found_suffix = 1;
+           }
+         else if (c == 'u')
+           {
+             unsigned_p = 1;
+             found_suffix = 1;
+           }
+         else
+           return ERROR;       /* Char not a digit.  */
+       }
+      if (i >= base)
+       return ERROR;           /* Invalid digit in this base.  */
+
+      /* Portably test for overflow (only works for nonzero values, so
+        make a second check for zero).  FIXME: Can't we just make n
+        and prevn unsigned and avoid this?  */
+      if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
+       unsigned_p = 1;         /* Try something unsigned.  */
+
+      /* Portably test for unsigned overflow.
+        FIXME: This check is wrong; for example it doesn't find 
+        overflow on 0x123456789 when LONGEST is 32 bits.  */
+      if (c != 'l' && c != 'u' && n != 0)
+       {       
+         if ((unsigned_p && (unsigned LONGEST) prevn >= (unsigned LONGEST) n))
+           error ("Numeric constant too large.");
+       }
+      prevn = n;
+    }
+
+  /* An integer constant is an int, a long, or a long long.  An L
+     suffix forces it to be long; an LL suffix forces it to be long
+     long.  If not forced to a larger size, it gets the first type of
+     the above that it fits in.  To figure out whether it fits, we
+     shift it right and see whether anything remains.  Note that we
+     can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
+     operation, because many compilers will warn about such a shift
+     (which always produces a zero result).  Sometimes TARGET_INT_BIT
+     or TARGET_LONG_BIT will be that big, sometimes not.  To deal with
+     the case where it is we just always shift the value more than
+     once, with fewer bits each time.  */
+
+  un = (unsigned LONGEST)n >> 2;
+  if (long_p == 0
+      && (un >> (TARGET_INT_BIT - 2)) == 0)
+    {
+      high_bit = ((unsigned LONGEST)1) << (TARGET_INT_BIT-1);
+
+      /* A large decimal (not hex or octal) constant (between INT_MAX
+        and UINT_MAX) is a long or unsigned long, according to ANSI,
+        never an unsigned int, but this code treats it as unsigned
+        int.  This probably should be fixed.  GCC gives a warning on
+        such constants.  */
+
+      unsigned_type = builtin_type_unsigned_int;
+      signed_type = builtin_type_int;
+    }
+  else if (long_p <= 1
+          && (un >> (TARGET_LONG_BIT - 2)) == 0)
+    {
+      high_bit = ((unsigned LONGEST)1) << (TARGET_LONG_BIT-1);
+      unsigned_type = builtin_type_unsigned_long;
+      signed_type = builtin_type_long;
+    }
+  else
+    {
+      high_bit = (((unsigned LONGEST)1)
+                 << (TARGET_LONG_LONG_BIT - 32 - 1)
+                 << 16
+                 << 16);
+      if (high_bit == 0)
+       /* A long long does not fit in a LONGEST.  */
+       high_bit =
+         (unsigned LONGEST)1 << (sizeof (LONGEST) * HOST_CHAR_BIT - 1);
+      unsigned_type = builtin_type_unsigned_long_long;
+      signed_type = builtin_type_long_long;
+    }
+
+   putithere->typed_val_int.val = n;
+
+   /* If the high bit of the worked out type is set then this number
+      has to be unsigned.  */
+
+   if (unsigned_p || (n & high_bit)) 
+     {
+       putithere->typed_val_int.type = unsigned_type;
+     }
+   else 
+     {
+       putithere->typed_val_int.type = signed_type;
+     }
+
+   return INT;
+}
+
+struct token
+{
+  char *operator;
+  int token;
+  enum exp_opcode opcode;
+};
+
+static const struct token tokentab3[] =
+  {
+    {">>=", ASSIGN_MODIFY, BINOP_RSH},
+    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
+  };
+
+static const struct token tokentab2[] =
+  {
+    {"+=", ASSIGN_MODIFY, BINOP_ADD},
+    {"-=", ASSIGN_MODIFY, BINOP_SUB},
+    {"*=", ASSIGN_MODIFY, BINOP_MUL},
+    {"/=", ASSIGN_MODIFY, BINOP_DIV},
+    {"%=", ASSIGN_MODIFY, BINOP_REM},
+    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
+    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
+    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
+    {"++", INCREMENT, BINOP_END},
+    {"--", DECREMENT, BINOP_END},
+    {"->", ARROW, BINOP_END},
+    {"&&", ANDAND, BINOP_END},
+    {"||", OROR, BINOP_END},
+    {"::", COLONCOLON, BINOP_END},
+    {"<<", LSH, BINOP_END},
+    {">>", RSH, BINOP_END},
+    {"==", EQUAL, BINOP_END},
+    {"!=", NOTEQUAL, BINOP_END},
+    {"<=", LEQ, BINOP_END},
+    {">=", GEQ, BINOP_END}
+  };
+
+/* Read one token, getting characters through lexptr.  */
+
+static int
+yylex ()
+{
+  int c, tokchr;
+  int namelen;
+  unsigned int i;
+  char *tokstart;
+  char *tokptr;
+  int tempbufindex;
+  static char *tempbuf;
+  static int tempbufsize;
+  
+ retry:
+
+  tokstart = lexptr;
+  /* See if it is a special token of length 3.  */
+  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
+    if (STREQN (tokstart, tokentab3[i].operator, 3))
+      {
+       lexptr += 3;
+       yylval.opcode = tokentab3[i].opcode;
+       return tokentab3[i].token;
+      }
+
+  /* See if it is a special token of length 2.  */
+  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
+    if (STREQN (tokstart, tokentab2[i].operator, 2))
+      {
+       lexptr += 2;
+       yylval.opcode = tokentab2[i].opcode;
+       return tokentab2[i].token;
+      }
+
+  switch (tokchr = *tokstart)
+    {
+    case 0:
+      return 0;
+
+    case ' ':
+    case '\t':
+    case '\n':
+      lexptr++;
+      goto retry;
+
+    case '\'':
+      /* We either have a character constant ('0' or '\177' for
+        example) or we have a quoted symbol reference ('foo(int,int)'
+        in C++ for example).  */
+      lexptr++;
+      c = *lexptr++;
+      if (c == '\\')
+       c = parse_escape (&lexptr);
+      else if (c == '\'')
+       error ("Empty character constant.");
+
+      yylval.typed_val_int.val = c;
+      yylval.typed_val_int.type = builtin_type_char;
+
+      c = *lexptr++;
+      if (c != '\'')
+       {
+         namelen = skip_quoted (tokstart, 
+                                get_gdb_completer_word_break_characters())
+           - tokstart;
+         if (namelen > 2)
+           {
+             lexptr = tokstart + namelen;
+             if (lexptr[-1] != '\'')
+               error ("Unmatched single quote.");
+             namelen -= 2;
+             tokstart++;
+             goto tryname;
+           }
+         error ("Invalid character constant.");
+       }
+      return INT;
+
+    case '(':
+      paren_depth++;
+      lexptr++;
+      return '(';
+
+    case ')':
+      if (paren_depth == 0)
+       return 0;
+      paren_depth--;
+      lexptr++;
+      return ')';
+
+    case ',':
+      if (comma_terminates && paren_depth == 0)
+       return 0;
+      lexptr++;
+      return ',';
+
+    case '.':
+      /* Might be a floating point number.  */
+      if (lexptr[1] < '0' || lexptr[1] > '9')
+       goto symbol;            /* Nope, must be a symbol.  */
+      /* FALL THRU into number case.  */
+
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      {
+       /* It's a number.  */
+       int got_dot = 0, got_e = 0, toktype = FLOAT;
+       /* Initialize toktype to anything other than ERROR.  */
+       register char *p = tokstart;
+       int hex = input_radix > 10;
+       int local_radix = input_radix;
+       if (tokchr == '0' && (p[1] == 'x' || p[1] == 'X'))
+         {
+           p += 2;
+           hex = 1;
+           local_radix = 16;
+         }
+       else if (tokchr == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
+         {
+           p += 2;
+           hex = 0;
+           local_radix = 10;
+         }
+
+       for (;; ++p)
+         {
+           /* This test includes !hex because 'e' is a valid hex digit
+              and thus does not indicate a floating point number when
+              the radix is hex.  */
+
+           if (!hex && (*p == 'e' || *p == 'E'))
+             if (got_e)
+               toktype = ERROR;        /* Only one 'e' in a float.  */
+             else
+               got_e = 1;
+           /* This test does not include !hex, because a '.' always
+              indicates a decimal floating point number regardless of
+              the radix.  */
+           else if (*p == '.')
+             if (got_dot)
+               toktype = ERROR;        /* Only one '.' in a float.  */
+             else
+               got_dot = 1;
+           else if (got_e && (p[-1] == 'e' || p[-1] == 'E') &&
+                   (*p == '-' || *p == '+'))
+             /* This is the sign of the exponent, not the end of the
+                number.  */
+             continue;
+           /* Always take decimal digits; parse_number handles radix
+               error.  */
+           else if (*p >= '0' && *p <= '9')
+             continue;
+           /* We will take letters only if hex is true, and only up
+              to what the input radix would permit.  FSF was content
+              to rely on parse_number to validate; but it leaks.  */
+           else if (*p >= 'a' && *p <= 'z') 
+             {
+               if (!hex || *p >= ('a' + local_radix - 10))
+                 toktype = ERROR;
+             }
+           else if (*p >= 'A' && *p <= 'Z') 
+             {
+               if (!hex || *p >= ('A' + local_radix - 10))
+                 toktype = ERROR;
+             }
+           else break;
+         }
+       if (toktype != ERROR)
+         toktype = parse_number (tokstart, p - tokstart, 
+                                 got_dot | got_e, &yylval);
+        if (toktype == ERROR)
+         {
+           char *err_copy = (char *) alloca (p - tokstart + 1);
+
+           memcpy (err_copy, tokstart, p - tokstart);
+           err_copy[p - tokstart] = 0;
+           error ("Invalid number \"%s\".", err_copy);
+         }
+       lexptr = p;
+       return toktype;
+      }
+
+    case '+':
+    case '-':
+    case '*':
+    case '/':
+    case '%':
+    case '|':
+    case '&':
+    case '^':
+    case '~':
+    case '!':
+#if 0
+    case '@':          /* Moved out below.  */
+#endif
+    case '<':
+    case '>':
+    case '[':
+    case ']':
+    case '?':
+    case ':':
+    case '=':
+    case '{':
+    case '}':
+    symbol:
+      lexptr++;
+      return tokchr;
+
+    case '@':
+      if (strncmp(tokstart, "@selector", 9) == 0)
+       {
+         tokptr = strchr(tokstart, '(');
+         if (tokptr == NULL)
+           {
+             error ("Missing '(' in @selector(...)");
+           }
+         tempbufindex = 0;
+         tokptr++;     /* Skip the '('.  */
+         do {
+           /* Grow the static temp buffer if necessary, including
+              allocating the first one on demand.  */
+           if (tempbufindex + 1 >= tempbufsize)
+             {
+               tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+             }
+           tempbuf[tempbufindex++] = *tokptr++;
+         } while ((*tokptr != ')') && (*tokptr != '\0'));
+         if (*tokptr++ != ')')
+           {
+             error ("Missing ')' in @selector(...)");
+           }
+         tempbuf[tempbufindex] = '\0';
+         yylval.sval.ptr = tempbuf;
+         yylval.sval.length = tempbufindex;
+         lexptr = tokptr;
+         return SELECTOR;
+       }
+      if (tokstart[1] != '"')
+        {
+          lexptr++;
+          return tokchr;
+        }
+      /* ObjC NextStep NSString constant: fall thru and parse like
+         STRING.  */
+      tokstart++;
+
+    case '"':
+
+      /* Build the gdb internal form of the input string in tempbuf,
+        translating any standard C escape forms seen.  Note that the
+        buffer is null byte terminated *only* for the convenience of
+        debugging gdb itself and printing the buffer contents when
+        the buffer contains no embedded nulls.  Gdb does not depend
+        upon the buffer being null byte terminated, it uses the
+        length string instead.  This allows gdb to handle C strings
+        (as well as strings in other languages) with embedded null
+        bytes.  */
+
+      tokptr = ++tokstart;
+      tempbufindex = 0;
+
+      do {
+       /* Grow the static temp buffer if necessary, including
+          allocating the first one on demand.  */
+       if (tempbufindex + 1 >= tempbufsize)
+         {
+           tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
+         }
+       switch (*tokptr)
+         {
+         case '\0':
+         case '"':
+           /* Do nothing, loop will terminate.  */
+           break;
+         case '\\':
+           tokptr++;
+           c = parse_escape (&tokptr);
+           if (c == -1)
+             {
+               continue;
+             }
+           tempbuf[tempbufindex++] = c;
+           break;
+         default:
+           tempbuf[tempbufindex++] = *tokptr++;
+           break;
+         }
+      } while ((*tokptr != '"') && (*tokptr != '\0'));
+      if (*tokptr++ != '"')
+       {
+         error ("Unterminated string in expression.");
+       }
+      tempbuf[tempbufindex] = '\0';    /* See note above.  */
+      yylval.sval.ptr = tempbuf;
+      yylval.sval.length = tempbufindex;
+      lexptr = tokptr;
+      return (tokchr == '@' ? NSSTRING : STRING);
+    }
+
+  if (!(tokchr == '_' || tokchr == '$' || 
+       (tokchr >= 'a' && tokchr <= 'z') || (tokchr >= 'A' && tokchr <= 'Z')))
+    /* We must have come across a bad character (e.g. ';').  */
+    error ("Invalid character '%c' in expression.", c);
+
+  /* It's a name.  See how long it is.  */
+  namelen = 0;
+  for (c = tokstart[namelen];
+       (c == '_' || c == '$' || (c >= '0' && c <= '9')
+       || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
+    {
+       if (c == '<')
+        {
+          int i = namelen;
+          while (tokstart[++i] && tokstart[i] != '>');
+          if (tokstart[i] == '>')
+            namelen = i;
+         }
+       c = tokstart[++namelen];
+     }
+
+  /* The token "if" terminates the expression and is NOT 
+     removed from the input stream.  */
+  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
+    {
+      return 0;
+    }
+
+  lexptr += namelen;
+
+  tryname:
+
+  /* Catch specific keywords.  Should be done with a data structure.  */
+  switch (namelen)
+    {
+    case 8:
+      if (STREQN (tokstart, "unsigned", 8))
+       return UNSIGNED;
+      if (current_language->la_language == language_cplus
+         && STREQN (tokstart, "template", 8))
+       return TEMPLATE;
+      if (STREQN (tokstart, "volatile", 8))
+       return VOLATILE_KEYWORD;
+      break;
+    case 6:
+      if (STREQN (tokstart, "struct", 6))
+       return STRUCT;
+      if (STREQN (tokstart, "signed", 6))
+       return SIGNED_KEYWORD;
+      if (STREQN (tokstart, "sizeof", 6))      
+       return SIZEOF;
+      if (STREQN (tokstart, "double", 6))      
+       return DOUBLE_KEYWORD;
+      break;
+    case 5:
+      if ((current_language->la_language == language_cplus)
+         && STREQN (tokstart, "class", 5))
+       return CLASS;
+      if (STREQN (tokstart, "union", 5))
+       return UNION;
+      if (STREQN (tokstart, "short", 5))
+       return SHORT;
+      if (STREQN (tokstart, "const", 5))
+       return CONST_KEYWORD;
+      break;
+    case 4:
+      if (STREQN (tokstart, "enum", 4))
+       return ENUM;
+      if (STREQN (tokstart, "long", 4))
+       return LONG;
+      if (current_language->la_language == language_cplus
+         && STREQN (tokstart, "this", 4))
+       {
+         static const char this_name[] = {
+           CPLUS_MARKER, 't', 'h', 'i', 's', '\0' 
+         };
+
+         if (lookup_symbol (this_name, expression_context_block,
+                            VAR_NAMESPACE, (int *) NULL,
+                            (struct symtab **) NULL))
+           return THIS;
+       }
+      break;
+    case 3:
+      if (STREQN (tokstart, "int", 3))
+       return INT_KEYWORD;
+      break;
+    default:
+      break;
+    }
+
+  yylval.sval.ptr = tokstart;
+  yylval.sval.length = namelen;
+
+  if (*tokstart == '$')
+    {
+      write_dollar_variable (yylval.sval);
+      return VARIABLE;
+    }
+
+  /* Use token-type BLOCKNAME for symbols that happen to be defined as
+     functions or symtabs.  If this is not so, then ...
+     Use token-type TYPENAME for symbols that happen to be defined
+     currently as names of types; NAME for other symbols.
+     The caller is not constrained to care about the distinction.  */
+  {
+    char *tmp = copy_name (yylval.sval);
+    struct symbol *sym;
+    int is_a_field_of_this = 0, *need_this;
+    int hextype;
+
+    if (current_language->la_language == language_cplus ||
+       current_language->la_language == language_objc)
+      need_this = &is_a_field_of_this;
+    else
+      need_this = (int *) NULL;
+
+    sym = lookup_symbol (tmp, expression_context_block,
+                        VAR_NAMESPACE,
+                        need_this,
+                        (struct symtab **) NULL);
+    /* Call lookup_symtab, not lookup_partial_symtab, in case there
+       are no psymtabs (coff, xcoff, or some future change to blow
+       away the psymtabs once symbols are read).  */
+    if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
+        lookup_symtab (tmp))
+      {
+       yylval.ssym.sym = sym;
+       yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+       return BLOCKNAME;
+      }
+    if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+        {
+#if 1
+         /* Despite the following flaw, we need to keep this code
+            enabled.  Because we can get called from
+            check_stub_method, if we don't handle nested types then
+            it screws many operations in any program which uses
+            nested types.  */
+         /* In "A::x", if x is a member function of A and there
+            happens to be a type (nested or not, since the stabs
+            don't make that distinction) named x, then this code
+            incorrectly thinks we are dealing with nested types
+            rather than a member function.  */
+
+         char *p;
+         char *namestart;
+         struct symbol *best_sym;
+
+         /* Look ahead to detect nested types.  This probably should
+            be done in the grammar, but trying seemed to introduce a
+            lot of shift/reduce and reduce/reduce conflicts.  It's
+            possible that it could be done, though.  Or perhaps a
+            non-grammar, but less ad hoc, approach would work well.  */
+
+         /* Since we do not currently have any way of distinguishing
+            a nested type from a non-nested one (the stabs don't tell
+            us whether a type is nested), we just ignore the
+            containing type.  */
+
+         p = lexptr;
+         best_sym = sym;
+         while (1)
+           {
+             /* Skip whitespace.  */
+             while (*p == ' ' || *p == '\t' || *p == '\n')
+               ++p;
+             if (*p == ':' && p[1] == ':')
+               {
+                 /* Skip the `::'.  */
+                 p += 2;
+                 /* Skip whitespace.  */
+                 while (*p == ' ' || *p == '\t' || *p == '\n')
+                   ++p;
+                 namestart = p;
+                 while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
+                        || (*p >= 'a' && *p <= 'z')
+                        || (*p >= 'A' && *p <= 'Z'))
+                   ++p;
+                 if (p != namestart)
+                   {
+                     struct symbol *cur_sym;
+                     /* As big as the whole rest of the expression,
+                        which is at least big enough.  */
+                     char *ncopy = alloca (strlen (tmp) +
+                                           strlen (namestart) + 3);
+                     char *tmp1;
+
+                     tmp1 = ncopy;
+                     memcpy (tmp1, tmp, strlen (tmp));
+                     tmp1 += strlen (tmp);
+                     memcpy (tmp1, "::", 2);
+                     tmp1 += 2;
+                     memcpy (tmp1, namestart, p - namestart);
+                     tmp1[p - namestart] = '\0';
+                     cur_sym = lookup_symbol (ncopy, 
+                                              expression_context_block,
+                                              VAR_NAMESPACE, (int *) NULL,
+                                              (struct symtab **) NULL);
+                     if (cur_sym)
+                       {
+                         if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
+                           {
+                             best_sym = cur_sym;
+                             lexptr = p;
+                           }
+                         else
+                           break;
+                       }
+                     else
+                       break;
+                   }
+                 else
+                   break;
+               }
+             else
+               break;
+           }
+
+         yylval.tsym.type = SYMBOL_TYPE (best_sym);
+#else /* not 0 */
+         yylval.tsym.type = SYMBOL_TYPE (sym);
+#endif /* not 0 */
+         return TYPENAME;
+        }
+    if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
+       return TYPENAME;
+
+    /* See if it's an ObjC classname.  */
+    if (!sym)
+      {
+       CORE_ADDR Class = lookup_objc_class(tmp);
+       if (Class)
+         {
+           extern struct symbol *lookup_struct_typedef();
+           yylval.class.class = Class;
+           if ((sym = lookup_struct_typedef (tmp, 
+                                             expression_context_block, 
+                                             1)))
+             yylval.class.type = SYMBOL_TYPE (sym);
+           return CLASSNAME;
+         }
+      }
+
+    /* Input names that aren't symbols but ARE valid hex numbers,
+       when the input radix permits them, can be names or numbers
+       depending on the parse.  Note we support radixes > 16 here.  */
+    if (!sym && 
+        ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
+         (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
+      {
+       YYSTYPE newlval;        /* Its value is ignored.  */
+       hextype = parse_number (tokstart, namelen, 0, &newlval);
+       if (hextype == INT)
+         {
+           yylval.ssym.sym = sym;
+           yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+           return NAME_OR_INT;
+         }
+      }
+
+    /* Any other kind of symbol.  */
+    yylval.ssym.sym = sym;
+    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
+    return NAME;
+  }
+}
+
+void
+yyerror (msg)
+     char *msg;
+{
+  if (*lexptr == '\0')
+    error("A %s near end of expression.",  (msg ? msg : "error"));
+  else
+    error ("A %s in expression, near `%s'.", (msg ? msg : "error"), 
+          lexptr);
+}
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
new file mode 100644 (file)
index 0000000..dc83951
--- /dev/null
@@ -0,0 +1,1960 @@
+/* Objective-C language support routines for GDB, the GNU debugger.
+
+   Copyright 2002 Free Software Foundation, Inc.
+
+   Contributed by Apple Computer, Inc.
+   Written by Michael Snyder.
+
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "symtab.h"
+#include "gdbtypes.h"
+#include "expression.h"
+#include "parser-defs.h"
+#include "language.h"
+#include "c-lang.h"
+#include "objc-lang.h"
+#include "complaints.h"
+#include "value.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "string.h"            /* for strchr */
+#include "target.h"            /* for target_has_execution */
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "frame.h"
+#include "gdb_regex.h"
+#include "regcache.h"
+
+#include <ctype.h>
+
+struct objc_object {
+  CORE_ADDR isa;
+};
+
+struct objc_class {
+  CORE_ADDR isa; 
+  CORE_ADDR super_class; 
+  CORE_ADDR name;               
+  long version;
+  long info;
+  long instance_size;
+  CORE_ADDR ivars;
+  CORE_ADDR methods;
+  CORE_ADDR cache;
+  CORE_ADDR protocols;
+};
+
+struct objc_super {
+  CORE_ADDR receiver;
+  CORE_ADDR class;
+};
+
+struct objc_method {
+  CORE_ADDR name;
+  CORE_ADDR types;
+  CORE_ADDR imp;
+};
+
+/* Complaints about ObjC classes, selectors, etc.  */
+
+static struct complaint noclass_lookup_complaint = {
+  "no way to lookup Objective-C classes", 0, 0
+};
+
+static struct complaint nosel_lookup_complaint = {
+  "no way to lookup Objective-C selectors", 0, 0
+};
+
+
+#if (!defined __GNUC__ || __GNUC__ < 2 || __GNUC_MINOR__ < (defined __cplusplus ? 6 : 4))
+#define __CHECK_FUNCTION ((__const char *) 0)
+#else
+#define __CHECK_FUNCTION __PRETTY_FUNCTION__
+#endif
+
+#define CHECK(expression) \
+  ((void) ((expression) ? 0 : gdb_check (#expression, __FILE__, __LINE__, \
+                                         __CHECK_FUNCTION)))
+
+#define CHECK_FATAL(expression) \
+  ((void) ((expression) ? 0 : gdb_check_fatal (#expression, __FILE__, \
+                              __LINE__, __CHECK_FUNCTION)))
+
+static void 
+gdb_check (const char *str, const char *file, 
+          unsigned int line, const char *func)
+{
+  error ("assertion failure on line %u of \"%s\" in function \"%s\": %s\n",
+        line, file, func, str);
+}
+
+static void 
+gdb_check_fatal (const char *str, const char *file, 
+                unsigned int line, const char *func)
+{
+  internal_error (file, line, 
+                 "assertion failure in function \"%s\": %s\n", func, str);
+}
+
+/* Lookup a structure type named "struct NAME", visible in lexical
+   block BLOCK.  If NOERR is nonzero, return zero if NAME is not
+   suitably defined.  */
+
+struct symbol *
+lookup_struct_typedef (char *name, struct block *block, int noerr)
+{
+  register struct symbol *sym;
+
+  sym = lookup_symbol (name, block, STRUCT_NAMESPACE, 0, 
+                      (struct symtab **) NULL);
+
+  if (sym == NULL)
+    {
+      if (noerr)
+       return 0;
+      else 
+       error ("No struct type named %s.", name);
+    }
+  if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
+    {
+      if (noerr)
+       return 0;
+      else
+       error ("This context has class, union or enum %s, not a struct.", 
+              name);
+    }
+  return sym;
+}
+
+CORE_ADDR 
+lookup_objc_class (char *classname)
+{
+  struct value * function, *classval;
+
+  if (! target_has_execution)
+    {
+      /* Can't call into inferior to lookup class.  */
+      return 0;
+    }
+
+  if (lookup_minimal_symbol("objc_lookUpClass", 0, 0))
+    function = find_function_in_inferior("objc_lookUpClass");
+  else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0))
+    function = find_function_in_inferior("objc_lookup_class");
+  else
+    {
+      complain (&noclass_lookup_complaint, 0);
+      return 0;
+    }
+
+  classval = value_string (classname, strlen (classname) + 1);
+  classval = value_coerce_array (classval);
+  return (CORE_ADDR) value_as_long (call_function_by_hand (function, 
+                                                          1, &classval));
+}
+
+int
+lookup_child_selector (char *selname)
+{
+  struct value * function, *selstring;
+
+  if (! target_has_execution)
+    {
+      /* Can't call into inferior to lookup selector.  */
+      return 0;
+    }
+
+  if (lookup_minimal_symbol("sel_getUid", 0, 0))
+    function = find_function_in_inferior("sel_getUid");
+  else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0))
+    function = find_function_in_inferior("sel_get_any_uid");
+  else
+    {
+      complain (&nosel_lookup_complaint, 0);
+      return 0;
+    }
+
+  selstring = value_coerce_array (value_string (selname, 
+                                               strlen (selname) + 1));
+  return value_as_long (call_function_by_hand (function, 1, &selstring));
+}
+
+struct value * 
+value_nsstring (char *ptr, int len)
+{
+  struct value *stringValue[3];
+  struct value *function, *nsstringValue;
+  struct symbol *sym;
+  struct type *type;
+
+  if (!target_has_execution)
+    return 0;          /* Can't call into inferior to create NSString.  */
+
+  if (!(sym = lookup_struct_typedef("NSString", 0, 1)) &&
+      !(sym = lookup_struct_typedef("NXString", 0, 1)))
+    type = lookup_pointer_type(builtin_type_void);
+  else
+    type = lookup_pointer_type(SYMBOL_TYPE (sym));
+
+  stringValue[2] = value_string(ptr, len);
+  stringValue[2] = value_coerce_array(stringValue[2]);
+  /* _NSNewStringFromCString replaces "istr" after Lantern2A.  */
+  if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0))
+    {
+      function = find_function_in_inferior("_NSNewStringFromCString");
+      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
+    }
+  else if (lookup_minimal_symbol("istr", 0, 0))
+    {
+      function = find_function_in_inferior("istr");
+      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
+    }
+  else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0))
+    {
+      function = find_function_in_inferior("+[NSString stringWithCString:]");
+      stringValue[0] = value_from_longest 
+       (builtin_type_long, lookup_objc_class ("NSString"));
+      stringValue[1] = value_from_longest 
+       (builtin_type_long, lookup_child_selector ("stringWithCString:"));
+      nsstringValue = call_function_by_hand(function, 3, &stringValue[0]);
+    }
+  else
+    error ("NSString: internal error -- no way to create new NSString");
+
+  VALUE_TYPE(nsstringValue) = type;
+  return nsstringValue;
+}
+
+/* Objective-C name demangling.  */
+
+char *
+objc_demangle (const char *mangled)
+{
+  char *demangled, *cp;
+
+  if (mangled[0] == '_' &&
+     (mangled[1] == 'i' || mangled[1] == 'c') &&
+      mangled[2] == '_')
+    {
+      cp = demangled = xmalloc(strlen(mangled) + 2);
+
+      if (mangled[1] == 'i')
+       *cp++ = '-';            /* for instance method */
+      else
+       *cp++ = '+';            /* for class    method */
+
+      *cp++ = '[';             /* opening left brace  */
+      strcpy(cp, mangled+3);   /* tack on the rest of the mangled name */
+
+      while (*cp && *cp == '_')
+       cp++;                   /* skip any initial underbars in class name */
+
+      if (!(cp = strchr(cp, '_')))     /* find first non-initial underbar */
+       {
+         free(demangled);      /* not mangled name */
+         return NULL;
+       }
+      if (cp[1] == '_') {      /* easy case: no category name     */
+       *cp++ = ' ';            /* replace two '_' with one ' '    */
+       strcpy(cp, mangled + (cp - demangled) + 2);
+      }
+      else {
+       *cp++ = '(';            /* less easy case: category name */
+       if (!(cp = strchr(cp, '_')))
+         {
+           free(demangled);    /* not mangled name */
+           return NULL;
+         }
+       *cp++ = ')';
+       *cp++ = ' ';            /* overwriting 1st char of method name...  */
+       strcpy(cp, mangled + (cp - demangled)); /* get it back */
+      }
+
+      while (*cp && *cp == '_')
+       cp++;                   /* skip any initial underbars in method name */
+
+      for (; *cp; cp++)
+       if (*cp == '_')
+         *cp = ':';            /* replace remaining '_' with ':' */
+
+      *cp++ = ']';             /* closing right brace */
+      *cp++ = 0;               /* string terminator */
+      return demangled;
+    }
+  else
+    return NULL;       /* Not an objc mangled name.  */
+}
+
+/* Print the character C on STREAM as part of the contents of a
+   literal string whose delimiter is QUOTER.  Note that that format
+   for printing characters and strings is language specific.  */
+
+static void
+objc_emit_char (register int c, struct ui_file *stream, int quoter)
+{
+
+  c &= 0xFF;                   /* Avoid sign bit follies.  */
+
+  if (PRINT_LITERAL_FORM (c))
+    {
+      if (c == '\\' || c == quoter)
+       {
+         fputs_filtered ("\\", stream);
+       }
+      fprintf_filtered (stream, "%c", c);
+    }
+  else
+    {
+      switch (c)
+       {
+       case '\n':
+         fputs_filtered ("\\n", stream);
+         break;
+       case '\b':
+         fputs_filtered ("\\b", stream);
+         break;
+       case '\t':
+         fputs_filtered ("\\t", stream);
+         break;
+       case '\f':
+         fputs_filtered ("\\f", stream);
+         break;
+       case '\r':
+         fputs_filtered ("\\r", stream);
+         break;
+       case '\033':
+         fputs_filtered ("\\e", stream);
+         break;
+       case '\007':
+         fputs_filtered ("\\a", stream);
+         break;
+       default:
+         fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+         break;
+       }
+    }
+}
+
+static void
+objc_printchar (int c, struct ui_file *stream)
+{
+  fputs_filtered ("'", stream);
+  objc_emit_char (c, stream, '\'');
+  fputs_filtered ("'", stream);
+}
+
+/* Print the character string STRING, printing at most LENGTH
+   characters.  Printing stops early if the number hits print_max;
+   repeat counts are printed as appropriate.  Print ellipses at the
+   end if we had to stop before printing LENGTH characters, or if
+   FORCE_ELLIPSES.  */
+
+static void
+objc_printstr (struct ui_file *stream, char *string, 
+              unsigned int length, int force_ellipses)
+{
+  register unsigned int i;
+  unsigned int things_printed = 0;
+  int in_quotes = 0;
+  int need_comma = 0;
+  extern int inspect_it;
+  extern int repeat_count_threshold;
+  extern int print_max;
+
+  /* If the string was not truncated due to `set print elements', and
+     the last byte of it is a null, we don't print that, in
+     traditional C style.  */
+  if ((!force_ellipses) && length > 0 && string[length-1] == '\0')
+    length--;
+
+  if (length == 0)
+    {
+      fputs_filtered ("\"\"", stream);
+      return;
+    }
+
+  for (i = 0; i < length && things_printed < print_max; ++i)
+    {
+      /* Position of the character we are examining to see whether it
+        is repeated.  */
+      unsigned int rep1;
+      /* Number of repetitions we have detected so far.  */
+      unsigned int reps;
+
+      QUIT;
+
+      if (need_comma)
+       {
+         fputs_filtered (", ", stream);
+         need_comma = 0;
+       }
+
+      rep1 = i + 1;
+      reps = 1;
+      while (rep1 < length && string[rep1] == string[i])
+       {
+         ++rep1;
+         ++reps;
+       }
+
+      if (reps > repeat_count_threshold)
+       {
+         if (in_quotes)
+           {
+             if (inspect_it)
+               fputs_filtered ("\\\", ", stream);
+             else
+               fputs_filtered ("\", ", stream);
+             in_quotes = 0;
+           }
+         objc_printchar (string[i], stream);
+         fprintf_filtered (stream, " <repeats %u times>", reps);
+         i = rep1 - 1;
+         things_printed += repeat_count_threshold;
+         need_comma = 1;
+       }
+      else
+       {
+         if (!in_quotes)
+           {
+             if (inspect_it)
+               fputs_filtered ("\\\"", stream);
+             else
+               fputs_filtered ("\"", stream);
+             in_quotes = 1;
+           }
+         objc_emit_char (string[i], stream, '"');
+         ++things_printed;
+       }
+    }
+
+  /* Terminate the quotes if necessary.  */
+  if (in_quotes)
+    {
+      if (inspect_it)
+       fputs_filtered ("\\\"", stream);
+      else
+       fputs_filtered ("\"", stream);
+    }
+
+  if (force_ellipses || i < length)
+    fputs_filtered ("...", stream);
+}
+
+/* Create a fundamental C type using default reasonable for the
+   current target.
+
+   Some object/debugging file formats (DWARF version 1, COFF, etc) do
+   not define fundamental types such as "int" or "double".  Others
+   (stabs or DWARF version 2, etc) do define fundamental types.  For
+   the formats which don't provide fundamental types, gdb can create
+   such types using this function.
+
+   FIXME: Some compilers distinguish explicitly signed integral types
+   (signed short, signed int, signed long) from "regular" integral
+   types (short, int, long) in the debugging information.  There is
+   some disagreement as to how useful this feature is.  In particular,
+   gcc does not support this.  Also, only some debugging formats allow
+   the distinction to be passed on to a debugger.  For now, we always
+   just use "short", "int", or "long" as the type name, for both the
+   implicit and explicitly signed types.  This also makes life easier
+   for the gdb test suite since we don't have to account for the
+   differences in output depending upon what the compiler and
+   debugging format support.  We will probably have to re-examine the
+   issue when gdb starts taking it's fundamental type information
+   directly from the debugging information supplied by the compiler.
+   fnf@cygnus.com */
+
+static struct type *
+objc_create_fundamental_type (struct objfile *objfile, int typeid)
+{
+  register struct type *type = NULL;
+
+  switch (typeid)
+    {
+      default:
+       /* FIXME: For now, if we are asked to produce a type not in
+          this language, create the equivalent of a C integer type
+          with the name "<?type?>".  When all the dust settles from
+          the type reconstruction work, this should probably become
+          an error.  */
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "<?type?>", objfile);
+        warning ("internal error: no C/C++ fundamental type %d", typeid);
+       break;
+      case FT_VOID:
+       type = init_type (TYPE_CODE_VOID,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "void", objfile);
+       break;
+      case FT_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "char", objfile);
+       break;
+      case FT_SIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         0, "signed char", objfile);
+       break;
+      case FT_UNSIGNED_CHAR:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_CHAR_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned char", objfile);
+       break;
+      case FT_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         0, "short", objfile);
+       break;
+      case FT_SIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         0, "short", objfile); /* FIXME-fnf */
+       break;
+      case FT_UNSIGNED_SHORT:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_SHORT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned short", objfile);
+       break;
+      case FT_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "int", objfile);
+       break;
+      case FT_SIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         0, "int", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_INTEGER:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_INT_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned int", objfile);
+       break;
+      case FT_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long", objfile);
+       break;
+      case FT_SIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long", objfile); /* FIXME -fnf */
+       break;
+      case FT_UNSIGNED_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long", objfile);
+       break;
+      case FT_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "long long", objfile);
+       break;
+      case FT_SIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         0, "signed long long", objfile);
+       break;
+      case FT_UNSIGNED_LONG_LONG:
+       type = init_type (TYPE_CODE_INT,
+                         TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+                         TYPE_FLAG_UNSIGNED, "unsigned long long", objfile);
+       break;
+      case FT_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
+                         0, "float", objfile);
+       break;
+      case FT_DBL_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "double", objfile);
+       break;
+      case FT_EXT_PREC_FLOAT:
+       type = init_type (TYPE_CODE_FLT,
+                         TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
+                         0, "long double", objfile);
+       break;
+      }
+  return (type);
+}
+
+
+/* Table mapping opcodes into strings for printing operators
+   and precedences of the operators.  */
+
+static const struct op_print objc_op_print_tab[] =
+  {
+    {",",  BINOP_COMMA, PREC_COMMA, 0},
+    {"=",  BINOP_ASSIGN, PREC_ASSIGN, 1},
+    {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
+    {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
+    {"|",  BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
+    {"^",  BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
+    {"&",  BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
+    {"==", BINOP_EQUAL, PREC_EQUAL, 0},
+    {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
+    {"<=", BINOP_LEQ, PREC_ORDER, 0},
+    {">=", BINOP_GEQ, PREC_ORDER, 0},
+    {">",  BINOP_GTR, PREC_ORDER, 0},
+    {"<",  BINOP_LESS, PREC_ORDER, 0},
+    {">>", BINOP_RSH, PREC_SHIFT, 0},
+    {"<<", BINOP_LSH, PREC_SHIFT, 0},
+    {"+",  BINOP_ADD, PREC_ADD, 0},
+    {"-",  BINOP_SUB, PREC_ADD, 0},
+    {"*",  BINOP_MUL, PREC_MUL, 0},
+    {"/",  BINOP_DIV, PREC_MUL, 0},
+    {"%",  BINOP_REM, PREC_MUL, 0},
+    {"@",  BINOP_REPEAT, PREC_REPEAT, 0},
+    {"-",  UNOP_NEG, PREC_PREFIX, 0},
+    {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
+    {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
+    {"*",  UNOP_IND, PREC_PREFIX, 0},
+    {"&",  UNOP_ADDR, PREC_PREFIX, 0},
+    {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
+    {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
+    {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
+    {NULL, 0, 0, 0}
+};
+
+struct type ** const (objc_builtin_types[]) = 
+{
+  &builtin_type_int,
+  &builtin_type_long,
+  &builtin_type_short,
+  &builtin_type_char,
+  &builtin_type_float,
+  &builtin_type_double,
+  &builtin_type_void,
+  &builtin_type_long_long,
+  &builtin_type_signed_char,
+  &builtin_type_unsigned_char,
+  &builtin_type_unsigned_short,
+  &builtin_type_unsigned_int,
+  &builtin_type_unsigned_long,
+  &builtin_type_unsigned_long_long,
+  &builtin_type_long_double,
+  &builtin_type_complex,
+  &builtin_type_double_complex,
+  0
+};
+
+const struct language_defn objc_language_defn = {
+  "objective-c",               /* Language name */
+  language_objc,
+  objc_builtin_types,
+  range_check_off,
+  type_check_off,
+  case_sensitive_on,
+  objc_parse,
+  objc_error,
+  evaluate_subexp_standard,
+  objc_printchar,              /* Print a character constant */
+  objc_printstr,               /* Function to print string constant */
+  objc_emit_char,
+  objc_create_fundamental_type,        /* Create fundamental type in this language */
+  c_print_type,                        /* Print a type using appropriate syntax */
+  c_val_print,                 /* Print a value using appropriate syntax */
+  c_value_print,               /* Print a top-level value */
+  {"",     "",    "",  ""},    /* Binary format info */
+  {"0%lo",  "0",   "o", ""},   /* Octal format info */
+  {"%ld",   "",    "d", ""},   /* Decimal format info */
+  {"0x%lx", "0x",  "x", ""},   /* Hex format info */
+  objc_op_print_tab,           /* Expression operators for printing */
+  1,                           /* C-style arrays */
+  0,                           /* String lower bound */
+  &builtin_type_char,          /* Type of string elements */
+  LANG_MAGIC
+};
+
+/*
+ * ObjC:
+ * Following functions help construct Objective-C message calls 
+ */
+
+struct selname         /* For parsing Objective-C.  */
+  {
+    struct selname *next;
+    char *msglist_sel;
+    int msglist_len;
+  };
+
+static int msglist_len;
+static struct selname *selname_chain;
+static char *msglist_sel;
+
+void
+start_msglist(void)
+{
+  register struct selname *new = 
+    (struct selname *) xmalloc (sizeof (struct selname));
+
+  new->next = selname_chain;
+  new->msglist_len = msglist_len;
+  new->msglist_sel = msglist_sel;
+  msglist_len = 0;
+  msglist_sel = (char *)xmalloc(1);
+  *msglist_sel = 0;
+  selname_chain = new;
+}
+
+void
+add_msglist(struct stoken *str, int addcolon)
+{
+  char *s, *p;
+  int len, plen;
+
+  if (str == 0) {              /* Unnamed arg, or...  */
+    if (addcolon == 0) {       /* variable number of args.  */
+      msglist_len++;
+      return;
+    }
+    p = "";
+    plen = 0;
+  } else {
+    p = str->ptr;
+    plen = str->length;
+  }
+  len = plen + strlen(msglist_sel) + 2;
+  s = (char *)xmalloc(len);
+  strcpy(s, msglist_sel);
+  strncat(s, p, plen);
+  free(msglist_sel);
+  msglist_sel = s;
+  if (addcolon) {
+    s[len-2] = ':';
+    s[len-1] = 0;
+    msglist_len++;
+  } else
+    s[len-2] = '\0';
+}
+
+int
+end_msglist(void)
+{
+  register int val = msglist_len;
+  register struct selname *sel = selname_chain;
+  register char *p = msglist_sel;
+  int selid;
+
+  selname_chain = sel->next;
+  msglist_len = sel->msglist_len;
+  msglist_sel = sel->msglist_sel;
+  selid = lookup_child_selector(p);
+  if (!selid)
+    error("Can't find selector \"%s\"", p);
+  write_exp_elt_longcst (selid);
+  free(p);
+  write_exp_elt_longcst (val); /* Number of args */
+  free(sel);
+
+  return val;
+}
+
+/*
+ * Function: specialcmp (char *a, char *b)
+ *
+ * Special strcmp: treats ']' and ' ' as end-of-string.
+ * Used for qsorting lists of objc methods (either by class or selector).
+ */
+
+int specialcmp(char *a, char *b)
+{
+  while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
+    {
+      if (*a != *b)
+       return *a - *b;
+      a++, b++;
+    }
+  if (*a && *a != ' ' && *a != ']')
+    return  1;         /* a is longer therefore greater */
+  if (*b && *b != ' ' && *b != ']')
+    return -1;         /* a is shorter therefore lesser */
+  return    0;         /* a and b are identical */
+}
+
+/*
+ * Function: compare_selectors (void *, void *)
+ *
+ * Comparison function for use with qsort.  Arguments are symbols or
+ * msymbols Compares selector part of objc method name alphabetically.
+ */
+
+static int
+compare_selectors (void *a, void *b)
+{
+  char *aname, *bname;
+
+  if ((aname = SYMBOL_SOURCE_NAME (*(struct symbol **) a)) == NULL ||
+      (bname = SYMBOL_SOURCE_NAME (*(struct symbol **) b)) == NULL)
+    error ("internal: compare_selectors(1)");
+
+  if ((aname = strchr(aname, ' ')) == NULL ||
+      (bname = strchr(bname, ' ')) == NULL)
+    error ("internal: compare_selectors(2)");
+
+  return specialcmp (aname+1, bname+1);
+}
+
+/*
+ * Function: selectors_info (regexp, from_tty)
+ *
+ * Implements the "Info selectors" command.  Takes an optional regexp
+ * arg.  Lists all objective c selectors that match the regexp.  Works
+ * by grepping thru all symbols for objective c methods.  Output list
+ * is sorted and uniqued. 
+ */
+
+static void
+selectors_info (char *regexp, int from_tty)
+{
+  struct objfile       *objfile;
+  struct minimal_symbol *msymbol;
+  char                  *name;
+  char                  *val;
+  int                    matches = 0;
+  int                    maxlen  = 0;
+  int                    ix;
+  char                   myregexp[2048];
+  char                   asel[256];
+  struct symbol        **sym_arr;
+  int                    plusminus = 0;
+
+  if (regexp == NULL)
+    strcpy(myregexp, ".*]");   /* Null input, match all objc methods.  */
+  else
+    {
+      if (*regexp == '+' || *regexp == '-')
+       { /* User wants only class methods or only instance methods.  */
+         plusminus = *regexp++;
+         while (*regexp == ' ' || *regexp == '\t')
+           regexp++;
+       }
+      if (*regexp == '\0')
+       strcpy(myregexp, ".*]");
+      else
+       {
+         strcpy(myregexp, regexp);
+         if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
+           myregexp[strlen(myregexp) - 1] = ']';    /* end of method name */
+         else
+           strcat(myregexp, ".*]");
+       }
+    }
+
+  if (regexp != NULL)
+    if (0 != (val = re_comp (myregexp)))
+      error ("Invalid regexp (%s): %s", val, regexp);
+
+  /* First time thru is JUST to get max length and count.  */
+  ALL_MSYMBOLS (objfile, msymbol)
+    {
+      QUIT;
+      if ((name = SYMBOL_DEMANGLED_NAME (msymbol)) == NULL)
+       name = SYMBOL_NAME (msymbol);
+      if (name &&
+        (name[0] == '-' || name[0] == '+') &&
+         name[1] == '[')               /* Got a method name.  */
+       {
+         /* Filter for class/instance methods.  */
+         if (plusminus && name[0] != plusminus)
+           continue;
+         /* Find selector part.  */
+         name = (char *) strchr(name+2, ' ');
+         if (regexp == NULL || re_exec(++name) != 0)
+           { 
+             char *mystart = name;
+             char *myend   = (char *) strchr(mystart, ']');
+             
+             if (myend && (myend - mystart > maxlen))
+               maxlen = myend - mystart;       /* Get longest selector.  */
+             matches++;
+           }
+       }
+    }
+  if (matches)
+    {
+      printf_filtered ("Selectors matching \"%s\":\n\n", 
+                      regexp ? regexp : "*");
+
+      sym_arr = alloca (matches * sizeof (struct symbol *));
+      matches = 0;
+      ALL_MSYMBOLS (objfile, msymbol)
+       {
+         QUIT;
+         if ((name = SYMBOL_DEMANGLED_NAME (msymbol)) == NULL)
+           name = SYMBOL_NAME (msymbol);
+         if (name &&
+            (name[0] == '-' || name[0] == '+') &&
+             name[1] == '[')           /* Got a method name.  */
+           {
+             /* Filter for class/instance methods.  */
+             if (plusminus && name[0] != plusminus)
+               continue;
+             /* Find selector part.  */
+             name = (char *) strchr(name+2, ' ');
+             if (regexp == NULL || re_exec(++name) != 0)
+               sym_arr[matches++] = (struct symbol *) msymbol;
+           }
+       }
+
+      qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
+            compare_selectors);
+      /* Prevent compare on first iteration.  */
+      asel[0] = 0;
+      for (ix = 0; ix < matches; ix++) /* Now do the output.  */
+       {
+         char *p = asel;
+
+         QUIT;
+         if ((name = SYMBOL_DEMANGLED_NAME (sym_arr[ix])) == NULL)
+           name = SYMBOL_NAME (sym_arr[ix]);
+         name = strchr (name, ' ') + 1;
+         if (p[0] && specialcmp(name, p) == 0)
+           continue;           /* Seen this one already (not unique).  */
+
+         /* Copy selector part.  */
+         while (*name && *name != ']')
+           *p++ = *name++;
+         *p++ = '\0';
+         /* Print in columns.  */
+         puts_filtered_tabular(asel, maxlen + 1, 0);
+       }
+      begin_line();
+    }
+  else
+    printf_filtered ("No selectors matching \"%s\"\n", regexp ? regexp : "*");
+}
+
+/*
+ * Function: compare_classes (void *, void *)
+ *
+ * Comparison function for use with qsort.  Arguments are symbols or
+ * msymbols Compares class part of objc method name alphabetically. 
+ */
+
+static int
+compare_classes (void *a, void *b)
+{
+  char *aname, *bname;
+
+  if ((aname = SYMBOL_SOURCE_NAME (*(struct symbol **) a)) == NULL ||
+      (bname = SYMBOL_SOURCE_NAME (*(struct symbol **) b)) == NULL)
+    error ("internal: compare_classes(1)");
+
+  return specialcmp (aname+1, bname+1);
+}
+
+/*
+ * Function: classes_info(regexp, from_tty)
+ *
+ * Implements the "info classes" command for objective c classes.
+ * Lists all objective c classes that match the optional regexp.
+ * Works by grepping thru the list of objective c methods.  List will
+ * be sorted and uniqued (since one class may have many methods).
+ * BUGS: will not list a class that has no methods. 
+ */
+
+static void
+classes_info (char *regexp, int from_tty)
+{
+  struct objfile       *objfile;
+  struct minimal_symbol *msymbol;
+  char                  *name;
+  char                  *val;
+  int                    matches = 0;
+  int                    maxlen  = 0;
+  int                    ix;
+  char                   myregexp[2048];
+  char                   aclass[256];
+  struct symbol        **sym_arr;
+
+  if (regexp == NULL)
+    strcpy(myregexp, ".* ");   /* Null input: match all objc classes.  */
+  else
+    {
+      strcpy(myregexp, regexp);
+      if (myregexp[strlen(myregexp) - 1] == '$')
+       /* In the method name, the end of the class name is marked by ' '.  */
+       myregexp[strlen(myregexp) - 1] = ' ';
+      else
+       strcat(myregexp, ".* ");
+    }
+
+  if (regexp != NULL)
+    if (0 != (val = re_comp (myregexp)))
+      error ("Invalid regexp (%s): %s", val, regexp);
+
+  /* First time thru is JUST to get max length and count.  */
+  ALL_MSYMBOLS (objfile, msymbol)
+    {
+      QUIT;
+      if ((name = SYMBOL_DEMANGLED_NAME (msymbol)) == NULL)
+       name = SYMBOL_NAME (msymbol);
+      if (name &&
+        (name[0] == '-' || name[0] == '+') &&
+         name[1] == '[')                       /* Got a method name.  */
+       if (regexp == NULL || re_exec(name+2) != 0)
+         { 
+           /* Compute length of classname part.  */
+           char *mystart = name + 2;
+           char *myend   = (char *) strchr(mystart, ' ');
+           
+           if (myend && (myend - mystart > maxlen))
+             maxlen = myend - mystart;
+           matches++;
+         }
+    }
+  if (matches)
+    {
+      printf_filtered ("Classes matching \"%s\":\n\n", 
+                      regexp ? regexp : "*");
+      sym_arr = alloca (matches * sizeof (struct symbol *));
+      matches = 0;
+      ALL_MSYMBOLS (objfile, msymbol)
+       {
+         QUIT;
+         if ((name = SYMBOL_DEMANGLED_NAME (msymbol)) == NULL)
+           name = SYMBOL_NAME (msymbol);
+         if (name &&
+            (name[0] == '-' || name[0] == '+') &&
+             name[1] == '[')                   /* Got a method name.  */
+           if (regexp == NULL || re_exec(name+2) != 0)
+               sym_arr[matches++] = (struct symbol *) msymbol;
+       }
+
+      qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
+            compare_classes);
+      /* Prevent compare on first iteration.  */
+      aclass[0] = 0;
+      for (ix = 0; ix < matches; ix++) /* Now do the output.  */
+       {
+         char *p = aclass;
+
+         QUIT;
+         if ((name = SYMBOL_DEMANGLED_NAME (sym_arr[ix])) == NULL)
+           name = SYMBOL_NAME (sym_arr[ix]);
+         name += 2;
+         if (p[0] && specialcmp(name, p) == 0)
+           continue;   /* Seen this one already (not unique).  */
+
+         /* Copy class part of method name.  */
+         while (*name && *name != ' ')
+           *p++ = *name++;
+         *p++ = '\0';
+         /* Print in columns.  */
+         puts_filtered_tabular(aclass, maxlen + 1, 0);
+       }
+      begin_line();
+    }
+  else
+    printf_filtered ("No classes matching \"%s\"\n", regexp ? regexp : "*");
+}
+
+/* 
+ * Function: find_imps (char *selector, struct symbol **sym_arr)
+ *
+ * Input:  a string representing a selector
+ *         a pointer to an array of symbol pointers
+ *         possibly a pointer to a symbol found by the caller.
+ *
+ * Output: number of methods that implement that selector.  Side
+ * effects: The array of symbol pointers is filled with matching syms.
+ *
+ * By analogy with function "find_methods" (symtab.c), builds a list
+ * of symbols matching the ambiguous input, so that "decode_line_2"
+ * (symtab.c) can list them and ask the user to choose one or more.
+ * In this case the matches are objective c methods
+ * ("implementations") matching an objective c selector.
+ *
+ * Note that it is possible for a normal (c-style) function to have
+ * the same name as an objective c selector.  To prevent the selector
+ * from eclipsing the function, we allow the caller (decode_line_1) to
+ * search for such a function first, and if it finds one, pass it in
+ * to us.  We will then integrate it into the list.  We also search
+ * for one here, among the minsyms.
+ *
+ * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
+ *       into two parts: debuggable (struct symbol) syms, and
+ *       non_debuggable (struct minimal_symbol) syms.  The debuggable
+ *       ones will come first, before NUM_DEBUGGABLE (which will thus
+ *       be the index of the first non-debuggable one). 
+ */
+
+/*
+ * Function: total_number_of_imps (char *selector);
+ *
+ * Input:  a string representing a selector 
+ * Output: number of methods that implement that selector.
+ *
+ * By analogy with function "total_number_of_methods", this allows
+ * decode_line_1 (symtab.c) to detect if there are objective c methods
+ * matching the input, and to allocate an array of pointers to them
+ * which can be manipulated by "decode_line_2" (also in symtab.c).
+ */
+
+char * 
+parse_selector (char *method, char **selector)
+{
+  char *s1 = NULL;
+  char *s2 = NULL;
+  int found_quote = 0;
+
+  char *nselector = NULL;
+
+  CHECK (selector != NULL);
+
+  s1 = method;
+
+  while (isspace (*s1))
+    s1++;
+  if (*s1 == '\'') 
+    {
+      found_quote = 1;
+      s1++;
+    }
+  while (isspace (*s1))
+    s1++;
+   
+  nselector = s1;
+  s2 = s1;
+
+  for (;;) {
+    if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
+      *s1++ = *s2;
+    else if (isspace (*s2))
+      ;
+    else if ((*s2 == '\0') || (*s2 == '\''))
+      break;
+    else
+      return NULL;
+    s2++;
+  }
+  *s1++ = '\0';
+
+  while (isspace (*s2))
+    s2++;
+  if (found_quote)
+    {
+      if (*s2 == '\'') 
+       s2++;
+      while (isspace (*s2))
+       s2++;
+    }
+
+  if (selector != NULL)
+    *selector = nselector;
+
+  return s2;
+}
+
+char * 
+parse_method (char *method, char *type, char **class, 
+             char **category, char **selector)
+{
+  char *s1 = NULL;
+  char *s2 = NULL;
+  int found_quote = 0;
+
+  char ntype = '\0';
+  char *nclass = NULL;
+  char *ncategory = NULL;
+  char *nselector = NULL;
+
+  CHECK (type != NULL);
+  CHECK (class != NULL);
+  CHECK (category != NULL);
+  CHECK (selector != NULL);
+  
+  s1 = method;
+
+  while (isspace (*s1))
+    s1++;
+  if (*s1 == '\'') 
+    {
+      found_quote = 1;
+      s1++;
+    }
+  while (isspace (*s1))
+    s1++;
+  
+  if ((s1[0] == '+') || (s1[0] == '-'))
+    ntype = *s1++;
+
+  while (isspace (*s1))
+    s1++;
+
+  if (*s1 != '[')
+    return NULL;
+  s1++;
+
+  nclass = s1;
+  while (isalnum (*s1) || (*s1 == '_'))
+    s1++;
+  
+  s2 = s1;
+  while (isspace (*s2))
+    s2++;
+  
+  if (*s2 == '(')
+    {
+      s2++;
+      while (isspace (*s2))
+       s2++;
+      ncategory = s2;
+      while (isalnum (*s2) || (*s2 == '_'))
+       s2++;
+      *s2++ = '\0';
+    }
+
+  /* Truncate the class name now that we're not using the open paren.  */
+  *s1++ = '\0';
+
+  nselector = s2;
+  s1 = s2;
+
+  for (;;) {
+    if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
+      *s1++ = *s2;
+    else if (isspace (*s2))
+      ;
+    else if (*s2 == ']')
+      break;
+    else
+      return NULL;
+    s2++;
+  }
+  *s1++ = '\0';
+  s2++;
+
+  while (isspace (*s2))
+    s2++;
+  if (found_quote)
+    {
+      if (*s2 != '\'') 
+       return NULL;
+      s2++;
+      while (isspace (*s2))
+       s2++;
+    }
+
+  if (type != NULL)
+    *type = ntype;
+  if (class != NULL)
+    *class = nclass;
+  if (category != NULL)
+    *category = ncategory;
+  if (selector != NULL)
+    *selector = nselector;
+
+  return s2;
+}
+
+void
+find_methods (struct symtab *symtab, char type, 
+             const char *class, const char *category, 
+             const char *selector, struct symbol **syms, 
+             unsigned int *nsym, unsigned int *ndebug)
+{
+  struct objfile *objfile = NULL;
+  struct minimal_symbol *msymbol = NULL;
+  struct block *block = NULL;
+  struct symbol *sym = NULL;
+
+  char *symname = NULL;
+
+  char ntype = '\0';
+  char *nclass = NULL;
+  char *ncategory = NULL;
+  char *nselector = NULL;
+
+  unsigned int csym = 0;
+  unsigned int cdebug = 0;
+
+  static char *tmp = NULL;
+  static unsigned int tmplen = 0;
+
+  CHECK (nsym != NULL);
+  CHECK (ndebug != NULL);
+
+  if (symtab)
+    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
+
+  ALL_MSYMBOLS (objfile, msymbol)
+    {
+      QUIT;
+
+      if ((msymbol->type != mst_text) && (msymbol->type != mst_file_text))
+       /* Not a function or method.  */
+       continue;
+
+      if (symtab)
+       if ((SYMBOL_VALUE_ADDRESS (msymbol) <  block->startaddr) ||
+           (SYMBOL_VALUE_ADDRESS (msymbol) >= block->endaddr))
+         /* Not in the specified symtab.  */
+         continue;
+
+      symname = SYMBOL_DEMANGLED_NAME (msymbol);
+      if (symname == NULL)
+       symname = SYMBOL_NAME (msymbol);
+      if (symname == NULL)
+       continue;
+
+      if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
+       /* Not a method name.  */
+       continue;
+      
+      while ((strlen (symname) + 1) >= tmplen)
+       {
+         tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
+         tmp = xrealloc (tmp, tmplen);
+       }
+      strcpy (tmp, symname);
+
+      if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
+       continue;
+      
+      if ((type != '\0') && (ntype != type))
+       continue;
+
+      if ((class != NULL) 
+         && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
+       continue;
+
+      if ((category != NULL) && 
+         ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
+       continue;
+
+      if ((selector != NULL) && 
+         ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
+       continue;
+
+      sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
+      if (sym != NULL)
+        {
+          const char    *newsymname = SYMBOL_DEMANGLED_NAME (sym);
+         
+          if (newsymname == NULL)
+            newsymname = SYMBOL_NAME (sym);
+          if (strcmp (symname, newsymname) == 0)
+            {
+              /* Found a high-level method sym: swap it into the
+                 lower part of sym_arr (below num_debuggable).  */
+              if (syms != NULL)
+                {
+                  syms[csym] = syms[cdebug];
+                  syms[cdebug] = sym;
+                }
+              csym++;
+              cdebug++;
+            }
+          else
+            {
+              warning (
+"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
+                       newsymname, symname);
+              if (syms != NULL)
+                syms[csym] = (struct symbol *) msymbol;
+              csym++;
+            }
+        }
+      else 
+       {
+         /* Found a non-debuggable method symbol.  */
+         if (syms != NULL)
+           syms[csym] = (struct symbol *) msymbol;
+         csym++;
+       }
+    }
+
+  if (nsym != NULL)
+    *nsym = csym;
+  if (ndebug != NULL)
+    *ndebug = cdebug;
+}
+
+char *find_imps (struct symtab *symtab, struct block *block,
+                char *method, struct symbol **syms, 
+                unsigned int *nsym, unsigned int *ndebug)
+{
+  char type = '\0';
+  char *class = NULL;
+  char *category = NULL;
+  char *selector = NULL;
+
+  unsigned int csym = 0;
+  unsigned int cdebug = 0;
+
+  unsigned int ncsym = 0;
+  unsigned int ncdebug = 0;
+
+  char *buf = NULL;
+  char *tmp = NULL;
+
+  CHECK (nsym != NULL);
+  CHECK (ndebug != NULL);
+
+  if (nsym != NULL)
+    *nsym = 0;
+  if (ndebug != NULL)
+    *ndebug = 0;
+
+  buf = (char *) alloca (strlen (method) + 1);
+  strcpy (buf, method);
+  tmp = parse_method (buf, &type, &class, &category, &selector);
+
+  if (tmp == NULL) {
+    
+    struct symtab *sym_symtab = NULL;
+    struct symbol *sym = NULL;
+    struct minimal_symbol *msym = NULL;
+    
+    strcpy (buf, method);
+    tmp = parse_selector (buf, &selector);
+    
+    if (tmp == NULL)
+      return NULL;
+    
+    sym = lookup_symbol (selector, block, VAR_NAMESPACE, 0, &sym_symtab);
+    if (sym != NULL) 
+      {
+       if (syms)
+         syms[csym] = sym;
+       csym++;
+       cdebug++;
+      }
+
+    if (sym == NULL)
+      msym = lookup_minimal_symbol (selector, 0, 0);
+
+    if (msym != NULL) 
+      {
+       if (syms)
+         syms[csym] = msym;
+       csym++;
+      }
+  }
+
+  if (syms != NULL)
+    find_methods (symtab, type, class, category, selector, 
+                 syms + csym, &ncsym, &ncdebug);
+  else
+    find_methods (symtab, type, class, category, selector, 
+                 NULL, &ncsym, &ncdebug);
+
+  /* If we didn't find any methods, just return.  */
+  if (ncsym == 0 && ncdebug == 0)
+    return method;
+
+  /* Take debug symbols from the second batch of symbols and swap them
+   * with debug symbols from the first batch.  Repeat until either the
+   * second section is out of debug symbols or the first section is
+   * full of debug symbols.  Either way we have all debug symbols
+   * packed to the beginning of the buffer.  
+   */
+
+  if (syms != NULL) 
+    {
+      while ((cdebug < csym) && (ncdebug > 0))
+       {
+         struct symbol *s = NULL;
+         /* First non-debugging symbol.  */
+         unsigned int i = cdebug;
+         /* Last of second batch of debug symbols.  */
+         unsigned int j = csym + ncdebug - 1;
+
+         s = syms[j];
+         syms[j] = syms[i];
+         syms[i] = s;
+
+         /* We've moved a symbol from the second debug section to the
+             first one.  */
+         cdebug++;
+         ncdebug--;
+       }
+    }
+
+  csym += ncsym;
+  cdebug += ncdebug;
+
+  if (nsym != NULL)
+    *nsym = csym;
+  if (ndebug != NULL)
+    *ndebug = cdebug;
+
+  if (syms == NULL)
+    return method + (tmp - buf);
+
+  if (csym > 1)
+    {
+      /* Sort debuggable symbols.  */
+      if (cdebug > 1)
+       qsort (syms, cdebug, sizeof (struct minimal_symbol *), 
+              compare_classes);
+      
+      /* Sort minimal_symbols.  */
+      if ((csym - cdebug) > 1)
+       qsort (&syms[cdebug], csym - cdebug, 
+              sizeof (struct minimal_symbol *), compare_classes);
+    }
+  /* Terminate the sym_arr list.  */
+  syms[csym] = 0;
+
+  return method + (tmp - buf);
+}
+
+void 
+print_object_command (char *args, int from_tty)
+{
+  struct value *object, *function, *description;
+  CORE_ADDR string_addr;
+  int i = 0;
+  char c = -1;
+
+  if (!args || !*args)
+    error (
+"The 'print-object' command requires an argument (an Objective-C object)");
+
+  {
+    struct expression *expr = parse_expression (args);
+    register struct cleanup *old_chain = 
+      make_cleanup (free_current_contents, &expr);
+    int pc = 0;
+
+#if 1
+    object = expr->language_defn->evaluate_exp (builtin_type_void_data_ptr,
+                                               expr, &pc, EVAL_NORMAL);
+#else
+    object = evaluate_subexp (builtin_type_void_data_ptr, 
+                             expr, &pc, EVAL_NORMAL);
+#endif
+    do_cleanups (old_chain);
+  }
+
+  if (!(function = find_function_in_inferior ("_NSPrintForDebugger")))
+    error ("Unable to locate _NSPrintForDebugger in child process");
+
+  description = call_function_by_hand (function, 1, &object);
+
+  if ((string_addr = value_as_long (description)) == 0)
+    error ("object returns null description");
+
+  read_memory (string_addr + i++, &c, 1);
+  if (c != '\0')
+    do
+      { /* Read and print characters up to EOS.  */
+       QUIT;
+       printf_filtered ("%c", c);
+       read_memory (string_addr + i++, &c, 1);
+      } while (c != 0);
+  else
+    printf_filtered("<object returns empty description>");
+  printf_filtered ("\n");
+}
+
+/* The data structure 'methcalls' is used to detect method calls (thru
+ * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
+ * and ultimately find the method being called. 
+ */
+
+struct objc_methcall {
+  char *name;
+ /* Return instance method to be called.  */
+  CORE_ADDR (*stop_at) (CORE_ADDR);
+  /* Start of pc range corresponding to method invocation.  */
+  CORE_ADDR begin;
+  /* End of pc range corresponding to method invocation.  */
+  CORE_ADDR end;
+};
+
+static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
+static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
+static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
+static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
+
+static struct objc_methcall methcalls[] = {
+  { "_objc_msgSend", resolve_msgsend, 0, 0},
+  { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
+  { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
+  { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
+  { "_objc_getClass", NULL, 0, 0},
+  { "_objc_getMetaClass", NULL, 0, 0}
+};
+
+#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
+
+/* The following function, "find_objc_msgsend", fills in the data
+ * structure "objc_msgs" by finding the addresses of each of the
+ * (currently four) functions that it holds (of which objc_msgSend is
+ * the first).  This must be called each time symbols are loaded, in
+ * case the functions have moved for some reason.  
+ */
+
+void 
+find_objc_msgsend (void)
+{
+  unsigned int i;
+  for (i = 0; i < nmethcalls; i++) {
+
+    struct minimal_symbol *func;
+
+    /* Try both with and without underscore.  */
+    func = lookup_minimal_symbol (methcalls[i].name, NULL, NULL);
+    if ((func == NULL) && (methcalls[i].name[0] == '_')) {
+      func = lookup_minimal_symbol (methcalls[i].name + 1, NULL, NULL);
+    }
+    if (func == NULL) { 
+      methcalls[i].begin = 0;
+      methcalls[i].end = 0;
+      continue; 
+    }
+    
+    methcalls[i].begin = SYMBOL_VALUE_ADDRESS (func);
+    do {
+      methcalls[i].end = SYMBOL_VALUE_ADDRESS (++func);
+    } while (methcalls[i].begin == methcalls[i].end);
+  }
+}
+
+/* find_objc_msgcall (replaces pc_off_limits)
+ *
+ * ALL that this function now does is to determine whether the input
+ * address ("pc") is the address of one of the Objective-C message
+ * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
+ * if so, it returns the address of the method that will be called.
+ *
+ * The old function "pc_off_limits" used to do a lot of other things
+ * in addition, such as detecting shared library jump stubs and
+ * returning the address of the shlib function that would be called.
+ * That functionality has been moved into the SKIP_TRAMPOLINE_CODE and
+ * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
+ * dependent modules.  
+ */
+
+struct objc_submethod_helper_data {
+  CORE_ADDR (*f) (CORE_ADDR, CORE_ADDR *);
+  CORE_ADDR pc;
+  CORE_ADDR *new_pc;
+};
+
+int 
+find_objc_msgcall_submethod_helper (PTR arg)
+{
+  struct objc_submethod_helper_data *s = 
+    (struct objc_submethod_helper_data *) arg;
+
+  if (s->f (s->pc, s->new_pc) == 0) 
+    return 1;
+  else 
+    return 0;
+}
+
+int 
+find_objc_msgcall_submethod (CORE_ADDR (*f) (CORE_ADDR, CORE_ADDR *),
+                            CORE_ADDR pc, 
+                            CORE_ADDR *new_pc)
+{
+  struct objc_submethod_helper_data s;
+
+  s.f = f;
+  s.pc = pc;
+  s.new_pc = new_pc;
+
+  if (catch_errors (find_objc_msgcall_submethod_helper,
+                   (PTR) &s,
+                   "Unable to determine target of Objective-C method call (ignoring):\n",
+                   RETURN_MASK_ALL) == 0) 
+    return 1;
+  else 
+    return 0;
+}
+
+int 
+find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
+{
+  unsigned int i;
+
+  find_objc_msgsend ();
+  if (new_pc != NULL) { *new_pc = 0; }
+
+  for (i = 0; i < nmethcalls; i++) 
+    if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end)) 
+      {
+       if (methcalls[i].stop_at != NULL) 
+         return find_objc_msgcall_submethod (methcalls[i].stop_at, 
+                                             pc, new_pc);
+       else 
+         return 0;
+      }
+
+  return 0;
+}
+
+void
+_initialize_objc_language (void)
+{
+  add_language (&objc_language_defn);
+  add_info ("selectors", selectors_info,    /* INFO SELECTORS command.  */
+           "All Objective-C selectors, or those matching REGEXP.");
+  add_info ("classes", classes_info,       /* INFO CLASSES   command.  */
+           "All Objective-C classes, or those matching REGEXP.");
+  add_com ("print-object", class_vars, print_object_command, 
+          "Ask an Objective-C object to print itself.\n");
+  add_com_alias ("po", "print-object", class_vars, 1);
+}
+
+#if defined (__powerpc__) || defined (__ppc__)
+static unsigned long FETCH_ARGUMENT (int i)
+{
+  return read_register (3 + i);
+}
+#elif defined (__i386__)
+static unsigned long FETCH_ARGUMENT (int i)
+{
+  CORE_ADDR stack = read_register (SP_REGNUM);
+  return read_memory_unsigned_integer (stack + (4 * (i + 1)), 4);
+}
+#elif defined (__sparc__)
+static unsigned long FETCH_ARGUMENT (int i)
+{
+  return read_register (O0_REGNUM + i);
+}
+#elif defined (__hppa__) || defined (__hppa)
+static unsigned long FETCH_ARGUMENT (int i)
+{
+  return read_register (R0_REGNUM + 26 - i);
+}
+#else
+#error unknown architecture
+#endif
+
+#if defined (__hppa__) || defined (__hppa)
+static CORE_ADDR CONVERT_FUNCPTR (CORE_ADDR pc)
+{
+  if (pc & 0x2)
+    pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4);
+
+  return pc;
+}
+#else
+static CORE_ADDR CONVERT_FUNCPTR (CORE_ADDR pc)
+{
+  return pc;
+}
+#endif
+
+static void 
+read_objc_method (CORE_ADDR addr, struct objc_method *method)
+{
+  method->name  = read_memory_unsigned_integer (addr + 0, 4);
+  method->types = read_memory_unsigned_integer (addr + 4, 4);
+  method->imp   = read_memory_unsigned_integer (addr + 8, 4);
+}
+
+static 
+unsigned long read_objc_methlist_nmethods (CORE_ADDR addr)
+{
+  return read_memory_unsigned_integer (addr + 4, 4);
+}
+
+static void 
+read_objc_methlist_method (CORE_ADDR addr, unsigned long num, 
+                          struct objc_method *method)
+{
+  CHECK_FATAL (num < read_objc_methlist_nmethods (addr));
+  read_objc_method (addr + 8 + (12 * num), method);
+}
+  
+static void 
+read_objc_object (CORE_ADDR addr, struct objc_object *object)
+{
+  object->isa = read_memory_unsigned_integer (addr, 4);
+}
+
+static void 
+read_objc_super (CORE_ADDR addr, struct objc_super *super)
+{
+  super->receiver = read_memory_unsigned_integer (addr, 4);
+  super->class = read_memory_unsigned_integer (addr + 4, 4);
+};
+
+static void 
+read_objc_class (CORE_ADDR addr, struct objc_class *class)
+{
+  class->isa = read_memory_unsigned_integer (addr, 4);
+  class->super_class = read_memory_unsigned_integer (addr + 4, 4);
+  class->name = read_memory_unsigned_integer (addr + 8, 4);
+  class->version = read_memory_unsigned_integer (addr + 12, 4);
+  class->info = read_memory_unsigned_integer (addr + 16, 4);
+  class->instance_size = read_memory_unsigned_integer (addr + 18, 4);
+  class->ivars = read_memory_unsigned_integer (addr + 24, 4);
+  class->methods = read_memory_unsigned_integer (addr + 28, 4);
+  class->cache = read_memory_unsigned_integer (addr + 32, 4);
+  class->protocols = read_memory_unsigned_integer (addr + 36, 4);
+}
+
+CORE_ADDR
+find_implementation_from_class (CORE_ADDR class, CORE_ADDR sel)
+{
+  CORE_ADDR subclass = class;
+
+  while (subclass != 0) 
+    {
+
+      struct objc_class class_str;
+      unsigned mlistnum = 0;
+
+      read_objc_class (subclass, &class_str);
+
+      for (;;) 
+       {
+         CORE_ADDR mlist;
+         unsigned long nmethods;
+         unsigned long i;
+      
+         mlist = read_memory_unsigned_integer (class_str.methods + 
+                                               (4 * mlistnum), 4);
+         if (mlist == 0) 
+           break;
+
+         nmethods = read_objc_methlist_nmethods (mlist);
+
+         for (i = 0; i < nmethods; i++) 
+           {
+             struct objc_method meth_str;
+             read_objc_methlist_method (mlist, i, &meth_str);
+
+#if 0
+             fprintf (stderr, 
+                      "checking method 0x%lx against selector 0x%lx\n", 
+                      meth_str.name, sel);
+#endif
+
+             if (meth_str.name == sel) 
+               return CONVERT_FUNCPTR (meth_str.imp);
+           }
+         mlistnum++;
+       }
+      subclass = class_str.super_class;
+    }
+
+  return 0;
+}
+
+CORE_ADDR
+find_implementation (CORE_ADDR object, CORE_ADDR sel)
+{
+  struct objc_object ostr;
+
+  if (object == 0)
+    return 0;
+  read_objc_object (object, &ostr);
+  if (ostr.isa == 0)
+    return 0;
+
+  return find_implementation_from_class (ostr.isa, sel);
+}
+
+static int
+resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
+{
+  CORE_ADDR object;
+  CORE_ADDR sel;
+  CORE_ADDR res;
+
+  object = FETCH_ARGUMENT (0);
+  sel = FETCH_ARGUMENT (1);
+
+  res = find_implementation (object, sel);
+  if (new_pc != 0)
+    *new_pc = res;
+  if (res == 0)
+    return 1;
+  return 0;
+}
+
+static int
+resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
+{
+  CORE_ADDR object;
+  CORE_ADDR sel;
+  CORE_ADDR res;
+
+  object = FETCH_ARGUMENT (1);
+  sel = FETCH_ARGUMENT (2);
+
+  res = find_implementation (object, sel);
+  if (new_pc != 0)
+    *new_pc = res;
+  if (res == 0)
+    return 1;
+  return 0;
+}
+
+static int
+resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
+{
+  struct objc_super sstr;
+
+  CORE_ADDR super;
+  CORE_ADDR sel;
+  CORE_ADDR res;
+
+  super = FETCH_ARGUMENT (0);
+  sel = FETCH_ARGUMENT (1);
+
+  read_objc_super (super, &sstr);
+  if (sstr.class == 0)
+    return 0;
+  
+  res = find_implementation_from_class (sstr.class, sel);
+  if (new_pc != 0)
+    *new_pc = res;
+  if (res == 0)
+    return 1;
+  return 0;
+}
+
+static int
+resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
+{
+  struct objc_super sstr;
+
+  CORE_ADDR super;
+  CORE_ADDR sel;
+  CORE_ADDR res;
+
+  super = FETCH_ARGUMENT (1);
+  sel = FETCH_ARGUMENT (2);
+
+  read_objc_super (super, &sstr);
+  if (sstr.class == 0)
+    return 0;
+  
+  res = find_implementation_from_class (sstr.class, sel);
+  if (new_pc != 0)
+    *new_pc = res;
+  if (res == 0)
+    return 1;
+  return 0;
+}
diff --git a/gdb/objc-lang.h b/gdb/objc-lang.h
new file mode 100644 (file)
index 0000000..87e315b
--- /dev/null
@@ -0,0 +1,57 @@
+/* Objective-C language support definitions for GDB, the GNU debugger.
+
+   Copyright 1992 Free Software Foundation, Inc.
+
+   Contributed by Apple Computer, 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 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifdef __STDC__                /* Forward decls for prototypes.  */
+struct value;
+#endif
+
+extern int objc_parse (void);          /* Defined in c-exp.y */
+
+extern void objc_error (char *);       /* Defined in c-exp.y */
+
+extern int c_val_print (struct type *, char *, int, 
+                       CORE_ADDR, struct ui_file *, int,
+                       int, int, enum val_prettyprint);
+
+extern int c_value_print (struct value *, struct ui_file *, 
+                         int, enum val_prettyprint);
+
+extern CORE_ADDR lookup_objc_class     (char *classname);
+extern int       lookup_child_selector (char *methodname);
+
+char *objc_demangle (const char *mangled);
+
+int find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc);
+
+char *parse_selector (char *method, char **selector);
+
+char *parse_method (char *method, char *type, 
+                   char **class, char **category, 
+                   char **selector);
+
+void find_methods (struct symtab *symtab, char type, 
+                  const char *class, const char *category, 
+                  const char *selector, struct symbol **syms, 
+                  unsigned int *nsym, unsigned int *ndebug);
+
+char *find_imps (struct symtab *symtab, struct block *block,
+                char *method, struct symbol **syms, 
+                unsigned int *nsym, unsigned int *ndebug);
diff --git a/gdb/testsuite/gdb.base/charset.c b/gdb/testsuite/gdb.base/charset.c
new file mode 100644 (file)
index 0000000..ece684a
--- /dev/null
@@ -0,0 +1,131 @@
+/* Test GDB's character set support
+   Jim Blandy <jimb@cygnus.com> --- December 2001 */
+
+#include <stdio.h>
+
+
+/* X_string is a null-terminated string in the X charset whose
+   elements are as follows.  X should be the name the `set charset'
+   command uses for the character set, in lower-case, with any
+   non-identifier characters replaced with underscores.  Where a
+   character set doesn't have the given character, the string should
+   contain the character 'x'.
+
+   [0] --- the `alert' character, '\a'
+   [1] --- the `backspace' character, '\b'
+   [2] --- the `escape' character, '\e'
+   [3] --- the `form feed' character, '\f'
+   [4] --- the `line feed' character, '\n'
+   [5] --- the `carriage return' character, '\r'
+   [6] --- the `horizontal tab' character, '\t'
+   [7] --- the `vertical tab' character, '\v'
+   [8  .. 33] --- the uppercase letters A-Z
+   [34 .. 59] --- the lowercase letters a-z
+   [60 .. 69] --- the digits 0-9
+   [70] --- the `cent' character
+   [71] --- a control character with no defined backslash escape
+
+   Feel free to extend these as you like.  */
+
+#define NUM_CHARS (72)
+
+char ascii_string[NUM_CHARS];
+char iso_8859_1_string[NUM_CHARS];
+char ebcdic_us_string[NUM_CHARS];
+char ibm1047_string[NUM_CHARS];
+
+
+void
+init_string (char string[],
+             char x,
+             char alert, char backspace, char escape, char form_feed,
+             char line_feed, char carriage_return, char horizontal_tab,
+             char vertical_tab, char cent, char misc_ctrl)
+{
+  memset (string, x, NUM_CHARS);
+  string[0] = alert;
+  string[1] = backspace;
+  string[2] = escape;
+  string[3] = form_feed;
+  string[4] = line_feed;
+  string[5] = carriage_return;
+  string[6] = horizontal_tab;
+  string[7] = vertical_tab;
+  string[70] = cent;
+  string[71] = misc_ctrl;
+}
+
+
+void
+fill_run (char string[], int start, int len, int first)
+{
+  int i;
+
+  for (i = 0; i < len; i++)
+    string[start + i] = first + i;
+}
+
+
+int main ()
+{
+#ifdef usestubs
+  set_debug_traps();
+  breakpoint();
+#endif
+  (void) malloc (1);
+  /* Initialize ascii_string.  */
+  init_string (ascii_string,
+               120,
+               7, 8, 27, 12,
+               10, 13, 9,
+               11, 120, 17);
+  fill_run (ascii_string, 8, 26, 65);
+  fill_run (ascii_string, 34, 26, 97);
+  fill_run (ascii_string, 60, 10, 48);
+
+  /* Initialize iso_8859_1_string.  */
+  init_string (iso_8859_1_string,
+               120,
+               7, 8, 27, 12,
+               10, 13, 9,
+               11, 162, 17);
+  fill_run (iso_8859_1_string, 8, 26, 65);
+  fill_run (iso_8859_1_string, 34, 26, 97);
+  fill_run (iso_8859_1_string, 60, 10, 48);
+
+  /* Initialize ebcdic_us_string.  */
+  init_string (ebcdic_us_string,
+               167,
+               47, 22, 39, 12,
+               37, 13, 5,
+               11, 74, 17);
+  /* In EBCDIC, the upper-case letters are broken into three separate runs.  */
+  fill_run (ebcdic_us_string, 8, 9, 193);
+  fill_run (ebcdic_us_string, 17, 9, 209);
+  fill_run (ebcdic_us_string, 26, 8, 226);
+  /* The lower-case letters are, too.  */
+  fill_run (ebcdic_us_string, 34, 9, 129);
+  fill_run (ebcdic_us_string, 43, 9, 145);
+  fill_run (ebcdic_us_string, 52, 8, 162);
+  /* The digits, at least, are contiguous.  */
+  fill_run (ebcdic_us_string, 60, 10, 240);
+
+  /* Initialize ibm1047_string.  */
+  init_string (ibm1047_string,
+               167,
+               47, 22, 39, 12,
+               37, 13, 5,
+               11, 74, 17);
+  /* In EBCDIC, the upper-case letters are broken into three separate runs.  */
+  fill_run (ibm1047_string, 8, 9, 193);
+  fill_run (ibm1047_string, 17, 9, 209);
+  fill_run (ibm1047_string, 26, 8, 226);
+  /* The lower-case letters are, too.  */
+  fill_run (ibm1047_string, 34, 9, 129);
+  fill_run (ibm1047_string, 43, 9, 145);
+  fill_run (ibm1047_string, 52, 8, 162);
+  /* The digits, at least, are contiguous.  */
+  fill_run (ibm1047_string, 60, 10, 240);
+
+  puts ("All set!");            /* all strings initialized */
+}
diff --git a/gdb/testsuite/gdb.base/charset.exp b/gdb/testsuite/gdb.base/charset.exp
new file mode 100644 (file)
index 0000000..8e765aa
--- /dev/null
@@ -0,0 +1,486 @@
+# Copyright 2001 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# Test GDB's character set support.
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "charset"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Start with a fresh gdb.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Parse the output from a `show charset' command.  Return the host
+# and target charset as a two-element list.
+proc parse_show_charset_output {testname} {
+    global gdb_prompt
+
+    gdb_expect {
+        -re "The current host and target character set is `(.*)'\\.\[\r\n\]+$gdb_prompt $" {
+            set host_charset $expect_out(1,string)
+            set target_charset $expect_out(1,string)
+            pass $testname
+        }
+        -re "The current host character set is `(.*)'\\.\[\r\n\]+The current target character set is `(.*)'\\.\[\r\n\]+$gdb_prompt $" {
+            set host_charset $expect_out(1,string)
+            set target_charset $expect_out(2,string)
+            pass $testname
+        }
+        -re ".*$gdb_prompt $" {
+            fail $testname
+        }
+        timeout {
+            fail "$testname (timeout)"
+        }
+    }
+
+    return [list $host_charset $target_charset]
+}
+
+
+# Try the various `show charset' commands.  These are all aliases of each
+# other; `show target-charset' and `show host-charset' actually print
+# both the host and target charsets.
+
+send_gdb "show charset\n"
+set show_charset [parse_show_charset_output "show charset"]
+
+send_gdb "show target-charset\n"
+set show_target_charset [parse_show_charset_output "show target-charset"]
+
+if {! [string compare $show_charset $show_target_charset]} {
+    pass "check `show target-charset' against `show charset'"
+} else {
+    fail "check `show target-charset' against `show charset'"
+}
+
+send_gdb "show host-charset\n"
+set show_host_charset [parse_show_charset_output "show host-charset"]
+
+if {! [string compare $show_charset $show_host_charset]} {
+    pass "check `show host-charset' against `show charset'"
+} else {
+    fail "check `show host-charset' against `show charset'"
+}
+
+
+# Get the list of supported charsets.
+send_gdb "set charset\n"
+
+# True iff we've seen the "Valid character sets are:" message.
+set seen_valid 0
+
+# True iff we've seen the "can be used as a host character set" message.
+set seen_can_host 0
+
+# A Tcl array mapping the names of all the character sets we've seen
+# to "1" if the character set can be used as a host character set, or
+# "0" otherwise.  We can use `array names charsets' just to get a list
+# of all character sets.
+array set charsets {}
+
+proc all_charset_names {} {
+    global charsets
+    return [array names charsets]
+}
+
+proc charset_exists {charset} {
+    global charsets
+    return [info exists charsets($charset)]
+}
+
+proc valid_host_charset {charset} {
+    global charsets
+    return $charsets($charset)
+}
+
+gdb_expect {
+    -re "Valid character sets are:\[\r\n\]+" {
+        # There's no ^ at the beginning of the pattern above, so that
+        # expect can skip the echoed `set charset' command.
+        set seen_valid 1
+        exp_continue
+    }
+    -re "^  (\[^ \t\n\]*) \\*\[\r\n\]+" {
+        set charsets($expect_out(1,string)) 1
+        exp_continue
+    }
+    -re "^  (\[^ \t\n\]*)\[ \t\]*\[\r\n\]+" {
+        set charsets($expect_out(1,string)) 0
+        exp_continue
+    }
+    -re "^\\* - can be used as a host character set\[\r\n\]+" {
+        set seen_can_host 1
+        exp_continue
+    }
+    -re ".*${gdb_prompt} $" {
+        # We don't do an exp_continue here.
+    }
+    timeout {
+        fail "get valid character sets (timeout)"
+    }
+}
+
+
+# Check that we've seen all the right pieces of the output, and that
+# we can at least use ASCII as a host character set.
+if {$seen_valid && $seen_can_host && [charset_exists ascii]} {
+    # We can't do the below as part of the test above, since all the
+    # [] substitution takes place before any expression evaluation
+    # takes place; && doesn't really short circuit things the way
+    # you'd like.  We'd get an "can't read $charsets(ascii)" error
+    # even when `info exists' had returned zero.
+    if {[valid_host_charset ascii]} {
+        pass "get valid character sets"
+    } else {
+        fail "get valid character sets"
+    }
+} else {
+    fail "get valid character sets (no ascii charset)"
+}
+
+
+# Try using `set host-charset' on an invalid character set.
+gdb_test "set host-charset my_grandma_bonnie" \
+         "GDB doesn't know of any character set named `my_grandma_bonnie'." \
+         "try `set host-charset' with invalid charset"
+
+
+# Try using `set target-charset' on an invalid character set.
+gdb_test "set target-charset my_grandma_bonnie" \
+         "GDB doesn't know of any character set named `my_grandma_bonnie'." \
+         "try `set target-charset' with invalid charset"
+
+
+# Make sure that GDB supports every host/target charset combination.
+foreach host_charset [all_charset_names] {
+    if {[valid_host_charset $host_charset]} {
+
+        set testname "try `set host-charset $host_charset'"
+        send_gdb "set host-charset $host_charset\n"
+        gdb_expect {
+            -re "GDB doesn't know of any character set named.*\[\r\n]+${gdb_prompt} $" {
+                # How did it get into `charsets' then?
+                fail "$testname (didn't recognize name)"
+            }
+            -re "GDB can't use `.*' as its host character set\\.\[\r\n]+${gdb_prompt} $" {
+                # Well, then why does its `charsets' entry say it can?
+                fail $testname
+            }
+            -re "${gdb_prompt} $" {
+                pass $testname
+            }
+            timeout {
+                fail "$testname (timeout)"
+            }
+        }
+
+        # Check that the command actually had its intended effect:
+        # $host_charset should now be the host character set.
+        send_gdb "show charset\n"
+        set result [parse_show_charset_output "parse `show charset' after `set host-charset $host_charset'"]
+        if {! [string compare [lindex $result 0] $host_charset]} {
+            pass "check effect of `set host-charset $host_charset'"
+        } else {
+            fail "check effect of `set host-charset $host_charset'"
+        }
+
+        # Now try setting every possible target character set,
+        # given that host charset.
+        foreach target_charset [all_charset_names] {
+            set testname "try `set target-charset $target_charset'"
+            send_gdb "set target-charset $target_charset\n"
+            gdb_expect {
+                -re "GDB doesn't know of any character set named.*\[\r\n]+${gdb_prompt} $" {
+                    fail "$testname (didn't recognize name)"
+                }
+                -re "GDB can't convert from the .* character set to .*\\.\[\r\n\]+${gdb_prompt} $" {
+                    # This is a serious problem.  GDB should be able to convert
+                    # between any arbitrary pair of character sets.
+                    fail "$testname (can't convert)"
+                }
+                -re "${gdb_prompt} $" {
+                    pass $testname
+                }
+                timeout {
+                    fail "$testname (timeout)"
+                }
+            }
+
+            # Check that the command actually had its intended effect:
+            # $target_charset should now be the target charset.
+            send_gdb "show charset\n"
+            set result [parse_show_charset_output "parse `show charset' after `set target-charset $target_charset'"]
+            if {! [string compare $result [list $host_charset $target_charset]]} {
+                pass "check effect of `set target-charset $target_charset'"
+            } else {
+                fail "check effect of `set target-charset $target_charset'"
+            }
+
+            # Test handling of characters in the host charset which
+            # can't be translated into the target charset.  \xA2 is
+            # `cent' in ISO-8859-1, which has no equivalent in ASCII.
+            #
+            # On some systems, the pseudo-tty through which we
+            # communicate with GDB insists on stripping the high bit
+            # from input characters, meaning that `cent' turns into
+            # `"'.  Since ISO-8859-1 and ASCII are identical in the
+            # lower 128 characters, it's tough to see how we can test
+            # this behavior on such systems, so we just xfail it.
+           #
+           # Note: the \x16 (Control-V) is an escape to allow \xA2 to
+           # get past readline.
+            if {! [string compare $host_charset iso-8859-1] && ! [string compare $target_charset ascii]} {
+
+                set testname "untranslatable character in character literal"
+                send_gdb "print '\x16\xA2'\n"
+                gdb_expect {
+                    -re "There is no character corresponding to .* in the target character set .*\\.\[\r\n\]+$gdb_prompt $" {
+                        pass $testname
+                    }
+                    -re " = 34 '\"'\[\r\n\]+$gdb_prompt $" {
+                        xfail "$testname (DejaGNU's pseudo-tty strips eighth bit)"
+                    }
+                    -re "$gdb_prompt $" {
+                        fail $testname
+                    }
+                    timeout {
+                        fail "$testname (timeout)"
+                    }
+                }
+
+                set testname "untranslatable character in string literal"
+                # If the PTTY zeros bit seven, then this turns into
+                #   print """
+                # which gets us a syntax error.  We don't care.
+                send_gdb "print \"\x16\xA2\"\n"
+                gdb_expect {
+                    -re "There is no character corresponding to .* in the target character set .*\\.\[\r\n\]+$gdb_prompt $" {
+                        pass $testname
+                    }
+                    -re "Unterminated string in expression.\[\r\n\]+$gdb_prompt $" {
+                        xfail "$testname (DejaGNU's pseudo-tty strips eighth bit)"
+                    }
+                    -re "$gdb_prompt $" {
+                        fail $testname
+                    }
+                    timeout {
+                        fail "$testname (timeout)"
+                    }
+                }
+
+                set testname "untranslatable characters in backslash escape"
+                send_gdb "print '\\\x16\xA2'\n"
+                gdb_expect {
+                    -re "The escape sequence .* is equivalent to plain .*, which has no equivalent\[\r\n\]+in the .* character set\\.\[\r\n\]+$gdb_prompt $" {
+                        pass $testname
+                    }
+                    -re " = 34 '\"'\[\r\n\]+$gdb_prompt $" {
+                        xfail "$testname (DejaGNU's pseudo-tty strips eighth bit)"
+                    }
+                    -re "$gdb_prompt $" {
+                        fail $testname
+                    }
+                    timeout {
+                        fail "$testname (timeout)"
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+# Set the host character set to plain ASCII, and try actually printing
+# some strings in various target character sets.  We need to run the
+# test program to the point at which the strings have been
+# initialized.
+gdb_test "break [gdb_get_line_number "all strings initialized"]" \
+         ".*Breakpoint.* at .*" \
+         "set breakpoint after all strings have been initialized"
+gdb_run_cmd
+gdb_expect {
+    -re "Breakpoint.*all strings initialized.*$gdb_prompt $" {
+        pass "run until all strings have been initialized"
+    }
+    -re "$gdb_prompt $" {
+        fail "run until all strings have been initialized"
+    }
+    timeout {
+        fail "run until all strings have been initialized (timeout)"
+    }
+}
+
+
+gdb_test "set host-charset ascii" ""
+foreach target_charset [all_charset_names] {
+    send_gdb "set target-charset $target_charset\n" 
+    gdb_expect {
+        -re "$gdb_prompt $" {
+            pass "set target-charset $target_charset"
+        }
+        timeout {
+            fail "set target-charset $target_charset (timeout)"
+        }
+    }
+
+    # Try printing the null character.  There seems to be a bug in
+    # gdb_test that requires us to use gdb_expect here.
+    send_gdb "print '\\0'\n"
+    gdb_expect {
+        -re "\\\$${decimal} = 0 '\\\\0'\[\r\n\]+$gdb_prompt $" {
+            pass "print the null character in ${target_charset}"
+        }
+        -re "$gdb_prompt $" {
+            fail "print the null character in ${target_charset}"
+        }
+        timeout {
+            fail "print the null character in ${target_charset} (timeout)"
+        }
+    }
+
+    # Compute the name of the variable in the test program that holds
+    # a string in $target_charset.  The variable's name is the
+    # character set's name, in lower-case, with all non-identifier
+    # characters replaced with '_', with "_string" stuck on the end.
+    set var_name [string tolower "${target_charset}_string"]
+    regsub -all -- "\[^a-z0-9_\]" $var_name "_" var_name
+    
+    # Compute a regexp matching the results we expect.  This is static,
+    # but it's easier than writing it out.
+    regsub -all "." "abefnrtv" "(\\\\&|x)" escapes
+    set uppercase "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    set lowercase "abcdefghijklmnopqrstuvwxyz"
+    set digits "0123456789"
+    set octal_escape "\\\\\[0-9\]\[0-9\]\[0-9\]"
+
+    send_gdb "print $var_name\n"
+    # ${escapes}${uppercase}${lowercase}${digits}${octal}${octal}
+    gdb_expect {
+        -re ".* = \"(\\\\a|x)(\\\\b|x)(\\\\e|x)(\\\\f|x)(\\\\n|x)(\\\\r|x)(\\\\t|x)(\\\\v|x)${uppercase}${lowercase}${digits}(\\\\\[0-9\]\[0-9\]\[0-9\]|x)(\\\\\[0-9\]\[0-9\]\[0-9\]|x).*\"\[\r\n\]+$gdb_prompt $" {
+            pass "print string in $target_charset"
+        }
+        -re "$gdb_prompt $" {
+            fail "print string in $target_charset"
+        }
+        timeout {
+            fail "print string in $target_charset (timeout)"
+        }
+    }
+
+    # Try entering a character literal, and see if it comes back unchanged.
+    gdb_test "print 'A'" \
+             " = \[0-9-\]+ 'A'" \
+             "parse character literal in ${target_charset}"
+
+    # Check that the character literal was encoded correctly.
+    gdb_test "print 'A' == $var_name\[8\]" \
+             " = 1" \
+             "check value of parsed character literal in ${target_charset}"
+
+    # Try entering a string literal, and see if it comes back unchanged.
+    gdb_test "print \"abcdefABCDEF012345\"" \
+             " = \"abcdefABCDEF012345\"" \
+             "parse string literal in ${target_charset}"
+
+    # Check that the string literal was encoded correctly.
+    gdb_test "print \"q\"\[0\] == $var_name\[50\]" \
+             " = 1" \
+             "check value of parsed string literal in ${target_charset}"
+
+    # Test handling of characters in the target charset which
+    # can't be translated into the host charset.
+    if {! [string compare $target_charset iso-8859-1]} {
+        gdb_test "print iso_8859_1_string\[70\]" \
+                 " = \[0-9-\]+ '\\\\242'" \
+                 "print character with no equivalent in host character set"
+        gdb_test "print iso_8859_1_string + 70" \
+                 " = ${hex} \"\\\\242.*\"" \
+                 "print string with no equivalent in host character set"
+    }
+
+    # Make sure that we don't apply the ISO-8859-1 `print_literally'
+    # function to ASCII.
+    if {! [string compare $target_charset ascii]} {
+        gdb_test "print iso_8859_1_string\[70\]" \
+                 " = \[0-9-\]+ '\\\\242'" \
+                 "print ASCII unprintable character"
+        gdb_test "print iso_8859_1_string + 70" \
+                 " = ${hex} \"\\\\242.*\"" \
+                 "print ASCII unprintable string"
+    }
+
+    # Try printing characters with backslash escape equivalents.
+    set escapees {a b e f n r t v}
+    for {set i 0} {$i < [llength $escapees]} {incr i} {
+        set escape [lindex $escapees $i]
+        send_gdb "print $var_name\[$i\]\n"
+        set have_escape 1
+        gdb_expect {
+            -re "= \[0-9-\]+ '\\\\${escape}'\[\r\n\]+$gdb_prompt $" {
+                pass "try printing '\\${escape}' in ${target_charset}"
+            }
+            -re "= \[0-9-\]+ 'x'\[\r\n\]+$gdb_prompt $" {
+                xfail "try printing '\\${escape}' in ${target_charset} (no such escape)"
+                set have_escape 0
+            }
+            -re "$gdb_prompt $" {
+                fail "try printing '\\${escape}' in ${target_charset}"
+            }
+            timeout {
+                fail "try printing '\\${escape}' in ${target_charset} (timeout)"
+            }
+        }
+
+        if {$have_escape} {
+
+            # Try parsing a backslash escape in a character literal.
+            gdb_test "print '\\${escape}' == $var_name\[$i\]" \
+                     " = 1" \
+                     "check value of '\\${escape}' in ${target_charset}"
+
+            # Try parsing a backslash escape in a string literal.
+            gdb_test "print \"\\${escape}\"\[0\] == $var_name\[$i\]" \
+                     " = 1" \
+                     "check value of \"\\${escape}\" in ${target_charset}"
+        }
+    }
+
+    # Try printing a character escape that doesn't exist.  We should 
+    # get the unescaped character, in the target character set.
+    gdb_test "print '\\q'" " = \[0-9-\]+ 'q'" \
+             "print escape that doesn't exist in $target_charset"
+    gdb_test "print '\\q' == $var_name\[50\]" " = 1" \
+             "check value of escape that doesn't exist in $target_charset"
+}
+
+gdb_exit 
diff --git a/gdb/testsuite/gdb.base/pc-fp.c b/gdb/testsuite/gdb.base/pc-fp.c
new file mode 100644 (file)
index 0000000..8c89a0f
--- /dev/null
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+void
+foo (int i)
+{
+  i++;
+  printf ("In foo %d\n", i);
+}
+
+int
+main ()
+{
+  foo (1);
+}
diff --git a/gdb/testsuite/gdb.base/pc-fp.exp b/gdb/testsuite/gdb.base/pc-fp.exp
new file mode 100644 (file)
index 0000000..f94e331
--- /dev/null
@@ -0,0 +1,94 @@
+#   Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# The doco makes reference to built-in registers -- $pc and $fp.  If
+# the ISA contains registers by that name then they should be
+# displayed.  If the ISA contains registers identified as being
+# equivalent, but have different names, then GDB will provide these as
+# aliases.  If the ISA doesn't provide any equivalent registers, then
+# GDB will provide registers that map onto the frame's PC and FP.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "pc-fp"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+proc get_valueofx { fmt exp default } {
+    global gdb_prompt
+    send_gdb "print${fmt} ${exp}\n"
+    gdb_expect {
+       -re "\\$\[0-9\]* = (0x\[0-9a-zA-Z\]+).*$gdb_prompt $" {
+           set val $expect_out(1,string)
+           pass "get value of ${exp} ($val)"
+       }
+       timeout {
+           set size ${default}
+           fail "get value of ${exp} (timeout)"
+       }
+    }
+    return ${val}
+}
+
+# Get the value of PC and FP
+
+set valueof_pc [get_valueofx "/x" "\$pc" "0"]
+set valueof_fp [get_valueofx "/x" "\$fp" "0"]
+
+# Check that the sequence $REGNAME -> REGNUM -> $REGNAME works.  Use
+# display since that encodes and then decodes the expression parameter
+# (and hence uses the mechanisms we're trying to test).
+
+gdb_test "display/i \$pc" "1: x/i +\\\$pc +${valueof_pc}.*"
+gdb_test "display/w \$fp" "2: x/xw +\\\$fp +${valueof_fp}.*"
+
+# FIXME: cagney/2002-09-04: Should also check that ``info registers
+# $pc'' et.al.'' come back with the same value as the above displays
+# and a print --- assuming that is that people agree to such behavour.
+# Need to re-write default_print_registers_info() for it to work (and
+# such a rewrite is on the reggroups branch).
+
+# gdb_test "info registers \$pc" "${valueof_pc}"
+# gdb_test "info registers \$fp" "${valueof_fp}"
diff --git a/gdb/testsuite/gdb.c++/m-static.h b/gdb/testsuite/gdb.c++/m-static.h
new file mode 100644 (file)
index 0000000..137d3b7
--- /dev/null
@@ -0,0 +1,11 @@
+// 2002-08-16
+
+class gnu_obj_4
+{
+ public:
+  static const int elsewhere;
+  static const int nowhere;
+  // At some point, perhaps:
+  // static const int everywhere = 317;
+};
+
diff --git a/gdb/testsuite/gdb.c++/m-static1.cc b/gdb/testsuite/gdb.c++/m-static1.cc
new file mode 100644 (file)
index 0000000..f88c9ce
--- /dev/null
@@ -0,0 +1,9 @@
+// 2002-08-16
+
+namespace __gnu_test {
+#include "m-static.h"
+}
+
+using namespace __gnu_test;
+
+const int gnu_obj_4::elsewhere = 221;
diff --git a/gdb/testsuite/gdb.c++/pr-574.cc b/gdb/testsuite/gdb.c++/pr-574.cc
new file mode 100644 (file)
index 0000000..eb06b61
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+  An attempt to replicate PR gdb/574 with a shorter program.
+
+  Printing out *theB failed if the program was compiled with GCC 2.95.
+*/
+
+class A {
+public:
+  virtual void foo() {};               // Stick in a virtual function.
+  int a;                               // Stick in a data member.
+};
+
+class B : public A {
+  static int b;                                // Stick in a static data member.
+};
+
+int main()
+{
+  B *theB = new B;
+
+  return 0;                            // breakpoint: constructs-done
+}
diff --git a/gdb/testsuite/gdb.c++/pr-574.exp b/gdb/testsuite/gdb.c++/pr-574.exp
new file mode 100644 (file)
index 0000000..5beacd1
--- /dev/null
@@ -0,0 +1,72 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Tests for the bug mentioned in PR gdb/574.  It's a bit
+# idiosyncratic, so I gave it its own file.
+
+# 2002-08-16  David Carlton <carlton@math.stanford.edu>
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+        strace $tracelevel
+        }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "pr-574"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# First, run to after we've constructed the object:
+
+gdb_breakpoint [gdb_get_line_number "constructs-done"]
+gdb_continue_to_breakpoint "end of constructors"
+
+# This failed, as long as the code was compiled with GCC v. 2.
+
+# Different compilers order the data for <A> differently, so I'm not
+# matching the result exactly.
+
+gdb_test "print *theB" "\\$\[0-9\]* = {<A> = {\[^}\]*}, static b = <optimized out>}" "PR gdb/574"
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.c++/printmethod.cc b/gdb/testsuite/gdb.c++/printmethod.cc
new file mode 100644 (file)
index 0000000..d32e1b1
--- /dev/null
@@ -0,0 +1,14 @@
+/* Create some objects, and try to print out their methods.  */
+
+class A {
+public:
+  virtual void virt() {};
+  void nonvirt() {};
+};
+
+int main()
+{
+  A *theA = new A;
+
+  return 0;                            // breakpoint: constructs-done
+}
diff --git a/gdb/testsuite/gdb.c++/printmethod.exp b/gdb/testsuite/gdb.c++/printmethod.exp
new file mode 100644 (file)
index 0000000..9b96cbf
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# This tries to print out methods of classes.
+
+# 2002-08-16  David Carlton <carlton@math.stanford.edu>
+
+# This file is part of the gdb testsuite
+
+if $tracelevel then {
+        strace $tracelevel
+        }
+
+if { [skip_cplus_tests] } { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "printmethod"
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+if [get_compiler_info ${binfile} "c++"] {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+
+if ![runto_main] then {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# First, run to after we've constructed the object:
+
+gdb_breakpoint [gdb_get_line_number "constructs-done"]
+gdb_continue_to_breakpoint "end of constructors"
+
+# The first of these is for PR gdb/653.
+
+gdb_test "print theA->virt" "\\$\[0-9\]* = &A::virt\\(\\)" "print virtual method."
+gdb_test "print theA->nonvirt" "Cannot take address of a method" "print nonvirtual method."
+
+gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.gdb/complaints.exp b/gdb/testsuite/gdb.gdb/complaints.exp
new file mode 100644 (file)
index 0000000..3d3426f
--- /dev/null
@@ -0,0 +1,318 @@
+#   Copyright 2002
+#   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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Andrew Cagney (cagney at redhat dot com),
+# derived from xfullpath.exp (written by Joel Brobecker), derived from
+# selftest.exp (written by Rob Savoye).
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# are we on a target board
+if [is_remote target] {
+    return
+}
+
+proc setup_test { executable } {
+    global gdb_prompt
+    global timeout
+
+    # load yourself into the debugger
+    # This can take a relatively long time, particularly for testing where
+    # the executable is being accessed over a network, or where gdb does not
+    # support partial symbols for a particular target and has to load the
+    # entire symbol table.  Set the timeout to 10 minutes, which should be
+    # adequate for most environments (it *has* timed out with 5 min on a
+    # SPARCstation SLC under moderate load, so this isn't unreasonable).
+    # After gdb is started, set the timeout to 30 seconds for the duration
+    # of this test, and then back to the original value.
+
+    set oldtimeout $timeout
+    set timeout 600
+    verbose "Timeout is now $timeout seconds" 2
+    if {[gdb_load $executable] <0} then {
+       set timeout $oldtimeout
+       verbose "Timeout is now $timeout seconds" 2
+       return -1
+    }
+    set timeout $oldtimeout
+    verbose "Timeout is now $timeout seconds" 2
+
+    # Set a breakpoint at main
+    gdb_test "break captured_command_loop" \
+            "Breakpoint.*at.* file.*, line.*" \
+            "breakpoint in captured_command_loop"
+
+    # run yourself
+    # It may take a very long time for the inferior gdb to start (lynx),
+    # so we bump it back up for the duration of this command.
+    set timeout 600
+
+    set description "run until breakpoint at captured_command_loop"
+    send_gdb "run -nw\n"
+    gdb_expect {
+        -re "Starting program.*Breakpoint \[0-9\]+,.*captured_command_loop .data.* at .*main.c:.*$gdb_prompt $" {
+            pass "$description"
+        }
+        -re "Starting program.*Breakpoint \[0-9\]+,.*captured_command_loop .data.*$gdb_prompt $" {
+            xfail "$description (line numbers scrambled?)"
+        }
+        -re "vfork: No more processes.*$gdb_prompt $" {
+            fail "$description (out of virtual memory)"
+            set timeout $oldtimeout
+            verbose "Timeout is now $timeout seconds" 2
+            return -1
+        }
+        -re ".*$gdb_prompt $" {
+            fail "$description"
+            set timeout $oldtimeout
+            verbose "Timeout is now $timeout seconds" 2
+            return -1
+        }
+        timeout {
+            fail "$description (timeout)"
+        }
+    }
+
+    set timeout $oldtimeout
+    verbose "Timeout is now $timeout seconds" 2
+
+    return 0
+}
+
+proc test_initial_complaints { } {
+
+    global gdb_prompt
+
+    # Unsupress complaints
+    gdb_test "set stop_whining = 2"
+
+    # Prime the system
+    gdb_test "call complaint (&symfile_complaints, \"Register a complaint\")" \
+           "During symbol reading, Register a complaint."
+
+    # Check that the complaint was inserted and where
+    gdb_test "print symfile_complaints->root->fmt" \
+           ".\[0-9\]+ =.*\"Register a complaint\""
+
+    # Re-issue the first message #1
+    gdb_test "call complaint (&symfile_complaints, symfile_complaints->root->fmt)" \
+           "During symbol reading, Register a complaint."
+
+    # Check that there is only one thing in the list
+    gdb_test "print symfile_complaints->root->next == &complaint_sentinel" \
+           ".\[0-9\]+ = 1" "list has one entry"
+
+    # Add a second complaint, expect it
+    gdb_test "call complaint (&symfile_complaints, \"Testing! Testing! Testing!\")" \
+           "During symbol reading, Testing. Testing. Testing.."
+
+    return 0
+}
+
+proc test_serial_complaints { } {
+
+    global gdb_prompt
+
+    gdb_test_exact "call clear_complaints (&symfile_complaints, 1, 0)" "" "serial start"
+
+    # Prime the system
+    send_gdb "call complaint (&symfile_complaints, \"serial line  1\")\n"
+    gdb_expect {
+       -re "During symbol reading...serial line  1...$gdb_prompt " {
+           pass "serial line 1"
+       }
+       "$gdb_prompt" {
+           fail "serial line  1"
+       }
+       timeout {
+           fail "serial line  1 (timeout)"
+       }
+    }
+
+    # Add a second complaint, expect it
+    send_gdb "call complaint (&symfile_complaints, \"serial line 2\")\n"
+    gdb_expect {
+       -re "serial line 2...$gdb_prompt " {
+           pass "serial line 2"
+       }
+       "$gdb_prompt" {
+           fail "serial line 2"
+       }
+       timeout {
+           fail "serial line 2 (timeout)"
+       }
+    }
+
+    send_gdb "call clear_complaints (&symfile_complaints, 1, 0)\n"
+    gdb_expect {
+       -re "\r\n\r\n$gdb_prompt " {
+           pass "serial end"
+       }
+       "$gdb_prompt" {
+           fail "serial end"
+       }
+       timeout {
+           fail "serial end (timeout)"
+       }
+    }
+
+    return 0
+}
+
+# For short complaints, all are the same
+
+proc test_short_complaints { } {
+
+    global gdb_prompt
+
+    gdb_test_exact "call clear_complaints (&symfile_complaints, 1, 1)" "" "short start"
+
+    # Prime the system
+    send_gdb "call complaint (&symfile_complaints, \"short line 1\")\n"
+    gdb_expect {
+       -re "short line 1...$gdb_prompt " {
+           pass "short line 1"
+       }
+       "$gdb_prompt" {
+           fail "short line 1"
+       }
+       timeout {
+           fail "short line 1 (timeout)"
+       }
+    }
+
+    # Add a second complaint, expect it
+    send_gdb "call complaint (&symfile_complaints, \"short line 2\")\n"
+    gdb_expect {
+       -re "short line 2...$gdb_prompt " {
+           pass "short line 2"
+       }
+       "$gdb_prompt" {
+           fail "short line 2"
+       }
+       timeout {
+           fail "short line 2 (timeout)"
+       }
+    }
+
+    send_gdb "call clear_complaints (&symfile_complaints, 1, 0)\n"
+    gdb_expect {
+       -re "\r\n\r\n$gdb_prompt " {
+           pass "short end"
+       }
+       "$gdb_prompt" {
+           fail "short end"
+       }
+       timeout {
+           fail "short end (timeout)"
+       }
+    }
+
+    return 0
+}
+
+# Check that nothing comes out when there haven't been any real
+# complaints.  Note that each test is really checking the previous
+# command.
+
+proc test_empty_complaint { cmd msg } {
+    global gdb_prompt
+    send_gdb $cmd
+    gdb_expect {
+       -re "\r\n\r\n$gdb_prompt " {
+           fail $msg
+       }
+       "\r\n$gdb_prompt" {
+           pass $msg
+       }
+       timeout {
+           fail "$msg (timeout)"
+       }
+    }
+  
+}
+
+proc test_empty_complaints { } {
+
+    test_empty_complaint "call clear_complaints(&symfile_complaints,0,0)\n" \
+           "empty non-verbose non-noisy clear"
+    test_empty_complaint "call clear_complaints(&symfile_complaints,1,0)\n" \
+           "empty verbose non-noisy clear"
+    test_empty_complaint "call clear_complaints(&symfile_complaints,1,1)\n" \
+           "empty verbose noisy clear"
+    test_empty_complaint "call clear_complaints(&symfile_complaints,0,1)\n" \
+           "empty non-verbose noisy clear"
+
+    return 0
+}
+
+# Find a pathname to a file that we would execute if the shell was asked
+# to run $arg using the current PATH.
+
+proc find_gdb { arg } {
+
+    # If the arg directly specifies an existing executable file, then
+    # simply use it.
+
+    if [file executable $arg] then {
+       return $arg
+    }
+
+    set result [which $arg]
+    if [string match "/" [ string range $result 0 0 ]] then {
+       return $result
+    }
+
+    # If everything fails, just return the unqualified pathname as default
+    # and hope for best.
+
+    return $arg
+}
+
+# Run the test with self.
+# Copy the file executable file in case this OS doesn't like to edit its own
+# text space.
+
+set GDB_FULLPATH [find_gdb $GDB]
+
+# Remove any old copy lying around.
+remote_file host delete x$tool
+
+gdb_start
+
+set file [remote_download host $GDB_FULLPATH x$tool]
+
+set setup_result [setup_test $file ]
+if {$setup_result <0} then {
+    return -1
+}
+
+test_initial_complaints
+test_serial_complaints
+test_short_complaints
+test_empty_complaints
+
+gdb_exit;
+catch "remote_file host delete $file";
diff --git a/gdb/testsuite/gdb.mi/gdb669.exp b/gdb/testsuite/gdb.mi/gdb669.exp
new file mode 100644 (file)
index 0000000..4f294b9
--- /dev/null
@@ -0,0 +1,200 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file checks for the bug gdb/669, where the console
+# command "info threads" and the MI command "-thread-list-ids"
+# return different threads in the system.
+
+# This only works with native configurations
+if {![isnative]} {
+  return
+}
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if {[mi_gdb_start]} {
+    continue
+}
+
+# The procs below are all stolen from mi-pthreads.exp. Any updates
+# should also be made to the procs there.
+
+proc get_mi_thread_list {name} {
+  global expect_out
+
+  # MI will return a list of thread ids:
+  #
+  # -thread-list-ids
+  # ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
+  # (gdb)
+  mi_gdb_test "-thread-list-ids" \
+    {\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},number-of-threads="[0-9]+"} \
+    "-thread_list_ids ($name)"
+
+  set output {}
+  if {[info exists expect_out(buffer)]} {
+    set output $expect_out(buffer)
+  }
+  set thread_list {}
+  if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $output threads]} {
+    fail "finding threads in MI output ($name)"
+  } else {
+    pass "finding threads in MI output ($name)"
+
+    # Make list of console threads
+    set start [expr {[string first \{ $threads] + 1}]
+    set end   [expr {[string first \} $threads] - 1}]
+    set threads [string range $threads $start $end]
+    foreach thread [split $threads ,] {
+      if {[scan $thread {thread-id="%d"} num]} {
+       lappend thread_list $num
+      }
+    }
+  }
+
+  return $thread_list
+}
+
+# Check that MI and the console know of the same threads.
+# Appends NAME to all test names.
+proc check_mi_and_console_threads {name} {
+  global expect_out
+
+  mi_gdb_test "-thread-list-ids" \
+    {\^done,thread-ids={(thread-id="[0-9]+"(,)*)+},number-of-threads="[0-9]+"} \
+    "-thread-list-ids ($name)"
+  set mi_output {}
+  if {[info exists expect_out(buffer)]} {
+    set mi_output $expect_out(buffer)
+  }
+
+  # GDB will return a list of thread ids and some more info:
+  #
+  # (gdb) 
+  # -interpreter-exec console "info threads"
+  # ~"  4 Thread 2051 (LWP 7734)  0x401166b1 in __libc_nanosleep () at __libc_nanosleep:-1"
+  # ~"  3 Thread 1026 (LWP 7733)   () at __libc_nanosleep:-1"
+  # ~"  2 Thread 2049 (LWP 7732)  0x401411f8 in __poll (fds=0x804bb24, nfds=1, timeout=2000) at ../sysdeps/unix/sysv/linux/poll.c:63"
+  # ~"* 1 Thread 1024 (LWP 7731)  main (argc=1, argv=0xbfffdd94) at ../../../src/gdb/testsuite/gdb.mi/pthreads.c:160"
+  # FIXME: kseitz/2002-09-05: Don't use the hack-cli method.
+  mi_gdb_test "info threads" \
+    {.*(~".*"[\r\n]*)+.*} \
+    "info threads ($name)"
+  set console_output {}
+  if {[info exists expect_out(buffer)]} {
+    set console_output $expect_out(buffer)
+  }
+
+  # Make a list of all known threads to console (gdb's thread IDs)
+  set console_thread_list {}
+  foreach line [split $console_output \n] {
+    if {[string index $line 0] == "~"} {
+      # This is a line from the console; trim off "~", " ", "*", and "\""
+      set line [string trim $line ~\ \"\*]
+      if {[scan $line "%d" id] == 1} {
+       lappend console_thread_list $id
+      }
+    }
+  }
+
+  # Now find the result string from MI
+  set mi_result ""
+  foreach line [split $mi_output \n] {
+    if {[string range $line 0 4] == "^done"} {
+      set mi_result $line
+    }
+  }
+  if {$mi_result == ""} {
+    fail "finding MI result string ($name)"
+  } else {
+    pass "finding MI result string ($name)"
+  }
+
+  # Finally, extract the thread ids and compare them to the console
+  set num_mi_threads_str ""
+  if {![regexp {number-of-threads="[0-9]+"} $mi_result num_mi_threads_str]} {
+    fail "finding number of threads in MI output ($name)"
+  } else {
+    pass "finding number of threads in MI output ($name)"
+
+    # Extract the number of threads from the MI result
+    if {![scan $num_mi_threads_str {number-of-threads="%d"} num_mi_threads]} {
+      fail "got number of threads from MI ($name)"
+    } else {
+      pass "got number of threads from MI ($name)"
+
+      # Check if MI and console have same number of threads
+      if {$num_mi_threads != [llength $console_thread_list]} {
+       fail "console and MI have same number of threads ($name)"
+      } else {
+       pass "console and MI have same number of threads ($name)"
+
+       # Get MI thread list
+       set mi_thread_list [get_mi_thread_list $name]
+
+       # Check if MI and console have the same threads
+       set fails 0
+       foreach ct [lsort $console_thread_list] mt [lsort $mi_thread_list] {
+         if {$ct != $mt} {
+           incr fails
+         }
+       }
+       if {$fails > 0} {
+         fail "MI and console have same threads ($name)"
+
+         # Send a list of failures to the log
+         send_log "Console has thread ids: $console_thread_list\n"
+         send_log "MI has thread ids: $mi_thread_list\n"
+       } else {
+         pass "MI and console have same threads ($name)"
+       }
+      }
+    }
+  }
+}
+
+#
+# Start here
+#
+set testfile "pthreads"
+set srcfile "$testfile.c"
+set binfile "$objdir/$subdir/$testfile"
+
+set options [list debug incdir=$subdir]
+if  {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile executable $options]
+     != "" } {
+  gdb_suppress_entire_file \
+    "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load $binfile
+
+mi_run_to_main
+check_mi_and_console_threads "at main"
+
+for {set i 0} {$i < 4} {incr i} {
+  mi_next "next, try $i"
+  check_mi_and_console_threads "try $i"
+}
+
+mi_gdb_exit
+
diff --git a/gdb/testsuite/gdb.mi/gdb680.exp b/gdb/testsuite/gdb.mi/gdb680.exp
new file mode 100644 (file)
index 0000000..eee96a6
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test gdb/680
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+proc do_test {count} {
+  mi_gdb_test "-data-list-register-names -1" \
+    {\^error,msg=\"bad register number\"} \
+    "-data-list-register-names -1, try $count"
+}
+
+# Tests a bug with ui-out and nested uiout types. When 
+# an error is encountered building a nest typed, like
+# lists or tuples, the uiout is not reset to some sane
+# state. As a result, uiout still thinks it is building
+# this nested type. Execute enough of these errors and
+# an assertion failure occurs. This is most obvious
+# with invalid register number and the register commands.
+
+# MAX_UIOUT_LEVELS is set to 5.
+set counter 0
+for {set i 0} {$i < 4} {incr i} {
+  do_test $i
+}
+
+#setup_kfail "gdb/680"
+do_test $i
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.mi/gdb701.c b/gdb/testsuite/gdb.mi/gdb701.c
new file mode 100644 (file)
index 0000000..16e5c29
--- /dev/null
@@ -0,0 +1,15 @@
+struct _foo
+{
+  int x;
+  int y;
+  int z;
+};
+
+typedef struct _foo Foo;
+
+int
+main (int argc, char *argv[])
+{
+  Foo *foo = 0;
+  exit (0);
+}
diff --git a/gdb/testsuite/gdb.mi/gdb701.exp b/gdb/testsuite/gdb.mi/gdb701.exp
new file mode 100644 (file)
index 0000000..703ec6a
--- /dev/null
@@ -0,0 +1,67 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+#
+# test gdb/701
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile gdb701
+set srcfile "$testfile.c"
+set binfile $objdir/$subdir/$testfile
+if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable debug] != ""} {
+  gdb_suppress_entire_file "Testcase compile failed, so all test in this file will automatically fail."
+}
+
+# When varobj reports the types of objects, it often isn't really reporting
+# the type as GDB knows it. For example, in this testcase, we have a
+# structure which has been typedefed. A varobj of this type would really have
+# a type of "TYPE_CODE_TYPEDEF". It's target type is "TYPE_CODE_STRUCT". Varobj
+# should skip over the TYPEDEF type when figuring out the varobj's children.
+# If it doesn't, Bad Things Happen(TM).
+
+# Run to main
+mi_run_to_main
+
+# Step over "foo = 0"
+mi_next "step over \"foo = 0\""
+
+mi_gdb_test "-var-create fooPtr * foo" \
+  "(&\".*\"\r\n)*\\^done,name=\"fooPtr\",numchild=\"3\",type=\"Foo \\*\"" \
+  "create fooPtr"
+
+mi_gdb_test "-var-list-children fooPtr" \
+  "(&\".*\"\r\n)*\\^done,numchild=\"3\",.*" \
+  "list children of fooPtr"
+
+foreach i [list x y z] {
+  mi_gdb_test "-var-list-children fooPtr.$i" \
+    "(&\".*\"\r\n)*\\^done,numchild=\"0\"" \
+    "list children of fooPtr.$i"
+}
+
+mi_gdb_exit
+return 0
diff --git a/gdb/testsuite/gdb.threads/killed.c b/gdb/testsuite/gdb.threads/killed.c
new file mode 100644 (file)
index 0000000..6cb3928
--- /dev/null
@@ -0,0 +1,24 @@
+#include <sys/types.h>
+#include <signal.h>
+#include <pthread.h>
+#include <stdio.h>
+
+int pid;
+
+void *
+child_func (void *dummy)
+{
+  kill (pid, SIGKILL);
+  exit (1);
+}
+
+int
+main ()
+{
+  pthread_t child;
+
+  pid = getpid ();
+  pthread_create (&child, 0, child_func, 0);
+  for (;;)
+    sleep (10000);
+}
diff --git a/gdb/testsuite/gdb.threads/killed.exp b/gdb/testsuite/gdb.threads/killed.exp
new file mode 100644 (file)
index 0000000..21e03aa
--- /dev/null
@@ -0,0 +1,97 @@
+# Copyright 2002 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 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This is a regression test for gdb/568 in the sources.redhat.com
+# GNATS database.  As of early June 2002, GDB could get sort of wedged
+# debugging the program `killed.c':
+#
+# $ $D6/gdb/gdb -nw killed
+# GNU gdb 2002-06-11-cvs
+# Copyright 2002 Free Software Foundation, Inc.
+# GDB is free software, covered by the GNU General Public License, and you are
+# welcome to change it and/or distribute copies of it under certain conditions.
+# Type "show copying" to see the conditions.
+# There is absolutely no warranty for GDB.  Type "show warranty" for details.
+# This GDB was configured as "i686-pc-linux-gnu"...
+# (gdb) run
+# Starting program: /home/jimb/foo/play/killed 
+# [New Thread 1024 (LWP 6487)]
+# [New Thread 2049 (LWP 6488)]
+# [New Thread 1026 (LWP 6489)]
+# Cannot find user-level thread for LWP 6487: generic error
+# (gdb) quit
+# The program is running.  Exit anyway? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb) kill
+# Kill the program being debugged? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb) The program is running.  Exit anyway? (y or n) y
+# Cannot find thread 2049: generic error
+# (gdb) 
+# [7]+  Stopped                 $D6/gdb/gdb -nw killed
+# $ kill %7
+# 
+# [7]+  Stopped                 $D6/gdb/gdb -nw killed
+# $ kill -9 %7
+# 
+# [7]+  Stopped                 $D6/gdb/gdb -nw killed
+# $ 
+# [7]+  Killed                  $D6/gdb/gdb -nw killed
+# $ 
+
+if $tracelevel then {
+       strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "killed"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}/${subdir}"]] != "" } {
+    gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "run" "" "run program to completion"
+
+# Try to quit.
+send_gdb "quit\n"
+gdb_expect {
+    -re "The program is running.  Exit anyway\\? \\(y or n\\) $" {
+        send_gdb "y\n"
+        exp_continue
+    }
+    eof {
+        pass "GDB exits after multi-threaded program exits messily"
+    }
+    -re "Cannot find thread ${decimal}: generic error\[\r\n\]*$gdb_prompt $" {
+        # setup_kfail "gdb/568"
+        fail "GDB exits after multi-threaded program exits messily (not a regression; gdb/568)"
+    }
+    timeout {
+        fail "GDB exits after multi-threaded program exits messily (timeout)"
+    }
+}
diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c
new file mode 100644 (file)
index 0000000..82f263e
--- /dev/null
@@ -0,0 +1,175 @@
+/* Demangler test program,
+   Copyright (C) 2002 Free Software Foundation, Inc.
+   Written by Zack Weinberg <zack@codesourcery.com
+
+   This file is part of GNU libiberty.
+
+   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 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "ansidecl.h"
+#include <stdio.h>
+#include "libiberty.h"
+#include "demangle.h"
+
+struct line
+{
+  size_t alloced;
+  char *data;
+};
+
+static unsigned int lineno;
+
+/* Safely read a single line of arbitrary length from standard input.  */
+
+#define LINELEN 80
+
+static void
+getline(buf)
+     struct line *buf;
+{
+  char *data = buf->data;
+  size_t alloc = buf->alloced;
+  size_t count = 0;
+  int c;
+
+  if (data == 0)
+    {
+      data = xmalloc (LINELEN);
+      alloc = LINELEN;
+    }
+
+  /* Skip comment lines.  */
+  while ((c = getchar()) == '#')
+    {
+      while ((c = getchar()) != EOF && c != '\n');
+      lineno++;
+    }
+
+  /* c is the first character on the line, and it's not a comment
+     line: copy this line into the buffer and return.  */
+  while (c != EOF && c != '\n')
+    {
+      if (count >= alloc)
+       {
+         alloc *= 2;
+         data = xrealloc (data, alloc);
+       }
+      data[count++] = c;
+      c = getchar();
+    }
+  lineno++;
+  data[count] = '\0';
+
+  buf->data = data;
+  buf->alloced = alloc;
+}
+
+/* The tester operates on a data file consisting of triples of lines:
+   format switch
+   input to be demangled
+   expected output
+
+   The format switch is expected to be either the empty string, a
+   line of the form --format=<name>, or just <name> by itself.  */
+
+#define FORMATS "--format="
+#define FORMATL (sizeof FORMATS - 1)
+
+int
+main(argc, argv)
+     int argc;
+     char **argv;
+{
+  enum demangling_styles style;
+  struct line format;
+  struct line input;
+  struct line expect;
+  char *fstyle;
+  char *result;
+  int failures = 0;
+  int tests = 0;
+
+  if (argc > 1)
+    {
+      fprintf (stderr, "usage: %s < test-set\n", argv[0]);
+      return 2;
+    }
+
+  format.data = 0;
+  input.data = 0;
+  expect.data = 0;
+
+  for (;;)
+    {
+      getline (&format);
+      if (feof (stdin))
+       break;
+
+      getline (&input);
+      getline (&expect);
+
+      tests++;
+
+      fstyle = format.data;
+      if (!strncmp (fstyle, FORMATS, FORMATL))
+       fstyle += FORMATL;
+
+      if (fstyle[0] == '\0')
+       style = auto_demangling;
+      else
+       style = cplus_demangle_name_to_style (fstyle);
+
+      if (style == unknown_demangling)
+       {
+         printf ("FAIL at line %d: unknown demangling style %s\n",
+                 lineno, fstyle);
+         failures++;
+         continue;
+       }
+
+      cplus_demangle_set_style (style);
+
+      result = cplus_demangle (input.data,
+                              DMGL_PARAMS|DMGL_ANSI|DMGL_VERBOSE|DMGL_TYPES);
+
+      if (result
+         ? strcmp (result, expect.data)
+         : strcmp (input.data, expect.data))
+       {
+         printf ("\
+FAIL at line %d, style %s:\n\
+in:  %s\n\
+out: %s\n\
+exp: %s\n",
+                  lineno, fstyle,
+                  input.data,
+                  result,
+                  expect.data);
+         failures++;
+       }
+      free (result);
+    }
+
+  free (format.data);
+  free (input.data);
+  free (expect.data);
+
+  printf ("%s: %d tests, %d failures\n", argv[0], tests, failures);
+  return failures ? 1 : 0;
+}