static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
static bfd_boolean prep_headers (bfd *);
static bfd_boolean swap_out_syms (bfd *, struct elf_strtab_hash **, int) ;
-static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
+static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type,
+ size_t align) ;
static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
- file_ptr offset);
+ file_ptr offset, size_t align);
/* Swap version information in and out. The version information is
currently size independent. If that ever changes, this code will
unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: invalid string offset %u >= %lu for section `%s'"),
- abfd, strindex, (unsigned long) hdr->sh_size,
+ (_("%B: invalid string offset %u >= %Lu for section `%s'"),
+ abfd, strindex, hdr->sh_size,
(shindex == shstrndx && strindex == hdr->sh_name
? ".shstrtab"
: bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
{
num_group = (unsigned) -1;
elf_tdata (abfd)->num_group = num_group;
+ elf_tdata (abfd)->group_sect_ptr = NULL;
}
else
{
bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
if (elf_tdata (abfd)->group_sect_ptr == NULL)
return FALSE;
-
+ memset (elf_tdata (abfd)->group_sect_ptr, 0, num_group * sizeof (Elf_Internal_Shdr *));
num_group = 0;
+
for (i = 0; i < shnum; i++)
{
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
unsigned char *src;
Elf_Internal_Group *dest;
+ /* Make sure the group section has a BFD section
+ attached to it. */
+ if (!bfd_section_from_shdr (abfd, i))
+ return FALSE;
+
/* Add to list of sections. */
elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
num_group += 1;
_bfd_error_handler
/* xgettext:c-format */
(_("%B: corrupt size field in group section"
- " header: 0x%lx"), abfd, shdr->sh_size);
+ " header: %#Lx"), abfd, shdr->sh_size);
bfd_set_error (bfd_error_bad_value);
-- num_group;
continue;
_bfd_error_handler
/* xgettext:c-format */
(_("%B: invalid size field in group section"
- " header: 0x%lx"), abfd, shdr->sh_size);
+ " header: %#Lx"), abfd, shdr->sh_size);
bfd_set_error (bfd_error_bad_value);
-- num_group;
/* PR 17510: If the group contents are even
for (i = 0; i < num_group; i++)
{
Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
- Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
- unsigned int n_elt = shdr->sh_size / 4;
+ Elf_Internal_Group *idx;
+ bfd_size_type n_elt;
+
+ if (shdr == NULL)
+ continue;
+
+ idx = (Elf_Internal_Group *) shdr->contents;
+ if (idx == NULL || shdr->sh_size < 4)
+ {
+ /* See PR 21957 for a reproducer. */
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%B: group section '%A' has no contents"),
+ abfd, shdr->bfd_section);
+ elf_tdata (abfd)->group_sect_ptr[i] = NULL;
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ n_elt = shdr->sh_size / 4;
/* Look through this group's sections to see if current
section is a member. */
if (elf_group_name (newsect) == NULL)
{
/* xgettext:c-format */
- _bfd_error_handler (_("%B: no group info for section %A"),
+ _bfd_error_handler (_("%B: no group info for section '%A'"),
abfd, newsect);
return FALSE;
}
n_elt = shdr->sh_size / 4;
while (--n_elt != 0)
- if ((++idx)->shdr->bfd_section)
- elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
- else if (idx->shdr->sh_type == SHT_RELA
- || idx->shdr->sh_type == SHT_REL)
- /* We won't include relocation sections in section groups in
- output object files. We adjust the group section size here
- so that relocatable link will work correctly when
- relocation sections are in section group in input object
- files. */
- shdr->bfd_section->size -= 4;
- else
- {
- /* There are some unknown sections in the group. */
- _bfd_error_handler
- /* xgettext:c-format */
- (_("%B: unknown [%d] section `%s' in group [%A]"),
- abfd,
- (unsigned int) idx->shdr->sh_type,
- bfd_elf_string_from_elf_section (abfd,
- (elf_elfheader (abfd)
- ->e_shstrndx),
- idx->shdr->sh_name),
- shdr->bfd_section);
- result = FALSE;
- }
+ {
+ ++ idx;
+
+ if (idx->shdr == NULL)
+ continue;
+ else if (idx->shdr->bfd_section)
+ elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
+ else if (idx->shdr->sh_type != SHT_RELA
+ && idx->shdr->sh_type != SHT_REL)
+ {
+ /* There are some unknown sections in the group. */
+ _bfd_error_handler
+ /* xgettext:c-format */
+ (_("%B: unknown type [%#x] section `%s' in group [%A]"),
+ abfd,
+ idx->shdr->sh_type,
+ bfd_elf_string_from_elf_section (abfd,
+ (elf_elfheader (abfd)
+ ->e_shstrndx),
+ idx->shdr->sh_name),
+ shdr->bfd_section);
+ result = FALSE;
+ }
+ }
}
+
return result;
}
if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
return FALSE;
- elf_parse_notes (abfd, (char *) contents, hdr->sh_size, hdr->sh_offset);
+ elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
+ hdr->sh_offset, hdr->sh_addralign);
free (contents);
}
to be the correct section. */
static unsigned int
-find_link (const bfd * obfd, const Elf_Internal_Shdr * iheader, const unsigned int hint)
+find_link (const bfd *obfd, const Elf_Internal_Shdr *iheader,
+ const unsigned int hint)
{
Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
unsigned int i;
BFD_ASSERT (iheader != NULL);
/* See PR 20922 for a reproducer of the NULL test. */
- if (oheaders[hint] != NULL
+ if (hint < elf_numsections (obfd)
+ && oheaders[hint] != NULL
&& section_match (oheaders[hint], iheader))
return hint;
/* See PR 20931 for a reproducer. */
if (iheader->sh_link >= elf_numsections (ibfd))
{
- (* _bfd_error_handler)
+ _bfd_error_handler
/* xgettext:c-format */
(_("%B: Invalid sh_link field (%d) in section number %d"),
ibfd, iheader->sh_link, secnum);
else
/* FIXME: Should we install iheader->sh_link
if we could not find a match ? */
- (* _bfd_error_handler)
+ _bfd_error_handler
/* xgettext:c-format */
(_("%B: Failed to find link section for section %d"), obfd, secnum);
}
changed = TRUE;
}
else
- (* _bfd_error_handler)
+ _bfd_error_handler
/* xgettext:c-format */
(_("%B: Failed to find info section for section %d"), obfd, secnum);
}
if (!strcmp (name, ""))
{
- sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
+ sprintf (ab, "%#" BFD_VMA_FMT "x", dyn.d_tag);
name = ab;
}
break;
case bfd_print_symbol_more:
fprintf (file, "elf ");
bfd_fprintf_vma (abfd, file, symbol->value);
- fprintf (file, " %lx", (unsigned long) symbol->flags);
+ fprintf (file, " %x", symbol->flags);
break;
case bfd_print_symbol_all:
{
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: invalid link %lu for reloc section %s (index %u)"),
+ (_("%B: invalid link %u for reloc section %s (index %u)"),
abfd, hdr->sh_link, name, shindex);
ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
shindex);
if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
goto fail;
- if (hdr->contents != NULL)
- {
- Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
- unsigned int n_elt = hdr->sh_size / sizeof (* idx);
- asection *s;
-
- if (n_elt == 0)
- goto fail;
- if (idx->flags & GRP_COMDAT)
- hdr->bfd_section->flags
- |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
-
- /* We try to keep the same section order as it comes in. */
- idx += n_elt;
-
- while (--n_elt != 0)
- {
- --idx;
-
- if (idx->shdr != NULL
- && (s = idx->shdr->bfd_section) != NULL
- && elf_next_in_group (s) != NULL)
- {
- elf_next_in_group (hdr->bfd_section) = s;
- break;
- }
- }
- }
goto success;
default:
for applications? */
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: don't know how to handle allocated, application "
- "specific section `%s' [0x%8x]"),
- abfd, name, hdr->sh_type);
+ (_("%B: unknown type [%#x] section `%s'"),
+ abfd, hdr->sh_type, name);
else
{
/* Allow sections reserved for applications. */
/* FIXME: We should handle this section. */
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: don't know how to handle processor specific section "
- "`%s' [0x%8x]"),
- abfd, name, hdr->sh_type);
+ (_("%B: unknown type [%#x] section `%s'"),
+ abfd, hdr->sh_type, name);
else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
{
/* Unrecognised OS-specific sections. */
be rejected with an error message. */
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: don't know how to handle OS specific section "
- "`%s' [0x%8x]"),
- abfd, name, hdr->sh_type);
+ (_("%B: unknown type [%#x] section `%s'"),
+ abfd, hdr->sh_type, name);
else
{
/* Otherwise it should be processed. */
/* FIXME: We should handle this section. */
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: don't know how to handle section `%s' [0x%8x]"),
- abfd, name, hdr->sh_type);
+ (_("%B: unknown type [%#x] section `%s'"),
+ abfd, hdr->sh_type, name);
goto fail;
}
case PT_NOTE:
if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
return FALSE;
- if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+ if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz,
+ hdr->p_align))
return FALSE;
return TRUE;
|| arg->link_info->emitrelocations))
{
if (esd->rel.count && esd->rel.hdr == NULL
- && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name, FALSE,
- delay_st_name_p))
+ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name,
+ FALSE, delay_st_name_p))
{
arg->failed = TRUE;
return;
}
if (esd->rela.count && esd->rela.hdr == NULL
- && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name, TRUE,
- delay_st_name_p))
+ && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name,
+ TRUE, delay_st_name_p))
{
arg->failed = TRUE;
return;
name,
asect->use_rela_p,
delay_st_name_p))
+ {
arg->failed = TRUE;
+ return;
+ }
}
/* Check for processor-specific section types. */
sh_type = this_hdr->sh_type;
if (bed->elf_backend_fake_sections
&& !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
- arg->failed = TRUE;
+ {
+ arg->failed = TRUE;
+ return;
+ }
if (sh_type == SHT_NOBITS && asect->size != 0)
{
if (s != NULL
&& !bfd_is_abs_section (s))
{
- unsigned int idx = elf_section_data (s)->this_idx;
+ struct bfd_elf_section_data *elf_sec = elf_section_data (s);
+ struct bfd_elf_section_data *input_elf_sec = elf_section_data (elt);
+ if (elf_sec->rel.hdr != NULL
+ && (gas
+ || (input_elf_sec->rel.hdr != NULL
+ && input_elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0))
+ {
+ elf_sec->rel.hdr->sh_flags |= SHF_GROUP;
+ loc -= 4;
+ H_PUT_32 (abfd, elf_sec->rel.idx, loc);
+ }
+ if (elf_sec->rela.hdr != NULL
+ && (gas
+ || (input_elf_sec->rela.hdr != NULL
+ && input_elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0))
+ {
+ elf_sec->rela.hdr->sh_flags |= SHF_GROUP;
+ loc -= 4;
+ H_PUT_32 (abfd, elf_sec->rela.idx, loc);
+ }
loc -= 4;
- H_PUT_32 (abfd, idx, loc);
+ H_PUT_32 (abfd, elf_sec->this_idx, loc);
}
elt = elf_next_in_group (elt);
if (elt == first)
goto error_return;
m->next = NULL;
m->p_type = PT_PHDR;
- /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not. */
- m->p_flags = PF_R | PF_X;
+ m->p_flags = PF_R;
m->p_flags_valid = 1;
m->includes_phdrs = 1;
linker_created_pt_phdr_segment = TRUE;
else
adjustment = vma_offset - off_offset;
- which can can be collapsed into the expression below. */
+ which can be collapsed into the expression below. */
static file_ptr
vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
- (unsigned long) s_start, (unsigned long) p_end);
+ (_("%B: section %A lma %#Lx adjusted to %#Lx"),
+ abfd, sec, s_start, p_end);
adjust = 0;
sec->lma = p_end;
}
{
/* PR 17512: file: 2195325e. */
_bfd_error_handler
- (_("%B: error: non-load segment %d includes file header and/or program header"),
- abfd, (int)(p - phdrs));
+ (_("%B: error: non-load segment %d includes file header "
+ "and/or program header"),
+ abfd, (int) (p - phdrs));
return FALSE;
}
#if DEBUG & 4
{
fprintf (stderr,
- "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx\n",
- (long) asym_ptr, asym_ptr->name, idx, (long) flags);
+ "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8x\n",
+ (long) asym_ptr, asym_ptr->name, idx, flags);
fflush (stderr);
}
#endif
if (segment->p_type == PT_LOAD
&& (segment->p_filesz > 0 || segment->p_memsz == 0))
/* xgettext:c-format */
- _bfd_error_handler (_("\
-%B: warning: Empty loadable segment detected at vaddr=0x%.8x, is this intentional ?"),
+ _bfd_error_handler (_("%B: warning: Empty loadable segment detected"
+ " at vaddr=%#Lx, is this intentional?"),
ibfd, segment->p_vaddr);
map->count = 0;
/* PR 17512: file: f17299af. */
if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
/* xgettext:c-format */
- _bfd_error_handler (_("\
-%B: warning: segment alignment of 0x%llx is too large"),
- ibfd, (long long) segment->p_align);
+ _bfd_error_handler (_("%B: warning: segment alignment of %#Lx"
+ " is too large"),
+ ibfd, segment->p_align);
else
maxpagesize = segment->p_align;
}
hdr = &elf_tdata (abfd)->dynverref_hdr;
- if (hdr->sh_info == 0 || hdr->sh_size < sizeof (Elf_External_Verneed))
+ if (hdr->sh_info == 0
+ || hdr->sh_info > hdr->sh_size / sizeof (Elf_External_Verneed))
{
error_return_bad_verref:
_bfd_error_handler
goto error_return_verref;
elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
- bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
+ bfd_alloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
if (elf_tdata (abfd)->verref == NULL)
goto error_return_verref;
such a section already exists.
- For the multi-threaded case, a section named "NAME/PID", where
PID is elfcore_make_pid (abfd).
- Both pseudosections have identical contents. */
+ Both pseudosections have identical contents. */
bfd_boolean
_bfd_elfcore_make_pseudosection (bfd *abfd,
char *name,
return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-high", note);
}
+static bfd_boolean
+elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-cb", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note)
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-bc", note);
+}
+
static bfd_boolean
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
{
else
return TRUE;
+ case NT_S390_GS_CB:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_gs_cb (abfd, note);
+ else
+ return TRUE;
+
+ case NT_S390_GS_BC:
+ if (note->namesz == 6
+ && strcmp (note->namedata, "LINUX") == 0)
+ return elfcore_grok_s390_gs_bc (abfd, note);
+ else
+ return TRUE;
+
case NT_ARM_VFP:
if (note->namesz == 6
&& strcmp (note->namedata, "LINUX") == 0)
/* Check for version 1 in pr_version. */
if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
return FALSE;
+
offset = 4;
/* Skip over pr_psinfosz. */
{
size_t offset;
size_t size;
+ size_t min_size;
- /* Check for version 1 in pr_version. */
- if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
- return FALSE;
- offset = 4;
-
- /* Skip over pr_statussz. */
+ /* Compute offset of pr_getregsz, skipping over pr_statussz.
+ Also compute minimum size of this note. */
switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
{
case ELFCLASS32:
- offset += 4;
+ offset = 4 + 4;
+ min_size = offset + (4 * 2) + 4 + 4 + 4;
break;
case ELFCLASS64:
- offset += 4; /* Padding before pr_statussz. */
- offset += 8;
+ offset = 4 + 4 + 8; /* Includes padding before pr_statussz. */
+ min_size = offset + (8 * 2) + 4 + 4 + 4 + 4;
break;
default:
return FALSE;
}
- /* Extract size of pr_reg from pr_gregsetsz. */
- if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
- size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
- else
- size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
+ if (note->descsz < min_size)
+ return FALSE;
- /* Skip over pr_gregsetsz and pr_fpregsetsz. */
+ /* Check for version 1 in pr_version. */
+ if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
+ return FALSE;
+
+ /* Extract size of pr_reg from pr_gregsetsz. */
+ /* Skip over pr_gregsetsz and pr_fpregsetsz. */
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
- offset += 4 * 2;
+ {
+ size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
+ offset += 4 * 2;
+ }
else
- offset += 8 * 2;
+ {
+ size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
+ offset += 8 * 2;
+ }
- /* Skip over pr_osreldate. */
+ /* Skip over pr_osreldate. */
offset += 4;
- /* Read signal from pr_cursig. */
+ /* Read signal from pr_cursig. */
if (elf_tdata (abfd)->core->signal == 0)
elf_tdata (abfd)->core->signal
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
offset += 4;
- /* Read TID from pr_pid. */
+ /* Read TID from pr_pid. */
elf_tdata (abfd)->core->lwpid
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
offset += 4;
- /* Padding before pr_reg. */
+ /* Padding before pr_reg. */
if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
offset += 4;
+ /* Make sure that there is enough data remaining in the note. */
+ if ((note->descsz - offset) < size)
+ return FALSE;
+
/* Make a ".reg/999" section and a ".reg" section. */
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
size, note->descpos + offset);
static bfd_boolean
elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
switch (note->type)
{
case NT_PRSTATUS:
+ if (bed->elf_backend_grok_freebsd_prstatus)
+ if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note))
+ return TRUE;
return elfcore_grok_freebsd_prstatus (abfd, note);
case NT_FPREGSET:
else
return TRUE;
+ case NT_FREEBSD_PTLWPINFO:
+ return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
+ note);
+
+ case NT_ARM_VFP:
+ return elfcore_grok_arm_vfp (abfd, note);
+
default:
return TRUE;
}
static bfd_boolean
elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
{
+ if (note->descsz <= 0x7c + 31)
+ return FALSE;
+
/* Signal number at offset 0x08. */
elf_tdata (abfd)->core->signal
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
static bfd_boolean
elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
{
+ if (note->descsz <= 0x48 + 31)
+ return FALSE;
+
/* Signal number at offset 0x08. */
elf_tdata (abfd)->core->signal
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
short sig;
unsigned flags;
+ if (note->descsz < 16)
+ return FALSE;
+
/* nto_procfs_status 'pid' field is at offset 0. */
elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
(bfd *abfd, char *buf, int *bufsiz,
const struct elf_internal_linux_prpsinfo *prpsinfo)
{
- struct elf_external_linux_prpsinfo32 data;
+ if (get_elf_backend_data (abfd)->linux_prpsinfo32_ugid16)
+ {
+ struct elf_external_linux_prpsinfo32_ugid16 data;
- swap_linux_prpsinfo32_out (abfd, prpsinfo, &data);
- return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
- &data, sizeof (data));
+ swap_linux_prpsinfo32_ugid16_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+ &data, sizeof (data));
+ }
+ else
+ {
+ struct elf_external_linux_prpsinfo32_ugid32 data;
+
+ swap_linux_prpsinfo32_ugid32_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+ &data, sizeof (data));
+ }
}
char *
(bfd *abfd, char *buf, int *bufsiz,
const struct elf_internal_linux_prpsinfo *prpsinfo)
{
- struct elf_external_linux_prpsinfo64 data;
+ if (get_elf_backend_data (abfd)->linux_prpsinfo64_ugid16)
+ {
+ struct elf_external_linux_prpsinfo64_ugid16 data;
- swap_linux_prpsinfo64_out (abfd, prpsinfo, &data);
- return elfcore_write_note (abfd, buf, bufsiz,
- "CORE", NT_PRPSINFO, &data, sizeof (data));
+ swap_linux_prpsinfo64_ugid16_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+ }
+ else
+ {
+ struct elf_external_linux_prpsinfo64_ugid32 data;
+
+ swap_linux_prpsinfo64_ugid32_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+ }
}
char *
s390_vxrs_high, size);
}
+char *
+elfcore_write_s390_gs_cb (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_gs_cb,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_GS_CB,
+ s390_gs_cb, size);
+}
+
+char *
+elfcore_write_s390_gs_bc (bfd *abfd,
+ char *buf,
+ int *bufsiz,
+ const void *s390_gs_bc,
+ int size)
+{
+ char *note_name = "LINUX";
+ return elfcore_write_note (abfd, buf, bufsiz,
+ note_name, NT_S390_GS_BC,
+ s390_gs_bc, size);
+}
+
char *
elfcore_write_arm_vfp (bfd *abfd,
char *buf,
return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-s390-vxrs-high") == 0)
return elfcore_write_s390_vxrs_high (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-gs-cb") == 0)
+ return elfcore_write_s390_gs_cb (abfd, buf, bufsiz, data, size);
+ if (strcmp (section, ".reg-s390-gs-bc") == 0)
+ return elfcore_write_s390_gs_bc (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-arm-vfp") == 0)
return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
if (strcmp (section, ".reg-aarch-tls") == 0)
}
static bfd_boolean
-elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
+elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset,
+ size_t align)
{
char *p;
+ /* NB: CORE PT_NOTE segments may have p_align values of 0 or 1.
+ gABI specifies that PT_NOTE alignment should be aligned to 4
+ bytes for 32-bit objects and to 8 bytes for 64-bit objects. If
+ align is less than 4, we use 4 byte alignment. */
+ if (align < 4)
+ align = 4;
+
p = buf;
while (p < buf + size)
{
- /* FIXME: bad alignment assumption. */
Elf_External_Note *xnp = (Elf_External_Note *) p;
Elf_Internal_Note in;
return FALSE;
in.descsz = H_GET_32 (abfd, xnp->descsz);
- in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
+ in.descdata = p + ELF_NOTE_DESC_OFFSET (in.namesz, align);
in.descpos = offset + (in.descdata - buf);
if (in.descsz != 0
&& (in.descdata >= buf + size
break;
}
- p = in.descdata + BFD_ALIGN (in.descsz, 4);
+ p += ELF_NOTE_NEXT_OFFSET (in.namesz, in.descsz, align);
}
return TRUE;
}
static bfd_boolean
-elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
+elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
+ size_t align)
{
char *buf;
- if (size <= 0)
+ if (size == 0 || (size + 1) == 0)
return TRUE;
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
buf[size] = 0;
if (bfd_bread (buf, size, abfd) != size
- || !elf_parse_notes (abfd, buf, size, offset))
+ || !elf_parse_notes (abfd, buf, size, offset, align))
{
free (buf);
return FALSE;