aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-05-20 16:04:59 +0000
committerIan Lance Taylor <ian@airs.com>1994-05-20 16:04:59 +0000
commit497c543457bbdabe61c03733d2a44167bf354dae (patch)
tree4c2207e298b66fa12ea3ecd088a3e5b2c6d6b640
parent09985c960d737684e85d60dcc5796e2f1e8b6b45 (diff)
downloadgdb-497c543457bbdabe61c03733d2a44167bf354dae.zip
gdb-497c543457bbdabe61c03733d2a44167bf354dae.tar.gz
gdb-497c543457bbdabe61c03733d2a44167bf354dae.tar.bz2
* 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.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/elf.c62
-rw-r--r--bfd/elf32-mips.c93
-rw-r--r--bfd/elfcode.h144
-rw-r--r--bfd/libelf.h3
5 files changed, 137 insertions, 177 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index a542d71..aaecc9c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+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
diff --git a/bfd/elf.c b/bfd/elf.c
index a3ec151..b5c23db 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -154,6 +154,68 @@ elf_string_from_elf_section (abfd, shindex, strindex)
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
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 7f4930d..1794210 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -795,6 +795,8 @@ mips_elf_section_from_shdr (abfd, hdr, name)
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
@@ -835,60 +837,33 @@ mips_elf_section_from_shdr (abfd, hdr, name)
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;
@@ -1201,20 +1176,15 @@ mips_elf_final_link (abfd, info)
_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;
@@ -1694,6 +1664,7 @@ static const struct ecoff_debug_swap mips_elf_ecoff_debug_swap =
#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
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index bdedb48..db0316a 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -496,7 +496,6 @@ bfd_add_2_to_strtab (abfd, ss, str, str2)
return ss->length - ln;
}
-
/* ELF .o/exec file reading */
/* Create a new bfd section from an ELF section header. */
@@ -508,84 +507,20 @@ bfd_section_from_shdr (abfd, shindex)
{
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)
@@ -612,7 +547,7 @@ bfd_section_from_shdr (abfd, shindex)
return true;
case SHT_STRTAB: /* A string table */
- if (hdr->rawdata)
+ if (hdr->rawdata != NULL)
return true;
if (ehdr->e_shstrndx == shindex)
{
@@ -658,48 +593,29 @@ bfd_section_from_shdr (abfd, 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
@@ -708,15 +624,13 @@ bfd_section_from_shdr (abfd, shindex)
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
@@ -728,7 +642,7 @@ bfd_section_from_shdr (abfd, shindex)
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;
diff --git a/bfd/libelf.h b/bfd/libelf.h
index 5d53f88..25d56b0 100644
--- a/bfd/libelf.h
+++ b/bfd/libelf.h
@@ -453,7 +453,8 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
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 *));