return elf;
}
-Elf *
-elf_file_init (struct elf_file *file, int fd)
-{
- Elf *elf = open_elf (fd);
- assert (elf != NULL);
- memset (file, 0, sizeof (*file));
+ Elf *
+ elf_file_init (struct elf_file *file, int fd)
+ {
+ Elf *elf = open_elf (fd);
+ assert (elf != NULL);
+ memset (file, 0, sizeof (*file));
- file->elf = elf;
- file->ebl = ebl_openbackend (elf);
+ file->elf = elf;
+ file->ebl = ebl_openbackend (elf);
- if (file->ebl == NULL
- || gelf_getehdr (elf, &file->ehdr) == NULL)
- return false;
+ if (file->ebl == NULL
+ || gelf_getehdr (elf, &file->ehdr) == NULL)
+ return false;
- file->addr_64 = file->ehdr.e_ident[EI_CLASS] == ELFCLASS64;
+ file->addr_64 = file->ehdr.e_ident[EI_CLASS] == ELFCLASS64;
- /* Taken from dwarf_begin_elf.c. */
- if ((BYTE_ORDER == LITTLE_ENDIAN
- && file->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
- || (BYTE_ORDER == BIG_ENDIAN
- && file->ehdr.e_ident[EI_DATA] == ELFDATA2LSB))
- file->other_byte_order = true;
+ /* Taken from dwarf_begin_elf.c. */
+ if ((BYTE_ORDER == LITTLE_ENDIAN
+ && file->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
+ || (BYTE_ORDER == BIG_ENDIAN
+ && file->ehdr.e_ident[EI_DATA] == ELFDATA2LSB))
+ file->other_byte_order = true;
- Elf_Scn *reloc_symtab = NULL;
+ Elf_Scn *reloc_symtab = NULL;
- secinfo_map secinfo;
+ secinfo_map secinfo;
#define SEC(n) secinfo[".debug_" #n] = secentry (sec_##n);
DEBUGINFO_SECTIONS
#undef SEC
- /* Now find all necessary debuginfo sections and associated
- relocation sections. */
-
- /* Section 0 is special, skip it. */
- REALLOC (file, sec);
- file->sec[file->size++].id = sec_invalid;
+ /* Now find all necessary debuginfo sections and associated
+ relocation sections. */
- bool check_rel = true;
-
- for (Elf_Scn *scn = NULL; (scn = elf_nextscn (elf, scn)); )
- {
+ /* Section 0 is special, skip it. */
REALLOC (file, sec);
- size_t curndx = file->size++;
- struct sec *cursec = file->sec + curndx;
-
- GElf_Shdr *shdr = gelf_getshdr (scn, &cursec->shdr);
- if (shdr == NULL)
- {
- invalid_elf:
- wr_error () << "Broken ELF." << std::endl;
- goto close_and_out;
- }
-
- const char *scnname = elf_strptr (elf, file->ehdr.e_shstrndx,
- shdr->sh_name);
- if (scnname == NULL)
- goto invalid_elf;
-
- if (!address_aligned (shdr->sh_addr, shdr->sh_addralign))
- wr_error ()
- << "Base address of section " << scnname << ", "
- << pri::addr (shdr->sh_addr) << ", should have an alignment of "
- << shdr->sh_addralign << std::endl;
-
- secentry *entry = secinfo.get (scnname);
- cursec->scn = scn;
- cursec->id = entry != NULL ? entry->id : sec_invalid;
- cursec->name = scnname;
- cursec->rel = (struct relocation_data){NULL, SHT_NULL, NULL, 0, 0, 0};
-
- /* Dwarf section. */
- if (entry != NULL)
- {
- if (unlikely (entry->secndx != 0))
- wr_error ()
- << "Multiple occurrences of section " << scnname << std::endl;
- else
- {
- /* Haven't seen a section of that name yet. */
- cursec->data = elf_getdata (scn, NULL);
- if (cursec->data == NULL || cursec->data->d_buf == NULL)
- /* Don't print out a warning, we'll get to that in
- process_file. */
- cursec->data = NULL;
- entry->secndx = curndx;
- }
- }
- /* Relocation section. */
- else if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL)
- {
- /* Get data of section that this REL(A) section relocates. */
- Elf_Scn *relocated_scn = elf_getscn (elf, shdr->sh_info);
- Elf_Scn *symtab_scn = elf_getscn (elf, shdr->sh_link);
- if (relocated_scn == NULL || symtab_scn == NULL)
- goto invalid_elf;
-
- GElf_Shdr relocated_shdr_mem;
- GElf_Shdr *relocated_shdr = gelf_getshdr (relocated_scn,
- &relocated_shdr_mem);
- if (relocated_shdr == NULL)
- goto invalid_elf;
-
- const char *relocated_scnname
- = elf_strptr (elf, file->ehdr.e_shstrndx,
- relocated_shdr->sh_name);
+ file->sec[file->size++].id = sec_invalid;
- secentry *relocated = secinfo.get (relocated_scnname);
-
- if (relocated != NULL)
- {
- if (relocated->reldata != NULL)
- wr_error ()
- << "Several relocation sections for debug section "
- << relocated_scnname << ". Ignoring " << scnname
- << "." << std::endl;
- else
- {
- relocated->reldata = elf_getdata (scn, NULL);
- if (unlikely (relocated->reldata == NULL
- || relocated->reldata->d_buf == NULL))
- {
- wr_error ()
- << "Data-less relocation section " << scnname
- << "." << std::endl;
- relocated->reldata = NULL;
- }
- else
- relocated->reltype = shdr->sh_type;
- }
+ bool check_rel = true;
- if (reloc_symtab == NULL)
- reloc_symtab = symtab_scn;
- else if (reloc_symtab != symtab_scn)
- wr_error ()
- << "Relocation sections use multiple symbol tables."
- << std::endl;
- }
- }
- }
+ for (Elf_Scn *scn = NULL; (scn = elf_nextscn (elf, scn)); )
+ {
+ REALLOC (file, sec);
+ size_t curndx = file->size++;
+ struct sec *cursec = file->sec + curndx;
+
+ GElf_Shdr *shdr = gelf_getshdr (scn, &cursec->shdr);
+ if (shdr == NULL)
+ {
+ invalid_elf:
+ wr_error () << "Broken ELF." << std::endl;
+ goto close_and_out;
+ }
+
+ const char *scnname = elf_strptr (elf, file->ehdr.e_shstrndx,
+ shdr->sh_name);
+ if (scnname == NULL)
+ goto invalid_elf;
+
+ if (!address_aligned (shdr->sh_addr, shdr->sh_addralign))
+ wr_error ()
+ << "Base address of section " << scnname << ", "
+ << pri::addr (shdr->sh_addr) << ", should have an alignment of "
+ << shdr->sh_addralign << std::endl;
+
+ secentry *entry = secinfo.get (scnname);
+ cursec->scn = scn;
+ cursec->id = entry != NULL ? entry->id : sec_invalid;
+ cursec->name = scnname;
+ cursec->rel = (struct relocation_data){NULL, SHT_NULL, NULL, 0, 0, 0};
+
+ /* Dwarf section. */
+ if (entry != NULL)
+ {
+ if (unlikely (entry->secndx != 0))
+ wr_error ()
+ << "Multiple occurrences of section " << scnname << std::endl;
+ else
+ {
+ /* Haven't seen a section of that name yet. */
+ cursec->data = elf_getdata (scn, NULL);
+ if (cursec->data == NULL || cursec->data->d_buf == NULL)
+ /* Don't print out a warning, we'll get to that in
+ process_file. */
+ cursec->data = NULL;
+ entry->secndx = curndx;
+ }
+ }
+ /* Relocation section. */
+ else if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL)
+ {
+ /* Get data of section that this REL(A) section relocates. */
+ Elf_Scn *relocated_scn = elf_getscn (elf, shdr->sh_info);
+ Elf_Scn *symtab_scn = elf_getscn (elf, shdr->sh_link);
+ if (relocated_scn == NULL || symtab_scn == NULL)
+ goto invalid_elf;
+
+ GElf_Shdr relocated_shdr_mem;
+ GElf_Shdr *relocated_shdr = gelf_getshdr (relocated_scn,
+ &relocated_shdr_mem);
+ if (relocated_shdr == NULL)
+ goto invalid_elf;
+
+ const char *relocated_scnname
+ = elf_strptr (elf, file->ehdr.e_shstrndx,
+ relocated_shdr->sh_name);
+
+ secentry *relocated = secinfo.get (relocated_scnname);
+
+ if (relocated != NULL)
+ {
+ if (relocated->reldata != NULL)
+ wr_error ()
+ << "Several relocation sections for debug section "
+ << relocated_scnname << ". Ignoring " << scnname
+ << "." << std::endl;
+ else
+ {
+ relocated->reldata = elf_getdata (scn, NULL);
+ if (unlikely (relocated->reldata == NULL
+ || relocated->reldata->d_buf == NULL))
+ {
+ wr_error ()
+ << "Data-less relocation section " << scnname
+ << "." << std::endl;
+ relocated->reldata = NULL;
+ }
+ else
+ relocated->reltype = shdr->sh_type;
+ }
+
+ if (reloc_symtab == NULL)
+ reloc_symtab = symtab_scn;
+ else if (reloc_symtab != symtab_scn)
+ wr_error ()
+ << "Relocation sections use multiple symbol tables."
+ << std::endl;
+ }
+ }
+ }
- for (secinfo_map::iterator it = secinfo.begin (); it != secinfo.end (); ++it)
- if (it->second.secndx != 0)
- file->debugsec[it->second.id] = file->sec + it->second.secndx;
+ for (secinfo_map::iterator it = secinfo.begin (); it != secinfo.end (); ++it)
+ if (it->second.secndx != 0)
+ file->debugsec[it->second.id] = file->sec + it->second.secndx;
- if (check_rel)
- {
- Elf_Data *reloc_symdata = NULL;
- if (reloc_symtab != NULL)
- {
- reloc_symdata = elf_getdata (reloc_symtab, NULL);
- if (reloc_symdata == NULL)
- /* Not a show stopper, we can check a lot of stuff even
- without a symbol table. */
- wr_error () << "Couldn't obtain symtab data." << std::endl;
- }
-
- /* Check relocation sections that we've got. */
- for (secinfo_map::iterator it = secinfo.begin (); it != secinfo.end (); ++it)
- {
- secentry *cur = &it->second;
- if (cur->secndx != 0 && cur->reldata != NULL)
- {
- struct sec *sec = file->sec + cur->secndx;
- sec->rel.type = cur->reltype;
- if (sec->data == NULL)
- wr_error (WHERE (sec->id, NULL))
- << "this data-less section has a relocation section."
- << std::endl;
- else if (read_rel (file, sec, cur->reldata, file->addr_64))
- sec->rel.symdata = reloc_symdata;
- }
- }
-
- if (secentry *str = secinfo.get (".debug_str"))
- if (str->reldata != NULL)
- wr_message (WHERE (sec_str, NULL), cat (mc_impact_2, mc_elf))
- << "there's a relocation section associated with this section."
- << std::endl;
- }
+ if (check_rel)
+ {
+ Elf_Data *reloc_symdata = NULL;
+ if (reloc_symtab != NULL)
+ {
+ reloc_symdata = elf_getdata (reloc_symtab, NULL);
+ if (reloc_symdata == NULL)
+ /* Not a show stopper, we can check a lot of stuff even
+ without a symbol table. */
+ wr_error () << "Couldn't obtain symtab data." << std::endl;
+ }
+
+ /* Check relocation sections that we've got. */
+ for (secinfo_map::iterator it = secinfo.begin (); it != secinfo.end (); ++it)
+ {
+ secentry *cur = &it->second;
+ if (cur->secndx != 0 && cur->reldata != NULL)
+ {
+ struct sec *sec = file->sec + cur->secndx;
+ sec->rel.type = cur->reltype;
+ if (sec->data == NULL)
+ wr_error (WHERE (sec->id, NULL))
+ << "this data-less section has a relocation section."
+ << std::endl;
+ else if (read_rel (file, sec, cur->reldata, file->addr_64))
+ sec->rel.symdata = reloc_symdata;
+ }
+ }
+
+ if (secentry *str = secinfo.get (".debug_str"))
+ if (str->reldata != NULL)
+ wr_message (WHERE (sec_str, NULL), cat (mc_impact_2, mc_elf))
+ << "there's a relocation section associated with this section."
+ << std::endl;
+ }
- return elf;
+ return elf;
- close_and_out:
- if (elf != NULL)
- {
- elf_errno (); // clear errno
- elf_end (elf);
- int err = elf_errno ();
- if (err != 0)
- wr_error ()
- << "error while closing Elf descriptor: "
- << elf_errmsg (err) << std::endl;
- }
- return NULL;
-}
+ close_and_out:
+ if (elf != NULL)
+ {
+ elf_errno (); // clear errno
+ elf_end (elf);
+ int err = elf_errno ();
+ if (err != 0)
+ wr_error ()
+ << "error while closing Elf descriptor: "
+ << elf_errmsg (err) << std::endl;
+ }
+ return NULL;
+ }
}
load_sections::load_sections (dwarflint &lint)