+bfd_boolean
+elf_checksum_contents (bfd *abfd,
+ void (*process) (const void *, size_t, void *),
+ void *arg)
+{
+ Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+ Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
+ Elf_Internal_Phdr *i_phdrp = elf_tdata (abfd)->phdr;
+ unsigned int count, num;
+
+ {
+ Elf_External_Ehdr x_ehdr;
+ Elf_Internal_Ehdr i_ehdr;
+
+ i_ehdr = *i_ehdrp;
+ i_ehdr.e_phoff = i_ehdr.e_shoff = 0;
+ elf_swap_ehdr_out (abfd, &i_ehdr, &x_ehdr);
+ (*process) (&x_ehdr, sizeof x_ehdr, arg);
+ }
+
+ num = i_ehdrp->e_phnum;
+ for (count = 0; count < num; count++)
+ {
+ Elf_External_Phdr x_phdr;
+ elf_swap_phdr_out (abfd, &i_phdrp[count], &x_phdr);
+ (*process) (&x_phdr, sizeof x_phdr, arg);
+ }
+
+ num = elf_numsections (abfd);
+ for (count = 0; count < num; count++)
+ {
+ Elf_Internal_Shdr i_shdr;
+ Elf_External_Shdr x_shdr;
+ bfd_byte *contents, *free_contents;
+
+ i_shdr = *i_shdrp[count];
+ i_shdr.sh_offset = 0;
+
+ elf_swap_shdr_out (abfd, &i_shdr, &x_shdr);
+ (*process) (&x_shdr, sizeof x_shdr, arg);
+
+ /* Process the section's contents, if it has some.
+ PR ld/12451: Read them in if necessary. */
+ if (i_shdr.sh_type == SHT_NOBITS)
+ continue;
+ free_contents = NULL;
+ contents = i_shdr.contents;
+ if (contents == NULL)
+ {
+ asection *sec;
+
+ sec = bfd_section_from_elf_index (abfd, count);
+ if (sec != NULL)
+ {
+ contents = sec->contents;
+ if (contents == NULL)
+ {
+ /* Force rereading from file. */
+ sec->flags &= ~SEC_IN_MEMORY;
+ if (!bfd_malloc_and_get_section (abfd, sec, &free_contents))
+ continue;
+ contents = free_contents;
+ }
+ }
+ }
+ if (contents != NULL)
+ {
+ (*process) (contents, i_shdr.sh_size, arg);
+ free (free_contents);
+ }
+ }
+
+ return TRUE;
+}
+