• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisión2f6ecaed667d1597c67991224948e0a3da427cc9 (tree)
Tiempo2020-06-26 23:56:39
AutorNick Alcock <nick.alcock@orac...>
CommiterNick Alcock

Log Message

libctf, binutils: support CTF archives like objdump

objdump and readelf have one major CTF-related behavioural difference:
objdump can read .ctf sections that contain CTF archives and extract and
dump their members, while readelf cannot. Since the linker often emits
CTF archives, this means that readelf intermittently and (from the
user's perspective) randomly fails to read CTF in files that ld emits,
with a confusing error message wrongly claiming that the CTF content is
corrupt. This is purely because the archive-opening code in libctf was
needlessly tangled up with the BFD code, so readelf couldn't use it.

Here, we disentangle it, moving ctf_new_archive_internal from
ctf-open-bfd.c into ctf-archive.c and merging it with the helper
function in ctf-archive.c it was already using. We add a new public API
function ctf_arc_bufopen, that looks very like ctf_bufopen but returns
an archive given suitable section data rather than a ctf_file_t: the
archive is a ctf_archive_t, so it can be called on raw CTF dictionaries
(with no archive present) and will return a single-member synthetic
"archive".

There is a tiny lifetime tweak here: before now, the archive code could
assume that the symbol section in the ctf_archive_internal wrapper
structure was always owned by BFD if it was present and should always be
freed: now, the caller can pass one in via ctf_arc_bufopen, wihch has
the usual lifetime rules for such sections (caller frees): so we add an
extra field to track whether this is an internal call from ctf-open-bfd,
in which case we still free the symbol section.

include/
* ctf-api.h (ctf_arc_bufopen): New.
libctf/
* ctf-impl.h (ctf_new_archive_internal): Declare.
(ctf_arc_bufopen): Remove.
(ctf_archive_internal) <ctfi_free_symsect>: New.
* ctf-archive.c (ctf_arc_close): Use it.
(ctf_arc_bufopen): Fuse into...
(ctf_new_archive_internal): ... this, moved across from...
* ctf-open-bfd.c: ... here.
(ctf_bfdopen_ctfsect): Use ctf_arc_bufopen.
* libctf.ver: Add it.
binutils/
* readelf.c (dump_section_as_ctf): Support .ctf archives using
ctf_arc_bufopen. Automatically load the .ctf member of such
archives as the parent of all other members, unless specifically
overridden via --ctf-parent. Split out dumping code into...
(dump_ctf_archive_member): ... here, as in objdump, and call
it once per archive member.
(dump_ctf_indent_lines): Code style fix.

Cambiar Resumen

Diferencia incremental

--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,5 +1,15 @@
11 2020-06-26 Nick Alcock <nick.alcock@oracle.com>
22
3+ * readelf.c (dump_section_as_ctf): Support .ctf archives using
4+ ctf_arc_bufopen. Automatically load the .ctf member of such
5+ archives as the parent of all other members, unless specifically
6+ overridden via --ctf-parent. Split out dumping code into...
7+ (dump_ctf_archive_member): ... here, as in objdump, and call
8+ it once per archive member.
9+ (dump_ctf_indent_lines): Code style fix.
10+
11+2020-06-26 Nick Alcock <nick.alcock@oracle.com>
12+
313 * configure.ac [--enable-libctf]: New, default yes.
414 Set ENABLE_LIBCTF accordingly.
515 * Makefile.am [!ENABLE_LIBCTF]: Empty LIBCTF and LIBCTF_NOBFD.
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14151,8 +14151,9 @@ shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
1415114151 it is passed, or a pointer to newly-allocated storage, in which case
1415214152 dump_ctf() will free it when it no longer needs it. */
1415314153
14154-static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14155- char *s, void *arg)
14154+static char *
14155+dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14156+ char *s, void *arg)
1415614157 {
1415714158 const char *blanks = arg;
1415814159 char *new_s;
@@ -14162,6 +14163,55 @@ static char *dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
1416214163 return new_s;
1416314164 }
1416414165
14166+/* Dump one CTF archive member. */
14167+
14168+static int
14169+dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14170+{
14171+ ctf_file_t *parent = (ctf_file_t *) arg;
14172+ const char *things[] = {"Header", "Labels", "Data objects",
14173+ "Function objects", "Variables", "Types", "Strings",
14174+ ""};
14175+ const char **thing;
14176+ size_t i;
14177+
14178+ /* Only print out the name of non-default-named archive members.
14179+ The name .ctf appears everywhere, even for things that aren't
14180+ really archives, so printing it out is liable to be confusing.
14181+
14182+ The parent, if there is one, is the default-owned archive member:
14183+ avoid importing it into itself. (This does no harm, but looks
14184+ confusing.) */
14185+
14186+ if (strcmp (name, ".ctf") != 0)
14187+ {
14188+ printf (_("\nCTF archive member: %s:\n"), name);
14189+ ctf_import (ctf, parent);
14190+ }
14191+
14192+ for (i = 0, thing = things; *thing[0]; thing++, i++)
14193+ {
14194+ ctf_dump_state_t *s = NULL;
14195+ char *item;
14196+
14197+ printf ("\n %s:\n", *thing);
14198+ while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14199+ (void *) " ")) != NULL)
14200+ {
14201+ printf ("%s\n", item);
14202+ free (item);
14203+ }
14204+
14205+ if (ctf_errno (ctf))
14206+ {
14207+ error (_("Iteration failed: %s, %s\n"), *thing,
14208+ ctf_errmsg (ctf_errno (ctf)));
14209+ return 1;
14210+ }
14211+ }
14212+ return 0;
14213+}
14214+
1416514215 static bfd_boolean
1416614216 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
1416714217 {
@@ -14175,16 +14225,12 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
1417514225 ctf_sect_t ctfsect, symsect, strsect, parentsect;
1417614226 ctf_sect_t * symsectp = NULL;
1417714227 ctf_sect_t * strsectp = NULL;
14178- ctf_file_t * ctf = NULL;
14179- ctf_file_t * parent = NULL;
14228+ ctf_archive_t * ctfa = NULL;
14229+ ctf_archive_t * parenta = NULL, *lookparent;
14230+ ctf_file_t * parent = NULL;
1418014231
14181- const char *things[] = {"Header", "Labels", "Data objects",
14182- "Function objects", "Variables", "Types", "Strings",
14183- ""};
14184- const char **thing;
1418514232 int err;
1418614233 bfd_boolean ret = FALSE;
14187- size_t i;
1418814234
1418914235 shdr_to_ctf_sect (&ctfsect, section, filedata);
1419014236 data = get_section_contents (section, filedata);
@@ -14243,9 +14289,11 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
1424314289 parentsect.cts_data = parentdata;
1424414290 }
1424514291
14246- /* Load the CTF file and dump it. */
14292+ /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14293+ libctf papers over the difference, so we can pretend it is always an
14294+ archive. Possibly open the parent as well, if one was specified. */
1424714295
14248- if ((ctf = ctf_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
14296+ if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
1424914297 {
1425014298 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
1425114299 goto fail;
@@ -14253,13 +14301,24 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
1425314301
1425414302 if (parentdata)
1425514303 {
14256- if ((parent = ctf_bufopen (&parentsect, symsectp, strsectp, &err)) == NULL)
14304+ if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14305+ &err)) == NULL)
1425714306 {
1425814307 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
1425914308 goto fail;
1426014309 }
14310+ lookparent = parenta;
14311+ }
14312+ else
14313+ lookparent = ctfa;
1426114314
14262- ctf_import (ctf, parent);
14315+ /* Assume that the applicable parent archive member is the default one.
14316+ (This is what all known implementations are expected to do, if they
14317+ put CTFs and their parents in archives together.) */
14318+ if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14319+ {
14320+ error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14321+ goto fail;
1426314322 }
1426414323
1426514324 ret = TRUE;
@@ -14267,30 +14326,13 @@ dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
1426714326 printf (_("\nDump of CTF section '%s':\n"),
1426814327 printable_section_name (filedata, section));
1426914328
14270- for (i = 0, thing = things; *thing[0]; thing++, i++)
14271- {
14272- ctf_dump_state_t *s = NULL;
14273- char *item;
14274-
14275- printf ("\n %s:\n", *thing);
14276- while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14277- (void *) " ")) != NULL)
14278- {
14279- printf ("%s\n", item);
14280- free (item);
14281- }
14282-
14283- if (ctf_errno (ctf))
14284- {
14285- error (_("Iteration failed: %s, %s\n"), *thing,
14286- ctf_errmsg (ctf_errno (ctf)));
14287- ret = FALSE;
14288- }
14289- }
14329+ if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14330+ ret = FALSE;
1429014331
1429114332 fail:
14292- ctf_file_close (ctf);
1429314333 ctf_file_close (parent);
14334+ ctf_close (ctfa);
14335+ ctf_close (parenta);
1429414336 free (parentdata);
1429514337 free (data);
1429614338 free (symdata);
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
1+2020-06-26 Nick Alcock <nick.alcock@oracle.com>
2+
3+ * ctf-api.h (ctf_arc_bufopen): New.
4+
15 2020-06-26 Pat Bernardi <bernardi@adacore.com>
26
37 * elf/m68k.h: Add enum for GNU object attribute with floating point
--- a/include/ctf-api.h
+++ b/include/ctf-api.h
@@ -263,6 +263,10 @@ extern void ctf_close (ctf_archive_t *);
263263 extern ctf_sect_t ctf_getdatasect (const ctf_file_t *);
264264 extern ctf_archive_t *ctf_get_arc (const ctf_file_t *);
265265 extern ctf_archive_t *ctf_arc_open (const char *, int *);
266+extern ctf_archive_t *ctf_arc_bufopen (const ctf_sect_t *,
267+ const ctf_sect_t *,
268+ const ctf_sect_t *,
269+ int *);
266270 extern void ctf_arc_close (ctf_archive_t *);
267271 extern ctf_file_t *ctf_arc_open_by_name (const ctf_archive_t *,
268272 const char *, int *);
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,17 @@
11 2020-06-26 Nick Alcock <nick.alcock@oracle.com>
22
3+ * ctf-impl.h (ctf_new_archive_internal): Declare.
4+ (ctf_arc_bufopen): Remove.
5+ (ctf_archive_internal) <ctfi_free_symsect>: New.
6+ * ctf-archive.c (ctf_arc_close): Use it.
7+ (ctf_arc_bufopen): Fuse into...
8+ (ctf_new_archive_internal): ... this, moved across from...
9+ * ctf-open-bfd.c: ... here.
10+ (ctf_bfdopen_ctfsect): Use ctf_arc_bufopen.
11+ * libctf.ver: Add it.
12+
13+2020-06-26 Nick Alcock <nick.alcock@oracle.com>
14+
315 * ctf-create.c (ctf_add_forward): Intern in the right namespace.
416 (ctf_dtd_delete): Remove correspondingly.
517 (ctf_rollback): Likewise.
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -343,21 +343,71 @@ search_modent_by_name (const void *key, const void *ent)
343343 return strcmp (k, &search_nametbl[le64toh (v->name_offset)]);
344344 }
345345
346-/* A trivial wrapper: open a CTF archive, from data in a buffer (which the
347- caller must preserve until ctf_arc_close() time). Returns the archive, or
348- NULL and an error in *err (if not NULL). */
349-struct ctf_archive *
350-ctf_arc_bufopen (const void *buf, size_t size _libctf_unused_, int *errp)
346+/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
347+ ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
348+ STRSECT, as needed, on close. */
349+
350+struct ctf_archive_internal *
351+ctf_new_archive_internal (int is_archive, struct ctf_archive *arc,
352+ ctf_file_t *fp, const ctf_sect_t *symsect,
353+ const ctf_sect_t *strsect,
354+ int *errp)
351355 {
352- struct ctf_archive *arc = (struct ctf_archive *) buf;
356+ struct ctf_archive_internal *arci;
353357
354- if (le64toh (arc->ctfa_magic) != CTFA_MAGIC)
358+ if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
355359 {
356- if (errp)
357- *errp = ECTF_FMT;
358- return NULL;
360+ if (is_archive)
361+ ctf_arc_close_internal (arc);
362+ else
363+ ctf_file_close (fp);
364+ return (ctf_set_open_errno (errp, errno));
359365 }
360- return arc;
366+ arci->ctfi_is_archive = is_archive;
367+ if (is_archive)
368+ arci->ctfi_archive = arc;
369+ else
370+ arci->ctfi_file = fp;
371+ if (symsect)
372+ memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
373+ if (strsect)
374+ memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
375+ arci->ctfi_free_symsect = 0;
376+
377+ return arci;
378+}
379+
380+/* Open a CTF archive or dictionary from data in a buffer (which the caller must
381+ preserve until ctf_arc_close() time). Returns the archive, or NULL and an
382+ error in *err (if not NULL). */
383+ctf_archive_t *
384+ctf_arc_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
385+ const ctf_sect_t *strsect, int *errp)
386+{
387+ struct ctf_archive *arc = NULL;
388+ int is_archive;
389+ ctf_file_t *fp = NULL;
390+
391+ if (ctfsect->cts_size > sizeof (uint64_t) &&
392+ ((*(uint64_t *) ctfsect->cts_data) == CTFA_MAGIC))
393+ {
394+ /* The archive is mmappable, so this operation is trivial. */
395+
396+ is_archive = 1;
397+ arc = (struct ctf_archive *) ctfsect->cts_data;
398+ }
399+ else
400+ {
401+ is_archive = 0;
402+ if ((fp = ctf_bufopen (ctfsect, symsect, strsect, errp)) == NULL)
403+ {
404+ ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n",
405+ ctf_errmsg (*errp));
406+ return NULL;
407+ }
408+ }
409+ return ctf_new_archive_internal (is_archive, arc, fp, symsect, strsect,
410+ errp);
361411 }
362412
363413 /* Open a CTF archive. Returns the archive, or NULL and an error in *err (if
@@ -436,8 +486,8 @@ ctf_arc_close (ctf_archive_t *arc)
436486 ctf_arc_close_internal (arc->ctfi_archive);
437487 else
438488 ctf_file_close (arc->ctfi_file);
439- free ((void *) arc->ctfi_symsect.cts_data);
440- /* Do not free the ctfi_strsect: it is bound to the bfd. */
489+ if (arc->ctfi_free_symsect)
490+ free ((void *) arc->ctfi_symsect.cts_data);
441491 free (arc->ctfi_data);
442492 if (arc->ctfi_bfd_close)
443493 arc->ctfi_bfd_close (arc);
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -309,6 +309,7 @@ struct ctf_archive_internal
309309 struct ctf_archive *ctfi_archive;
310310 ctf_sect_t ctfi_symsect;
311311 ctf_sect_t ctfi_strsect;
312+ int ctfi_free_symsect;
312313 void *ctfi_data;
313314 bfd *ctfi_abfd; /* Optional source of section data. */
314315 void (*ctfi_bfd_close) (struct ctf_archive_internal *);
@@ -435,8 +436,11 @@ extern void ctf_str_rollback (ctf_file_t *, ctf_snapshot_id_t);
435436 extern void ctf_str_purge_refs (ctf_file_t *);
436437 extern ctf_strs_writable_t ctf_str_write_strtab (ctf_file_t *);
437438
439+extern struct ctf_archive_internal *ctf_new_archive_internal
440+ (int is_archive, struct ctf_archive *arc,
441+ ctf_file_t *fp, const ctf_sect_t *symsect,
442+ const ctf_sect_t *strsect, int *errp);
438443 extern struct ctf_archive *ctf_arc_open_internal (const char *, int *);
439-extern struct ctf_archive *ctf_arc_bufopen (const void *, size_t, int *);
440444 extern void ctf_arc_close_internal (struct ctf_archive *);
441445 extern void *ctf_set_open_errno (int *, int);
442446 extern unsigned long ctf_set_errno (ctf_file_t *, int);
--- a/libctf/ctf-open-bfd.c
+++ b/libctf/ctf-open-bfd.c
@@ -32,40 +32,6 @@
3232
3333 #include "elf-bfd.h"
3434
35-/* Make a new struct ctf_archive_internal wrapper for a ctf_archive or a
36- ctf_file. Closes ARC and/or FP on error. Arrange to free the SYMSECT or
37- STRSECT, as needed, on close (though the STRSECT interior is bound to the bfd
38- * and is not actually freed by this machinery). */
39-
40-static struct ctf_archive_internal *
41-ctf_new_archive_internal (int is_archive, struct ctf_archive *arc,
42- ctf_file_t *fp, const ctf_sect_t *symsect,
43- const ctf_sect_t *strsect,
44- int *errp)
45-{
46- struct ctf_archive_internal *arci;
47-
48- if ((arci = calloc (1, sizeof (struct ctf_archive_internal))) == NULL)
49- {
50- if (is_archive)
51- ctf_arc_close_internal (arc);
52- else
53- ctf_file_close (fp);
54- return (ctf_set_open_errno (errp, errno));
55- }
56- arci->ctfi_is_archive = is_archive;
57- if (is_archive)
58- arci->ctfi_archive = arc;
59- else
60- arci->ctfi_file = fp;
61- if (symsect)
62- memcpy (&arci->ctfi_symsect, symsect, sizeof (struct ctf_sect));
63- if (strsect)
64- memcpy (&arci->ctfi_strsect, strsect, sizeof (struct ctf_sect));
65-
66- return arci;
67-}
68-
6935 /* Free the BFD bits of a CTF file on ctf_arc_close(). */
7036
7137 static void
@@ -107,6 +73,7 @@ ctf_bfdopen (struct bfd *abfd, int *errp)
10773
10874 if ((arc = ctf_bfdopen_ctfsect (abfd, &ctfsect, errp)) != NULL)
10975 {
76+ /* This frees the cts_data later. */
11077 arc->ctfi_data = (void *) ctfsect.cts_data;
11178 return arc;
11279 }
@@ -116,20 +83,16 @@ ctf_bfdopen (struct bfd *abfd, int *errp)
11683 }
11784
11885 /* Open a CTF file given the specified BFD and CTF section (which may contain a
119- CTF archive or a file). Takes ownership of the ctfsect, and frees it
120- later. */
86+ CTF archive or a file). */
12187
12288 ctf_archive_t *
12389 ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
12490 const ctf_sect_t *ctfsect, int *errp)
12591 {
126- struct ctf_archive *arc = NULL;
12792 ctf_archive_t *arci;
128- ctf_file_t *fp = NULL;
12993 ctf_sect_t *symsectp = NULL;
13094 ctf_sect_t *strsectp = NULL;
13195 const char *bfderrstr = NULL;
132- int is_archive;
13396
13497 #ifdef HAVE_BFD_ELF
13598 ctf_sect_t symsect, strsect;
@@ -192,30 +155,13 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
192155 }
193156 #endif
194157
195- if (ctfsect->cts_size > sizeof (uint64_t) &&
196- ((*(uint64_t *) ctfsect->cts_data) == CTFA_MAGIC))
197- {
198- is_archive = 1;
199- if ((arc = ctf_arc_bufopen ((void *) ctfsect->cts_data,
200- ctfsect->cts_size, errp)) == NULL)
201- goto err_free_str;
202- }
203- else
158+ arci = ctf_arc_bufopen (ctfsect, symsectp, strsectp, errp);
159+ if (arci)
204160 {
205- is_archive = 0;
206- if ((fp = ctf_bufopen (ctfsect, symsectp, strsectp, errp)) == NULL)
207- {
208- ctf_dprintf ("ctf_internal_open(): cannot open CTF: %s\n",
209- ctf_errmsg (*errp));
210- goto err_free_str;
211- }
161+ /* Request freeing of the symsect. */
162+ arci->ctfi_free_symsect = 1;
163+ return arci;
212164 }
213- arci = ctf_new_archive_internal (is_archive, arc, fp, symsectp, strsectp,
214- errp);
215-
216- if (arci)
217- return arci;
218- err_free_str: ;
219165 #ifdef HAVE_BFD_ELF
220166 err_free_sym:
221167 free (symtab);
--- a/libctf/libctf.ver
+++ b/libctf/libctf.ver
@@ -128,6 +128,7 @@ LIBCTF_1.0 {
128128 ctf_arc_write;
129129 ctf_arc_write_fd;
130130 ctf_arc_open;
131+ ctf_arc_bufopen;
131132 ctf_arc_close;
132133 ctf_arc_open_by_name;
133134 ctf_arc_open_by_name_sections;