aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog55
-rw-r--r--bfd/elfcode.h597
-rw-r--r--bfd/libelf.h16
3 files changed, 237 insertions, 431 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0b818d9..605141a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,8 +1,63 @@
Fri Aug 20 15:16:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+ * elfcode.h (elf_build_phdrs): Unused function deleted.
+ (bfd_shdr_from_section): Ditto.
+ (write_relocs): Don't change section contents for addend.
+ (elf_locate_sh): Return type is now always elf_internal_shdr,
+ since the other types were really aliases for this type anyways.
+ Don't compile this function, since it is static and doesn't appear
+ to be used in this file.
+ (sym_is_global): Return non-zero for weak symbols. Abort if
+ section pointer is null.
+ (swap_out_syms): Reorder tests so function symbols can be weak.
+ (elf_slurp_symbol_table): Don't use BSF_EXPORT.
+ (elf_slurp_reloca_table): Make RELOC_PROCESSING section smaller by
+ extracting out some common code. Abort if BFD section symbol has
+ null name.
+ (elf_slurp_reloc_table): Translate ELF section symbols into BFD
+ section symbols. Don't read section contents to fill in addend
+ field.
+
* elf32-i386.c (elf_howto_table): All partial_inplace fields
should be "true".
+ * Merged from OSF:
+
+ Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org)
+
+ * libelf.h (struct Elf_Sym_Extra): New structure to contain ELF
+ specific information for a symbol. Put in elf_sym_num, which
+ gives the external symbol number in the elf object file, since
+ local symbols must come before global symbols.
+ (elf_sym_extra): New macro.
+ (elf_symtab_map): Delete, in favor of using Elf_Sym_Extra.
+ * elfcode.h (elf_map_symbols): Use Elf_Sym_Extra to map internal
+ symbol number to external number. Store the address of the
+ Elf_Sym_Extra field for the symbol in the udata field.
+ (elf_write_object_contents): Use Elf_Sym_Extra to map out symbols.
+
+ Sun Jun 20 16:30:11 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_obj_tdata): Add field to count the size of the
+ array of pointers to section symbols.
+ (elf_map_symbols): Bump the max index of the section symbols so
+ that we don't overwrite memory. Store the max index into the
+ elf_obj_tdata field.
+
+ Sat Jun 19 10:12:27 1993 Michael Meissner (meissner@osf.org)
+
+ * elfcode.h (elf_obj_tdata): Add pointer to an array of pointers
+ to the section symbols we created. Remove unused field
+ internal_syms.
+ (elf_map_symbols): Fill in array of pointers to section symbols.
+ Only create section symbols for sections that have SEC_ALLOC set,
+ and have non-zero size.
+ (elf_symbol_from_bfd_symbol): If udata is NULL, and this is a
+ section symbol, look up the section in the list of section
+ symbols, and set the udata pointer appropriately. Otherwise, if
+ udata is still NULL, fail an assertion, and use 0, instead of
+ dropping core.
+
Fri Aug 20 12:18:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* config.bfd (mips-*-elfl*, mips-*-elf*): New targets, using
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index fb00ae0..ee5c454 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -54,7 +54,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
once in 64-bit mode. More of it should be made size-independent
and moved into elf.c.
-*/
+ (3) ELF section symbols are handled rather sloppily now. This should
+ be cleaned up, and ELF section symbols reconciled with BFD section
+ symbols.
+ */
#include <assert.h>
#include <string.h> /* For strrchr and friends */
@@ -776,6 +779,20 @@ DEFUN (elf_file_p, (x_ehdrp), Elf_External_Ehdr * x_ehdrp)
&& (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
}
+/* Check to see if the file associated with ABFD matches the target vector
+ that ABFD points to.
+
+ Note that we may be called several times with the same ABFD, but different
+ target vectors, most of which will not match. We have to avoid leaving
+ any side effects in ABFD, or any data it points to (like tdata), if the
+ file does not match the target vector.
+
+ FIXME: There is memory leak if we are called more than once with the same
+ ABFD, and that bfd already has tdata allocated, since we allocate more tdata
+ and the old tdata is orphaned. Since it's in the bfd obstack, there isn't
+ much we can do about this except possibly rewrite the code. There are
+ also other bfd_allocs that may be the source of memory leaks as well. */
+
bfd_target *
DEFUN (elf_object_p, (abfd), bfd * abfd)
{
@@ -786,14 +803,12 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
int shindex;
char *shstrtab; /* Internal copy of section header stringtab */
struct elf_backend_data *ebd; /* Use to get ELF_ARCH stored in xvec */
+ struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
/* Read in the ELF header in external format. */
if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
- {
- bfd_error = system_call_error;
- return NULL;
- }
+ goto got_system_call_error;
/* Now check to see if we have a valid ELF file, and one that BFD can
make use of. The magic number must match, the address size ('class')
@@ -801,46 +816,34 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
section header table (FIXME: See comments re sections at top of this
file). */
- if (elf_file_p (&x_ehdr) == false)
- {
- wrong:
- bfd_error = wrong_format;
- return NULL;
- }
-
- if (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT)
- goto wrong;
+ if ((elf_file_p (&x_ehdr) == false) ||
+ (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) ||
+ (x_ehdr.e_ident[EI_CLASS] != ELFCLASS))
+ goto got_wrong_format_error;
- if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
- goto wrong;
-
- /* Switch xvec to match the specified byte order. */
+ /* Check that file's byte order matches xvec's */
switch (x_ehdr.e_ident[EI_DATA])
{
case ELFDATA2MSB: /* Big-endian */
if (!abfd->xvec->header_byteorder_big_p)
- goto wrong;
+ goto got_wrong_format_error;
break;
case ELFDATA2LSB: /* Little-endian */
if (abfd->xvec->header_byteorder_big_p)
- goto wrong;
+ goto got_wrong_format_error;
break;
case ELFDATANONE: /* No data encoding specified */
default: /* Unknown data encoding specified */
- goto wrong;
+ goto got_wrong_format_error;
}
/* Allocate an instance of the elf_obj_tdata structure and hook it up to
- the tdata pointer in the bfd. */
-
- if (NULL == (elf_tdata (abfd) = (struct elf_obj_tdata *)
- bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))))
- {
- bfd_error = no_memory;
- return NULL;
- }
+ the tdata pointer in the bfd. FIXME: memory leak, see above. */
- /* FIXME: Any `wrong' exits below here will leak memory (tdata). */
+ elf_tdata (abfd) =
+ (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+ if (elf_tdata (abfd) == NULL)
+ goto got_no_memory_error;
/* Now that we know the byte order, swap in the rest of the header */
i_ehdrp = elf_elfheader (abfd);
@@ -851,7 +854,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
/* If there is no section header table, we're hosed. */
if (i_ehdrp->e_shoff == 0)
- goto wrong;
+ goto got_wrong_format_error;
if (i_ehdrp->e_type == ET_EXEC || i_ehdrp->e_type == ET_DYN)
abfd->flags |= EXEC_P;
@@ -884,7 +887,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
arch = bfd_arch_sparc;
/* end-sanitize-v9 */
if (ebd->arch != arch)
- goto wrong;
+ goto got_wrong_format_error;
bfd_default_set_arch_mach (abfd, arch, 0);
}
@@ -895,29 +898,19 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
header table entry actually matches the size recorded in the file. */
if (i_ehdrp->e_shentsize != sizeof (x_shdr))
- goto wrong;
+ goto got_wrong_format_error;
i_shdrp = (Elf_Internal_Shdr *)
bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum);
elf_elfsections (abfd) =
(Elf_Internal_Shdr **) bfd_alloc (abfd, sizeof (i_shdrp) * i_ehdrp->e_shnum);
if (!i_shdrp || !elf_elfsections(abfd))
- {
- bfd_error = no_memory;
- return NULL;
- }
+ goto got_no_memory_error;
if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) == -1)
- {
- bfd_error = system_call_error;
- return NULL;
- }
+ goto got_system_call_error;
for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)
{
- if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd)
- != sizeof (x_shdr))
- {
- bfd_error = system_call_error;
- return NULL;
- }
+ if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr))
+ goto got_system_call_error;
elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
elf_elfsections(abfd)[shindex] = i_shdrp + shindex;
}
@@ -955,7 +948,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
if (!shstrtab)
- return NULL;
+ goto got_wrong_format_error;
/* Once all of the section headers have been read and converted, we
can start processing them. Note that the first section header is
@@ -974,75 +967,30 @@ DEFUN (elf_object_p, (abfd), bfd * abfd)
bfd_get_start_address (abfd) = i_ehdrp->e_entry;
- return abfd->xvec;
+ return (abfd->xvec);
+
+ /* If we are going to use goto's to avoid duplicating error setting
+ and return(NULL) code, then this at least makes it more maintainable. */
+
+ got_system_call_error:
+ bfd_error = system_call_error;
+ goto got_no_match;
+ got_wrong_format_error:
+ bfd_error = wrong_format;
+ goto got_no_match;
+ got_no_memory_error:
+ bfd_error = no_memory;
+ goto got_no_match;
+ got_no_match:
+ elf_tdata (abfd) = preserved_tdata;
+ return (NULL);
}
/* ELF .o/exec file writing */
-/* Create a new ELF section from a bfd section. */
-
-#if 0 /* not used */
-static boolean
-DEFUN (bfd_shdr_from_section, (abfd, hdr, shstrtab, indx),
- bfd * abfd AND
- Elf_Internal_Shdr * hdr AND
- struct strtab *shstrtab AND
- int indx)
-{
- asection *sect;
- int ndx;
-
- sect = abfd->sections;
- for (ndx = indx; --ndx;)
- {
- sect = sect->next;
- }
- hdr[indx].sh_name = bfd_add_to_strtab (abfd, shstrtab,
- bfd_section_name (abfd, sect));
- hdr[indx].sh_addr = sect->vma;
- hdr[indx].sh_size = sect->_raw_size;
- hdr[indx].sh_addralign = 1 << sect->alignment_power;
- hdr[indx].sh_flags = 0;
- /* these need to be preserved on */
- hdr[indx].sh_link = 0;
- hdr[indx].sh_info = 0;
- hdr[indx].sh_entsize = 0;
-
- hdr[indx].sh_type = 0;
- if (sect->flags & SEC_RELOC)
- {
- int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
- hdr[indx].sh_type = use_rela_p ? SHT_RELA : SHT_REL;
- }
-
- if (sect->flags & SEC_HAS_CONTENTS)
- {
- hdr[indx].sh_offset = sect->filepos;
- hdr[indx].sh_size = sect->_raw_size;
- }
- if (sect->flags & SEC_ALLOC)
- {
- hdr[indx].sh_flags |= SHF_ALLOC;
- if (sect->flags & SEC_LOAD)
- {
- /* do something with sh_type ? */
- }
- }
- if (!(sect->flags & SEC_READONLY))
- hdr[indx].sh_flags |= SHF_WRITE;
-
- if (sect->flags & SEC_CODE)
- hdr[indx].sh_flags |= SHF_EXECINSTR;
-
- return true;
-}
-#endif
-
-/*
- Takes a bfd and a symbol, returns a pointer to the elf specific area
- of the symbol if there is one.
- */
+/* Takes a bfd and a symbol, returns a pointer to the elf specific area
+ of the symbol if there is one. */
static INLINE elf_symbol_type *
DEFUN (elf_symbol_from, (ignore_abfd, symbol),
bfd * ignore_abfd AND
@@ -1057,13 +1005,10 @@ DEFUN (elf_symbol_from, (ignore_abfd, symbol),
return (elf_symbol_type *) symbol;
}
-/*
- Create ELF output from BFD sections.
-
- Essentially, just create the section header and forget about the program
- header for now.
+/* Create ELF output from BFD sections.
-*/
+ Essentially, just create the section header and forget about the program
+ header for now. */
static void
DEFUN (elf_make_sections, (abfd, asect, obj),
@@ -1215,11 +1160,6 @@ write_relocs (abfd, sec, xxx)
dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type);
elf_swap_reloc_out (abfd, &dst_rel, src_rel);
-
- /* Update the addend -- FIXME add 64 bit support. */
- bfd_put_32 (abfd, ptr->addend,
- (unsigned char *) (elf_section_data (sec)->this_hdr.contents)
- + dst_rel.r_offset);
}
}
}
@@ -1331,6 +1271,7 @@ DEFUN (elf_fake_sections, (abfd, asect, obj),
}
+#if 0
/*
xxxINTERNAL_FUNCTION
bfd_elf_locate_sh
@@ -1346,11 +1287,11 @@ xxxDESCRIPTION
name of a BFD section.
*/
-static struct elfNAME (internal_shdr) *
+static struct elf_internal_shdr *
DEFUN (elf_locate_sh, (abfd, strtab, shdrp, name),
bfd * abfd AND
struct strtab *strtab AND
- struct elfNAME (internal_shdr) *shdrp AND
+ struct elf_internal_shdr *shdrp AND
CONST char *name)
{
Elf_Internal_Shdr *gotit = NULL;
@@ -1369,6 +1310,7 @@ DEFUN (elf_locate_sh, (abfd, strtab, shdrp, name),
}
return gotit;
}
+#endif
/* Map symbol from it's internal number to the external number, moving
all local symbols to be at the head of the list. */
@@ -1377,12 +1319,19 @@ static INLINE int
sym_is_global (sym)
asymbol *sym;
{
- if (sym->flags & BSF_GLOBAL)
+ if (sym->flags & (BSF_GLOBAL | BSF_WEAK))
{
if (sym->flags & BSF_LOCAL)
abort ();
return 1;
}
+ if (sym->section == 0)
+ {
+ /* Is this valid? */
+ abort ();
+
+ return 1;
+ }
if (sym->section == &bfd_und_section)
return 1;
if (bfd_is_com_section (sym->section))
@@ -1397,12 +1346,14 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
{
int symcount = bfd_get_symcount (abfd);
asymbol **syms = bfd_get_outsymbols (abfd);
+ asymbol **sect_syms;
int num_locals = 0;
int num_globals = 0;
int num_locals2 = 0;
int num_globals2 = 0;
+ int max_index = 0;
int num_sections = 0;
- int *symtab_map;
+ Elf_Sym_Extra *sym_extra;
int idx;
asection *asect;
@@ -1411,15 +1362,40 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
fflush (stderr);
#endif
- /* Add local symbols for each allocated section
+ /* Add local symbols for each allocated section.
FIXME -- we should only put out symbols for sections that
are actually relocated against. */
for (asect = abfd->sections; asect; asect = asect->next)
{
- if (/*asect->flags & (SEC_LOAD | SEC_DATA | SEC_CODE)*/1)
- num_sections++;
+ if (max_index < asect->index)
+ max_index = asect->index;
}
+ max_index++;
+ elf_num_section_syms (abfd) = max_index;
+ sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *));
+ elf_section_syms (abfd) = sect_syms;
+
+ BFD_ASSERT (sect_syms != 0);
+
+ for (asect = abfd->sections; asect; asect = asect->next)
+ if ((asect->flags & SEC_ALLOC) && asect->_raw_size > 0)
+ {
+ asymbol *sym = bfd_make_empty_symbol (abfd);
+ sym->the_bfd = abfd;
+ sym->name = asect->name;
+ sym->value = asect->vma;
+ sym->flags = BSF_SECTION_SYM;
+ sym->section = asect;
+ sect_syms[asect->index] = sym;
+ num_sections++;
+#ifdef DEBUG
+ fprintf (stderr,
+ "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n",
+ asect->name, (long) asect->vma, asect->index, (long) asect);
+#endif
+ }
+
if (num_sections)
{
if (syms)
@@ -1432,23 +1408,16 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
for (asect = abfd->sections; asect; asect = asect->next)
{
- if (/* asect->flags & (SEC_LOAD | SEC_DATA | SEC_CODE) */ 1)
- {
- asymbol *sym = syms[symcount++] = bfd_make_empty_symbol (abfd);
- sym->the_bfd = abfd;
- sym->name = asect->name;
- sym->value = asect->vma;
- sym->flags = BSF_SECTION_SYM;
- sym->section = asect;
- }
+ if (sect_syms[asect->index])
+ syms[symcount++] = sect_syms[asect->index];
}
syms[symcount] = (asymbol *) 0;
bfd_set_symtab (abfd, syms, symcount);
}
- elf_symtab_map (abfd) = symtab_map
- = (int *) bfd_alloc (abfd, symcount * sizeof (int *));
+ elf_sym_extra (abfd) = sym_extra
+ = (Elf_Sym_Extra *) bfd_alloc (abfd, symcount * sizeof (Elf_Sym_Extra));
/* Identify and classify all of the symbols. */
for (idx = 0; idx < symcount; idx++)
@@ -1463,10 +1432,11 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd)
dummy symbol. */
for (idx = 0; idx < symcount; idx++)
{
+ syms[idx]->udata = (PTR) &sym_extra[idx];
if (!sym_is_global (syms[idx]))
- symtab_map[idx] = 1 + num_locals2++;
+ sym_extra[idx].elf_sym_num = 1 + num_locals2++;
else
- symtab_map[idx] = 1 + num_locals + num_globals2++;
+ sym_extra[idx].elf_sym_num = 1 + num_locals + num_globals2++;
}
elf_num_locals (abfd) = num_locals;
@@ -1522,183 +1492,6 @@ DEFUN (elf_write_phdrs, (abfd, i_ehdrp, i_phdrp, phdr_cnt),
return true;
}
-#if 0
-static Elf_Internal_Phdr *
-DEFUN (elf_build_phdrs, (abfd, i_ehdrp, i_shdrp, phdr_cnt),
- bfd * abfd AND
- Elf_Internal_Ehdr * i_ehdrp AND
- Elf_Internal_Shdr * i_shdrp AND
- Elf32_Half * phdr_cnt)
-{
- Elf_Internal_Phdr *phdr_buf;
- int idx;
- /* NOTES:
- 1. The program header table is *not* loaded as part
- of the memory image of the program. If this
- changes later, the PT_PHDR entry must come first.
- 2. there is currently no support for program header
- entries of type PT_PHDR, PT_DYNAMIC, PT_INTERP,
- or PT_SHLIB. */
-
- /* A. Figure out how many program header table entries are needed
- 1. PT_LOAD for the text segment
- 2. PT_LOAD for the data segment
- Then, reserve space for one more pointer. This will be NULL
- to indicate the end of the program header table. */
-
-#ifdef PHDRS_INCLUDED
- *phdr_cnt = 4;
-#else
- /* XXX right now, execve() expects exactly 3 PT entries on HPPA-OSF. */
- *phdr_cnt = 3;
-#endif
-
- phdr_buf = (Elf_Internal_Phdr *) bfd_xmalloc (((*phdr_cnt) + 1)
- *
- sizeof (Elf_Internal_Phdr));
-
- idx = 0;
-#ifdef PHDRS_INCLUDED
- /* B. Fill in the PT_PHDR entry. */
-
- idx++;
-#endif
-
- /* C. Fill in the PT_LOAD entry for the text segment. */
-
- phdr_buf[idx].p_type = PT_LOAD;
-
- /* get virtual/physical address from .text section */
- phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".text")->vma;
- phdr_buf[idx].p_paddr = 0; /* XXX */
-
- /* Ultimately, we would like the size of the .text load
- segment to be the sum of the following sections:
- the program header table itself
- .interp
- .hash
- .dynsym
- .dynstr
- .rela.bss
- .rela.plt
- .init
- .text
- .fini
- .rodata
- But, right now, it will be the sum of the following sections:
- .text
- .rodata */
-
- {
- static char *CONST ld_sect_names[] =
- {".text", ".rodata", NULL};
- int i;
- int ld_size = 0;
-
- for (i = 0; ld_sect_names[i]; i++)
- {
- asection *asect = bfd_get_section_by_name (abfd,
- ld_sect_names[i]);
-
- if (asect)
- ld_size += bfd_section_size (abfd, asect);
- }
- phdr_buf[idx].p_filesz = ld_size;
- /* XXX: need to fix this */
- phdr_buf[idx].p_memsz = ld_size;
- }
- phdr_buf[idx].p_flags = PF_R + PF_X;
- phdr_buf[idx].p_align =
- bfd_get_section_by_name (abfd, ".text")->alignment_power;
-
- idx++;
-
- /* D. Fill in the PT_LOAD entry for the data segment. */
-
- phdr_buf[idx].p_type = PT_LOAD;
-
- /* get virtual/physical address from .data section */
- phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".data")->vma;
- phdr_buf[idx].p_paddr = 0; /* XXX */
-
- /* Ultimately, we would like the size of the data load segment
- to be the sum of the following sections:
- the PT_DYNAMIC program header table entry
- .plt
- .data
- .data1
- .got
- .dynamic
- But, right now, it will be the sum of the following sections:
- .data */
-
- {
- static char *CONST ld_sect_names[] =
- {".data", NULL};
- int i;
- int ld_size = 0;
-
- for (i = 0; ld_sect_names[i]; i++)
- {
- asection *asect = bfd_get_section_by_name (abfd,
- ld_sect_names[i]);
-
- if (asect)
- ld_size += bfd_section_size (abfd, asect);
- }
- phdr_buf[idx].p_filesz = ld_size;
- /* XXX: need to fix this */
- phdr_buf[idx].p_memsz = ld_size;
- }
- phdr_buf[idx].p_flags = PF_R + PF_W + PF_X;
- phdr_buf[idx].p_align
- = bfd_get_section_by_name (abfd, ".data")->alignment_power;
-
- idx++;
-
- /* E. Fill in the PT_LOAD entry for the bss segment. */
-
- phdr_buf[idx].p_type = PT_LOAD;
-
- /* get virtual/physical address from .data section */
- phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".bss")->vma;
- phdr_buf[idx].p_paddr = 0; /* XXX */
-
- {
- static char *CONST ld_sect_names[] =
- {".bss", NULL};
- int i;
- int ld_size = 0;
-
- for (i = 0; ld_sect_names[i]; i++)
- {
- asection *asect = bfd_get_section_by_name (abfd,
- ld_sect_names[i]);
-
- if (asect)
- ld_size += bfd_section_size (abfd, asect);
- }
- phdr_buf[idx].p_filesz = 0;
- /* XXX: need to fix this */
- phdr_buf[idx].p_memsz = ld_size;
- }
- phdr_buf[idx].p_flags = PF_R + PF_W + PF_X;
- phdr_buf[idx].p_align
- = bfd_get_section_by_name (abfd, ".bss")->alignment_power;
-
- idx++;
-
- /* F. Set up the "end of program header table" sentinel. */
-
- memset ((char *) (phdr_buf + idx), 0, sizeof (Elf_Internal_Phdr));
- idx++;
-
- BFD_ASSERT (idx - 1 == *phdr_cnt);
-
- return phdr_buf;
-}
-#endif
-
static const Elf_Internal_Shdr null_shdr;
/* Assign all ELF section numbers. The dummy first section is handled here
@@ -2287,33 +2080,33 @@ swap_out_syms (abfd)
sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE);
else if (syms[idx]->section == &bfd_und_section)
sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE);
- else if (syms[idx]->flags & BSF_WEAK)
- sym.st_info = ELF_ST_INFO (STB_WEAK, STT_OBJECT);
else if (syms[idx]->flags & BSF_SECTION_SYM)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
else if (syms[idx]->flags & BSF_FILE)
sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
- else if (syms[idx]->flags & (BSF_GLOBAL | BSF_EXPORT))
- {
- if (syms[idx]->flags & BSF_FUNCTION)
- sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_FUNC);
- else
- sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT);
- }
- else if (syms[idx]->flags & BSF_LOCAL)
+ else
{
- if (syms[idx]->flags & BSF_FUNCTION)
- sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC);
- else
- sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT);
+ int bind = STB_LOCAL;
+ int type = STT_OBJECT;
+ unsigned int flags = syms[idx]->flags;
+
+ if (flags & BSF_LOCAL)
+ bind = STB_LOCAL;
+ else if (flags & BSF_WEAK)
+ bind = STB_WEAK;
+ else if (flags & BSF_GLOBAL)
+ bind = STB_GLOBAL;
+
+ if (flags & BSF_FUNCTION)
+ type = STT_FUNC;
+
+ sym.st_info = ELF_ST_INFO (bind, type);
}
- else
- /* Default to local if flag isn't set at all. */
- sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT);
sym.st_other = 0;
elf_swap_symbol_out (abfd, &sym,
- outbound_syms + elf_symtab_map (abfd)[idx]);
+ (outbound_syms
+ + elf_sym_extra (abfd)[idx].elf_sym_num));
}
symtab_hdr->contents = (PTR) outbound_syms;
@@ -2537,85 +2330,31 @@ DEFUN (elf_symbol_from_bfd_symbol, (abfd, asym_ptr_ptr),
CONST char *name = asym_ptr->name;
int idx;
int symcount = bfd_get_symcount (abfd);
+ flagword flags = asym_ptr->flags;
asymbol **syms = bfd_get_outsymbols (abfd);
- /* FIXME -- there has to be a better way than linear search. */
- for (idx = 0; idx < symcount; idx++)
- {
- if (syms[idx] == asym_ptr
- || (name == syms[idx]->name && name)
- || ((asym_ptr->flags & BSF_SECTION_SYM)
- && (syms[idx]->flags & BSF_SECTION_SYM)
- && asym_ptr->section == syms[idx]->section))
- break;
- }
-
- if (idx >= symcount)
+ /* When gas creates relocations against local labels, it creates its
+ own symbol for the section, but does put the symbol into the
+ symbol chain, so udata is 0. */
+ if (asym_ptr->udata == (PTR) 0
+ && (flags & BSF_SECTION_SYM)
+ && asym_ptr->section
+ && elf_section_syms (abfd)[asym_ptr->section->index])
+ asym_ptr->udata = elf_section_syms (abfd)[asym_ptr->section->index]->udata;
+
+ if (asym_ptr->udata)
+ idx = ((Elf_Sym_Extra *)asym_ptr->udata)->elf_sym_num;
+ else
{
- /* badness... */
- fprintf (stderr, "bfd app err: can't find sym `%s' in symtab\n",
- name);
abort ();
}
- idx = elf_symtab_map (abfd)[idx];
#if DEBUG & 4
{
- flagword flags = asym_ptr->flags;
fprintf (stderr,
- "elfsym<-bfdsym %.8lx `%s' sec=%s symnum=%d {",
- (long) asym_ptr, asym_ptr->name, asym_ptr->section->name, idx);
-
- if (flags == BSF_NO_FLAGS)
- fprintf (stderr, " none");
-
- if (flags & BSF_LOCAL)
- fprintf (stderr, " local");
-
- if (flags & BSF_GLOBAL)
- fprintf (stderr, " global");
-
- if (flags & BSF_EXPORT)
- fprintf (stderr, " export");
-
- if (flags & BSF_DEBUGGING)
- fprintf (stderr, " debugging");
-
- if (flags & BSF_KEEP)
- fprintf (stderr, " keep");
-
- if (flags & BSF_KEEP_G)
- fprintf (stderr, " keep_g");
-
- if (flags & BSF_WEAK)
- fprintf (stderr, " weak");
-
- if (flags & BSF_SECTION_SYM)
- fprintf (stderr, " section_sym");
-
- if (flags & BSF_OLD_COMMON)
- fprintf (stderr, " old_common");
-
- if (flags & BSF_NOT_AT_END)
- fprintf (stderr, " not_at_end");
-
- if (flags & BSF_CONSTRUCTOR)
- fprintf (stderr, " constructor");
-
- if (flags & BSF_WARNING)
- fprintf (stderr, " warning");
-
- if (flags & BSF_INDIRECT)
- fprintf (stderr, " indirect");
-
- if (flags & BSF_FILE)
- fprintf (stderr, " file");
-
- if (flags & BSF_FUNCTION)
- fprintf (stderr, " function");
-
- fputs (" }\n", stderr);
+ "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx %s\n",
+ (long) asym_ptr, asym_ptr->name, idx, flags, elf_symbol_flags (flags));
fflush (stderr);
}
#endif
@@ -2722,7 +2461,7 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs),
sym->symbol.flags |= BSF_LOCAL;
break;
case STB_GLOBAL:
- sym->symbol.flags |= (BSF_GLOBAL | BSF_EXPORT);
+ sym->symbol.flags |= BSF_GLOBAL;
break;
case STB_WEAK:
sym->symbol.flags |= BSF_WEAK;
@@ -2743,7 +2482,7 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs),
}
/* Is this a definition of $global$? If so, keep it because it will be
- needd if any relocations are performed. */
+ needed if any relocations are performed. */
if (!strcmp (sym->symbol.name, "$global$")
&& sym->symbol.section != &bfd_und_section)
{
@@ -2853,7 +2592,6 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols),
for (idx = 0; idx < asect->reloc_count; idx++)
{
-#ifdef RELOC_PROCESSING
Elf_Internal_Rela dst;
Elf_External_Rela *src;
@@ -2861,16 +2599,9 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols),
src = native_relocs + idx;
elf_swap_reloca_in (abfd, src, &dst);
+#ifdef RELOC_PROCESSING
RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect);
#else
- Elf_Internal_Rela dst;
- Elf_External_Rela *src;
-
- cache_ptr = reloc_cache + idx;
- src = native_relocs + idx;
-
- elf_swap_reloca_in (abfd, src, &dst);
-
if (asect->flags & SEC_RELOC)
{
/* relocatable, so the offset is off of the section */
@@ -2889,7 +2620,12 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols),
BFD section symbol. */
asymbol *s = *(cache_ptr->sym_ptr_ptr);
if (s->flags & BSF_SECTION_SYM)
- cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr;
+ {
+ cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr;
+ s = *cache_ptr->sym_ptr_ptr;
+ if (s->name == 0 || s->name[0] == 0)
+ abort ();
+ }
}
cache_ptr->addend = dst.r_addend;
@@ -3029,17 +2765,22 @@ DEFUN (elf_slurp_reloc_table, (abfd, asect, symbols),
cache_ptr->address = dst.r_offset;
}
/* ELF_R_SYM(dst.r_info) is the symbol table offset...
- -1 is to skip the dummy symbol table entry */
+ -1 is to skip the dummy symbol table entry */
cache_ptr->sym_ptr_ptr = symbols + ELF_R_SYM (dst.r_info) - 1;
+ {
+ /* Is it an ELF section symbol? If so, translate it into a
+ BFD section symbol. */
+ asymbol *s = *(cache_ptr->sym_ptr_ptr);
+ if (s->flags & BSF_SECTION_SYM)
+ {
+ cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr;
+ s = *cache_ptr->sym_ptr_ptr;
+ if (s->name == 0 || s->name[0] == 0)
+ abort ();
+ }
+ }
BFD_ASSERT (dst.r_offset <= data_max);
- if (bfd_seek (abfd, data_off + dst.r_offset, SEEK_SET) != 0
- || bfd_read ((PTR) buf, sizeof (buf), 1, abfd) != sizeof (buf))
- {
- bfd_error = system_call_error;
- return false;
- }
-
- cache_ptr->addend = (*abfd->xvec->bfd_getx_signed_32) ((bfd_byte *) buf);
+ cache_ptr->addend = 0;
/* Fill in the cache_ptr->howto field from dst.r_type */
{
diff --git a/bfd/libelf.h b/bfd/libelf.h
index 1f0f1a5..f5bc2c8 100644
--- a/bfd/libelf.h
+++ b/bfd/libelf.h
@@ -98,6 +98,13 @@ struct elf_backend_data
PTR global_sym;
};
+struct elf_sym_extra
+{
+ int elf_sym_num; /* sym# after locals/globals are reordered */
+};
+
+typedef struct elf_sym_extra Elf_Sym_Extra;
+
struct bfd_elf_arch_map {
enum bfd_architecture bfd_arch;
int elf_arch;
@@ -139,11 +146,12 @@ struct elf_obj_tdata
struct strtab *strtab_ptr;
int num_locals;
int num_globals;
- int *symtab_map;
PTR raw_syms; /* Elf_External_Sym* */
Elf_Internal_Sym *internal_syms;
PTR symbols; /* elf_symbol_type */
-/* struct strtab *shstrtab;*/
+ Elf_Sym_Extra *sym_extra;
+ asymbol **section_syms; /* STT_SECTION symbols for each section */
+ int num_section_syms; /* number of section_syms allocated */
Elf_Internal_Shdr symtab_hdr;
Elf_Internal_Shdr shstrtab_hdr;
Elf_Internal_Shdr strtab_hdr;
@@ -160,7 +168,9 @@ struct elf_obj_tdata
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
#define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals)
#define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals)
-#define elf_symtab_map(bfd) (elf_tdata(bfd) -> symtab_map)
+#define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra)
+#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms)
+#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
#define obj_symbols(bfd) ((elf_symbol_type*)(elf_tdata(bfd) -> symbols))