This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
This patch deletes a whole lot of duplicated code. The best kind of
patch. :-) I've moved all the raw elf symbol reading code into a new
function, bfd_elf_get_elf_syms. Saved 20k in ld's text size on an
x86 --enable-targets=all build.
Slightly more controversially, I've also changed caching of local syms
from raw ELF to internal form. This uses more memory per sym, 20 vs.
16 bytes for ELF32, 32 vs 24 bytes for ELF64, but I feel the change is
well worth it because:
a) swapping syms in isn't a zero cost operation.
b) some back-ends edit local syms, requiring the syms to be swapped
back out to a raw cache.
c) >64k elf section support complicates caching of raw symbols.
You'd need to cache symbol section extension entries as well, or
include code to read the SHT_SYMTAB_SHNDX section with every place
that reads symbols.
While doing this, I noticed that freeing of internal relocs and other
possibly cached info, was wrong. Typically, code looked like:
free_relocs = NULL;
relocs = _bfd_elfNN_link_read_relocs (abfd, sec, NULL, NULL,
info->keep_memory);
if (relocs == NULL)
goto error_return;
if (!info->keep_memory)
free_relocs = relocs;
.
.
.
if (free_relocs != NULL)
free (free_relocs);
This is wrong for !info->keep_memory when the relocs are already
cached before the link_read_relocs call, as can happen for backends
that edit relocs like powerpc64-linux. Correct is to set free_relocs
with
if (elf_section_data (sec)->relocs != relocs)
free_relocs = relocs;
or to dispense with free_relocs entirely as I've done.
bfd/ChangeLog
* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
change type of locsyms.
(bfd_elf_get_elf_syms): Declare.
* elf.c (bfd_elf_get_elf_syms): New function.
(group_signature): Use bfd_elf_get_elf_syms.
(bfd_section_from_r_symndx): Likewise.
* elfcode.h (elf_slurp_symbol_table): Likewise.
* elflink.h (elf_link_is_defined_archive_symbol): Likewise.
(elf_link_add_object_symbols): Likewise. Reorganise to increase
locality of various data structures. Properly free internal relocs.
(elf_bfd_final_link): Properly free internal relocs.
(elf_link_check_versioned_symbol): Use bfd_elf_get_elf_syms.
(elf_link_input_bfd): Likewise.
(elf_gc_mark): Likewise. Properly free internal relocs.
(elf_gc_sweep): Properly free internal relocs.
(elf_reloc_symbol_deleted_p): No need to swap syms in.
(elf_bfd_discard_info): Use bfd_elf_get_elf_syms. Properly free
internal relocs.
* elf-m10200.c (mn10200_elf_relax_section): Use bfd_elf_get_elf_syms.
Properly free possibly cached info.
(mn10200_elf_relax_delete_bytes): Remove symbol swapping code.
(mn10200_elf_symbol_address_p): Pass in internal syms. Remove
symbol swapping code.
(mn10200_elf_get_relocated_section_contents): Use bfd_elf_get_elf_syms.
Properly free possibly cached info.
* elf-m10300.c (mn10300_elf_relax_section): As above for elf-m10200.c.
(mn10300_elf_relax_delete_bytes): Likewise.
(mn10300_elf_symbol_address_p): Likewise.
(mn10300_elf_get_relocated_section_contents): Likewise.
* elf32-h8300.c (elf32_h8_relax_section): As above for elf-m10200.c.
(elf32_h8_relax_delete_bytes): Likewise.
(elf32_h8_symbol_address_p): Likewise.
(elf32_h8_get_relocated_section_contents): Likewise.
* elf32-m32r.c (m32r_elf_relax_section): As above for elf-m10200.c.
(m32r_elf_relax_delete_bytes): Likewise.
(m32r_elf_get_relocated_section_contents): Likewise.
* elf32-sh.c (sh_elf_reloc_loop): Free section contents using
elf_section_data to determine whether cached.
(sh_elf_relax_section): As above for elf-m10200.c.
(sh_elf_relax_delete_bytes): Likewise.
(sh_elf_get_relocated_section_contents): Likewise.
* elf32-xstormy16.c (xstormy16_elf_relax_section): As above.
* elf64-alpha.c (elf64_alpha_relax_section): As above. Also delay
reading of local syms.
* elf64-mmix.c (mmix_elf_relax_section): Likewise.
* elf64-sh64.c (sh_elf64_get_relocated_section_contents): As above.
* elfxx-ia64.c (elfNN_ia64_relax_section): As above.
* elfxx-mips.c (_bfd_mips_elf_check_relocs): Properly free internal
relocs.
* elf32-arm.h (bfd_elf32_arm_process_before_allocation): Properly
free internal relocs and section contents. Don't read symbols.
* elf32-hppa.c (get_local_syms): Use bfd_elf_get_elf_syms.
(elf32_hppa_size_stubs): Don't free local syms.
* elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Delay
reading of local syms. Use bfd_elf_get_elf_syms. Properly free
possibly cached info.
* elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise.
* elf64-hppa.c (elf64_hppa_check_relocs): Use bfd_elf_get_elf_syms.
* elf64-ppc.c (struct ppc_link_hash_table): Delete bfd_count and
all_local_syms.
(get_local_syms): Delete function.
(edit_opd): Use bfd_elf_get_elf_syms. Free on error exit. Cache
on exit.
(ppc64_elf_size_stubs): Use bfd_elf_get_elf_syms. Free/cache on exit.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.82
diff -u -p -r1.82 elf-bfd.h
--- bfd/elf-bfd.h 1 Jul 2002 08:06:40 -0000 1.82
+++ bfd/elf-bfd.h 7 Jul 2002 06:58:46 -0000
@@ -417,8 +417,7 @@ enum elf_reloc_type_class {
struct elf_reloc_cookie
{
Elf_Internal_Rela *rels, *rel, *relend;
- PTR locsyms;
- PTR locsym_shndx;
+ Elf_Internal_Sym *locsyms;
bfd *abfd;
size_t locsymcount;
size_t extsymoff;
@@ -1216,6 +1215,9 @@ extern char *bfd_elf_string_from_elf_sec
PARAMS ((bfd *, unsigned, unsigned));
extern char *bfd_elf_get_str_section
PARAMS ((bfd *, unsigned));
+extern Elf_Internal_Sym *bfd_elf_get_elf_syms
+ PARAMS ((bfd *, Elf_Internal_Shdr *, size_t, size_t,
+ Elf_Internal_Sym *, PTR, Elf_External_Sym_Shndx *));
extern boolean _bfd_elf_copy_private_bfd_data
PARAMS ((bfd *, bfd *));
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.152
diff -u -p -r1.152 elf.c
--- bfd/elf.c 4 Jul 2002 13:26:30 -0000 1.152
+++ bfd/elf.c 7 Jul 2002 06:58:52 -0000
@@ -352,6 +352,107 @@ bfd_elf_string_from_elf_section (abfd, s
return ((char *) hdr->contents) + strindex;
}
+/* Read and convert symbols to internal format.
+ SYMCOUNT specifies the number of symbols to read, starting from
+ symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
+ are non-NULL, they are used to store the internal symbols, external
+ symbols, and symbol section index extensions, respectively. */
+
+Elf_Internal_Sym *
+bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset,
+ intsym_buf, extsym_buf, extshndx_buf)
+ bfd *ibfd;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t symcount;
+ size_t symoffset;
+ Elf_Internal_Sym *intsym_buf;
+ PTR extsym_buf;
+ Elf_External_Sym_Shndx *extshndx_buf;
+{
+ Elf_Internal_Shdr *shndx_hdr;
+ PTR alloc_ext;
+ const PTR esym;
+ Elf_External_Sym_Shndx *alloc_extshndx;
+ Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ struct elf_backend_data *bed;
+ size_t extsym_size;
+ bfd_size_type amt;
+ file_ptr pos;
+
+ if (symcount == 0)
+ return intsym_buf;
+
+ /* Normal syms might have section extension entries. */
+ shndx_hdr = NULL;
+ if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
+ shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
+
+ /* Read the symbols. */
+ alloc_ext = NULL;
+ alloc_extshndx = NULL;
+ bed = get_elf_backend_data (ibfd);
+ extsym_size = bed->s->sizeof_sym;
+ amt = symcount * extsym_size;
+ pos = symtab_hdr->sh_offset + symoffset * extsym_size;
+ if (extsym_buf == NULL)
+ {
+ alloc_ext = bfd_malloc (amt);
+ extsym_buf = alloc_ext;
+ }
+ if (extsym_buf == NULL
+ || bfd_seek (ibfd, pos, SEEK_SET) != 0
+ || bfd_bread (extsym_buf, amt, ibfd) != amt)
+ {
+ intsym_buf = NULL;
+ goto out;
+ }
+
+ if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
+ extshndx_buf = NULL;
+ else
+ {
+ amt = symcount * sizeof (Elf_External_Sym_Shndx);
+ pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
+ if (extshndx_buf == NULL)
+ {
+ alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
+ extshndx_buf = alloc_extshndx;
+ }
+ if (extshndx_buf == NULL
+ || bfd_seek (ibfd, pos, SEEK_SET) != 0
+ || bfd_bread (extshndx_buf, amt, ibfd) != amt)
+ {
+ intsym_buf = NULL;
+ goto out;
+ }
+ }
+
+ if (intsym_buf == NULL)
+ {
+ bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
+ intsym_buf = (Elf_Internal_Sym *) bfd_malloc (amt);
+ if (intsym_buf == NULL)
+ goto out;
+ }
+
+ /* Convert the symbols to internal form. */
+ isymend = intsym_buf + symcount;
+ for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
+ isym < isymend;
+ esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
+ (*bed->s->swap_symbol_in) (ibfd, esym, (const PTR) shndx, isym);
+
+ out:
+ if (alloc_ext != NULL)
+ free (alloc_ext);
+ if (alloc_extshndx != NULL)
+ free (alloc_extshndx);
+
+ return intsym_buf;
+}
+
/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
sections. The first element is the flags, the rest are section
pointers. */
@@ -369,11 +470,7 @@ group_signature (abfd, ghdr)
bfd *abfd;
Elf_Internal_Shdr *ghdr;
{
- struct elf_backend_data *bed;
- file_ptr pos;
- bfd_size_type amt;
Elf_Internal_Shdr *hdr;
- Elf_Internal_Shdr *shndx_hdr;
unsigned char esym[sizeof (Elf64_External_Sym)];
Elf_External_Sym_Shndx eshndx;
Elf_Internal_Sym isym;
@@ -386,29 +483,10 @@ group_signature (abfd, ghdr)
/* Go read the symbol. */
hdr = &elf_tdata (abfd)->symtab_hdr;
- bed = get_elf_backend_data (abfd);
- amt = bed->s->sizeof_sym;
- pos = hdr->sh_offset + ghdr->sh_info * amt;
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread (esym, amt, abfd) != amt)
+ if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
+ &isym, esym, &eshndx) == NULL)
return NULL;
- /* And possibly the symbol section index extension. */
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- if (elf_elfsections (abfd) != NULL
- && elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
- {
- amt = sizeof (Elf_External_Sym_Shndx);
- pos = shndx_hdr->sh_offset + ghdr->sh_info * amt;
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) &eshndx, amt, abfd) != amt)
- return NULL;
- }
-
- /* Convert to internal format. */
- (*bed->s->swap_symbol_in) (abfd, (const PTR *) &esym, (const PTR *) &eshndx,
- &isym);
-
/* Look up the symbol name. */
iname = isym.st_name;
shindex = hdr->sh_link;
@@ -1976,50 +2054,19 @@ bfd_section_from_r_symndx (abfd, cache,
asection *sec;
unsigned long r_symndx;
{
- unsigned char esym_shndx[4];
- unsigned int isym_shndx;
Elf_Internal_Shdr *symtab_hdr;
- file_ptr pos;
- bfd_size_type amt;
+ unsigned char esym[sizeof (Elf64_External_Sym)];
+ Elf_External_Sym_Shndx eshndx;
+ Elf_Internal_Sym isym;
unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
return cache->sec[ent];
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- pos = symtab_hdr->sh_offset;
- if (get_elf_backend_data (abfd)->s->sizeof_sym
- == sizeof (Elf64_External_Sym))
- {
- 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);
- }
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
+ if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
+ &isym, esym, &eshndx) == NULL)
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)
{
@@ -2028,10 +2075,10 @@ bfd_section_from_r_symndx (abfd, cache,
}
cache->indx[ent] = r_symndx;
cache->sec[ent] = sec;
- if (isym_shndx < SHN_LORESERVE || isym_shndx > SHN_HIRESERVE)
+ if (isym.st_shndx < SHN_LORESERVE || isym.st_shndx > SHN_HIRESERVE)
{
asection *s;
- s = bfd_section_from_elf_index (abfd, isym_shndx);
+ s = bfd_section_from_elf_index (abfd, isym.st_shndx);
if (s != NULL)
cache->sec[ent] = s;
}
Index: bfd/elfcode.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcode.h,v
retrieving revision 1.32
diff -u -p -r1.32 elfcode.h
--- bfd/elfcode.h 25 Jun 2002 06:21:53 -0000 1.32
+++ bfd/elfcode.h 7 Jul 2002 06:58:53 -0000
@@ -1133,10 +1133,12 @@ elf_slurp_symbol_table (abfd, symptrs, d
unsigned long symcount; /* Number of external ELF symbols */
elf_symbol_type *sym; /* Pointer to current bfd symbol */
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
- Elf_Internal_Sym i_sym;
- Elf_External_Sym *x_symp = NULL;
- Elf_External_Sym_Shndx *x_shndx = NULL;
- Elf_External_Versym *x_versymp = NULL;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_External_Versym *xver;
+ Elf_External_Versym *xverbuf = NULL;
+ struct elf_backend_data *ebd;
bfd_size_type amt;
/* Read each raw ELF symbol, converting from external ELF form to
@@ -1151,24 +1153,8 @@ elf_slurp_symbol_table (abfd, symptrs, d
if (! dynamic)
{
- Elf_Internal_Shdr *shndx_hdr;
-
hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
verhdr = NULL;
-
- /* If we have a SHT_SYMTAB_SHNDX section for the symbol table,
- read the raw contents. */
- if (elf_elfsections (abfd) != NULL
- && elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
- {
- amt = shndx_hdr->sh_size;
- x_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (x_shndx == NULL
- || bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) x_shndx, amt, abfd) != amt)
- goto error_return;
- }
}
else
{
@@ -1187,39 +1173,24 @@ elf_slurp_symbol_table (abfd, symptrs, d
}
}
- if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
- goto error_return;
-
+ ebd = get_elf_backend_data (abfd);
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
-
if (symcount == 0)
sym = symbase = NULL;
else
{
- unsigned long i;
-
- if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
- goto error_return;
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return -1;
amt = symcount;
amt *= sizeof (elf_symbol_type);
symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
if (symbase == (elf_symbol_type *) NULL)
goto error_return;
- sym = symbase;
-
- /* Temporarily allocate room for the raw ELF symbols. */
- amt = symcount;
- amt *= sizeof (Elf_External_Sym);
- x_symp = (Elf_External_Sym *) bfd_malloc (amt);
- if (x_symp == NULL)
- goto error_return;
-
- if (bfd_bread ((PTR) x_symp, amt, abfd) != amt)
- goto error_return;
/* Read the raw ELF version symbol information. */
-
if (verhdr != NULL
&& verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
{
@@ -1239,42 +1210,40 @@ elf_slurp_symbol_table (abfd, symptrs, d
if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
goto error_return;
- x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
- if (x_versymp == NULL && verhdr->sh_size != 0)
+ xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
+ if (xverbuf == NULL && verhdr->sh_size != 0)
goto error_return;
- if (bfd_bread ((PTR) x_versymp, verhdr->sh_size, abfd)
+ if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd)
!= verhdr->sh_size)
goto error_return;
}
/* Skip first symbol, which is a null dummy. */
- for (i = 1; i < symcount; i++)
+ xver = xverbuf;
+ if (xver != NULL)
+ ++xver;
+ isymend = isymbuf + symcount;
+ for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
{
- elf_swap_symbol_in (abfd, (const PTR) (x_symp + i),
- (const PTR) (x_shndx + (x_shndx ? i : 0)),
- &i_sym);
- memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym));
-#ifdef ELF_KEEP_EXTSYM
- memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym));
-#endif
+ memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
sym->symbol.the_bfd = abfd;
sym->symbol.name = bfd_elf_string_from_elf_section (abfd,
hdr->sh_link,
- i_sym.st_name);
+ isym->st_name);
- sym->symbol.value = i_sym.st_value;
+ sym->symbol.value = isym->st_value;
- if (i_sym.st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
{
sym->symbol.section = bfd_und_section_ptr;
}
- else if (i_sym.st_shndx < SHN_LORESERVE
- || i_sym.st_shndx > SHN_HIRESERVE)
+ else if (isym->st_shndx < SHN_LORESERVE
+ || isym->st_shndx > SHN_HIRESERVE)
{
sym->symbol.section = section_from_elf_index (abfd,
- i_sym.st_shndx);
+ isym->st_shndx);
if (sym->symbol.section == NULL)
{
/* This symbol is in a section for which we did not
@@ -1283,18 +1252,18 @@ elf_slurp_symbol_table (abfd, symptrs, d
sym->symbol.section = bfd_abs_section_ptr;
}
}
- else if (i_sym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
{
sym->symbol.section = bfd_abs_section_ptr;
}
- else if (i_sym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
{
sym->symbol.section = bfd_com_section_ptr;
/* Elf puts the alignment into the `value' field, and
the size into the `size' field. BFD wants to see the
size in the value field, and doesn't care (at the
moment) about the alignment. */
- sym->symbol.value = i_sym.st_size;
+ sym->symbol.value = isym->st_size;
}
else
sym->symbol.section = bfd_abs_section_ptr;
@@ -1304,14 +1273,13 @@ elf_slurp_symbol_table (abfd, symptrs, d
if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
sym->symbol.value -= sym->symbol.section->vma;
- switch (ELF_ST_BIND (i_sym.st_info))
+ switch (ELF_ST_BIND (isym->st_info))
{
case STB_LOCAL:
sym->symbol.flags |= BSF_LOCAL;
break;
case STB_GLOBAL:
- if (i_sym.st_shndx != SHN_UNDEF
- && i_sym.st_shndx != SHN_COMMON)
+ if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
sym->symbol.flags |= BSF_GLOBAL;
break;
case STB_WEAK:
@@ -1319,7 +1287,7 @@ elf_slurp_symbol_table (abfd, symptrs, d
break;
}
- switch (ELF_ST_TYPE (i_sym.st_info))
+ switch (ELF_ST_TYPE (isym->st_info))
{
case STT_SECTION:
sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
@@ -1338,31 +1306,24 @@ elf_slurp_symbol_table (abfd, symptrs, d
if (dynamic)
sym->symbol.flags |= BSF_DYNAMIC;
- if (x_versymp != NULL)
+ if (xver != NULL)
{
Elf_Internal_Versym iversym;
- _bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
+ _bfd_elf_swap_versym_in (abfd, xver, &iversym);
sym->version = iversym.vs_vers;
+ xver++;
}
/* Do some backend-specific processing on this symbol. */
- {
- struct elf_backend_data *ebd = get_elf_backend_data (abfd);
- if (ebd->elf_backend_symbol_processing)
- (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
- }
-
- sym++;
+ if (ebd->elf_backend_symbol_processing)
+ (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
}
}
/* Do some backend-specific processing on this symbol table. */
- {
- struct elf_backend_data *ebd = get_elf_backend_data (abfd);
- if (ebd->elf_backend_symbol_table_processing)
- (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
- }
+ if (ebd->elf_backend_symbol_table_processing)
+ (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
/* We rely on the zalloc to clear out the final symbol entry. */
@@ -1382,21 +1343,17 @@ elf_slurp_symbol_table (abfd, symptrs, d
*symptrs = 0; /* Final null pointer */
}
- if (x_shndx != NULL)
- free (x_shndx);
- if (x_versymp != NULL)
- free (x_versymp);
- if (x_symp != NULL)
- free (x_symp);
+ if (xverbuf != NULL)
+ free (xverbuf);
+ if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
return symcount;
error_return:
- if (x_shndx != NULL)
- free (x_shndx);
- if (x_versymp != NULL)
- free (x_versymp);
- if (x_symp != NULL)
- free (x_symp);
+ if (xverbuf != NULL)
+ free (xverbuf);
+ if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
return -1;
}
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.173
diff -u -p -r1.173 elflink.h
--- bfd/elflink.h 4 Jul 2002 13:26:30 -0000 1.173
+++ bfd/elflink.h 7 Jul 2002 06:59:01 -0000
@@ -149,18 +149,13 @@ elf_link_is_defined_archive_symbol (abfd
carsym * symdef;
{
Elf_Internal_Shdr * hdr;
- Elf_Internal_Shdr * shndx_hdr;
- Elf_External_Sym * esym;
- Elf_External_Sym * esymend;
- Elf_External_Sym * buf = NULL;
- Elf_External_Sym_Shndx * shndx_buf = NULL;
- Elf_External_Sym_Shndx * shndx;
bfd_size_type symcount;
bfd_size_type extsymcount;
bfd_size_type extsymoff;
- boolean result = false;
- file_ptr pos;
- bfd_size_type amt;
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ boolean result;
abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
if (abfd == (bfd *) NULL)
@@ -178,15 +173,9 @@ elf_link_is_defined_archive_symbol (abfd
/* Select the appropriate symbol table. */
if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
- {
- hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- }
+ hdr = &elf_tdata (abfd)->symtab_hdr;
else
- {
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
- shndx_hdr = NULL;
- }
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
@@ -203,58 +192,34 @@ elf_link_is_defined_archive_symbol (abfd
extsymoff = hdr->sh_info;
}
- amt = extsymcount * sizeof (Elf_External_Sym);
- buf = (Elf_External_Sym *) bfd_malloc (amt);
- if (buf == NULL && extsymcount != 0)
- return false;
-
- /* Read in the symbol table.
- FIXME: This ought to be cached somewhere. */
- pos = hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym);
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) buf, amt, abfd) != amt)
- goto error_exit;
-
- if (shndx_hdr != NULL && shndx_hdr->sh_size != 0)
- {
- amt = extsymcount * sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL && extsymcount != 0)
- goto error_exit;
-
- pos = shndx_hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym_Shndx);
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
- goto error_exit;
- }
+ if (extsymcount == 0)
+ return false;
+
+ /* Read in the symbol table. */
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return false;
/* Scan the symbol table looking for SYMDEF. */
- esymend = buf + extsymcount;
- for (esym = buf, shndx = shndx_buf;
- esym < esymend;
- esym++, shndx = (shndx != NULL ? shndx + 1 : NULL))
+ result = false;
+ for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++)
{
- Elf_Internal_Sym sym;
- const char * name;
-
- elf_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx, &sym);
+ const char *name;
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name);
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
if (name == (const char *) NULL)
break;
if (strcmp (name, symdef->name) == 0)
{
- result = is_global_data_symbol_definition (abfd, & sym);
+ result = is_global_data_symbol_definition (abfd, isym);
break;
}
}
- error_exit:
- if (shndx_buf != NULL)
- free (shndx_buf);
- if (buf != NULL)
- free (buf);
+ free (isymbuf);
return result;
}
@@ -1186,25 +1151,20 @@ elf_link_add_object_symbols (abfd, info)
asection *, const Elf_Internal_Rela *));
boolean collect;
Elf_Internal_Shdr *hdr;
- Elf_Internal_Shdr *shndx_hdr;
bfd_size_type symcount;
bfd_size_type extsymcount;
bfd_size_type extsymoff;
- Elf_External_Sym *buf = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
- Elf_External_Sym_Shndx *shndx;
struct elf_link_hash_entry **sym_hash;
boolean dynamic;
Elf_External_Versym *extversym = NULL;
Elf_External_Versym *ever;
- Elf_External_Dyn *dynbuf = NULL;
struct elf_link_hash_entry *weaks;
- Elf_External_Sym *esym;
- Elf_External_Sym *esymend;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
struct elf_backend_data *bed;
boolean dt_needed;
struct elf_link_hash_table * hash_table;
- file_ptr pos;
bfd_size_type amt;
hash_table = elf_hash_table (info);
@@ -1303,85 +1263,7 @@ elf_link_add_object_symbols (abfd, info)
}
}
- /* If this is a dynamic object, we always link against the .dynsym
- symbol table, not the .symtab symbol table. The dynamic linker
- will only see the .dynsym symbol table, so there is no reason to
- look at .symtab for a dynamic object. */
-
- if (! dynamic || elf_dynsymtab (abfd) == 0)
- {
- hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- }
- else
- {
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
- shndx_hdr = NULL;
- }
-
- if (dynamic)
- {
- /* Read in any version definitions. */
-
- if (! _bfd_elf_slurp_version_tables (abfd))
- goto error_return;
-
- /* Read in the symbol versions, but don't bother to convert them
- to internal format. */
- if (elf_dynversym (abfd) != 0)
- {
- Elf_Internal_Shdr *versymhdr;
-
- versymhdr = &elf_tdata (abfd)->dynversym_hdr;
- extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
- if (extversym == NULL)
- goto error_return;
- amt = versymhdr->sh_size;
- if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) extversym, amt, abfd) != amt)
- goto error_return;
- }
- }
-
- symcount = hdr->sh_size / sizeof (Elf_External_Sym);
-
- /* The sh_info field of the symtab header tells us where the
- external symbols start. We don't care about the local symbols at
- this point. */
- if (elf_bad_symtab (abfd))
- {
- extsymcount = symcount;
- extsymoff = 0;
- }
- else
- {
- extsymcount = symcount - hdr->sh_info;
- extsymoff = hdr->sh_info;
- }
-
- amt = extsymcount * sizeof (Elf_External_Sym);
- buf = (Elf_External_Sym *) bfd_malloc (amt);
- if (buf == NULL && extsymcount != 0)
- goto error_return;
-
- if (shndx_hdr != NULL && shndx_hdr->sh_size != 0)
- {
- amt = extsymcount * sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL && extsymcount != 0)
- goto error_return;
- }
-
- /* We store a pointer to the hash table entry for each external
- symbol. */
- amt = extsymcount * sizeof (struct elf_link_hash_entry *);
- sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
- if (sym_hash == NULL)
- goto error_return;
- elf_sym_hashes (abfd) = sym_hash;
-
dt_needed = false;
-
if (! dynamic)
{
/* If we are creating a shared library, create all the dynamic
@@ -1431,6 +1313,7 @@ elf_link_add_object_symbols (abfd, info)
s = bfd_get_section_by_name (abfd, ".dynamic");
if (s != NULL)
{
+ Elf_External_Dyn *dynbuf = NULL;
Elf_External_Dyn *extdyn;
Elf_External_Dyn *extdynend;
int elfsec;
@@ -1444,11 +1327,11 @@ elf_link_add_object_symbols (abfd, info)
if (! bfd_get_section_contents (abfd, s, (PTR) dynbuf,
(file_ptr) 0, s->_raw_size))
- goto error_return;
+ goto error_free_dyn;
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
if (elfsec == -1)
- goto error_return;
+ goto error_free_dyn;
shlink = elf_elfsections (abfd)[elfsec]->sh_link;
extdyn = dynbuf;
@@ -1465,7 +1348,7 @@ elf_link_add_object_symbols (abfd, info)
unsigned int tagv = dyn.d_un.d_val;
name = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (name == NULL)
- goto error_return;
+ goto error_free_dyn;
}
if (dyn.d_tag == DT_NEEDED)
{
@@ -1477,11 +1360,11 @@ elf_link_add_object_symbols (abfd, info)
n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (n == NULL || fnm == NULL)
- goto error_return;
+ goto error_free_dyn;
amt = strlen (fnm) + 1;
anm = bfd_alloc (abfd, amt);
if (anm == NULL)
- goto error_return;
+ goto error_free_dyn;
memcpy (anm, fnm, (size_t) amt);
n->name = anm;
n->by = abfd;
@@ -1509,11 +1392,11 @@ elf_link_add_object_symbols (abfd, info)
n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (n == NULL || fnm == NULL)
- goto error_return;
+ goto error_free_dyn;
amt = strlen (fnm) + 1;
anm = bfd_alloc (abfd, amt);
if (anm == NULL)
- goto error_return;
+ goto error_free_dyn;
memcpy (anm, fnm, (size_t) amt);
n->name = anm;
n->by = abfd;
@@ -1537,11 +1420,15 @@ elf_link_add_object_symbols (abfd, info)
n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
if (n == NULL || fnm == NULL)
- goto error_return;
+ goto error_free_dyn;
amt = strlen (fnm) + 1;
anm = bfd_alloc (abfd, amt);
if (anm == NULL)
- goto error_return;
+ {
+ error_free_dyn:
+ free (dynbuf);
+ goto error_return;
+ }
memcpy (anm, fnm, (size_t) amt);
n->name = anm;
n->by = abfd;
@@ -1556,7 +1443,6 @@ elf_link_add_object_symbols (abfd, info)
}
free (dynbuf);
- dynbuf = NULL;
}
/* We do not want to include any of the sections in a dynamic
@@ -1606,10 +1492,6 @@ elf_link_add_object_symbols (abfd, info)
if (dyn.d_tag == DT_NEEDED
&& dyn.d_un.d_val == strindex)
{
- if (buf != NULL)
- free (buf);
- if (extversym != NULL)
- free (extversym);
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
return true;
}
@@ -1627,31 +1509,79 @@ elf_link_add_object_symbols (abfd, info)
elf_dt_name (abfd) = name;
}
- pos = hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym);
- amt = extsymcount * sizeof (Elf_External_Sym);
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) buf, amt, abfd) != amt)
- goto error_return;
+ /* If this is a dynamic object, we always link against the .dynsym
+ symbol table, not the .symtab symbol table. The dynamic linker
+ will only see the .dynsym symbol table, so there is no reason to
+ look at .symtab for a dynamic object. */
+
+ if (! dynamic || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
- if (shndx_hdr != NULL && shndx_hdr->sh_size != 0)
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local symbols at
+ this point. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
{
- amt = extsymcount * sizeof (Elf_External_Sym_Shndx);
- pos = shndx_hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym_Shndx);
- if (bfd_seek (abfd, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ sym_hash = NULL;
+ if (extsymcount != 0)
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
goto error_return;
+
+ /* We store a pointer to the hash table entry for each external
+ symbol. */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_free_sym;
+ elf_sym_hashes (abfd) = sym_hash;
+ }
+
+ if (dynamic)
+ {
+ /* Read in any version definitions. */
+ if (! _bfd_elf_slurp_version_tables (abfd))
+ goto error_free_sym;
+
+ /* Read in the symbol versions, but don't bother to convert them
+ to internal format. */
+ if (elf_dynversym (abfd) != 0)
+ {
+ Elf_Internal_Shdr *versymhdr;
+
+ versymhdr = &elf_tdata (abfd)->dynversym_hdr;
+ extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
+ if (extversym == NULL)
+ goto error_free_sym;
+ amt = versymhdr->sh_size;
+ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread ((PTR) extversym, amt, abfd) != amt)
+ goto error_free_vers;
+ }
}
weaks = NULL;
ever = extversym != NULL ? extversym + extsymoff : NULL;
- esymend = buf + extsymcount;
- for (esym = buf, shndx = shndx_buf;
- esym < esymend;
- esym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL),
- shndx = (shndx != NULL ? shndx + 1 : NULL))
+ for (isym = isymbuf, isymend = isymbuf + extsymcount;
+ isym < isymend;
+ isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
{
- Elf_Internal_Sym sym;
int bind;
bfd_vma value;
asection *sec;
@@ -1666,14 +1596,12 @@ elf_link_add_object_symbols (abfd, info)
override = false;
- elf_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx, &sym);
-
flags = BSF_NO_FLAGS;
sec = NULL;
- value = sym.st_value;
+ value = isym->st_value;
*sym_hash = NULL;
- bind = ELF_ST_BIND (sym.st_info);
+ bind = ELF_ST_BIND (isym->st_info);
if (bind == STB_LOCAL)
{
/* This should be impossible, since ELF requires that all
@@ -1684,8 +1612,8 @@ elf_link_add_object_symbols (abfd, info)
}
else if (bind == STB_GLOBAL)
{
- if (sym.st_shndx != SHN_UNDEF
- && sym.st_shndx != SHN_COMMON)
+ if (isym->st_shndx != SHN_UNDEF
+ && isym->st_shndx != SHN_COMMON)
flags = BSF_GLOBAL;
}
else if (bind == STB_WEAK)
@@ -1695,35 +1623,37 @@ elf_link_add_object_symbols (abfd, info)
/* Leave it up to the processor backend. */
}
- if (sym.st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
sec = bfd_und_section_ptr;
- else if (sym.st_shndx < SHN_LORESERVE || sym.st_shndx > SHN_HIRESERVE)
+ else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
{
- sec = section_from_elf_index (abfd, sym.st_shndx);
+ sec = section_from_elf_index (abfd, isym->st_shndx);
if (sec == NULL)
sec = bfd_abs_section_ptr;
else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
value -= sec->vma;
}
- else if (sym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sec = bfd_abs_section_ptr;
- else if (sym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
{
sec = bfd_com_section_ptr;
/* What ELF calls the size we call the value. What ELF
calls the value we call the alignment. */
- value = sym.st_size;
+ value = isym->st_size;
}
else
{
/* Leave it up to the processor backend. */
}
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, sym.st_name);
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
if (name == (const char *) NULL)
- goto error_return;
+ goto error_free_vers;
- if (sym.st_shndx == SHN_COMMON && ELF_ST_TYPE (sym.st_info) == STT_TLS)
+ if (isym->st_shndx == SHN_COMMON
+ && ELF_ST_TYPE (isym->st_info) == STT_TLS)
{
asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
@@ -1735,15 +1665,15 @@ elf_link_add_object_symbols (abfd, info)
| SEC_IS_COMMON
| SEC_LINKER_CREATED
| SEC_THREAD_LOCAL)))
- goto error_return;
+ goto error_free_vers;
}
sec = tcomm;
}
else if (add_symbol_hook)
{
- if (! (*add_symbol_hook) (abfd, info, &sym, &name, &flags, &sec,
+ if (! (*add_symbol_hook) (abfd, info, isym, &name, &flags, &sec,
&value))
- goto error_return;
+ goto error_free_vers;
/* The hook function sets the name to NULL if this symbol
should be skipped for some reason. */
@@ -1755,7 +1685,7 @@ elf_link_add_object_symbols (abfd, info)
if (sec == (asection *) NULL)
{
bfd_set_error (bfd_error_bad_value);
- goto error_return;
+ goto error_free_vers;
}
if (bfd_is_und_section (sec)
@@ -1789,7 +1719,7 @@ elf_link_add_object_symbols (abfd, info)
size_t namelen, verlen, newlen;
char *newname, *p;
- if (sym.st_shndx != SHN_UNDEF)
+ if (isym->st_shndx != SHN_UNDEF)
{
if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
{
@@ -1798,7 +1728,7 @@ elf_link_add_object_symbols (abfd, info)
bfd_archive_filename (abfd), name, vernum,
elf_tdata (abfd)->dynverdef_hdr.sh_info);
bfd_set_error (bfd_error_bad_value);
- goto error_return;
+ goto error_free_vers;
}
else if (vernum > 1)
verstr =
@@ -1838,7 +1768,7 @@ elf_link_add_object_symbols (abfd, info)
(_("%s: %s: invalid needed version %d"),
bfd_archive_filename (abfd), name, vernum);
bfd_set_error (bfd_error_bad_value);
- goto error_return;
+ goto error_free_vers;
}
}
@@ -1846,12 +1776,12 @@ elf_link_add_object_symbols (abfd, info)
verlen = strlen (verstr);
newlen = namelen + verlen + 2;
if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && sym.st_shndx != SHN_UNDEF)
+ && isym->st_shndx != SHN_UNDEF)
++newlen;
newname = (char *) bfd_alloc (abfd, (bfd_size_type) newlen);
if (newname == NULL)
- goto error_return;
+ goto error_free_vers;
memcpy (newname, name, namelen);
p = newname + namelen;
*p++ = ELF_VER_CHR;
@@ -1859,7 +1789,7 @@ elf_link_add_object_symbols (abfd, info)
we add another @ to the name. This indicates the
default version of the symbol. */
if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && sym.st_shndx != SHN_UNDEF)
+ && isym->st_shndx != SHN_UNDEF)
*p++ = ELF_VER_CHR;
memcpy (p, verstr, verlen + 1);
@@ -1867,10 +1797,10 @@ elf_link_add_object_symbols (abfd, info)
}
}
- if (! elf_merge_symbol (abfd, info, name, &sym, &sec, &value,
+ if (! elf_merge_symbol (abfd, info, name, isym, &sec, &value,
sym_hash, &override, &type_change_ok,
&size_change_ok, dt_needed))
- goto error_return;
+ goto error_free_vers;
if (override)
definition = false;
@@ -1898,7 +1828,7 @@ elf_link_add_object_symbols (abfd, info)
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, sec, value, (const char *) NULL,
false, collect, (struct bfd_link_hash_entry **) sym_hash)))
- goto error_return;
+ goto error_free_vers;
h = *sym_hash;
while (h->root.type == bfd_link_hash_indirect
@@ -1910,7 +1840,7 @@ elf_link_add_object_symbols (abfd, info)
if (dynamic
&& definition
&& (flags & BSF_WEAK) != 0
- && ELF_ST_TYPE (sym.st_info) != STT_FUNC
+ && ELF_ST_TYPE (isym->st_info) != STT_FUNC
&& info->hash->creator->flavour == bfd_target_elf_flavour
&& h->weakdef == NULL)
{
@@ -1932,16 +1862,16 @@ elf_link_add_object_symbols (abfd, info)
}
/* Set the alignment of a common symbol. */
- if (sym.st_shndx == SHN_COMMON
+ if (isym->st_shndx == SHN_COMMON
&& h->root.type == bfd_link_hash_common)
{
unsigned int align;
- align = bfd_log2 (sym.st_value);
+ align = bfd_log2 (isym->st_value);
if (align > old_alignment
/* Permit an alignment power of zero if an alignment of one
is specified and no other alignments have been specified. */
- || (sym.st_value == 1 && old_alignment == 0))
+ || (isym->st_value == 1 && old_alignment == 0))
h->root.u.c.p->alignment_power = align;
}
@@ -1952,16 +1882,16 @@ elf_link_add_object_symbols (abfd, info)
int new_flag;
/* Remember the symbol size and type. */
- if (sym.st_size != 0
+ if (isym->st_size != 0
&& (definition || h->size == 0))
{
- if (h->size != 0 && h->size != sym.st_size && ! size_change_ok)
+ if (h->size != 0 && h->size != isym->st_size && ! size_change_ok)
(*_bfd_error_handler)
(_("Warning: size of symbol `%s' changed from %lu to %lu in %s"),
- name, (unsigned long) h->size, (unsigned long) sym.st_size,
- bfd_archive_filename (abfd));
+ name, (unsigned long) h->size,
+ (unsigned long) isym->st_size, bfd_archive_filename (abfd));
- h->size = sym.st_size;
+ h->size = isym->st_size;
}
/* If this is a common symbol, then we always want H->SIZE
@@ -1972,37 +1902,37 @@ elf_link_add_object_symbols (abfd, info)
if (h->root.type == bfd_link_hash_common)
h->size = h->root.u.c.size;
- if (ELF_ST_TYPE (sym.st_info) != STT_NOTYPE
+ if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
&& (definition || h->type == STT_NOTYPE))
{
if (h->type != STT_NOTYPE
- && h->type != ELF_ST_TYPE (sym.st_info)
+ && h->type != ELF_ST_TYPE (isym->st_info)
&& ! type_change_ok)
(*_bfd_error_handler)
(_("Warning: type of symbol `%s' changed from %d to %d in %s"),
- name, h->type, ELF_ST_TYPE (sym.st_info),
+ name, h->type, ELF_ST_TYPE (isym->st_info),
bfd_archive_filename (abfd));
- h->type = ELF_ST_TYPE (sym.st_info);
+ h->type = ELF_ST_TYPE (isym->st_info);
}
/* If st_other has a processor-specific meaning, specific code
might be needed here. */
- if (sym.st_other != 0)
+ if (isym->st_other != 0)
{
/* Combine visibilities, using the most constraining one. */
unsigned char hvis = ELF_ST_VISIBILITY (h->other);
- unsigned char symvis = ELF_ST_VISIBILITY (sym.st_other);
+ unsigned char symvis = ELF_ST_VISIBILITY (isym->st_other);
if (symvis && (hvis > symvis || hvis == 0))
- h->other = sym.st_other;
+ h->other = isym->st_other;
/* If neither has visibility, use the st_other of the
definition. This is an arbitrary choice, since the
other bits have no general meaning. */
if (!symvis && !hvis
&& (definition || h->other == 0))
- h->other = sym.st_other;
+ h->other = isym->st_other;
}
/* Set a flag in the hash table entry indicating the type of
@@ -2046,21 +1976,21 @@ elf_link_add_object_symbols (abfd, info)
/* Check to see if we need to add an indirect symbol for
the default name. */
if (definition || h->root.type == bfd_link_hash_common)
- if (! elf_add_default_symbol (abfd, info, h, name, &sym,
+ if (! elf_add_default_symbol (abfd, info, h, name, isym,
&sec, &value, &dynsym,
override, dt_needed))
- goto error_return;
+ goto error_free_vers;
if (dynsym && h->dynindx == -1)
{
if (! _bfd_elf_link_record_dynamic_symbol (info, h))
- goto error_return;
+ goto error_free_vers;
if (h->weakdef != NULL
&& ! new_weakdef
&& h->weakdef->dynindx == -1)
{
if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef))
- goto error_return;
+ goto error_free_vers;
}
}
else if (dynsym && h->dynindx != -1)
@@ -2083,7 +2013,7 @@ elf_link_add_object_symbols (abfd, info)
bfd_size_type strindex;
if (! is_elf_hash_table (info))
- goto error_return;
+ goto error_free_vers;
/* The symbol from a DT_NEEDED object is referenced from
the regular object to create a dynamic executable. We
@@ -2094,7 +2024,7 @@ elf_link_add_object_symbols (abfd, info)
strindex = _bfd_elf_strtab_add (hash_table->dynstr,
elf_dt_soname (abfd), false);
if (strindex == (bfd_size_type) -1)
- goto error_return;
+ goto error_free_vers;
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
{
@@ -2120,11 +2050,21 @@ elf_link_add_object_symbols (abfd, info)
}
if (! elf_add_dynamic_entry (info, (bfd_vma) DT_NEEDED, strindex))
- goto error_return;
+ goto error_free_vers;
}
}
}
+ if (extversym != NULL)
+ {
+ free (extversym);
+ extversym = NULL;
+ }
+
+ if (isymbuf != NULL)
+ free (isymbuf);
+ isymbuf = NULL;
+
/* Now set the weakdefs field correctly for all the weak defined
symbols we found. The only way to do this is to search all the
symbols. Since we only need the information for non functions in
@@ -2192,24 +2132,11 @@ elf_link_add_object_symbols (abfd, info)
if (! _bfd_elf_link_record_dynamic_symbol (info, hlook))
goto error_return;
}
-
break;
}
}
}
- if (buf != NULL)
- {
- free (buf);
- buf = NULL;
- }
-
- if (extversym != NULL)
- {
- free (extversym);
- extversym = NULL;
- }
-
/* If this object is the same format as the output object, and it is
not a shared library, then let the backend look through the
relocs.
@@ -2255,7 +2182,7 @@ elf_link_add_object_symbols (abfd, info)
ok = (*check_relocs) (abfd, info, o, internal_relocs);
- if (! info->keep_memory)
+ if (elf_section_data (o)->relocs != internal_relocs)
free (internal_relocs);
if (! ok)
@@ -2334,13 +2261,13 @@ elf_link_add_object_symbols (abfd, info)
return true;
- error_return:
- if (buf != NULL)
- free (buf);
- if (dynbuf != NULL)
- free (dynbuf);
+ error_free_vers:
if (extversym != NULL)
free (extversym);
+ error_free_sym:
+ if (isymbuf != NULL)
+ free (isymbuf);
+ error_return:
return false;
}
@@ -5050,7 +4977,7 @@ elf_bfd_final_link (abfd, info)
o->reloc_count
+= (*bed->elf_backend_count_relocs) (sec, relocs);
- if (!info->keep_memory)
+ if (elf_section_data (o)->relocs != relocs)
free (relocs);
}
@@ -6072,8 +5999,6 @@ elf_link_check_versioned_symbol (info, h
{
bfd *undef_bfd = h->root.u.undef.abfd;
struct elf_link_loaded_list *loaded;
- Elf_External_Sym *buf;
- Elf_External_Versym *extversym;
if ((undef_bfd->flags & DYNAMIC) == 0
|| info->hash->creator->flavour != bfd_target_elf_flavour
@@ -6090,11 +6015,11 @@ elf_link_check_versioned_symbol (info, h
bfd_size_type extsymcount;
bfd_size_type extsymoff;
Elf_Internal_Shdr *versymhdr;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ Elf_Internal_Sym *isymbuf;
Elf_External_Versym *ever;
- Elf_External_Sym *esym;
- Elf_External_Sym *esymend;
- bfd_size_type count;
- file_ptr pos;
+ Elf_External_Versym *extversym;
input = loaded->abfd;
@@ -6121,17 +6046,11 @@ elf_link_check_versioned_symbol (info, h
if (extsymcount == 0)
continue;
- count = extsymcount * sizeof (Elf_External_Sym);
- buf = (Elf_External_Sym *) bfd_malloc (count);
- if (buf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
return false;
- /* Read in the symbol table. */
- pos = hdr->sh_offset + extsymoff * sizeof (Elf_External_Sym);
- if (bfd_seek (input, pos, SEEK_SET) != 0
- || bfd_bread ((PTR) buf, count, input) != count)
- goto error_ret;
-
/* Read in any version definitions. */
versymhdr = &elf_tdata (input)->dynversym_hdr;
extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size);
@@ -6144,26 +6063,24 @@ elf_link_check_versioned_symbol (info, h
{
free (extversym);
error_ret:
- free (buf);
+ free (isymbuf);
return false;
}
ever = extversym + extsymoff;
- esymend = buf + extsymcount;
- for (esym = buf; esym < esymend; esym++, ever++)
+ isymend = isymbuf + extsymcount;
+ for (isym = isymbuf; isym < isymend; isym++, ever++)
{
const char *name;
- Elf_Internal_Sym sym;
Elf_Internal_Versym iver;
- elf_swap_symbol_in (input, esym, NULL, &sym);
- if (ELF_ST_BIND (sym.st_info) == STB_LOCAL
- || sym.st_shndx == SHN_UNDEF)
+ if (ELF_ST_BIND (isym->st_info) == STB_LOCAL
+ || isym->st_shndx == SHN_UNDEF)
continue;
name = bfd_elf_string_from_elf_section (input,
hdr->sh_link,
- sym.st_name);
+ isym->st_name);
if (strcmp (name, h->root.root.string) != 0)
continue;
@@ -6180,13 +6097,13 @@ elf_link_check_versioned_symbol (info, h
{
/* This is the oldest (default) sym. We can use it. */
free (extversym);
- free (buf);
+ free (isymbuf);
return true;
}
}
free (extversym);
- free (buf);
+ free (isymbuf);
}
return false;
@@ -6611,15 +6528,11 @@ elf_link_input_bfd (finfo, input_bfd)
Elf_Internal_Sym *, asection **));
bfd *output_bfd;
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
size_t locsymcount;
size_t extsymoff;
- Elf_External_Sym *external_syms;
- Elf_External_Sym *esym;
- Elf_External_Sym *esymend;
- Elf_External_Sym_Shndx *shndx_buf;
- Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isymbuf;
Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
long *pindex;
asection **ppsection;
asection *o;
@@ -6654,45 +6567,29 @@ elf_link_input_bfd (finfo, input_bfd)
}
/* Read the local symbols. */
- if (symtab_hdr->contents != NULL)
- external_syms = (Elf_External_Sym *) symtab_hdr->contents;
- else if (locsymcount == 0)
- external_syms = NULL;
- else
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL && locsymcount != 0)
{
- bfd_size_type amt = locsymcount * sizeof (Elf_External_Sym);
- external_syms = finfo->external_syms;
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (external_syms, amt, input_bfd) != amt)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
+ finfo->internal_syms,
+ finfo->external_syms,
+ finfo->locsym_shndx);
+ if (isymbuf == NULL)
return false;
}
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
- shndx_buf = NULL;
- if (shndx_hdr->sh_size != 0 && locsymcount != 0)
- {
- bfd_size_type amt = locsymcount * sizeof (Elf_External_Sym_Shndx);
- shndx_buf = finfo->locsym_shndx;
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (shndx_buf, amt, input_bfd) != amt)
- return false;
- }
-
- /* Swap in the local symbols and write out the ones which we know
- are going into the output file. */
- for (esym = external_syms, esymend = esym + locsymcount,
- isym = finfo->internal_syms, pindex = finfo->indices,
- ppsection = finfo->sections, shndx = shndx_buf;
- esym < esymend;
- esym++, isym++, pindex++, ppsection++,
- shndx = (shndx != NULL ? shndx + 1 : NULL))
+ /* Find local symbol sections and adjust values of symbols in
+ SEC_MERGE sections. Write out those local symbols we know are
+ going into the output file. */
+ isymend = isymbuf + locsymcount;
+ for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections;
+ isym < isymend;
+ isym++, pindex++, ppsection++)
{
asection *isec;
const char *name;
Elf_Internal_Sym osym;
- elf_swap_symbol_in (input_bfd, (const PTR) esym, (const PTR) shndx,
- isym);
*pindex = -1;
if (elf_bad_symtab (input_bfd))
@@ -6731,7 +6628,7 @@ elf_link_input_bfd (finfo, input_bfd)
*ppsection = isec;
/* Don't output the first, undefined, symbol. */
- if (esym == external_syms)
+ if (ppsection == finfo->sections)
continue;
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
@@ -7001,7 +6898,7 @@ elf_link_input_bfd (finfo, input_bfd)
if (! (*relocate_section) (output_bfd, finfo->info,
input_bfd, o, contents,
internal_relocs,
- finfo->internal_syms,
+ isymbuf,
finfo->sections))
return false;
@@ -7085,7 +6982,7 @@ elf_link_input_bfd (finfo, input_bfd)
/* This is a reloc against a local symbol. */
*rel_hash = NULL;
- isym = finfo->internal_syms + r_symndx;
+ isym = isymbuf + r_symndx;
sec = finfo->sections[r_symndx];
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
{
@@ -7762,17 +7659,12 @@ elf_gc_mark (info, sec, gc_mark_hook)
{
Elf_Internal_Rela *relstart, *rel, *relend;
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
struct elf_link_hash_entry **sym_hashes;
size_t nlocsyms;
size_t extsymoff;
- Elf_External_Sym *locsyms, *freesyms = NULL;
- Elf_External_Sym_Shndx *locsym_shndx;
bfd *input_bfd = sec->owner;
struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
-
- /* GCFIXME: how to arrange so that relocs and symbols are not
- reread continually? */
+ Elf_Internal_Sym *isym = NULL;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (input_bfd);
@@ -7786,37 +7678,18 @@ elf_gc_mark (info, sec, gc_mark_hook)
else
extsymoff = nlocsyms = symtab_hdr->sh_info;
- if (symtab_hdr->contents)
- locsyms = (Elf_External_Sym *) symtab_hdr->contents;
- else if (nlocsyms == 0)
- locsyms = NULL;
- else
- {
- bfd_size_type amt = nlocsyms * sizeof (Elf_External_Sym);
- locsyms = freesyms = bfd_malloc (amt);
- if (freesyms == NULL
- || bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (locsyms, amt, input_bfd) != amt)
- {
- ret = false;
- goto out1;
- }
- }
-
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
- locsym_shndx = NULL;
- if (shndx_hdr->sh_size != 0 && nlocsyms != 0)
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isym == NULL && nlocsyms != 0)
{
- bfd_size_type amt = nlocsyms * sizeof (Elf_External_Sym_Shndx);
- locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (locsym_shndx, amt, input_bfd) != amt)
+ isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0,
+ NULL, NULL, NULL);
+ if (isym == NULL)
return false;
}
/* Read the relocations. */
relstart = (NAME(_bfd_elf,link_read_relocs)
- (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL,
+ (input_bfd, sec, NULL, (Elf_Internal_Rela *) NULL,
info->keep_memory));
if (relstart == NULL)
{
@@ -7830,41 +7703,20 @@ elf_gc_mark (info, sec, gc_mark_hook)
unsigned long r_symndx;
asection *rsec;
struct elf_link_hash_entry *h;
- Elf_Internal_Sym s;
- Elf_External_Sym_Shndx *locshndx;
r_symndx = ELF_R_SYM (rel->r_info);
if (r_symndx == 0)
continue;
- if (elf_bad_symtab (sec->owner))
- {
- locshndx = locsym_shndx + (locsym_shndx ? r_symndx : 0);
- elf_swap_symbol_in (input_bfd,
- (const PTR) (locsyms + r_symndx),
- (const PTR) locshndx,
- &s);
- if (ELF_ST_BIND (s.st_info) == STB_LOCAL)
- rsec = (*gc_mark_hook) (sec, info, rel, NULL, &s);
- else
- {
- h = sym_hashes[r_symndx - extsymoff];
- rsec = (*gc_mark_hook) (sec, info, rel, h, NULL);
- }
- }
- else if (r_symndx >= nlocsyms)
+ if (r_symndx >= nlocsyms
+ || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL)
{
h = sym_hashes[r_symndx - extsymoff];
rsec = (*gc_mark_hook) (sec, info, rel, h, NULL);
}
else
{
- locshndx = locsym_shndx + (locsym_shndx ? r_symndx : 0);
- elf_swap_symbol_in (input_bfd,
- (const PTR) (locsyms + r_symndx),
- (const PTR) locshndx,
- &s);
- rsec = (*gc_mark_hook) (sec, info, rel, NULL, &s);
+ rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]);
}
if (rsec && !rsec->gc_mark)
@@ -7880,11 +7732,16 @@ elf_gc_mark (info, sec, gc_mark_hook)
}
out2:
- if (!info->keep_memory)
+ if (elf_section_data (sec)->relocs != relstart)
free (relstart);
out1:
- if (freesyms)
- free (freesyms);
+ if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym)
+ {
+ if (! info->keep_memory)
+ free (isym);
+ else
+ symtab_hdr->contents = (unsigned char *) isym;
+ }
}
return ret;
@@ -7941,7 +7798,7 @@ elf_gc_sweep (info, gc_sweep_hook)
r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
- if (!info->keep_memory)
+ if (elf_section_data (o)->relocs != internal_relocs)
free (internal_relocs);
if (!r)
@@ -8439,7 +8296,6 @@ elf_reloc_symbol_deleted_p (offset, cook
for (; rcookie->rel < rcookie->relend; rcookie->rel++)
{
unsigned long r_symndx = ELF_R_SYM (rcookie->rel->r_info);
- Elf_Internal_Sym isym;
if (! rcookie->bad_symtab)
if (rcookie->rel->r_offset > offset)
@@ -8447,22 +8303,8 @@ elf_reloc_symbol_deleted_p (offset, cook
if (rcookie->rel->r_offset != offset)
continue;
- if (rcookie->locsyms && r_symndx < rcookie->locsymcount)
- {
- Elf_External_Sym *lsym;
- Elf_External_Sym_Shndx *lshndx;
-
- lsym = (Elf_External_Sym *) rcookie->locsyms + r_symndx;
- lshndx = (Elf_External_Sym_Shndx *) rcookie->locsym_shndx;
- if (lshndx != NULL)
- lshndx += r_symndx;
- elf_swap_symbol_in (rcookie->abfd, (const PTR) lsym,
- (const PTR) lshndx, &isym);
- }
-
if (r_symndx >= rcookie->locsymcount
- || (rcookie->locsyms
- && ELF_ST_BIND (isym.st_info) != STB_LOCAL))
+ || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{
struct elf_link_hash_entry *h;
@@ -8479,17 +8321,19 @@ elf_reloc_symbol_deleted_p (offset, cook
else
return false;
}
- else if (rcookie->locsyms)
+ else
{
/* It's not a relocation against a global symbol,
but it could be a relocation against a local
symbol for a discarded section. */
asection *isec;
+ Elf_Internal_Sym *isym;
/* Need to: get the symbol; get the section. */
- if (isym.st_shndx < SHN_LORESERVE || isym.st_shndx > SHN_HIRESERVE)
+ isym = &rcookie->locsyms[r_symndx];
+ if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
{
- isec = section_from_elf_index (rcookie->abfd, isym.st_shndx);
+ isec = section_from_elf_index (rcookie->abfd, isym->st_shndx);
if (isec != NULL && elf_discarded_section (isec))
return true;
}
@@ -8512,8 +8356,6 @@ elf_bfd_discard_info (output_bfd, info)
struct elf_reloc_cookie cookie;
asection *stab, *eh, *ehdr;
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
- Elf_External_Sym *freesyms;
struct elf_backend_data *bed;
bfd *abfd;
boolean ret = false;
@@ -8564,8 +8406,6 @@ elf_bfd_discard_info (output_bfd, info)
continue;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
-
cookie.abfd = abfd;
cookie.sym_hashes = elf_sym_hashes (abfd);
cookie.bad_symtab = elf_bad_symtab (abfd);
@@ -8581,48 +8421,20 @@ elf_bfd_discard_info (output_bfd, info)
cookie.extsymoff = symtab_hdr->sh_info;
}
- freesyms = NULL;
- if (symtab_hdr->contents)
- cookie.locsyms = (void *) symtab_hdr->contents;
- else if (cookie.locsymcount == 0)
- cookie.locsyms = NULL;
- else
+ cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (cookie.locsyms == NULL && cookie.locsymcount != 0)
{
- bfd_size_type amt = cookie.locsymcount * sizeof (Elf_External_Sym);
- cookie.locsyms = bfd_malloc (amt);
+ cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ cookie.locsymcount, 0,
+ NULL, NULL, NULL);
if (cookie.locsyms == NULL)
return false;
- freesyms = cookie.locsyms;
- if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (cookie.locsyms, amt, abfd) != amt)
- {
- error_ret_free_loc:
- free (cookie.locsyms);
- return false;
- }
- }
-
- cookie.locsym_shndx = NULL;
- if (shndx_hdr->sh_size != 0 && cookie.locsymcount != 0)
- {
- bfd_size_type amt;
- amt = cookie.locsymcount * sizeof (Elf_External_Sym_Shndx);
- cookie.locsym_shndx = bfd_malloc (amt);
- if (cookie.locsym_shndx == NULL)
- goto error_ret_free_loc;
- if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (cookie.locsym_shndx, amt, abfd) != amt)
- {
- free (cookie.locsym_shndx);
- goto error_ret_free_loc;
- }
}
if (stab)
{
cookie.rels = (NAME(_bfd_elf,link_read_relocs)
- (abfd, stab, (PTR) NULL,
- (Elf_Internal_Rela *) NULL,
+ (abfd, stab, (PTR) NULL, (Elf_Internal_Rela *) NULL,
info->keep_memory));
if (cookie.rels)
{
@@ -8634,7 +8446,7 @@ elf_bfd_discard_info (output_bfd, info)
elf_reloc_symbol_deleted_p,
&cookie))
ret = true;
- if (! info->keep_memory)
+ if (elf_section_data (stab)->relocs != cookie.rels)
free (cookie.rels);
}
}
@@ -8658,7 +8470,7 @@ elf_bfd_discard_info (output_bfd, info)
elf_reloc_symbol_deleted_p,
&cookie))
ret = true;
- if (! info->keep_memory)
+ if (cookie.rels && elf_section_data (eh)->relocs != cookie.rels)
free (cookie.rels);
}
@@ -8668,11 +8480,14 @@ elf_bfd_discard_info (output_bfd, info)
ret = true;
}
- if (cookie.locsym_shndx != NULL)
- free (cookie.locsym_shndx);
-
- if (freesyms != NULL)
- free (freesyms);
+ if (cookie.locsyms != NULL
+ && symtab_hdr->contents != (unsigned char *) cookie.locsyms)
+ {
+ if (! info->keep_memory)
+ free (cookie.locsyms);
+ else
+ symtab_hdr->contents = (unsigned char *) cookie.locsyms;
+ }
}
if (ehdr && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info, ehdr))
Index: bfd/elf-m10200.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10200.c,v
retrieving revision 1.16
diff -u -p -r1.16 elf-m10200.c
--- bfd/elf-m10200.c 6 Jun 2002 00:29:20 -0000 1.16
+++ bfd/elf-m10200.c 7 Jul 2002 06:59:01 -0000
@@ -30,7 +30,7 @@ static void mn10200_info_to_howto
static boolean mn10200_elf_relax_delete_bytes
PARAMS ((bfd *, asection *, bfd_vma, int));
static boolean mn10200_elf_symbol_address_p
- PARAMS ((bfd *, asection *, bfd_vma));
+ PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
static bfd_reloc_status_type mn10200_elf_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
@@ -508,15 +508,10 @@ mn10200_elf_relax_section (abfd, sec, li
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs;
- Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
- bfd_byte *free_contents = NULL;
- Elf32_External_Sym *extsyms = NULL;
- Elf32_External_Sym *free_extsyms = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
/* Assume nothing changes. */
*again = false;
@@ -536,7 +531,6 @@ mn10200_elf_relax_section (abfd, sec, li
sec->_cooked_size = sec->_raw_size;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf32_link_read_relocs
@@ -544,8 +538,6 @@ mn10200_elf_relax_section (abfd, sec, li
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
- if (! link_info->keep_memory)
- free_relocs = internal_relocs;
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
@@ -572,7 +564,6 @@ mn10200_elf_relax_section (abfd, sec, li
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
- free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@@ -580,68 +571,35 @@ mn10200_elf_relax_section (abfd, sec, li
}
}
- /* Read this BFD's symbols if we haven't done so already. */
- if (extsyms == NULL)
+ /* Read this BFD's local symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
- /* Get cached copy if it exists. */
- if (symtab_hdr->contents != NULL)
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
- else
- {
- /* Go get them off disk. */
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (extsyms == NULL)
- goto error_return;
- free_extsyms = extsyms;
- if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
- goto error_return;
- symtab_hdr->contents = (bfd_byte *) extsyms;
- }
-
- if (shndx_hdr->sh_size != 0)
- {
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
- goto error_return;
- shndx_hdr->contents = (bfd_byte *) shndx_buf;
- }
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
/* A local symbol. */
- Elf32_External_Sym *esym;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym isym;
+ Elf_Internal_Sym *isym;
asection *sym_sec;
- esym = extsyms + ELF32_R_SYM (irel->r_info);
- shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == SHN_UNDEF)
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
- else if (isym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
- else if (isym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
- sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
- symval = (isym.st_value
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
@@ -702,12 +660,8 @@ mn10200_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
if (code == 0xe0)
@@ -759,12 +713,8 @@ mn10200_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xea, contents + irel->r_offset - 1);
@@ -849,17 +799,14 @@ mn10200_elf_relax_section (abfd, sec, li
/* We also have to be sure there is no symbol/label
at the unconditional branch. */
- if (mn10200_elf_symbol_address_p (abfd, sec, irel->r_offset + 1))
+ if (mn10200_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset + 1))
continue;
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Reverse the condition of the first branch. */
switch (code)
@@ -977,12 +924,8 @@ mn10200_elf_relax_section (abfd, sec, li
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xf8 + (code & 0x03),
@@ -1020,12 +963,8 @@ mn10200_elf_relax_section (abfd, sec, li
case 0xc8:
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
if ((code & 0xfc) == 0x74)
code = 0xdc + (code & 0x03);
@@ -1107,12 +1046,8 @@ mn10200_elf_relax_section (abfd, sec, li
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xf7, contents + irel->r_offset - 2);
@@ -1170,12 +1105,8 @@ mn10200_elf_relax_section (abfd, sec, li
case 0xc4:
/* Note that we've changed the reldection contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
bfd_put_8 (abfd, 0xcc + (code & 0x03),
contents + irel->r_offset - 2);
@@ -1205,52 +1136,46 @@ mn10200_elf_relax_section (abfd, sec, li
}
}
- if (free_relocs != NULL)
- free (free_relocs);
-
- if (free_contents != NULL)
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
- free (free_contents);
+ free (isymbuf);
else
{
- /* Cache the section contents for elf_link_input_bfd. */
- elf_section_data (sec)->this_hdr.contents = contents;
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
- if (shndx_buf != NULL)
- {
- shndx_hdr->contents = NULL;
- free (shndx_buf);
- }
-
- if (free_extsyms != NULL)
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
+ free (contents);
+ else
{
- symtab_hdr->contents = NULL;
- free (free_extsyms);
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
}
}
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
return true;
error_return:
- if (free_relocs != NULL)
- free (free_relocs);
- if (free_contents != NULL)
- free (free_contents);
- if (shndx_buf != NULL)
- {
- shndx_hdr->contents = NULL;
- free (shndx_buf);
- }
- if (free_extsyms != NULL)
- {
- symtab_hdr->contents = NULL;
- free (free_extsyms);
- }
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
return false;
}
@@ -1265,22 +1190,17 @@ mn10200_elf_relax_delete_bytes (abfd, se
int count;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
- Elf32_External_Sym *extsyms;
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
-
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
contents = elf_section_data (sec)->this_hdr.contents;
@@ -1309,25 +1229,14 @@ mn10200_elf_relax_delete_bytes (abfd, se
}
/* Adjust the local symbols defined in this section. */
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
- esym = extsyms;
- esymend = esym + symtab_hdr->sh_info;
- for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
- Elf_External_Sym_Shndx dummy;
-
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == sec_shndx
- && isym.st_value > addr
- && isym.st_value < toaddr)
- {
- isym.st_value -= count;
- bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) &dummy);
- }
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
@@ -1354,37 +1263,27 @@ mn10200_elf_relax_delete_bytes (abfd, se
/* Return true if a symbol exists at the given address, else return
false. */
static boolean
-mn10200_elf_symbol_address_p (abfd, sec, addr)
+mn10200_elf_symbol_address_p (abfd, sec, isym, addr)
bfd *abfd;
asection *sec;
+ Elf_Internal_Sym *isym;
bfd_vma addr;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
unsigned int sec_shndx;
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
- /* Examine all the symbols. */
+ /* Examine all the local symbols. */
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
- esym = (Elf32_External_Sym *) symtab_hdr->contents;
- esymend = esym + symtab_hdr->sh_info;
- for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
-
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == sec_shndx
- && isym.st_value == addr)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value == addr)
return true;
}
@@ -1419,15 +1318,11 @@ mn10200_elf_get_relocated_section_conten
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
- Elf32_External_Sym *external_syms = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym *internal_syms = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@@ -1439,7 +1334,6 @@ mn10200_elf_get_relocated_section_conten
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
(size_t) input_section->_raw_size);
@@ -1447,48 +1341,27 @@ mn10200_elf_get_relocated_section_conten
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
{
- Elf_Internal_Sym *isymp;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
asection **secpp;
- Elf32_External_Sym *esym, *esymend;
bfd_size_type amt;
- if (symtab_hdr->contents != NULL)
- external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
- else if (symtab_hdr->sh_info != 0)
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (external_syms == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
- goto error_return;
- }
-
- if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
- goto error_return;
- }
-
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_Internal_Sym);
- internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
- if (internal_syms == NULL && amt != 0)
- goto error_return;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@@ -1496,59 +1369,48 @@ mn10200_elf_get_relocated_section_conten
if (sections == NULL && amt != 0)
goto error_return;
- for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
- esym = external_syms, esymend = esym + symtab_hdr->sh_info;
- esym < esymend;
- ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
- bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
- (const PTR) shndx, isymp);
-
- if (isymp->st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
- else if (isymp->st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
- else if (isymp->st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else
- isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! mn10200_elf_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
- internal_syms, sections))
+ isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
- if (internal_syms != NULL)
- free (internal_syms);
- if (shndx_buf != NULL)
- free (shndx_buf);
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
- if (internal_relocs != elf_section_data (input_section)->relocs)
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (elf_section_data (input_section)->relocs != internal_relocs)
free (internal_relocs);
}
return data;
error_return:
- if (internal_relocs != NULL
- && internal_relocs != elf_section_data (input_section)->relocs)
- free (internal_relocs);
- if (shndx_buf != NULL)
- free (shndx_buf);
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
- if (internal_syms != NULL)
- free (internal_syms);
if (sections != NULL)
free (sections);
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (internal_relocs != NULL
+ && elf_section_data (input_section)->relocs != internal_relocs)
+ free (internal_relocs);
return NULL;
}
Index: bfd/elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf-m10300.c
--- bfd/elf-m10300.c 1 Jul 2002 08:06:40 -0000 1.27
+++ bfd/elf-m10300.c 7 Jul 2002 06:59:04 -0000
@@ -127,7 +127,7 @@ static asection *mn10300_elf_gc_mark_hoo
static boolean mn10300_elf_relax_delete_bytes
PARAMS ((bfd *, asection *, bfd_vma, int));
static boolean mn10300_elf_symbol_address_p
- PARAMS ((bfd *, asection *, bfd_vma));
+PARAMS ((bfd *, asection *, Elf_Internal_Sym *, bfd_vma));
static boolean elf32_mn10300_finish_hash_table_entry
PARAMS ((struct bfd_hash_entry *, PTR));
static void compute_function_info
@@ -783,16 +783,12 @@ mn10300_elf_relax_section (abfd, sec, li
boolean *again;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
Elf_Internal_Rela *internal_relocs = NULL;
- Elf_Internal_Rela *free_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
bfd_byte *contents = NULL;
- bfd_byte *free_contents = NULL;
- Elf32_External_Sym *extsyms = NULL;
- Elf32_External_Sym *free_extsyms = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
struct elf32_mn10300_link_hash_table *hash_table;
+ asection *section = sec;
/* Assume nothing changes. */
*again = false;
@@ -810,42 +806,16 @@ mn10300_elf_relax_section (abfd, sec, li
input_bfd != NULL;
input_bfd = input_bfd->link_next)
{
- asection *section;
-
/* We're going to need all the symbols for each bfd. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
-
- /* Get cached copy if it exists. */
- if (symtab_hdr->contents != NULL)
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
- else
- {
- /* Go get them off disk. */
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (extsyms == NULL)
- goto error_return;
- free_extsyms = extsyms;
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) extsyms, amt, input_bfd) != amt)
- goto error_return;
- }
-
- if (shndx_hdr->sh_size != 0)
+ if (symtab_hdr->sh_info != 0)
{
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
goto error_return;
}
@@ -875,7 +845,6 @@ mn10300_elf_relax_section (abfd, sec, li
contents = (bfd_byte *) bfd_malloc (section->_raw_size);
if (contents == NULL)
goto error_return;
- free_contents = contents;
if (!bfd_get_section_contents (input_bfd, section,
contents, (file_ptr) 0,
@@ -883,10 +852,7 @@ mn10300_elf_relax_section (abfd, sec, li
goto error_return;
}
else
- {
- contents = NULL;
- free_contents = NULL;
- }
+ contents = NULL;
/* If there aren't any relocs, then there's nothing to do. */
if ((section->flags & SEC_RELOC) != 0
@@ -900,8 +866,6 @@ mn10300_elf_relax_section (abfd, sec, li
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
- if (! link_info->keep_memory)
- free_relocs = internal_relocs;
/* Now examine each relocation. */
irel = internal_relocs;
@@ -927,40 +891,31 @@ mn10300_elf_relax_section (abfd, sec, li
if (r_index < symtab_hdr->sh_info)
{
/* A local symbol. */
- Elf32_External_Sym *esym;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym isym;
+ Elf_Internal_Sym *isym;
struct elf_link_hash_table *elftab;
bfd_size_type amt;
- esym = extsyms + r_index;
- shndx = shndx_buf + (shndx_buf ? r_index : 0);
- bfd_elf32_swap_symbol_in (input_bfd,
- (const PTR) esym,
- (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == SHN_UNDEF)
+ isym = isymbuf + r_index;
+ if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
- else if (isym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
- else if (isym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
sym_sec
= bfd_section_from_elf_index (input_bfd,
- isym.st_shndx);
+ isym->st_shndx);
sym_name
= bfd_elf_string_from_elf_section (input_bfd,
(symtab_hdr
->sh_link),
- isym.st_name);
+ isym->st_name);
/* If it isn't a function, then we don't care
about it. */
- if (r_index < symtab_hdr->sh_info
- && ELF_ST_TYPE (isym.st_info) != STT_FUNC)
+ if (ELF_ST_TYPE (isym->st_info) != STT_FUNC)
continue;
/* Tack on an ID so we can uniquely identify this
@@ -995,8 +950,9 @@ mn10300_elf_relax_section (abfd, sec, li
if (code != 0xdd && code != 0xcd)
hash->flags |= MN10300_CONVERT_CALL_TO_CALLS;
- /* If this is a jump/call, then bump the direct_calls
- counter. Else force "call" to "calls" conversions. */
+ /* If this is a jump/call, then bump the
+ direct_calls counter. Else force "call" to
+ "calls" conversions. */
if (r_type == R_MN10300_PCREL32
|| r_type == R_MN10300_PCREL16)
hash->direct_calls++;
@@ -1010,46 +966,40 @@ mn10300_elf_relax_section (abfd, sec, li
(ie movm_args). */
if ((section->flags & SEC_CODE) != 0)
{
-
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
- int idx;
+ Elf_Internal_Sym *isym, *isymend;
unsigned int sec_shndx;
+ struct elf_link_hash_entry **hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
sec_shndx = _bfd_elf_section_from_bfd_section (input_bfd,
section);
/* Look at each function defined in this section and
update info for that function. */
- for (esym = extsyms, esymend = esym + symtab_hdr->sh_info,
- shndx = shndx_buf;
- esym < esymend;
- esym++, shndx = (shndx ? shndx + 1 : NULL))
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
-
- bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
- (const PTR) shndx, &isym);
- if (isym.st_shndx == sec_shndx
- && ELF_ST_TYPE (isym.st_info) == STT_FUNC)
+ if (isym->st_shndx == sec_shndx
+ && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
{
struct elf_link_hash_table *elftab;
bfd_size_type amt;
- if (isym.st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
- else if (isym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
- else if (isym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
sym_sec
= bfd_section_from_elf_index (input_bfd,
- isym.st_shndx);
+ isym->st_shndx);
sym_name = (bfd_elf_string_from_elf_section
(input_bfd, symtab_hdr->sh_link,
- isym.st_name));
+ isym->st_name));
/* Tack on an ID so we can uniquely identify this
local symbol in the global hash table. */
@@ -1068,23 +1018,21 @@ mn10300_elf_relax_section (abfd, sec, li
true, true, false));
free (new_name);
compute_function_info (input_bfd, hash,
- isym.st_value, contents);
+ isym->st_value, contents);
}
}
- esym = extsyms + symtab_hdr->sh_info;
- esymend = extsyms + (symtab_hdr->sh_size
- / sizeof (Elf32_External_Sym));
- for (idx = 0; esym < esymend; esym++, idx++)
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ - symtab_hdr->sh_info);
+ hashes = elf_sym_hashes (abfd);
+ end_hashes = hashes + symcount;
+ for (; hashes < end_hashes; hashes++)
{
- Elf_Internal_Sym isym;
-
- hash = (struct elf32_mn10300_link_hash_entry *)
- elf_sym_hashes (input_bfd)[idx];
+ hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
if ((hash->root.root.type == bfd_link_hash_defined
|| hash->root.root.type == bfd_link_hash_defweak)
&& hash->root.root.u.def.section == section
- && ELF_ST_TYPE (isym.st_info) == STT_FUNC)
+ && ELF_ST_TYPE (isym->st_info) == STT_FUNC)
compute_function_info (input_bfd, hash,
(hash)->root.root.u.def.value,
contents);
@@ -1092,44 +1040,39 @@ mn10300_elf_relax_section (abfd, sec, li
}
/* Cache or free any memory we allocated for the relocs. */
- if (free_relocs != NULL)
- {
- free (free_relocs);
- free_relocs = NULL;
- }
+ if (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
/* Cache or free any memory we allocated for the contents. */
- if (free_contents != NULL)
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
- free (free_contents);
+ free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
elf_section_data (section)->this_hdr.contents = contents;
}
- free_contents = NULL;
}
- }
-
- if (shndx_buf != NULL)
- {
- free (shndx_buf);
- shndx_buf = NULL;
+ contents = NULL;
}
/* Cache or free any memory we allocated for the symbols. */
- if (free_extsyms != NULL)
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
- free (free_extsyms);
+ free (isymbuf);
else
{
/* Cache the symbols for elf_link_input_bfd. */
- symtab_hdr->contents = (unsigned char *) extsyms;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
}
- free_extsyms = NULL;
}
+ isymbuf = NULL;
}
/* Now iterate on each symbol in the hash table and perform
@@ -1152,45 +1095,17 @@ mn10300_elf_relax_section (abfd, sec, li
input_bfd != NULL;
input_bfd = input_bfd->link_next)
{
- asection *section;
-
/* We're going to need all the local symbols for each bfd. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
-
- /* Get cached copy if it exists. */
- if (symtab_hdr->contents != NULL)
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
- else
- {
- /* Go get them off disk. */
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (extsyms == NULL)
- goto error_return;
- free_extsyms = extsyms;
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) extsyms, amt, input_bfd) != amt)
- goto error_return;
- symtab_hdr->contents = (bfd_byte *) extsyms;
- }
-
- if (shndx_hdr->sh_size != 0)
+ if (symtab_hdr->sh_info != 0)
{
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
goto error_return;
- shndx_hdr->contents = (bfd_byte *) shndx_buf;
}
/* Walk over each section in this bfd. */
@@ -1199,9 +1114,10 @@ mn10300_elf_relax_section (abfd, sec, li
section = section->next)
{
unsigned int sec_shndx;
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
- unsigned int idx;
+ Elf_Internal_Sym *isym, *isymend;
+ struct elf_link_hash_entry **hashes;
+ struct elf_link_hash_entry **end_hashes;
+ unsigned int symcount;
/* Skip non-code sections and empty sections. */
if ((section->flags & SEC_CODE) == 0 || section->_raw_size == 0)
@@ -1216,8 +1132,6 @@ mn10300_elf_relax_section (abfd, sec, li
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
- if (! link_info->keep_memory)
- free_relocs = internal_relocs;
}
/* Get cached copy of section contents if it exists. */
@@ -1229,7 +1143,6 @@ mn10300_elf_relax_section (abfd, sec, li
contents = (bfd_byte *) bfd_malloc (section->_raw_size);
if (contents == NULL)
goto error_return;
- free_contents = contents;
if (!bfd_get_section_contents (input_bfd, section,
contents, (file_ptr) 0,
@@ -1242,12 +1155,9 @@ mn10300_elf_relax_section (abfd, sec, li
/* Now look for any function in this section which needs
insns deleted from its prologue. */
- for (esym = extsyms, esymend = esym + symtab_hdr->sh_info,
- shndx = shndx_buf;
- esym < esymend;
- esym++, shndx = (shndx ? shndx + 1 : NULL))
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
struct elf32_mn10300_link_hash_entry *sym_hash;
asection *sym_sec = NULL;
const char *sym_name;
@@ -1255,26 +1165,23 @@ mn10300_elf_relax_section (abfd, sec, li
struct elf_link_hash_table *elftab;
bfd_size_type amt;
- bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
- (const PTR) shndx, &isym);
-
- if (isym.st_shndx != sec_shndx)
+ if (isym->st_shndx != sec_shndx)
continue;
- if (isym.st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
- else if (isym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
- else if (isym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
sym_sec
- = bfd_section_from_elf_index (input_bfd, isym.st_shndx);
+ = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
sym_name
= bfd_elf_string_from_elf_section (input_bfd,
symtab_hdr->sh_link,
- isym.st_name);
+ isym->st_name);
/* Tack on an ID so we can uniquely identify this
local symbol in the global hash table. */
@@ -1301,12 +1208,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed things. */
elf_section_data (section)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (section)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Count how many bytes we're going to delete. */
if (sym_hash->movm_args)
@@ -1325,7 +1228,7 @@ mn10300_elf_relax_section (abfd, sec, li
/* Actually delete the bytes. */
if (!mn10300_elf_relax_delete_bytes (input_bfd,
section,
- isym.st_value,
+ isym->st_value,
bytes))
goto error_return;
@@ -1337,15 +1240,15 @@ mn10300_elf_relax_section (abfd, sec, li
/* Look for any global functions in this section which
need insns deleted from their prologues. */
- for (idx = 0;
- idx < (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
+ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
- symtab_hdr->sh_info);
- idx++)
+ hashes = elf_sym_hashes (abfd);
+ end_hashes = hashes + symcount;
+ for (; hashes < end_hashes; hashes++)
{
struct elf32_mn10300_link_hash_entry *sym_hash;
- sym_hash = (struct elf32_mn10300_link_hash_entry *)
- (elf_sym_hashes (input_bfd)[idx]);
+ sym_hash = (struct elf32_mn10300_link_hash_entry *) *hashes;
if ((sym_hash->root.root.type == bfd_link_hash_defined
|| sym_hash->root.root.type == bfd_link_hash_defweak)
&& sym_hash->root.root.u.def.section == section
@@ -1357,12 +1260,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed things. */
elf_section_data (section)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (section)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Count how many bytes we're going to delete. */
if (sym_hash->movm_args)
@@ -1393,53 +1292,48 @@ mn10300_elf_relax_section (abfd, sec, li
}
/* Cache or free any memory we allocated for the relocs. */
- if (free_relocs != NULL)
- {
- free (free_relocs);
- free_relocs = NULL;
- }
+ if (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
+ internal_relocs = NULL;
/* Cache or free any memory we allocated for the contents. */
- if (free_contents != NULL)
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
- free (free_contents);
+ free (contents);
else
{
/* Cache the section contents for elf_link_input_bfd. */
elf_section_data (section)->this_hdr.contents = contents;
}
- free_contents = NULL;
}
- }
-
- if (shndx_buf != NULL)
- {
- shndx_hdr->contents = NULL;
- free (shndx_buf);
- shndx_buf = NULL;
+ contents = NULL;
}
/* Cache or free any memory we allocated for the symbols. */
- if (free_extsyms != NULL)
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
+ free (isymbuf);
+ else
{
- symtab_hdr->contents = NULL;
- free (free_extsyms);
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
}
- free_extsyms = NULL;
}
+ isymbuf = NULL;
}
}
/* (Re)initialize for the basic instruction shortening/relaxing pass. */
contents = NULL;
- extsyms = NULL;
internal_relocs = NULL;
- free_relocs = NULL;
- free_contents = NULL;
- free_extsyms = NULL;
+ isymbuf = NULL;
+ /* For error_return. */
+ section = sec;
/* We don't have to do anything for a relocateable link, if
this section does not have relocs, or if this is not a
@@ -1456,7 +1350,6 @@ mn10300_elf_relax_section (abfd, sec, li
sec->_cooked_size = sec->_raw_size;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
/* Get a copy of the native relocations. */
internal_relocs = (_bfd_elf32_link_read_relocs
@@ -1464,8 +1357,6 @@ mn10300_elf_relax_section (abfd, sec, li
link_info->keep_memory));
if (internal_relocs == NULL)
goto error_return;
- if (! link_info->keep_memory)
- free_relocs = internal_relocs;
/* Walk through them looking for relaxing opportunities. */
irelend = internal_relocs + sec->reloc_count;
@@ -1493,7 +1384,6 @@ mn10300_elf_relax_section (abfd, sec, li
contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
if (contents == NULL)
goto error_return;
- free_contents = contents;
if (! bfd_get_section_contents (abfd, sec, contents,
(file_ptr) 0, sec->_raw_size))
@@ -1501,76 +1391,43 @@ mn10300_elf_relax_section (abfd, sec, li
}
}
- /* Read this BFD's symbols if we haven't done so already. */
- if (extsyms == NULL)
+ /* Read this BFD's symbols if we haven't done so already. */
+ if (isymbuf == NULL && symtab_hdr->sh_info != 0)
{
- /* Get cached copy if it exists. */
- if (symtab_hdr->contents != NULL)
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
- else
- {
- /* Go get them off disk. */
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (extsyms == NULL)
- goto error_return;
- free_extsyms = extsyms;
- if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
- goto error_return;
- symtab_hdr->contents = (bfd_byte *) extsyms;
- }
-
- if (shndx_hdr->sh_size != 0)
- {
- bfd_size_type amt;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
- goto error_return;
- shndx_hdr->contents = (bfd_byte *) shndx_buf;
- }
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
}
/* Get the value of the symbol referred to by the reloc. */
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
- Elf32_External_Sym *esym;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym isym;
+ Elf_Internal_Sym *isym;
asection *sym_sec = NULL;
const char *sym_name;
char *new_name;
/* A local symbol. */
- esym = extsyms + ELF32_R_SYM (irel->r_info);
- shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym,
- (const PTR) shndx, &isym);
-
- if (isym.st_shndx == SHN_UNDEF)
+ isym = isymbuf + ELF32_R_SYM (irel->r_info);
+ if (isym->st_shndx == SHN_UNDEF)
sym_sec = bfd_und_section_ptr;
- else if (isym.st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
sym_sec = bfd_abs_section_ptr;
- else if (isym.st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
sym_sec = bfd_com_section_ptr;
else
- sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- symval = (isym.st_value
+ symval = (isym->st_value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
sym_name = bfd_elf_string_from_elf_section (abfd,
symtab_hdr->sh_link,
- isym.st_name);
+ isym->st_name);
/* Tack on an ID so we can uniquely identify this
local symbol in the global hash table. */
@@ -1638,12 +1495,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfc, contents + irel->r_offset - 1);
@@ -1702,12 +1555,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
if (code == 0xdc)
@@ -1753,12 +1602,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 1);
@@ -1815,12 +1660,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xca, contents + irel->r_offset - 1);
@@ -1904,17 +1745,14 @@ mn10300_elf_relax_section (abfd, sec, li
/* We also have to be sure there is no symbol/label
at the unconditional branch. */
- if (mn10300_elf_symbol_address_p (abfd, sec, irel->r_offset + 1))
+ if (mn10300_elf_symbol_address_p (abfd, sec, isymbuf,
+ irel->r_offset + 1))
continue;
/* Note that we've changed the relocs, section contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Reverse the condition of the first branch. */
switch (code)
@@ -2022,12 +1860,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfb, contents + irel->r_offset - 3);
@@ -2097,12 +1931,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents,
etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfd, contents + irel->r_offset - 3);
@@ -2180,12 +2010,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
@@ -2217,12 +2043,8 @@ mn10300_elf_relax_section (abfd, sec, li
case 0x83:
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
if ((code & 0xf3) == 0x81)
code = 0x01 + (code & 0x0c);
@@ -2271,12 +2093,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
@@ -2323,12 +2141,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
if ((code & 0xfc) == 0xcc)
code = 0x2c + (code & 0x03);
@@ -2404,12 +2218,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
@@ -2435,12 +2245,8 @@ mn10300_elf_relax_section (abfd, sec, li
/* Note that we've changed the relocation contents, etc. */
elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- free_extsyms = NULL;
+ symtab_hdr->contents = (unsigned char *) isymbuf;
/* Fix the opcode. */
bfd_put_8 (abfd, 0xfa, contents + irel->r_offset - 2);
@@ -2464,52 +2270,46 @@ mn10300_elf_relax_section (abfd, sec, li
}
}
- if (free_relocs != NULL)
- free (free_relocs);
-
- if (free_contents != NULL)
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
{
if (! link_info->keep_memory)
- free (free_contents);
+ free (isymbuf);
else
{
- /* Cache the section contents for elf_link_input_bfd. */
- elf_section_data (sec)->this_hdr.contents = contents;
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) isymbuf;
}
}
- if (shndx_buf != NULL)
- {
- shndx_hdr->contents = NULL;
- free (shndx_buf);
- }
-
- if (free_extsyms != NULL)
+ if (contents != NULL
+ && elf_section_data (sec)->this_hdr.contents != contents)
{
if (! link_info->keep_memory)
+ free (contents);
+ else
{
- symtab_hdr->contents = NULL;
- free (free_extsyms);
+ /* Cache the section contents for elf_link_input_bfd. */
+ elf_section_data (sec)->this_hdr.contents = contents;
}
}
+ if (internal_relocs != NULL
+ && elf_section_data (sec)->relocs != internal_relocs)
+ free (internal_relocs);
+
return true;
error_return:
- if (free_relocs != NULL)
- free (free_relocs);
- if (free_contents != NULL)
- free (free_contents);
- if (shndx_buf != NULL)
- {
- shndx_hdr->contents = NULL;
- free (shndx_buf);
- }
- if (free_extsyms != NULL)
- {
- symtab_hdr->contents = NULL;
- free (free_extsyms);
- }
+ if (isymbuf != NULL
+ && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
+ if (contents != NULL
+ && elf_section_data (section)->this_hdr.contents != contents)
+ free (contents);
+ if (internal_relocs != NULL
+ && elf_section_data (section)->relocs != internal_relocs)
+ free (internal_relocs);
return false;
}
@@ -2624,22 +2424,16 @@ mn10300_elf_relax_delete_bytes (abfd, se
int count;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
- Elf32_External_Sym *extsyms;
unsigned int sec_shndx;
bfd_byte *contents;
Elf_Internal_Rela *irel, *irelend;
Elf_Internal_Rela *irelalign;
bfd_vma toaddr;
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isym, *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
-
sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
contents = elf_section_data (sec)->this_hdr.contents;
@@ -2668,25 +2462,14 @@ mn10300_elf_relax_delete_bytes (abfd, se
}
/* Adjust the local symbols defined in this section. */
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
- esym = extsyms;
- esymend = esym + symtab_hdr->sh_info;
- for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ isym = (Elf_Internal_Sym *) symtab_hdr->contents;
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
- Elf_External_Sym_Shndx dummy;
-
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == sec_shndx
- && isym.st_value > addr
- && isym.st_value < toaddr)
- {
- isym.st_value -= count;
- bfd_elf32_swap_symbol_out (abfd, &isym, (PTR) esym, (PTR) &dummy);
- }
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value > addr
+ && isym->st_value < toaddr)
+ isym->st_value -= count;
}
/* Now adjust the global symbols defined in this section. */
@@ -2713,16 +2496,15 @@ mn10300_elf_relax_delete_bytes (abfd, se
/* Return true if a symbol exists at the given address, else return
false. */
static boolean
-mn10300_elf_symbol_address_p (abfd, sec, addr)
+mn10300_elf_symbol_address_p (abfd, sec, isym, addr)
bfd *abfd;
asection *sec;
+ Elf_Internal_Sym *isym;
bfd_vma addr;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
unsigned int sec_shndx;
- Elf32_External_Sym *esym, *esymend;
- Elf_External_Sym_Shndx *shndx;
+ Elf_Internal_Sym *isymend;
struct elf_link_hash_entry **sym_hashes;
struct elf_link_hash_entry **end_hashes;
unsigned int symcount;
@@ -2731,19 +2513,10 @@ mn10300_elf_symbol_address_p (abfd, sec,
/* Examine all the symbols. */
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
- esym = (Elf32_External_Sym *) symtab_hdr->contents;
- esymend = esym + symtab_hdr->sh_info;
- for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
+ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
{
- Elf_Internal_Sym isym;
-
- bfd_elf32_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- &isym);
-
- if (isym.st_shndx == sec_shndx
- && isym.st_value == addr)
+ if (isym->st_shndx == sec_shndx
+ && isym->st_value == addr)
return true;
}
@@ -2778,15 +2551,11 @@ mn10300_elf_get_relocated_section_conten
asymbol **symbols;
{
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
asection *input_section = link_order->u.indirect.section;
bfd *input_bfd = input_section->owner;
asection **sections = NULL;
Elf_Internal_Rela *internal_relocs = NULL;
- Elf32_External_Sym *external_syms = NULL;
- Elf_External_Sym_Shndx *shndx_buf = NULL;
- Elf_External_Sym_Shndx *shndx;
- Elf_Internal_Sym *internal_syms = NULL;
+ Elf_Internal_Sym *isymbuf = NULL;
/* We only need to handle the case of relaxing, or of having a
particular set of section contents, specially. */
@@ -2798,7 +2567,6 @@ mn10300_elf_get_relocated_section_conten
symbols);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
memcpy (data, elf_section_data (input_section)->this_hdr.contents,
(size_t) input_section->_raw_size);
@@ -2806,48 +2574,26 @@ mn10300_elf_get_relocated_section_conten
if ((input_section->flags & SEC_RELOC) != 0
&& input_section->reloc_count > 0)
{
- Elf_Internal_Sym *isymp;
asection **secpp;
- Elf32_External_Sym *esym, *esymend;
+ Elf_Internal_Sym *isym, *isymend;
bfd_size_type amt;
- if (symtab_hdr->contents != NULL)
- external_syms = (Elf32_External_Sym *) symtab_hdr->contents;
- else if (symtab_hdr->sh_info != 0)
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf32_External_Sym);
- external_syms = (Elf32_External_Sym *) bfd_malloc (amt);
- if (external_syms == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) external_syms, amt, input_bfd) != amt)
- goto error_return;
- }
-
- if (symtab_hdr->sh_info != 0 && shndx_hdr->sh_size != 0)
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- goto error_return;
- if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
- goto error_return;
- }
-
internal_relocs = (_bfd_elf32_link_read_relocs
(input_bfd, input_section, (PTR) NULL,
(Elf_Internal_Rela *) NULL, false));
if (internal_relocs == NULL)
goto error_return;
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_Internal_Sym);
- internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
- if (internal_syms == NULL && amt != 0)
- goto error_return;
+ if (symtab_hdr->sh_info != 0)
+ {
+ isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (isymbuf == NULL)
+ isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+ }
amt = symtab_hdr->sh_info;
amt *= sizeof (asection *);
@@ -2855,41 +2601,32 @@ mn10300_elf_get_relocated_section_conten
if (sections == NULL && amt != 0)
goto error_return;
- for (isymp = internal_syms, secpp = sections, shndx = shndx_buf,
- esym = external_syms, esymend = esym + symtab_hdr->sh_info;
- esym < esymend;
- ++esym, ++isymp, ++secpp, shndx = (shndx ? shndx + 1 : NULL))
+ isymend = isymbuf + symtab_hdr->sh_info;
+ for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
{
asection *isec;
- bfd_elf32_swap_symbol_in (input_bfd, (const PTR) esym,
- (const PTR) shndx, isymp);
-
- if (isymp->st_shndx == SHN_UNDEF)
+ if (isym->st_shndx == SHN_UNDEF)
isec = bfd_und_section_ptr;
- else if (isymp->st_shndx == SHN_ABS)
+ else if (isym->st_shndx == SHN_ABS)
isec = bfd_abs_section_ptr;
- else if (isymp->st_shndx == SHN_COMMON)
+ else if (isym->st_shndx == SHN_COMMON)
isec = bfd_com_section_ptr;
else
- isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx);
+ isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
*secpp = isec;
}
if (! mn10300_elf_relocate_section (output_bfd, link_info, input_bfd,
input_section, data, internal_relocs,
- internal_syms, sections))
+ isymbuf, sections))
goto error_return;
if (sections != NULL)
free (sections);
- if (internal_syms != NULL)
- free (internal_syms);
- if (shndx_buf != NULL)
- free (shndx_buf);
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
if (internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
}
@@ -2897,17 +2634,13 @@ mn10300_elf_get_relocated_section_conten
return data;
error_return:
+ if (sections != NULL)
+ free (sections);
+ if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
+ free (isymbuf);
if (internal_relocs != NULL
&& internal_relocs != elf_section_data (input_section)->relocs)
free (internal_relocs);
- if (shndx_buf != NULL)
- free (shndx_buf);
- if (external_syms != NULL && symtab_hdr->contents == NULL)
- free (external_syms);
- if (internal_syms != NULL)
- free (internal_syms);
- if (sections != NULL)
- free (sections);
return NULL;
}
Index: bfd/elf32-h8300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-h8300.c,v
retrieving revision 1.13
dif