h ^= g;
}
}
- return h;
+ return h & 0xffffffff;
}
/* Read a specified number of bytes at a specified offset in an ELF
"SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
};
-/* ELF relocs are against symbols. If we are producing relocateable
+/* ELF relocs are against symbols. If we are producing relocatable
output, and the reloc is against an external symbol, and nothing
has given us any additional addend, the resulting reloc will also
be against the same symbol. In such a case, we don't want to
all be done at final link time. Rather than put special case code
into bfd_perform_relocation, all the reloc types use this howto
function. It just short circuits the reloc if producing
- relocateable output against an external symbol. */
+ relocatable output against an external symbol. */
bfd_reloc_status_type
bfd_elf_generic_reloc (abfd,
case PT_PHDR: pt = "PHDR"; break;
case PT_TLS: pt = "TLS"; break;
case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
+ case PT_GNU_STACK: pt = "STACK"; break;
default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break;
}
fprintf (f, "%8s off 0x", pt);
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
- if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ if (! is_elf_hash_table (info))
return NULL;
return elf_hash_table (info)->needed;
}
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
- if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ if (! is_elf_hash_table (info))
return NULL;
return elf_hash_table (info)->runpath;
}
SHF_ALLOC is set, and this is a shared object, then we also
treat this section as a BFD section. We can not base the
decision purely on SHF_ALLOC, because that flag is sometimes
- set in a relocateable object file, which would confuse the
+ set in a relocatable object file, which would confuse the
linker. */
if ((hdr->sh_flags & SHF_ALLOC) != 0
&& (abfd->flags & DYNAMIC) != 0
return _bfd_elf_make_section_from_phdr (abfd, hdr, index,
"eh_frame_hdr");
+ case PT_GNU_STACK:
+ return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack");
+
default:
/* Check for any processor-specific program segment types.
If no handler for them, default to making "segment" sections. */
rel_hdr->sh_entsize = (use_rela_p
? bed->s->sizeof_rela
: bed->s->sizeof_rel);
- rel_hdr->sh_addralign = bed->s->file_align;
+ rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
rel_hdr->sh_flags = 0;
rel_hdr->sh_addr = 0;
rel_hdr->sh_size = 0;
this_hdr = &elf_section_data (asect)->this_hdr;
- this_hdr->sh_name = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd),
- asect->name, FALSE);
- if (this_hdr->sh_name == (unsigned long) -1)
+ this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
+ asect->name, FALSE);
+ if (this_hdr->sh_name == (unsigned int) -1)
{
*failedptr = TRUE;
return;
pm = &m->next;
}
+ if (elf_tdata (abfd)->stack_flags)
+ {
+ amt = sizeof (struct elf_segment_map);
+ m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
+ if (m == NULL)
+ goto error_return;
+ m->next = NULL;
+ m->p_type = PT_GNU_STACK;
+ m->p_flags = elf_tdata (abfd)->stack_flags;
+ m->p_flags_valid = 1;
+
+ *pm = m;
+ pm = &m->next;
+ }
+
free (sections);
sections = NULL;
&& (abfd->flags & D_PAGED) != 0)
p->p_align = bed->maxpagesize;
else if (m->count == 0)
- p->p_align = bed->s->file_align;
+ p->p_align = 1 << bed->s->log_file_align;
else
p->p_align = 0;
++segs;
}
+ if (elf_tdata (abfd)->stack_flags)
+ {
+ /* We need a PT_GNU_STACK segment. */
+ ++segs;
+ }
+
for (s = abfd->sections; s != NULL; s = s->next)
{
if ((s->flags & SEC_LOAD) != 0
}
/* Place the section headers. */
- off = align_file_position (off, bed->s->file_align);
+ off = align_file_position (off, 1 << bed->s->log_file_align);
i_ehdrp->e_shoff = off;
off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
symtab_hdr->sh_entsize = bed->s->sizeof_sym;
symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
- symtab_hdr->sh_addralign = bed->s->file_align;
+ symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
symstrtab_hdr->sh_type = SHT_STRTAB;
#else
return TRUE;
#endif
+
+ case NT_AUXV:
+ {
+ asection *sect = bfd_make_section (abfd, ".auxv");
+
+ if (sect == NULL)
+ return FALSE;
+ sect->_raw_size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
+
+ return TRUE;
+ }
}
}
char buf[100];
char *name;
asection *sect;
+ short sig;
+ unsigned flags;
/* nto_procfs_status 'pid' field is at offset 0. */
elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
- /* nto_procfs_status 'tid' field is at offset 4. */
- elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+ /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */
+ *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
+
+ /* nto_procfs_status 'flags' field is at offset 8. */
+ flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
/* nto_procfs_status 'what' field is at offset 14. */
- elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, (bfd_byte *) ddata + 14);
+ if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
+ {
+ elf_tdata (abfd)->core_signal = sig;
+ elf_tdata (abfd)->core_lwpid = *tid;
+ }
- /* Pass tid back. */
- *tid = elf_tdata (abfd)->core_lwpid;
+ /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores
+ do not come from signals so we make sure we set the current
+ thread just in case. */
+ if (flags & 0x00000080)
+ elf_tdata (abfd)->core_lwpid = *tid;
/* Make a ".qnx_core_status/%d" section. */
sprintf (buf, ".qnx_core_status/%d", *tid);
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
- return elfcore_maybe_make_sect (abfd, ".reg", sect);
+ /* This is the current thread. */
+ if (elf_tdata (abfd)->core_lwpid == tid)
+ return elfcore_maybe_make_sect (abfd, ".reg", sect);
+
+ return TRUE;
}
#define BFD_QNT_CORE_INFO 7
namesz = strlen (name) + 1;
bed = get_elf_backend_data (abfd);
- pad = -namesz & (bed->s->file_align - 1);
+ pad = -namesz & ((1 << bed->s->log_file_align) - 1);
}
newspace = sizeof (Elf_External_Note) - 1 + namesz + pad + size;
return offset;
}
}
+\f
+/* Create a new BFD as if by bfd_openr. Rather than opening a file,
+ reconstruct an ELF file by reading the segments out of remote memory
+ based on the ELF file header at EHDR_VMA and the ELF program headers it
+ points to. If not null, *LOADBASEP is filled in with the difference
+ between the VMAs from which the segments were read, and the VMAs the
+ file headers (and hence BFD's idea of each section's VMA) put them at.
+
+ The function TARGET_READ_MEMORY is called to copy LEN bytes from the
+ remote memory at target address VMA into the local buffer at MYADDR; it
+ should return zero on success or an `errno' code on failure. TEMPL must
+ be a BFD for an ELF target with the word size and byte order found in
+ the remote memory. */
+
+bfd *
+bfd_elf_bfd_from_remote_memory (templ, ehdr_vma, loadbasep, target_read_memory)
+ bfd *templ;
+ bfd_vma ehdr_vma;
+ bfd_vma *loadbasep;
+ int (*target_read_memory) PARAMS ((bfd_vma vma, char *myaddr, int len));
+{
+ return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
+ (templ, ehdr_vma, loadbasep, target_read_memory);
+}