* elf32-i386.c: Add comment re linker function names and ordering.
(elf_i386_link_hash_newfunc): Rename to link_hash_newfunc. (elf_i386_grok_prstatus): Move before linker functions. (elf_i386_grok_psinfo): Likewise. (elf_i386_fake_sections): Move so that functions are ordered. (elf_i386_reloc_type_class): Likewise. Comment function purpose.
This commit is contained in:
parent
6e22e505ed
commit
387019538f
@ -1,3 +1,12 @@
|
||||
2001-09-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-i386.c: Add comment re linker function names and ordering.
|
||||
(elf_i386_link_hash_newfunc): Rename to link_hash_newfunc.
|
||||
(elf_i386_grok_prstatus): Move before linker functions.
|
||||
(elf_i386_grok_psinfo): Likewise.
|
||||
(elf_i386_fake_sections): Move so that functions are ordered.
|
||||
(elf_i386_reloc_type_class): Likewise. Comment function purpose.
|
||||
|
||||
2001-09-25 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-hppa.c: Rename all occurrences of "hplink" to "htab"
|
||||
|
276
bfd/elf32-i386.c
276
bfd/elf32-i386.c
@ -31,7 +31,11 @@ static void elf_i386_info_to_howto
|
||||
static void elf_i386_info_to_howto_rel
|
||||
PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
|
||||
static boolean elf_i386_is_local_label_name PARAMS ((bfd *, const char *));
|
||||
static struct bfd_hash_entry *elf_i386_link_hash_newfunc
|
||||
static boolean elf_i386_grok_prstatus
|
||||
PARAMS ((bfd *abfd, Elf_Internal_Note *note));
|
||||
static boolean elf_i386_grok_psinfo
|
||||
PARAMS ((bfd *abfd, Elf_Internal_Note *note));
|
||||
static struct bfd_hash_entry *link_hash_newfunc
|
||||
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
|
||||
static struct bfd_link_hash_table *elf_i386_link_hash_table_create
|
||||
PARAMS ((bfd *));
|
||||
@ -53,6 +57,8 @@ static boolean allocate_dynrelocs
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean readonly_dynrelocs
|
||||
PARAMS ((struct elf_link_hash_entry *, PTR));
|
||||
static boolean elf_i386_fake_sections
|
||||
PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
|
||||
static boolean elf_i386_size_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean elf_i386_relocate_section
|
||||
@ -61,16 +67,10 @@ static boolean elf_i386_relocate_section
|
||||
static boolean elf_i386_finish_dynamic_symbol
|
||||
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
|
||||
Elf_Internal_Sym *));
|
||||
static boolean elf_i386_finish_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
static boolean elf_i386_fake_sections
|
||||
PARAMS ((bfd *, Elf32_Internal_Shdr *, asection *));
|
||||
static enum elf_reloc_type_class elf_i386_reloc_type_class
|
||||
PARAMS ((const Elf_Internal_Rela *));
|
||||
static boolean elf_i386_grok_prstatus
|
||||
PARAMS ((bfd *abfd, Elf_Internal_Note *note));
|
||||
static boolean elf_i386_grok_psinfo
|
||||
PARAMS ((bfd *abfd, Elf_Internal_Note *note));
|
||||
static boolean elf_i386_finish_dynamic_sections
|
||||
PARAMS ((bfd *, struct bfd_link_info *));
|
||||
|
||||
#define USE_REL 1 /* 386 uses REL relocations instead of RELA */
|
||||
|
||||
@ -315,7 +315,84 @@ elf_i386_is_local_label_name (abfd, name)
|
||||
return _bfd_elf_is_local_label_name (abfd, name);
|
||||
}
|
||||
|
||||
/* Functions for the i386 ELF linker. */
|
||||
/* Support for core dump NOTE sections. */
|
||||
static boolean
|
||||
elf_i386_grok_prstatus (abfd, note)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Note *note;
|
||||
{
|
||||
int offset;
|
||||
size_t raw_size;
|
||||
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
|
||||
case 144: /* Linux/i386 */
|
||||
/* pr_cursig */
|
||||
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
||||
|
||||
/* pr_pid */
|
||||
elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
|
||||
|
||||
/* pr_reg */
|
||||
offset = 72;
|
||||
raw_size = 68;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make a ".reg/999" section. */
|
||||
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
|
||||
raw_size, note->descpos + offset);
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf_i386_grok_psinfo (abfd, note)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Note *note;
|
||||
{
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
|
||||
case 128: /* Linux/MIPS elf_prpsinfo */
|
||||
elf_tdata (abfd)->core_program
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||
elf_tdata (abfd)->core_command
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
||||
}
|
||||
|
||||
/* Note that for some reason, a spurious space is tacked
|
||||
onto the end of the args in some (at least one anyway)
|
||||
implementations, so strip it off if it exists. */
|
||||
|
||||
{
|
||||
char *command = elf_tdata (abfd)->core_command;
|
||||
int n = strlen (command);
|
||||
|
||||
if (0 < n && command[n - 1] == ' ')
|
||||
command[n - 1] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Functions for the i386 ELF linker.
|
||||
|
||||
In order to gain some understanding of code in this file without
|
||||
knowing all the intricate details of the linker, note the
|
||||
following:
|
||||
|
||||
Functions named elf_i386_* are called by external routines, other
|
||||
functions are only called locally. elf_i386_* functions appear
|
||||
in this file more or less in the order in which they are called
|
||||
from external routines. eg. elf_i386_check_relocs is called
|
||||
early in the link process, elf_i386_finish_dynamic_sections is
|
||||
one of the last functions. */
|
||||
|
||||
|
||||
/* The name of the dynamic interpreter. This is put in the .interp
|
||||
section. */
|
||||
@ -426,7 +503,7 @@ struct elf_i386_link_hash_table
|
||||
/* Create an entry in an i386 ELF linker hash table. */
|
||||
|
||||
static struct bfd_hash_entry *
|
||||
elf_i386_link_hash_newfunc (entry, table, string)
|
||||
link_hash_newfunc (entry, table, string)
|
||||
struct bfd_hash_entry *entry;
|
||||
struct bfd_hash_table *table;
|
||||
const char *string;
|
||||
@ -468,8 +545,7 @@ elf_i386_link_hash_table_create (abfd)
|
||||
if (ret == (struct elf_i386_link_hash_table *) NULL)
|
||||
return NULL;
|
||||
|
||||
if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
|
||||
elf_i386_link_hash_newfunc))
|
||||
if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, link_hash_newfunc))
|
||||
{
|
||||
bfd_release (abfd, ret);
|
||||
return NULL;
|
||||
@ -1508,6 +1584,41 @@ elf_i386_size_dynamic_sections (output_bfd, info)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set the correct type for an x86 ELF section. We do this by the
|
||||
section name, which is a hack, but ought to work. */
|
||||
|
||||
static boolean
|
||||
elf_i386_fake_sections (abfd, hdr, sec)
|
||||
bfd *abfd ATTRIBUTE_UNUSED;
|
||||
Elf32_Internal_Shdr *hdr;
|
||||
asection *sec;
|
||||
{
|
||||
register const char *name;
|
||||
|
||||
name = bfd_get_section_name (abfd, sec);
|
||||
|
||||
/* This is an ugly, but unfortunately necessary hack that is
|
||||
needed when producing EFI binaries on x86. It tells
|
||||
elf.c:elf_fake_sections() not to consider ".reloc" as a section
|
||||
containing ELF relocation info. We need this hack in order to
|
||||
be able to generate ELF binaries that can be translated into
|
||||
EFI applications (which are essentially COFF objects). Those
|
||||
files contain a COFF ".reloc" section inside an ELFNN object,
|
||||
which would normally cause BFD to segfault because it would
|
||||
attempt to interpret this section as containing relocation
|
||||
entries for section "oc". With this hack enabled, ".reloc"
|
||||
will be treated as a normal data section, which will avoid the
|
||||
segfault. However, you won't be able to create an ELFNN binary
|
||||
with a section named "oc" that needs relocations, but that's
|
||||
the kind of ugly side-effects you get when detecting section
|
||||
types based on their names... In practice, this limitation is
|
||||
unlikely to bite. */
|
||||
if (strcmp (name, ".reloc") == 0)
|
||||
hdr->sh_type = SHT_PROGBITS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Relocate an i386 ELF section. */
|
||||
|
||||
static boolean
|
||||
@ -2096,6 +2207,26 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Used to decide how to sort relocs in an optimal manner for the
|
||||
dynamic linker, before writing them out. */
|
||||
|
||||
static enum elf_reloc_type_class
|
||||
elf_i386_reloc_type_class (rela)
|
||||
const Elf_Internal_Rela *rela;
|
||||
{
|
||||
switch ((int) ELF32_R_TYPE (rela->r_info))
|
||||
{
|
||||
case R_386_RELATIVE:
|
||||
return reloc_class_relative;
|
||||
case R_386_JUMP_SLOT:
|
||||
return reloc_class_plt;
|
||||
case R_386_COPY:
|
||||
return reloc_class_copy;
|
||||
default:
|
||||
return reloc_class_normal;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish up the dynamic sections. */
|
||||
|
||||
static boolean
|
||||
@ -2218,125 +2349,6 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set the correct type for an x86 ELF section. We do this by the
|
||||
section name, which is a hack, but ought to work. */
|
||||
|
||||
static boolean
|
||||
elf_i386_fake_sections (abfd, hdr, sec)
|
||||
bfd *abfd ATTRIBUTE_UNUSED;
|
||||
Elf32_Internal_Shdr *hdr;
|
||||
asection *sec;
|
||||
{
|
||||
register const char *name;
|
||||
|
||||
name = bfd_get_section_name (abfd, sec);
|
||||
|
||||
if (strcmp (name, ".reloc") == 0)
|
||||
/*
|
||||
* This is an ugly, but unfortunately necessary hack that is
|
||||
* needed when producing EFI binaries on x86. It tells
|
||||
* elf.c:elf_fake_sections() not to consider ".reloc" as a section
|
||||
* containing ELF relocation info. We need this hack in order to
|
||||
* be able to generate ELF binaries that can be translated into
|
||||
* EFI applications (which are essentially COFF objects). Those
|
||||
* files contain a COFF ".reloc" section inside an ELFNN object,
|
||||
* which would normally cause BFD to segfault because it would
|
||||
* attempt to interpret this section as containing relocation
|
||||
* entries for section "oc". With this hack enabled, ".reloc"
|
||||
* will be treated as a normal data section, which will avoid the
|
||||
* segfault. However, you won't be able to create an ELFNN binary
|
||||
* with a section named "oc" that needs relocations, but that's
|
||||
* the kind of ugly side-effects you get when detecting section
|
||||
* types based on their names... In practice, this limitation is
|
||||
* unlikely to bite.
|
||||
*/
|
||||
hdr->sh_type = SHT_PROGBITS;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static enum elf_reloc_type_class
|
||||
elf_i386_reloc_type_class (rela)
|
||||
const Elf_Internal_Rela *rela;
|
||||
{
|
||||
switch ((int) ELF32_R_TYPE (rela->r_info))
|
||||
{
|
||||
case R_386_RELATIVE:
|
||||
return reloc_class_relative;
|
||||
case R_386_JUMP_SLOT:
|
||||
return reloc_class_plt;
|
||||
case R_386_COPY:
|
||||
return reloc_class_copy;
|
||||
default:
|
||||
return reloc_class_normal;
|
||||
}
|
||||
}
|
||||
|
||||
/* Support for core dump NOTE sections */
|
||||
static boolean
|
||||
elf_i386_grok_prstatus (abfd, note)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Note *note;
|
||||
{
|
||||
int offset;
|
||||
size_t raw_size;
|
||||
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
|
||||
case 144: /* Linux/i386 */
|
||||
/* pr_cursig */
|
||||
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
|
||||
|
||||
/* pr_pid */
|
||||
elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
|
||||
|
||||
/* pr_reg */
|
||||
offset = 72;
|
||||
raw_size = 68;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make a ".reg/999" section. */
|
||||
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
|
||||
raw_size, note->descpos + offset);
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf_i386_grok_psinfo (abfd, note)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Note *note;
|
||||
{
|
||||
switch (note->descsz)
|
||||
{
|
||||
default:
|
||||
return false;
|
||||
|
||||
case 128: /* Linux/MIPS elf_prpsinfo */
|
||||
elf_tdata (abfd)->core_program
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
|
||||
elf_tdata (abfd)->core_command
|
||||
= _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
|
||||
}
|
||||
|
||||
/* Note that for some reason, a spurious space is tacked
|
||||
onto the end of the args in some (at least one anyway)
|
||||
implementations, so strip it off if it exists. */
|
||||
|
||||
{
|
||||
char *command = elf_tdata (abfd)->core_command;
|
||||
int n = strlen (command);
|
||||
|
||||
if (0 < n && command[n - 1] == ' ')
|
||||
command[n - 1] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
|
||||
#define TARGET_LITTLE_NAME "elf32-i386"
|
||||
#define ELF_ARCH bfd_arch_i386
|
||||
|
Loading…
Reference in New Issue
Block a user