删除.h文件,上传新程序
This commit is contained in:
parent
38b24072f0
commit
054eeb577a
@ -1,436 +0,0 @@
|
||||
/* ANSI and traditional C compatability macros
|
||||
Copyright (C) 1991-2021 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__ (gnu_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__ (gnu_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
|
||||
|
||||
/* Attribute `alloc_size' was valid as of gcc 4.3. */
|
||||
#ifndef ATTRIBUTE_RESULT_SIZE_1
|
||||
# if (GCC_VERSION >= 4003)
|
||||
# define ATTRIBUTE_RESULT_SIZE_1 __attribute__ ((alloc_size (1)))
|
||||
# else
|
||||
# define ATTRIBUTE_RESULT_SIZE_1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ATTRIBUTE_RESULT_SIZE_2
|
||||
# if (GCC_VERSION >= 4003)
|
||||
# define ATTRIBUTE_RESULT_SIZE_2 __attribute__ ((alloc_size (2)))
|
||||
# else
|
||||
# define ATTRIBUTE_RESULT_SIZE_2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ATTRIBUTE_RESULT_SIZE_1_2
|
||||
# if (GCC_VERSION >= 4003)
|
||||
# define ATTRIBUTE_RESULT_SIZE_1_2 __attribute__ ((alloc_size (1, 2)))
|
||||
# else
|
||||
# define ATTRIBUTE_RESULT_SIZE_1_2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Attribute `warn_unused_result' was valid as of gcc 3.3. */
|
||||
#ifndef ATTRIBUTE_WARN_UNUSED_RESULT
|
||||
# if GCC_VERSION >= 3003
|
||||
# define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
|
||||
# else
|
||||
# define ATTRIBUTE_WARN_UNUSED_RESULT
|
||||
# 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 */
|
7937
include/bfd.h
7937
include/bfd.h
File diff suppressed because it is too large
Load Diff
@ -1,47 +0,0 @@
|
||||
/* generated for gcc.exe (GCC) 10.3.0 */
|
||||
|
||||
#ifndef GCC_GENERATED_STDINT_H
|
||||
#define GCC_GENERATED_STDINT_H 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
/* glibc uses these symbols as guards to prevent redefinitions. */
|
||||
#ifdef __int8_t_defined
|
||||
#define _INT8_T
|
||||
#define _INT16_T
|
||||
#define _INT32_T
|
||||
#endif
|
||||
#ifdef __uint32_t_defined
|
||||
#define _UINT32_T
|
||||
#endif
|
||||
|
||||
|
||||
/* Some systems have guard macros to prevent redefinitions, define them. */
|
||||
#ifndef _INT8_T
|
||||
#define _INT8_T
|
||||
#endif
|
||||
#ifndef _INT16_T
|
||||
#define _INT16_T
|
||||
#endif
|
||||
#ifndef _INT32_T
|
||||
#define _INT32_T
|
||||
#endif
|
||||
#ifndef _UINT8_T
|
||||
#define _UINT8_T
|
||||
#endif
|
||||
#ifndef _UINT16_T
|
||||
#define _UINT16_T
|
||||
#endif
|
||||
#ifndef _UINT32_T
|
||||
#define _UINT32_T
|
||||
#endif
|
||||
|
||||
/* system headers have good uint64_t and int64_t */
|
||||
#ifndef _INT64_T
|
||||
#define _INT64_T
|
||||
#endif
|
||||
#ifndef _UINT64_T
|
||||
#define _UINT64_T
|
||||
#endif
|
||||
|
||||
#endif /* GCC_GENERATED_STDINT_H */
|
1019
include/bfdlink.h
1019
include/bfdlink.h
File diff suppressed because it is too large
Load Diff
@ -1,552 +0,0 @@
|
||||
/* Public API to libctf.
|
||||
Copyright (C) 2019-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libctf.
|
||||
|
||||
libctf 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, 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; see the file COPYING. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This header file defines the interfaces available from the CTF debugger
|
||||
library, libctf. This API can be used by a debugger to operate on data in
|
||||
the Compact ANSI-C Type Format (CTF). */
|
||||
|
||||
#ifndef _CTF_API_H
|
||||
#define _CTF_API_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctf.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Clients can open one or more CTF containers and obtain a pointer to an
|
||||
opaque ctf_dict_t. Types are identified by an opaque ctf_id_t token.
|
||||
They can also open or create read-only archives of CTF containers in a
|
||||
ctf_archive_t.
|
||||
|
||||
These opaque definitions allow libctf to evolve without breaking clients. */
|
||||
|
||||
typedef struct ctf_dict ctf_dict_t;
|
||||
typedef struct ctf_archive_internal ctf_archive_t;
|
||||
typedef unsigned long ctf_id_t;
|
||||
|
||||
/* This opaque definition allows libctf to accept BFD data structures without
|
||||
importing all the BFD noise into users' namespaces. */
|
||||
|
||||
struct bfd;
|
||||
|
||||
/* If the debugger needs to provide the CTF library with a set of raw buffers
|
||||
for use as the CTF data, symbol table, and string table, it can do so by
|
||||
filling in ctf_sect_t structures and passing them to ctf_bufopen.
|
||||
|
||||
The contents of this structure must always be in native endianness. At read
|
||||
time, the symbol table endianness is derived from the BFD target (if BFD is
|
||||
in use): if a BFD target is not in use, please call ctf_symsect_endianness or
|
||||
ctf_arc_symsect_endianness. */
|
||||
|
||||
typedef struct ctf_sect
|
||||
{
|
||||
const char *cts_name; /* Section name (if any). */
|
||||
const void *cts_data; /* Pointer to section data. */
|
||||
size_t cts_size; /* Size of data in bytes. */
|
||||
size_t cts_entsize; /* Size of each section entry (symtab only). */
|
||||
} ctf_sect_t;
|
||||
|
||||
/* A minimal symbol extracted from a linker's internal symbol table
|
||||
representation. The symbol name can be given either via st_name or via a
|
||||
strtab offset in st_nameidx, which corresponds to one of the string offsets
|
||||
communicated via the ctf_link_add_strtab callback. */
|
||||
|
||||
typedef struct ctf_link_sym
|
||||
{
|
||||
/* The st_name and st_nameidx will not be accessed outside the call to
|
||||
ctf_link_shuffle_syms. If you set st_nameidx to offset zero, make sure
|
||||
to set st_nameidx_set as well. */
|
||||
|
||||
const char *st_name;
|
||||
size_t st_nameidx;
|
||||
int st_nameidx_set;
|
||||
uint32_t st_symidx;
|
||||
uint32_t st_shndx;
|
||||
uint32_t st_type;
|
||||
uint32_t st_value;
|
||||
} ctf_link_sym_t;
|
||||
|
||||
/* Flags applying to this specific link. */
|
||||
|
||||
/* Share all types that are not in conflict. The default. */
|
||||
#define CTF_LINK_SHARE_UNCONFLICTED 0x0
|
||||
|
||||
/* Share only types that are used by multiple inputs. */
|
||||
#define CTF_LINK_SHARE_DUPLICATED 0x1
|
||||
|
||||
/* Do a nondeduplicating link. */
|
||||
#define CTF_LINK_NONDEDUP 0x2
|
||||
|
||||
/* Create empty outputs for all registered CU mappings even if no types are
|
||||
emitted into them. */
|
||||
#define CTF_LINK_EMPTY_CU_MAPPINGS 0x4
|
||||
|
||||
/* Omit the content of the variables section. */
|
||||
#define CTF_LINK_OMIT_VARIABLES_SECTION 0x8
|
||||
|
||||
/* Symbolic names for CTF sections. */
|
||||
|
||||
typedef enum ctf_sect_names
|
||||
{
|
||||
CTF_SECT_HEADER,
|
||||
CTF_SECT_LABEL,
|
||||
CTF_SECT_OBJT,
|
||||
CTF_SECT_OBJTIDX = CTF_SECT_OBJT,
|
||||
CTF_SECT_FUNC,
|
||||
CTF_SECT_FUNCIDX = CTF_SECT_FUNC,
|
||||
CTF_SECT_VAR,
|
||||
CTF_SECT_TYPE,
|
||||
CTF_SECT_STR
|
||||
} ctf_sect_names_t;
|
||||
|
||||
/* Encoding information for integers, floating-point values, and certain other
|
||||
intrinsics can be obtained by calling ctf_type_encoding, below. The flags
|
||||
field will contain values appropriate for the type defined in <ctf.h>. */
|
||||
|
||||
typedef struct ctf_encoding
|
||||
{
|
||||
uint32_t cte_format; /* Data format (CTF_INT_* or CTF_FP_* flags). */
|
||||
uint32_t cte_offset; /* Offset of value in bits. */
|
||||
uint32_t cte_bits; /* Size of storage in bits. */
|
||||
} ctf_encoding_t;
|
||||
|
||||
typedef struct ctf_membinfo
|
||||
{
|
||||
ctf_id_t ctm_type; /* Type of struct or union member. */
|
||||
unsigned long ctm_offset; /* Offset of member in bits. */
|
||||
} ctf_membinfo_t;
|
||||
|
||||
typedef struct ctf_arinfo
|
||||
{
|
||||
ctf_id_t ctr_contents; /* Type of array contents. */
|
||||
ctf_id_t ctr_index; /* Type of array index. */
|
||||
uint32_t ctr_nelems; /* Number of elements. */
|
||||
} ctf_arinfo_t;
|
||||
|
||||
typedef struct ctf_funcinfo
|
||||
{
|
||||
ctf_id_t ctc_return; /* Function return type. */
|
||||
uint32_t ctc_argc; /* Number of typed arguments to function. */
|
||||
uint32_t ctc_flags; /* Function attributes (see below). */
|
||||
} ctf_funcinfo_t;
|
||||
|
||||
typedef struct ctf_lblinfo
|
||||
{
|
||||
ctf_id_t ctb_type; /* Last type associated with the label. */
|
||||
} ctf_lblinfo_t;
|
||||
|
||||
typedef struct ctf_snapshot_id
|
||||
{
|
||||
unsigned long dtd_id; /* Highest DTD ID at time of snapshot. */
|
||||
unsigned long snapshot_id; /* Snapshot id at time of snapshot. */
|
||||
} ctf_snapshot_id_t;
|
||||
|
||||
#define CTF_FUNC_VARARG 0x1 /* Function arguments end with varargs. */
|
||||
|
||||
/* Functions that return a ctf_id_t use the following value to indicate failure.
|
||||
ctf_errno can be used to obtain an error code. Functions that return
|
||||
a straight integral -1 also use ctf_errno. */
|
||||
#define CTF_ERR ((ctf_id_t) -1L)
|
||||
|
||||
/* This macro holds information about all the available ctf errors.
|
||||
It is used to form both an enum holding all the error constants,
|
||||
and also the error strings themselves. To use, define _CTF_FIRST
|
||||
and _CTF_ITEM to expand as you like, then mention the macro name.
|
||||
See the enum after this for an example. */
|
||||
#define _CTF_ERRORS \
|
||||
_CTF_FIRST (ECTF_FMT, "File is not in CTF or ELF format.") \
|
||||
_CTF_ITEM (ECTF_BFDERR, "BFD error.") \
|
||||
_CTF_ITEM (ECTF_CTFVERS, "CTF dict version is too new for libctf.") \
|
||||
_CTF_ITEM (ECTF_BFD_AMBIGUOUS, "Ambiguous BFD target.") \
|
||||
_CTF_ITEM (ECTF_SYMTAB, "Symbol table uses invalid entry size.") \
|
||||
_CTF_ITEM (ECTF_SYMBAD, "Symbol table data buffer is not valid.") \
|
||||
_CTF_ITEM (ECTF_STRBAD, "String table data buffer is not valid.") \
|
||||
_CTF_ITEM (ECTF_CORRUPT, "File data structure corruption detected.") \
|
||||
_CTF_ITEM (ECTF_NOCTFDATA, "File does not contain CTF data.") \
|
||||
_CTF_ITEM (ECTF_NOCTFBUF, "Buffer does not contain CTF data.") \
|
||||
_CTF_ITEM (ECTF_NOSYMTAB, "Symbol table information is not available.") \
|
||||
_CTF_ITEM (ECTF_NOPARENT, "The parent CTF dictionary is unavailable.") \
|
||||
_CTF_ITEM (ECTF_DMODEL, "Data model mismatch.") \
|
||||
_CTF_ITEM (ECTF_LINKADDEDLATE, "File added to link too late.") \
|
||||
_CTF_ITEM (ECTF_ZALLOC, "Failed to allocate (de)compression buffer.") \
|
||||
_CTF_ITEM (ECTF_DECOMPRESS, "Failed to decompress CTF data.") \
|
||||
_CTF_ITEM (ECTF_STRTAB, "External string table is not available.") \
|
||||
_CTF_ITEM (ECTF_BADNAME, "String name offset is corrupt.") \
|
||||
_CTF_ITEM (ECTF_BADID, "Invalid type identifier.") \
|
||||
_CTF_ITEM (ECTF_NOTSOU, "Type is not a struct or union.") \
|
||||
_CTF_ITEM (ECTF_NOTENUM, "Type is not an enum.") \
|
||||
_CTF_ITEM (ECTF_NOTSUE, "Type is not a struct, union, or enum.") \
|
||||
_CTF_ITEM (ECTF_NOTINTFP, "Type is not an integer, float, or enum.") \
|
||||
_CTF_ITEM (ECTF_NOTARRAY, "Type is not an array.") \
|
||||
_CTF_ITEM (ECTF_NOTREF, "Type does not reference another type.") \
|
||||
_CTF_ITEM (ECTF_NAMELEN, "Buffer is too small to hold type name.") \
|
||||
_CTF_ITEM (ECTF_NOTYPE, "No type found corresponding to name.") \
|
||||
_CTF_ITEM (ECTF_SYNTAX, "Syntax error in type name.") \
|
||||
_CTF_ITEM (ECTF_NOTFUNC, "Symbol table entry or type is not a function.") \
|
||||
_CTF_ITEM (ECTF_NOFUNCDAT, "No function information available for function.") \
|
||||
_CTF_ITEM (ECTF_NOTDATA, "Symbol table entry does not refer to a data object.") \
|
||||
_CTF_ITEM (ECTF_NOTYPEDAT, "No type information available for symbol.") \
|
||||
_CTF_ITEM (ECTF_NOLABEL, "No label found corresponding to name.") \
|
||||
_CTF_ITEM (ECTF_NOLABELDATA, "File does not contain any labels.") \
|
||||
_CTF_ITEM (ECTF_NOTSUP, "Feature not supported.") \
|
||||
_CTF_ITEM (ECTF_NOENUMNAM, "Enum element name not found.") \
|
||||
_CTF_ITEM (ECTF_NOMEMBNAM, "Member name not found.") \
|
||||
_CTF_ITEM (ECTF_RDONLY, "CTF container is read-only.") \
|
||||
_CTF_ITEM (ECTF_DTFULL, "CTF type is full (no more members allowed).") \
|
||||
_CTF_ITEM (ECTF_FULL, "CTF container is full.") \
|
||||
_CTF_ITEM (ECTF_DUPLICATE, "Duplicate member or variable name.") \
|
||||
_CTF_ITEM (ECTF_CONFLICT, "Conflicting type is already defined.") \
|
||||
_CTF_ITEM (ECTF_OVERROLLBACK, "Attempt to roll back past a ctf_update.") \
|
||||
_CTF_ITEM (ECTF_COMPRESS, "Failed to compress CTF data.") \
|
||||
_CTF_ITEM (ECTF_ARCREATE, "Error creating CTF archive.") \
|
||||
_CTF_ITEM (ECTF_ARNNAME, "Name not found in CTF archive.") \
|
||||
_CTF_ITEM (ECTF_SLICEOVERFLOW, "Overflow of type bitness or offset in slice.") \
|
||||
_CTF_ITEM (ECTF_DUMPSECTUNKNOWN, "Unknown section number in dump.") \
|
||||
_CTF_ITEM (ECTF_DUMPSECTCHANGED, "Section changed in middle of dump.") \
|
||||
_CTF_ITEM (ECTF_NOTYET, "Feature not yet implemented.") \
|
||||
_CTF_ITEM (ECTF_INTERNAL, "Internal error: assertion failure.") \
|
||||
_CTF_ITEM (ECTF_NONREPRESENTABLE, "Type not representable in CTF.") \
|
||||
_CTF_ITEM (ECTF_NEXT_END, "End of iteration.") \
|
||||
_CTF_ITEM (ECTF_NEXT_WRONGFUN, "Wrong iteration function called.") \
|
||||
_CTF_ITEM (ECTF_NEXT_WRONGFP, "Iteration entity changed in mid-iterate.") \
|
||||
_CTF_ITEM (ECTF_FLAGS, "CTF header contains flags unknown to libctf.") \
|
||||
_CTF_ITEM (ECTF_NEEDSBFD, "This feature needs a libctf with BFD support.") \
|
||||
_CTF_ITEM (ECTF_INCOMPLETE, "Type is not a complete type.")
|
||||
|
||||
#define ECTF_BASE 1000 /* Base value for libctf errnos. */
|
||||
|
||||
enum
|
||||
{
|
||||
#define _CTF_FIRST(NAME, STR) NAME = ECTF_BASE
|
||||
#define _CTF_ITEM(NAME, STR) , NAME
|
||||
_CTF_ERRORS
|
||||
#undef _CTF_ITEM
|
||||
#undef _CTF_FIRST
|
||||
};
|
||||
|
||||
#define ECTF_NERR (ECTF_INCOMPLETE - ECTF_BASE + 1) /* Count of CTF errors. */
|
||||
|
||||
/* The CTF data model is inferred to be the caller's data model or the data
|
||||
model of the given object, unless ctf_setmodel is explicitly called. */
|
||||
#define CTF_MODEL_ILP32 1 /* Object data model is ILP32. */
|
||||
#define CTF_MODEL_LP64 2 /* Object data model is LP64. */
|
||||
#ifdef _LP64
|
||||
# define CTF_MODEL_NATIVE CTF_MODEL_LP64
|
||||
#else
|
||||
# define CTF_MODEL_NATIVE CTF_MODEL_ILP32
|
||||
#endif
|
||||
|
||||
/* Dynamic CTF containers can be created using ctf_create. The ctf_add_*
|
||||
routines can be used to add new definitions to the dynamic container.
|
||||
New types are labeled as root or non-root to determine whether they are
|
||||
visible at the top-level program scope when subsequently doing a lookup. */
|
||||
|
||||
#define CTF_ADD_NONROOT 0 /* Type only visible in nested scope. */
|
||||
#define CTF_ADD_ROOT 1 /* Type visible at top-level scope. */
|
||||
|
||||
/* Flags for ctf_member_next. */
|
||||
|
||||
#define CTF_MN_RECURSE 0x1 /* Recurse into unnamed members. */
|
||||
|
||||
/* These typedefs are used to define the signature for callback functions that
|
||||
can be used with the iteration and visit functions below. There is also a
|
||||
family of iteration functions that do not require callbacks. */
|
||||
|
||||
typedef int ctf_visit_f (const char *name, ctf_id_t type, unsigned long offset,
|
||||
int depth, void *arg);
|
||||
typedef int ctf_member_f (const char *name, ctf_id_t membtype,
|
||||
unsigned long offset, void *arg);
|
||||
typedef int ctf_enum_f (const char *name, int val, void *arg);
|
||||
typedef int ctf_variable_f (const char *name, ctf_id_t type, void *arg);
|
||||
typedef int ctf_type_f (ctf_id_t type, void *arg);
|
||||
typedef int ctf_type_all_f (ctf_id_t type, int flag, void *arg);
|
||||
typedef int ctf_label_f (const char *name, const ctf_lblinfo_t *info,
|
||||
void *arg);
|
||||
typedef int ctf_archive_member_f (ctf_dict_t *fp, const char *name, void *arg);
|
||||
typedef int ctf_archive_raw_member_f (const char *name, const void *content,
|
||||
size_t len, void *arg);
|
||||
typedef char *ctf_dump_decorate_f (ctf_sect_names_t sect,
|
||||
char *line, void *arg);
|
||||
|
||||
typedef struct ctf_dump_state ctf_dump_state_t;
|
||||
|
||||
/* Iteration state for the _next functions, and allocators/copiers/freers for
|
||||
it. (None of these are needed for the simple case of iterating to the end:
|
||||
the _next function allocate and free the iterators for you.) */
|
||||
|
||||
typedef struct ctf_next ctf_next_t;
|
||||
extern ctf_next_t *ctf_next_create (void);
|
||||
extern void ctf_next_destroy (ctf_next_t *);
|
||||
extern ctf_next_t *ctf_next_copy (ctf_next_t *);
|
||||
|
||||
/* Opening. These mostly return an abstraction over both CTF files and CTF
|
||||
archives: so they can be used to open both. CTF files will appear to be an
|
||||
archive with one member named '.ctf'. The low-level functions
|
||||
ctf_simple_open and ctf_bufopen return ctf_dict_t's directly, and cannot
|
||||
be used on CTF archives. */
|
||||
|
||||
extern ctf_archive_t *ctf_bfdopen (struct bfd *, int *);
|
||||
extern ctf_archive_t *ctf_bfdopen_ctfsect (struct bfd *, const ctf_sect_t *,
|
||||
int *);
|
||||
extern ctf_archive_t *ctf_fdopen (int fd, const char *filename,
|
||||
const char *target, int *errp);
|
||||
extern ctf_archive_t *ctf_open (const char *filename,
|
||||
const char *target, int *errp);
|
||||
extern void ctf_close (ctf_archive_t *);
|
||||
extern ctf_sect_t ctf_getdatasect (const ctf_dict_t *);
|
||||
extern ctf_sect_t ctf_getsymsect (const ctf_dict_t *);
|
||||
extern ctf_sect_t ctf_getstrsect (const ctf_dict_t *);
|
||||
extern void ctf_symsect_endianness (ctf_dict_t *, int little_endian);
|
||||
extern ctf_archive_t *ctf_get_arc (const ctf_dict_t *);
|
||||
extern ctf_archive_t *ctf_arc_open (const char *, int *);
|
||||
extern ctf_archive_t *ctf_arc_bufopen (const ctf_sect_t *,
|
||||
const ctf_sect_t *,
|
||||
const ctf_sect_t *,
|
||||
int *);
|
||||
extern void ctf_arc_symsect_endianness (ctf_archive_t *, int little_endian);
|
||||
extern void ctf_arc_close (ctf_archive_t *);
|
||||
extern ctf_dict_t *ctf_arc_lookup_symbol (ctf_archive_t *,
|
||||
unsigned long symidx,
|
||||
ctf_id_t *, int *errp);
|
||||
extern void ctf_arc_flush_caches (ctf_archive_t *);
|
||||
extern ctf_dict_t *ctf_dict_open (const ctf_archive_t *,
|
||||
const char *, int *);
|
||||
extern ctf_dict_t *ctf_dict_open_sections (const ctf_archive_t *,
|
||||
const ctf_sect_t *,
|
||||
const ctf_sect_t *,
|
||||
const char *, int *);
|
||||
extern size_t ctf_archive_count (const ctf_archive_t *);
|
||||
|
||||
/* The next functions return or close real CTF files, or write out CTF archives,
|
||||
not opaque containers around either. */
|
||||
|
||||
extern ctf_dict_t *ctf_simple_open (const char *, size_t, const char *, size_t,
|
||||
size_t, const char *, size_t, int *);
|
||||
extern ctf_dict_t *ctf_bufopen (const ctf_sect_t *, const ctf_sect_t *,
|
||||
const ctf_sect_t *, int *);
|
||||
extern void ctf_ref (ctf_dict_t *);
|
||||
extern void ctf_dict_close (ctf_dict_t *);
|
||||
|
||||
extern int ctf_arc_write (const char *, ctf_dict_t **, size_t,
|
||||
const char **, size_t);
|
||||
extern int ctf_arc_write_fd (int, ctf_dict_t **, size_t, const char **,
|
||||
size_t);
|
||||
|
||||
extern const char *ctf_cuname (ctf_dict_t *);
|
||||
extern int ctf_cuname_set (ctf_dict_t *, const char *);
|
||||
extern ctf_dict_t *ctf_parent_dict (ctf_dict_t *);
|
||||
extern const char *ctf_parent_name (ctf_dict_t *);
|
||||
extern int ctf_parent_name_set (ctf_dict_t *, const char *);
|
||||
extern int ctf_type_isparent (ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_type_ischild (ctf_dict_t *, ctf_id_t);
|
||||
|
||||
extern int ctf_import (ctf_dict_t *, ctf_dict_t *);
|
||||
extern int ctf_setmodel (ctf_dict_t *, int);
|
||||
extern int ctf_getmodel (ctf_dict_t *);
|
||||
|
||||
extern void ctf_setspecific (ctf_dict_t *, void *);
|
||||
extern void *ctf_getspecific (ctf_dict_t *);
|
||||
|
||||
extern int ctf_errno (ctf_dict_t *);
|
||||
extern const char *ctf_errmsg (int);
|
||||
extern int ctf_version (int);
|
||||
|
||||
extern int ctf_func_info (ctf_dict_t *, unsigned long, ctf_funcinfo_t *);
|
||||
extern int ctf_func_args (ctf_dict_t *, unsigned long, uint32_t, ctf_id_t *);
|
||||
extern int ctf_func_type_info (ctf_dict_t *, ctf_id_t, ctf_funcinfo_t *);
|
||||
extern int ctf_func_type_args (ctf_dict_t *, ctf_id_t, uint32_t, ctf_id_t *);
|
||||
|
||||
extern ctf_id_t ctf_lookup_by_name (ctf_dict_t *, const char *);
|
||||
extern ctf_id_t ctf_lookup_by_symbol (ctf_dict_t *, unsigned long);
|
||||
extern ctf_id_t ctf_symbol_next (ctf_dict_t *, ctf_next_t **,
|
||||
const char **name, int functions);
|
||||
extern ctf_id_t ctf_lookup_variable (ctf_dict_t *, const char *);
|
||||
|
||||
extern ctf_id_t ctf_type_resolve (ctf_dict_t *, ctf_id_t);
|
||||
extern char *ctf_type_aname (ctf_dict_t *, ctf_id_t);
|
||||
extern char *ctf_type_aname_raw (ctf_dict_t *, ctf_id_t);
|
||||
extern ssize_t ctf_type_lname (ctf_dict_t *, ctf_id_t, char *, size_t);
|
||||
extern char *ctf_type_name (ctf_dict_t *, ctf_id_t, char *, size_t);
|
||||
extern const char *ctf_type_name_raw (ctf_dict_t *, ctf_id_t);
|
||||
extern ssize_t ctf_type_size (ctf_dict_t *, ctf_id_t);
|
||||
extern ssize_t ctf_type_align (ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_type_kind (ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_type_kind_forwarded (ctf_dict_t *, ctf_id_t);
|
||||
extern ctf_id_t ctf_type_reference (ctf_dict_t *, ctf_id_t);
|
||||
extern ctf_id_t ctf_type_pointer (ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_type_encoding (ctf_dict_t *, ctf_id_t, ctf_encoding_t *);
|
||||
extern int ctf_type_visit (ctf_dict_t *, ctf_id_t, ctf_visit_f *, void *);
|
||||
extern int ctf_type_cmp (ctf_dict_t *, ctf_id_t, ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_type_compat (ctf_dict_t *, ctf_id_t, ctf_dict_t *, ctf_id_t);
|
||||
|
||||
extern int ctf_member_info (ctf_dict_t *, ctf_id_t, const char *,
|
||||
ctf_membinfo_t *);
|
||||
extern int ctf_array_info (ctf_dict_t *, ctf_id_t, ctf_arinfo_t *);
|
||||
|
||||
extern const char *ctf_enum_name (ctf_dict_t *, ctf_id_t, int);
|
||||
extern int ctf_enum_value (ctf_dict_t *, ctf_id_t, const char *, int *);
|
||||
|
||||
extern void ctf_label_set (ctf_dict_t *, const char *);
|
||||
extern const char *ctf_label_get (ctf_dict_t *);
|
||||
|
||||
extern const char *ctf_label_topmost (ctf_dict_t *);
|
||||
extern int ctf_label_info (ctf_dict_t *, const char *, ctf_lblinfo_t *);
|
||||
|
||||
extern int ctf_member_count (ctf_dict_t *, ctf_id_t);
|
||||
extern int ctf_member_iter (ctf_dict_t *, ctf_id_t, ctf_member_f *, void *);
|
||||
extern ssize_t ctf_member_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
|
||||
const char **name, ctf_id_t *membtype,
|
||||
int flags);
|
||||
extern int ctf_enum_iter (ctf_dict_t *, ctf_id_t, ctf_enum_f *, void *);
|
||||
extern const char *ctf_enum_next (ctf_dict_t *, ctf_id_t, ctf_next_t **,
|
||||
int *);
|
||||
extern int ctf_type_iter (ctf_dict_t *, ctf_type_f *, void *);
|
||||
extern int ctf_type_iter_all (ctf_dict_t *, ctf_type_all_f *, void *);
|
||||
extern ctf_id_t ctf_type_next (ctf_dict_t *, ctf_next_t **,
|
||||
int *flag, int want_hidden);
|
||||
extern int ctf_label_iter (ctf_dict_t *, ctf_label_f *, void *);
|
||||
extern int ctf_label_next (ctf_dict_t *, ctf_next_t **, const char **); /* TBD */
|
||||
extern int ctf_variable_iter (ctf_dict_t *, ctf_variable_f *, void *);
|
||||
extern ctf_id_t ctf_variable_next (ctf_dict_t *, ctf_next_t **,
|
||||
const char **);
|
||||
extern int ctf_archive_iter (const ctf_archive_t *, ctf_archive_member_f *,
|
||||
void *);
|
||||
extern ctf_dict_t *ctf_archive_next (const ctf_archive_t *, ctf_next_t **,
|
||||
const char **, int skip_parent, int *errp);
|
||||
|
||||
/* This function alone does not currently operate on CTF files masquerading
|
||||
as archives, and returns -EINVAL: the raw data is no longer available. It is
|
||||
expected to be used only by archiving tools, in any case, which have no need
|
||||
to deal with non-archives at all. */
|
||||
extern int ctf_archive_raw_iter (const ctf_archive_t *,
|
||||
ctf_archive_raw_member_f *, void *);
|
||||
extern char *ctf_dump (ctf_dict_t *, ctf_dump_state_t **state,
|
||||
ctf_sect_names_t sect, ctf_dump_decorate_f *,
|
||||
void *arg);
|
||||
|
||||
/* Error-warning reporting: an 'iterator' that returns errors and warnings from
|
||||
the error/warning list, in order of emission. Errors and warnings are popped
|
||||
after return: the caller must free the returned error-text pointer. */
|
||||
extern char *ctf_errwarning_next (ctf_dict_t *, ctf_next_t **,
|
||||
int *is_warning, int *errp);
|
||||
|
||||
extern ctf_id_t ctf_add_array (ctf_dict_t *, uint32_t,
|
||||
const ctf_arinfo_t *);
|
||||
extern ctf_id_t ctf_add_const (ctf_dict_t *, uint32_t, ctf_id_t);
|
||||
extern ctf_id_t ctf_add_enum_encoded (ctf_dict_t *, uint32_t, const char *,
|
||||
const ctf_encoding_t *);
|
||||
extern ctf_id_t ctf_add_enum (ctf_dict_t *, uint32_t, const char *);
|
||||
extern ctf_id_t ctf_add_float (ctf_dict_t *, uint32_t,
|
||||
const char *, const ctf_encoding_t *);
|
||||
extern ctf_id_t ctf_add_forward (ctf_dict_t *, uint32_t, const char *,
|
||||
uint32_t);
|
||||
extern ctf_id_t ctf_add_function (ctf_dict_t *, uint32_t,
|
||||
const ctf_funcinfo_t *, const ctf_id_t *);
|
||||
extern ctf_id_t ctf_add_integer (ctf_dict_t *, uint32_t, const char *,
|
||||
const ctf_encoding_t *);
|
||||
extern ctf_id_t ctf_add_slice (ctf_dict_t *, uint32_t, ctf_id_t, const ctf_encoding_t *);
|
||||
extern ctf_id_t ctf_add_pointer (ctf_dict_t *, uint32_t, ctf_id_t);
|
||||
extern ctf_id_t ctf_add_type (ctf_dict_t *, ctf_dict_t *, ctf_id_t);
|
||||
extern ctf_id_t ctf_add_typedef (ctf_dict_t *, uint32_t, const char *,
|
||||
ctf_id_t);
|
||||
extern ctf_id_t ctf_add_restrict (ctf_dict_t *, uint32_t, ctf_id_t);
|
||||
extern ctf_id_t ctf_add_struct (ctf_dict_t *, uint32_t, const char *);
|
||||
extern ctf_id_t ctf_add_union (ctf_dict_t *, uint32_t, const char *);
|
||||
extern ctf_id_t ctf_add_struct_sized (ctf_dict_t *, uint32_t, const char *,
|
||||
size_t);
|
||||
extern ctf_id_t ctf_add_union_sized (ctf_dict_t *, uint32_t, const char *,
|
||||
size_t);
|
||||
extern ctf_id_t ctf_add_volatile (ctf_dict_t *, uint32_t, ctf_id_t);
|
||||
|
||||
extern int ctf_add_enumerator (ctf_dict_t *, ctf_id_t, const char *, int);
|
||||
extern int ctf_add_member (ctf_dict_t *, ctf_id_t, const char *, ctf_id_t);
|
||||
extern int ctf_add_member_offset (ctf_dict_t *, ctf_id_t, const char *,
|
||||
ctf_id_t, unsigned long);
|
||||
extern int ctf_add_member_encoded (ctf_dict_t *, ctf_id_t, const char *,
|
||||
ctf_id_t, unsigned long,
|
||||
const ctf_encoding_t);
|
||||
|
||||
extern int ctf_add_variable (ctf_dict_t *, const char *, ctf_id_t);
|
||||
|
||||
extern int ctf_add_objt_sym (ctf_dict_t *, const char *, ctf_id_t);
|
||||
extern int ctf_add_func_sym (ctf_dict_t *, const char *, ctf_id_t);
|
||||
|
||||
extern int ctf_set_array (ctf_dict_t *, ctf_id_t, const ctf_arinfo_t *);
|
||||
|
||||
extern ctf_dict_t *ctf_create (int *);
|
||||
extern int ctf_update (ctf_dict_t *);
|
||||
extern ctf_snapshot_id_t ctf_snapshot (ctf_dict_t *);
|
||||
extern int ctf_rollback (ctf_dict_t *, ctf_snapshot_id_t);
|
||||
extern int ctf_discard (ctf_dict_t *);
|
||||
extern int ctf_write (ctf_dict_t *, int);
|
||||
extern int ctf_gzwrite (ctf_dict_t *fp, gzFile fd);
|
||||
extern int ctf_compress_write (ctf_dict_t * fp, int fd);
|
||||
extern unsigned char *ctf_write_mem (ctf_dict_t *, size_t *, size_t threshold);
|
||||
|
||||
extern int ctf_link_add_ctf (ctf_dict_t *, ctf_archive_t *, const char *);
|
||||
/* The variable filter should return nonzero if a variable should not
|
||||
appear in the output. */
|
||||
typedef int ctf_link_variable_filter_f (ctf_dict_t *, const char *, ctf_id_t,
|
||||
void *);
|
||||
extern int ctf_link_set_variable_filter (ctf_dict_t *,
|
||||
ctf_link_variable_filter_f *, void *);
|
||||
extern int ctf_link (ctf_dict_t *, int flags);
|
||||
typedef const char *ctf_link_strtab_string_f (uint32_t *offset, void *arg);
|
||||
extern int ctf_link_add_strtab (ctf_dict_t *, ctf_link_strtab_string_f *,
|
||||
void *);
|
||||
extern int ctf_link_add_linker_symbol (ctf_dict_t *, ctf_link_sym_t *);
|
||||
extern int ctf_link_shuffle_syms (ctf_dict_t *);
|
||||
extern unsigned char *ctf_link_write (ctf_dict_t *, size_t *size,
|
||||
size_t threshold);
|
||||
|
||||
/* Specialist linker functions. These functions are not used by ld, but can be
|
||||
used by other programs making use of the linker machinery for other purposes
|
||||
to customize its output. */
|
||||
extern int ctf_link_add_cu_mapping (ctf_dict_t *, const char *from,
|
||||
const char *to);
|
||||
typedef char *ctf_link_memb_name_changer_f (ctf_dict_t *,
|
||||
const char *, void *);
|
||||
extern void ctf_link_set_memb_name_changer
|
||||
(ctf_dict_t *, ctf_link_memb_name_changer_f *, void *);
|
||||
|
||||
extern void ctf_setdebug (int debug);
|
||||
extern int ctf_getdebug (void);
|
||||
|
||||
/* Deprecated aliases for existing functions and types. */
|
||||
|
||||
struct ctf_file;
|
||||
typedef struct ctf_dict ctf_file_t;
|
||||
extern void ctf_file_close (ctf_file_t *);
|
||||
extern ctf_dict_t *ctf_parent_file (ctf_dict_t *);
|
||||
extern ctf_dict_t *ctf_arc_open_by_name (const ctf_archive_t *,
|
||||
const char *, int *);
|
||||
extern ctf_dict_t *ctf_arc_open_by_name_sections (const ctf_archive_t *,
|
||||
const ctf_sect_t *,
|
||||
const ctf_sect_t *,
|
||||
const char *, int *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CTF_API_H */
|
620
include/ctf.h
620
include/ctf.h
@ -1,620 +0,0 @@
|
||||
/* CTF format description.
|
||||
Copyright (C) 2019-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of libctf.
|
||||
|
||||
libctf 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, 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; see the file COPYING. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _CTF_H
|
||||
#define _CTF_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* CTF - Compact ANSI-C Type Format
|
||||
|
||||
This file format can be used to compactly represent the information needed
|
||||
by a debugger to interpret the ANSI-C types used by a given program.
|
||||
Traditionally, this kind of information is generated by the compiler when
|
||||
invoked with the -g flag and is stored in "stabs" strings or in the more
|
||||
modern DWARF format. CTF provides a representation of only the information
|
||||
that is relevant to debugging a complex, optimized C program such as the
|
||||
operating system kernel in a form that is significantly more compact than
|
||||
the equivalent stabs or DWARF representation. The format is data-model
|
||||
independent, so consumers do not need different code depending on whether
|
||||
they are 32-bit or 64-bit programs; libctf automatically compensates for
|
||||
endianness variations. CTF assumes that a standard ELF symbol table is
|
||||
available for use in the debugger, and uses the structure and data of the
|
||||
symbol table to avoid storing redundant information. The CTF data may be
|
||||
compressed on disk or in memory, indicated by a bit in the header. CTF may
|
||||
be interpreted in a raw disk file, or it may be stored in an ELF section,
|
||||
typically named .ctf. Data structures are aligned so that a raw CTF file or
|
||||
CTF ELF section may be manipulated using mmap(2).
|
||||
|
||||
The CTF file or section itself has the following structure:
|
||||
|
||||
+--------+--------+---------+----------+--------+----------+...
|
||||
| file | type | data | function | object | function |...
|
||||
| header | labels | objects | info | index | index |...
|
||||
+--------+--------+---------+----------+--------+----------+...
|
||||
|
||||
...+----------+-------+--------+
|
||||
...| variable | data | string |
|
||||
...| info | types | table |
|
||||
+----------+-------+--------+
|
||||
|
||||
The file header stores a magic number and version information, encoding
|
||||
flags, and the byte offset of each of the sections relative to the end of the
|
||||
header itself. If the CTF data has been uniquified against another set of
|
||||
CTF data, a reference to that data also appears in the the header. This
|
||||
reference is the name of the label corresponding to the types uniquified
|
||||
against.
|
||||
|
||||
Following the header is a list of labels, used to group the types included in
|
||||
the data types section. Each label is accompanied by a type ID i. A given
|
||||
label refers to the group of types whose IDs are in the range [0, i].
|
||||
|
||||
Data object and function records (collectively, "symtypetabs") are stored in
|
||||
the same order as they appear in the corresponding symbol table, except that
|
||||
symbols marked SHN_UNDEF are not stored and symbols that have no type data
|
||||
are padded out with zeroes. For each entry in these tables, the type ID (a
|
||||
small integer) is recorded. (Functions get CTF_K_FUNCTION types, just like
|
||||
data objects that are function pointers.)
|
||||
|
||||
For situations in which the order of the symbols in the symtab is not known,
|
||||
or most symbols have no type in this dict and most entries would be
|
||||
zero-pads, a pair of optional indexes follow the data object and function
|
||||
info sections: each of these is an array of strtab indexes, mapped 1:1 to the
|
||||
corresponding data object / function info section, giving each entry in those
|
||||
sections a name so that the linker can correlate them with final symtab
|
||||
entries and reorder them accordingly (dropping the indexes in the process).
|
||||
|
||||
Variable records (as distinct from data objects) provide a modicum of support
|
||||
for non-ELF systems, mapping a variable name to a CTF type ID. The variable
|
||||
names are sorted into ASCIIbetical order, permitting binary searching. We do
|
||||
not define how the consumer maps these variable names to addresses or
|
||||
anything else, or indeed what these names represent: they might be names
|
||||
looked up at runtime via dlsym() or names extracted at runtime by a debugger
|
||||
or anything else the consumer likes. Variable records with identically-
|
||||
named entries in the data object section are removed.
|
||||
|
||||
The data types section is a list of variable size records that represent each
|
||||
type, in order by their ID. The types themselves form a directed graph,
|
||||
where each node may contain one or more outgoing edges to other type nodes,
|
||||
denoted by their ID. Most type nodes are standalone or point backwards to
|
||||
earlier nodes, but this is not required: nodes can point to later nodes,
|
||||
particularly structure and union members.
|
||||
|
||||
Strings are recorded as a string table ID (0 or 1) and a byte offset into the
|
||||
string table. String table 0 is the internal CTF string table. String table
|
||||
1 is the external string table, which is the string table associated with the
|
||||
ELF dynamic symbol table for this object. CTF does not record any strings
|
||||
that are already in the symbol table, and the CTF string table does not
|
||||
contain any duplicated strings.
|
||||
|
||||
If the CTF data has been merged with another parent CTF object, some outgoing
|
||||
edges may refer to type nodes that exist in another CTF object. The debugger
|
||||
and libctf library are responsible for connecting the appropriate objects
|
||||
together so that the full set of types can be explored and manipulated.
|
||||
|
||||
This connection is done purely using the ctf_import() function. The
|
||||
ctf_archive machinery (and thus ctf_open et al) automatically imports archive
|
||||
members named ".ctf" into child dicts if available in the same archive, to
|
||||
match the relationship set up by the linker, but callers can call ctf_import
|
||||
themselves as well if need be, if they know a different relationship is in
|
||||
force. */
|
||||
|
||||
#define CTF_MAX_TYPE 0xfffffffe /* Max type identifier value. */
|
||||
#define CTF_MAX_PTYPE 0x7fffffff /* Max parent type identifier value. */
|
||||
#define CTF_MAX_NAME 0x7fffffff /* Max offset into a string table. */
|
||||
#define CTF_MAX_VLEN 0xffffff /* Max struct, union, enum members or args. */
|
||||
|
||||
/* See ctf_type_t */
|
||||
#define CTF_MAX_SIZE 0xfffffffe /* Max size of a v2 type in bytes. */
|
||||
#define CTF_LSIZE_SENT 0xffffffff /* Sentinel for v2 ctt_size. */
|
||||
|
||||
# define CTF_MAX_TYPE_V1 0xffff /* Max type identifier value. */
|
||||
# define CTF_MAX_PTYPE_V1 0x7fff /* Max parent type identifier value. */
|
||||
# define CTF_MAX_VLEN_V1 0x3ff /* Max struct, union, enums or args. */
|
||||
# define CTF_MAX_SIZE_V1 0xfffe /* Max size of a type in bytes. */
|
||||
# define CTF_LSIZE_SENT_V1 0xffff /* Sentinel for v1 ctt_size. */
|
||||
|
||||
/* Start of actual data structure definitions.
|
||||
|
||||
Every field in these structures must have corresponding code in the
|
||||
endianness-swapping machinery in libctf/ctf-open.c. */
|
||||
|
||||
typedef struct ctf_preamble
|
||||
{
|
||||
unsigned short ctp_magic; /* Magic number (CTF_MAGIC). */
|
||||
unsigned char ctp_version; /* Data format version number (CTF_VERSION). */
|
||||
unsigned char ctp_flags; /* Flags (see below). */
|
||||
} ctf_preamble_t;
|
||||
|
||||
typedef struct ctf_header_v2
|
||||
{
|
||||
ctf_preamble_t cth_preamble;
|
||||
uint32_t cth_parlabel; /* Ref to name of parent lbl uniq'd against. */
|
||||
uint32_t cth_parname; /* Ref to basename of parent. */
|
||||
uint32_t cth_lbloff; /* Offset of label section. */
|
||||
uint32_t cth_objtoff; /* Offset of object section. */
|
||||
uint32_t cth_funcoff; /* Offset of function section. */
|
||||
uint32_t cth_varoff; /* Offset of variable section. */
|
||||
uint32_t cth_typeoff; /* Offset of type section. */
|
||||
uint32_t cth_stroff; /* Offset of string section. */
|
||||
uint32_t cth_strlen; /* Length of string section in bytes. */
|
||||
} ctf_header_v2_t;
|
||||
|
||||
typedef struct ctf_header
|
||||
{
|
||||
ctf_preamble_t cth_preamble;
|
||||
uint32_t cth_parlabel; /* Ref to name of parent lbl uniq'd against. */
|
||||
uint32_t cth_parname; /* Ref to basename of parent. */
|
||||
uint32_t cth_cuname; /* Ref to CU name (may be 0). */
|
||||
uint32_t cth_lbloff; /* Offset of label section. */
|
||||
uint32_t cth_objtoff; /* Offset of object section. */
|
||||
uint32_t cth_funcoff; /* Offset of function section. */
|
||||
uint32_t cth_objtidxoff; /* Offset of object index section. */
|
||||
uint32_t cth_funcidxoff; /* Offset of function index section. */
|
||||
uint32_t cth_varoff; /* Offset of variable section. */
|
||||
uint32_t cth_typeoff; /* Offset of type section. */
|
||||
uint32_t cth_stroff; /* Offset of string section. */
|
||||
uint32_t cth_strlen; /* Length of string section in bytes. */
|
||||
} ctf_header_t;
|
||||
|
||||
#define cth_magic cth_preamble.ctp_magic
|
||||
#define cth_version cth_preamble.ctp_version
|
||||
#define cth_flags cth_preamble.ctp_flags
|
||||
|
||||
#define CTF_MAGIC 0xdff2 /* Magic number identifying header. */
|
||||
|
||||
/* Data format version number. */
|
||||
|
||||
/* v1 upgraded to a later version is not quite the same as the native form,
|
||||
because the boundary between parent and child types is different but not
|
||||
recorded anywhere, and you can write it out again via ctf_compress_write(),
|
||||
so we must track whether the thing was originally v1 or not. If we were
|
||||
writing the header from scratch, we would add a *pair* of version number
|
||||
fields to allow for this, but this will do for now. (A flag will not do,
|
||||
because we need to encode both the version we came from and the version we
|
||||
went to, not just "we were upgraded".) */
|
||||
|
||||
# define CTF_VERSION_1 1
|
||||
# define CTF_VERSION_1_UPGRADED_3 2
|
||||
# define CTF_VERSION_2 3
|
||||
|
||||
#define CTF_VERSION_3 4
|
||||
#define CTF_VERSION CTF_VERSION_3 /* Current version. */
|
||||
|
||||
/* All of these flags bar CTF_F_COMPRESS and CTF_F_IDXSORTED are bug-workaround
|
||||
flags and are valid only in format v3: in v2 and below they cannot occur and
|
||||
in v4 and later, they will be recycled for other purposes. */
|
||||
|
||||
#define CTF_F_COMPRESS 0x1 /* Data buffer is compressed by libctf. */
|
||||
#define CTF_F_NEWFUNCINFO 0x2 /* New v3 func info section format. */
|
||||
#define CTF_F_IDXSORTED 0x4 /* Index sections already sorted. */
|
||||
#define CTF_F_DYNSTR 0x8 /* Strings come from .dynstr. */
|
||||
#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO | CTF_F_IDXSORTED \
|
||||
| CTF_F_DYNSTR)
|
||||
|
||||
typedef struct ctf_lblent
|
||||
{
|
||||
uint32_t ctl_label; /* Ref to name of label. */
|
||||
uint32_t ctl_type; /* Last type associated with this label. */
|
||||
} ctf_lblent_t;
|
||||
|
||||
typedef struct ctf_varent
|
||||
{
|
||||
uint32_t ctv_name; /* Reference to name in string table. */
|
||||
uint32_t ctv_type; /* Index of type of this variable. */
|
||||
} ctf_varent_t;
|
||||
|
||||
/* In format v2, type sizes, measured in bytes, come in two flavours. Nearly
|
||||
all of them fit into a (UINT_MAX - 1), and thus can be stored in the ctt_size
|
||||
member of a ctf_stype_t. The maximum value for these sizes is CTF_MAX_SIZE.
|
||||
Types larger than this must be stored in the ctf_lsize member of a
|
||||
ctf_type_t. Use of this member is indicated by the presence of
|
||||
CTF_LSIZE_SENT in ctt_size. */
|
||||
|
||||
/* In v1, the same applies, only the limit is (USHRT_MAX - 1) and
|
||||
CTF_MAX_SIZE_V1, and CTF_LSIZE_SENT_V1 is the sentinel. */
|
||||
|
||||
typedef struct ctf_stype_v1
|
||||
{
|
||||
uint32_t ctt_name; /* Reference to name in string table. */
|
||||
unsigned short ctt_info; /* Encoded kind, variant length (see below). */
|
||||
#ifndef __GNUC__
|
||||
union
|
||||
{
|
||||
unsigned short _size; /* Size of entire type in bytes. */
|
||||
unsigned short _type; /* Reference to another type. */
|
||||
} _u;
|
||||
#else
|
||||
__extension__
|
||||
union
|
||||
{
|
||||
unsigned short ctt_size; /* Size of entire type in bytes. */
|
||||
unsigned short ctt_type; /* Reference to another type. */
|
||||
};
|
||||
#endif
|
||||
} ctf_stype_v1_t;
|
||||
|
||||
typedef struct ctf_type_v1
|
||||
{
|
||||
uint32_t ctt_name; /* Reference to name in string table. */
|
||||
unsigned short ctt_info; /* Encoded kind, variant length (see below). */
|
||||
#ifndef __GNUC__
|
||||
union
|
||||
{
|
||||
unsigned short _size; /* Always CTF_LSIZE_SENT_V1. */
|
||||
unsigned short _type; /* Do not use. */
|
||||
} _u;
|
||||
#else
|
||||
__extension__
|
||||
union
|
||||
{
|
||||
unsigned short ctt_size; /* Always CTF_LSIZE_SENT_V1. */
|
||||
unsigned short ctt_type; /* Do not use. */
|
||||
};
|
||||
#endif
|
||||
uint32_t ctt_lsizehi; /* High 32 bits of type size in bytes. */
|
||||
uint32_t ctt_lsizelo; /* Low 32 bits of type size in bytes. */
|
||||
} ctf_type_v1_t;
|
||||
|
||||
|
||||
typedef struct ctf_stype
|
||||
{
|
||||
uint32_t ctt_name; /* Reference to name in string table. */
|
||||
uint32_t ctt_info; /* Encoded kind, variant length (see below). */
|
||||
#ifndef __GNUC__
|
||||
union
|
||||
{
|
||||
uint32_t _size; /* Size of entire type in bytes. */
|
||||
uint32_t _type; /* Reference to another type. */
|
||||
} _u;
|
||||
#else
|
||||
__extension__
|
||||
union
|
||||
{
|
||||
uint32_t ctt_size; /* Size of entire type in bytes. */
|
||||
uint32_t ctt_type; /* Reference to another type. */
|
||||
};
|
||||
#endif
|
||||
} ctf_stype_t;
|
||||
|
||||
typedef struct ctf_type
|
||||
{
|
||||
uint32_t ctt_name; /* Reference to name in string table. */
|
||||
uint32_t ctt_info; /* Encoded kind, variant length (see below). */
|
||||
#ifndef __GNUC__
|
||||
union
|
||||
{
|
||||
uint32_t _size; /* Always CTF_LSIZE_SENT. */
|
||||
uint32_t _type; /* Do not use. */
|
||||
} _u;
|
||||
#else
|
||||
__extension__
|
||||
union
|
||||
{
|
||||
uint32_t ctt_size; /* Always CTF_LSIZE_SENT. */
|
||||
uint32_t ctt_type; /* Do not use. */
|
||||
};
|
||||
#endif
|
||||
uint32_t ctt_lsizehi; /* High 32 bits of type size in bytes. */
|
||||
uint32_t ctt_lsizelo; /* Low 32 bits of type size in bytes. */
|
||||
} ctf_type_t;
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define ctt_size _u._size /* For fundamental types that have a size. */
|
||||
#define ctt_type _u._type /* For types that reference another type. */
|
||||
#endif
|
||||
|
||||
/* The following macros and inline functions compose and decompose values for
|
||||
ctt_info and ctt_name, as well as other structures that contain name
|
||||
references. Use outside libdtrace-ctf itself is explicitly for access to CTF
|
||||
files directly: types returned from the library will always appear to be
|
||||
CTF_V2.
|
||||
|
||||
v1: (transparently upgraded to v2 at open time: may be compiled out of the
|
||||
library)
|
||||
------------------------
|
||||
ctt_info: | kind | isroot | vlen |
|
||||
------------------------
|
||||
15 11 10 9 0
|
||||
|
||||
v2:
|
||||
------------------------
|
||||
ctt_info: | kind | isroot | vlen |
|
||||
------------------------
|
||||
31 26 25 24 0
|
||||
|
||||
CTF_V1 and V2 _INFO_VLEN have the same interface:
|
||||
|
||||
kind = CTF_*_INFO_KIND(c.ctt_info); <-- CTF_K_* value (see below)
|
||||
vlen = CTF_*_INFO_VLEN(fp, c.ctt_info); <-- length of variable data list
|
||||
|
||||
stid = CTF_NAME_STID(c.ctt_name); <-- string table id number (0 or 1)
|
||||
offset = CTF_NAME_OFFSET(c.ctt_name); <-- string table byte offset
|
||||
|
||||
c.ctt_info = CTF_TYPE_INFO(kind, vlen);
|
||||
c.ctt_name = CTF_TYPE_NAME(stid, offset); */
|
||||
|
||||
# define CTF_V1_INFO_KIND(info) (((info) & 0xf800) >> 11)
|
||||
# define CTF_V1_INFO_ISROOT(info) (((info) & 0x0400) >> 10)
|
||||
# define CTF_V1_INFO_VLEN(info) (((info) & CTF_MAX_VLEN_V1))
|
||||
|
||||
#define CTF_V2_INFO_KIND(info) (((info) & 0xfc000000) >> 26)
|
||||
#define CTF_V2_INFO_ISROOT(info) (((info) & 0x2000000) >> 25)
|
||||
#define CTF_V2_INFO_VLEN(info) (((info) & CTF_MAX_VLEN))
|
||||
|
||||
#define CTF_NAME_STID(name) ((name) >> 31)
|
||||
#define CTF_NAME_OFFSET(name) ((name) & CTF_MAX_NAME)
|
||||
#define CTF_SET_STID(name, stid) ((name) | (stid) << 31)
|
||||
|
||||
/* V2 only. */
|
||||
#define CTF_TYPE_INFO(kind, isroot, vlen) \
|
||||
(((kind) << 26) | (((isroot) ? 1 : 0) << 25) | ((vlen) & CTF_MAX_VLEN))
|
||||
|
||||
#define CTF_TYPE_NAME(stid, offset) \
|
||||
(((stid) << 31) | ((offset) & CTF_MAX_NAME))
|
||||
|
||||
/* The next set of macros are for public consumption only. Not used internally,
|
||||
since the relevant type boundary is dependent upon the version of the file at
|
||||
*opening* time, not the version after transparent upgrade. Use
|
||||
ctf_type_isparent() / ctf_type_ischild() for that. */
|
||||
|
||||
#define CTF_V2_TYPE_ISPARENT(fp, id) ((id) <= CTF_MAX_PTYPE)
|
||||
#define CTF_V2_TYPE_ISCHILD(fp, id) ((id) > CTF_MAX_PTYPE)
|
||||
#define CTF_V2_TYPE_TO_INDEX(id) ((id) & CTF_MAX_PTYPE)
|
||||
#define CTF_V2_INDEX_TO_TYPE(id, child) ((child) ? ((id) | (CTF_MAX_PTYPE+1)) : (id))
|
||||
|
||||
# define CTF_V1_TYPE_ISPARENT(fp, id) ((id) <= CTF_MAX_PTYPE_V1)
|
||||
# define CTF_V1_TYPE_ISCHILD(fp, id) ((id) > CTF_MAX_PTYPE_V1)
|
||||
# define CTF_V1_TYPE_TO_INDEX(id) ((id) & CTF_MAX_PTYPE_V1)
|
||||
# define CTF_V1_INDEX_TO_TYPE(id, child) ((child) ? ((id) | (CTF_MAX_PTYPE_V1+1)) : (id))
|
||||
|
||||
/* Valid for both V1 and V2. */
|
||||
#define CTF_TYPE_LSIZE(cttp) \
|
||||
(((uint64_t)(cttp)->ctt_lsizehi) << 32 | (cttp)->ctt_lsizelo)
|
||||
#define CTF_SIZE_TO_LSIZE_HI(size) ((uint32_t)((uint64_t)(size) >> 32))
|
||||
#define CTF_SIZE_TO_LSIZE_LO(size) ((uint32_t)(size))
|
||||
|
||||
#define CTF_STRTAB_0 0 /* String table id 0 (in-CTF). */
|
||||
#define CTF_STRTAB_1 1 /* String table id 1 (ELF strtab). */
|
||||
|
||||
/* Values for CTF_TYPE_KIND(). If the kind has an associated data list,
|
||||
CTF_INFO_VLEN() will extract the number of elements in the list, and
|
||||
the type of each element is shown in the comments below. */
|
||||
|
||||
#define CTF_K_UNKNOWN 0 /* Unknown type (used for padding). */
|
||||
#define CTF_K_INTEGER 1 /* Variant data is CTF_INT_DATA (see below). */
|
||||
#define CTF_K_FLOAT 2 /* Variant data is CTF_FP_DATA (see below). */
|
||||
#define CTF_K_POINTER 3 /* ctt_type is referenced type. */
|
||||
#define CTF_K_ARRAY 4 /* Variant data is single ctf_array_t. */
|
||||
#define CTF_K_FUNCTION 5 /* ctt_type is return type, variant data is
|
||||
list of argument types (unsigned short's for v1,
|
||||
uint32_t's for v2). */
|
||||
#define CTF_K_STRUCT 6 /* Variant data is list of ctf_member_t's. */
|
||||
#define CTF_K_UNION 7 /* Variant data is list of ctf_member_t's. */
|
||||
#define CTF_K_ENUM 8 /* Variant data is list of ctf_enum_t's. */
|
||||
#define CTF_K_FORWARD 9 /* No additional data; ctt_name is tag. */
|
||||
#define CTF_K_TYPEDEF 10 /* ctt_type is referenced type. */
|
||||
#define CTF_K_VOLATILE 11 /* ctt_type is base type. */
|
||||
#define CTF_K_CONST 12 /* ctt_type is base type. */
|
||||
#define CTF_K_RESTRICT 13 /* ctt_type is base type. */
|
||||
#define CTF_K_SLICE 14 /* Variant data is a ctf_slice_t. */
|
||||
|
||||
#define CTF_K_MAX 63 /* Maximum possible (V2) CTF_K_* value. */
|
||||
|
||||
/* Values for ctt_type when kind is CTF_K_INTEGER. The flags, offset in bits,
|
||||
and size in bits are encoded as a single word using the following macros.
|
||||
(However, you can also encode the offset and bitness in a slice.) */
|
||||
|
||||
#define CTF_INT_ENCODING(data) (((data) & 0xff000000) >> 24)
|
||||
#define CTF_INT_OFFSET(data) (((data) & 0x00ff0000) >> 16)
|
||||
#define CTF_INT_BITS(data) (((data) & 0x0000ffff))
|
||||
|
||||
#define CTF_INT_DATA(encoding, offset, bits) \
|
||||
(((encoding) << 24) | ((offset) << 16) | (bits))
|
||||
|
||||
#define CTF_INT_SIGNED 0x01 /* Integer is signed (otherwise unsigned). */
|
||||
#define CTF_INT_CHAR 0x02 /* Character display format. */
|
||||
#define CTF_INT_BOOL 0x04 /* Boolean display format. */
|
||||
#define CTF_INT_VARARGS 0x08 /* Varargs display format. */
|
||||
|
||||
/* Use CTF_CHAR to produce a char that agrees with the system's native
|
||||
char signedness. */
|
||||
#if CHAR_MIN == 0
|
||||
# define CTF_CHAR (CTF_INT_CHAR)
|
||||
#else
|
||||
# define CTF_CHAR (CTF_INT_CHAR | CTF_INT_SIGNED)
|
||||
#endif
|
||||
|
||||
/* Values for ctt_type when kind is CTF_K_FLOAT. The encoding, offset in bits,
|
||||
and size in bits are encoded as a single word using the following macros.
|
||||
(However, you can also encode the offset and bitness in a slice.) */
|
||||
|
||||
#define CTF_FP_ENCODING(data) (((data) & 0xff000000) >> 24)
|
||||
#define CTF_FP_OFFSET(data) (((data) & 0x00ff0000) >> 16)
|
||||
#define CTF_FP_BITS(data) (((data) & 0x0000ffff))
|
||||
|
||||
#define CTF_FP_DATA(encoding, offset, bits) \
|
||||
(((encoding) << 24) | ((offset) << 16) | (bits))
|
||||
|
||||
/* Variant data when kind is CTF_K_FLOAT is an encoding in the top eight bits. */
|
||||
#define CTF_FP_ENCODING(data) (((data) & 0xff000000) >> 24)
|
||||
|
||||
#define CTF_FP_SINGLE 1 /* IEEE 32-bit float encoding. */
|
||||
#define CTF_FP_DOUBLE 2 /* IEEE 64-bit float encoding. */
|
||||
#define CTF_FP_CPLX 3 /* Complex encoding. */
|
||||
#define CTF_FP_DCPLX 4 /* Double complex encoding. */
|
||||
#define CTF_FP_LDCPLX 5 /* Long double complex encoding. */
|
||||
#define CTF_FP_LDOUBLE 6 /* Long double encoding. */
|
||||
#define CTF_FP_INTRVL 7 /* Interval (2x32-bit) encoding. */
|
||||
#define CTF_FP_DINTRVL 8 /* Double interval (2x64-bit) encoding. */
|
||||
#define CTF_FP_LDINTRVL 9 /* Long double interval (2x128-bit) encoding. */
|
||||
#define CTF_FP_IMAGRY 10 /* Imaginary (32-bit) encoding. */
|
||||
#define CTF_FP_DIMAGRY 11 /* Long imaginary (64-bit) encoding. */
|
||||
#define CTF_FP_LDIMAGRY 12 /* Long double imaginary (128-bit) encoding. */
|
||||
|
||||
#define CTF_FP_MAX 12 /* Maximum possible CTF_FP_* value */
|
||||
|
||||
/* A slice increases the offset and reduces the bitness of the referenced
|
||||
ctt_type, which must be a type which has an encoding (fp, int, or enum). We
|
||||
also store the referenced type in here, because it is easier to keep the
|
||||
ctt_size correct for the slice than to shuffle the size into here and keep
|
||||
the ctt_type where it is for other types.
|
||||
|
||||
In a future version, where we loosen requirements on alignment in the CTF
|
||||
file, the cts_offset and cts_bits will be chars: but for now they must be
|
||||
shorts or everything after a slice will become unaligned. */
|
||||
|
||||
typedef struct ctf_slice
|
||||
{
|
||||
uint32_t cts_type;
|
||||
unsigned short cts_offset;
|
||||
unsigned short cts_bits;
|
||||
} ctf_slice_t;
|
||||
|
||||
typedef struct ctf_array_v1
|
||||
{
|
||||
unsigned short cta_contents; /* Reference to type of array contents. */
|
||||
unsigned short cta_index; /* Reference to type of array index. */
|
||||
uint32_t cta_nelems; /* Number of elements. */
|
||||
} ctf_array_v1_t;
|
||||
|
||||
typedef struct ctf_array
|
||||
{
|
||||
uint32_t cta_contents; /* Reference to type of array contents. */
|
||||
uint32_t cta_index; /* Reference to type of array index. */
|
||||
uint32_t cta_nelems; /* Number of elements. */
|
||||
} ctf_array_t;
|
||||
|
||||
/* Most structure members have bit offsets that can be expressed using a short.
|
||||
Some don't. ctf_member_t is used for structs which cannot contain any of
|
||||
these large offsets, whereas ctf_lmember_t is used in the latter case. If
|
||||
any member of a given struct has an offset that cannot be expressed using a
|
||||
uint32_t, all members will be stored as type ctf_lmember_t. This is expected
|
||||
to be very rare (but nonetheless possible). */
|
||||
|
||||
#define CTF_LSTRUCT_THRESH 536870912
|
||||
|
||||
/* In v1, the same is true, except that lmembers are used for structs >= 8192
|
||||
bytes in size. (The ordering of members in the ctf_member_* structures is
|
||||
different to improve padding.) */
|
||||
|
||||
#define CTF_LSTRUCT_THRESH_V1 8192
|
||||
|
||||
typedef struct ctf_member_v1
|
||||
{
|
||||
uint32_t ctm_name; /* Reference to name in string table. */
|
||||
unsigned short ctm_type; /* Reference to type of member. */
|
||||
unsigned short ctm_offset; /* Offset of this member in bits. */
|
||||
} ctf_member_v1_t;
|
||||
|
||||
typedef struct ctf_lmember_v1
|
||||
{
|
||||
uint32_t ctlm_name; /* Reference to name in string table. */
|
||||
unsigned short ctlm_type; /* Reference to type of member. */
|
||||
unsigned short ctlm_pad; /* Padding. */
|
||||
uint32_t ctlm_offsethi; /* High 32 bits of member offset in bits. */
|
||||
uint32_t ctlm_offsetlo; /* Low 32 bits of member offset in bits. */
|
||||
} ctf_lmember_v1_t;
|
||||
|
||||
typedef struct ctf_member_v2
|
||||
{
|
||||
uint32_t ctm_name; /* Reference to name in string table. */
|
||||
uint32_t ctm_offset; /* Offset of this member in bits. */
|
||||
uint32_t ctm_type; /* Reference to type of member. */
|
||||
} ctf_member_t;
|
||||
|
||||
typedef struct ctf_lmember_v2
|
||||
{
|
||||
uint32_t ctlm_name; /* Reference to name in string table. */
|
||||
uint32_t ctlm_offsethi; /* High 32 bits of member offset in bits. */
|
||||
uint32_t ctlm_type; /* Reference to type of member. */
|
||||
uint32_t ctlm_offsetlo; /* Low 32 bits of member offset in bits. */
|
||||
} ctf_lmember_t;
|
||||
|
||||
#define CTF_LMEM_OFFSET(ctlmp) \
|
||||
(((uint64_t)(ctlmp)->ctlm_offsethi) << 32 | (ctlmp)->ctlm_offsetlo)
|
||||
#define CTF_OFFSET_TO_LMEMHI(offset) ((uint32_t)((uint64_t)(offset) >> 32))
|
||||
#define CTF_OFFSET_TO_LMEMLO(offset) ((uint32_t)(offset))
|
||||
|
||||
typedef struct ctf_enum
|
||||
{
|
||||
uint32_t cte_name; /* Reference to name in string table. */
|
||||
int32_t cte_value; /* Value associated with this name. */
|
||||
} ctf_enum_t;
|
||||
|
||||
/* The ctf_archive is a collection of ctf_dict_t's stored together. The format
|
||||
is suitable for mmap()ing: this control structure merely describes the
|
||||
mmap()ed archive (and overlaps the first few bytes of it), hence the
|
||||
greater care taken with integral types. All CTF files in an archive
|
||||
must have the same data model. (This is not validated.)
|
||||
|
||||
All integers in this structure are stored in little-endian byte order.
|
||||
|
||||
The code relies on the fact that everything in this header is a uint64_t
|
||||
and thus the header needs no padding (in particular, that no padding is
|
||||
needed between ctfa_ctfs and the unnamed ctfa_archive_modent array
|
||||
that follows it).
|
||||
|
||||
This is *not* the same as the data structure returned by the ctf_arc_*()
|
||||
functions: this is the low-level on-disk representation. */
|
||||
|
||||
#define CTFA_MAGIC 0x8b47f2a4d7623eeb /* Random. */
|
||||
struct ctf_archive
|
||||
{
|
||||
/* Magic number. (In loaded files, overwritten with the file size
|
||||
so ctf_arc_close() knows how much to munmap()). */
|
||||
uint64_t ctfa_magic;
|
||||
|
||||
/* CTF data model. */
|
||||
uint64_t ctfa_model;
|
||||
|
||||
/* Number of CTF dicts in the archive. */
|
||||
uint64_t ctfa_ndicts;
|
||||
|
||||
/* Offset of the name table. */
|
||||
uint64_t ctfa_names;
|
||||
|
||||
/* Offset of the CTF table. Each element starts with a size (a uint64_t
|
||||
in network byte order) then a ctf_dict_t of that size. */
|
||||
uint64_t ctfa_ctfs;
|
||||
};
|
||||
|
||||
/* An array of ctfa_nnamed of this structure lies at
|
||||
ctf_archive[ctf_archive->ctfa_modents] and gives the ctfa_ctfs or
|
||||
ctfa_names-relative offsets of each name or ctf_dict_t. */
|
||||
|
||||
typedef struct ctf_archive_modent
|
||||
{
|
||||
uint64_t name_offset;
|
||||
uint64_t ctf_offset;
|
||||
} ctf_archive_modent_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CTF_H */
|
@ -1,103 +0,0 @@
|
||||
/* Copyright (C) 2017-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef DIAGNOSTICS_H
|
||||
#define DIAGNOSTICS_H
|
||||
|
||||
/* If at all possible, fix the source rather than using these macros
|
||||
to silence warnings. If you do use these macros be aware that
|
||||
you'll need to condition their use on particular compiler versions,
|
||||
which can be done for gcc using ansidecl.h's GCC_VERSION macro.
|
||||
|
||||
gcc versions between 4.2 and 4.6 do not allow pragma control of
|
||||
diagnostics inside functions, giving a hard error if you try to use
|
||||
the finer control available with later versions.
|
||||
gcc prior to 4.2 warns about diagnostic push and pop.
|
||||
|
||||
The other macros have restrictions too, for example gcc-5, gcc-6
|
||||
and gcc-7 warn that -Wstringop-truncation is unknown, unless you
|
||||
also add DIAGNOSTIC_IGNORE ("-Wpragma"). */
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define DIAGNOSTIC_PUSH _Pragma ("GCC diagnostic push")
|
||||
# define DIAGNOSTIC_POP _Pragma ("GCC diagnostic pop")
|
||||
|
||||
/* Stringification. */
|
||||
# define DIAGNOSTIC_STRINGIFY_1(x) #x
|
||||
# define DIAGNOSTIC_STRINGIFY(x) DIAGNOSTIC_STRINGIFY_1 (x)
|
||||
|
||||
# define DIAGNOSTIC_IGNORE(option) \
|
||||
_Pragma (DIAGNOSTIC_STRINGIFY (GCC diagnostic ignored option))
|
||||
#else
|
||||
# define DIAGNOSTIC_PUSH
|
||||
# define DIAGNOSTIC_POP
|
||||
# define DIAGNOSTIC_IGNORE(option)
|
||||
#endif
|
||||
|
||||
#if defined (__clang__) /* clang */
|
||||
|
||||
# define DIAGNOSTIC_IGNORE_SELF_MOVE DIAGNOSTIC_IGNORE ("-Wself-move")
|
||||
# define DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \
|
||||
DIAGNOSTIC_IGNORE ("-Wdeprecated-declarations")
|
||||
# define DIAGNOSTIC_IGNORE_DEPRECATED_REGISTER \
|
||||
DIAGNOSTIC_IGNORE ("-Wdeprecated-register")
|
||||
# if __has_warning ("-Wenum-compare-switch")
|
||||
# define DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES \
|
||||
DIAGNOSTIC_IGNORE ("-Wenum-compare-switch")
|
||||
# endif
|
||||
|
||||
# define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
|
||||
DIAGNOSTIC_IGNORE ("-Wformat-nonliteral")
|
||||
|
||||
#elif defined (__GNUC__) /* GCC */
|
||||
|
||||
# if __GNUC__ >= 7
|
||||
# define DIAGNOSTIC_IGNORE_DEPRECATED_REGISTER \
|
||||
DIAGNOSTIC_IGNORE ("-Wregister")
|
||||
# endif
|
||||
|
||||
# define DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION \
|
||||
DIAGNOSTIC_IGNORE ("-Wstringop-truncation")
|
||||
|
||||
# define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL \
|
||||
DIAGNOSTIC_IGNORE ("-Wformat-nonliteral")
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_SELF_MOVE
|
||||
# define DIAGNOSTIC_IGNORE_SELF_MOVE
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
|
||||
# define DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_DEPRECATED_REGISTER
|
||||
# define DIAGNOSTIC_IGNORE_DEPRECATED_REGISTER
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
|
||||
# define DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION
|
||||
# define DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION
|
||||
#endif
|
||||
|
||||
#ifndef DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
|
||||
# define DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
|
||||
#endif
|
||||
|
||||
#endif /* DIAGNOSTICS_H */
|
@ -1,400 +0,0 @@
|
||||
/* Interface between the opcode library and its callers.
|
||||
|
||||
Copyright (C) 1999-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, 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.
|
||||
|
||||
Written by Cygnus Support, 1993.
|
||||
|
||||
The opcode library (libopcodes.a) provides instruction decoders for
|
||||
a large variety of instruction sets, callable with an identical
|
||||
interface, for making instruction-processing programs more independent
|
||||
of the instruction set being processed. */
|
||||
|
||||
#ifndef DIS_ASM_H
|
||||
#define DIS_ASM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "bfd.h"
|
||||
|
||||
typedef int (*fprintf_ftype) (void *, const char*, ...) ATTRIBUTE_FPTR_PRINTF_2;
|
||||
|
||||
enum dis_insn_type
|
||||
{
|
||||
dis_noninsn, /* Not a valid instruction. */
|
||||
dis_nonbranch, /* Not a branch instruction. */
|
||||
dis_branch, /* Unconditional branch. */
|
||||
dis_condbranch, /* Conditional branch. */
|
||||
dis_jsr, /* Jump to subroutine. */
|
||||
dis_condjsr, /* Conditional jump to subroutine. */
|
||||
dis_dref, /* Data reference instruction. */
|
||||
dis_dref2 /* Two data references in instruction. */
|
||||
};
|
||||
|
||||
/* This struct is passed into the instruction decoding routine,
|
||||
and is passed back out into each callback. The various fields are used
|
||||
for conveying information from your main routine into your callbacks,
|
||||
for passing information into the instruction decoders (such as the
|
||||
addresses of the callback functions), or for passing information
|
||||
back from the instruction decoders to their callers.
|
||||
|
||||
It must be initialized before it is first passed; this can be done
|
||||
by hand, or using one of the initialization macros below. */
|
||||
|
||||
typedef struct disassemble_info
|
||||
{
|
||||
fprintf_ftype fprintf_func;
|
||||
void *stream;
|
||||
void *application_data;
|
||||
|
||||
/* Target description. We could replace this with a pointer to the bfd,
|
||||
but that would require one. There currently isn't any such requirement
|
||||
so to avoid introducing one we record these explicitly. */
|
||||
/* The bfd_flavour. This can be bfd_target_unknown_flavour. */
|
||||
enum bfd_flavour flavour;
|
||||
/* The bfd_arch value. */
|
||||
enum bfd_architecture arch;
|
||||
/* The bfd_mach value. */
|
||||
unsigned long mach;
|
||||
/* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
|
||||
enum bfd_endian endian;
|
||||
/* Endianness of code, for mixed-endian situations such as ARM BE8. */
|
||||
enum bfd_endian endian_code;
|
||||
|
||||
/* Some targets need information about the current section to accurately
|
||||
display insns. If this is NULL, the target disassembler function
|
||||
will have to make its best guess. */
|
||||
asection *section;
|
||||
|
||||
/* An array of pointers to symbols either at the location being disassembled
|
||||
or at the start of the function being disassembled. The array is sorted
|
||||
so that the first symbol is intended to be the one used. The others are
|
||||
present for any misc. purposes. This is not set reliably, but if it is
|
||||
not NULL, it is correct. */
|
||||
asymbol **symbols;
|
||||
/* Number of symbols in array. */
|
||||
int num_symbols;
|
||||
|
||||
/* Symbol table provided for targets that want to look at it. This is
|
||||
used on Arm to find mapping symbols and determine Arm/Thumb code. */
|
||||
asymbol **symtab;
|
||||
int symtab_pos;
|
||||
int symtab_size;
|
||||
|
||||
/* For use by the disassembler.
|
||||
The top 16 bits are reserved for public use (and are documented here).
|
||||
The bottom 16 bits are for the internal use of the disassembler. */
|
||||
unsigned long flags;
|
||||
/* Set if the disassembler has determined that there are one or more
|
||||
relocations associated with the instruction being disassembled. */
|
||||
#define INSN_HAS_RELOC (1u << 31)
|
||||
/* Set if the user has requested the disassembly of data as well as code. */
|
||||
#define DISASSEMBLE_DATA (1u << 30)
|
||||
/* Set if the user has specifically set the machine type encoded in the
|
||||
mach field of this structure. */
|
||||
#define USER_SPECIFIED_MACHINE_TYPE (1u << 29)
|
||||
/* Set if the user has requested wide output. */
|
||||
#define WIDE_OUTPUT (1u << 28)
|
||||
|
||||
/* Use internally by the target specific disassembly code. */
|
||||
void *private_data;
|
||||
|
||||
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||
address of the stuff to be disassembled, MYADDR is the address to
|
||||
put the bytes in, and LENGTH is the number of bytes to read.
|
||||
INFO is a pointer to this struct.
|
||||
Returns an errno value or 0 for success. */
|
||||
int (*read_memory_func)
|
||||
(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
|
||||
struct disassemble_info *dinfo);
|
||||
|
||||
/* Function which should be called if we get an error that we can't
|
||||
recover from. STATUS is the errno value from read_memory_func and
|
||||
MEMADDR is the address that we were trying to read. INFO is a
|
||||
pointer to this struct. */
|
||||
void (*memory_error_func)
|
||||
(int status, bfd_vma memaddr, struct disassemble_info *dinfo);
|
||||
|
||||
/* Function called to print ADDR. */
|
||||
void (*print_address_func)
|
||||
(bfd_vma addr, struct disassemble_info *dinfo);
|
||||
|
||||
/* Function called to determine if there is a symbol at the given ADDR.
|
||||
If there is, the function returns 1, otherwise it returns 0.
|
||||
This is used by ports which support an overlay manager where
|
||||
the overlay number is held in the top part of an address. In
|
||||
some circumstances we want to include the overlay number in the
|
||||
address, (normally because there is a symbol associated with
|
||||
that address), but sometimes we want to mask out the overlay bits. */
|
||||
int (* symbol_at_address_func)
|
||||
(bfd_vma addr, struct disassemble_info *dinfo);
|
||||
|
||||
/* Function called to check if a SYMBOL is can be displayed to the user.
|
||||
This is used by some ports that want to hide special symbols when
|
||||
displaying debugging outout. */
|
||||
bfd_boolean (* symbol_is_valid)
|
||||
(asymbol *, struct disassemble_info *dinfo);
|
||||
|
||||
/* These are for buffer_read_memory. */
|
||||
bfd_byte *buffer;
|
||||
bfd_vma buffer_vma;
|
||||
size_t buffer_length;
|
||||
|
||||
/* This variable may be set by the instruction decoder. It suggests
|
||||
the number of bytes objdump should display on a single line. If
|
||||
the instruction decoder sets this, it should always set it to
|
||||
the same value in order to get reasonable looking output. */
|
||||
int bytes_per_line;
|
||||
|
||||
/* The next two variables control the way objdump displays the raw data. */
|
||||
/* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
|
||||
/* output will look like this:
|
||||
00: 00000000 00000000
|
||||
with the chunks displayed according to "display_endian". */
|
||||
int bytes_per_chunk;
|
||||
enum bfd_endian display_endian;
|
||||
|
||||
/* Number of octets per incremented target address
|
||||
Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
|
||||
unsigned int octets_per_byte;
|
||||
|
||||
/* The number of zeroes we want to see at the end of a section before we
|
||||
start skipping them. */
|
||||
unsigned int skip_zeroes;
|
||||
|
||||
/* The number of zeroes to skip at the end of a section. If the number
|
||||
of zeroes at the end is between SKIP_ZEROES_AT_END and SKIP_ZEROES,
|
||||
they will be disassembled. If there are fewer than
|
||||
SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic
|
||||
attempt to avoid disassembling zeroes inserted by section
|
||||
alignment. */
|
||||
unsigned int skip_zeroes_at_end;
|
||||
|
||||
/* Whether the disassembler always needs the relocations. */
|
||||
bfd_boolean disassembler_needs_relocs;
|
||||
|
||||
/* Results from instruction decoders. Not all decoders yet support
|
||||
this information. This info is set each time an instruction is
|
||||
decoded, and is only valid for the last such instruction.
|
||||
|
||||
To determine whether this decoder supports this information, set
|
||||
insn_info_valid to 0, decode an instruction, then check it. */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
/* Command line options specific to the target disassembler. */
|
||||
const char *disassembler_options;
|
||||
|
||||
/* If non-zero then try not disassemble beyond this address, even if
|
||||
there are values left in the buffer. This address is the address
|
||||
of the nearest symbol forwards from the start of the disassembly,
|
||||
and it is assumed that it lies on the boundary between instructions.
|
||||
If an instruction spans this address then this is an error in the
|
||||
file being disassembled. */
|
||||
bfd_vma stop_vma;
|
||||
|
||||
/* The end range of the current range being disassembled. This is required
|
||||
in order to notify the disassembler when it's currently handling a
|
||||
different range than it was before. This prevent unsafe optimizations when
|
||||
disassembling such as the way mapping symbols are found on AArch64. */
|
||||
bfd_vma stop_offset;
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
/* This struct is used to pass information about valid disassembler
|
||||
option arguments from the target to the generic GDB functions
|
||||
that set and display them. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Option argument name to use in descriptions. */
|
||||
const char *name;
|
||||
|
||||
/* Vector of acceptable option argument values, NULL-terminated. */
|
||||
const char **values;
|
||||
} disasm_option_arg_t;
|
||||
|
||||
/* This struct is used to pass information about valid disassembler
|
||||
options, their descriptions and arguments from the target to the
|
||||
generic GDB functions that set and display them. Options are
|
||||
defined by tuples of vector entries at each index. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Vector of option names, NULL-terminated. */
|
||||
const char **name;
|
||||
|
||||
/* Vector of option descriptions or NULL if none to be shown. */
|
||||
const char **description;
|
||||
|
||||
/* Vector of option argument information pointers or NULL if no
|
||||
option accepts an argument. NULL entries denote individual
|
||||
options that accept no argument. */
|
||||
const disasm_option_arg_t **arg;
|
||||
} disasm_options_t;
|
||||
|
||||
/* This struct is used to pass information about valid disassembler
|
||||
options and arguments from the target to the generic GDB functions
|
||||
that set and display them. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Valid disassembler options. Individual options that support
|
||||
an argument will refer to entries in the ARGS vector. */
|
||||
disasm_options_t options;
|
||||
|
||||
/* Vector of acceptable option arguments, NULL-terminated. This
|
||||
collects all possible option argument choices, some of which
|
||||
may be shared by different options from the OPTIONS member. */
|
||||
disasm_option_arg_t *args;
|
||||
} disasm_options_and_args_t;
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of octets processed. */
|
||||
typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *);
|
||||
|
||||
/* Disassemblers used out side of opcodes library. */
|
||||
extern int print_insn_m32c (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_mep (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_s12z (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sh (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_sparc (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rx (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g10 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g13 (bfd_vma, disassemble_info *);
|
||||
extern int print_insn_rl78_g14 (bfd_vma, disassemble_info *);
|
||||
|
||||
extern disassembler_ftype arc_get_disassembler (bfd *);
|
||||
extern disassembler_ftype cris_get_disassembler (bfd *);
|
||||
|
||||
extern void print_aarch64_disassembler_options (FILE *);
|
||||
extern void print_i386_disassembler_options (FILE *);
|
||||
extern void print_mips_disassembler_options (FILE *);
|
||||
extern void print_nfp_disassembler_options (FILE *);
|
||||
extern void print_ppc_disassembler_options (FILE *);
|
||||
extern void print_riscv_disassembler_options (FILE *);
|
||||
extern void print_arm_disassembler_options (FILE *);
|
||||
extern void print_arc_disassembler_options (FILE *);
|
||||
extern void print_s390_disassembler_options (FILE *);
|
||||
extern void print_wasm32_disassembler_options (FILE *);
|
||||
extern bfd_boolean aarch64_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern bfd_boolean csky_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern bfd_boolean riscv_symbol_is_valid (asymbol *, struct disassemble_info *);
|
||||
extern void disassemble_init_powerpc (struct disassemble_info *);
|
||||
extern void disassemble_init_s390 (struct disassemble_info *);
|
||||
extern void disassemble_init_wasm32 (struct disassemble_info *);
|
||||
extern void disassemble_init_nds32 (struct disassemble_info *);
|
||||
extern const disasm_options_and_args_t *disassembler_options_arm (void);
|
||||
extern const disasm_options_and_args_t *disassembler_options_mips (void);
|
||||
extern const disasm_options_and_args_t *disassembler_options_powerpc (void);
|
||||
extern const disasm_options_and_args_t *disassembler_options_s390 (void);
|
||||
|
||||
/* Fetch the disassembler for a given architecture ARC, endianess (big
|
||||
endian if BIG is true), bfd_mach value MACH, and ABFD, if that support
|
||||
is available. ABFD may be NULL. */
|
||||
extern disassembler_ftype disassembler (enum bfd_architecture arc,
|
||||
bfd_boolean big, unsigned long mach,
|
||||
bfd *abfd);
|
||||
|
||||
/* Amend the disassemble_info structure as necessary for the target architecture.
|
||||
Should only be called after initialising the info->arch field. */
|
||||
extern void disassemble_init_for_target (struct disassemble_info *);
|
||||
|
||||
/* Tidy any memory allocated by targets, such as info->private_data. */
|
||||
extern void disassemble_free_target (struct disassemble_info *);
|
||||
|
||||
/* Document any target specific options available from the disassembler. */
|
||||
extern void disassembler_usage (FILE *);
|
||||
|
||||
/* Remove whitespace and consecutive commas. */
|
||||
extern char *remove_whitespace_and_extra_commas (char *);
|
||||
|
||||
/* Like STRCMP, but treat ',' the same as '\0' so that we match
|
||||
strings like "foobar" against "foobar,xxyyzz,...". */
|
||||
extern int disassembler_options_cmp (const char *, const char *);
|
||||
|
||||
/* A helper function for FOR_EACH_DISASSEMBLER_OPTION. */
|
||||
static inline const char *
|
||||
next_disassembler_option (const char *options)
|
||||
{
|
||||
const char *opt = strchr (options, ',');
|
||||
if (opt != NULL)
|
||||
opt++;
|
||||
return opt;
|
||||
}
|
||||
|
||||
/* A macro for iterating over each comma separated option in OPTIONS. */
|
||||
#define FOR_EACH_DISASSEMBLER_OPTION(OPT, OPTIONS) \
|
||||
for ((OPT) = (OPTIONS); \
|
||||
(OPT) != NULL; \
|
||||
(OPT) = next_disassembler_option (OPT))
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
||||
/* Here is a function which callers may wish to use for read_memory_func.
|
||||
It gets bytes from a buffer. */
|
||||
extern int buffer_read_memory
|
||||
(bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *);
|
||||
|
||||
/* This function goes with buffer_read_memory.
|
||||
It prints a message using info->fprintf_func and info->stream. */
|
||||
extern void perror_memory (int, bfd_vma, struct disassemble_info *);
|
||||
|
||||
|
||||
/* Just print the address in hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
extern void generic_print_address
|
||||
(bfd_vma, struct disassemble_info *);
|
||||
|
||||
/* Always true. */
|
||||
extern int generic_symbol_at_address
|
||||
(bfd_vma, struct disassemble_info *);
|
||||
|
||||
/* Also always true. */
|
||||
extern bfd_boolean generic_symbol_is_valid
|
||||
(asymbol *, struct disassemble_info *);
|
||||
|
||||
/* Method to initialize a disassemble_info struct. This should be
|
||||
called by all applications creating such a struct. */
|
||||
extern void init_disassemble_info (struct disassemble_info *dinfo, void *stream,
|
||||
fprintf_ftype fprintf_func);
|
||||
|
||||
/* For compatibility with existing code. */
|
||||
#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
|
||||
init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! defined (DIS_ASM_H) */
|
@ -1,572 +0,0 @@
|
||||
/* plugin-api.h -- External linker plugin API. */
|
||||
|
||||
/* Copyright (C) 2009-2021 Free Software Foundation, Inc.
|
||||
Written by Cary Coutant <ccoutant@google.com>.
|
||||
|
||||
This file is part of 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
/* This file defines the interface for writing a linker plugin, which is
|
||||
described at < http://gcc.gnu.org/wiki/whopr/driver >. */
|
||||
|
||||
#ifndef PLUGIN_API_H
|
||||
#define PLUGIN_API_H
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#if !defined(HAVE_STDINT_H) && !defined(HAVE_INTTYPES_H) && \
|
||||
!defined(UINT64_MAX) && !defined(uint64_t)
|
||||
#error cannot find uint64_t type
|
||||
#endif
|
||||
|
||||
/* Detect endianess based on __BYTE_ORDER__ macro. */
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
|
||||
defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_PDP_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define PLUGIN_LITTLE_ENDIAN 1
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define PLUGIN_BIG_ENDIAN 1
|
||||
#elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
|
||||
#define PLUGIN_PDP_ENDIAN 1
|
||||
#endif
|
||||
#else
|
||||
/* Older GCC releases (<4.6.0) can make detection from glibc macros. */
|
||||
#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID__)
|
||||
#include <endian.h>
|
||||
#ifdef __BYTE_ORDER
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define PLUGIN_LITTLE_ENDIAN 1
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define PLUGIN_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
/* Include all necessary header files based on target. */
|
||||
#if defined(__SVR4) && defined(__sun)
|
||||
#include <sys/byteorder.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || \
|
||||
defined(__DragonFly__) || defined(__minix)
|
||||
#include <sys/endian.h>
|
||||
#endif
|
||||
#if defined(__OpenBSD__)
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
/* Detect endianess based on _BYTE_ORDER. */
|
||||
#ifdef _BYTE_ORDER
|
||||
#if _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
#define PLUGIN_LITTLE_ENDIAN 1
|
||||
#elif _BYTE_ORDER == _BIG_ENDIAN
|
||||
#define PLUGIN_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
/* Detect based on _WIN32. */
|
||||
#if defined(_WIN32)
|
||||
#define PLUGIN_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
/* Detect based on __BIG_ENDIAN__ and __LITTLE_ENDIAN__ */
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#define PLUGIN_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#ifdef __BIG_ENDIAN__
|
||||
#define PLUGIN_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Status code returned by most API routines. */
|
||||
|
||||
enum ld_plugin_status
|
||||
{
|
||||
LDPS_OK = 0,
|
||||
LDPS_NO_SYMS, /* Attempt to get symbols that haven't been added. */
|
||||
LDPS_BAD_HANDLE, /* No claimed object associated with given handle. */
|
||||
LDPS_ERR
|
||||
/* Additional Error codes TBD. */
|
||||
};
|
||||
|
||||
/* The version of the API specification. */
|
||||
|
||||
enum ld_plugin_api_version
|
||||
{
|
||||
LD_PLUGIN_API_VERSION = 1
|
||||
};
|
||||
|
||||
/* The type of output file being generated by the linker. */
|
||||
|
||||
enum ld_plugin_output_file_type
|
||||
{
|
||||
LDPO_REL,
|
||||
LDPO_EXEC,
|
||||
LDPO_DYN,
|
||||
LDPO_PIE
|
||||
};
|
||||
|
||||
/* An input file managed by the plugin library. */
|
||||
|
||||
struct ld_plugin_input_file
|
||||
{
|
||||
const char *name;
|
||||
int fd;
|
||||
off_t offset;
|
||||
off_t filesize;
|
||||
void *handle;
|
||||
};
|
||||
|
||||
/* A symbol belonging to an input file managed by the plugin library. */
|
||||
|
||||
struct ld_plugin_symbol
|
||||
{
|
||||
char *name;
|
||||
char *version;
|
||||
/* This is for compatibility with older ABIs. The older ABI defined
|
||||
only 'def' field. */
|
||||
#if PLUGIN_BIG_ENDIAN == 1
|
||||
char unused;
|
||||
char section_kind;
|
||||
char symbol_type;
|
||||
char def;
|
||||
#elif PLUGIN_LITTLE_ENDIAN == 1
|
||||
char def;
|
||||
char symbol_type;
|
||||
char section_kind;
|
||||
char unused;
|
||||
#elif PLUGIN_PDP_ENDIAN == 1
|
||||
char symbol_type;
|
||||
char def;
|
||||
char unused;
|
||||
char section_kind;
|
||||
#else
|
||||
#error "Could not detect architecture endianess"
|
||||
#endif
|
||||
int visibility;
|
||||
uint64_t size;
|
||||
char *comdat_key;
|
||||
int resolution;
|
||||
};
|
||||
|
||||
/* An object's section. */
|
||||
|
||||
struct ld_plugin_section
|
||||
{
|
||||
const void* handle;
|
||||
unsigned int shndx;
|
||||
};
|
||||
|
||||
/* Whether the symbol is a definition, reference, or common, weak or not. */
|
||||
|
||||
enum ld_plugin_symbol_kind
|
||||
{
|
||||
LDPK_DEF,
|
||||
LDPK_WEAKDEF,
|
||||
LDPK_UNDEF,
|
||||
LDPK_WEAKUNDEF,
|
||||
LDPK_COMMON
|
||||
};
|
||||
|
||||
/* The visibility of the symbol. */
|
||||
|
||||
enum ld_plugin_symbol_visibility
|
||||
{
|
||||
LDPV_DEFAULT,
|
||||
LDPV_PROTECTED,
|
||||
LDPV_INTERNAL,
|
||||
LDPV_HIDDEN
|
||||
};
|
||||
|
||||
/* The type of the symbol. */
|
||||
|
||||
enum ld_plugin_symbol_type
|
||||
{
|
||||
LDST_UNKNOWN,
|
||||
LDST_FUNCTION,
|
||||
LDST_VARIABLE
|
||||
};
|
||||
|
||||
enum ld_plugin_symbol_section_kind
|
||||
{
|
||||
LDSSK_DEFAULT,
|
||||
LDSSK_BSS
|
||||
};
|
||||
|
||||
/* How a symbol is resolved. */
|
||||
|
||||
enum ld_plugin_symbol_resolution
|
||||
{
|
||||
LDPR_UNKNOWN = 0,
|
||||
|
||||
/* Symbol is still undefined at this point. */
|
||||
LDPR_UNDEF,
|
||||
|
||||
/* This is the prevailing definition of the symbol, with references from
|
||||
regular object code. */
|
||||
LDPR_PREVAILING_DEF,
|
||||
|
||||
/* This is the prevailing definition of the symbol, with no
|
||||
references from regular objects. It is only referenced from IR
|
||||
code. */
|
||||
LDPR_PREVAILING_DEF_IRONLY,
|
||||
|
||||
/* This definition was pre-empted by a definition in a regular
|
||||
object file. */
|
||||
LDPR_PREEMPTED_REG,
|
||||
|
||||
/* This definition was pre-empted by a definition in another IR file. */
|
||||
LDPR_PREEMPTED_IR,
|
||||
|
||||
/* This symbol was resolved by a definition in another IR file. */
|
||||
LDPR_RESOLVED_IR,
|
||||
|
||||
/* This symbol was resolved by a definition in a regular object
|
||||
linked into the main executable. */
|
||||
LDPR_RESOLVED_EXEC,
|
||||
|
||||
/* This symbol was resolved by a definition in a shared object. */
|
||||
LDPR_RESOLVED_DYN,
|
||||
|
||||
/* This is the prevailing definition of the symbol, with no
|
||||
references from regular objects. It is only referenced from IR
|
||||
code, but the symbol is exported and may be referenced from
|
||||
a dynamic object (not seen at link time). */
|
||||
LDPR_PREVAILING_DEF_IRONLY_EXP
|
||||
};
|
||||
|
||||
/* The plugin library's "claim file" handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_claim_file_handler) (
|
||||
const struct ld_plugin_input_file *file, int *claimed);
|
||||
|
||||
/* The plugin library's "all symbols read" handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_all_symbols_read_handler) (void);
|
||||
|
||||
/* The plugin library's cleanup handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_cleanup_handler) (void);
|
||||
|
||||
/* The linker's interface for registering the "claim file" handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
|
||||
|
||||
/* The linker's interface for registering the "all symbols read" handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_register_all_symbols_read) (
|
||||
ld_plugin_all_symbols_read_handler handler);
|
||||
|
||||
/* The linker's interface for registering the cleanup handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_register_cleanup) (ld_plugin_cleanup_handler handler);
|
||||
|
||||
/* The linker's interface for adding symbols from a claimed input file. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_add_symbols) (void *handle, int nsyms,
|
||||
const struct ld_plugin_symbol *syms);
|
||||
|
||||
/* The linker's interface for getting the input file information with
|
||||
an open (possibly re-opened) file descriptor. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_file) (const void *handle,
|
||||
struct ld_plugin_input_file *file);
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_view) (const void *handle, const void **viewp);
|
||||
|
||||
/* The linker's interface for releasing the input file. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_release_input_file) (const void *handle);
|
||||
|
||||
/* The linker's interface for retrieving symbol resolution information. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_symbols) (const void *handle, int nsyms,
|
||||
struct ld_plugin_symbol *syms);
|
||||
|
||||
/* The linker's interface for adding a compiled input file. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_add_input_file) (const char *pathname);
|
||||
|
||||
/* The linker's interface for adding a library that should be searched. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_add_input_library) (const char *libname);
|
||||
|
||||
/* The linker's interface for adding a library path that should be searched. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_set_extra_library_path) (const char *path);
|
||||
|
||||
/* The linker's interface for issuing a warning or error message. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_message) (int level, const char *format, ...);
|
||||
|
||||
/* The linker's interface for retrieving the number of sections in an object.
|
||||
The handle is obtained in the claim_file handler. This interface should
|
||||
only be invoked in the claim_file handler. This function sets *COUNT to
|
||||
the number of sections in the object. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_count) (const void* handle, unsigned int *count);
|
||||
|
||||
/* The linker's interface for retrieving the section type of a specific
|
||||
section in an object. This interface should only be invoked in the
|
||||
claim_file handler. This function sets *TYPE to an ELF SHT_xxx value. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_type) (const struct ld_plugin_section section,
|
||||
unsigned int *type);
|
||||
|
||||
/* The linker's interface for retrieving the name of a specific section in
|
||||
an object. This interface should only be invoked in the claim_file handler.
|
||||
This function sets *SECTION_NAME_PTR to a null-terminated buffer allocated
|
||||
by malloc. The plugin must free *SECTION_NAME_PTR. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_name) (const struct ld_plugin_section section,
|
||||
char **section_name_ptr);
|
||||
|
||||
/* The linker's interface for retrieving the contents of a specific section
|
||||
in an object. This interface should only be invoked in the claim_file
|
||||
handler. This function sets *SECTION_CONTENTS to point to a buffer that is
|
||||
valid until clam_file handler returns. It sets *LEN to the size of the
|
||||
buffer. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_contents) (const struct ld_plugin_section section,
|
||||
const unsigned char **section_contents,
|
||||
size_t* len);
|
||||
|
||||
/* The linker's interface for specifying the desired order of sections.
|
||||
The sections should be specifed using the array SECTION_LIST in the
|
||||
order in which they should appear in the final layout. NUM_SECTIONS
|
||||
specifies the number of entries in each array. This should be invoked
|
||||
in the all_symbols_read handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_update_section_order) (const struct ld_plugin_section *section_list,
|
||||
unsigned int num_sections);
|
||||
|
||||
/* The linker's interface for specifying that reordering of sections is
|
||||
desired so that the linker can prepare for it. This should be invoked
|
||||
before update_section_order, preferably in the claim_file handler. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_allow_section_ordering) (void);
|
||||
|
||||
/* The linker's interface for specifying that a subset of sections is
|
||||
to be mapped to a unique segment. If the plugin wants to call
|
||||
unique_segment_for_sections, it must call this function from a
|
||||
claim_file_handler or when it is first loaded. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_allow_unique_segment_for_sections) (void);
|
||||
|
||||
/* The linker's interface for specifying that a specific set of sections
|
||||
must be mapped to a unique segment. ELF segments do not have names
|
||||
and the NAME is used as the name of the newly created output section
|
||||
that is then placed in the unique PT_LOAD segment. FLAGS is used to
|
||||
specify if any additional segment flags need to be set. For instance,
|
||||
a specific segment flag can be set to identify this segment. Unsetting
|
||||
segment flags that would be set by default is not possible. The
|
||||
parameter SEGMENT_ALIGNMENT when non-zero will override the default. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_unique_segment_for_sections) (
|
||||
const char* segment_name,
|
||||
uint64_t segment_flags,
|
||||
uint64_t segment_alignment,
|
||||
const struct ld_plugin_section * section_list,
|
||||
unsigned int num_sections);
|
||||
|
||||
/* The linker's interface for retrieving the section alignment requirement
|
||||
of a specific section in an object. This interface should only be invoked in the
|
||||
claim_file handler. This function sets *ADDRALIGN to the ELF sh_addralign
|
||||
value of the input section. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_alignment) (const struct ld_plugin_section section,
|
||||
unsigned int *addralign);
|
||||
|
||||
/* The linker's interface for retrieving the section size of a specific section
|
||||
in an object. This interface should only be invoked in the claim_file handler.
|
||||
This function sets *SECSIZE to the ELF sh_size
|
||||
value of the input section. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_input_section_size) (const struct ld_plugin_section section,
|
||||
uint64_t *secsize);
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_new_input_handler) (const struct ld_plugin_input_file *file);
|
||||
|
||||
/* The linker's interface for registering the "new_input" handler. This handler
|
||||
will be notified when a new input file has been added after the
|
||||
all_symbols_read event, allowing the plugin to, for example, set a unique
|
||||
segment for sections in plugin-generated input files. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_register_new_input) (ld_plugin_new_input_handler handler);
|
||||
|
||||
/* The linker's interface for getting the list of wrapped symbols using the
|
||||
--wrap option. This sets *NUM_SYMBOLS to number of wrapped symbols and
|
||||
*WRAP_SYMBOL_LIST to the list of wrapped symbols. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_get_wrap_symbols) (uint64_t *num_symbols,
|
||||
const char ***wrap_symbol_list);
|
||||
|
||||
enum ld_plugin_level
|
||||
{
|
||||
LDPL_INFO,
|
||||
LDPL_WARNING,
|
||||
LDPL_ERROR,
|
||||
LDPL_FATAL
|
||||
};
|
||||
|
||||
/* Values for the tv_tag field of the transfer vector. */
|
||||
|
||||
enum ld_plugin_tag
|
||||
{
|
||||
LDPT_NULL = 0,
|
||||
LDPT_API_VERSION = 1,
|
||||
LDPT_GOLD_VERSION = 2,
|
||||
LDPT_LINKER_OUTPUT = 3,
|
||||
LDPT_OPTION = 4,
|
||||
LDPT_REGISTER_CLAIM_FILE_HOOK = 5,
|
||||
LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK = 6,
|
||||
LDPT_REGISTER_CLEANUP_HOOK = 7,
|
||||
LDPT_ADD_SYMBOLS = 8,
|
||||
LDPT_GET_SYMBOLS = 9,
|
||||
LDPT_ADD_INPUT_FILE = 10,
|
||||
LDPT_MESSAGE = 11,
|
||||
LDPT_GET_INPUT_FILE = 12,
|
||||
LDPT_RELEASE_INPUT_FILE = 13,
|
||||
LDPT_ADD_INPUT_LIBRARY = 14,
|
||||
LDPT_OUTPUT_NAME = 15,
|
||||
LDPT_SET_EXTRA_LIBRARY_PATH = 16,
|
||||
LDPT_GNU_LD_VERSION = 17,
|
||||
LDPT_GET_VIEW = 18,
|
||||
LDPT_GET_INPUT_SECTION_COUNT = 19,
|
||||
LDPT_GET_INPUT_SECTION_TYPE = 20,
|
||||
LDPT_GET_INPUT_SECTION_NAME = 21,
|
||||
LDPT_GET_INPUT_SECTION_CONTENTS = 22,
|
||||
LDPT_UPDATE_SECTION_ORDER = 23,
|
||||
LDPT_ALLOW_SECTION_ORDERING = 24,
|
||||
LDPT_GET_SYMBOLS_V2 = 25,
|
||||
LDPT_ALLOW_UNIQUE_SEGMENT_FOR_SECTIONS = 26,
|
||||
LDPT_UNIQUE_SEGMENT_FOR_SECTIONS = 27,
|
||||
LDPT_GET_SYMBOLS_V3 = 28,
|
||||
LDPT_GET_INPUT_SECTION_ALIGNMENT = 29,
|
||||
LDPT_GET_INPUT_SECTION_SIZE = 30,
|
||||
LDPT_REGISTER_NEW_INPUT_HOOK = 31,
|
||||
LDPT_GET_WRAP_SYMBOLS = 32,
|
||||
LDPT_ADD_SYMBOLS_V2 = 33
|
||||
};
|
||||
|
||||
/* The plugin transfer vector. */
|
||||
|
||||
struct ld_plugin_tv
|
||||
{
|
||||
enum ld_plugin_tag tv_tag;
|
||||
union
|
||||
{
|
||||
int tv_val;
|
||||
const char *tv_string;
|
||||
ld_plugin_register_claim_file tv_register_claim_file;
|
||||
ld_plugin_register_all_symbols_read tv_register_all_symbols_read;
|
||||
ld_plugin_register_cleanup tv_register_cleanup;
|
||||
ld_plugin_add_symbols tv_add_symbols;
|
||||
ld_plugin_get_symbols tv_get_symbols;
|
||||
ld_plugin_add_input_file tv_add_input_file;
|
||||
ld_plugin_message tv_message;
|
||||
ld_plugin_get_input_file tv_get_input_file;
|
||||
ld_plugin_get_view tv_get_view;
|
||||
ld_plugin_release_input_file tv_release_input_file;
|
||||
ld_plugin_add_input_library tv_add_input_library;
|
||||
ld_plugin_set_extra_library_path tv_set_extra_library_path;
|
||||
ld_plugin_get_input_section_count tv_get_input_section_count;
|
||||
ld_plugin_get_input_section_type tv_get_input_section_type;
|
||||
ld_plugin_get_input_section_name tv_get_input_section_name;
|
||||
ld_plugin_get_input_section_contents tv_get_input_section_contents;
|
||||
ld_plugin_update_section_order tv_update_section_order;
|
||||
ld_plugin_allow_section_ordering tv_allow_section_ordering;
|
||||
ld_plugin_allow_unique_segment_for_sections tv_allow_unique_segment_for_sections;
|
||||
ld_plugin_unique_segment_for_sections tv_unique_segment_for_sections;
|
||||
ld_plugin_get_input_section_alignment tv_get_input_section_alignment;
|
||||
ld_plugin_get_input_section_size tv_get_input_section_size;
|
||||
ld_plugin_register_new_input tv_register_new_input;
|
||||
ld_plugin_get_wrap_symbols tv_get_wrap_symbols;
|
||||
} tv_u;
|
||||
};
|
||||
|
||||
/* The plugin library's "onload" entry point. */
|
||||
|
||||
typedef
|
||||
enum ld_plugin_status
|
||||
(*ld_plugin_onload) (struct ld_plugin_tv *tv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(PLUGIN_API_H) */
|
@ -1,55 +0,0 @@
|
||||
/* Symbol concatenation utilities.
|
||||
|
||||
Copyright (C) 1998-2021 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
#ifndef SYM_CAT_H
|
||||
#define SYM_CAT_H
|
||||
|
||||
#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
|
||||
#define CONCAT2(a,b) a##b
|
||||
#define CONCAT3(a,b,c) a##b##c
|
||||
#define CONCAT4(a,b,c,d) a##b##c##d
|
||||
#define CONCAT5(a,b,c,d,e) a##b##c##d##e
|
||||
#define CONCAT6(a,b,c,d,e,f) a##b##c##d##e##f
|
||||
#define STRINGX(s) #s
|
||||
#else
|
||||
/* Note one should never pass extra whitespace to the CONCATn macros,
|
||||
e.g. CONCAT2(foo, bar) because traditonal C will keep the space between
|
||||
the two labels instead of concatenating them. Instead, make sure to
|
||||
write CONCAT2(foo,bar). */
|
||||
#define CONCAT2(a,b) a/**/b
|
||||
#define CONCAT3(a,b,c) a/**/b/**/c
|
||||
#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
|
||||
#define CONCAT5(a,b,c,d,e) a/**/b/**/c/**/d/**/e
|
||||
#define CONCAT6(a,b,c,d,e,f) a/**/b/**/c/**/d/**/e/**/f
|
||||
#define STRINGX(s) "s"
|
||||
#endif
|
||||
|
||||
#define XCONCAT2(a,b) CONCAT2(a,b)
|
||||
#define XCONCAT3(a,b,c) CONCAT3(a,b,c)
|
||||
#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
|
||||
#define XCONCAT5(a,b,c,d,e) CONCAT5(a,b,c,d,e)
|
||||
#define XCONCAT6(a,b,c,d,e,f) CONCAT6(a,b,c,d,e,f)
|
||||
|
||||
/* Note the layer of indirection here is typically used to allow
|
||||
stringification of the expansion of macros. I.e. "#define foo
|
||||
bar", "XSTRING(foo)", to yield "bar". Be aware that this only
|
||||
works for __STDC__, not for traditional C which will still resolve
|
||||
to "foo". */
|
||||
#define XSTRING(s) STRINGX(s)
|
||||
|
||||
#endif /* SYM_CAT_H */
|
40
sha_lou.cpp
Normal file
40
sha_lou.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
//沙漏
|
||||
|
||||
#include<bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
int n;
|
||||
cin >>n;
|
||||
|
||||
int mid = (n - 1) / 2;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int a,b;
|
||||
|
||||
if (i <= mid)
|
||||
{
|
||||
a = i;
|
||||
b = n - 2 *i;
|
||||
}else
|
||||
{
|
||||
int j = 2 * mid - i;
|
||||
a = j;
|
||||
b = n -2 *j;
|
||||
}
|
||||
|
||||
for (int j = 0; j < a; j++)
|
||||
{
|
||||
cout <<" ";
|
||||
}
|
||||
for (int y = 0; y < b; y++)
|
||||
{
|
||||
cout <<"*";
|
||||
}
|
||||
cout <<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user