forked from Imagelibrary/binutils-gdb
libctf: link: BTF support
This is in two parts, one new API function and one change. New API: +int ctf_link_output_is_btf (ctf_dict_t *); Changed API: unsigned char *ctf_link_write (ctf_dict_t *, size_t *size, - size_t threshold); + size_t threshold, int *is_btf); The idea here is that callers can call ctf_link_output_is_btf on a ctf_link()ed (deduplicated) dict to tell whether a link will yield BTF-compatible output before actually generating that output, so they can e.g. decide whether to avoid trying to compress the dict if they know it would be BTF otherwise (since compressing a dict renders it non-BTF-compatible). ctf_link_write() gains an optional is_btf output parameter that reports whether the dict that was finally generated is actually BTF after all, perhaps because the caller didn't call ctf_link_output_is_btf or wants to be robust against possible future changes that may add other reasons why a written-out dict can't be BTF at the last minute. These are simple wrappers around already-existing machinery earlier in this series.
This commit is contained in:
@@ -1117,7 +1117,10 @@ extern int ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited);
|
||||
object files into a single .ctf section which is an archive possibly
|
||||
containing members containing types whose names collide across multiple
|
||||
compilation units, but they are usable by other programs as well and are not
|
||||
private to the linker. */
|
||||
private to the linker.
|
||||
|
||||
They should be called in the order they appear below, though some are
|
||||
optional. */
|
||||
|
||||
/* Add a CTF archive to the link with a given NAME (usually the name of the
|
||||
containing object file). The dict added to is usually a new dict created
|
||||
@@ -1136,7 +1139,7 @@ extern int ctf_link_add_ctf (ctf_dict_t *, ctf_archive_t *, const char *name);
|
||||
extern int ctf_link (ctf_dict_t *, int flags);
|
||||
|
||||
/* Symtab linker handling, called after ctf_link to set up the symbol type
|
||||
information used by ctf_*_lookup_symbol. */
|
||||
information used by ctf_*_lookup_symbol. Optional. */
|
||||
|
||||
/* Add strings to the link from the ELF string table, repeatedly calling
|
||||
ADD_STRING to add each string and its corresponding offset in turn. */
|
||||
@@ -1153,19 +1156,28 @@ extern int ctf_link_add_strtab (ctf_dict_t *,
|
||||
extern int ctf_link_add_linker_symbol (ctf_dict_t *, ctf_link_sym_t *);
|
||||
|
||||
/* Impose an ordering on symbols, as defined by the strtab and symbol
|
||||
added by earlier calls to the above two functions. */
|
||||
added by earlier calls to the above two functions. Optional. */
|
||||
|
||||
extern int ctf_link_shuffle_syms (ctf_dict_t *);
|
||||
|
||||
/* Determine the file format of the dict that will be written out after the
|
||||
calls above is compatible with pure BTF or would require CTF. (Other things
|
||||
may nonetheless require CTF, in particular, compression.) */
|
||||
|
||||
extern int ctf_link_output_is_btf (ctf_dict_t *);
|
||||
|
||||
/* Return the serialized form of this ctf_linked dict as a new
|
||||
dynamically-allocated string, compressed if size over THRESHOLD.
|
||||
|
||||
May be a CTF dict or a CTF archive (this library mostly papers over the
|
||||
differences so you can open both the same way, treat both as ctf_archive_t
|
||||
and so on). */
|
||||
and so on).
|
||||
|
||||
If IS_BTF is set on return, the output is BTF-compatible and can be stored
|
||||
in a .BTF section. */
|
||||
|
||||
extern unsigned char *ctf_link_write (ctf_dict_t *, size_t *size,
|
||||
size_t threshold);
|
||||
size_t threshold, int *is_btf);
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -793,6 +793,7 @@ extern void ctf_str_purge_refs (ctf_dict_t *fp);
|
||||
extern void ctf_str_rollback (ctf_dict_t *, ctf_snapshot_id_t);
|
||||
extern const ctf_strs_writable_t *ctf_str_write_strtab (ctf_dict_t *);
|
||||
|
||||
extern int ctf_serialize_output_format (ctf_dict_t *fp, int force_ctf);
|
||||
extern int ctf_preserialize (ctf_dict_t *fp, int force_ctf);
|
||||
extern void ctf_depreserialize (ctf_dict_t *fp);
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
const char *
|
||||
ctf_link_input_name (ctf_dict_t *fp)
|
||||
{
|
||||
if (fp->ctf_parent && fp->ctf_parent->ctf_cuname)
|
||||
return fp->ctf_parent->ctf_cuname;
|
||||
else if (fp->ctf_cuname)
|
||||
return fp->ctf_cuname;
|
||||
if (fp->ctf_parent && fp->ctf_parent->ctf_cu_name)
|
||||
return fp->ctf_parent->ctf_cu_name;
|
||||
else if (fp->ctf_cu_name)
|
||||
return fp->ctf_cu_name;
|
||||
else
|
||||
return "(unnamed)";
|
||||
}
|
||||
@@ -1501,6 +1501,11 @@ ctf_link_add_linker_symbol (ctf_dict_t *fp, ctf_link_sym_t *sym)
|
||||
if (sym->st_type != STT_OBJECT && sym->st_type != STT_FUNC)
|
||||
return 0;
|
||||
|
||||
/* If emitting BTF, there is no symtypetab so linker symbols are ignored. */
|
||||
|
||||
if (fp->ctf_serialize.cs_is_btf)
|
||||
return 0;
|
||||
|
||||
/* Add the symbol to the in-flight list. */
|
||||
|
||||
if ((cid = malloc (sizeof (ctf_in_flight_dynsym_t))) == NULL)
|
||||
@@ -1533,6 +1538,11 @@ ctf_link_shuffle_syms (ctf_dict_t *fp)
|
||||
if (fp->ctf_stypes > 0)
|
||||
return ctf_set_errno (fp, ECTF_RDONLY);
|
||||
|
||||
/* If emitting BTF, there is no symtypetab to shuffle. */
|
||||
|
||||
if (fp->ctf_serialize.cs_is_btf)
|
||||
return 0;
|
||||
|
||||
if (!fp->ctf_dynsyms)
|
||||
{
|
||||
fp->ctf_dynsyms = ctf_dynhash_create (ctf_hash_string,
|
||||
@@ -1732,6 +1742,28 @@ ctf_elf64_to_link_sym (ctf_dict_t *fp, ctf_link_sym_t *dst, const Elf64_Sym *src
|
||||
return dst;
|
||||
}
|
||||
|
||||
/* Determine whether the archive that will be built from this linked dict is compatible
|
||||
with pure BTF or would require CTF. (Other things may nonetheless require CTF, in
|
||||
particular, compression.) */
|
||||
int
|
||||
ctf_link_output_is_btf (ctf_dict_t *fp)
|
||||
{
|
||||
/* Can't call when nothing has been linked yet. */
|
||||
|
||||
if (!fp->ctf_link_outputs)
|
||||
return (ctf_set_errno (fp, EINVAL));
|
||||
|
||||
/* Cannot be BTF if child dicts are present. */
|
||||
|
||||
if (ctf_dynhash_elements (fp->ctf_link_outputs) != 0)
|
||||
return 0;
|
||||
|
||||
if (ctf_serialize_output_format (fp, 0) < 0)
|
||||
return -1; /* errno is set for us. */
|
||||
|
||||
return fp->ctf_serialize.cs_is_btf;
|
||||
}
|
||||
|
||||
typedef struct ctf_name_list_accum_cb_arg
|
||||
{
|
||||
char **names;
|
||||
@@ -1863,9 +1895,12 @@ ctf_link_warn_outdated_inputs (ctf_dict_t *fp)
|
||||
|
||||
/* Write out a CTF archive (if there are per-CU CTF files) or a CTF file
|
||||
(otherwise) into a new dynamically-allocated string, and return it.
|
||||
Members with sizes above THRESHOLD are compressed. */
|
||||
Members with sizes above THRESHOLD are compressed.
|
||||
|
||||
The optional arg IS_BTF is set to 1 if the written output is valid BTF
|
||||
(no archives, no CTF-specific types). */
|
||||
unsigned char *
|
||||
ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
|
||||
ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold, int *is_btf)
|
||||
{
|
||||
ctf_name_list_accum_cb_arg_t arg;
|
||||
char **names;
|
||||
@@ -1894,11 +1929,18 @@ ctf_link_write (ctf_dict_t *fp, size_t *size, size_t threshold)
|
||||
}
|
||||
}
|
||||
|
||||
if (is_btf)
|
||||
*is_btf = 0;
|
||||
|
||||
/* No extra outputs? Just write a simple ctf_dict_t. */
|
||||
if (arg.i == 0)
|
||||
{
|
||||
unsigned char *ret = ctf_write_mem (fp, size, threshold);
|
||||
fp->ctf_flags &= ~LCTF_LINKING;
|
||||
|
||||
if (is_btf && fp->ctf_serialize.cs_is_btf)
|
||||
*is_btf = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ LIBCTF_2.0 {
|
||||
ctf_link;
|
||||
ctf_link_add_strtab;
|
||||
ctf_link_shuffle_syms;
|
||||
ctf_link_output_is_btf;
|
||||
ctf_link_write;
|
||||
|
||||
ctf_link_add_linker_symbol;
|
||||
|
||||
Reference in New Issue
Block a user