• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

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

修訂1ba0a754ad8c035eac5f7476002ca32b6fd560ec (tree)
時間2019-09-23 22:12:54
作者Nick Alcock <nick.alcock@orac...>
CommiterNick Alcock

Log Message

libctf: write CTF files to memory, and CTF archives to fds

Before now, we've been able to write CTF files to gzFile descriptors or
fds, and CTF archives to named files only.

Make this a bit less irregular by allowing CTF archives to be written
to fds with the new function ctf_arc_write_fd: also allow CTF
files to be written to a new memory buffer via ctf_write_mem.

(It would be nice to complete things by adding a new function to write
CTF archives to memory, but this is too difficult to do given the short
time the linker is expected to be writing them out: we will transition
to a better format in format v4, though we will always support reading
CTF archives that are stored in .ctf sections.)

include/
* ctf-api.h (ctf_arc_write_fd): New.
(ctf_write_mem): Likewise.
(ctf_gzwrite): Spacing fix.

libctf/
* ctf-archive.c (ctf_arc_write): Split off, and reimplement in terms
of...
(ctf_arc_write_fd): ... this new function.
* ctf-create.c (ctf_write_mem): New.

Change Summary

差異

--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,11 @@
11 2019-07-13 Nick Alcock <nick.alcock@oracle.com>
22
3+ * ctf-api.h (ctf_arc_write_fd): New.
4+ (ctf_write_mem): Likewise.
5+ (ctf_gzwrite): Spacing fix.
6+
7+2019-07-13 Nick Alcock <nick.alcock@oracle.com>
8+
39 * ctf.h (CTF_SET_STID): New.
410
511 2019-07-13 Nick Alcock <nick.alcock@oracle.com>
--- a/include/ctf-api.h
+++ b/include/ctf-api.h
@@ -258,6 +258,8 @@ extern void ctf_file_close (ctf_file_t *);
258258
259259 extern int ctf_arc_write (const char *, ctf_file_t **, size_t,
260260 const char **, size_t);
261+extern int ctf_arc_write_fd (int, ctf_file_t **, size_t, const char **,
262+ size_t);
261263
262264 extern const char *ctf_cuname (ctf_file_t *);
263265 extern void ctf_cuname_set (ctf_file_t *, const char *);
@@ -379,8 +381,9 @@ extern ctf_snapshot_id_t ctf_snapshot (ctf_file_t *);
379381 extern int ctf_rollback (ctf_file_t *, ctf_snapshot_id_t);
380382 extern int ctf_discard (ctf_file_t *);
381383 extern int ctf_write (ctf_file_t *, int);
382-extern int ctf_gzwrite (ctf_file_t * fp, gzFile fd);
384+extern int ctf_gzwrite (ctf_file_t *fp, gzFile fd);
383385 extern int ctf_compress_write (ctf_file_t * fp, int fd);
386+extern unsigned char *ctf_write_mem (ctf_file_t *, size_t *, size_t threshold);
384387
385388 extern void ctf_setdebug (int debug);
386389 extern int ctf_getdebug (void);
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,12 @@
11 2019-07-13 Nick Alcock <nick.alcock@oracle.com>
22
3+ * ctf-archive.c (ctf_arc_write): Split off, and reimplement in terms
4+ of...
5+ (ctf_arc_write_fd): ... this new function.
6+ * ctf-create.c (ctf_write_mem): New.
7+
8+2019-07-13 Nick Alcock <nick.alcock@oracle.com>
9+
310 * ctf-impl.h (ctf_str_atom_t) <csa_offset>: New field.
411 (ctf_file_t) <ctf_syn_ext_strtab>: Likewise.
512 (ctf_str_add_ref): Name the last arg.
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -47,17 +47,17 @@ static int arc_mmap_unmap (void *header, size_t headersz, const char **errmsg);
4747 /* bsearch() internal state. */
4848 static __thread char *search_nametbl;
4949
50-/* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
51- the names are passed in the names array, which must have CTF_FILES entries.
50+/* Write out a CTF archive to the start of the file referenced by the passed-in
51+ fd. The entries in CTF_FILES are referenced by name: the names are passed in
52+ the names array, which must have CTF_FILES entries.
5253
5354 Returns 0 on success, or an errno, or an ECTF_* value. */
5455 int
55-ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
56- const char **names, size_t threshold)
56+ctf_arc_write_fd (int fd, ctf_file_t **ctf_files, size_t ctf_file_cnt,
57+ const char **names, size_t threshold)
5758 {
5859 const char *errmsg;
5960 struct ctf_archive *archdr;
60- int fd;
6161 size_t i;
6262 char dummy = 0;
6363 size_t headersz;
@@ -68,15 +68,9 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
6868 off_t nameoffs;
6969 struct ctf_archive_modent *modent;
7070
71- ctf_dprintf ("Writing archive %s with %lu files\n", file,
71+ ctf_dprintf ("Writing CTF archive with %lu files\n",
7272 (unsigned long) ctf_file_cnt);
7373
74- if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
75- {
76- errmsg = "ctf_arc_write(): cannot create %s: %s\n";
77- goto err;
78- }
79-
8074 /* Figure out the size of the mmap()ed header, including the
8175 ctf_archive_modent array. We assume that all of this needs no
8276 padding: a likely assumption, given that it's all made up of
@@ -91,20 +85,20 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
9185 ctf_startoffs = headersz;
9286 if (lseek (fd, ctf_startoffs - 1, SEEK_SET) < 0)
9387 {
94- errmsg = "ctf_arc_write(): cannot extend file while writing %s: %s\n";
95- goto err_close;
88+ errmsg = "ctf_arc_write(): cannot extend file while writing: %s\n";
89+ goto err;
9690 }
9791
9892 if (write (fd, &dummy, 1) < 0)
9993 {
100- errmsg = "ctf_arc_write(): cannot extend file while writing %s: %s\n";
101- goto err_close;
94+ errmsg = "ctf_arc_write(): cannot extend file while writing: %s\n";
95+ goto err;
10296 }
10397
10498 if ((archdr = arc_mmap_header (fd, headersz)) == NULL)
10599 {
106- errmsg = "ctf_arc_write(): Cannot mmap() %s: %s\n";
107- goto err_close;
100+ errmsg = "ctf_arc_write(): Cannot mmap(): %s\n";
101+ goto err;
108102 }
109103
110104 /* Fill in everything we can, which is everything other than the name
@@ -137,7 +131,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
137131 nametbl = malloc (namesz);
138132 if (nametbl == NULL)
139133 {
140- errmsg = "Error writing named CTF to %s: %s\n";
134+ errmsg = "Error writing named CTF to archive: %s\n";
141135 goto err_unmap;
142136 }
143137
@@ -154,12 +148,12 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
154148 if ((off < 0) && (off > -ECTF_BASE))
155149 {
156150 errmsg = "ctf_arc_write(): Cannot determine file "
157- "position while writing %s: %s";
151+ "position while writing to archive: %s";
158152 goto err_free;
159153 }
160154 if (off < 0)
161155 {
162- errmsg = "ctf_arc_write(): Cannot write CTF file to %s: %s\n";
156+ errmsg = "ctf_arc_write(): Cannot write CTF file to archive: %s\n";
163157 errno = off * -1;
164158 goto err_free;
165159 }
@@ -181,7 +175,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
181175 if ((nameoffs = lseek (fd, 0, SEEK_CUR)) < 0)
182176 {
183177 errmsg = "ctf_arc_write(): Cannot get current file position "
184- "in %s: %s\n";
178+ "in archive: %s\n";
185179 goto err_free;
186180 }
187181 archdr->ctfa_names = htole64 (nameoffs);
@@ -191,7 +185,7 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
191185 ssize_t len;
192186 if ((len = write (fd, np, namesz)) < 0)
193187 {
194- errmsg = "ctf_arc_write(): Cannot write name table in %s: %s\n";
188+ errmsg = "ctf_arc_write(): Cannot write name table to archive: %s\n";
195189 goto err_free;
196190 }
197191 namesz -= len;
@@ -202,29 +196,64 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
202196 if (arc_mmap_writeout (fd, archdr, headersz, &errmsg) < 0)
203197 goto err_unmap;
204198 if (arc_mmap_unmap (archdr, headersz, &errmsg) < 0)
205- goto err_unlink;
206- if (close (fd) < 0)
207- {
208- errmsg = "ctf_arc_write(): Cannot close after writing to %s: %s\n";
209- goto err_unlink;
210- }
211-
199+ goto err;
212200 return 0;
213201
214202 err_free:
215203 free (nametbl);
216204 err_unmap:
217205 arc_mmap_unmap (archdr, headersz, NULL);
218-err_close:
219- close (fd);
220-err_unlink:
221- unlink (file);
222206 err:
223- ctf_dprintf (errmsg, file, errno < ECTF_BASE ? strerror (errno) :
207+ ctf_dprintf (errmsg, errno < ECTF_BASE ? strerror (errno) :
224208 ctf_errmsg (errno));
225209 return errno;
226210 }
227211
212+/* Write out a CTF archive. The entries in CTF_FILES are referenced by name:
213+ the names are passed in the names array, which must have CTF_FILES entries.
214+
215+ If the filename is NULL, create a temporary file and return a pointer to it.
216+
217+ Returns 0 on success, or an errno, or an ECTF_* value. */
218+int
219+ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
220+ const char **names, size_t threshold)
221+{
222+ int err;
223+ int fd;
224+
225+ if ((fd = open (file, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0666)) < 0)
226+ {
227+ ctf_dprintf ("ctf_arc_write(): cannot create %s: %s\n", file,
228+ strerror (errno));
229+ return errno;
230+ }
231+
232+ err = ctf_arc_write_fd (fd, ctf_files, ctf_file_cnt, names, threshold);
233+ if (err)
234+ goto err;
235+
236+ if ((err = close (fd)) < 0)
237+ {
238+ ctf_dprintf ("ctf_arc_write(): Cannot close after writing to archive: "
239+ "%s\n", strerror (errno));
240+ goto err_close;
241+ }
242+
243+ err:
244+ close (fd);
245+ if (err < 0)
246+ unlink (file);
247+
248+ return err;
249+
250+ err_close:
251+ if (err < 0)
252+ unlink (file);
253+
254+ return err;
255+}
256+
228257 /* Write one CTF file out. Return the file position of the written file (or
229258 rather, of the file-size uint64_t that precedes it): negative return is a
230259 negative errno or ctf_errno value. On error, the file position may no longer
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -2029,6 +2029,57 @@ ret:
20292029 return err;
20302030 }
20312031
2032+/* Optionally compress the specified CTF data stream and return it as a new
2033+ dynamically-allocated string. */
2034+unsigned char *
2035+ctf_write_mem (ctf_file_t *fp, size_t *size, size_t threshold)
2036+{
2037+ unsigned char *buf;
2038+ unsigned char *bp;
2039+ ctf_header_t *hp;
2040+ ssize_t header_len = sizeof (ctf_header_t);
2041+ ssize_t compress_len;
2042+ size_t max_compress_len = compressBound (fp->ctf_size);
2043+ int rc;
2044+
2045+ if (fp->ctf_size < threshold)
2046+ max_compress_len = fp->ctf_size;
2047+ if ((buf = malloc (max_compress_len
2048+ + sizeof (struct ctf_header))) == NULL)
2049+ {
2050+ ctf_set_errno (fp, ENOMEM);
2051+ return NULL;
2052+ }
2053+
2054+ hp = (ctf_header_t *) buf;
2055+ memcpy (hp, fp->ctf_header, header_len);
2056+ bp = buf + sizeof (struct ctf_header);
2057+ *size = sizeof (struct ctf_header);
2058+
2059+ compress_len = max_compress_len;
2060+
2061+ if (fp->ctf_size < threshold)
2062+ {
2063+ hp->cth_flags &= ~CTF_F_COMPRESS;
2064+ memcpy (bp, fp->ctf_buf, fp->ctf_size);
2065+ *size += fp->ctf_size;
2066+ }
2067+ else
2068+ {
2069+ hp->cth_flags |= CTF_F_COMPRESS;
2070+ if ((rc = compress (bp, (uLongf *) &compress_len,
2071+ fp->ctf_buf, fp->ctf_size)) != Z_OK)
2072+ {
2073+ ctf_dprintf ("zlib deflate err: %s\n", zError (rc));
2074+ ctf_set_errno (fp, ECTF_COMPRESS);
2075+ ctf_free (buf);
2076+ return NULL;
2077+ }
2078+ *size += compress_len;
2079+ }
2080+ return buf;
2081+}
2082+
20322083 /* Write the uncompressed CTF data stream to the specified file descriptor. */
20332084 int
20342085 ctf_write (ctf_file_t *fp, int fd)