Merge remote-tracking branch

'origin/GT-3481-dragonmacher-gnu-demangler-update'

Fixes #1195, fixes #1308, fixes #1454, fixes #1451
This commit is contained in:
ghidorahrex
2020-02-18 10:53:58 -05:00
105 changed files with 17388 additions and 1217 deletions
+99 -31
View File
@@ -12,6 +12,12 @@ apply plugin: 'eclipse'
eclipse.project.name = 'GPL DemanglerGnu'
def v33_1 = "demangler_gnu_v2_33_1"
def v24 = "demangler_gnu_v2_24"
def srcVersion33_1 = "src/demangler_gnu_v2_33_1"
def srcVersion24 = "src/demangler_gnu_v2_24"
/****************************************************************************
* Defines the platforms we have to support in Ghidra. This model is used
* for all native builds and should be extended by each module as-needed.
@@ -53,65 +59,127 @@ task zipBuildableSource(type:Zip) {
description "Collects the source files needed to build this module."
baseName project.name + "-src-for-build"
extension 'zip'
from (project.projectDir.toString() + "/src/demangler_gnu/c") {
into "/src/demangler_gnu"
//
// Version 2.33.1
//
from (project.projectDir.toString() + "/" + srcVersion33_1 + "c") {
into "/" + srcVersion33_1
}
from (project.projectDir.toString() + "/src/demangler_gnu/headers") {
into "/src/demangler_gnu"
from (project.projectDir.toString() + "/" + srcVersion33_1 + "/headers") {
into "/" + srcVersion33_1
}
from (project.projectDir.toString() + "/src/demangler_gnu/build") {
into "/src/demangler_gnu"
from (project.projectDir.toString() + "/" + srcVersion33_1 + "/build") {
into "/" + srcVersion33_1
}
from (project.projectDir.toString() + "/src/demangler_gnu/README.txt")
from (project.projectDir.toString() + "/" + srcVersion33_1 + "/README.txt")
//
// Version 2.24
//
from (project.projectDir.toString() + "/" + srcVersion24 + "c") {
into "/" + srcVersion24
}
from (project.projectDir.toString() + "/" + srcVersion24 + "/headers") {
into "/" + srcVersion24
}
from (project.projectDir.toString() + "/" + srcVersion24 + "/build") {
into "/" + srcVersion24
}
from (project.projectDir.toString() + "/" + srcVersion24 + "/README.txt")
}
model {
//
// Version 2.33.1
//
components {
demangler_gnu(NativeExecutableSpec) {
demangler_gnu_v2_33_1(NativeExecutableSpec) {
targetPlatform "win64"
targetPlatform "linux64"
targetPlatform "osx64"
sources {
c {
source {
srcDir "src/demangler_gnu/c"
srcDir srcVersion33_1 + "/c"
}
exportedHeaders {
srcDir "src/demangler_gnu/headers"
srcDir srcVersion33_1 + "/headers"
}
}
}
}
}
//
// Version 2.24
//
demangler_gnu_v2_24(NativeExecutableSpec) {
targetPlatform "win64"
targetPlatform "linux64"
targetPlatform "osx64"
sources {
c {
source {
srcDir srcVersion24 + "/c"
}
exportedHeaders {
srcDir srcVersion24 + "/headers"
}
}
}
}
}
}
model {
binaries {
/*
Note: 'all' will pass all binary output, which is each platform for each version
*/
all{ b ->
if (toolChain in Gcc) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
if (targetPlatform.operatingSystem.linux) {
// linker.args "-static"
def version = b.getApplication().getName()
println "have binary: " + b
if (version.equals(v33_1)) {
if (toolChain in Gcc) {
//cCompiler.args "-DCP_DEMANGLE_DEBUG"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in VisualCpp) {
cCompiler.args "/D_CONSOLE"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in Clang) {
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
}
else if (toolChain in VisualCpp) {
cCompiler.args "/D_CONSOLE"
cCompiler.args "/DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in Clang) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
if (targetPlatform.operatingSystem.linux) {
// linker.args "-static"
else if (version.equals(v24)) {
if (toolChain in Gcc) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in VisualCpp) {
cCompiler.args "/D_CONSOLE"
cCompiler.args "/DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
else if (toolChain in Clang) {
cCompiler.args "-DMAIN_CPLUS_DEM"
cCompiler.args "-DHAVE_STDLIB_H"
cCompiler.args "-DHAVE_STRING_H"
}
}
}
}
}
+2 -1
View File
@@ -7,4 +7,5 @@
Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END|
settings.gradle||Public Domain||||END|
src/demangler_gnu/README.txt||Public Domain||||END|
src/demangler_gnu_v2_24/README.txt||Public Domain||||END|
src/demangler_gnu_v2_33_1/README.txt||Public Domain||||END|
@@ -1,5 +1,5 @@
/* ###
* IP: GPL 3 Linking Permitted
* IP: LGPL 2.1
*/
/* Demangler for g++ V3 ABI.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
@@ -31,12 +31,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
CHANGE NOTICE:
This file was changed on July 1st, 2014.
CHANGE NOTICE:
This file was changed on July 4th, 2019.
This file was changed on July 22nd, 2020
This file was changed on Jan 22, 2020
- Added a method to wrap calls to d_print_comp() in order to track too much recursion
*/
/* This code implements a demangler for the g++ V3 ABI. The ABI is
@@ -312,6 +311,11 @@ struct d_print_info
int pack_index;
/* Number of d_print_flush calls so far. */
unsigned long int flush_count;
// Changed Jan 22, 2020 - Added a method to wrap calls to d_print_comp() in
// order to track too much recursion
int recursion_level;
};
#ifdef CP_DEMANGLE_DEBUG
@@ -470,6 +474,12 @@ static inline char d_last_char (struct d_print_info *);
static void
d_print_comp (struct d_print_info *, int, const struct demangle_component *);
// Changed Jan 22, 2020 - Added a method to wrap calls to d_print_comp() in
// order to track too much recursion
static void
d_print_comp_delegate (struct d_print_info *, int, const struct demangle_component *);
static void
d_print_java_identifier (struct d_print_info *, const char *, int);
@@ -3670,6 +3680,7 @@ static void
d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
void *opaque)
{
dpi->len = 0;
dpi->last_char = '\0';
dpi->templates = NULL;
@@ -3681,6 +3692,10 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
dpi->opaque = opaque;
dpi->demangle_failure = 0;
// Changed Jan 22, 2020 - Added a method to wrap calls to d_print_comp() in
// order to track too much recursion
dpi->recursion_level = 0;
}
/* Indicate that an error occurred during printing, and test for error. */
@@ -3931,10 +3946,28 @@ d_print_subexpr (struct d_print_info *dpi, int options,
/* Subroutine to handle components. */
// Changed Jan 22, 2020 - Added a method to wrap calls to d_print_comp() in
// order to track too much recursion
static void
d_print_comp (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
if (dpi->recursion_level > DEMANGLE_RECURSION_LIMIT) {
d_print_error (dpi);
return;
}
dpi->recursion_level++;
d_print_comp_delegate(dpi, options, dc);
dpi->recursion_level--;
}
static void
d_print_comp_delegate (struct d_print_info *dpi, int options,
const struct demangle_component *dc)
{
/* Magic variable to let reference smashing skip over the next modifier
without needing to modify *dc. */
const struct demangle_component *mod_inner = NULL;
@@ -1,6 +1,5 @@
/* ###
* IP: LGPL 3.0
* REVIEWED: YES
*/
/* Defs for interface to demanglers.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
@@ -71,6 +70,9 @@ extern "C" {
/* If none of these are set, use 'current_demangling_style' as the default. */
#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT)
// Changed Jan 22, 2020 - Added constant to allow us to limit degenerate recursive calls
#define DEMANGLE_RECURSION_LIMIT 10000
/* Enumeration of possible demangling styles.
Lucid and ARM styles are still kept logically distinct, even though
@@ -0,0 +1,81 @@
PURPOSE
This is a readme file to note the changes made to the binutils-2.33.1 source
code in to build its GNU demangler. The files in this directory are used to create a demangling
utility during the full build process.
COPIED SOURCE CODE / BUILDING RESTRICTIONS
Most of the files used to build the Ghidra GNU demangler are copied from binutils and have
not been changed. Further, the files in this directory are a small subset of the files used to
build the binutils suite. By copying specific files we are able to use Make and Visual Studio
to build a stand alone demangler without having to perform the more complicated build needed
to build binutils. Specifically, we do not have to run the configure utility that is
provided by binutils. This is critical, as we are using Visual Studio to build on Windows,
which does not have the configure utility support. If we ever wished to build the entire
binutils suite on Windows, then we would most likely need to use a GNU environment made for
Windows, such as MinGW.
CHANGES TO BINUTILS SOURCE
cp-demangle.c
This file contains a small, one-line change to flush to the standard output stream. Without
this change, the program, when called repeatedly from Java would hang as it attempts to read
characters that are buffered on the native side.
UPDATING
If we ever wish to update to a newer version of binutils, then we will need to re-copy the files
in this directory. That is, unless at least one of the following changes happens:
1) building a stand alone c++filt is simple enough that we can do it on each platform, or
2) we decide to build the entire binutils suite and use the full c++filt binary.
SOURCE FILES
binutils/libiberty/alloca.c
binutils/libiberty/argv.c
binutils/libiberty/cp-demangle.c
binutils/libiberty/cplus-dem.c
binutils/libiberty/d-demangle.c
binutils/libiberty/dyn-string.c
binutils/libiberty/getopt.c
binutils/libiberty/getopt1.c
binutils/libiberty/rust-demangle.c
binutils/libiberty/safe-ctype.c
binutils/libiberty/xexit.c
binutils/libiberty/xstrdup.c
binutils/include/ansidecl.h
binutils/libiberty/cp-demangle.h
binutils/include/demangle.h
binutils/include/dyn-string.h
binutils/include/getopt.h
binutils/include/libiberty.h
binutils/libiberty/rust-demangle.h
binutils/include/safe-ctype.h
This file is created to add minor missing dependencies.
missing.c
LICENSE
The files listed above are licensed by using the file header or the COPYING or COPYING.LIB file
listed in the original source directory of binutils.
@@ -0,0 +1,487 @@
/* ###
* IP: LGPL 2.1
* NOTE: license is not in file, but in the directory from whence it came: binutils-2.24/libiberty/COPYING.LIB
*/
/* alloca.c -- allocate automatically reclaimed memory
(Mostly) portable public-domain implementation -- D A Gwyn
This implementation of the PWB library alloca function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
J.Otto Tennant <jot@cray.com> contributed the Cray support.
There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection. */
/*
@deftypefn Replacement void* alloca (size_t @var{size})
This function allocates memory which will be automatically reclaimed
after the procedure exits. The @libib{} implementation does not free
the memory immediately but will do so eventually during subsequent
calls to this function. Memory is allocated using @code{xmalloc} under
normal circumstances.
The header file @file{alloca-conf.h} can be used in conjunction with the
GNU Autoconf test @code{AC_FUNC_ALLOCA} to test for and properly make
available this function. The @code{AC_FUNC_ALLOCA} test requires that
client code use a block of preprocessor code to be safe (see the Autoconf
manual for more); this header incorporates that logic and more, including
the possibility of a GCC built-in function.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <libiberty.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
/* These variables are used by the ASTRDUP implementation that relies
on C_alloca. */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
const char *libiberty_optr;
char *libiberty_nptr;
unsigned long libiberty_len;
#ifdef __cplusplus
}
#endif /* __cplusplus */
/* If your stack is a linked list of frames, you have to
provide an "address metric" ADDRESS_FUNCTION macro. */
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
static long i00afunc ();
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
#else
#define ADDRESS_FUNCTION(arg) &(arg)
#endif
#ifndef NULL
#define NULL 0
#endif
/* Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* Direction unknown. */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
#else /* STACK_DIRECTION == 0; need run-time code. */
static int stack_dir; /* 1 or -1 once known. */
#define STACK_DIR stack_dir
static void
find_stack_direction (void)
{
static char *addr = NULL; /* Address of first `dummy', once known. */
auto char dummy; /* To get stack address. */
if (addr == NULL)
{ /* Initial entry. */
addr = ADDRESS_FUNCTION (dummy);
find_stack_direction (); /* Recurse once. */
}
else
{
/* Second entry. */
if (ADDRESS_FUNCTION (dummy) > addr)
stack_dir = 1; /* Stack grew upward. */
else
stack_dir = -1; /* Stack grew downward. */
}
}
#endif /* STACK_DIRECTION == 0 */
/* An "alloca header" is used to:
(a) chain together all alloca'ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc
alignment chunk size. The following default should work okay. */
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* To force sizeof(header). */
struct
{
union hdr *next; /* For chaining headers. */
char *deep; /* For stack depth measure. */
} h;
} header;
static header *last_alloca_header = NULL; /* -> last alloca header. */
/* Return a pointer to at least SIZE bytes of storage,
which will be automatically reclaimed upon exit from
the procedure that called alloca. Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32. */
/* @undocumented C_alloca */
PTR
C_alloca (size_t size)
{
auto char probe; /* Probes stack depth: */
register char *depth = ADDRESS_FUNCTION (probe);
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* Unknown growth direction. */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca'd storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* Traverses linked list. */
for (hp = last_alloca_header; hp != NULL;)
if ((STACK_DIR > 0 && hp->h.deep > depth)
|| (STACK_DIR < 0 && hp->h.deep < depth))
{
register header *np = hp->h.next;
free ((PTR) hp); /* Collect garbage. */
hp = np; /* -> next header. */
}
else
break; /* Rest are not deeper. */
last_alloca_header = hp; /* -> last valid storage. */
}
if (size == 0)
return NULL; /* No allocation required. */
/* Allocate combined header + user data storage. */
{
register void *new_storage = XNEWVEC (char, sizeof (header) + size);
/* Address of header. */
if (new_storage == 0)
abort();
((header *) new_storage)->h.next = last_alloca_header;
((header *) new_storage)->h.deep = depth;
last_alloca_header = (header *) new_storage;
/* User storage begins just after header. */
return (PTR) ((char *) new_storage + sizeof (header));
}
}
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
#ifdef DEBUG_I00AFUNC
#include <stdio.h>
#endif
#ifndef CRAY_STACK
#define CRAY_STACK
#ifndef CRAY2
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
struct stack_control_header
{
long shgrow:32; /* Number of times stack has grown. */
long shaseg:32; /* Size of increments to stack. */
long shhwm:32; /* High water mark of stack. */
long shsize:32; /* Current size of stack (all segments). */
};
/* The stack segment linkage control information occurs at
the high-address end of a stack segment. (The stack
grows from low addresses to high addresses.) The initial
part of the stack segment linkage control information is
0200 (octal) words. This provides for register storage
for the routine which overflows the stack. */
struct stack_segment_linkage
{
long ss[0200]; /* 0200 overflow words. */
long sssize:32; /* Number of words in this segment. */
long ssbase:32; /* Offset to stack base. */
long:32;
long sspseg:32; /* Offset to linkage control of previous
segment of stack. */
long:32;
long sstcpt:32; /* Pointer to task common address block. */
long sscsnm; /* Private control structure number for
microtasking. */
long ssusr1; /* Reserved for user. */
long ssusr2; /* Reserved for user. */
long sstpid; /* Process ID for pid based multi-tasking. */
long ssgvup; /* Pointer to multitasking thread giveup. */
long sscray[7]; /* Reserved for Cray Research. */
long ssa0;
long ssa1;
long ssa2;
long ssa3;
long ssa4;
long ssa5;
long ssa6;
long ssa7;
long sss0;
long sss1;
long sss2;
long sss3;
long sss4;
long sss5;
long sss6;
long sss7;
};
#else /* CRAY2 */
/* The following structure defines the vector of words
returned by the STKSTAT library routine. */
struct stk_stat
{
long now; /* Current total stack size. */
long maxc; /* Amount of contiguous space which would
be required to satisfy the maximum
stack demand to date. */
long high_water; /* Stack high-water mark. */
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
long hits; /* Number of internal buffer hits. */
long extends; /* Number of block extensions. */
long stko_mallocs; /* Block allocations by $STKOFEN. */
long underflows; /* Number of stack underflow calls ($STKRETN). */
long stko_free; /* Number of deallocations by $STKRETN. */
long stkm_free; /* Number of deallocations by $STKMRET. */
long segments; /* Current number of stack segments. */
long maxs; /* Maximum number of stack segments so far. */
long pad_size; /* Stack pad size. */
long current_address; /* Current stack segment address. */
long current_size; /* Current stack segment size. This
number is actually corrupted by STKSTAT to
include the fifteen word trailer area. */
long initial_address; /* Address of initial segment. */
long initial_size; /* Size of initial segment. */
};
/* The following structure describes the data structure which trails
any stack segment. I think that the description in 'asdef' is
out of date. I only describe the parts that I am sure about. */
struct stk_trailer
{
long this_address; /* Address of this block. */
long this_size; /* Size of this block (does not include
this trailer). */
long unknown2;
long unknown3;
long link; /* Address of trailer block of previous
segment. */
long unknown5;
long unknown6;
long unknown7;
long unknown8;
long unknown9;
long unknown10;
long unknown11;
long unknown12;
long unknown13;
long unknown14;
};
#endif /* CRAY2 */
#endif /* not CRAY_STACK */
#ifdef CRAY2
/* Determine a "stack measure" for an arbitrary ADDRESS.
I doubt that "lint" will like this much. */
static long
i00afunc (long *address)
{
struct stk_stat status;
struct stk_trailer *trailer;
long *block, size;
long result = 0;
/* We want to iterate through all of the segments. The first
step is to get the stack status structure. We could do this
more quickly and more directly, perhaps, by referencing the
$LM00 common block, but I know that this works. */
STKSTAT (&status);
/* Set up the iteration. */
trailer = (struct stk_trailer *) (status.current_address
+ status.current_size
- 15);
/* There must be at least one stack segment. Therefore it is
a fatal error if "trailer" is null. */
if (trailer == 0)
abort ();
/* Discard segments that do not contain our argument address. */
while (trailer != 0)
{
block = (long *) trailer->this_address;
size = trailer->this_size;
if (block == 0 || size == 0)
abort ();
trailer = (struct stk_trailer *) trailer->link;
if ((block <= address) && (address < (block + size)))
break;
}
/* Set the result to the offset in this segment and add the sizes
of all predecessor segments. */
result = address - block;
if (trailer == 0)
{
return result;
}
do
{
if (trailer->this_size <= 0)
abort ();
result += trailer->this_size;
trailer = (struct stk_trailer *) trailer->link;
}
while (trailer != 0);
/* We are done. Note that if you present a bogus address (one
not in any segment), you will get a different number back, formed
from subtracting the address of the first block. This is probably
not what you want. */
return (result);
}
#else /* not CRAY2 */
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Determine the number of the cell within the stack,
given the address of the cell. The purpose of this
routine is to linearize, in some sense, stack addresses
for alloca. */
static long
i00afunc (long address)
{
long stkl = 0;
long size, pseg, this_segment, stack;
long result = 0;
struct stack_segment_linkage *ssptr;
/* Register B67 contains the address of the end of the
current stack segment. If you (as a subprogram) store
your registers on the stack and find that you are past
the contents of B67, you have overflowed the segment.
B67 also points to the stack segment linkage control
area, which is what we are really interested in. */
stkl = CRAY_STACKSEG_END ();
ssptr = (struct stack_segment_linkage *) stkl;
/* If one subtracts 'size' from the end of the segment,
one has the address of the first word of the segment.
If this is not the first segment, 'pseg' will be
nonzero. */
pseg = ssptr->sspseg;
size = ssptr->sssize;
this_segment = stkl - size;
/* It is possible that calling this routine itself caused
a stack overflow. Discard stack segments which do not
contain the target address. */
while (!(this_segment <= address && address <= stkl))
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
#endif
if (pseg == 0)
break;
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
this_segment = stkl - size;
}
result = address - this_segment;
/* If you subtract pseg from the current end of the stack,
you get the address of the previous stack segment's end.
This seems a little convoluted to me, but I'll bet you save
a cycle somewhere. */
while (pseg != 0)
{
#ifdef DEBUG_I00AFUNC
fprintf (stderr, "%011o %011o\n", pseg, size);
#endif
stkl = stkl - pseg;
ssptr = (struct stack_segment_linkage *) stkl;
size = ssptr->sssize;
pseg = ssptr->sspseg;
result += size;
}
return (result);
}
#endif /* not CRAY2 */
#endif /* CRAY */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,495 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/libiberty/COPYING.LIB
*/
/* Demangler for GNU C++
Copyright (C) 1989-2019 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited permission
to link the compiled version of this file into combinations with other
programs, and to distribute those combinations without any restriction
coming from the use of this file. (The Library Public License
restrictions do apply in other respects; for example, they cover
modification of the file, and distribution when not linked into a
combined executable.)
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/* This file lives in both GCC and libiberty. When making changes, please
try not to break either. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "safe-ctype.h"
#include <string.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
void * malloc ();
void * realloc ();
#endif
#include <demangle.h>
#undef CURRENT_DEMANGLING_STYLE
#define CURRENT_DEMANGLING_STYLE options
#include "libiberty.h"
#include "rust-demangle.h"
enum demangling_styles current_demangling_style = auto_demangling;
const struct demangler_engine libiberty_demanglers[] =
{
{
NO_DEMANGLING_STYLE_STRING,
no_demangling,
"Demangling disabled"
}
,
{
AUTO_DEMANGLING_STYLE_STRING,
auto_demangling,
"Automatic selection based on executable"
}
,
{
GNU_V3_DEMANGLING_STYLE_STRING,
gnu_v3_demangling,
"GNU (g++) V3 (Itanium C++ ABI) style demangling"
}
,
{
JAVA_DEMANGLING_STYLE_STRING,
java_demangling,
"Java style demangling"
}
,
{
GNAT_DEMANGLING_STYLE_STRING,
gnat_demangling,
"GNAT style demangling"
}
,
{
DLANG_DEMANGLING_STYLE_STRING,
dlang_demangling,
"DLANG style demangling"
}
,
{
RUST_DEMANGLING_STYLE_STRING,
rust_demangling,
"Rust style demangling"
}
,
{
NULL, unknown_demangling, NULL
}
};
/* Add a routine to set the demangling style to be sure it is valid and
allow for any demangler initialization that maybe necessary. */
enum demangling_styles
cplus_demangle_set_style (enum demangling_styles style)
{
const struct demangler_engine *demangler = libiberty_demanglers;
for (; demangler->demangling_style != unknown_demangling; ++demangler)
if (style == demangler->demangling_style)
{
current_demangling_style = style;
return current_demangling_style;
}
return unknown_demangling;
}
/* Do string name to style translation */
enum demangling_styles
cplus_demangle_name_to_style (const char *name)
{
const struct demangler_engine *demangler = libiberty_demanglers;
for (; demangler->demangling_style != unknown_demangling; ++demangler)
if (strcmp (name, demangler->demangling_style_name) == 0)
return demangler->demangling_style;
return unknown_demangling;
}
/* char *cplus_demangle (const char *mangled, int options)
If MANGLED is a mangled function name produced by GNU C++, then
a pointer to a @code{malloc}ed string giving a C++ representation
of the name will be returned; otherwise NULL will be returned.
It is the caller's responsibility to free the string which
is returned.
Note that any leading underscores, or other such characters prepended by
the compilation system, are presumed to have already been stripped from
MANGLED. */
char *
cplus_demangle (const char *mangled, int options)
{
char *ret;
if (current_demangling_style == no_demangling)
return xstrdup (mangled);
if ((options & DMGL_STYLE_MASK) == 0)
options |= (int) current_demangling_style & DMGL_STYLE_MASK;
/* The V3 ABI demangling is implemented elsewhere. */
if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
{
ret = cplus_demangle_v3 (mangled, options);
if (GNU_V3_DEMANGLING)
return ret;
if (ret)
{
/* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
The subtitutions are always smaller, so do in place changes. */
if (rust_is_mangled (ret))
rust_demangle_sym (ret);
else if (RUST_DEMANGLING)
{
free (ret);
ret = NULL;
}
}
if (ret || RUST_DEMANGLING)
return ret;
}
if (JAVA_DEMANGLING)
{
ret = java_demangle_v3 (mangled);
if (ret)
return ret;
}
if (GNAT_DEMANGLING)
return ada_demangle (mangled, options);
if (DLANG_DEMANGLING)
{
ret = dlang_demangle (mangled, options);
if (ret)
return ret;
}
return (ret);
}
char *
rust_demangle (const char *mangled, int options)
{
/* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
char *ret = cplus_demangle_v3 (mangled, options);
/* The Rust subtitutions are always smaller, so do in place changes. */
if (ret != NULL)
{
if (rust_is_mangled (ret))
rust_demangle_sym (ret);
else
{
free (ret);
ret = NULL;
}
}
return ret;
}
/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
char *
ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
int len0;
const char* p;
char *d;
char *demangled = NULL;
/* Discard leading _ada_, which is used for library level subprograms. */
if (strncmp (mangled, "_ada_", 5) == 0)
mangled += 5;
/* All ada unit names are lower-case. */
if (!ISLOWER (mangled[0]))
goto unknown;
/* Most of the demangling will trivially remove chars. Operator names
may add one char but because they are always preceeded by '__' which is
replaced by '.', they eventually never expand the size.
A few special names such as '___elabs' add a few chars (at most 7), but
they occur only once. */
len0 = strlen (mangled) + 7 + 1;
demangled = XNEWVEC (char, len0);
d = demangled;
p = mangled;
while (1)
{
/* An entity names is expected. */
if (ISLOWER (*p))
{
/* An identifier, which is always lower case. */
do
*d++ = *p++;
while (ISLOWER(*p) || ISDIGIT (*p)
|| (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
}
else if (p[0] == 'O')
{
/* An operator name. */
static const char * const operators[][2] =
{{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
{"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
{"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
{"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
{"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
{"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
{"Oexpon", "**"}, {NULL, NULL}};
int k;
for (k = 0; operators[k][0] != NULL; k++)
{
size_t slen = strlen (operators[k][0]);
if (strncmp (p, operators[k][0], slen) == 0)
{
p += slen;
slen = strlen (operators[k][1]);
*d++ = '"';
memcpy (d, operators[k][1], slen);
d += slen;
*d++ = '"';
break;
}
}
/* Operator not found. */
if (operators[k][0] == NULL)
goto unknown;
}
else
{
/* Not a GNAT encoding. */
goto unknown;
}
/* The name can be directly followed by some uppercase letters. */
if (p[0] == 'T' && p[1] == 'K')
{
/* Task stuff. */
if (p[2] == 'B' && p[3] == 0)
{
/* Subprogram for task body. */
break;
}
else if (p[2] == '_' && p[3] == '_')
{
/* Inner declarations in a task. */
p += 4;
*d++ = '.';
continue;
}
else
goto unknown;
}
if (p[0] == 'E' && p[1] == 0)
{
/* Exception name. */
goto unknown;
}
if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
{
/* Protected type subprogram. */
break;
}
if ((*p == 'N' || *p == 'S') && p[1] == 0)
{
/* Enumerated type name table. */
goto unknown;
}
if (p[0] == 'X')
{
/* Body nested. */
p++;
while (p[0] == 'n' || p[0] == 'b')
p++;
}
if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
{
/* Stream operations. */
const char *name;
switch (p[1])
{
case 'R':
name = "'Read";
break;
case 'W':
name = "'Write";
break;
case 'I':
name = "'Input";
break;
case 'O':
name = "'Output";
break;
default:
goto unknown;
}
p += 2;
strcpy (d, name);
d += strlen (name);
}
else if (p[0] == 'D')
{
/* Controlled type operation. */
const char *name;
switch (p[1])
{
case 'F':
name = ".Finalize";
break;
case 'A':
name = ".Adjust";
break;
default:
goto unknown;
}
strcpy (d, name);
d += strlen (name);
break;
}
if (p[0] == '_')
{
/* Separator. */
if (p[1] == '_')
{
/* Standard separator. Handled first. */
p += 2;
if (ISDIGIT (*p))
{
/* Overloading number. */
do
p++;
while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
if (*p == 'X')
{
p++;
while (p[0] == 'n' || p[0] == 'b')
p++;
}
}
else if (p[0] == '_' && p[1] != '_')
{
/* Special names. */
static const char * const special[][2] = {
{ "_elabb", "'Elab_Body" },
{ "_elabs", "'Elab_Spec" },
{ "_size", "'Size" },
{ "_alignment", "'Alignment" },
{ "_assign", ".\":=\"" },
{ NULL, NULL }
};
int k;
for (k = 0; special[k][0] != NULL; k++)
{
size_t slen = strlen (special[k][0]);
if (strncmp (p, special[k][0], slen) == 0)
{
p += slen;
slen = strlen (special[k][1]);
memcpy (d, special[k][1], slen);
d += slen;
break;
}
}
if (special[k][0] != NULL)
break;
else
goto unknown;
}
else
{
*d++ = '.';
continue;
}
}
else if (p[1] == 'B' || p[1] == 'E')
{
/* Entry Body or barrier Evaluation. */
p += 2;
while (ISDIGIT (*p))
p++;
if (p[0] == 's' && p[1] == 0)
break;
else
goto unknown;
}
else
goto unknown;
}
if (p[0] == '.' && ISDIGIT (p[1]))
{
/* Nested subprogram. */
p += 2;
while (ISDIGIT (*p))
p++;
}
if (*p == 0)
{
/* End of mangled name. */
break;
}
else
goto unknown;
}
*d = 0;
return demangled;
unknown:
XDELETEVEC (demangled);
len0 = strlen (mangled);
demangled = XNEWVEC (char, len0 + 3);
if (mangled[0] == '<')
strcpy (demangled, mangled);
else
sprintf (demangled, "<%s>", mangled);
return demangled;
}
@@ -0,0 +1,272 @@
/* ###
* IP: GPL 3
*/
/* Demangler for GNU C++ - main program
Copyright (C) 1989-2019 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA.
CHANGE NOTICE:
This file was changed on July 22nd, 2020.
*/
#include "libiberty.h"
#include "demangle.h"
#include "getopt.h"
#include "safe-ctype.h"
static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
static int strip_underscore = 0; // TARGET_PREPENDS_UNDERSCORE; // Changed Jan 22, 2020
static const char *program_name; // Changed Jan 22, 2020
static const struct option long_options[] =
{
{"strip-underscore", no_argument, NULL, '_'},
{"format", required_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{"no-params", no_argument, NULL, 'p'},
{"no-strip-underscores", no_argument, NULL, 'n'},
{"no-verbose", no_argument, NULL, 'i'},
{"types", no_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
{"recurse-limit", no_argument, NULL, 'R'},
{"recursion-limit", no_argument, NULL, 'R'},
{"no-recurse-limit", no_argument, NULL, 'r'},
{"no-recursion-limit", no_argument, NULL, 'r'},
{NULL, no_argument, NULL, 0}
};
static void
demangle_it (char *mangled_name)
{
char *result;
unsigned int skip_first = 0;
/* _ and $ are sometimes found at the start of function names
in assembler sources in order to distinguish them from other
names (eg register names). So skip them here. */
if (mangled_name[0] == '.' || mangled_name[0] == '$')
++skip_first;
if (strip_underscore && mangled_name[skip_first] == '_')
++skip_first;
result = cplus_demangle (mangled_name + skip_first, flags);
if (result == NULL)
printf ("%s", mangled_name);
else
{
if (mangled_name[0] == '.')
putchar ('.');
printf ("%s", result);
free (result);
}
}
static void
print_demangler_list (FILE *stream)
{
const struct demangler_engine *demangler;
fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
for (demangler = libiberty_demanglers + 1;
demangler->demangling_style != unknown_demangling;
++demangler)
fprintf (stream, ",%s", demangler->demangling_style_name);
fprintf (stream, "}");
}
ATTRIBUTE_NORETURN static void
usage (FILE *stream, int status)
{
fprintf (stream, "\
Usage: %s [options] [mangled names]\n", program_name);
fprintf (stream, "\
Options are:\n\
[-_|--strip-underscore] Ignore first leading underscore%s\n",
strip_underscore ? " (default)" : ""); // Changed Jan 22, 2020
fprintf (stream, "\
[-n|--no-strip-underscore] Do not ignore a leading underscore%s\n",
strip_underscore ? "" : " (default)"); // Changed Jan 22, 2020
fprintf (stream, "\
[-p|--no-params] Do not display function arguments\n\
[-i|--no-verbose] Do not show implementation details (if any)\n\
[-R|--recurse-limit] Enable a limit on recursion whilst demangling. [Default]\n\
]-r|--no-recurse-limit] Disable a limit on recursion whilst demangling\n\
[-t|--types] Also attempt to demangle type encodings\n\
[-s|--format ");
print_demangler_list (stream);
fprintf (stream, "]\n");
fprintf (stream, "\
[@<file>] Read extra options from <file>\n\
[-h|--help] Display this information\n\
[-v|--version] Show the version information\n\
Demangled names are displayed to stdout.\n\
If a name cannot be demangled it is just echoed to stdout.\n\
If no names are provided on the command line, stdin is read.\n");
/* Changed Jan 22, 2020
if (REPORT_BUGS_TO[0] && status == 0)
fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
*/
exit (status);
}
/* Return the string of non-alnum characters that may occur
as a valid symbol component, in the standard assembler symbol
syntax. */
static const char *
standard_symbol_characters (void)
{
return "_$.";
}
extern int main (int, char **);
int
main (int argc, char **argv)
{
int c;
const char *valid_symbols;
enum demangling_styles style = auto_demangling;
program_name = argv[0];
// xmalloc_set_program_name (program_name); // Changed Jan 22, 2020
// bfd_set_error_program_name (program_name); // Changed Jan 22, 2020
expandargv (&argc, &argv);
while ((c = getopt_long (argc, argv, "_hinprRs:tv", long_options, (int *) 0)) != EOF)
{
switch (c)
{
case '?':
usage (stderr, 1);
break;
case 'h':
usage (stdout, 0);
case 'n':
strip_underscore = 0;
break;
case 'p':
flags &= ~ DMGL_PARAMS;
break;
case 'r':
flags |= DMGL_NO_RECURSE_LIMIT;
break;
case 'R':
flags &= ~ DMGL_NO_RECURSE_LIMIT;
break;
case 't':
flags |= DMGL_TYPES;
break;
case 'i':
flags &= ~ DMGL_VERBOSE;
break;
case 'v':
printf ("(GNU Binutils) c++filt 2.33.1\n"); // Changed Jan 22, 2020
return 0;
case '_':
strip_underscore = 1;
break;
case 's':
style = cplus_demangle_name_to_style (optarg);
if (style == unknown_demangling)
{
fprintf (stderr, "%s: unknown demangling style `%s'\n",
program_name, optarg);
return 1;
}
cplus_demangle_set_style (style);
break;
}
}
if (optind < argc)
{
for ( ; optind < argc; optind++)
{
demangle_it (argv[optind]);
putchar ('\n');
}
return 0;
}
switch (current_demangling_style)
{
case auto_demangling:
case gnu_v3_demangling:
case java_demangling:
case gnat_demangling:
case dlang_demangling:
case rust_demangling:
valid_symbols = standard_symbol_characters ();
break;
default: {
/* Folks should explicitly indicate the appropriate alphabet for
each demangling. Providing a default would allow the
question to go unconsidered. */
fprintf (stderr, "Internal error: no symbol alphabet for current style\n"); // Changed Jan 22, 2020
exit (1); // Changed Jan 22, 2020
}
}
for (;;)
{
static char mbuffer[32767];
unsigned i = 0;
c = getchar ();
/* Try to read a mangled name. */
while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
{
if (i >= sizeof (mbuffer) - 1)
break;
mbuffer[i++] = c;
c = getchar ();
}
if (i > 0)
{
mbuffer[i] = 0;
demangle_it (mbuffer);
}
if (c == EOF)
break;
/* Echo the whitespace characters so that the output looks
like the input, only with the mangled names demangled. */
putchar (c);
if (c == '\n')
fflush (stdout);
}
fflush (stdout);
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,401 @@
/* ###
* IP: GPL 3 Linking Permitted
* NOTE: See binutils/include/COPYING3
*/
/* An abstract string datatype.
Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "libiberty.h"
#include "dyn-string.h"
/* Performs in-place initialization of a dyn_string struct. This
function can be used with a dyn_string struct on the stack or
embedded in another object. The contents of of the string itself
are still dynamically allocated. The string initially is capable
of holding at least SPACE characeters, including the terminating
NUL. If SPACE is 0, it will silently be increated to 1.
If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation
fails, returns 0. Otherwise returns 1. */
int
dyn_string_init (struct dyn_string *ds_struct_ptr, int space)
{
/* We need at least one byte in which to store the terminating NUL. */
if (space == 0)
space = 1;
#ifdef RETURN_ON_ALLOCATION_FAILURE
ds_struct_ptr->s = (char *) malloc (space);
if (ds_struct_ptr->s == NULL)
return 0;
#else
ds_struct_ptr->s = XNEWVEC (char, space);
#endif
ds_struct_ptr->allocated = space;
ds_struct_ptr->length = 0;
ds_struct_ptr->s[0] = '\0';
return 1;
}
/* Create a new dynamic string capable of holding at least SPACE
characters, including the terminating NUL. If SPACE is 0, it will
be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is
defined and memory allocation fails, returns NULL. Otherwise
returns the newly allocated string. */
dyn_string_t
dyn_string_new (int space)
{
dyn_string_t result;
#ifdef RETURN_ON_ALLOCATION_FAILURE
result = (dyn_string_t) malloc (sizeof (struct dyn_string));
if (result == NULL)
return NULL;
if (!dyn_string_init (result, space))
{
free (result);
return NULL;
}
#else
result = XNEW (struct dyn_string);
dyn_string_init (result, space);
#endif
return result;
}
/* Free the memory used by DS. */
void
dyn_string_delete (dyn_string_t ds)
{
free (ds->s);
free (ds);
}
/* Returns the contents of DS in a buffer allocated with malloc. It
is the caller's responsibility to deallocate the buffer using free.
DS is then set to the empty string. Deletes DS itself. */
char*
dyn_string_release (dyn_string_t ds)
{
/* Store the old buffer. */
char* result = ds->s;
/* The buffer is no longer owned by DS. */
ds->s = NULL;
/* Delete DS. */
free (ds);
/* Return the old buffer. */
return result;
}
/* Increase the capacity of DS so it can hold at least SPACE
characters, plus the terminating NUL. This function will not (at
present) reduce the capacity of DS. Returns DS on success.
If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation
operation fails, deletes DS and returns NULL. */
dyn_string_t
dyn_string_resize (dyn_string_t ds, int space)
{
int new_allocated = ds->allocated;
/* Increase SPACE to hold the NUL termination. */
++space;
/* Increase allocation by factors of two. */
while (space > new_allocated)
new_allocated *= 2;
if (new_allocated != ds->allocated)
{
ds->allocated = new_allocated;
/* We actually need more space. */
#ifdef RETURN_ON_ALLOCATION_FAILURE
ds->s = (char *) realloc (ds->s, ds->allocated);
if (ds->s == NULL)
{
free (ds);
return NULL;
}
#else
ds->s = XRESIZEVEC (char, ds->s, ds->allocated);
#endif
}
return ds;
}
/* Sets the contents of DS to the empty string. */
void
dyn_string_clear (dyn_string_t ds)
{
/* A dyn_string always has room for at least the NUL terminator. */
ds->s[0] = '\0';
ds->length = 0;
}
/* Makes the contents of DEST the same as the contents of SRC. DEST
and SRC must be distinct. Returns 1 on success. On failure, if
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_copy (dyn_string_t dest, dyn_string_t src)
{
if (dest == src)
abort ();
/* Make room in DEST. */
if (dyn_string_resize (dest, src->length) == NULL)
return 0;
/* Copy DEST into SRC. */
strcpy (dest->s, src->s);
/* Update the size of DEST. */
dest->length = src->length;
return 1;
}
/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_copy_cstr (dyn_string_t dest, const char *src)
{
int length = strlen (src);
/* Make room in DEST. */
if (dyn_string_resize (dest, length) == NULL)
return 0;
/* Copy DEST into SRC. */
strcpy (dest->s, src);
/* Update the size of DEST. */
dest->length = length;
return 1;
}
/* Inserts SRC at the beginning of DEST. DEST is expanded as
necessary. SRC and DEST must be distinct. Returns 1 on success.
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
returns 0. */
int
dyn_string_prepend (dyn_string_t dest, dyn_string_t src)
{
return dyn_string_insert (dest, 0, src);
}
/* Inserts SRC, a NUL-terminated string, at the beginning of DEST.
DEST is expanded as necessary. Returns 1 on success. On failure,
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_prepend_cstr (dyn_string_t dest, const char *src)
{
return dyn_string_insert_cstr (dest, 0, src);
}
/* Inserts SRC into DEST starting at position POS. DEST is expanded
as necessary. SRC and DEST must be distinct. Returns 1 on
success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src)
{
int i;
if (src == dest)
abort ();
if (dyn_string_resize (dest, dest->length + src->length) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + src->length] = dest->s[i];
/* Splice in the new stuff. */
strncpy (dest->s + pos, src->s, src->length);
/* Compute the new length. */
dest->length += src->length;
return 1;
}
/* Inserts SRC, a NUL-terminated string, into DEST starting at
position POS. DEST is expanded as necessary. Returns 1 on
success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST
and returns 0. */
int
dyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src)
{
int i;
int length = strlen (src);
if (dyn_string_resize (dest, dest->length + length) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + length] = dest->s[i];
/* Splice in the new stuff. */
strncpy (dest->s + pos, src, length);
/* Compute the new length. */
dest->length += length;
return 1;
}
/* Inserts character C into DEST starting at position POS. DEST is
expanded as necessary. Returns 1 on success. On failure,
RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_insert_char (dyn_string_t dest, int pos, int c)
{
int i;
if (dyn_string_resize (dest, dest->length + 1) == NULL)
return 0;
/* Make room for the insertion. Be sure to copy the NUL. */
for (i = dest->length; i >= pos; --i)
dest->s[i + 1] = dest->s[i];
/* Add the new character. */
dest->s[pos] = c;
/* Compute the new length. */
++dest->length;
return 1;
}
/* Append S to DS, resizing DS if necessary. Returns 1 on success.
On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and
returns 0. */
int
dyn_string_append (dyn_string_t dest, dyn_string_t s)
{
if (dyn_string_resize (dest, dest->length + s->length) == 0)
return 0;
strcpy (dest->s + dest->length, s->s);
dest->length += s->length;
return 1;
}
/* Append the NUL-terminated string S to DS, resizing DS if necessary.
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
deletes DEST and returns 0. */
int
dyn_string_append_cstr (dyn_string_t dest, const char *s)
{
int len = strlen (s);
/* The new length is the old length plus the size of our string, plus
one for the null at the end. */
if (dyn_string_resize (dest, dest->length + len) == NULL)
return 0;
strcpy (dest->s + dest->length, s);
dest->length += len;
return 1;
}
/* Appends C to the end of DEST. Returns 1 on success. On failure,
if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */
int
dyn_string_append_char (dyn_string_t dest, int c)
{
/* Make room for the extra character. */
if (dyn_string_resize (dest, dest->length + 1) == NULL)
return 0;
/* Append the character; it will overwrite the old NUL. */
dest->s[dest->length] = c;
/* Add a new NUL at the end. */
dest->s[dest->length + 1] = '\0';
/* Update the length. */
++(dest->length);
return 1;
}
/* Sets the contents of DEST to the substring of SRC starting at START
and ending before END. START must be less than or equal to END,
and both must be between zero and the length of SRC, inclusive.
Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE,
deletes DEST and returns 0. */
int
dyn_string_substring (dyn_string_t dest, dyn_string_t src,
int start, int end)
{
int i;
int length = end - start;
if (start > end || start > src->length || end > src->length)
abort ();
/* Make room for the substring. */
if (dyn_string_resize (dest, length) == NULL)
return 0;
/* Copy the characters in the substring, */
for (i = length; --i >= 0; )
dest->s[i] = src->s[start + i];
/* NUL-terimate the result. */
dest->s[length] = '\0';
/* Record the length of the substring. */
dest->length = length;
return 1;
}
/* Returns non-zero if DS1 and DS2 have the same contents. */
int
dyn_string_eq (dyn_string_t ds1, dyn_string_t ds2)
{
/* If DS1 and DS2 have different lengths, they must not be the same. */
if (ds1->length != ds2->length)
return 0;
else
return !strcmp (ds1->s, ds2->s);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,183 @@
/* ###
* IP: GPL 3
* NOTE: See binutils/include/COPYING3
*/
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987-2019 Free Software Foundation, Inc.
NOTE: This source is derived from an old version taken from the GNU C
Library (glibc).
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
#include "getopt.h"
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */
@@ -0,0 +1,75 @@
/* ###
* IP: LGPL 2.1
* NOTE: Code copied from older version of cplus-dem.c that Ghidra had modified
*/
/*
Copyright (C) 2003-2019 Free Software Foundation, Inc.
This file exists to provide code missing from sibling files in this directory.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited permission
to link the compiled version of this file into combinations with other
programs, and to distribute those combinations without any restriction
coming from the use of this file. (The Library Public License
restrictions do apply in other respects; for example, they cover
modification of the file, and distribution when not linked into a
combined executable.)
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA.
CHANGE NOTICE:
This file was created on January 22nd, 2020:
-This code was copied and modified from a previous version of libiberty
*/
#include <sys/types.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
void * malloc ();
void * realloc ();
#endif
static void
fatal (str)
const char *str;
{
fprintf (stderr, "%s\n", str);
exit (1);
}
void *
xmalloc (size)
size_t size;
{
register void * value = malloc (size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
void *
xrealloc (ptr, size)
size_t size;
{
register void * value = realloc (ptr, size);
if (value == 0)
fatal ("virtual memory exhausted");
return value;
}
@@ -0,0 +1,353 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/libiberty/COPYING.LIB
*/
/* Demangler for the Rust programming language
Copyright (C) 2016-2019 Free Software Foundation, Inc.
Written by David Tolnay (dtolnay@gmail.com).
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited permission
to link the compiled version of this file into combinations with other
programs, and to distribute those combinations without any restriction
coming from the use of this file. (The Library Public License
restrictions do apply in other respects; for example, they cover
modification of the file, and distribution when not linked into a
combined executable.)
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "safe-ctype.h"
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
extern size_t strlen(const char *s);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern void *memset(void *s, int c, size_t n);
#endif
#include <demangle.h>
#include "libiberty.h"
#include "rust-demangle.h"
/* Mangled Rust symbols look like this:
_$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
The original symbol is:
<std::sys::fd::FileDesc as core::ops::Drop>::drop
The last component of the path is a 64-bit hash in lowercase hex,
prefixed with "h". Rust does not have a global namespace between
crates, an illusion which Rust maintains by using the hash to
distinguish things that would otherwise have the same symbol.
Any path component not starting with a XID_Start character is
prefixed with "_".
The following escape sequences are used:
"," => $C$
"@" => $SP$
"*" => $BP$
"&" => $RF$
"<" => $LT$
">" => $GT$
"(" => $LP$
")" => $RP$
" " => $u20$
"\"" => $u22$
"'" => $u27$
"+" => $u2b$
";" => $u3b$
"[" => $u5b$
"]" => $u5d$
"{" => $u7b$
"}" => $u7d$
"~" => $u7e$
A double ".." means "::" and a single "." means "-".
The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$ */
static const char *hash_prefix = "::h";
static const size_t hash_prefix_len = 3;
static const size_t hash_len = 16;
static int is_prefixed_hash (const char *start);
static int looks_like_rust (const char *sym, size_t len);
static int unescape (const char **in, char **out, const char *seq, char value);
/* INPUT: sym: symbol that has been through C++ (gnu v3) demangling
This function looks for the following indicators:
1. The hash must consist of "h" followed by 16 lowercase hex digits.
2. As a sanity check, the hash must use between 5 and 15 of the 16
possible hex digits. This is true of 99.9998% of hashes so once
in your life you may see a false negative. The point is to
notice path components that could be Rust hashes but are
probably not, like "haaaaaaaaaaaaaaaa". In this case a false
positive (non-Rust symbol has an important path component
removed because it looks like a Rust hash) is worse than a false
negative (the rare Rust symbol is not demangled) so this sets
the balance in favor of false negatives.
3. There must be no characters other than a-zA-Z0-9 and _.:$
4. There must be no unrecognized $-sign sequences.
5. There must be no sequence of three or more dots in a row ("..."). */
int
rust_is_mangled (const char *sym)
{
size_t len, len_without_hash;
if (!sym)
return 0;
len = strlen (sym);
if (len <= hash_prefix_len + hash_len)
/* Not long enough to contain "::h" + hash + something else */
return 0;
len_without_hash = len - (hash_prefix_len + hash_len);
if (!is_prefixed_hash (sym + len_without_hash))
return 0;
return looks_like_rust (sym, len_without_hash);
}
/* A hash is the prefix "::h" followed by 16 lowercase hex digits. The
hex digits must comprise between 5 and 15 (inclusive) distinct
digits. */
static int
is_prefixed_hash (const char *str)
{
const char *end;
char seen[16];
size_t i;
int count;
if (strncmp (str, hash_prefix, hash_prefix_len))
return 0;
str += hash_prefix_len;
memset (seen, 0, sizeof(seen));
for (end = str + hash_len; str < end; str++)
if (*str >= '0' && *str <= '9')
seen[*str - '0'] = 1;
else if (*str >= 'a' && *str <= 'f')
seen[*str - 'a' + 10] = 1;
else
return 0;
/* Count how many distinct digits seen */
count = 0;
for (i = 0; i < 16; i++)
if (seen[i])
count++;
return count >= 5 && count <= 15;
}
static int
looks_like_rust (const char *str, size_t len)
{
const char *end = str + len;
while (str < end)
switch (*str)
{
case '$':
if (!strncmp (str, "$C$", 3))
str += 3;
else if (!strncmp (str, "$SP$", 4)
|| !strncmp (str, "$BP$", 4)
|| !strncmp (str, "$RF$", 4)
|| !strncmp (str, "$LT$", 4)
|| !strncmp (str, "$GT$", 4)
|| !strncmp (str, "$LP$", 4)
|| !strncmp (str, "$RP$", 4))
str += 4;
else if (!strncmp (str, "$u20$", 5)
|| !strncmp (str, "$u22$", 5)
|| !strncmp (str, "$u27$", 5)
|| !strncmp (str, "$u2b$", 5)
|| !strncmp (str, "$u3b$", 5)
|| !strncmp (str, "$u5b$", 5)
|| !strncmp (str, "$u5d$", 5)
|| !strncmp (str, "$u7b$", 5)
|| !strncmp (str, "$u7d$", 5)
|| !strncmp (str, "$u7e$", 5))
str += 5;
else
return 0;
break;
case '.':
/* Do not allow three or more consecutive dots */
if (!strncmp (str, "...", 3))
return 0;
/* Fall through */
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case '_':
case ':':
str++;
break;
default:
return 0;
}
return 1;
}
/*
INPUT: sym: symbol for which rust_is_mangled(sym) returned 1.
The input is demangled in-place because the mangled name is always
longer than the demangled one. */
void
rust_demangle_sym (char *sym)
{
const char *in;
char *out;
const char *end;
if (!sym)
return;
in = sym;
out = sym;
end = sym + strlen (sym) - (hash_prefix_len + hash_len);
while (in < end)
switch (*in)
{
case '$':
if (!(unescape (&in, &out, "$C$", ',')
|| unescape (&in, &out, "$SP$", '@')
|| unescape (&in, &out, "$BP$", '*')
|| unescape (&in, &out, "$RF$", '&')
|| unescape (&in, &out, "$LT$", '<')
|| unescape (&in, &out, "$GT$", '>')
|| unescape (&in, &out, "$LP$", '(')
|| unescape (&in, &out, "$RP$", ')')
|| unescape (&in, &out, "$u20$", ' ')
|| unescape (&in, &out, "$u22$", '\"')
|| unescape (&in, &out, "$u27$", '\'')
|| unescape (&in, &out, "$u2b$", '+')
|| unescape (&in, &out, "$u3b$", ';')
|| unescape (&in, &out, "$u5b$", '[')
|| unescape (&in, &out, "$u5d$", ']')
|| unescape (&in, &out, "$u7b$", '{')
|| unescape (&in, &out, "$u7d$", '}')
|| unescape (&in, &out, "$u7e$", '~'))) {
/* unexpected escape sequence, not looks_like_rust. */
goto fail;
}
break;
case '_':
/* If this is the start of a path component and the next
character is an escape sequence, ignore the underscore. The
mangler inserts an underscore to make sure the path
component begins with a XID_Start character. */
if ((in == sym || in[-1] == ':') && in[1] == '$')
in++;
else
*out++ = *in++;
break;
case '.':
if (in[1] == '.')
{
/* ".." becomes "::" */
*out++ = ':';
*out++ = ':';
in += 2;
}
else
{
/* "." becomes "-" */
*out++ = '-';
in++;
}
break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
case ':':
*out++ = *in++;
break;
default:
/* unexpected character in symbol, not looks_like_rust. */
goto fail;
}
goto done;
fail:
*out++ = '?'; /* This is pretty lame, but it's hard to do better. */
done:
*out = '\0';
}
static int
unescape (const char **in, char **out, const char *seq, char value)
{
size_t len = strlen (seq);
if (strncmp (*in, seq, len))
return 0;
**out = value;
*in += len;
*out += 1;
return 1;
}
@@ -0,0 +1,258 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/include/COPYING
*/
/* <ctype.h> replacement macros.
Copyright (C) 2000-2019 Free Software Foundation, Inc.
Contributed by Zack Weinberg <zackw@stanford.edu>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/*
@defvr Extension HOST_CHARSET
This macro indicates the basic character set and encoding used by the
host: more precisely, the encoding used for character constants in
preprocessor @samp{#if} statements (the C "execution character set").
It is defined by @file{safe-ctype.h}, and will be an integer constant
with one of the following values:
@ftable @code
@item HOST_CHARSET_UNKNOWN
The host character set is unknown - that is, not one of the next two
possibilities.
@item HOST_CHARSET_ASCII
The host character set is ASCII.
@item HOST_CHARSET_EBCDIC
The host character set is some variant of EBCDIC. (Only one of the
nineteen EBCDIC varying characters is tested; exercise caution.)
@end ftable
@end defvr
@deffn Extension ISALPHA (@var{c})
@deffnx Extension ISALNUM (@var{c})
@deffnx Extension ISBLANK (@var{c})
@deffnx Extension ISCNTRL (@var{c})
@deffnx Extension ISDIGIT (@var{c})
@deffnx Extension ISGRAPH (@var{c})
@deffnx Extension ISLOWER (@var{c})
@deffnx Extension ISPRINT (@var{c})
@deffnx Extension ISPUNCT (@var{c})
@deffnx Extension ISSPACE (@var{c})
@deffnx Extension ISUPPER (@var{c})
@deffnx Extension ISXDIGIT (@var{c})
These twelve macros are defined by @file{safe-ctype.h}. Each has the
same meaning as the corresponding macro (with name in lowercase)
defined by the standard header @file{ctype.h}. For example,
@code{ISALPHA} returns true for alphabetic characters and false for
others. However, there are two differences between these macros and
those provided by @file{ctype.h}:
@itemize @bullet
@item These macros are guaranteed to have well-defined behavior for all
values representable by @code{signed char} and @code{unsigned char}, and
for @code{EOF}.
@item These macros ignore the current locale; they are true for these
fixed sets of characters:
@multitable {@code{XDIGIT}} {yada yada yada yada yada yada yada yada}
@item @code{ALPHA} @tab @kbd{A-Za-z}
@item @code{ALNUM} @tab @kbd{A-Za-z0-9}
@item @code{BLANK} @tab @kbd{space tab}
@item @code{CNTRL} @tab @code{!PRINT}
@item @code{DIGIT} @tab @kbd{0-9}
@item @code{GRAPH} @tab @code{ALNUM || PUNCT}
@item @code{LOWER} @tab @kbd{a-z}
@item @code{PRINT} @tab @code{GRAPH ||} @kbd{space}
@item @code{PUNCT} @tab @kbd{`~!@@#$%^&*()_-=+[@{]@}\|;:'",<.>/?}
@item @code{SPACE} @tab @kbd{space tab \n \r \f \v}
@item @code{UPPER} @tab @kbd{A-Z}
@item @code{XDIGIT} @tab @kbd{0-9A-Fa-f}
@end multitable
Note that, if the host character set is ASCII or a superset thereof,
all these macros will return false for all values of @code{char} outside
the range of 7-bit ASCII. In particular, both ISPRINT and ISCNTRL return
false for characters with numeric values from 128 to 255.
@end itemize
@end deffn
@deffn Extension ISIDNUM (@var{c})
@deffnx Extension ISIDST (@var{c})
@deffnx Extension IS_VSPACE (@var{c})
@deffnx Extension IS_NVSPACE (@var{c})
@deffnx Extension IS_SPACE_OR_NUL (@var{c})
@deffnx Extension IS_ISOBASIC (@var{c})
These six macros are defined by @file{safe-ctype.h} and provide
additional character classes which are useful when doing lexical
analysis of C or similar languages. They are true for the following
sets of characters:
@multitable {@code{SPACE_OR_NUL}} {yada yada yada yada yada yada yada yada}
@item @code{IDNUM} @tab @kbd{A-Za-z0-9_}
@item @code{IDST} @tab @kbd{A-Za-z_}
@item @code{VSPACE} @tab @kbd{\r \n}
@item @code{NVSPACE} @tab @kbd{space tab \f \v \0}
@item @code{SPACE_OR_NUL} @tab @code{VSPACE || NVSPACE}
@item @code{ISOBASIC} @tab @code{VSPACE || NVSPACE || PRINT}
@end multitable
@end deffn
*/
#include "ansidecl.h"
#include <safe-ctype.h>
#include <stdio.h> /* for EOF */
#if EOF != -1
#error "<safe-ctype.h> requires EOF == -1"
#endif
/* Shorthand */
#define bl _sch_isblank
#define cn _sch_iscntrl
#define di _sch_isdigit
#define is _sch_isidst
#define lo _sch_islower
#define nv _sch_isnvsp
#define pn _sch_ispunct
#define pr _sch_isprint
#define sp _sch_isspace
#define up _sch_isupper
#define vs _sch_isvsp
#define xd _sch_isxdigit
/* Masks. */
#define L (const unsigned short) (lo|is |pr) /* lower case letter */
#define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */
#define U (const unsigned short) (up|is |pr) /* upper case letter */
#define XU (const unsigned short) (up|is|xd|pr) /* uppercase hex digit */
#define D (const unsigned short) (di |xd|pr) /* decimal digit */
#define P (const unsigned short) (pn |pr) /* punctuation */
#define _ (const unsigned short) (pn|is |pr) /* underscore */
#define C (const unsigned short) ( cn) /* control character */
#define Z (const unsigned short) (nv |cn) /* NUL */
#define M (const unsigned short) (nv|sp |cn) /* cursor movement: \f \v */
#define V (const unsigned short) (vs|sp |cn) /* vertical space: \r \n */
#define T (const unsigned short) (nv|sp|bl|cn) /* tab */
#define S (const unsigned short) (nv|sp|bl|pr) /* space */
/* Are we ASCII? */
#if HOST_CHARSET == HOST_CHARSET_ASCII
const unsigned short _sch_istable[256] =
{
Z, C, C, C, C, C, C, C, /* NUL SOH STX ETX EOT ENQ ACK BEL */
C, T, V, M, M, V, C, C, /* BS HT LF VT FF CR SO SI */
C, C, C, C, C, C, C, C, /* DLE DC1 DC2 DC3 DC4 NAK SYN ETB */
C, C, C, C, C, C, C, C, /* CAN EM SUB ESC FS GS RS US */
S, P, P, P, P, P, P, P, /* SP ! " # $ % & ' */
P, P, P, P, P, P, P, P, /* ( ) * + , - . / */
D, D, D, D, D, D, D, D, /* 0 1 2 3 4 5 6 7 */
D, D, P, P, P, P, P, P, /* 8 9 : ; < = > ? */
P, XU, XU, XU, XU, XU, XU, U, /* @ A B C D E F G */
U, U, U, U, U, U, U, U, /* H I J K L M N O */
U, U, U, U, U, U, U, U, /* P Q R S T U V W */
U, U, U, P, P, P, P, _, /* X Y Z [ \ ] ^ _ */
P, XL, XL, XL, XL, XL, XL, L, /* ` a b c d e f g */
L, L, L, L, L, L, L, L, /* h i j k l m n o */
L, L, L, L, L, L, L, L, /* p q r s t u v w */
L, L, L, P, P, P, P, C, /* x y z { | } ~ DEL */
/* high half of unsigned char is locale-specific, so all tests are
false in "C" locale */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const unsigned char _sch_tolower[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
91, 92, 93, 94, 95, 96,
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
const unsigned char _sch_toupper[256] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
91, 92, 93, 94, 95, 96,
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
123,124,125,126,127,
128,129,130,131, 132,133,134,135, 136,137,138,139, 140,141,142,143,
144,145,146,147, 148,149,150,151, 152,153,154,155, 156,157,158,159,
160,161,162,163, 164,165,166,167, 168,169,170,171, 172,173,174,175,
176,177,178,179, 180,181,182,183, 184,185,186,187, 188,189,190,191,
192,193,194,195, 196,197,198,199, 200,201,202,203, 204,205,206,207,
208,209,210,211, 212,213,214,215, 216,217,218,219, 220,221,222,223,
224,225,226,227, 228,229,230,231, 232,233,234,235, 236,237,238,239,
240,241,242,243, 244,245,246,247, 248,249,250,251, 252,253,254,255,
};
#else
# if HOST_CHARSET == HOST_CHARSET_EBCDIC
#error "FIXME: write tables for EBCDIC"
# else
#error "Unrecognized host character set"
# endif
#endif
@@ -0,0 +1,56 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/libiberty/COPYING.LIB
*/
/* xexit.c -- Run any exit handlers, then exit.
Copyright (C) 1994-2019 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If not, write
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/*
@deftypefn Replacement void xexit (int @var{code})
Terminates the program. If any functions have been registered with
the @code{xatexit} replacement function, they will be called first.
Termination is handled via the system's normal @code{exit} call.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "libiberty.h"
/* This variable is set by xatexit if it is called. This way, xmalloc
doesn't drag xatexit into the link. */
void (*_xexit_cleanup) (void);
void
xexit (int code)
{
if (_xexit_cleanup != NULL)
(*_xexit_cleanup) ();
exit (code);
}
@@ -0,0 +1,39 @@
/* ###
* IP: Public Domain
*/
/* xstrdup.c -- Duplicate a string in memory, using xmalloc.
This trivial function is in the public domain.
Ian Lance Taylor, Cygnus Support, December 1995. */
/*
@deftypefn Replacement char* xstrdup (const char *@var{s})
Duplicates a character string without fail, using @code{xmalloc} to
obtain memory.
@end deftypefn
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
# ifdef HAVE_STRINGS_H
# include <strings.h>
# endif
#endif
#include "ansidecl.h"
#include "libiberty.h"
char *
xstrdup (const char *s)
{
register size_t len = strlen (s) + 1;
register char *ret = XNEWVEC (char, len);
return (char *) memcpy (ret, s, len);
}
@@ -0,0 +1,406 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/include/COPYING
*/
/* ANSI and traditional C compatability macros
Copyright (C) 1991-2019 Free Software Foundation, Inc.
This file is part of the GNU C 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* ANSI and traditional C compatibility macros
ANSI C is assumed if __STDC__ is #defined.
Macro ANSI C definition Traditional C definition
----- ---- - ---------- ----------- - ----------
PTR `void *' `char *'
const not defined `'
volatile not defined `'
signed not defined `'
For ease of writing code which uses GCC extensions but needs to be
portable to other compilers, we provide the GCC_VERSION macro that
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
wrappers around __attribute__. Also, __extension__ will be #defined
to nothing if it doesn't work. See below. */
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
older preprocessors. Thus we can't define something like this:
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
and then test "#if HAVE_GCC_VERSION(2,7)".
So instead we use the macro below and test it against specific values. */
/* This macro simplifies testing whether we are using gcc, and if it
is of a particular minimum version. (Both major & minor numbers are
significant.) This macro will evaluate to 0 if we are not using
gcc at all. */
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */
#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
/* All known AIX compilers implement these things (but don't always
define __STDC__). The RISC/OS MIPS compiler defines these things
in SVR4 mode, but does not define __STDC__. */
/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other
C++ compilers, does not define __STDC__, though it acts as if this
was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */
#define PTR void *
#undef const
#undef volatile
#undef signed
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
# else
# define inline /* nothing */
# endif
#endif
#else /* Not ANSI C. */
#define PTR char *
/* some systems define these in header files for non-ansi mode */
#undef const
#undef volatile
#undef signed
#undef inline
#define const
#define volatile
#define signed
#define inline
#endif /* ANSI C. */
/* Define macros for some gcc attributes. This permits us to use the
macros freely, and know that they will come into play for the
version of gcc in which they are supported. */
#if (GCC_VERSION < 2007)
# define __attribute__(x)
#endif
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
#ifndef ATTRIBUTE_MALLOC
# if (GCC_VERSION >= 2096)
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
# else
# define ATTRIBUTE_MALLOC
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
g++ an attribute on a label must be followed by a semicolon. */
#ifndef ATTRIBUTE_UNUSED_LABEL
# ifndef __cplusplus
# if GCC_VERSION >= 2093
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# else
# if GCC_VERSION >= 4005
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# endif
#endif
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
couldn't parse attributes placed after the identifier name, and now
the entire compiler is built with C++. */
#ifndef ATTRIBUTE_UNUSED
#if GCC_VERSION >= 3004
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#else
#define ATTRIBUTE_UNUSED
#endif
#endif /* ATTRIBUTE_UNUSED */
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
identifier name. */
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
#else /* !__cplusplus || GNUC >= 3.4 */
# define ARG_UNUSED(NAME) NAME
#endif /* !__cplusplus || GNUC >= 3.4 */
#ifndef ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
#endif /* ATTRIBUTE_NORETURN */
/* Attribute `nonnull' was valid as of gcc 3.3. */
#ifndef ATTRIBUTE_NONNULL
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
# else
# define ATTRIBUTE_NONNULL(m)
# endif /* GNUC >= 3.3 */
#endif /* ATTRIBUTE_NONNULL */
/* Attribute `returns_nonnull' was valid as of gcc 4.9. */
#ifndef ATTRIBUTE_RETURNS_NONNULL
# if (GCC_VERSION >= 4009)
# define ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
# else
# define ATTRIBUTE_RETURNS_NONNULL
# endif /* GNUC >= 4.9 */
#endif /* ATTRIBUTE_RETURNS_NONNULL */
/* Attribute `pure' was valid as of gcc 3.0. */
#ifndef ATTRIBUTE_PURE
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
# define ATTRIBUTE_PURE
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_PURE */
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
This was the case for the `printf' format attribute by itself
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
attribute to retain this behavior. */
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
a function pointer. Format attributes were allowed on function
pointers as of gcc 3.1. */
#ifndef ATTRIBUTE_FPTR_PRINTF
# if (GCC_VERSION >= 3001)
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
# else
# define ATTRIBUTE_FPTR_PRINTF(m, n)
# endif /* GNUC >= 3.1 */
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
#endif /* ATTRIBUTE_FPTR_PRINTF */
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
NULL format specifier was allowed as of gcc 3.3. */
#ifndef ATTRIBUTE_NULL_PRINTF
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
# else
# define ATTRIBUTE_NULL_PRINTF(m, n)
# endif /* GNUC >= 3.3 */
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
#endif /* ATTRIBUTE_NULL_PRINTF */
/* Attribute `sentinel' was valid as of gcc 3.5. */
#ifndef ATTRIBUTE_SENTINEL
# if (GCC_VERSION >= 3005)
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
# else
# define ATTRIBUTE_SENTINEL
# endif /* GNUC >= 3.5 */
#endif /* ATTRIBUTE_SENTINEL */
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
# else
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
/* Useful for structures whose layout must match some binary specification
regardless of the alignment and padding qualities of the compiler. */
#ifndef ATTRIBUTE_PACKED
# define ATTRIBUTE_PACKED __attribute__ ((packed))
#endif
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
#ifndef ATTRIBUTE_COLD
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
# else
# define ATTRIBUTE_COLD
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_COLD */
#ifndef ATTRIBUTE_HOT
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
# else
# define ATTRIBUTE_HOT
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_HOT */
/* Attribute 'no_sanitize_undefined' was valid as of gcc 4.9. */
#ifndef ATTRIBUTE_NO_SANITIZE_UNDEFINED
# if (GCC_VERSION >= 4009)
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined))
# else
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
# endif /* GNUC >= 4.9 */
#endif /* ATTRIBUTE_NO_SANITIZE_UNDEFINED */
/* Attribute 'nonstring' was valid as of gcc 8. */
#ifndef ATTRIBUTE_NONSTRING
# if GCC_VERSION >= 8000
# define ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
# else
# define ATTRIBUTE_NONSTRING
# endif
#endif
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */
#if GCC_VERSION < 2008
#define __extension__
#endif
/* This is used to declare a const variable which should be visible
outside of the current compilation unit. Use it as
EXPORTED_CONST int i = 1;
This is because the semantics of const are different in C and C++.
"extern const" is permitted in C but it looks strange, and gcc
warns about it when -Wc++-compat is not used. */
#ifdef __cplusplus
#define EXPORTED_CONST extern const
#else
#define EXPORTED_CONST const
#endif
/* Be conservative and only use enum bitfields with C++ or GCC.
FIXME: provide a complete autoconf test for buggy enum bitfields. */
#ifdef __cplusplus
#define ENUM_BITFIELD(TYPE) enum TYPE
#elif (GCC_VERSION > 2000)
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
#else
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
#if __cpp_constexpr >= 200704
#define CONSTEXPR constexpr
#else
#define CONSTEXPR
#endif
/* C++11 adds the ability to add "override" after an implementation of a
virtual function in a subclass, to:
(A) document that this is an override of a virtual function
(B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
of the type signature).
Similarly, it allows us to add a "final" to indicate that no subclass
may subsequently override the vfunc.
Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
when compiling with C++11 support, but without requiring C++11.
For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
this by default (actually GNU++14). */
#if defined __cplusplus
# if __cplusplus >= 201103
/* C++11 claims to be available: use it. Final/override were only
implemented in 4.7, though. */
# if GCC_VERSION < 4007
# define OVERRIDE
# define FINAL
# else
# define OVERRIDE override
# define FINAL final
# endif
# elif GCC_VERSION >= 4007
/* G++ 4.7 supports __final in C++98. */
# define OVERRIDE
# define FINAL __final
# else
/* No C++11 support; leave the macros empty. */
# define OVERRIDE
# define FINAL
# endif
#else
/* No C++11 support; leave the macros empty. */
# define OVERRIDE
# define FINAL
#endif
/* A macro to disable the copy constructor and assignment operator.
When building with C++11 and above, the methods are explicitly
deleted, causing a compile-time error if something tries to copy.
For C++03, this just declares the methods, causing a link-time
error if the methods end up called (assuming you don't
define them). For C++03, for best results, place the macro
under the private: access specifier, like this,
class name_lookup
{
private:
DISABLE_COPY_AND_ASSIGN (name_lookup);
};
so that most attempts at copy are caught at compile-time. */
#if __cplusplus >= 201103
#define DISABLE_COPY_AND_ASSIGN(TYPE) \
TYPE (const TYPE&) = delete; \
void operator= (const TYPE &) = delete
#else
#define DISABLE_COPY_AND_ASSIGN(TYPE) \
TYPE (const TYPE&); \
void operator= (const TYPE &)
#endif /* __cplusplus >= 201103 */
#ifdef __cplusplus
}
#endif
#endif /* ansidecl.h */
@@ -0,0 +1,201 @@
/* ###
* IP: GPL 3 Linking Permitted
* NOTE: See binutils/libiberty/COPYING.LIB; Used GPL 3 from this file's header
*/
/* Internal demangler interface for g++ V3 ABI.
Copyright (C) 2003-2019 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
This file is part of the libiberty library, which is part of GCC.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* This file provides some definitions shared by cp-demangle.c and
cp-demint.c. It should not be included by any other files. */
/* Information we keep for operators. */
struct demangle_operator_info
{
/* Mangled name. */
const char *code;
/* Real name. */
const char *name;
/* Length of real name. */
int len;
/* Number of arguments. */
int args;
};
/* How to print the value of a builtin type. */
enum d_builtin_type_print
{
/* Print as (type)val. */
D_PRINT_DEFAULT,
/* Print as integer. */
D_PRINT_INT,
/* Print as unsigned integer, with trailing "u". */
D_PRINT_UNSIGNED,
/* Print as long, with trailing "l". */
D_PRINT_LONG,
/* Print as unsigned long, with trailing "ul". */
D_PRINT_UNSIGNED_LONG,
/* Print as long long, with trailing "ll". */
D_PRINT_LONG_LONG,
/* Print as unsigned long long, with trailing "ull". */
D_PRINT_UNSIGNED_LONG_LONG,
/* Print as bool. */
D_PRINT_BOOL,
/* Print as float--put value in square brackets. */
D_PRINT_FLOAT,
/* Print in usual way, but here to detect void. */
D_PRINT_VOID
};
/* Information we keep for a builtin type. */
struct demangle_builtin_type_info
{
/* Type name. */
const char *name;
/* Length of type name. */
int len;
/* Type name when using Java. */
const char *java_name;
/* Length of java name. */
int java_len;
/* How to print a value of this type. */
enum d_builtin_type_print print;
};
/* The information structure we pass around. */
struct d_info
{
/* The string we are demangling. */
const char *s;
/* The end of the string we are demangling. */
const char *send;
/* The options passed to the demangler. */
int options;
/* The next character in the string to consider. */
const char *n;
/* The array of components. */
struct demangle_component *comps;
/* The index of the next available component. */
int next_comp;
/* The number of available component structures. */
int num_comps;
/* The array of substitutions. */
struct demangle_component **subs;
/* The index of the next substitution. */
int next_sub;
/* The number of available entries in the subs array. */
int num_subs;
/* The last name we saw, for constructors and destructors. */
struct demangle_component *last_name;
/* A running total of the length of large expansions from the
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
/* Non-zero if we are parsing an expression. */
int is_expression;
/* Non-zero if we are parsing the type operand of a conversion
operator, but not when in an expression. */
int is_conversion;
/* If DMGL_NO_RECURSE_LIMIT is not active then this is set to
the current recursion level. */
unsigned int recursion_level;
};
/* To avoid running past the ending '\0', don't:
- call d_peek_next_char if d_peek_char returned '\0'
- call d_advance with an 'i' that is too large
- call d_check_char(di, '\0')
Everything else is safe. */
#define d_peek_char(di) (*((di)->n))
#ifndef CHECK_DEMANGLER
# define d_peek_next_char(di) ((di)->n[1])
# define d_advance(di, i) ((di)->n += (i))
#endif
#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
#define d_str(di) ((di)->n)
#ifdef CHECK_DEMANGLER
static inline char
d_peek_next_char (const struct d_info *di)
{
if (!di->n[0])
abort ();
return di->n[1];
}
static inline void
d_advance (struct d_info *di, int i)
{
if (i < 0)
abort ();
while (i--)
{
if (!di->n[0])
abort ();
di->n++;
}
}
#endif
/* Functions and arrays in cp-demangle.c which are referenced by
functions in cp-demint.c. */
#ifdef IN_GLIBCPP_V3
#define CP_STATIC_IF_GLIBCPP_V3 static
#else
#define CP_STATIC_IF_GLIBCPP_V3 extern
#endif
#ifndef IN_GLIBCPP_V3
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif
#define D_BUILTIN_TYPE_COUNT (34)
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *, int);
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_type (struct d_info *);
extern void
cplus_demangle_init_info (const char *, int, size_t, struct d_info *);
/* cp-demangle.c needs to define this a little differently */
#undef CP_STATIC_IF_GLIBCPP_V3
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
/* ###
* IP: GPL 3
* NOTE: See binutils/include/COPYING3
*/
/* An abstract string datatype.
Copyright (C) 1998-2019 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC 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 GCC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifndef DYN_STRING_H
#define DYN_STRING_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct dyn_string
{
int allocated; /* The amount of space allocated for the string. */
int length; /* The actual length of the string. */
char *s; /* The string itself, NUL-terminated. */
}* dyn_string_t;
/* The length STR, in bytes, not including the terminating NUL. */
#define dyn_string_length(STR) \
((STR)->length)
/* The NTBS in which the contents of STR are stored. */
#define dyn_string_buf(STR) \
((STR)->s)
/* Compare DS1 to DS2 with strcmp. */
#define dyn_string_compare(DS1, DS2) \
(strcmp ((DS1)->s, (DS2)->s))
extern int dyn_string_init (struct dyn_string *, int);
extern dyn_string_t dyn_string_new (int);
extern void dyn_string_delete (dyn_string_t);
extern char *dyn_string_release (dyn_string_t);
extern dyn_string_t dyn_string_resize (dyn_string_t, int);
extern void dyn_string_clear (dyn_string_t);
extern int dyn_string_copy (dyn_string_t, dyn_string_t);
extern int dyn_string_copy_cstr (dyn_string_t, const char *);
extern int dyn_string_prepend (dyn_string_t, dyn_string_t);
extern int dyn_string_prepend_cstr (dyn_string_t, const char *);
extern int dyn_string_insert (dyn_string_t, int, dyn_string_t);
extern int dyn_string_insert_cstr (dyn_string_t, int, const char *);
extern int dyn_string_insert_char (dyn_string_t, int, int);
extern int dyn_string_append (dyn_string_t, dyn_string_t);
extern int dyn_string_append_cstr (dyn_string_t, const char *);
extern int dyn_string_append_char (dyn_string_t, int);
extern int dyn_string_substring (dyn_string_t, dyn_string_t, int, int);
extern int dyn_string_eq (dyn_string_t, dyn_string_t);
#ifdef __cplusplus
}
#endif
#endif /* !defined (DYN_STRING_H) */
@@ -0,0 +1,147 @@
/* ###
* IP: GPL 3
* NOTE: See binutils/include/COPYING3
*/
/* Declarations for getopt.
Copyright (C) 1989-2019 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@gnu.org.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if defined (__STDC__) && __STDC__
/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is
undefined, we haven't run the autoconf check so provide the
declaration without arguments. If it is 0, we checked and failed
to find the declaration so provide a fully prototyped one. If it
is 1, we found it so don't provide any declaration at all. */
#if !HAVE_DECL_GETOPT
#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT)
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in unistd.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else
#ifndef __cplusplus
extern int getopt ();
#endif /* __cplusplus */
#endif
#endif /* !HAVE_DECL_GETOPT */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* getopt.h */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,49 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/libiberty/COPYING.LIB
*/
/* Internal demangler interface for the Rust programming language.
Copyright (C) 2016-2019 Free Software Foundation, Inc.
Written by David Tolnay (dtolnay@gmail.com).
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
In addition to the permissions in the GNU Library General Public
License, the Free Software Foundation gives you unlimited permission
to link the compiled version of this file into combinations with other
programs, and to distribute those combinations without any restriction
coming from the use of this file. (The Library Public License
restrictions do apply in other respects; for example, they cover
modification of the file, and distribution when not linked into a
combined executable.)
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/>. */
/* This file provides some definitions shared by cplus-dem.c and
rust-demangle.c. It should not be included by any other files. */
/* Returns non-zero iff MANGLED is a rust mangled symbol. MANGLED must
already have been demangled through cplus_demangle_v3. If this function
returns non-zero then MANGLED can be demangled (in-place) using
RUST_DEMANGLE_SYM. */
extern int
rust_is_mangled (const char *mangled);
/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
replace characters that cannot be demangled with '?' and might truncate
SYM. After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
larger. */
extern void
rust_demangle_sym (char *sym);
@@ -0,0 +1,154 @@
/* ###
* IP: LGPL 2.1
* NOTE: See binutils/include/COPYING
*/
/* <ctype.h> replacement macros.
Copyright (C) 2000-2019 Free Software Foundation, Inc.
Contributed by Zack Weinberg <zackw@stanford.edu>.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
/* This is a compatible replacement of the standard C library's <ctype.h>
with the following properties:
- Implements all isxxx() macros required by C99.
- Also implements some character classes useful when
parsing C-like languages.
- Does not change behavior depending on the current locale.
- Behaves properly for all values in the range of a signed or
unsigned char.
To avoid conflicts, this header defines the isxxx functions in upper
case, e.g. ISALPHA not isalpha. */
#ifndef SAFE_CTYPE_H
#define SAFE_CTYPE_H
/* Determine host character set. */
#define HOST_CHARSET_UNKNOWN 0
#define HOST_CHARSET_ASCII 1
#define HOST_CHARSET_EBCDIC 2
#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
&& 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
# define HOST_CHARSET HOST_CHARSET_ASCII
#else
# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
&& 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
# define HOST_CHARSET HOST_CHARSET_EBCDIC
# else
# define HOST_CHARSET HOST_CHARSET_UNKNOWN
# endif
#endif
/* Categories. */
enum {
/* In C99 */
_sch_isblank = 0x0001, /* space \t */
_sch_iscntrl = 0x0002, /* nonprinting characters */
_sch_isdigit = 0x0004, /* 0-9 */
_sch_islower = 0x0008, /* a-z */
_sch_isprint = 0x0010, /* any printing character including ' ' */
_sch_ispunct = 0x0020, /* all punctuation */
_sch_isspace = 0x0040, /* space \t \n \r \f \v */
_sch_isupper = 0x0080, /* A-Z */
_sch_isxdigit = 0x0100, /* 0-9A-Fa-f */
/* Extra categories useful to cpplib. */
_sch_isidst = 0x0200, /* A-Za-z_ */
_sch_isvsp = 0x0400, /* \n \r */
_sch_isnvsp = 0x0800, /* space \t \f \v \0 */
/* Combinations of the above. */
_sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */
_sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */
_sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */
_sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */
_sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */
_sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C
(plus ` and @) */
};
/* Character classification. */
extern const unsigned short _sch_istable[256];
#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit))
#define ISALPHA(c) _sch_test(c, _sch_isalpha)
#define ISALNUM(c) _sch_test(c, _sch_isalnum)
#define ISBLANK(c) _sch_test(c, _sch_isblank)
#define ISCNTRL(c) _sch_test(c, _sch_iscntrl)
#define ISDIGIT(c) _sch_test(c, _sch_isdigit)
#define ISGRAPH(c) _sch_test(c, _sch_isgraph)
#define ISLOWER(c) _sch_test(c, _sch_islower)
#define ISPRINT(c) _sch_test(c, _sch_isprint)
#define ISPUNCT(c) _sch_test(c, _sch_ispunct)
#define ISSPACE(c) _sch_test(c, _sch_isspace)
#define ISUPPER(c) _sch_test(c, _sch_isupper)
#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit)
#define ISIDNUM(c) _sch_test(c, _sch_isidnum)
#define ISIDST(c) _sch_test(c, _sch_isidst)
#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic)
#define IS_VSPACE(c) _sch_test(c, _sch_isvsp)
#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp)
#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp)
/* Character transformation. */
extern const unsigned char _sch_toupper[256];
extern const unsigned char _sch_tolower[256];
#define TOUPPER(c) _sch_toupper[(c) & 0xff]
#define TOLOWER(c) _sch_tolower[(c) & 0xff]
/* Prevent the users of safe-ctype.h from accidently using the routines
from ctype.h. Initially, the approach was to produce an error when
detecting that ctype.h has been included. But this was causing
trouble as ctype.h might get indirectly included as a result of
including another system header (for instance gnulib's stdint.h).
So we include ctype.h here and then immediately redefine its macros. */
#include <ctype.h>
#undef isalpha
#define isalpha(c) do_not_use_isalpha_with_safe_ctype
#undef isalnum
#define isalnum(c) do_not_use_isalnum_with_safe_ctype
#undef iscntrl
#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype
#undef isdigit
#define isdigit(c) do_not_use_isdigit_with_safe_ctype
#undef isgraph
#define isgraph(c) do_not_use_isgraph_with_safe_ctype
#undef islower
#define islower(c) do_not_use_islower_with_safe_ctype
#undef isprint
#define isprint(c) do_not_use_isprint_with_safe_ctype
#undef ispunct
#define ispunct(c) do_not_use_ispunct_with_safe_ctype
#undef isspace
#define isspace(c) do_not_use_isspace_with_safe_ctype
#undef isupper
#define isupper(c) do_not_use_isupper_with_safe_ctype
#undef isxdigit
#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype
#undef toupper
#define toupper(c) do_not_use_toupper_with_safe_ctype
#undef tolower
#define tolower(c) do_not_use_tolower_with_safe_ctype
#endif /* SAFE_CTYPE_H */
@@ -28,7 +28,7 @@ body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 1
li { font-family:times new roman; font-size:14pt; }
h1 { color:#000080; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; }
h2 { margin: 10px; margin-top: 20px; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; font-size:14pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; `font-size:14pt; font-weight:bold; }
h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; }
/*
@@ -55,4 +55,10 @@ table { margin-left: 20px; margin-top: 10px; width: 80%;}
td { font-family:times new roman; font-size:14pt; vertical-align: top; }
th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; }
code { color: black; font-family: courier new; font-size: 14pt; }
/*
Code-like formatting for things such as file system paths and proper names of classes,
methods, etc. To apply this to a file path, use this syntax:
<CODE CLASS="path">...</CODE>
*/
code { color: black; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
@@ -28,7 +28,7 @@ body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 1
li { font-family:times new roman; font-size:14pt; }
h1 { color:#000080; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; }
h2 { margin: 10px; margin-top: 20px; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; font-size:14pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; `font-size:14pt; font-weight:bold; }
h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; }
/*
@@ -55,4 +55,10 @@ table { margin-left: 20px; margin-top: 10px; width: 80%;}
td { font-family:times new roman; font-size:14pt; vertical-align: top; }
th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; }
code { color: black; font-family: courier new; font-size: 14pt; }
/*
Code-like formatting for things such as file system paths and proper names of classes,
methods, etc. To apply this to a file path, use this syntax:
<CODE CLASS="path">...</CODE>
*/
code { color: black; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
@@ -82,7 +82,6 @@ ghidra_scripts/world.png||FAMFAMFAM Icons - CC 2.5|||famfamfam silk icon set|END
src/main/help/help/TOC_Source.xml||GHIDRA||||END|
src/main/help/help/shared/arrow.gif||GHIDRA||||END|
src/main/help/help/shared/close16.gif||GHIDRA||||END|
src/main/help/help/shared/helpWarning.png||Oxygen Icons - LGPL 3.0|||Oxygen icon theme (dual license; LGPL or CC-SA-3.0)|END|
src/main/help/help/shared/menu16.gif||GHIDRA||||END|
src/main/help/help/shared/note-red.png||Oxygen Icons - LGPL 3.0|||renamed from flag-red.png|END|
src/main/help/help/shared/note.png||Oxygen Icons - LGPL 3.0|||renamed from flag-green.png|END|
@@ -28,7 +28,7 @@ body { margin-bottom: 50px; margin-left: 10px; margin-right: 10px; margin-top: 1
li { font-family:times new roman; font-size:14pt; }
h1 { color:#000080; font-family:times new roman; font-size:36pt; font-style:italic; font-weight:bold; text-align:center; }
h2 { margin: 10px; margin-top: 20px; color:#984c4c; font-family:times new roman; font-size:18pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; font-size:14pt; font-weight:bold; }
h3 { margin-left: 10px; margin-top: 20px; color:#0000ff; font-family:times new roman; `font-size:14pt; font-weight:bold; }
h4 { margin-left: 10px; margin-top: 20px; font-family:times new roman; font-size:14pt; font-style:italic; }
/*
@@ -55,4 +55,10 @@ table { margin-left: 20px; margin-top: 10px; width: 80%;}
td { font-family:times new roman; font-size:14pt; vertical-align: top; }
th { font-family:times new roman; font-size:14pt; font-weight:bold; background-color: #EDF3FE; }
code { color: black; font-family: courier new; font-size: 14pt; }
/*
Code-like formatting for things such as file system paths and proper names of classes,
methods, etc. To apply this to a file path, use this syntax:
<CODE CLASS="path">...</CODE>
*/
code { color: black; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
code.path { color: #4682B4; font-weight: bold; font-family: courier new, monospace; font-size: 14pt; white-space: nowrap; }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

@@ -5,7 +5,7 @@
<META name="generator" content=
"HTML Tidy for Java (vers. 2009-12-01), see jtidy.sourceforge.net">
<TITLE>Auto-analysis</TITLE>
<TITLE>Auto Analysis</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=windows-1252">
<LINK rel="stylesheet" type="text/css" href="../../shared/Frontpage.css">
</HEAD>
@@ -24,7 +24,7 @@
<BLOCKQUOTE>
<OL>
<LI>User Disassembles</LI>
<LI>The user triggers disassembly</LI>
<LI>Function Analyzer - looks at all calls and creates Functions</LI>
@@ -34,9 +34,8 @@
<LI>Operand Analyzer - looks at scalar operands for possible address references</LI>
<LI>Data Reference Analyzer - looks at references for possible strings or pointers to
code.<BR>
References to code are disassembled.<BR>
..... Cycle repeats with 2) as additional code is disassembled.</LI>
code. References to code are disassembled.<BR>
.....The cycle repeats with 2) as additional code is disassembled.</LI>
</OL>
<P>One program change might cause several Analyzers to become active, however only one
@@ -210,46 +209,46 @@
<H4><B>Options</B></H4>
<UL>
<LI><B>Create strings containing existing strings</B> - if checked, strings will be
<LI><B>Create Strings Containing Existing Strings</B> - if checked, strings will be
created even if they contain existing substrings (existing strings will be cleared). The
string will be created only if existing strings (a) are wholly contained within the
potential string, (b) do not share the same starting address as the potential string, (c)
share the same ending address as the potential string, and (d) are the same datatype as
the potential string to be created).</LI>
<LI><B>Create strings containing references</B> - if checked, strings that contain, but
<LI><B>Create Strings Containing References</B> - if checked, strings that contain, but
do not start with, one or more references will be created.</LI>
<LI><B>Force model reload</B> - if checked, forces the model to be reloaded every time
<LI><B>Force Model Reload</B> - if checked, forces the model to be reloaded every time
the analyzer is run (in cases where the user wishes to see the effect of changing a model
without restarting Ghidra).</LI>
<LI><B>Minimum string length</B> - specifies the smallest number of characters in a
<LI><B>Minimum String Length</B> - specifies the smallest number of characters in a
string for it to be considered a valid string. For this analyzer, null termination
characters are ignored for the purposes of counting characters. Note that smaller numbers
will result in a larger number of false positives. String length must be at least 4.</LI>
<LI><B>Model file</B> - Specifies the model file built using the BuildStringModels class
<LI><B>Model File</B> - Specifies the model file built using the BuildStringModels class
(default is 'StringModel.sng'). Note that the location of the model file does not need to
be specified, as models should always be placed in the
'Ghidra/Features/Base/data/stringngrams' directory.</LI>
<CODE CLASS="path">&lt;GHIDRA_INSTALL_DIR&gt;/Ghidra/Features/Base/data/stringngrams/</CODE> directory.</LI>
<LI><B>Require null termination for string</B> - if checked, only null-terminated strings
<LI><B>Require Null Termination for String</B> - if checked, only null-terminated strings
are created.</LI>
<LI><B>Search only in accessible memory blocks</B> - if checked, searches only in memory
<LI><B>Search Only in Accessible Memory Blocks</B> - if checked, searches only in memory
blocks that have at least one of the Read (R), Write (W), or Execute (X) permissions set
to true. Enabling this option ensures strings are not created in areas such as overlays
or debug sections.</LI>
<LI><B>String end alignment</B> - specifies the byte alignment requirement for the end of
<LI><B>String End Alignment</B> - specifies the byte alignment requirement for the end of
the string. An alignment of 1 means the string can end at any address. Alignments greater
than 1 require that (a) the 'require null termination' option be enabled, and (b) if the
null-terminated string does not end at an aligned boundary, that there exist enough
trailing '0' bytes following the string to allow alignment. If neither (a) nor (b) apply,
end alignment is not enforced.</LI>
<LI><B>String start alignment</B> - specifies the byte alignment requirement for the
<LI><B>String Start Alignment</B> - specifies the byte alignment requirement for the
start of the string. An alignment of 1 means that strings can start at any address. An
alignment of 2 means that strings must start on an even address. An alignment of 4 means
that strings must start on an address that is a multiple of 4.</LI>
@@ -344,7 +343,100 @@
name and create a new primary symbol for the demangled name. It will also assign the
appropriate datatypes to the parameters and return type.</P>
<P><U>Started By:</U> New defined functions</P>
<P>
The default demangler options are:
<TABLE BORDER="1">
<TR>
<TH WIDTH="25%">Name</TH>
<TH WIDTH="75%">Description</TH>
</TR>
<TR>
<TD>Apply Function Signatures
</TD>
<TD>
Apply any recovered function signature type information
in addition to the function name
</TD>
</TR>
<TR>
<TD>Only Demangle Known Mangled Symbols
</TD>
<TD>
Only demangle symbols that follow known compiler mangling patterns.
Leaving this option off may cause non-mangled symbols to get demangled.
</TD>
</TR>
</TABLE>
</P>
<P><A name="Gnu_Demangler_Options">
<BR>
<BR>
<B>The GNU Demangler</B> adds the following analysis options:
<BLOCKQUOTE>
<P>
<U><B>Use Deprecated Demangler</B></U> -
By default, GCC symbols will be demangled using the most up-to-date demangler
that Ghidra contains (<B>version 2.33.1</B> as of this writing). Turning this
option on will also invoke the now deprecated previous version of the demangler
(<B>version 2.24</B>) if the preferred demangler cannot demangle a given symbol.
</P>
<P>
Support for older demangling styles was removed in <CODE>c++filt (v2.32)</CODE>.
Specifically, the following formats are no longer supported:
<CODE>Lucid, ARM, HP, and EDG</CODE>. To use these formats, you must enable
usage of the deprecated demangler, which is <B>version 2.24</B>. Further, you
may have to pass the required external demangler options using the Ghidra
option below.
</P>
<P>
<U><B>Use External Demangler Options</B></U> -
This allows users to pass settings to the demangler. As an example, you can enter
in this Ghidra option text field the following text to use the <CODE>rust</CODE>
format: <CODE>-s rust</CODE>. This is not needed for
normal operation. To see a full list of supported options, query each demangler
directly using the <CODE>--help</CODE> switch.
</P>
<P>
The GNU demanglers can be found at:
<CODE CLASS="path">
&lt;GHIDRA_INSTALL_DIR&gt;/GPL/DemanglerGnu/build/os/&lt;OS&gt;/
</CODE><BR>
</P>
<BLOCKQUOTE>
<P>
The available programs are:
<UL>
<LI><CODE>demangler_gnu_v2_33_1</CODE></LI>
<LI><CODE>demangler_gnu_v2_24</CODE></LI>
</UL>
</P>
<P style="background-color: #FFF0E0;">
<IMG SRC="../../shared/warning.png" />When using an external GNU demangler,
please understand the risks associated with using that version of the
software. The <CODE>demangler_gnu_v2_24</CODE> version of the
demangler is a modified version of GNU's <CODE>c++filt (v2.24)</CODE>. The
original version has known vulnerabilities, some of which have been
mitigated in the version created for Ghidra. Use caution when enabling this
feature.
</P>
</BLOCKQUOTE>
<P>
<IMG SRC="../../shared/tip.png" />The Demangler Analyzer is designed to be extensible.
You can extend <CODE>ghidra.app.plugin.core.analysis.AbstractDemanglerAnalyzer</CODE>
to add your demangler analyzer callback. This allows you to precisely control
which demanglers get called, as well as which options are used.
</P>
</BLOCKQUOTE>
<P STYLE="margin-top: 30px;"><U>Started By:</U> New defined functions</P>
</BLOCKQUOTE>
<H3><A name="Auto_Analysis_Option_Byte"></A>Entry Point Analyzer</H3>
@@ -72,7 +72,7 @@ public class DemanglerCmd extends BackgroundCommand {
private boolean doDemangle(Demangler demangler, Program program, TaskMonitor monitor) {
try {
demangledObject = demangler.demangle(mangled, options.demangleOnlyKnownPatterns());
demangledObject = demangler.demangle(mangled, options);
}
catch (DemangledException e) {
if (e.isInvalidMangledName()) {

Some files were not shown because too many files have changed in this diff Show More