/* Get the CTF preamble from data in a buffer, which may be either an archive or
a CTF dict. If multiple dicts are present in an archive, the preamble comes
from an arbitrary dict. The preamble is a pointer into the ctfsect passed
- in. */
+ in. Returns NULL if this cannot be a CTF archive or dict at all. */
const ctf_preamble_t *
ctf_arc_bufpreamble (const ctf_sect_t *ctfsect)
{
- if (ctfsect->cts_data != NULL
- && ctfsect->cts_size >= sizeof (struct ctf_archive)
- && (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC))
+ if (ctfsect->cts_data == NULL
+ || ctfsect->cts_size < sizeof (uint64_t)
+ || (le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC
+ && ctfsect->cts_size < (sizeof (ctf_archive_t) + sizeof (uint64_t))))
+ return NULL;
+
+ if (ctfsect->cts_size >= (sizeof (struct ctf_archive) + sizeof (uint64_t))
+ && le64toh ((*(uint64_t *) ctfsect->cts_data)) == CTFA_MAGIC)
{
struct ctf_archive *arc = (struct ctf_archive *) ctfsect->cts_data;
return (const ctf_preamble_t *) ((char *) arc + le64toh (arc->ctfa_ctfs)
}
preamble = ctf_arc_bufpreamble (ctfsect);
- if (preamble->ctp_flags & CTF_F_DYNSTR)
+ if (preamble && (preamble->ctp_flags & CTF_F_DYNSTR))
{
symhdr = &elf_tdata (abfd)->dynsymtab_hdr;
strtab_name = ".dynstr";
symtab_name = ".dynsym";
}
- else
+ else /* Might not be CTF at all: ctf_arc_bufopen will fail if so. */
{
symhdr = &elf_tdata (abfd)->symtab_hdr;
strtab_name = ".strtab";