* 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.
This commit is contained in:
Ian Lance Taylor 1994-05-20 16:04:59 +00:00
parent 09985c960d
commit 497c543457
5 changed files with 136 additions and 176 deletions

View File

@ -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) 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 * elf32-target.h, elf64-target.h: Change ar_max_namelen value from

View File

@ -154,6 +154,68 @@ elf_string_from_elf_section (abfd, shindex, strindex)
return ((char *) hdr->rawdata) + 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 INTERNAL_FUNCTION
bfd_elf_find_section bfd_elf_find_section

View File

@ -795,6 +795,8 @@ mips_elf_section_from_shdr (abfd, hdr, name)
Elf32_Internal_Shdr *hdr; Elf32_Internal_Shdr *hdr;
char *name; char *name;
{ {
asection *newsect;
/* There ought to be a place to keep ELF backend specific flags, but /* 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 at the moment there isn't one. We just keep track of the
sections by their name, instead. Fortunately, the ABI gives sections by their name, instead. Fortunately, the ABI gives
@ -835,60 +837,33 @@ mips_elf_section_from_shdr (abfd, hdr, name)
return false; return false;
} }
if (hdr->rawdata == NULL) if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
return false;
newsect = (asection *) hdr->rawdata;
if (hdr->sh_type == SHT_MIPS_DEBUG)
{ {
asection *newsect; if (! bfd_set_section_flags (abfd, newsect,
(bfd_get_section_flags (abfd, newsect)
| SEC_DEBUGGING)))
return false;
}
newsect = bfd_make_section (abfd, name); /* FIXME: We should record sh_info for a .gptab section. */
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) /* For a .reginfo section, set the gp value in the tdata information
{ from the contents of this section. We need the gp value while
newsect->flags |= SEC_ALLOC; processing relocs, so we just get it now. */
newsect->flags |= SEC_LOAD; if (hdr->sh_type == SHT_MIPS_REGINFO)
} {
Elf32_External_RegInfo ext;
Elf32_RegInfo s;
if (!(hdr->sh_flags & SHF_WRITE)) if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext,
newsect->flags |= SEC_READONLY; (file_ptr) 0, sizeof ext))
return false;
if (hdr->sh_flags & SHF_EXECINSTR) bfd_mips_elf32_swap_reginfo_in (abfd, &ext, &s);
newsect->flags |= SEC_CODE; elf_gp (abfd) = s.ri_gp_value;
else if (newsect->flags & SEC_ALLOC)
newsect->flags |= SEC_DATA;
if (hdr->sh_type == SHT_MIPS_DEBUG)
newsect->flags |= SEC_DEBUGGING;
hdr->rawdata = (void *) newsect;
/* FIXME: We should record the sh_info field 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;
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);
} }
return true; return true;
@ -1201,20 +1176,15 @@ mips_elf_final_link (abfd, info)
_bfd_generic_link_write_global_symbol, _bfd_generic_link_write_global_symbol,
(PTR) &wginfo); (PTR) &wginfo);
/* Remove empty sections. Also drop the .options section, since it /* Drop the .options section, since it has special semantics which I
has special semantics which I haven't bothered to figure out. haven't bothered to figure out. Also drop the .gptab sections,
Also drop the .gptab sections, which also require special which also require special handling which is not currently done.
handling which is not currently done. Removing the .gptab Removing the .gptab sections is required for Irix 5
sections is required for Irix 5 compatibility; I don't know about compatibility; I don't know about .options. */
the other sections. */
secpp = &abfd->sections; secpp = &abfd->sections;
while (*secpp != NULL) while (*secpp != NULL)
{ {
if (((*secpp)->_raw_size == 0 if (strcmp ((*secpp)->name, ".options") == 0
&& strcmp ((*secpp)->name, ".data") != 0
&& strcmp ((*secpp)->name, ".text") != 0
&& strcmp ((*secpp)->name, ".bss") != 0)
|| strcmp ((*secpp)->name, ".options") == 0
|| strncmp ((*secpp)->name, ".gptab", 6) == 0) || strncmp ((*secpp)->name, ".gptab", 6) == 0)
{ {
*secpp = (*secpp)->next; *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_ARCH bfd_arch_mips
#define ELF_MACHINE_CODE EM_MIPS #define ELF_MACHINE_CODE EM_MIPS
#define ELF_MAXPAGESIZE 0x10000 #define ELF_MAXPAGESIZE 0x10000
#define elf_backend_collect true
#define elf_info_to_howto 0 #define elf_info_to_howto 0
#define elf_info_to_howto_rel mips_info_to_howto_rel #define elf_info_to_howto_rel mips_info_to_howto_rel
#define elf_backend_sym_is_global mips_elf_sym_is_global #define elf_backend_sym_is_global mips_elf_sym_is_global

View File

@ -496,7 +496,6 @@ bfd_add_2_to_strtab (abfd, ss, str, str2)
return ss->length - ln; return ss->length - ln;
} }
/* ELF .o/exec file reading */ /* ELF .o/exec file reading */
/* Create a new bfd section from an ELF section header. */ /* 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_Shdr *hdr = elf_elfsections (abfd)[shindex];
Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd); Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
asection *newsect;
char *name; char *name;
name = elf_string_from_elf_strtab (abfd, hdr->sh_name); name = elf_string_from_elf_strtab (abfd, hdr->sh_name);
switch (hdr->sh_type) switch (hdr->sh_type)
{ {
case SHT_NULL: case SHT_NULL:
/* inactive section. Throw it away. */ /* Inactive section. Throw it away. */
return true; return true;
case SHT_PROGBITS: case SHT_PROGBITS: /* Normal section with contents. */
case SHT_DYNAMIC: case SHT_DYNAMIC: /* Dynamic linking information. */
/* Bits that get saved. This one is real. */ case SHT_NOBITS: /* .bss section. */
if (hdr->rawdata == NULL) return _bfd_elf_make_section_from_shdr (abfd, hdr, name);
{
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_SYMTAB: /* A symbol table */ case SHT_SYMTAB: /* A symbol table */
if (elf_onesymtab (abfd) == shindex) if (elf_onesymtab (abfd) == shindex)
@ -612,7 +547,7 @@ bfd_section_from_shdr (abfd, shindex)
return true; return true;
case SHT_STRTAB: /* A string table */ case SHT_STRTAB: /* A string table */
if (hdr->rawdata) if (hdr->rawdata != NULL)
return true; return true;
if (ehdr->e_shstrndx == shindex) if (ehdr->e_shstrndx == shindex)
{ {
@ -658,48 +593,29 @@ bfd_section_from_shdr (abfd, shindex)
} }
} }
newsect = bfd_make_section_anyway (abfd, name); return _bfd_elf_make_section_from_shdr (abfd, hdr, 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;
case SHT_REL: case SHT_REL:
case SHT_RELA: case SHT_RELA:
/* *These* do a lot of work -- but build no sections! /* *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 */
{ {
asection *target_sect; asection *target_sect;
Elf_Internal_Shdr *hdr2; Elf_Internal_Shdr *hdr2;
int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; 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 /* Don't allow REL relocations on a machine that uses RELA and
vice versa. */ vice versa. */
/* @@ Actually, the generic ABI does suggest that both might be /* @@ 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 each of those architectures. It's conceivable that, e.g., a
bunch of absolute 32-bit relocs might be more compact in REL bunch of absolute 32-bit relocs might be more compact in REL
form even on a RELA machine... */ form even on a RELA machine... */
BFD_ASSERT (!(use_rela_p && (hdr->sh_type == SHT_REL))); BFD_ASSERT (use_rela_p
BFD_ASSERT (!(!use_rela_p && (hdr->sh_type == SHT_RELA))); ? (hdr->sh_type == SHT_RELA
BFD_ASSERT (hdr->sh_entsize == && hdr->sh_entsize == sizeof (Elf_External_Rela))
(use_rela_p : (hdr->sh_type == SHT_REL
? sizeof (Elf_External_Rela) && hdr->sh_entsize == sizeof (Elf_External_Rel)));
: sizeof (Elf_External_Rel)));
if (! bfd_section_from_shdr (abfd, hdr->sh_info) /* target */ if (! bfd_section_from_shdr (abfd, hdr->sh_info))
|| ! bfd_section_from_shdr (abfd, hdr->sh_link)) /* symbol table */
return false; return false;
target_sect = section_from_elf_index (abfd, hdr->sh_info); target_sect = section_from_elf_index (abfd, hdr->sh_info);
if (target_sect == NULL if (target_sect == NULL
@ -728,7 +642,7 @@ bfd_section_from_shdr (abfd, shindex)
elf_elfsections (abfd)[shindex] = hdr2; elf_elfsections (abfd)[shindex] = hdr2;
target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize; target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize;
target_sect->flags |= SEC_RELOC; target_sect->flags |= SEC_RELOC;
target_sect->relocation = 0; target_sect->relocation = NULL;
target_sect->rel_filepos = hdr->sh_offset; target_sect->rel_filepos = hdr->sh_offset;
abfd->flags |= HAS_RELOC; abfd->flags |= HAS_RELOC;
return true; return true;

View File

@ -453,7 +453,8 @@ extern bfd_reloc_status_type bfd_elf_generic_reloc PARAMS ((bfd *,
char **)); char **));
extern boolean bfd_elf_mkobject PARAMS ((bfd *)); extern boolean bfd_elf_mkobject PARAMS ((bfd *));
extern Elf_Internal_Shdr *bfd_elf_find_section PARAMS ((bfd *, char *)); 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 extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
PARAMS ((bfd *)); PARAMS ((bfd *));