aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2001-12-17 00:52:35 +0000
committerAlan Modra <amodra@gmail.com>2001-12-17 00:52:35 +0000
commit9ad5cbcfb23cb74d34bd04f88f4e47c0f5de5155 (patch)
treead50ccd4f5e9865bf609bf15586311f30452ee23 /bfd/elf.c
parent76f63e91263a394065560500287a32d72c088967 (diff)
downloadgdb-9ad5cbcfb23cb74d34bd04f88f4e47c0f5de5155.zip
gdb-9ad5cbcfb23cb74d34bd04f88f4e47c0f5de5155.tar.gz
gdb-9ad5cbcfb23cb74d34bd04f88f4e47c0f5de5155.tar.bz2
Support for more than 64k ELF sections.
include/elf/ChangeLog * external.h (Elf_External_Sym_Shndx): Declare. * internal.h (struct elf_internal_sym <st_shndx>): Make it an unsigned int. * common.h (SHN_BAD): Define. bfd/ChangeLog * configure.in: Bump bfd version. * configure: Regenerate. * elf-bfd.h (elf_size_info <swap_symbol_out>): Add shndx param. (bfd_elf32_swap_symbol_in): Likewise. (bfd_elf32_swap_symbol_out): Likewise. (bfd_elf64_swap_symbol_in): Likewise. (bfd_elf64_swap_symbol_out): Likewise. (elf_reloc_cookie): Add locsym_shndx field. Make locsyms a PTR. (elf_obj_tdata): Add num_elf_sections, symtab_shndx_hdr and symtab_shndx_section. (elf_numsections): Define. (elf_symtab_shndx): Define. * elf.c (setup_group): Use elf_numsections rather than header e_shnum. (bfd_elf_find_section): Likewise. (bfd_section_from_elf_index): Likewise. (bfd_section_from_shdr): Likewise. Handle SHT_SYMTAB_SHNDX. (bfd_section_from_r_symndx): Read symbol shndx extension, and translate st_shndx for > SHN_HIRESERVE. (assign_section_numbers): Skip reserved sections. Assign symtab_shndx_section and elf_numsections. Exclude reserved sections from e_shnum. Set up symtab_shndx_hdr. (_bfd_elf_compute_section_file_positions): Handle symtab_shndx_hdr. (map_sections_to_segments): Don't map eh_frame_hdr unless required. (assign_file_positions_except_relocs): Use elf_numsections rather than header e_shnum. Skip reserved sections and symtab_shndx_section. (prep_headers): Set name for symtab_shndx_hdr. (_bfd_elf_assign_file_positions_for_relocs): Use elf_numsections. (_bfd_elf_write_object_contents): Likewise. Skip reserved sections. (_bfd_elf_section_from_bfd_section): Check bfd_{abs,com,und}_section first. Use elf_section_data if available. Use elf_numsections. Start scan at index 1. (copy_private_bfd_data ): Comment fixes. (MAP_ONESYMTAB): Define above SHN_HIOS. (MAP_DYNSYMTAB): Likewise. (MAP_STRTAB): Likewise. (MAP_SHSTRTAB): Likewise. (MAP_SYM_SHNDX): New define. (_bfd_elf_copy_private_symbol_data): Handle symtab_shndx_section. (swap_out_syms): Swap out SHT_SYMTAB_SHNDX section too. * elfcode.h (elf_swap_symbol_in): Add shndx param, and handle shndx extension. (elf_swap_symbol_out): Likewise. (elf_object_p): Set elf_numsections, and use instead of e_shnum. Initialialise reserved elf_elfsections to point at shdr[0]. Remove redundant bfd_release calls. (elf_slurp_symbol_table): Read symbol shndx extension, and use with elf_swap_symbol_in. Translate st_shndx for > SHN_HIRESERVE too. * elflink.h (elf_link_is_defined_archive_symbol): Read symbol shndx extension, and use with elf_swap_symbol_in. (elf_link_record_local_dynamic_symbol): Likewise. (elf_link_add_object_symbols): Likewise. Also translate st_shndx for elf sections > SHN_HIRESERVE. (NAME(bfd_elf,size_dynamic_sections)): Adjust elf_swap_symbol_out call. (struct elf_final_link_info): Add locsym_shndx and symshndxbuf. (elf_bfd_final_link): Allocate the above, and tidy code allocating other buffers. Use elf_numsections instead of e_shnum. Adjust elf_swap_symbol_out calls. (elf_link_output_sym): Swap out symbol shndx extension too. (elf_link_flush_output_syms): And flush them to disk. (elf_link_output_extsym): Use SHN_BAD. Adjust elf_swap_symbol_out calls. (elf_gc_mark): Read symbol shndx extension, and use with elf_swap_symbol_in. (elf_link_input_bfd): Likewise, Translate st_shndx for elf sections > SHN_HIRESERVE too. Use SHN_BAD. (elf_reloc_symbol_deleted_p): Use symbol shndx extensions with elf_swap_symbol_in. Translate st_shndx > SHN_HIRESERVE too. (elf_bfd_discard_info): Read symbol shndx extension. Don't attempt to continue after a bfd error. * elf-m10200.c (mn10200_elf_relax_section): Only read local syms. Stash them immediately to symtab_hdr->contents rather than later in multiple places. Clean up afterwards. Read symbol shndx extension, and use with swap_symbol_in. Translate SHN_UNDEF, SHN_ABS, SHN_COMMON and elf sections > SHN_HIRESERVE to bfd sections too. Remove dead code. (mn10200_elf_relax_delete_bytes): Use symbol shndx extension when swapping in symbols. Tidy code adjusting global syms. Don't swap in global syms. (mn10200_elf_symbol_address_p): Likewise. Remove extsyms param. (mn10200_elf_get_relocated_section_contents): Read symbol shndx extension, and use with swap_symbol_in. Rename "size" -> "amt" to maximize code in common with other files. Translate st_shndx for > SHN_HIRESERVE too. Remove dead code. * elf-m10300.c (mn10300_elf_relax_section): Only read local syms. Stash them immediately to symtab_hdr->contents rather than later in multiple places. Clean up afterwards. Read symbol shndx extension, and use with swap_symbol_in. Remove dead code. (mn10300_elf_relax_delete_bytes): As for elf-m10200.c. (mn10300_elf_symbol_address_p): Likewise. (mn10300_elf_get_relocated_section_contents): Likewise. * elf32-h8300.c (elf32_h8_relax_section): As for elf-m10300.c. (elf32_h8_relax_delete_bytes): Likewise. (elf32_h8_symbol_address_p): Likewise. (elf32_h8_get_relocated_section_contents): Likewise. * elf32-hppa.c (elf32_hppa_size_stubs): Read symbol shndx extension, and use with swap_symbol_in. * elf64-hppa.c (elf64_hppa_check_relocs): Likewise. * elf32-i370.c (i370_elf_finish_dynamic_sections): Adjust call to bfd_elf32_swap_symbol_out. * elf32-m32r.c (m32r_elf_get_relocated_section_contents): Translate elf sections > SHN_HIRESERVE too. * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Only read local syms. Read symbol shndx extension, and use with swap_symbol_in. * elf32-mips.c (_bfd_mips_elf_final_write_processing): Use elf_numsections rather than header e_shnum. * elf32-sh.c (sh_elf_relax_section): As for elf-m10300.c. (sh_elf_relax_delete_bytes): Likewise. (sh_elf_get_relocated_section_contents): Likewise. Only read local symbols. * elf32-v850.c (v850_elf_symbol_processing): Use an unsigned int to hold section index. Use elf_numsections rather than e_shnum. Rename "index" -> "indx" to avoid shadowing warning. (v850_elf_add_symbol_hook): Likewise. * elf64-alpha.c (elf64_alpha_relax_section): Only read local syms. Read symbol shndx extension, and use with swap_symbol_in. * elf32-xstormy16.c (xstormy16_elf_relax_section): Likewise. Translate SHN_COMMON and elf sections > SHN_HIRESERVE too. * elfxx-ia64.c (elfNN_ia64_relax_section): Likewise. (elfNN_ia64_aix_add_symbol_hook): Use elf_numsections. * elf-m10300.c (mn10300_elf_gc_mark_hook): Remove unnecessary checks before calling bfd_section_from_elf_index on local syms. * elf32-arm.h (elf32_arm_gc_mark_hook): Likewise. * elf32-avr.c (elf32_avr_gc_mark_hook): Likewise. * elf32-cris.c (cris_elf_gc_mark_hook): Likewise. * elf32-d10v.c (elf32_d10v_gc_mark_hook): Likewise. * elf32-fr30.c (fr30_elf_gc_mark_hook): Likewise. * elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise. * elf32-i386.c (elf_i386_gc_mark_hook): Likewise. * elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise. * elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise. * elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise. * elf32-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise. * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Likewise. * elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise. * elf32-s390.c (elf_s390_gc_mark_hook): Likewise. * elf32-sh.c (sh_elf_gc_mark_hook): Likewise. * elf32-sparc.c (elf32_sparc_gc_mark_hook): Likewise. * elf32-v850.c (v850_elf_gc_mark_hook): Likewise. * elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Likewise. * elf64-mips.c (mips_elf64_gc_mark_hook): Likewise. * elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise. * elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise. * elf64-s390.c (elf_s390_gc_mark_hook): Likewise. * elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise. binutils/ChangeLog * readelf.c (symtab_shndx_hdr): New global. (SECTION_HEADER_INDEX): Define. (SECTION_HEADER_NUM): Define. (SECTION_HEADER): Define. (GET_ELF_SYMBOLS): Pass two params rather than three. (get_32bit_elf_symbols): Take file and section args. Read and use SHT_SYMTAB_SHNDX. (get_64bit_elf_symbols): Likewise. (dump_relocations): Use SECTION_HEADER to index "section_headers". (process_section_headers): Likewise. Use SECTION_HEADER_NUM too. Remember symtab_shdx_hdr. (process_program_headers): Scan from index 1 for segment map. (slurp_ia64_unwind_table): Use SECTION_HEADER to index "section_headers". (process_relocs): Likewise. Also adjust call to GET_ELF_SYMBOLS. (process_unwind): Likewise. (process_version_sections): Likewise. (process_symbol_table): Likewise. (display_debug_info): Likewise. (process_dynamic_segment): Fake up a symtab section for changed GET_ELF_SYMBOLS. (get_symbol_index_type): Check SHN_LOOS before SHN_LORESERVE. (process_program_headers): Kill signed/unsigned warning. (load_debug_str): Likewise. (display_debug_info): Likewise.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c226
1 files changed, 173 insertions, 53 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 98d3cd2..cf13ad6 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -375,7 +375,7 @@ setup_group (abfd, hdr, newsect)
/* First count the number of groups. If we have a SHT_GROUP
section with just a flag word (ie. sh_size is 4), ignore it. */
- shnum = elf_elfheader (abfd)->e_shnum;
+ shnum = elf_numsections (abfd);
num_group = 0;
for (i = 0; i < shnum; i++)
{
@@ -708,11 +708,11 @@ bfd_elf_find_section (abfd, name)
i_shdrp = elf_elfsections (abfd);
if (i_shdrp != NULL)
{
- shstrtab = bfd_elf_get_str_section
- (abfd, elf_elfheader (abfd)->e_shstrndx);
+ shstrtab = bfd_elf_get_str_section (abfd,
+ elf_elfheader (abfd)->e_shstrndx);
if (shstrtab != NULL)
{
- max = elf_elfheader (abfd)->e_shnum;
+ max = elf_numsections (abfd);
for (i = 1; i < max; i++)
if (!strcmp (&shstrtab[i_shdrp[i]->sh_name], name))
return i_shdrp[i];
@@ -1549,6 +1549,20 @@ bfd_section_from_shdr (abfd, shindex)
section, so that objcopy can handle it. */
return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+ case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections */
+ if (elf_symtab_shndx (abfd) == shindex)
+ return true;
+
+ /* Get the associated symbol table. */
+ if (! bfd_section_from_shdr (abfd, hdr->sh_link)
+ || hdr->sh_link != elf_onesymtab (abfd))
+ return false;
+
+ elf_symtab_shndx (abfd) = shindex;
+ elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
+ elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
+ return true;
+
case SHT_STRTAB: /* A string table */
if (hdr->bfd_section != NULL)
return true;
@@ -1559,9 +1573,10 @@ bfd_section_from_shdr (abfd, shindex)
return true;
}
{
- unsigned int i;
+ unsigned int i, num_sec;
- for (i = 1; i < ehdr->e_shnum; i++)
+ num_sec = elf_numsections (abfd);
+ for (i = 1; i < num_sec; i++)
{
Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
if (hdr2->sh_link == shindex)
@@ -1607,9 +1622,11 @@ bfd_section_from_shdr (abfd, shindex)
{
asection *target_sect;
Elf_Internal_Shdr *hdr2;
+ unsigned int num_sec = elf_numsections (abfd);
/* Check for a bogus link to avoid crashing. */
- if (hdr->sh_link >= ehdr->e_shnum)
+ if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
+ || hdr->sh_link >= num_sec)
{
((*_bfd_error_handler)
(_("%s: invalid link %lu for reloc section %s (index %u)"),
@@ -1627,11 +1644,11 @@ bfd_section_from_shdr (abfd, shindex)
if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
&& elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
{
- int scan;
+ unsigned int scan;
int found;
found = 0;
- for (scan = 1; scan < ehdr->e_shnum; scan++)
+ for (scan = 1; scan < num_sec; scan++)
{
if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
|| elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
@@ -1758,7 +1775,7 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
asection *sec;
unsigned long r_symndx;
{
- unsigned char esym_shndx[2];
+ unsigned char esym_shndx[4];
unsigned int isym_shndx;
Elf_Internal_Shdr *symtab_hdr;
file_ptr pos;
@@ -1775,18 +1792,34 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
{
pos += r_symndx * sizeof (Elf64_External_Sym);
pos += offsetof (Elf64_External_Sym, st_shndx);
+ amt = sizeof (((Elf64_External_Sym *) 0)->st_shndx);
}
else
{
pos += r_symndx * sizeof (Elf32_External_Sym);
pos += offsetof (Elf32_External_Sym, st_shndx);
+ amt = sizeof (((Elf32_External_Sym *) 0)->st_shndx);
}
- amt = sizeof (esym_shndx);
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
return NULL;
isym_shndx = H_GET_16 (abfd, esym_shndx);
+ if (isym_shndx == SHN_XINDEX)
+ {
+ Elf_Internal_Shdr *shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (shndx_hdr->sh_size != 0)
+ {
+ pos = shndx_hdr->sh_offset;
+ pos += r_symndx * sizeof (Elf_External_Sym_Shndx);
+ amt = sizeof (Elf_External_Sym_Shndx);
+ if (bfd_seek (abfd, pos, SEEK_SET) != 0
+ || bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
+ return NULL;
+ isym_shndx = H_GET_32 (abfd, esym_shndx);
+ }
+ }
+
if (cache->abfd != abfd)
{
memset (cache->indx, -1, sizeof (cache->indx));
@@ -1794,7 +1827,7 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
}
cache->indx[ent] = r_symndx;
cache->sec[ent] = sec;
- if (isym_shndx > 0 && isym_shndx < SHN_LORESERVE)
+ if (isym_shndx < SHN_LORESERVE || isym_shndx > SHN_HIRESERVE)
{
asection *s;
s = bfd_section_from_elf_index (abfd, isym_shndx);
@@ -1812,8 +1845,7 @@ bfd_section_from_elf_index (abfd, index)
bfd *abfd;
unsigned int index;
{
- BFD_ASSERT (index > 0 && index < SHN_LORESERVE);
- if (index >= elf_elfheader (abfd)->e_shnum)
+ if (index >= elf_numsections (abfd))
return NULL;
return elf_elfsections (abfd)[index]->bfd_section;
}
@@ -2268,18 +2300,24 @@ assign_section_numbers (abfd)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->this_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
if ((sec->flags & SEC_RELOC) == 0)
d->rel_idx = 0;
else
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->rel_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
}
if (d->rel_hdr2)
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
d->rel_idx2 = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
}
@@ -2287,21 +2325,42 @@ assign_section_numbers (abfd)
d->rel_idx2 = 0;
}
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->shstrtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
if (bfd_get_symcount (abfd) > 0)
{
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->symtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
+ if (section_number > SHN_LORESERVE - 2)
+ {
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ t->symtab_shndx_section = 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;
+ }
+ if (section_number == SHN_LORESERVE)
+ section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
t->strtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
}
_bfd_elf_strtab_finalize (elf_shstrtab (abfd));
t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
+
+ elf_numsections (abfd) = section_number;
elf_elfheader (abfd)->e_shnum = section_number;
+ if (section_number > SHN_LORESERVE)
+ elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
/* Set up the list of section header pointers, in agreement with the
indices. */
@@ -2325,6 +2384,11 @@ assign_section_numbers (abfd)
if (bfd_get_symcount (abfd) > 0)
{
i_shdrp[t->symtab_section] = &t->symtab_hdr;
+ if (elf_numsections (abfd) > SHN_LORESERVE)
+ {
+ i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
+ t->symtab_shndx_hdr.sh_link = t->symtab_section;
+ }
i_shdrp[t->strtab_section] = &t->strtab_hdr;
t->symtab_hdr.sh_link = t->strtab_section;
}
@@ -2438,9 +2502,11 @@ assign_section_numbers (abfd)
}
for (secn = 1; secn < section_number; ++secn)
- i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
- i_shdrp[secn]->sh_name);
-
+ if (i_shdrp[secn] == NULL)
+ i_shdrp[secn] = i_shdrp[0];
+ else
+ i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
+ i_shdrp[secn]->sh_name);
return true;
}
@@ -2722,6 +2788,10 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
hdr = &elf_tdata (abfd)->symtab_hdr;
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (hdr->sh_size != 0)
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
hdr = &elf_tdata (abfd)->strtab_hdr;
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
@@ -3037,7 +3107,9 @@ map_sections_to_segments (abfd)
/* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
segment. */
- eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr");
+ eh_frame_hdr = NULL;
+ if (elf_tdata (abfd)->eh_frame_hdr)
+ eh_frame_hdr = bfd_get_section_by_name (abfd, ".eh_frame_hdr");
if (eh_frame_hdr != NULL && (eh_frame_hdr->flags & SEC_LOAD))
{
amt = sizeof (struct elf_segment_map);
@@ -3617,6 +3689,7 @@ assign_file_positions_except_relocs (abfd)
struct elf_obj_tdata * const tdata = elf_tdata (abfd);
Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
+ unsigned int num_sec = elf_numsections (abfd);
file_ptr off;
struct elf_backend_data *bed = get_elf_backend_data (abfd);
@@ -3632,24 +3705,27 @@ assign_file_positions_except_relocs (abfd)
/* We are not creating an executable, which means that we are
not creating a program header, and that the actual order of
the sections in the file is unimportant. */
- for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
hdr = *hdrpp;
- if (hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
- {
- hdr->sh_offset = -1;
- continue;
- }
- if (i == tdata->symtab_section
+ if (hdr->sh_type == SHT_REL
+ || hdr->sh_type == SHT_RELA
+ || i == tdata->symtab_section
+ || i == tdata->symtab_shndx_section
|| i == tdata->strtab_section)
{
hdr->sh_offset = -1;
- continue;
}
+ else
+ off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
- off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+ if (i == SHN_LORESERVE - 1)
+ {
+ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ }
}
}
else
@@ -3665,7 +3741,7 @@ assign_file_positions_except_relocs (abfd)
/* Assign file positions for the other sections. */
off = elf_tdata (abfd)->next_file_pos;
- for (i = 1, hdrpp = i_shdrpp + 1; i < i_ehdrp->e_shnum; i++, hdrpp++)
+ for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
{
Elf_Internal_Shdr *hdr;
@@ -3691,10 +3767,17 @@ assign_file_positions_except_relocs (abfd)
else if (hdr->sh_type == SHT_REL
|| hdr->sh_type == SHT_RELA
|| hdr == i_shdrpp[tdata->symtab_section]
+ || hdr == i_shdrpp[tdata->symtab_shndx_section]
|| hdr == i_shdrpp[tdata->strtab_section])
hdr->sh_offset = -1;
else
off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
+
+ if (i == SHN_LORESERVE - 1)
+ {
+ i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+ }
}
}
@@ -3829,14 +3912,13 @@ _bfd_elf_assign_file_positions_for_relocs (abfd)
bfd *abfd;
{
file_ptr off;
- unsigned int i;
+ unsigned int i, num_sec;
Elf_Internal_Shdr **shdrpp;
off = elf_tdata (abfd)->next_file_pos;
- for (i = 1, shdrpp = elf_elfsections (abfd) + 1;
- i < elf_elfheader (abfd)->e_shnum;
- i++, shdrpp++)
+ num_sec = elf_numsections (abfd);
+ for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
{
Elf_Internal_Shdr *shdrp;
@@ -3857,7 +3939,7 @@ _bfd_elf_write_object_contents (abfd)
Elf_Internal_Ehdr *i_ehdrp;
Elf_Internal_Shdr **i_shdrp;
boolean failed;
- unsigned int count;
+ unsigned int count, num_sec;
if (! abfd->output_has_begun
&& ! _bfd_elf_compute_section_file_positions
@@ -3875,7 +3957,8 @@ _bfd_elf_write_object_contents (abfd)
_bfd_elf_assign_file_positions_for_relocs (abfd);
/* After writing the headers, we need to write the sections too... */
- for (count = 1; count < i_ehdrp->e_shnum; count++)
+ num_sec = elf_numsections (abfd);
+ for (count = 1; count < num_sec; count++)
{
if (bed->elf_backend_section_processing)
(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
@@ -3887,6 +3970,8 @@ _bfd_elf_write_object_contents (abfd)
|| bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
return false;
}
+ if (count == SHN_LORESERVE - 1)
+ count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
}
/* Write out the section header names. */
@@ -3920,12 +4005,23 @@ _bfd_elf_section_from_bfd_section (abfd, asect)
Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
int index;
Elf_Internal_Shdr *hdr;
- int maxindex = elf_elfheader (abfd)->e_shnum;
+ int maxindex = elf_numsections (abfd);
- for (index = 0; index < maxindex; index++)
+ if (elf_section_data (asect) != NULL
+ && elf_section_data (asect)->this_idx != 0)
+ return elf_section_data (asect)->this_idx;
+
+ if (bfd_is_abs_section (asect))
+ return SHN_ABS;
+ if (bfd_is_com_section (asect))
+ return SHN_COMMON;
+ if (bfd_is_und_section (asect))
+ return SHN_UNDEF;
+
+ for (index = 1; index < maxindex; index++)
{
hdr = i_shdrp[index];
- if (hdr->bfd_section == asect)
+ if (hdr != NULL && hdr->bfd_section == asect)
return index;
}
@@ -3936,6 +4032,9 @@ _bfd_elf_section_from_bfd_section (abfd, asect)
int retval;
hdr = i_shdrp[index];
+ if (hdr == NULL)
+ continue;
+
retval = index;
if ((*bed->elf_backend_section_from_bfd_section)
(abfd, hdr, asect, &retval))
@@ -3943,16 +4042,9 @@ _bfd_elf_section_from_bfd_section (abfd, asect)
}
}
- if (bfd_is_abs_section (asect))
- return SHN_ABS;
- if (bfd_is_com_section (asect))
- return SHN_COMMON;
- if (bfd_is_und_section (asect))
- return SHN_UNDEF;
-
bfd_set_error (bfd_error_nonrepresentable_section);
- return -1;
+ return SHN_BAD;
}
/* Given a BFD symbol, return the index in the ELF symbol table, or -1
@@ -4119,7 +4211,7 @@ copy_private_bfd_data (ibfd, obfd)
/* Scan through the segments specified in the program header
of the input BFD. For this first scan we look for overlaps
- in the loadable segments. These can be created by wierd
+ in the loadable segments. These can be created by weird
parameters to objcopy. */
for (i = 0, segment = elf_tdata (ibfd)->phdr;
i < num_segments;
@@ -4521,7 +4613,7 @@ copy_private_bfd_data (ibfd, obfd)
elf_tdata (obfd)->segment_map = map_first;
/* If we had to estimate the number of program headers that were
- going to be needed, then check our estimate know and adjust
+ going to be needed, then check our estimate now and adjust
the offset if necessary. */
if (phdr_adjust_seg != NULL)
{
@@ -4634,10 +4726,11 @@ _bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec)
section indices; these definitions are interpreted by the
swap_out_syms function. */
-#define MAP_ONESYMTAB (SHN_LORESERVE - 1)
-#define MAP_DYNSYMTAB (SHN_LORESERVE - 2)
-#define MAP_STRTAB (SHN_LORESERVE - 3)
-#define MAP_SHSTRTAB (SHN_LORESERVE - 4)
+#define MAP_ONESYMTAB (SHN_HIOS + 1)
+#define MAP_DYNSYMTAB (SHN_HIOS + 2)
+#define MAP_STRTAB (SHN_HIOS + 3)
+#define MAP_SHSTRTAB (SHN_HIOS + 4)
+#define MAP_SYM_SHNDX (SHN_HIOS + 5)
boolean
_bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg)
@@ -4670,6 +4763,8 @@ _bfd_elf_copy_private_symbol_data (ibfd, isymarg, obfd, osymarg)
shndx = MAP_STRTAB;
else if (shndx == elf_tdata (ibfd)->shstrtab_section)
shndx = MAP_SHSTRTAB;
+ else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
+ shndx = MAP_SYM_SHNDX;
osym->internal_elf_sym.st_shndx = shndx;
}
@@ -4689,8 +4784,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
asymbol **syms;
struct bfd_strtab_hash *stt;
Elf_Internal_Shdr *symtab_hdr;
+ Elf_Internal_Shdr *symtab_shndx_hdr;
Elf_Internal_Shdr *symstrtab_hdr;
char *outbound_syms;
+ char *outbound_shndx;
int idx;
bfd_size_type amt;
@@ -4720,6 +4817,22 @@ swap_out_syms (abfd, sttp, relocatable_p)
return false;
symtab_hdr->contents = (PTR) outbound_syms;
+ outbound_shndx = NULL;
+ symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+ if (symtab_shndx_hdr->sh_name != 0)
+ {
+ amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
+ outbound_shndx = bfd_alloc (abfd, amt);
+ if (outbound_shndx == NULL)
+ return false;
+ memset (outbound_shndx, 0, (unsigned long) amt);
+ symtab_shndx_hdr->contents = outbound_shndx;
+ symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
+ symtab_shndx_hdr->sh_size = amt;
+ symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
+ symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
+ }
+
/* now generate the data (for "contents") */
{
/* Fill in zeroth symbol and swap it out. */
@@ -4730,8 +4843,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
sym.st_info = 0;
sym.st_other = 0;
sym.st_shndx = SHN_UNDEF;
- bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
}
syms = bfd_get_outsymbols (abfd);
@@ -4812,6 +4927,9 @@ swap_out_syms (abfd, sttp, relocatable_p)
case MAP_SHSTRTAB:
shndx = elf_tdata (abfd)->shstrtab_section;
break;
+ case MAP_SYM_SHNDX:
+ shndx = elf_tdata (abfd)->symtab_shndx_section;
+ break;
default:
break;
}
@@ -4889,8 +5007,10 @@ swap_out_syms (abfd, sttp, relocatable_p)
else
sym.st_other = 0;
- bed->s->swap_symbol_out (abfd, &sym, (PTR) outbound_syms);
+ bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
outbound_syms += bed->s->sizeof_sym;
+ if (outbound_shndx != NULL)
+ outbound_shndx += sizeof (Elf_External_Sym_Shndx);
}
*sttp = stt;