(bfd_elf_hash): Optimize the hash function a bit.

This commit is contained in:
Ulrich Drepper 1998-10-27 00:00:50 +00:00
parent e841d72322
commit eaa57a10aa

581
bfd/elf.c
View file

@ -199,8 +199,7 @@ _bfd_elf_swap_versym_out (abfd, src, dst)
}
/* Standard ELF hash function. Do not change this function; you will
cause invalid hash tables to be generated. (Well, you would if this
were being used yet.) */
cause invalid hash tables to be generated. */
unsigned long
bfd_elf_hash (name)
CONST unsigned char *name;
@ -215,7 +214,9 @@ bfd_elf_hash (name)
if ((g = (h & 0xf0000000)) != 0)
{
h ^= g >> 24;
h &= ~g;
/* The ELF ABI says `h &= ~g', but this is equivalent in
this case and on some machines one insn instead of two. */
h ^= g;
}
}
return h;
@ -2392,7 +2393,7 @@ elf_sort_sections (arg1, arg2)
{
if (TOEND (sec2))
return sec1->target_index - sec2->target_index;
else
else
return 1;
}
@ -2481,7 +2482,7 @@ assign_file_positions_for_segments (abfd)
filehdr_paddr = 0;
phdrs_vaddr = 0;
phdrs_paddr = 0;
for (m = elf_tdata (abfd)->segment_map, p = phdrs;
m != NULL;
m = m->next, p++)
@ -2536,7 +2537,7 @@ assign_file_positions_for_segments (abfd)
p->p_offset = 0;
p->p_filesz = 0;
p->p_memsz = 0;
if (m->includes_filehdr)
{
if (! m->p_flags_valid)
@ -2555,7 +2556,7 @@ assign_file_positions_for_segments (abfd)
bfd_set_error (bfd_error_bad_value);
return false;
}
p->p_vaddr -= off;
if (! m->p_paddr_valid)
p->p_paddr -= off;
@ -2571,7 +2572,7 @@ assign_file_positions_for_segments (abfd)
{
if (! m->p_flags_valid)
p->p_flags |= PF_R;
if (m->includes_filehdr)
{
if (p->p_type == PT_LOAD)
@ -2583,7 +2584,7 @@ assign_file_positions_for_segments (abfd)
else
{
p->p_offset = bed->s->sizeof_ehdr;
if (m->count > 0)
{
BFD_ASSERT (p->p_type == PT_LOAD);
@ -2591,7 +2592,7 @@ assign_file_positions_for_segments (abfd)
if (! m->p_paddr_valid)
p->p_paddr -= off - p->p_offset;
}
if (p->p_type == PT_LOAD)
{
phdrs_vaddr = p->p_vaddr;
@ -2600,12 +2601,12 @@ assign_file_positions_for_segments (abfd)
else
phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
}
p->p_filesz += alloc * bed->s->sizeof_phdr;
p->p_memsz += alloc * bed->s->sizeof_phdr;
}
if (p->p_type == PT_LOAD
if (p->p_type == PT_LOAD
|| (p->p_type == PT_NOTE && abfd->format == bfd_core))
{
if (! m->includes_filehdr && ! m->includes_phdrs)
@ -2621,7 +2622,7 @@ assign_file_positions_for_segments (abfd)
}
voff = off;
for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
{
asection *sec;
@ -2632,7 +2633,7 @@ assign_file_positions_for_segments (abfd)
flags = sec->flags;
align = 1 << bfd_get_section_alignment (abfd, sec);
/* The section may have artificial alignment forced by a
/* The section may have artificial alignment forced by a
link script. Notice this case by the gap between the
cumulative phdr vma and the section's vma. */
if (p->p_vaddr + p->p_memsz < sec->vma)
@ -2649,7 +2650,7 @@ assign_file_positions_for_segments (abfd)
if (p->p_type == PT_LOAD)
{
bfd_signed_vma adjust;
if ((flags & SEC_LOAD) != 0)
{
adjust = sec->lma - (p->p_paddr + p->p_memsz);
@ -2681,7 +2682,7 @@ assign_file_positions_for_segments (abfd)
(* _bfd_error_handler)
(_(" whereas segment starts at 0x%x"),
p->p_paddr);
return false;
}
p->p_memsz += adjust;
@ -2700,7 +2701,7 @@ assign_file_positions_for_segments (abfd)
if ((flags & SEC_LOAD) != 0
|| (flags & SEC_HAS_CONTENTS) != 0)
off += sec->_raw_size;
if ((flags & SEC_ALLOC) != 0)
voff += sec->_raw_size;
}
@ -2920,7 +2921,7 @@ assign_file_positions_except_relocs (abfd)
hdr->sh_offset = -1;
continue;
}
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
}
}
@ -2967,7 +2968,7 @@ assign_file_positions_except_relocs (abfd)
hdr->sh_offset = -1;
else
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
}
}
}
/* Place the section headers. */
@ -3343,7 +3344,7 @@ copy_private_bfd_data (ibfd, obfd)
unsigned int i;
unsigned int num_segments;
boolean phdr_included = false;
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|| bfd_get_flavour (obfd) != bfd_target_elf_flavour)
return true;
@ -3455,19 +3456,19 @@ copy_private_bfd_data (ibfd, obfd)
/* Special segments, such as the PT_PHDR segment, may contain
no sections, but ordinary, loadable segments should contain
something. */
if (p->p_type == PT_LOAD)
_bfd_error_handler
(_("%s: warning: Empty loadable segment detected\n"),
bfd_get_filename (ibfd));
m->count = 0;
*pm = m;
pm = &m->next;
continue;
}
/* Now scan the sections in the input BFD again and attempt
to add their corresponding output sections to the segment map.
The problem here is how to handle an output section which has
@ -3476,7 +3477,7 @@ copy_private_bfd_data (ibfd, obfd)
1. None of the sections have been moved.
In this case we can continue to use the segment LMA from the
input BFD.
2. All of the sections have been moved by the same amount.
In this case we can change the segment's LMA to match the LMA
of the first section.
@ -3490,23 +3491,23 @@ copy_private_bfd_data (ibfd, obfd)
4. The sections have been moved, but not be the same amount.
In this case we can change the segment's LMA to match the LMA
of the first section and we will have to create a new segment
or segments to contain the other sections.
or segments to contain the other sections.
In order to save time, we allocate an array to hold the section
pointers that we are interested in. As these sections get assigned
to a segment, they are removed from this array. */
sections = (asection **) bfd_malloc (sizeof (asection *) * csecs);
if (sections == NULL)
return false;
/* Step One: Scan for segment vs section LMA conflicts.
Also add the sections to the section array allocated above.
Also add the sections to the current segment. In the common
case, where the sections have not been moved, this means that
we have completely filled the segment, and there is nothing
more to do. */
isec = 0;
matching_lma = false;
suggested_lma = 0;
@ -3514,15 +3515,15 @@ copy_private_bfd_data (ibfd, obfd)
for (j = 0, s = ibfd->sections; s != NULL; s = s->next)
{
os = s->output_section;
if ((((IS_CONTAINED_BY (s->vma, s->_raw_size, p->p_vaddr, p)
|| IS_SOLARIS_PT_INTERP (p, s))
&& (s->flags & SEC_ALLOC) != 0)
&& (s->flags & SEC_ALLOC) != 0)
|| IS_COREFILE_NOTE (p, s))
&& os != NULL)
{
sections[j++] = s;
/* The Solaris native linker always sets p_paddr to 0.
We try to catch that case here, and set it to the
correct value. */
@ -3546,7 +3547,7 @@ copy_private_bfd_data (ibfd, obfd)
{
if (matching_lma == 0)
matching_lma = os->lma;
/* We assume that if the section fits within the segment
that it does not overlap any other section within that
segment. */
@ -3582,7 +3583,7 @@ copy_private_bfd_data (ibfd, obfd)
m->p_paddr = matching_lma;
}
else
else
{
/* None of the sections fitted inside the current segment.
Change the current segment's physical address to match
@ -3603,17 +3604,17 @@ copy_private_bfd_data (ibfd, obfd)
{
m->count = 0;
suggested_lma = 0;
/* Fill the current segment with sections that fit. */
for (j = 0; j < csecs; j++)
{
s = sections[j];
if (s == NULL)
continue;
os = s->output_section;
if (IS_CONTAINED_BY (os->lma, os->_raw_size, m->p_paddr, p)
|| IS_COREFILE_NOTE (p, s))
{
@ -3624,11 +3625,11 @@ copy_private_bfd_data (ibfd, obfd)
if (os->lma != m->p_paddr)
abort ();
}
else
else
{
asection * prev_sec;
bfd_vma maxpagesize;
prev_sec = m->sections[m->count - 1];
maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
@ -3640,7 +3641,7 @@ copy_private_bfd_data (ibfd, obfd)
{
if (suggested_lma == 0)
suggested_lma = os->lma;
continue;
}
}
@ -3654,7 +3655,7 @@ copy_private_bfd_data (ibfd, obfd)
}
BFD_ASSERT (m->count > 0);
/* Add the current segment to the list of built segments. */
*pm = m;
pm = &m->next;
@ -3675,7 +3676,7 @@ copy_private_bfd_data (ibfd, obfd)
/* Initialise the fields of the segment map. Set the physical
physical address to the LMA of the first section that has
not yet been assigned. */
m->next = NULL;
m->p_type = p->p_type;
m->p_flags = p->p_flags;
@ -3711,7 +3712,7 @@ copy_private_bfd_data (ibfd, obfd)
if (mfirst != NULL)
{
struct elf_segment_map* prev;
prev = mfirst;
for (m = mfirst->next; m != NULL; prev = m, m = m->next)
{
@ -3729,7 +3730,7 @@ copy_private_bfd_data (ibfd, obfd)
}
}
#endif
#undef IS_CONTAINED_BY
#undef IS_SOLARIS_PT_INTERP
#undef IS_COREFILE_NOTE
@ -3916,7 +3917,8 @@ swap_out_syms (abfd, sttp, relocatable_p)
type_ptr = elf_symbol_from (abfd, syms[idx]);
if (bfd_is_com_section (syms[idx]->section))
if ((flags & BSF_SECTION_SYM) == 0
&& bfd_is_com_section (syms[idx]->section))
{
/* ELF common symbols put the alignment into the `value' field,
and the size into the `size' field. This is backwards from
@ -4006,17 +4008,17 @@ swap_out_syms (abfd, sttp, relocatable_p)
/* Processor-specific types */
if (bed->elf_backend_get_symbol_type)
type = (*bed->elf_backend_get_symbol_type) (&type_ptr->internal_elf_sym);
type = (*bed->elf_backend_get_symbol_type) (&type_ptr->internal_elf_sym, type);
if (bfd_is_com_section (syms[idx]->section))
if (flags & BSF_SECTION_SYM)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
else if (bfd_is_com_section (syms[idx]->section))
sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
else if (bfd_is_und_section (syms[idx]->section))
sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
? STB_WEAK
: STB_GLOBAL),
type);
else if (flags & BSF_SECTION_SYM)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
else if (flags & BSF_FILE)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
else
@ -4517,11 +4519,16 @@ _bfd_elf_find_nearest_line (abfd,
bfd_vma low_func;
asymbol **p;
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr))
return true;
if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
filename_ptr, functionname_ptr,
line_ptr))
return true;
if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
&found, filename_ptr,
functionname_ptr, line_ptr,
@ -4642,11 +4649,11 @@ _bfd_elf_validate_reloc (abfd, areloc)
{
/* Check whether we really have an ELF howto. */
if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
{
bfd_reloc_code_real_type code;
reloc_howto_type *howto;
/* Alien reloc: Try to determine its type to replace it with an
equivalent ELF reloc. */
@ -4655,22 +4662,22 @@ _bfd_elf_validate_reloc (abfd, areloc)
switch (areloc->howto->bitsize)
{
case 8:
code = BFD_RELOC_8_PCREL;
code = BFD_RELOC_8_PCREL;
break;
case 12:
code = BFD_RELOC_12_PCREL;
code = BFD_RELOC_12_PCREL;
break;
case 16:
code = BFD_RELOC_16_PCREL;
code = BFD_RELOC_16_PCREL;
break;
case 24:
code = BFD_RELOC_24_PCREL;
code = BFD_RELOC_24_PCREL;
break;
case 32:
code = BFD_RELOC_32_PCREL;
code = BFD_RELOC_32_PCREL;
break;
case 64:
code = BFD_RELOC_64_PCREL;
code = BFD_RELOC_64_PCREL;
break;
default:
goto fail;
@ -4691,22 +4698,22 @@ _bfd_elf_validate_reloc (abfd, areloc)
switch (areloc->howto->bitsize)
{
case 8:
code = BFD_RELOC_8;
code = BFD_RELOC_8;
break;
case 14:
code = BFD_RELOC_14;
code = BFD_RELOC_14;
break;
case 16:
code = BFD_RELOC_16;
code = BFD_RELOC_16;
break;
case 26:
code = BFD_RELOC_26;
code = BFD_RELOC_26;
break;
case 32:
code = BFD_RELOC_32;
code = BFD_RELOC_32;
break;
case 64:
code = BFD_RELOC_64;
code = BFD_RELOC_64;
break;
default:
goto fail;
@ -4761,3 +4768,445 @@ _bfd_elf_rel_vtable_reloc_fn (abfd, re, symbol, data, is, obfd, errmsg)
{
return bfd_reloc_ok;
}
/* Elf core file support. Much of this only works on native
toolchains, since we rely on knowing the
machine-dependent procfs structure in order to pick
out details about the corefile. */
#ifdef HAVE_SYS_PROCFS_H
# include <sys/procfs.h>
#endif
/* Define offsetof for those systems which lack it. */
#ifndef offsetof
# define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
/* FIXME: this is kinda wrong, but it's what gdb wants. */
static int
elfcore_make_pid (abfd)
bfd* abfd;
{
return ((elf_tdata (abfd)->core_lwpid << 16)
+ (elf_tdata (abfd)->core_pid));
}
/* If there isn't a section called NAME, make one, using
data from SECT. Note, this function will generate a
reference to NAME, so you shouldn't deallocate or
overwrite it. */
static boolean
elfcore_maybe_make_sect (abfd, name, sect)
bfd* abfd;
char* name;
asection* sect;
{
asection* sect2;
if (bfd_get_section_by_name (abfd, name) != NULL)
return true;
sect2 = bfd_make_section (abfd, name);
if (sect2 == NULL)
return false;
sect2->_raw_size = sect->_raw_size;
sect2->filepos = sect->filepos;
sect2->flags = sect->flags;
sect2->alignment_power = sect->alignment_power;
return true;
}
/* prstatus_t exists on:
solaris 2.[567]
linux 2.[01] + glibc
unixware 4.2
*/
#if defined (HAVE_PRSTATUS_T)
static boolean
elfcore_grok_prstatus (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
prstatus_t prstat;
char buf[100];
char* name;
asection* sect;
if (note->descsz != sizeof (prstat))
return true;
memcpy (&prstat, note->descdata, sizeof (prstat));
elf_tdata (abfd)->core_signal = prstat.pr_cursig;
elf_tdata (abfd)->core_pid = prstat.pr_pid;
/* pr_who exists on:
solaris 2.[567]
unixware 4.2
pr_who doesn't exist on:
linux 2.[01]
*/
#if defined (HAVE_PRSTATUS_T_PR_WHO)
elf_tdata (abfd)->core_lwpid = prstat.pr_who;
#endif
/* Make a ".reg/999" section. */
sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
name = bfd_alloc (abfd, strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
sect = bfd_make_section (abfd, name);
if (sect == NULL)
return false;
sect->_raw_size = sizeof (prstat.pr_reg);
sect->filepos = note->descpos + offsetof (prstatus_t, pr_reg);
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
return false;
return true;
}
#endif /* defined (HAVE_PRSTATUS_T) */
/* There isn't a consistent prfpregset_t across platforms,
but it doesn't matter, because we don't have to pick this
data structure apart. */
static boolean
elfcore_grok_prfpreg (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
char buf[100];
char* name;
asection* sect;
/* Make a ".reg2/999" section. */
sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
name = bfd_alloc (abfd, strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
sect = bfd_make_section (abfd, name);
if (sect == NULL)
return false;
sect->_raw_size = note->descsz;
sect->filepos = note->descpos;
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
if (! elfcore_maybe_make_sect (abfd, ".reg2", sect))
return false;
return true;
}
/* return a malloc'ed copy of a string at START which is at
most MAX bytes long, possibly without a terminating '\0'.
the copy will always have a terminating '\0'. */
static char*
elfcore_strndup (abfd, start, max)
bfd* abfd;
char* start;
int max;
{
char* dup;
char* end = memchr (start, '\0', max);
int len;
if (end == NULL)
len = max;
else
len = end - start;
dup = bfd_alloc (abfd, len + 1);
if (dup == NULL)
return NULL;
memcpy (dup, start, len);
dup[len] = '\0';
return dup;
}
#if defined (HAVE_PRPSINFO_T)
# define elfcore_psinfo_t prpsinfo_t
#endif
#if defined (HAVE_PSINFO_T)
# define elfcore_psinfo_t psinfo_t
#endif
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
static boolean
elfcore_grok_psinfo (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
elfcore_psinfo_t psinfo;
if (note->descsz != sizeof (elfcore_psinfo_t))
return true;
memcpy (&psinfo, note->descdata, note->descsz);
elf_tdata (abfd)->core_program
= elfcore_strndup (abfd, psinfo.pr_fname, sizeof (psinfo.pr_fname));
elf_tdata (abfd)->core_command
= elfcore_strndup (abfd, psinfo.pr_psargs, sizeof (psinfo.pr_psargs));
/* Note that for some reason, a spurious space is tacked
onto the end of the args in some (at least one anyway)
implementations, so strip it off if it exists. */
{
char* command = elf_tdata (abfd)->core_command;
int n = strlen (command);
if (0 < n && command[n - 1] == ' ')
command[n - 1] = '\0';
}
return true;
}
#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
#if defined (HAVE_PSTATUS_T)
static boolean
elfcore_grok_pstatus (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
pstatus_t pstat;
if (note->descsz != sizeof (pstat))
return true;
memcpy (&pstat, note->descdata, sizeof (pstat));
elf_tdata (abfd)->core_pid = pstat.pr_pid;
/* Could grab some more details from the "representative"
lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
NT_LWPSTATUS note, presumably. */
return true;
}
#endif /* defined (HAVE_PSTATUS_T) */
#if defined (HAVE_LWPSTATUS_T)
static boolean
elfcore_grok_lwpstatus (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
lwpstatus_t lwpstat;
char buf[100];
char* name;
asection* sect;
if (note->descsz != sizeof (lwpstat))
return true;
memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
/* Make a ".reg/999" section. */
sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
name = bfd_alloc (abfd, strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
sect = bfd_make_section (abfd, name);
if (sect == NULL)
return false;
#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
sect->filepos = note->descpos
+ offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
#endif
#if defined (HAVE_LWPSTATUS_T_PR_REG)
sect->_raw_size = sizeof (lwpstat.pr_reg);
sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
#endif
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
return false;
/* Make a ".reg2/999" section */
sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
name = bfd_alloc (abfd, strlen (buf) + 1);
if (name == NULL)
return false;
strcpy (name, buf);
sect = bfd_make_section (abfd, name);
if (sect == NULL)
return false;
#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
sect->_raw_size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
sect->filepos = note->descpos
+ offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
#endif
#if defined (HAVE_LWPSTATUS_T_PR_FPREG)
sect->_raw_size = sizeof (lwpstat.pr_fpreg);
sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
#endif
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
if (!elfcore_maybe_make_sect (abfd, ".reg2", sect))
return false;
return true;
}
#endif /* defined (HAVE_LWPSTATUS_T) */
static boolean
elfcore_grok_note (abfd, note)
bfd* abfd;
Elf_Internal_Note* note;
{
switch (note->type)
{
default:
return true;
#if defined (HAVE_PRSTATUS_T)
case NT_PRSTATUS:
return elfcore_grok_prstatus (abfd, note);
#endif
#if defined (HAVE_PSTATUS_T)
case NT_PSTATUS:
return elfcore_grok_pstatus (abfd, note);
#endif
#if defined (HAVE_LWPSTATUS_T)
case NT_LWPSTATUS:
return elfcore_grok_lwpstatus (abfd, note);
#endif
case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */
return elfcore_grok_prfpreg (abfd, note);
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
case NT_PRPSINFO:
case NT_PSINFO:
return elfcore_grok_psinfo (abfd, note);
#endif
}
}
static boolean
elfcore_read_notes (abfd, offset, size)
bfd* abfd;
bfd_vma offset;
bfd_vma size;
{
char* buf;
char* p;
if (size <= 0)
return true;
if (bfd_seek (abfd, offset, SEEK_SET) == -1)
return false;
buf = bfd_malloc ((size_t) size);
if (buf == NULL)
return false;
if (bfd_read (buf, size, 1, abfd) != size)
{
error:
free (buf);
return false;
}
p = buf;
while (p < buf + size)
{
/* FIXME: bad alignment assumption. */
Elf_External_Note* xnp = (Elf_External_Note*) p;
Elf_Internal_Note in;
in.type = bfd_h_get_32 (abfd, (bfd_byte *) xnp->type);
in.namesz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->namesz);
in.namedata = xnp->name;
in.descsz = bfd_h_get_32 (abfd, (bfd_byte *) xnp->descsz);
in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
in.descpos = offset + (in.descdata - buf);
if (! elfcore_grok_note (abfd, &in))
goto error;
p = in.descdata + BFD_ALIGN (in.descsz, 4);
}
free (buf);
return true;
}
boolean
_bfd_elfcore_section_from_phdr (abfd, phdr, sec_num)
bfd* abfd;
Elf_Internal_Phdr* phdr;
int sec_num;
{
if (! bfd_section_from_phdr (abfd, phdr, sec_num))
return false;
if (phdr->p_type == PT_NOTE
&& ! elfcore_read_notes (abfd, phdr->p_offset, phdr->p_filesz))
return false;
return true;
}