Index: bfd/elf.c |
diff --git a/bfd/elf.c b/bfd/elf.c |
index 48e5d68341354e0d6915c8d9659e5cc6885d71d8..8df38ee37923c020994715f111a0ffc6bae83c8c 100644 |
--- a/bfd/elf.c |
+++ b/bfd/elf.c |
@@ -1,8 +1,6 @@ |
/* ELF executable support for BFD. |
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 |
- Free Software Foundation, Inc. |
+ Copyright 1993-2013 Free Software Foundation, Inc. |
This file is part of BFD, the Binary File Descriptor library. |
@@ -44,6 +42,7 @@ SECTION |
#include "elf-bfd.h" |
#include "libiberty.h" |
#include "safe-ctype.h" |
+#include "elf-linux-psinfo.h" |
#ifdef CORE_HEADER |
#include CORE_HEADER |
@@ -244,7 +243,14 @@ bfd_elf_allocate_object (bfd *abfd, |
return FALSE; |
elf_object_id (abfd) = object_id; |
- elf_program_header_size (abfd) = (bfd_size_type) -1; |
+ if (abfd->direction != read_direction) |
+ { |
+ struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o); |
+ if (o == NULL) |
+ return FALSE; |
+ elf_tdata (abfd)->o = o; |
+ elf_program_header_size (abfd) = (bfd_size_type) -1; |
+ } |
return TRUE; |
} |
@@ -261,7 +267,10 @@ bfd_boolean |
bfd_elf_mkcorefile (bfd *abfd) |
{ |
/* I think this can be done just like an object file. */ |
- return abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd); |
+ if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd)) |
+ return FALSE; |
+ elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core)); |
+ return elf_tdata (abfd)->core != NULL; |
} |
static char * |
@@ -545,9 +554,9 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) |
shnum = elf_numsections (abfd); |
num_group = 0; |
-#define IS_VALID_GROUP_SECTION_HEADER(shdr) \ |
+#define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize) \ |
( (shdr)->sh_type == SHT_GROUP \ |
- && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE) \ |
+ && (shdr)->sh_size >= minsize \ |
&& (shdr)->sh_entsize == GRP_ENTRY_SIZE \ |
&& ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0) |
@@ -555,7 +564,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) |
{ |
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; |
- if (IS_VALID_GROUP_SECTION_HEADER (shdr)) |
+ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE)) |
num_group += 1; |
} |
@@ -581,7 +590,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect) |
{ |
Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i]; |
- if (IS_VALID_GROUP_SECTION_HEADER (shdr)) |
+ if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE)) |
{ |
unsigned char *src; |
Elf_Internal_Group *dest; |
@@ -880,45 +889,25 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, |
{ |
/* The debugging sections appear to be recognized only by name, |
not any sort of flag. Their SEC_ALLOC bits are cleared. */ |
- static const struct |
- { |
- const char *name; |
- int len; |
- } debug_sections [] = |
- { |
- { STRING_COMMA_LEN ("debug") }, /* 'd' */ |
- { NULL, 0 }, /* 'e' */ |
- { NULL, 0 }, /* 'f' */ |
- { STRING_COMMA_LEN ("gnu.linkonce.wi.") }, /* 'g' */ |
- { NULL, 0 }, /* 'h' */ |
- { NULL, 0 }, /* 'i' */ |
- { NULL, 0 }, /* 'j' */ |
- { NULL, 0 }, /* 'k' */ |
- { STRING_COMMA_LEN ("line") }, /* 'l' */ |
- { NULL, 0 }, /* 'm' */ |
- { NULL, 0 }, /* 'n' */ |
- { NULL, 0 }, /* 'o' */ |
- { NULL, 0 }, /* 'p' */ |
- { NULL, 0 }, /* 'q' */ |
- { NULL, 0 }, /* 'r' */ |
- { STRING_COMMA_LEN ("stab") }, /* 's' */ |
- { NULL, 0 }, /* 't' */ |
- { NULL, 0 }, /* 'u' */ |
- { NULL, 0 }, /* 'v' */ |
- { NULL, 0 }, /* 'w' */ |
- { NULL, 0 }, /* 'x' */ |
- { NULL, 0 }, /* 'y' */ |
- { STRING_COMMA_LEN ("zdebug") } /* 'z' */ |
- }; |
- |
if (name [0] == '.') |
{ |
- int i = name [1] - 'd'; |
- if (i >= 0 |
- && i < (int) ARRAY_SIZE (debug_sections) |
- && debug_sections [i].name != NULL |
- && strncmp (&name [1], debug_sections [i].name, |
- debug_sections [i].len) == 0) |
+ const char *p; |
+ int n; |
+ if (name[1] == 'd') |
+ p = ".debug", n = 6; |
+ else if (name[1] == 'g' && name[2] == 'n') |
+ p = ".gnu.linkonce.wi.", n = 17; |
+ else if (name[1] == 'g' && name[2] == 'd') |
+ p = ".gdb_index", n = 11; /* yes we really do mean 11. */ |
+ else if (name[1] == 'l') |
+ p = ".line", n = 5; |
+ else if (name[1] == 's') |
+ p = ".stab", n = 5; |
+ else if (name[1] == 'z') |
+ p = ".zdebug", n = 7; |
+ else |
+ p = NULL, n = 0; |
+ if (p != NULL && strncmp (name, p, n) == 0) |
flags |= SEC_DEBUGGING; |
} |
} |
@@ -1454,9 +1443,9 @@ bfd_elf_print_symbol (bfd *abfd, |
bfd_fprintf_vma (abfd, file, val); |
/* If we have version information, print it. */ |
- if (elf_tdata (abfd)->dynversym_section != 0 |
- && (elf_tdata (abfd)->dynverdef_section != 0 |
- || elf_tdata (abfd)->dynverref_section != 0)) |
+ if (elf_dynversym (abfd) != 0 |
+ && (elf_dynverdef (abfd) != 0 |
+ || elf_dynverref (abfd) != 0)) |
{ |
unsigned int vernum; |
const char *version_string; |
@@ -1929,7 +1918,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) |
return TRUE; |
case SHT_GROUP: |
- if (! IS_VALID_GROUP_SECTION_HEADER (hdr)) |
+ if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE)) |
return FALSE; |
if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) |
return FALSE; |
@@ -2081,6 +2070,9 @@ static const struct bfd_elf_special_section special_sections_d[] = |
{ |
{ STRING_COMMA_LEN (".data"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
{ STRING_COMMA_LEN (".data1"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, |
+ /* There are more DWARF sections than these, but they needn't be added here |
+ unless you have to cope with broken compilers that don't emit section |
+ attributes or you want to help the user writing assembler. */ |
{ STRING_COMMA_LEN (".debug"), 0, SHT_PROGBITS, 0 }, |
{ STRING_COMMA_LEN (".debug_line"), 0, SHT_PROGBITS, 0 }, |
{ STRING_COMMA_LEN (".debug_info"), 0, SHT_PROGBITS, 0 }, |
@@ -2529,7 +2521,7 @@ _bfd_elf_single_rel_hdr (asection *sec) |
USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL |
relocations. */ |
-bfd_boolean |
+static bfd_boolean |
_bfd_elf_init_reloc_shdr (bfd *abfd, |
struct bfd_elf_section_reloc_data *reldata, |
asection *asect, |
@@ -2989,9 +2981,9 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) |
d->rela.idx = 0; |
} |
- t->shstrtab_section = section_number++; |
+ elf_shstrtab_sec (abfd) = section_number++; |
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name); |
- elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section; |
+ elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd); |
need_symtab = (bfd_get_symcount (abfd) > 0 |
|| (link_info == NULL |
@@ -2999,18 +2991,18 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) |
== HAS_RELOC))); |
if (need_symtab) |
{ |
- t->symtab_section = section_number++; |
+ elf_onesymtab (abfd) = section_number++; |
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name); |
if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF)) |
{ |
- t->symtab_shndx_section = section_number++; |
+ elf_symtab_shndx (abfd) = section_number++; |
t->symtab_shndx_hdr.sh_name |
= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), |
".symtab_shndx", FALSE); |
if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1) |
return FALSE; |
} |
- t->strtab_section = section_number++; |
+ elf_strtab_sec (abfd) = section_number++; |
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name); |
} |
@@ -3044,17 +3036,17 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) |
elf_elfsections (abfd) = i_shdrp; |
- i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr; |
+ i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr; |
if (need_symtab) |
{ |
- i_shdrp[t->symtab_section] = &t->symtab_hdr; |
+ i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr; |
if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) |
{ |
- i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr; |
- t->symtab_shndx_hdr.sh_link = t->symtab_section; |
+ i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr; |
+ t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd); |
} |
- i_shdrp[t->strtab_section] = &t->strtab_hdr; |
- t->symtab_hdr.sh_link = t->strtab_section; |
+ i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr; |
+ t->symtab_hdr.sh_link = elf_strtab_sec (abfd); |
} |
for (sec = abfd->sections; sec; sec = sec->next) |
@@ -3077,12 +3069,12 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) |
the relocation entries apply. */ |
if (d->rel.idx != 0) |
{ |
- d->rel.hdr->sh_link = t->symtab_section; |
+ d->rel.hdr->sh_link = elf_onesymtab (abfd); |
d->rel.hdr->sh_info = d->this_idx; |
} |
if (d->rela.idx != 0) |
{ |
- d->rela.hdr->sh_link = t->symtab_section; |
+ d->rela.hdr->sh_link = elf_onesymtab (abfd); |
d->rela.hdr->sh_info = d->this_idx; |
} |
@@ -3237,7 +3229,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) |
break; |
case SHT_GROUP: |
- d->this_hdr.sh_link = t->symtab_section; |
+ d->this_hdr.sh_link = elf_onesymtab (abfd); |
} |
} |
@@ -3264,13 +3256,21 @@ sym_is_global (bfd *abfd, asymbol *sym) |
} |
/* Don't output section symbols for sections that are not going to be |
- output, or that are duplicates. */ |
+ output, that are duplicates or there is no BFD section. */ |
static bfd_boolean |
ignore_section_sym (bfd *abfd, asymbol *sym) |
{ |
- return ((sym->flags & BSF_SECTION_SYM) != 0 |
- && !(sym->section->owner == abfd |
+ elf_symbol_type *type_ptr; |
+ |
+ if ((sym->flags & BSF_SECTION_SYM) == 0) |
+ return FALSE; |
+ |
+ type_ptr = elf_symbol_from (abfd, sym); |
+ return ((type_ptr != NULL |
+ && type_ptr->internal_elf_sym.st_shndx != 0 |
+ && bfd_is_abs_section (sym->section)) |
+ || !(sym->section->owner == abfd |
|| (sym->section->output_section->owner == abfd |
&& sym->section->output_offset == 0) |
|| bfd_is_abs_section (sym->section))); |
@@ -3280,7 +3280,7 @@ ignore_section_sym (bfd *abfd, asymbol *sym) |
all local symbols to be at the head of the list. */ |
static bfd_boolean |
-elf_map_symbols (bfd *abfd) |
+elf_map_symbols (bfd *abfd, unsigned int *pnum_locals) |
{ |
unsigned int symcount = bfd_get_symcount (abfd); |
asymbol **syms = bfd_get_outsymbols (abfd); |
@@ -3396,8 +3396,7 @@ elf_map_symbols (bfd *abfd) |
bfd_set_symtab (abfd, new_syms, num_locals + num_globals); |
- elf_num_locals (abfd) = num_locals; |
- elf_num_globals (abfd) = num_globals; |
+ *pnum_locals = num_locals; |
return TRUE; |
} |
@@ -3508,7 +3507,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd, |
file_ptr off; |
Elf_Internal_Shdr *hdr; |
- off = elf_tdata (abfd)->next_file_pos; |
+ off = elf_next_file_pos (abfd); |
hdr = &elf_tdata (abfd)->symtab_hdr; |
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); |
@@ -3520,7 +3519,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd, |
hdr = &elf_tdata (abfd)->strtab_hdr; |
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); |
- elf_tdata (abfd)->next_file_pos = off; |
+ elf_next_file_pos (abfd) = off; |
/* Now that we know where the .strtab section goes, write it |
out. */ |
@@ -3571,13 +3570,13 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info) |
++segs; |
} |
- if (elf_tdata (abfd)->eh_frame_hdr) |
+ if (elf_eh_frame_hdr (abfd)) |
{ |
/* We need a PT_GNU_EH_FRAME segment. */ |
++segs; |
} |
- if (elf_tdata (abfd)->stack_flags) |
+ if (elf_stack_flags (abfd)) |
{ |
/* We need a PT_GNU_STACK segment. */ |
++segs; |
@@ -3639,8 +3638,7 @@ _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section) |
struct elf_segment_map *m; |
Elf_Internal_Phdr *p; |
- for (m = elf_tdata (abfd)->segment_map, |
- p = elf_tdata (abfd)->phdr; |
+ for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr; |
m != NULL; |
m = m->next, p++) |
{ |
@@ -3724,7 +3722,7 @@ elf_modify_segment_map (bfd *abfd, |
sections from the segment map. We also remove excluded |
sections. Finally, any PT_LOAD segment without sections is |
removed. */ |
- m = &elf_tdata (abfd)->segment_map; |
+ m = &elf_seg_map (abfd); |
while (*m) |
{ |
unsigned int i, new_count; |
@@ -3768,7 +3766,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
bfd_boolean no_user_phdrs; |
- no_user_phdrs = elf_tdata (abfd)->segment_map == NULL; |
+ no_user_phdrs = elf_seg_map (abfd) == NULL; |
if (info != NULL) |
info->user_phdrs = !no_user_phdrs; |
@@ -3879,10 +3877,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
program headers we will need. */ |
if (count > 0) |
{ |
- bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; |
+ bfd_size_type phdr_size = elf_program_header_size (abfd); |
if (phdr_size == (bfd_size_type) -1) |
phdr_size = get_program_header_size (abfd, info); |
+ phdr_size += bed->s->sizeof_ehdr; |
if ((abfd->flags & D_PAGED) == 0 |
|| (sections[0]->lma & addr_mask) < phdr_size |
|| ((sections[0]->lma & addr_mask) % maxpagesize |
@@ -4123,7 +4122,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
/* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME |
segment. */ |
- eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr; |
+ eh_frame_hdr = elf_eh_frame_hdr (abfd); |
if (eh_frame_hdr != NULL |
&& (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0) |
{ |
@@ -4140,7 +4139,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
pm = &m->next; |
} |
- if (elf_tdata (abfd)->stack_flags) |
+ if (elf_stack_flags (abfd)) |
{ |
amt = sizeof (struct elf_segment_map); |
m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); |
@@ -4148,8 +4147,15 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
goto error_return; |
m->next = NULL; |
m->p_type = PT_GNU_STACK; |
- m->p_flags = elf_tdata (abfd)->stack_flags; |
+ m->p_flags = elf_stack_flags (abfd); |
+ m->p_align = bed->stack_align; |
m->p_flags_valid = 1; |
+ m->p_align_valid = m->p_align != 0; |
+ if (info->stacksize > 0) |
+ { |
+ m->p_size = info->stacksize; |
+ m->p_size_valid = 1; |
+ } |
*pm = m; |
pm = &m->next; |
@@ -4197,15 +4203,15 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) |
} |
free (sections); |
- elf_tdata (abfd)->segment_map = mfirst; |
+ elf_seg_map (abfd) = mfirst; |
} |
if (!elf_modify_segment_map (abfd, info, no_user_phdrs)) |
return FALSE; |
- for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) |
+ for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next) |
++count; |
- elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr; |
+ elf_program_header_size (abfd) = count * bed->s->sizeof_phdr; |
return TRUE; |
@@ -4369,7 +4375,7 @@ assign_file_positions_for_load_sections (bfd *abfd, |
return FALSE; |
alloc = 0; |
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) |
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next) |
{ |
++alloc; |
if (m->header_size) |
@@ -4390,32 +4396,32 @@ assign_file_positions_for_load_sections (bfd *abfd, |
elf_elfheader (abfd)->e_phnum = alloc; |
- if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1) |
- elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr; |
+ if (elf_program_header_size (abfd) == (bfd_size_type) -1) |
+ elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr; |
else |
- BFD_ASSERT (elf_tdata (abfd)->program_header_size |
+ BFD_ASSERT (elf_program_header_size (abfd) |
>= alloc * bed->s->sizeof_phdr); |
if (alloc == 0) |
{ |
- elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr; |
+ elf_next_file_pos (abfd) = bed->s->sizeof_ehdr; |
return TRUE; |
} |
- /* We're writing the size in elf_tdata (abfd)->program_header_size, |
+ /* We're writing the size in elf_program_header_size (abfd), |
see assign_file_positions_except_relocs, so make sure we have |
that amount allocated, with trailing space cleared. |
- The variable alloc contains the computed need, while elf_tdata |
- (abfd)->program_header_size contains the size used for the |
+ The variable alloc contains the computed need, while |
+ elf_program_header_size (abfd) contains the size used for the |
layout. |
See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments |
where the layout is forced to according to a larger size in the |
last iterations for the testcase ld-elf/header. */ |
- BFD_ASSERT (elf_tdata (abfd)->program_header_size % bed->s->sizeof_phdr |
+ BFD_ASSERT (elf_program_header_size (abfd) % bed->s->sizeof_phdr |
== 0); |
phdrs = (Elf_Internal_Phdr *) |
bfd_zalloc2 (abfd, |
- (elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr), |
+ (elf_program_header_size (abfd) / bed->s->sizeof_phdr), |
sizeof (Elf_Internal_Phdr)); |
elf_tdata (abfd)->phdr = phdrs; |
if (phdrs == NULL) |
@@ -4433,7 +4439,7 @@ assign_file_positions_for_load_sections (bfd *abfd, |
header_pad -= off; |
off += header_pad; |
- for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0; |
+ for (m = elf_seg_map (abfd), p = phdrs, j = 0; |
m != NULL; |
m = m->next, p++, j++) |
{ |
@@ -4814,7 +4820,7 @@ assign_file_positions_for_load_sections (bfd *abfd, |
} |
} |
- elf_tdata (abfd)->next_file_pos = off; |
+ elf_next_file_pos (abfd) = off; |
return TRUE; |
} |
@@ -4840,10 +4846,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
i_shdrpp = elf_elfsections (abfd); |
num_sec = elf_numsections (abfd); |
- off = elf_tdata (abfd)->next_file_pos; |
+ off = elf_next_file_pos (abfd); |
for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++) |
{ |
- struct elf_obj_tdata *tdata = elf_tdata (abfd); |
Elf_Internal_Shdr *hdr; |
hdr = *hdrpp; |
@@ -4873,9 +4878,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
} |
else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) |
&& hdr->bfd_section == NULL) |
- || hdr == i_shdrpp[tdata->symtab_section] |
- || hdr == i_shdrpp[tdata->symtab_shndx_section] |
- || hdr == i_shdrpp[tdata->strtab_section]) |
+ || hdr == i_shdrpp[elf_onesymtab (abfd)] |
+ || hdr == i_shdrpp[elf_symtab_shndx (abfd)] |
+ || hdr == i_shdrpp[elf_strtab_sec (abfd)]) |
hdr->sh_offset = -1; |
else |
off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE); |
@@ -4890,9 +4895,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
phdrs_paddr = 0; |
hdrs_segment = NULL; |
phdrs = elf_tdata (abfd)->phdr; |
- for (m = elf_tdata (abfd)->segment_map, p = phdrs; |
- m != NULL; |
- m = m->next, p++) |
+ for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++) |
{ |
++count; |
if (p->p_type != PT_LOAD) |
@@ -4938,7 +4941,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
s = hdrs_segment->sections[0]; |
else |
/* Use the first (i.e. lowest-addressed) section in any segment. */ |
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) |
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next) |
if (m->count != 0) |
{ |
s = m->sections[0]; |
@@ -4962,9 +4965,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
} |
} |
- for (m = elf_tdata (abfd)->segment_map, p = phdrs; |
- m != NULL; |
- m = m->next, p++) |
+ for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++) |
{ |
if (p->p_type == PT_GNU_RELRO) |
{ |
@@ -4975,7 +4976,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
{ |
/* During linking the range of the RELRO segment is passed |
in link_info. */ |
- for (lm = elf_tdata (abfd)->segment_map, lp = phdrs; |
+ for (lm = elf_seg_map (abfd), lp = phdrs; |
lm != NULL; |
lm = lm->next, lp++) |
{ |
@@ -5031,6 +5032,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
p->p_type = PT_NULL; |
} |
} |
+ else if (p->p_type == PT_GNU_STACK) |
+ { |
+ if (m->p_size_valid) |
+ p->p_memsz = m->p_size; |
+ } |
else if (m->count != 0) |
{ |
if (p->p_type != PT_LOAD |
@@ -5068,7 +5074,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, |
} |
} |
- elf_tdata (abfd)->next_file_pos = off; |
+ elf_next_file_pos (abfd) = off; |
return TRUE; |
} |
@@ -5117,9 +5123,9 @@ assign_file_positions_except_relocs (bfd *abfd, |
hdr = *hdrpp; |
if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA) |
&& hdr->bfd_section == NULL) |
- || i == tdata->symtab_section |
- || i == tdata->symtab_shndx_section |
- || i == tdata->strtab_section) |
+ || i == elf_onesymtab (abfd) |
+ || i == elf_symtab_shndx (abfd) |
+ || i == elf_strtab_sec (abfd)) |
{ |
hdr->sh_offset = -1; |
} |
@@ -5147,12 +5153,12 @@ assign_file_positions_except_relocs (bfd *abfd, |
} |
/* Write out the program headers. */ |
- alloc = tdata->program_header_size / bed->s->sizeof_phdr; |
+ alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr; |
if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 |
|| bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0) |
return FALSE; |
- off = tdata->next_file_pos; |
+ off = elf_next_file_pos (abfd); |
} |
/* Place the section headers. */ |
@@ -5160,7 +5166,7 @@ assign_file_positions_except_relocs (bfd *abfd, |
i_ehdrp->e_shoff = off; |
off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize; |
- tdata->next_file_pos = off; |
+ elf_next_file_pos (abfd) = off; |
return TRUE; |
} |
@@ -5263,7 +5269,7 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd) |
unsigned int i, num_sec; |
Elf_Internal_Shdr **shdrpp; |
- off = elf_tdata (abfd)->next_file_pos; |
+ off = elf_next_file_pos (abfd); |
num_sec = elf_numsections (abfd); |
for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++) |
@@ -5276,7 +5282,7 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd) |
off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE); |
} |
- elf_tdata (abfd)->next_file_pos = off; |
+ elf_next_file_pos (abfd) = off; |
} |
bfd_boolean |
@@ -5286,6 +5292,7 @@ _bfd_elf_write_object_contents (bfd *abfd) |
Elf_Internal_Shdr **i_shdrp; |
bfd_boolean failed; |
unsigned int count, num_sec; |
+ struct elf_obj_tdata *t; |
if (! abfd->output_has_begun |
&& ! _bfd_elf_compute_section_file_positions (abfd, NULL)) |
@@ -5317,21 +5324,21 @@ _bfd_elf_write_object_contents (bfd *abfd) |
} |
/* Write out the section header names. */ |
+ t = elf_tdata (abfd); |
if (elf_shstrtab (abfd) != NULL |
- && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0 |
+ && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0 |
|| !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))) |
return FALSE; |
if (bed->elf_backend_final_write_processing) |
- (*bed->elf_backend_final_write_processing) (abfd, |
- elf_tdata (abfd)->linker); |
+ (*bed->elf_backend_final_write_processing) (abfd, elf_linker (abfd)); |
if (!bed->s->write_shdrs_and_ehdr (abfd)) |
return FALSE; |
/* This is last since write_shdrs_and_ehdr can touch i_shdrp[0]. */ |
- if (elf_tdata (abfd)->after_write_object_contents) |
- return (*elf_tdata (abfd)->after_write_object_contents) (abfd); |
+ if (t->o->build_id.after_write_object_contents != NULL) |
+ return (*t->o->build_id.after_write_object_contents) (abfd); |
return TRUE; |
} |
@@ -6040,7 +6047,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) |
and carry on looping. */ |
amt = sizeof (struct elf_segment_map); |
amt += ((bfd_size_type) section_count - 1) * sizeof (asection *); |
- map = (struct elf_segment_map *) bfd_alloc (obfd, amt); |
+ map = (struct elf_segment_map *) bfd_zalloc (obfd, amt); |
if (map == NULL) |
{ |
free (sections); |
@@ -6065,7 +6072,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) |
free (sections); |
} |
- elf_tdata (obfd)->segment_map = map_first; |
+ elf_seg_map (obfd) = map_first; |
/* If we had to estimate the number of program headers that were |
going to be needed, then check our estimate now and adjust |
@@ -6175,12 +6182,15 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) |
map->p_align_valid = 1; |
map->p_vaddr_offset = 0; |
- if (map->p_type == PT_GNU_RELRO) |
+ if (map->p_type == PT_GNU_RELRO |
+ || map->p_type == PT_GNU_STACK) |
{ |
/* The PT_GNU_RELRO segment may contain the first a few |
bytes in the .got.plt section even if the whole .got.plt |
section isn't in the PT_GNU_RELRO segment. We won't |
- change the size of the PT_GNU_RELRO segment. */ |
+ change the size of the PT_GNU_RELRO segment. |
+ Similarly, PT_GNU_STACK size is significant on uclinux |
+ systems. */ |
map->p_size = segment->p_memsz; |
map->p_size_valid = 1; |
} |
@@ -6216,12 +6226,13 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) |
if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) |
{ |
map->sections[isec++] = section->output_section; |
- if (section->lma < lowest_section->lma) |
- lowest_section = section; |
if ((section->flags & SEC_ALLOC) != 0) |
{ |
bfd_vma seg_off; |
+ if (section->lma < lowest_section->lma) |
+ lowest_section = section; |
+ |
/* Section lmas are set up from PT_LOAD header |
p_paddr in _bfd_elf_make_section_from_shdr. |
If this header has a p_paddr that disagrees |
@@ -6256,7 +6267,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) |
pointer_to_map = &map->next; |
} |
- elf_tdata (obfd)->segment_map = map_first; |
+ elf_seg_map (obfd) = map_first; |
return TRUE; |
} |
@@ -6350,6 +6361,26 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd) |
} |
rewrite: |
+ if (ibfd->xvec == obfd->xvec) |
+ { |
+ /* When rewriting program header, set the output maxpagesize to |
+ the maximum alignment of input PT_LOAD segments. */ |
+ Elf_Internal_Phdr *segment; |
+ unsigned int i; |
+ unsigned int num_segments = elf_elfheader (ibfd)->e_phnum; |
+ bfd_vma maxpagesize = 0; |
+ |
+ for (i = 0, segment = elf_tdata (ibfd)->phdr; |
+ i < num_segments; |
+ i++, segment++) |
+ if (segment->p_type == PT_LOAD |
+ && maxpagesize < segment->p_align) |
+ maxpagesize = segment->p_align; |
+ |
+ if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize) |
+ bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize); |
+ } |
+ |
return rewrite_elf_program_header (ibfd, obfd); |
} |
@@ -6527,7 +6558,7 @@ _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd) |
entry point, because the latter is called after the section |
contents have been set, which means that the program headers have |
already been worked out. */ |
- if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL) |
+ if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL) |
{ |
if (! copy_private_bfd_data (ibfd, obfd)) |
return FALSE; |
@@ -6575,11 +6606,11 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd, |
shndx = MAP_ONESYMTAB; |
else if (shndx == elf_dynsymtab (ibfd)) |
shndx = MAP_DYNSYMTAB; |
- else if (shndx == elf_tdata (ibfd)->strtab_section) |
+ else if (shndx == elf_strtab_sec (ibfd)) |
shndx = MAP_STRTAB; |
- else if (shndx == elf_tdata (ibfd)->shstrtab_section) |
+ else if (shndx == elf_shstrtab_sec (ibfd)) |
shndx = MAP_SHSTRTAB; |
- else if (shndx == elf_tdata (ibfd)->symtab_shndx_section) |
+ else if (shndx == elf_symtab_shndx (ibfd)) |
shndx = MAP_SYM_SHNDX; |
osym->internal_elf_sym.st_shndx = shndx; |
} |
@@ -6604,10 +6635,11 @@ swap_out_syms (bfd *abfd, |
bfd_byte *outbound_syms; |
bfd_byte *outbound_shndx; |
int idx; |
+ unsigned int num_locals; |
bfd_size_type amt; |
bfd_boolean name_local_sections; |
- if (!elf_map_symbols (abfd)) |
+ if (!elf_map_symbols (abfd, &num_locals)) |
return FALSE; |
/* Dump out the symtabs. */ |
@@ -6621,7 +6653,7 @@ swap_out_syms (bfd *abfd, |
symtab_hdr->sh_type = SHT_SYMTAB; |
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_info = num_locals + 1; |
symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align; |
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; |
@@ -6755,15 +6787,16 @@ swap_out_syms (bfd *abfd, |
shndx = elf_dynsymtab (abfd); |
break; |
case MAP_STRTAB: |
- shndx = elf_tdata (abfd)->strtab_section; |
+ shndx = elf_strtab_sec (abfd); |
break; |
case MAP_SHSTRTAB: |
- shndx = elf_tdata (abfd)->shstrtab_section; |
+ shndx = elf_shstrtab_sec (abfd); |
break; |
case MAP_SYM_SHNDX: |
- shndx = elf_tdata (abfd)->symtab_shndx_section; |
+ shndx = elf_symtab_shndx (abfd); |
break; |
default: |
+ shndx = SHN_ABS; |
break; |
} |
} |
@@ -7356,7 +7389,7 @@ error_return_verdef: |
Elf_Internal_Verdef *iverdef; |
Elf_Internal_Verdaux *iverdaux; |
- iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];; |
+ iverdef = &elf_tdata (abfd)->verdef[freeidx - 1]; |
iverdef->vd_version = VER_DEF_CURRENT; |
iverdef->vd_flags = 0; |
@@ -7474,18 +7507,29 @@ elf_find_function (bfd *abfd, |
const char **filename_ptr, |
const char **functionname_ptr) |
{ |
- static asection *last_section; |
- static asymbol *func; |
- static const char *filename; |
- static bfd_size_type func_size; |
+ struct elf_find_function_cache |
+ { |
+ asection *last_section; |
+ asymbol *func; |
+ const char *filename; |
+ bfd_size_type func_size; |
+ } *cache; |
if (symbols == NULL) |
return FALSE; |
- if (last_section != section |
- || func == NULL |
- || offset < func->value |
- || offset >= func->value + func_size) |
+ cache = elf_tdata (abfd)->elf_find_function_cache; |
+ if (cache == NULL) |
+ { |
+ cache = bfd_zalloc (abfd, sizeof (*cache)); |
+ elf_tdata (abfd)->elf_find_function_cache = cache; |
+ if (cache == NULL) |
+ return FALSE; |
+ } |
+ if (cache->last_section != section |
+ || cache->func == NULL |
+ || offset < cache->func->value |
+ || offset >= cache->func->value + cache->func_size) |
{ |
asymbol *file; |
bfd_vma low_func; |
@@ -7501,13 +7545,13 @@ elf_find_function (bfd *abfd, |
enum { nothing_seen, symbol_seen, file_after_symbol_seen } state; |
const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
- filename = NULL; |
- func = NULL; |
file = NULL; |
low_func = 0; |
state = nothing_seen; |
- func_size = 0; |
- last_section = section; |
+ cache->filename = NULL; |
+ cache->func = NULL; |
+ cache->func_size = 0; |
+ cache->last_section = section; |
for (p = symbols; *p != NULL; p++) |
{ |
@@ -7528,29 +7572,29 @@ elf_find_function (bfd *abfd, |
&& code_off <= offset |
&& (code_off > low_func |
|| (code_off == low_func |
- && size > func_size))) |
+ && size > cache->func_size))) |
{ |
- func = sym; |
- func_size = size; |
+ cache->func = sym; |
+ cache->func_size = size; |
+ cache->filename = NULL; |
low_func = code_off; |
- filename = NULL; |
if (file != NULL |
&& ((sym->flags & BSF_LOCAL) != 0 |
|| state != file_after_symbol_seen)) |
- filename = bfd_asymbol_name (file); |
+ cache->filename = bfd_asymbol_name (file); |
} |
if (state == nothing_seen) |
state = symbol_seen; |
} |
} |
- if (func == NULL) |
+ if (cache->func == NULL) |
return FALSE; |
if (filename_ptr) |
- *filename_ptr = filename; |
+ *filename_ptr = cache->filename; |
if (functionname_ptr) |
- *functionname_ptr = bfd_asymbol_name (func); |
+ *functionname_ptr = bfd_asymbol_name (cache->func); |
return TRUE; |
} |
@@ -7567,6 +7611,23 @@ _bfd_elf_find_nearest_line (bfd *abfd, |
const char **functionname_ptr, |
unsigned int *line_ptr) |
{ |
+ return _bfd_elf_find_nearest_line_discriminator (abfd, section, symbols, |
+ offset, filename_ptr, |
+ functionname_ptr, |
+ line_ptr, |
+ NULL); |
+} |
+ |
+bfd_boolean |
+_bfd_elf_find_nearest_line_discriminator (bfd *abfd, |
+ asection *section, |
+ asymbol **symbols, |
+ bfd_vma offset, |
+ const char **filename_ptr, |
+ const char **functionname_ptr, |
+ unsigned int *line_ptr, |
+ unsigned int *discriminator_ptr) |
+{ |
bfd_boolean found; |
if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, |
@@ -7584,7 +7645,7 @@ _bfd_elf_find_nearest_line (bfd *abfd, |
if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, |
section, symbols, offset, |
filename_ptr, functionname_ptr, |
- line_ptr, 0, |
+ line_ptr, discriminator_ptr, 0, |
&elf_tdata (abfd)->dwarf2_find_line_info)) |
{ |
if (!*functionname_ptr) |
@@ -7620,8 +7681,19 @@ bfd_boolean |
_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, |
const char **filename_ptr, unsigned int *line_ptr) |
{ |
+ return _bfd_elf_find_line_discriminator (abfd, symbols, symbol, |
+ filename_ptr, line_ptr, |
+ NULL); |
+} |
+ |
+bfd_boolean |
+_bfd_elf_find_line_discriminator (bfd *abfd, asymbol **symbols, asymbol *symbol, |
+ const char **filename_ptr, |
+ unsigned int *line_ptr, |
+ unsigned int *discriminator_ptr) |
+{ |
return _bfd_dwarf2_find_line (abfd, symbols, symbol, |
- filename_ptr, line_ptr, 0, |
+ filename_ptr, line_ptr, discriminator_ptr, 0, |
&elf_tdata (abfd)->dwarf2_find_line_info); |
} |
@@ -7652,21 +7724,21 @@ _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info) |
if (!info->relocatable) |
{ |
- bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size; |
+ bfd_size_type phdr_size = elf_program_header_size (abfd); |
if (phdr_size == (bfd_size_type) -1) |
{ |
struct elf_segment_map *m; |
phdr_size = 0; |
- for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) |
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next) |
phdr_size += bed->s->sizeof_phdr; |
if (phdr_size == 0) |
phdr_size = get_program_header_size (abfd, info); |
} |
- elf_tdata (abfd)->program_header_size = phdr_size; |
+ elf_program_header_size (abfd) = phdr_size; |
ret += phdr_size; |
} |
@@ -7806,7 +7878,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd) |
struct elf_obj_tdata *tdata = elf_tdata (abfd); |
if (bfd_get_format (abfd) == bfd_object && tdata != NULL) |
{ |
- if (elf_shstrtab (abfd) != NULL) |
+ if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL) |
_bfd_elf_strtab_free (elf_shstrtab (abfd)); |
_bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info); |
} |
@@ -7848,9 +7920,9 @@ elfcore_make_pid (bfd *abfd) |
{ |
int pid; |
- pid = elf_tdata (abfd)->core_lwpid; |
+ pid = elf_tdata (abfd)->core->lwpid; |
if (pid == 0) |
- pid = elf_tdata (abfd)->core_pid; |
+ pid = elf_tdata (abfd)->core->pid; |
return pid; |
} |
@@ -7940,10 +8012,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
/* Do not overwrite the core signal if it |
has already been set by another thread. */ |
- if (elf_tdata (abfd)->core_signal == 0) |
- elf_tdata (abfd)->core_signal = prstat.pr_cursig; |
- if (elf_tdata (abfd)->core_pid == 0) |
- elf_tdata (abfd)->core_pid = prstat.pr_pid; |
+ if (elf_tdata (abfd)->core->signal == 0) |
+ elf_tdata (abfd)->core->signal = prstat.pr_cursig; |
+ if (elf_tdata (abfd)->core->pid == 0) |
+ elf_tdata (abfd)->core->pid = prstat.pr_pid; |
/* pr_who exists on: |
solaris 2.5+ |
@@ -7952,9 +8024,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
linux 2.[01] |
*/ |
#if defined (HAVE_PRSTATUS_T_PR_WHO) |
- elf_tdata (abfd)->core_lwpid = prstat.pr_who; |
+ elf_tdata (abfd)->core->lwpid = prstat.pr_who; |
#else |
- elf_tdata (abfd)->core_lwpid = prstat.pr_pid; |
+ elf_tdata (abfd)->core->lwpid = prstat.pr_pid; |
#endif |
} |
#if defined (HAVE_PRSTATUS32_T) |
@@ -7969,10 +8041,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
/* Do not overwrite the core signal if it |
has already been set by another thread. */ |
- if (elf_tdata (abfd)->core_signal == 0) |
- elf_tdata (abfd)->core_signal = prstat.pr_cursig; |
- if (elf_tdata (abfd)->core_pid == 0) |
- elf_tdata (abfd)->core_pid = prstat.pr_pid; |
+ if (elf_tdata (abfd)->core->signal == 0) |
+ elf_tdata (abfd)->core->signal = prstat.pr_cursig; |
+ if (elf_tdata (abfd)->core->pid == 0) |
+ elf_tdata (abfd)->core->pid = prstat.pr_pid; |
/* pr_who exists on: |
solaris 2.5+ |
@@ -7981,9 +8053,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) |
linux 2.[01] |
*/ |
#if defined (HAVE_PRSTATUS32_T_PR_WHO) |
- elf_tdata (abfd)->core_lwpid = prstat.pr_who; |
+ elf_tdata (abfd)->core->lwpid = prstat.pr_who; |
#else |
- elf_tdata (abfd)->core_lwpid = prstat.pr_pid; |
+ elf_tdata (abfd)->core->lwpid = prstat.pr_pid; |
#endif |
} |
#endif /* HAVE_PRSTATUS32_T */ |
@@ -8101,11 +8173,35 @@ elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note) |
} |
static bfd_boolean |
+elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note) |
+{ |
+ return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note); |
+} |
+ |
+static bfd_boolean |
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note) |
{ |
return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note); |
} |
+static bfd_boolean |
+elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note) |
+{ |
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note); |
+} |
+ |
+static bfd_boolean |
+elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note) |
+{ |
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note); |
+} |
+ |
+static bfd_boolean |
+elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note) |
+{ |
+ return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note); |
+} |
+ |
#if defined (HAVE_PRPSINFO_T) |
typedef prpsinfo_t elfcore_psinfo_t; |
#if defined (HAVE_PRPSINFO32_T) /* Sparc64 cross Sparc32 */ |
@@ -8157,13 +8253,13 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) |
memcpy (&psinfo, note->descdata, sizeof (psinfo)); |
#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID) |
- elf_tdata (abfd)->core_pid = psinfo.pr_pid; |
+ elf_tdata (abfd)->core->pid = psinfo.pr_pid; |
#endif |
- elf_tdata (abfd)->core_program |
+ elf_tdata (abfd)->core->program |
= _bfd_elfcore_strndup (abfd, psinfo.pr_fname, |
sizeof (psinfo.pr_fname)); |
- elf_tdata (abfd)->core_command |
+ elf_tdata (abfd)->core->command |
= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, |
sizeof (psinfo.pr_psargs)); |
} |
@@ -8176,13 +8272,13 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) |
memcpy (&psinfo, note->descdata, sizeof (psinfo)); |
#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID) |
- elf_tdata (abfd)->core_pid = psinfo.pr_pid; |
+ elf_tdata (abfd)->core->pid = psinfo.pr_pid; |
#endif |
- elf_tdata (abfd)->core_program |
+ elf_tdata (abfd)->core->program |
= _bfd_elfcore_strndup (abfd, psinfo.pr_fname, |
sizeof (psinfo.pr_fname)); |
- elf_tdata (abfd)->core_command |
+ elf_tdata (abfd)->core->command |
= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs, |
sizeof (psinfo.pr_psargs)); |
} |
@@ -8200,7 +8296,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) |
implementations, so strip it off if it exists. */ |
{ |
- char *command = elf_tdata (abfd)->core_command; |
+ char *command = elf_tdata (abfd)->core->command; |
int n = strlen (command); |
if (0 < n && command[n - 1] == ' ') |
@@ -8225,7 +8321,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) |
memcpy (&pstat, note->descdata, sizeof (pstat)); |
- elf_tdata (abfd)->core_pid = pstat.pr_pid; |
+ elf_tdata (abfd)->core->pid = pstat.pr_pid; |
} |
#if defined (HAVE_PSTATUS32_T) |
else if (note->descsz == sizeof (pstatus32_t)) |
@@ -8235,7 +8331,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note) |
memcpy (&pstat, note->descdata, sizeof (pstat)); |
- elf_tdata (abfd)->core_pid = pstat.pr_pid; |
+ elf_tdata (abfd)->core->pid = pstat.pr_pid; |
} |
#endif |
/* Could grab some more details from the "representative" |
@@ -8265,11 +8361,11 @@ elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note) |
memcpy (&lwpstat, note->descdata, sizeof (lwpstat)); |
- elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid; |
+ elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid; |
/* Do not overwrite the core signal if it has already been set by |
another thread. */ |
- if (elf_tdata (abfd)->core_signal == 0) |
- elf_tdata (abfd)->core_signal = lwpstat.pr_cursig; |
+ if (elf_tdata (abfd)->core->signal == 0) |
+ elf_tdata (abfd)->core->signal = lwpstat.pr_cursig; |
/* Make a ".reg/999" section. */ |
@@ -8352,11 +8448,11 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note) |
switch (type) |
{ |
case 1 /* NOTE_INFO_PROCESS */: |
- /* FIXME: need to add ->core_command. */ |
+ /* FIXME: need to add ->core->command. */ |
/* process_info.pid */ |
- elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 8); |
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8); |
/* process_info.signal */ |
- elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 12); |
+ elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12); |
break; |
case 2 /* NOTE_INFO_THREAD */: |
@@ -8539,6 +8635,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) |
else |
return TRUE; |
+ case NT_S390_TDB: |
+ if (note->namesz == 6 |
+ && strcmp (note->namedata, "LINUX") == 0) |
+ return elfcore_grok_s390_tdb (abfd, note); |
+ else |
+ return TRUE; |
+ |
case NT_ARM_VFP: |
if (note->namesz == 6 |
&& strcmp (note->namedata, "LINUX") == 0) |
@@ -8546,6 +8649,27 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) |
else |
return TRUE; |
+ case NT_ARM_TLS: |
+ if (note->namesz == 6 |
+ && strcmp (note->namedata, "LINUX") == 0) |
+ return elfcore_grok_aarch_tls (abfd, note); |
+ else |
+ return TRUE; |
+ |
+ case NT_ARM_HW_BREAK: |
+ if (note->namesz == 6 |
+ && strcmp (note->namedata, "LINUX") == 0) |
+ return elfcore_grok_aarch_hw_break (abfd, note); |
+ else |
+ return TRUE; |
+ |
+ case NT_ARM_HW_WATCH: |
+ if (note->namesz == 6 |
+ && strcmp (note->namedata, "LINUX") == 0) |
+ return elfcore_grok_aarch_hw_watch (abfd, note); |
+ else |
+ return TRUE; |
+ |
case NT_PRPSINFO: |
case NT_PSINFO: |
if (bed->elf_backend_grok_psinfo) |
@@ -8570,18 +8694,32 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) |
return TRUE; |
} |
+ |
+ case NT_FILE: |
+ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file", |
+ note); |
+ |
+ case NT_SIGINFO: |
+ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo", |
+ note); |
} |
} |
static bfd_boolean |
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note) |
{ |
- elf_tdata (abfd)->build_id_size = note->descsz; |
- elf_tdata (abfd)->build_id = (bfd_byte *) bfd_alloc (abfd, note->descsz); |
- if (elf_tdata (abfd)->build_id == NULL) |
+ struct elf_obj_tdata *t; |
+ |
+ if (note->descsz == 0) |
+ return FALSE; |
+ |
+ t = elf_tdata (abfd); |
+ t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz); |
+ if (t->build_id == NULL) |
return FALSE; |
- memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz); |
+ t->build_id->size = note->descsz; |
+ memcpy (t->build_id->data, note->descdata, note->descsz); |
return TRUE; |
} |
@@ -8646,15 +8784,15 @@ static bfd_boolean |
elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) |
{ |
/* Signal number at offset 0x08. */ |
- elf_tdata (abfd)->core_signal |
+ elf_tdata (abfd)->core->signal |
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); |
/* Process ID at offset 0x50. */ |
- elf_tdata (abfd)->core_pid |
+ elf_tdata (abfd)->core->pid |
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50); |
/* Command name at 0x7c (max 32 bytes, including nul). */ |
- elf_tdata (abfd)->core_command |
+ elf_tdata (abfd)->core->command |
= _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31); |
return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo", |
@@ -8667,7 +8805,7 @@ elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note) |
int lwp; |
if (elfcore_netbsd_get_lwpid (note, &lwp)) |
- elf_tdata (abfd)->core_lwpid = lwp; |
+ elf_tdata (abfd)->core->lwpid = lwp; |
if (note->type == NT_NETBSDCORE_PROCINFO) |
{ |
@@ -8730,15 +8868,15 @@ static bfd_boolean |
elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note) |
{ |
/* Signal number at offset 0x08. */ |
- elf_tdata (abfd)->core_signal |
+ elf_tdata (abfd)->core->signal |
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08); |
/* Process ID at offset 0x20. */ |
- elf_tdata (abfd)->core_pid |
+ elf_tdata (abfd)->core->pid |
= bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20); |
/* Command name at 0x48 (max 32 bytes, including nul). */ |
- elf_tdata (abfd)->core_command |
+ elf_tdata (abfd)->core->command |
= _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31); |
return TRUE; |
@@ -8801,7 +8939,7 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid) |
unsigned flags; |
/* nto_procfs_status 'pid' field is at offset 0. */ |
- elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata); |
+ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata); |
/* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ |
*tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); |
@@ -8812,15 +8950,15 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid) |
/* nto_procfs_status 'what' field is at offset 14. */ |
if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) |
{ |
- elf_tdata (abfd)->core_signal = sig; |
- elf_tdata (abfd)->core_lwpid = *tid; |
+ elf_tdata (abfd)->core->signal = sig; |
+ elf_tdata (abfd)->core->lwpid = *tid; |
} |
/* _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; |
+ elf_tdata (abfd)->core->lwpid = *tid; |
/* Make a ".qnx_core_status/%d" section. */ |
sprintf (buf, ".qnx_core_status/%ld", *tid); |
@@ -8868,7 +9006,7 @@ elfcore_grok_nto_regs (bfd *abfd, |
sect->alignment_power = 2; |
/* This is the current thread. */ |
- if (elf_tdata (abfd)->core_lwpid == tid) |
+ if (elf_tdata (abfd)->core->lwpid == tid) |
return elfcore_maybe_make_sect (abfd, base, sect); |
return TRUE; |
@@ -9055,6 +9193,34 @@ elfcore_write_prpsinfo (bfd *abfd, |
} |
char * |
+elfcore_write_linux_prpsinfo32 |
+ (bfd *abfd, char *buf, int *bufsiz, |
+ const struct elf_internal_linux_prpsinfo *prpsinfo) |
+{ |
+ struct elf_external_linux_prpsinfo32 data; |
+ |
+ memset (&data, 0, sizeof (data)); |
+ LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data); |
+ |
+ return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO, |
+ &data, sizeof (data)); |
+} |
+ |
+char * |
+elfcore_write_linux_prpsinfo64 |
+ (bfd *abfd, char *buf, int *bufsiz, |
+ const struct elf_internal_linux_prpsinfo *prpsinfo) |
+{ |
+ struct elf_external_linux_prpsinfo64 data; |
+ |
+ memset (&data, 0, sizeof (data)); |
+ LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data); |
+ |
+ return elfcore_write_note (abfd, buf, bufsiz, |
+ "CORE", NT_PRPSINFO, &data, sizeof (data)); |
+} |
+ |
+char * |
elfcore_write_prstatus (bfd *abfd, |
char *buf, |
int *bufsiz, |
@@ -9330,6 +9496,18 @@ elfcore_write_s390_system_call (bfd *abfd, |
} |
char * |
+elfcore_write_s390_tdb (bfd *abfd, |
+ char *buf, |
+ int *bufsiz, |
+ const void *s390_tdb, |
+ int size) |
+{ |
+ char *note_name = "LINUX"; |
+ return elfcore_write_note (abfd, buf, bufsiz, |
+ note_name, NT_S390_TDB, s390_tdb, size); |
+} |
+ |
+char * |
elfcore_write_arm_vfp (bfd *abfd, |
char *buf, |
int *bufsiz, |
@@ -9342,6 +9520,42 @@ elfcore_write_arm_vfp (bfd *abfd, |
} |
char * |
+elfcore_write_aarch_tls (bfd *abfd, |
+ char *buf, |
+ int *bufsiz, |
+ const void *aarch_tls, |
+ int size) |
+{ |
+ char *note_name = "LINUX"; |
+ return elfcore_write_note (abfd, buf, bufsiz, |
+ note_name, NT_ARM_TLS, aarch_tls, size); |
+} |
+ |
+char * |
+elfcore_write_aarch_hw_break (bfd *abfd, |
+ char *buf, |
+ int *bufsiz, |
+ const void *aarch_hw_break, |
+ int size) |
+{ |
+ char *note_name = "LINUX"; |
+ return elfcore_write_note (abfd, buf, bufsiz, |
+ note_name, NT_ARM_HW_BREAK, aarch_hw_break, size); |
+} |
+ |
+char * |
+elfcore_write_aarch_hw_watch (bfd *abfd, |
+ char *buf, |
+ int *bufsiz, |
+ const void *aarch_hw_watch, |
+ int size) |
+{ |
+ char *note_name = "LINUX"; |
+ return elfcore_write_note (abfd, buf, bufsiz, |
+ note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size); |
+} |
+ |
+char * |
elfcore_write_register_note (bfd *abfd, |
char *buf, |
int *bufsiz, |
@@ -9375,8 +9589,16 @@ elfcore_write_register_note (bfd *abfd, |
return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size); |
if (strcmp (section, ".reg-s390-system-call") == 0) |
return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size); |
+ if (strcmp (section, ".reg-s390-tdb") == 0) |
+ return elfcore_write_s390_tdb (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) |
+ return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size); |
+ if (strcmp (section, ".reg-aarch-hw-break") == 0) |
+ return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size); |
+ if (strcmp (section, ".reg-aarch-hw-watch") == 0) |
+ return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size); |
return NULL; |
} |
@@ -9535,7 +9757,9 @@ bfd_get_elf_phdrs (bfd *abfd, void *phdrs) |
} |
enum elf_reloc_type_class |
-_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) |
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, |
+ const asection *rel_sec ATTRIBUTE_UNUSED, |
+ const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED) |
{ |
return reloc_class_normal; |
} |