code repeated three times in bfd_section_from_shdr in elfcode.h.
* libelf.h (_bfd_elf_make_section_from_shdr): Declare.
* elfcode.h (bfd_section_from_shdr): Use new function
_bfd_elf_make_section_from_shdr to create BFD sections. If a
reloc section does not use the main symbol table, or it is part of
the process image, treat it as a normal section, not relocs.
* elf32-mips.c (mips_elf_section_from_shdr): Use new function
_bfd_elf_make_section_from_shdr.
+Fri May 20 11:57:05 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
+
+ * elf.c (_bfd_elf_make_section_from_shdr): New function, based on
+ code repeated three times in bfd_section_from_shdr in elfcode.h.
+ * libelf.h (_bfd_elf_make_section_from_shdr): Declare.
+ * elfcode.h (bfd_section_from_shdr): Use new function
+ _bfd_elf_make_section_from_shdr to create BFD sections. If a
+ reloc section does not use the main symbol table, or it is part of
+ the process image, treat it as a normal section, not relocs.
+ * elf32-mips.c (mips_elf_section_from_shdr): Use new function
+ _bfd_elf_make_section_from_shdr.
+
Thu May 19 11:37:11 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* elf32-target.h, elf64-target.h: Change ar_max_namelen value from
return ((char *) hdr->rawdata) + strindex;
}
+/* Make a BFD section from an ELF section. We store a pointer to the
+ BFD section in the rawdata field of the header. */
+
+boolean
+_bfd_elf_make_section_from_shdr (abfd, hdr, name)
+ bfd *abfd;
+ Elf_Internal_Shdr *hdr;
+ const char *name;
+{
+ asection *newsect;
+ flagword flags;
+
+ if (hdr->rawdata != NULL)
+ {
+ BFD_ASSERT (strcmp (name, ((asection *) hdr->rawdata)->name) == 0);
+ return true;
+ }
+
+ newsect = bfd_make_section_anyway (abfd, name);
+ if (newsect == NULL)
+ return false;
+
+ newsect->filepos = hdr->sh_offset;
+
+ if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
+ || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
+ || ! bfd_set_section_alignment (abfd, newsect,
+ bfd_log2 (hdr->sh_addralign)))
+ return false;
+
+ flags = SEC_NO_FLAGS;
+ if (hdr->sh_type != SHT_NOBITS)
+ flags |= SEC_HAS_CONTENTS;
+ if ((hdr->sh_flags & SHF_ALLOC) != 0)
+ {
+ flags |= SEC_ALLOC;
+ if (hdr->sh_type != SHT_NOBITS)
+ flags |= SEC_LOAD;
+ }
+ if ((hdr->sh_flags & SHF_WRITE) == 0)
+ flags |= SEC_READONLY;
+ if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
+ flags |= SEC_CODE;
+ else if ((flags & SEC_ALLOC) != 0)
+ flags |= SEC_DATA;
+
+ /* The debugging sections appear to be recognized only by name, not
+ any sort of flag. */
+ if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
+ || strncmp (name, ".line", sizeof ".line" - 1) == 0
+ || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
+ flags |= SEC_DEBUGGING;
+
+ if (! bfd_set_section_flags (abfd, newsect, flags))
+ return false;
+
+ hdr->rawdata = (PTR) newsect;
+ elf_section_data (newsect)->this_hdr = *hdr;
+
+ return true;
+}
+
/*
INTERNAL_FUNCTION
bfd_elf_find_section
Elf32_Internal_Shdr *hdr;
char *name;
{
+ asection *newsect;
+
/* There ought to be a place to keep ELF backend specific flags, but
at the moment there isn't one. We just keep track of the
sections by their name, instead. Fortunately, the ABI gives
return false;
}
- if (hdr->rawdata == NULL)
- {
- asection *newsect;
-
- newsect = bfd_make_section (abfd, name);
- if (newsect != NULL)
- {
- newsect->filepos = hdr->sh_offset;
- newsect->flags |= SEC_HAS_CONTENTS;
- newsect->vma = hdr->sh_addr;
- newsect->_raw_size = hdr->sh_size;
- newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-
- if (hdr->sh_flags & SHF_ALLOC)
- {
- newsect->flags |= SEC_ALLOC;
- newsect->flags |= SEC_LOAD;
- }
-
- if (!(hdr->sh_flags & SHF_WRITE))
- newsect->flags |= SEC_READONLY;
-
- if (hdr->sh_flags & SHF_EXECINSTR)
- newsect->flags |= SEC_CODE;
- else if (newsect->flags & SEC_ALLOC)
- newsect->flags |= SEC_DATA;
-
- if (hdr->sh_type == SHT_MIPS_DEBUG)
- newsect->flags |= SEC_DEBUGGING;
+ if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
+ return false;
+ newsect = (asection *) hdr->rawdata;
- hdr->rawdata = (void *) newsect;
+ if (hdr->sh_type == SHT_MIPS_DEBUG)
+ {
+ if (! bfd_set_section_flags (abfd, newsect,
+ (bfd_get_section_flags (abfd, newsect)
+ | SEC_DEBUGGING)))
+ return false;
+ }
- /* FIXME: We should record the sh_info field for a .gptab
- section. */
+ /* FIXME: We should record sh_info for a .gptab section. */
- /* For a .reginfo section, set the gp value in the tdata
- information from the contents of this section. We need
- the gp value while processing relocs, so we just get it
- now. */
- if (hdr->sh_type == SHT_MIPS_REGINFO)
- {
- Elf32_External_RegInfo ext;
- Elf32_RegInfo s;
+ /* For a .reginfo section, set the gp value in the tdata information
+ from the contents of this section. We need the gp value while
+ processing relocs, so we just get it now. */
+ if (hdr->sh_type == SHT_MIPS_REGINFO)
+ {
+ Elf32_External_RegInfo ext;
+ Elf32_RegInfo s;
- if (bfd_get_section_contents (abfd, newsect, (PTR) &ext,
- (file_ptr) 0,
- sizeof ext) == false)
- return false;
- bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
- elf_gp (abfd) = s.ri_gp_value;
- }
- }
- else
- hdr->rawdata = (void *) bfd_get_section_by_name (abfd, name);
+ if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,
+ (file_ptr) 0, sizeof ext))
+ return false;
+ bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
+ elf_gp (abfd) = s.ri_gp_value;
}
return true;
_bfd_generic_link_write_global_symbol,
(PTR) &wginfo);
- /* Remove empty sections. Also drop the .options section, since it
- has special semantics which I haven't bothered to figure out.
- Also drop the .gptab sections, which also require special
- handling which is not currently done. Removing the .gptab
- sections is required for Irix 5 compatibility; I don't know about
- the other sections. */
+ /* Drop the .options section, since it has special semantics which I
+ haven't bothered to figure out. Also drop the .gptab sections,
+ which also require special handling which is not currently done.
+ Removing the .gptab sections is required for Irix 5
+ compatibility; I don't know about .options. */
secpp = &abfd->sections;
while (*secpp != NULL)
{
- if (((*secpp)->_raw_size == 0
- && strcmp ((*secpp)->name, ".data") != 0
- && strcmp ((*secpp)->name, ".text") != 0
- && strcmp ((*secpp)->name, ".bss") != 0)
- || strcmp ((*secpp)->name, ".options") == 0
+ if (strcmp ((*secpp)->name, ".options") == 0
|| strncmp ((*secpp)->name, ".gptab", 6) == 0)
{
*secpp = (*secpp)->next;
#define ELF_ARCH bfd_arch_mips
#define ELF_MACHINE_CODE EM_MIPS
#define ELF_MAXPAGESIZE 0x10000
+#define elf_backend_collect true
#define elf_info_to_howto 0
#define elf_info_to_howto_rel mips_info_to_howto_rel
#define elf_backend_sym_is_global mips_elf_sym_is_global
return ss->length - ln;
}
\f
-
/* ELF .o/exec file reading */
/* Create a new bfd section from an ELF section header. */
{
Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
- asection *newsect;
char *name;
name = elf_string_from_elf_strtab (abfd, hdr->sh_name);
switch (hdr->sh_type)
{
-
case SHT_NULL:
- /* inactive section. Throw it away. */
+ /* Inactive section. Throw it away. */
return true;
- case SHT_PROGBITS:
- case SHT_DYNAMIC:
- /* Bits that get saved. This one is real. */
- if (hdr->rawdata == NULL)
- {
- newsect = bfd_make_section_anyway (abfd, name);
- if (newsect == NULL)
- return false;
-
- newsect->filepos = hdr->sh_offset;
- newsect->flags |= SEC_HAS_CONTENTS;
- newsect->vma = hdr->sh_addr;
- newsect->_raw_size = hdr->sh_size;
- newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
-
- if (hdr->sh_flags & SHF_ALLOC)
- {
- newsect->flags |= SEC_ALLOC;
- newsect->flags |= SEC_LOAD;
- }
-
- if (!(hdr->sh_flags & SHF_WRITE))
- newsect->flags |= SEC_READONLY;
-
- if (hdr->sh_flags & SHF_EXECINSTR)
- newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
- else if (newsect->flags & SEC_ALLOC)
- newsect->flags |= SEC_DATA;
-
- /* The debugging sections appear to recognized only by name,
- not any sort of flag. */
- if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
- || strncmp (name, ".line", sizeof ".line" - 1) == 0
- || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
- newsect->flags |= SEC_DEBUGGING;
-
- hdr->rawdata = (PTR) newsect;
- }
- return true;
-
- case SHT_NOBITS:
- /* Bits that get saved. This one is real. */
- if (hdr->rawdata == NULL)
- {
- newsect = bfd_make_section_anyway (abfd, name);
- if (newsect == NULL)
- return false;
-
- newsect->vma = hdr->sh_addr;
- newsect->_raw_size = hdr->sh_size;
- newsect->filepos = hdr->sh_offset; /* fake */
- newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
- if (hdr->sh_flags & SHF_ALLOC)
- newsect->flags |= SEC_ALLOC;
-
- if (!(hdr->sh_flags & SHF_WRITE))
- newsect->flags |= SEC_READONLY;
-
- /* FIXME: This section is empty. Does it really make sense
- to set SEC_CODE for it? */
- if (hdr->sh_flags & SHF_EXECINSTR)
- newsect->flags |= SEC_CODE; /* FIXME: may only contain SOME code */
-
- hdr->rawdata = (PTR) newsect;
- }
- return true;
+ case SHT_PROGBITS: /* Normal section with contents. */
+ case SHT_DYNAMIC: /* Dynamic linking information. */
+ case SHT_NOBITS: /* .bss section. */
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
case SHT_SYMTAB: /* A symbol table */
if (elf_onesymtab (abfd) == shindex)
return true;
case SHT_STRTAB: /* A string table */
- if (hdr->rawdata)
+ if (hdr->rawdata != NULL)
return true;
if (ehdr->e_shstrndx == shindex)
{
}
}
- newsect = bfd_make_section_anyway (abfd, name);
- if (newsect == NULL)
- return false;
-
- newsect->flags = SEC_HAS_CONTENTS;
- hdr->rawdata = (PTR) newsect;
- newsect->_raw_size = hdr->sh_size;
- newsect->alignment_power = bfd_log2 (hdr->sh_addralign);
- newsect->vma = hdr->sh_addr;
- newsect->filepos = hdr->sh_offset;
-
- if (hdr->sh_flags & SHF_ALLOC)
- newsect->flags |= SEC_ALLOC | SEC_LOAD;
- if (!(hdr->sh_flags & SHF_WRITE))
- newsect->flags |= SEC_READONLY;
- if (hdr->sh_flags & SHF_EXECINSTR)
- newsect->flags |= SEC_CODE;
- else if (newsect->flags & SEC_ALLOC)
- newsect->flags |= SEC_DATA;
-
- /* Check for debugging string tables. */
- if (strncmp (name, ".debug", sizeof ".debug" - 1) == 0
- || strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
- newsect->flags |= SEC_DEBUGGING;
-
- return true;
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
case SHT_REL:
case SHT_RELA:
- /* *These* do a lot of work -- but build no sections!
- The spec says there can be multiple strtabs, but only one symtab,
- but there can be lots of REL* sections. */
- /* FIXME: The above statement is wrong! There are typically at least
- two symbol tables in a dynamically linked executable, ".dynsym"
- which is the dynamic linkage symbol table and ".symtab", which is
- the "traditional" symbol table. -fnf */
-
+ /* *These* do a lot of work -- but build no sections! */
{
asection *target_sect;
Elf_Internal_Shdr *hdr2;
int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
+ /* Get the symbol table. */
+ if (! bfd_section_from_shdr (abfd, hdr->sh_link))
+ return false;
+
+ /* If this reloc section does not use the main symbol table,
+ or if it is in the process image, we don't treat it as a
+ reloc section. BFD can't adequately represent such a
+ section, so at least for now, we don't try. We just
+ present it as a normal section. */
+ if ((hdr->sh_flags & SHF_ALLOC) != 0
+ || hdr->sh_link != elf_onesymtab (abfd))
+ return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
+
/* Don't allow REL relocations on a machine that uses RELA and
vice versa. */
/* @@ Actually, the generic ABI does suggest that both might be
each of those architectures. It's conceivable that, e.g., a
bunch of absolute 32-bit relocs might be more compact in REL
form even on a RELA machine... */
- BFD_ASSERT (!(use_rela_p && (hdr->sh_type == SHT_REL)));
- BFD_ASSERT (!(!use_rela_p && (hdr->sh_type == SHT_RELA)));
- BFD_ASSERT (hdr->sh_entsize ==
- (use_rela_p
- ? sizeof (Elf_External_Rela)
- : sizeof (Elf_External_Rel)));
-
- if (! bfd_section_from_shdr (abfd, hdr->sh_info) /* target */
- || ! bfd_section_from_shdr (abfd, hdr->sh_link)) /* symbol table */
+ BFD_ASSERT (use_rela_p
+ ? (hdr->sh_type == SHT_RELA
+ && hdr->sh_entsize == sizeof (Elf_External_Rela))
+ : (hdr->sh_type == SHT_REL
+ && hdr->sh_entsize == sizeof (Elf_External_Rel)));
+
+ if (! bfd_section_from_shdr (abfd, hdr->sh_info))
return false;
target_sect = section_from_elf_index (abfd, hdr->sh_info);
if (target_sect == NULL
elf_elfsections (abfd)[shindex] = hdr2;
target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize;
target_sect->flags |= SEC_RELOC;
- target_sect->relocation = 0;
+ target_sect->relocation = NULL;
target_sect->rel_filepos = hdr->sh_offset;
abfd->flags |= HAS_RELOC;
return true;
char **));
extern boolean bfd_elf_mkobject PARAMS ((bfd *));
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *));
-
+extern boolean _bfd_elf_make_section_from_shdr
+ PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, const char *name));
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
PARAMS ((bfd *));