38alloc_lzma (
void *opaque,
size_t nmemb,
size_t size)
46free_lzma (
void *opaque,
void *ptr)
54static lzma_allocator gdb_lzma_allocator = { alloc_lzma, free_lzma, NULL };
63 asection *section =
nullptr;
66 lzma_index *index =
nullptr;
69 bfd_size_type data_start = 0;
70 bfd_size_type data_end = 0;
71 gdb::byte_vector
data;
76 lzma_index_end (index, &gdb_lzma_allocator);
79 file_ptr
read (bfd *abfd,
void *buffer, file_ptr nbytes,
80 file_ptr offset)
override;
82 int stat (
struct bfd *abfd,
struct stat *sb)
override;
88static gdb_lzma_stream *
89lzma_open (
struct bfd *nbfd, asection *section)
91 bfd_size_type
size, offset;
92 lzma_stream_flags options;
93 gdb_byte footer[LZMA_STREAM_HEADER_SIZE];
95 uint64_t memlimit = UINT64_MAX;
96 struct gdb_lzma_stream *lstream;
99 size = bfd_section_size (section);
100 offset = section->filepos +
size - LZMA_STREAM_HEADER_SIZE;
101 if (
size < LZMA_STREAM_HEADER_SIZE
102 || bfd_seek (section->owner, offset,
SEEK_SET) != 0
103 || bfd_read (footer, LZMA_STREAM_HEADER_SIZE, section->owner)
104 != LZMA_STREAM_HEADER_SIZE
105 || lzma_stream_footer_decode (&options, footer) != LZMA_OK
106 || offset < options.backward_size)
108 bfd_set_error (bfd_error_wrong_format);
112 offset -= options.backward_size;
113 gdb::byte_vector indexdata (options.backward_size);
116 if (bfd_seek (section->owner, offset,
SEEK_SET) != 0
117 || bfd_read (indexdata.data (), options.backward_size, section->owner)
118 != options.backward_size
119 || lzma_index_buffer_decode (&index, &memlimit, &gdb_lzma_allocator,
120 indexdata.data (), &pos,
121 options.backward_size)
123 || lzma_index_size (index) != options.backward_size)
125 bfd_set_error (bfd_error_wrong_format);
129 lstream =
new struct gdb_lzma_stream;
130 lstream->section = section;
131 lstream->index = index;
140gdb_lzma_stream::read (
struct bfd *nbfd,
void *buf, file_ptr nbytes,
143 bfd_size_type chunk_size;
144 lzma_index_iter iter;
145 file_ptr block_offset;
146 lzma_filter filters[LZMA_FILTERS_MAX + 1];
148 size_t compressed_pos, uncompressed_pos;
154 if (
data.empty () || data_start > offset || offset >= data_end)
156 lzma_index_iter_init (&iter, index);
157 if (lzma_index_iter_locate (&iter, offset))
160 gdb::byte_vector compressed (iter.block.total_size);
161 block_offset = section->filepos + iter.block.compressed_file_offset;
162 if (bfd_seek (section->owner, block_offset,
SEEK_SET) != 0
163 || bfd_read (compressed.data (), iter.block.total_size,
164 section->owner) != iter.block.total_size)
167 gdb::byte_vector uncompressed (iter.block.uncompressed_size);
170 block.filters = filters;
171 block.header_size = lzma_block_header_size_decode (compressed[0]);
172 if (lzma_block_header_decode (&
block, &gdb_lzma_allocator,
177 compressed_pos =
block.header_size;
178 uncompressed_pos = 0;
179 if (lzma_block_buffer_decode (&
block, &gdb_lzma_allocator,
180 compressed.data (), &compressed_pos,
181 iter.block.total_size,
182 uncompressed.data (),
184 iter.block.uncompressed_size)
188 data = std::move (uncompressed);
189 data_start = iter.block.uncompressed_file_offset;
190 data_end = (iter.block.uncompressed_file_offset
191 + iter.block.uncompressed_size);
194 chunk_size = std::min (nbytes, (file_ptr) data_end - offset);
195 memcpy (buf,
data.data () + offset - data_start, chunk_size);
196 buf = (gdb_byte *) buf + chunk_size;
197 offset += chunk_size;
198 nbytes -= chunk_size;
209gdb_lzma_stream::stat (
struct bfd *abfd,
struct stat *sb)
211 memset (sb, 0,
sizeof (
struct stat));
212 sb->st_size = lzma_index_uncompressed_size (index);
234 section = bfd_get_section_by_name (
objfile->
obfd.get (),
".gnu_debugdata");
240 if (shared !=
nullptr)
243 std::string filename = string_printf (_(
".gnu_debugdata for %s"),
246 auto open = [&] (bfd *nbfd) -> gdb_lzma_stream *
248 return lzma_open (nbfd, section);
255 if (!bfd_check_format (abfd.get (), bfd_object))
257 warning (_(
"Cannot parse .gnu_debugdata section; not a BFD object"));
261 gnu_debug_key.emplace (
objfile->
obfd.get (), abfd);
264 warning (_(
"Cannot parse .gnu_debugdata section; LZMA support was "
265 "disabled at compile time"));
virtual int stat(struct bfd *abfd, struct stat *sb)=0
virtual file_ptr read(bfd *abfd, void *buffer, file_ptr nbytes, file_ptr offset)=0
ssize_t read(int fd, void *buf, size_t count)
gdb_bfd_ref_ptr gdb_bfd_openr_iovec(const char *filename, const char *target, gdb_iovec_opener_ftype open_fn)
gdb::ref_ptr< struct bfd, gdb_bfd_ref_policy > gdb_bfd_ref_ptr
gdb_bfd_ref_ptr find_separate_debug_file_in_section(struct objfile *objfile)
const char * objfile_name(const struct objfile *objfile)