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
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. */
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
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)";
}
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)
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,
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;
/* 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;
}
}
+ 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;
}