2019-04-23 23:05:52 +02:00
|
|
|
/* Error table.
|
|
|
|
Copyright (C) 2019 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/>. */
|
|
|
|
|
|
|
|
#include <ctf-impl.h>
|
|
|
|
|
|
|
|
static const char *const _ctf_errlist[] = {
|
|
|
|
"File is not in CTF or ELF format", /* ECTF_FMT */
|
|
|
|
"BFD error", /* ECTF_BFDERR */
|
|
|
|
"File uses more recent CTF version than libctf", /* ECTF_CTFVERS */
|
|
|
|
"Ambiguous BFD target", /* ECTF_BFD_AMBIGUOUS */
|
|
|
|
"Symbol table uses invalid entry size", /* ECTF_SYMTAB */
|
|
|
|
"Symbol table data buffer is not valid", /* ECTF_SYMBAD */
|
|
|
|
"String table data buffer is not valid", /* ECTF_STRBAD */
|
|
|
|
"File data structure corruption detected", /* ECTF_CORRUPT */
|
|
|
|
"File does not contain CTF data", /* ECTF_NOCTFDATA */
|
|
|
|
"Buffer does not contain CTF data", /* ECTF_NOCTFBUF */
|
|
|
|
"Symbol table information is not available", /* ECTF_NOSYMTAB */
|
|
|
|
"Type information is in parent and unavailable", /* ECTF_NOPARENT */
|
|
|
|
"Cannot import types with different data model", /* ECTF_DMODEL */
|
libctf: add the ctf_link machinery
This is the start of work on the core of the linking mechanism for CTF
sections. This commit handles the type and string sections.
The linker calls these functions in sequence:
ctf_link_add_ctf: to add each CTF section in the input in turn to a
newly-created ctf_file_t (which will appear in the output, and which
itself will become the shared parent that contains types that all
TUs have in common (in all link modes) and all types that do not
have conflicting definitions between types (by default). Input files
that are themselves products of ld -r are supported, though this is
not heavily tested yet.
ctf_link: called once all input files are added to merge the types in
all the input containers into the output container, eliminating
duplicates.
ctf_link_add_strtab: called once the ELF string table is finalized and
all its offsets are known, this calls a callback provided by the
linker which returns the string content and offset of every string in
the ELF strtab in turn: all these strings which appear in the input
CTF strtab are eliminated from it in favour of the ELF strtab:
equally, any strings that only appear in the input strtab will
reappear in the internal CTF strtab of the output.
ctf_link_shuffle_syms (not yet implemented): called once the ELF symtab
is finalized, this calls a callback provided by the linker which
returns information on every symbol in turn as a ctf_link_sym_t. This
is then used to shuffle the function info and data object sections in
the CTF section into symbol table order, eliminating the index
sections which map those sections to symbol names before that point.
Currently just returns ECTF_NOTYET.
ctf_link_write: Returns a buffer containing either a serialized
ctf_file_t (if there are no types with conflicting definitions in the
object files in the link) or a ctf_archive_t containing a large
ctf_file_t (the common types) and a bunch of small ones named after
individual CUs in which conflicting types are found (containing the
conflicting types, and all types that reference them). A threshold
size above which compression takes place is passed as one parameter.
(Currently, only gzip compression is supported, but I hope to add lzma
as well.)
Lifetime rules for this are simple: don't close the input CTF files
until you've called ctf_link for the last time. We do not assume
that symbols or strings passed in by the callback outlast the
call to ctf_link_add_strtab or ctf_link_shuffle_syms.
Right now, the duplicate elimination mechanism is the one already
present as part of the ctf_add_type function, and is not particularly
good: it misses numerous actual duplicates, and the conflicting-types
detection hardly ever reports that types conflict, even when they do
(one of them just tends to get silently dropped): it is also very slow.
This will all be fixed in the next few weeks, but the fix hardly touches
any of this code, and the linker does work without it, just not as
well as it otherwise might. (And when no CTF section is present,
there is no effect on performance, of course. So only people using
a trunk GCC with not-yet-committed patches will even notice. By the
time it gets upstream, things should be better.)
v3: Fix error handling.
v4: check for strdup failure.
v5: fix tabdamage.
include/
* ctf-api.h (struct ctf_link_sym): New, a symbol in flight to the
libctf linking machinery.
(CTF_LINK_SHARE_UNCONFLICTED): New.
(CTF_LINK_SHARE_DUPLICATED): New.
(ECTF_LINKADDEDLATE): New, replacing ECTF_UNUSED.
(ECTF_NOTYET): New, a 'not yet implemented' message.
(ctf_link_add_ctf): New, add an input file's CTF to the link.
(ctf_link): New, merge the type and string sections.
(ctf_link_strtab_string_f): New, callback for feeding strtab info.
(ctf_link_iter_symbol_f): New, callback for feeding symtab info.
(ctf_link_add_strtab): New, tell the CTF linker about the ELF
strtab's strings.
(ctf_link_shuffle_syms): New, ask the CTF linker to shuffle its
symbols into symtab order.
(ctf_link_write): New, ask the CTF linker to write the CTF out.
libctf/
* ctf-link.c: New file, linking of the string and type sections.
* Makefile.am (libctf_a_SOURCES): Add it.
* Makefile.in: Regenerate.
* ctf-impl.h (ctf_file_t): New fields ctf_link_inputs,
ctf_link_outputs.
* ctf-create.c (ctf_update): Update accordingly.
* ctf-open.c (ctf_file_close): Likewise.
* ctf-error.c (_ctf_errlist): Updated with new errors.
2019-07-13 22:06:55 +02:00
|
|
|
"File added to link too late", /* ECTF_LINKADDEDLATE */
|
2019-04-23 23:05:52 +02:00
|
|
|
"Failed to allocate (de)compression buffer", /* ECTF_ZALLOC */
|
|
|
|
"Failed to decompress CTF data", /* ECTF_DECOMPRESS */
|
|
|
|
"External string table is not available", /* ECTF_STRTAB */
|
|
|
|
"String name offset is corrupt", /* ECTF_BADNAME */
|
|
|
|
"Invalid type identifier", /* ECTF_BADID */
|
|
|
|
"Type is not a struct or union", /* ECTF_NOTSOU */
|
|
|
|
"Type is not an enum", /* ECTF_NOTENUM */
|
|
|
|
"Type is not a struct, union, or enum", /* ECTF_NOTSUE */
|
|
|
|
"Type is not an integer, float, or enum", /* ECTF_NOTINTFP */
|
|
|
|
"Type is not an array", /* ECTF_NOTARRAY */
|
|
|
|
"Type does not reference another type", /* ECTF_NOTREF */
|
|
|
|
"Input buffer is too small for type name", /* ECTF_NAMELEN */
|
|
|
|
"No type information available for that name", /* ECTF_NOTYPE */
|
|
|
|
"Syntax error in type name", /* ECTF_SYNTAX */
|
2019-07-18 19:44:21 +02:00
|
|
|
"Symbol table entry or type is not a function", /* ECTF_NOTFUNC */
|
2019-04-23 23:05:52 +02:00
|
|
|
"No function information available for symbol", /* ECTF_NOFUNCDAT */
|
|
|
|
"Symbol table entry is not a data object", /* ECTF_NOTDATA */
|
|
|
|
"No type information available for symbol", /* ECTF_NOTYPEDAT */
|
|
|
|
"No label information available for that name", /* ECTF_NOLABEL */
|
|
|
|
"File does not contain any labels", /* ECTF_NOLABELDATA */
|
|
|
|
"Feature not supported", /* ECTF_NOTSUP */
|
|
|
|
"Invalid enum element name", /* ECTF_NOENUMNAM */
|
|
|
|
"Invalid member name", /* ECTF_NOMEMBNAM */
|
|
|
|
"CTF container is read-only", /* ECTF_RDONLY */
|
|
|
|
"Limit on number of dynamic type members reached", /* ECTF_DTFULL */
|
|
|
|
"Limit on number of dynamic types reached", /* ECTF_FULL */
|
|
|
|
"Duplicate member or variable name", /* ECTF_DUPLICATE */
|
|
|
|
"Conflicting type is already defined", /* ECTF_CONFLICT */
|
|
|
|
"Attempt to roll back past a ctf_update", /* ECTF_OVERROLLBACK */
|
|
|
|
"Failed to compress CTF data", /* ECTF_COMPRESS */
|
|
|
|
"Failed to create CTF archive", /* ECTF_ARCREATE */
|
|
|
|
"Name not found in CTF archive", /* ECTF_ARNNAME */
|
|
|
|
"Overflow of type bitness or offset in slice", /* ECTF_SLICEOVERFLOW */
|
|
|
|
"Unknown section number in dump", /* ECTF_DUMPSECTUNKNOWN */
|
libctf: add the ctf_link machinery
This is the start of work on the core of the linking mechanism for CTF
sections. This commit handles the type and string sections.
The linker calls these functions in sequence:
ctf_link_add_ctf: to add each CTF section in the input in turn to a
newly-created ctf_file_t (which will appear in the output, and which
itself will become the shared parent that contains types that all
TUs have in common (in all link modes) and all types that do not
have conflicting definitions between types (by default). Input files
that are themselves products of ld -r are supported, though this is
not heavily tested yet.
ctf_link: called once all input files are added to merge the types in
all the input containers into the output container, eliminating
duplicates.
ctf_link_add_strtab: called once the ELF string table is finalized and
all its offsets are known, this calls a callback provided by the
linker which returns the string content and offset of every string in
the ELF strtab in turn: all these strings which appear in the input
CTF strtab are eliminated from it in favour of the ELF strtab:
equally, any strings that only appear in the input strtab will
reappear in the internal CTF strtab of the output.
ctf_link_shuffle_syms (not yet implemented): called once the ELF symtab
is finalized, this calls a callback provided by the linker which
returns information on every symbol in turn as a ctf_link_sym_t. This
is then used to shuffle the function info and data object sections in
the CTF section into symbol table order, eliminating the index
sections which map those sections to symbol names before that point.
Currently just returns ECTF_NOTYET.
ctf_link_write: Returns a buffer containing either a serialized
ctf_file_t (if there are no types with conflicting definitions in the
object files in the link) or a ctf_archive_t containing a large
ctf_file_t (the common types) and a bunch of small ones named after
individual CUs in which conflicting types are found (containing the
conflicting types, and all types that reference them). A threshold
size above which compression takes place is passed as one parameter.
(Currently, only gzip compression is supported, but I hope to add lzma
as well.)
Lifetime rules for this are simple: don't close the input CTF files
until you've called ctf_link for the last time. We do not assume
that symbols or strings passed in by the callback outlast the
call to ctf_link_add_strtab or ctf_link_shuffle_syms.
Right now, the duplicate elimination mechanism is the one already
present as part of the ctf_add_type function, and is not particularly
good: it misses numerous actual duplicates, and the conflicting-types
detection hardly ever reports that types conflict, even when they do
(one of them just tends to get silently dropped): it is also very slow.
This will all be fixed in the next few weeks, but the fix hardly touches
any of this code, and the linker does work without it, just not as
well as it otherwise might. (And when no CTF section is present,
there is no effect on performance, of course. So only people using
a trunk GCC with not-yet-committed patches will even notice. By the
time it gets upstream, things should be better.)
v3: Fix error handling.
v4: check for strdup failure.
v5: fix tabdamage.
include/
* ctf-api.h (struct ctf_link_sym): New, a symbol in flight to the
libctf linking machinery.
(CTF_LINK_SHARE_UNCONFLICTED): New.
(CTF_LINK_SHARE_DUPLICATED): New.
(ECTF_LINKADDEDLATE): New, replacing ECTF_UNUSED.
(ECTF_NOTYET): New, a 'not yet implemented' message.
(ctf_link_add_ctf): New, add an input file's CTF to the link.
(ctf_link): New, merge the type and string sections.
(ctf_link_strtab_string_f): New, callback for feeding strtab info.
(ctf_link_iter_symbol_f): New, callback for feeding symtab info.
(ctf_link_add_strtab): New, tell the CTF linker about the ELF
strtab's strings.
(ctf_link_shuffle_syms): New, ask the CTF linker to shuffle its
symbols into symtab order.
(ctf_link_write): New, ask the CTF linker to write the CTF out.
libctf/
* ctf-link.c: New file, linking of the string and type sections.
* Makefile.am (libctf_a_SOURCES): Add it.
* Makefile.in: Regenerate.
* ctf-impl.h (ctf_file_t): New fields ctf_link_inputs,
ctf_link_outputs.
* ctf-create.c (ctf_update): Update accordingly.
* ctf-open.c (ctf_file_close): Likewise.
* ctf-error.c (_ctf_errlist): Updated with new errors.
2019-07-13 22:06:55 +02:00
|
|
|
"Section changed in middle of dump", /* ECTF_DUMPSECTCHANGED */
|
2019-07-13 22:41:25 +02:00
|
|
|
"Feature not yet implemented", /* ECTF_NOTYET */
|
libctf: handle nonrepresentable types at link time
GCC can emit references to type 0 to indicate that this type is one that
is not representable in the version of CTF it emits (for instance,
version 3 cannot encode vector types). Type 0 is already used in the
function section to indicate padding inserted to skip functions we do
not want to encode the type of, so using zero in this way is a good
extension of the format: but libctf reports such types as ECTF_BADID,
which is indistinguishable from file corruption via links to truly
nonexistent types with IDs like 0xDEADBEEF etc, which we really do want
to stop for.
In particular, this stops all traversals of types dead at this point,
preventing us from even dumping CTF files containing unrepresentable
types to see what's going on!
So add a new error, ECTF_NONREPRESENTABLE, which is returned by
recursive type resolution when a reference to a zero type is found. (No
zero type is ever emitted into the CTF file by GCC, only references to
one). We can't do much with types that are ultimately nonrepresentable,
but we can do enough to keep functioning.
Adjust ctf_add_type to ensure that top-level types of type zero and
structure and union members of ultimate type zero are simply skipped
without reporting an error, so we can copy structures and unions that
contain nonrepresentable members (skipping them and leaving a hole where
they would be, so no consumers downstream of the linker need to worry
about this): adjust the dumper so that we dump members of
nonrepresentable types in a simple form that indicates
nonrepresentability rather than terminating the dump, and do not falsely
assume all errors to be -ENOMEM: adjust the linker so that types that
fail to get added are simply skipped, so that both nonrepresentable
types and outright errors do not terminate the type addition, which
could skip many valid types and cause further errors when variables of
those types are added.
In future, when we gain the ability to call back to the linker to report
link-time type resolution errors, we should report failures to add all
but nonrepresentable types. But we can't do that yet.
v5: Fix tabdamage.
include/
* ctf-api.h (ECTF_NONREPRESENTABLE): New.
libctf/
* ctf-types.c (ctf_type_resolve): Return ECTF_NONREPRESENTABLE on
type zero.
* ctf-create.c (ctf_add_type): Detect and skip nonrepresentable
members and types.
(ctf_add_variable): Likewise for variables pointing to them.
* ctf-link.c (ctf_link_one_type): Do not warn for nonrepresentable
type link failure, but do warn for others.
* ctf-dump.c (ctf_dump_format_type): Likewise. Do not assume all
errors to be ENOMEM.
(ctf_dump_member): Likewise.
(ctf_dump_type): Likewise.
(ctf_dump_header_strfield): Do not assume all errors to be ENOMEM.
(ctf_dump_header_sectfield): Do not assume all errors to be ENOMEM.
(ctf_dump_header): Likewise.
(ctf_dump_label): likewise.
(ctf_dump_objts): likewise.
(ctf_dump_funcs): likewise.
(ctf_dump_var): likewise.
(ctf_dump_str): Likewise.
2019-08-05 12:40:33 +02:00
|
|
|
"Internal error in link", /* ECTF_INTERNAL */
|
|
|
|
"Type not representable in CTF" /* ECTF_NONREPRESENTABLE */
|
2019-04-23 23:05:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static const int _ctf_nerr = sizeof (_ctf_errlist) / sizeof (_ctf_errlist[0]);
|
|
|
|
|
|
|
|
const char *
|
|
|
|
ctf_errmsg (int error)
|
|
|
|
{
|
|
|
|
const char *str;
|
|
|
|
|
|
|
|
if (error >= ECTF_BASE && (error - ECTF_BASE) < _ctf_nerr)
|
|
|
|
str = _ctf_errlist[error - ECTF_BASE];
|
|
|
|
else
|
|
|
|
str = ctf_strerror (error);
|
|
|
|
|
|
|
|
return (str ? str : "Unknown error");
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ctf_errno (ctf_file_t * fp)
|
|
|
|
{
|
|
|
|
return fp->ctf_errno;
|
|
|
|
}
|