+ ctf_str_atom_t *atom;
+ if (!str)
+ return 0;
+
+ atom = ctf_str_add_ref_internal (fp, str, FALSE, TRUE, 0);
+ if (!atom)
+ return 0;
+
+ return atom->csa_offset;
+}
+
+/* Like ctf_str_add(), but additionally augment the atom's refs list with the
+ passed-in ref, whether or not the string is already present. There is no
+ attempt to deduplicate the refs list (but duplicates are harmless). */
+uint32_t
+ctf_str_add_ref (ctf_file_t *fp, const char *str, uint32_t *ref)
+{
+ ctf_str_atom_t *atom;
+ if (!str)
+ return 0;
+
+ atom = ctf_str_add_ref_internal (fp, str, TRUE, TRUE, ref);
+ if (!atom)
+ return 0;
+
+ return atom->csa_offset;
+}
+
+/* Add an external strtab reference at OFFSET. Returns zero if the addition
+ failed, nonzero otherwise. */
+int
+ctf_str_add_external (ctf_file_t *fp, const char *str, uint32_t offset)
+{
+ ctf_str_atom_t *atom;
+ if (!str)
+ return 0;
+
+ atom = ctf_str_add_ref_internal (fp, str, FALSE, FALSE, 0);
+ if (!atom)
+ return 0;
+
+ atom->csa_external_offset = CTF_SET_STID (offset, CTF_STRTAB_1);
+ return 1;
+}
+
+/* Remove a single ref. */
+void
+ctf_str_remove_ref (ctf_file_t *fp, const char *str, uint32_t *ref)
+{
+ ctf_str_atom_ref_t *aref, *anext;
+ ctf_str_atom_t *atom = NULL;
+
+ atom = ctf_dynhash_lookup (fp->ctf_str_atoms, str);
+ if (!atom)
+ return;
+
+ for (aref = ctf_list_next (&atom->csa_refs); aref != NULL; aref = anext)
+ {
+ anext = ctf_list_next (aref);
+ if (aref->caf_ref == ref)
+ {
+ ctf_list_delete (&atom->csa_refs, aref);
+ free (aref);
+ }
+ }