diff options
author | Ian Lance Taylor <ian@airs.com> | 1994-07-26 17:18:37 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1994-07-26 17:18:37 +0000 |
commit | 374d2ef9053ed629c495b9f9f07b7e4f70578f81 (patch) | |
tree | ae10177842c1a8edaacf8b4282365ed3fbab3eb5 /bfd/libelf.h | |
parent | b019d460d18d477bd951cbc98f6372290775f50f (diff) | |
download | gdb-374d2ef9053ed629c495b9f9f07b7e4f70578f81.zip gdb-374d2ef9053ed629c495b9f9f07b7e4f70578f81.tar.gz gdb-374d2ef9053ed629c495b9f9f07b7e4f70578f81.tar.bz2 |
Add support for creating shared libraries under i386 ELF and SPARC
ELF. Based on patches by Eric Youngdale <ericy@cais.cais.com>.
* libelf.h (struct elf_link_hash_entry): Remove copy_offset field.
Add got_offset and plt_offset fields.
(ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE): Don't define.
(ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE): Don't define.
(ELF_LINK_HASH_NEEDS_COPY): Define.
(struct elf_backend_data): Add check_relocs field.
(struct bfd_elf_section_data): Change relocs from PTR to
Elf_Internal_Rela *.
(struct elf_obj_tdata): Add local_got_offsets field.
(elf_local_got_offsets): Define accessor macro.
(bfd_elf32_link_create_dynamic_sections): Declare.
(bfd_elf32_link_record_dynamic_symbol): Declare.
(bfd_elf64_link_create_dynamic_sections): Declare.
(bfd_elf64_link_record_dynamic_symbol): Declare.
* elfcode.h (elf_slurp_reloc_table): Don't use the section data
relocs field.
(elf_link_record_dynamic_symbol): Make globally visible. Use
macro to rename to NAME(bfd_elf,link_record_dynamic_symbol).
(elf_link_add_object_symbols): If creating a shared library, put
make all local symbols dynamic. Don't bother with the
DYNAMIC_MULTIPLE flags. Call the check_relocs backend function if
it is defined.
(elf_link_create_dynamic_sections): Make globally visible. Use
macro to rename to NAME(bfd_elf,link_create_dynamic_sections). If
creating a shared library, make sure that _DYNAMIC is added as a
dynamic symbol.
(elf_link_read_relocs): New function.
(NAME(bfd_elf,record_link_assignment)): If creating a shared
library, always create symbols, and always make them dynamic.
(elf_bfd_final_link): Permit creation of shared libraries.
(elf_link_input_bfd): Use elf_link_read_relocs to get the relocs.
* elf.c (_bfd_elf_link_hash_newfunc): Don't initialize
copy_offset. Initialize got_offset and plt_offset.
* elf32-target.h (elf_backend_check_relocs): Define as 0 if not
defined.
(elf32_bed): Initialize check_relocs field.
* elf64-target.h (elf_backend_check_relocs): Define as 0 if not
defined.
(elf64_bed): Initialize check_relocs field.
* elf32-i386.c (elf_howto_table): Change R_386_PLT32 and
R_386_GOTPC to be pc_relative and pcrel_offset.
(elf_i386_pic_plt0_entry): Define.
(elf_i386_pic_plt_entry): Define.
(elf_i386_create_dynamic_sections): Create a .got.plt section, and
define _GLOBAL_OFFSET_TABLE_ at the start of it. If creating a
shared library, make sure that _GLOBAL_OFFSET_TABLE_ is added as a
dynamic symbol. Don't create .rel.bss if creating a shared
library.
(elf_i386_check_relocs): New function.
(elf_i386_adjust_dynamic_symbol): Don't make a PLT entry if the
symbol already has one. When making a PLT entry, set plt_offset.
Don't create a copy reloc when creating a shared library. Don't
set copy_offset, just set ELF_LINK_HASH_NEEDS_COPY.
(elf_i386_allocate_dynamic_section): Remove.
(elf_i386_size_dynamic_sections): Look through all the sections
rather than assuming we know their names. Remove any empty reloc
or plt sections. Only add a DT_DEBUG entry if not creating a
shared library. Only add a DT_PLTGOT entry if there is a PLT.
Add a DT_TEXTREL entry if required.
(elf_i386_relocate_section): Permit undefined symbols when
creating a shared library. Handle the special relocation types
specially.
(elf_i386_finish_dynamic_symbol): Create a PLT entry if plt_offset
is set. If creating a shared library, produce a PIC PLT entry.
Only mark a PLT symbol as undefined if it was not defined by a
regular object file. Create a GOT entry if got_offset is set.
Create a copy reloc if ELF_LINK_HASH_NEEDS_COPY is set.
(elf_i386_finish_dynamic_sections): Change the handling of
DT_RELSZ to simply subtract out the size of .rel.plt. If creating
a shared library, produce PIC PLT code.
(elf_backend_check_relocs): Define.
* elf32-sparc.c (elf_sparc_howto_table): Change R_SPARC_GOT10,
R_SPARC_GOT22, and R_SPARC_PC10 to not warn about reloc overflow.
(elf32_sparc_create_dynamic_sections): If creating a shared
library, make sure that _GLOBAL_OFFSET_TABLE_ is added as a
dynamic symbol, and set the type to STT_OBJECT. Likewise for
_PROCEDURE_LINKAGE_TABLE_. Don't create .rel.bss if creating a
shared library.
(elf32_sparc_check_relocs): New function.
(elf32_sparc_adjust_dynamic_symbol): Don't make a PLT entry if the
symbol already has one. When making a PLT entry, set plt_offset.
Don't create a copy reloc when creating a shared library. Don't
set copy_offset, just set ELF_LINK_HASH_NEEDS_COPY.
(elf32_sparc_allocate_dynamic_section): Remove.
(elf32_sparc_size_dynamic_sections): Look through all the sections
rather than assuming we know their names. Only add a DT_DEBUG
entry if not creating a shared library. Add a DT_TEXTREL entry if
required.
(elf32_sparc_relocate_section): Permit undefined symbols when
creating a shared library. Handle the special relocation types
specially.
(elf32_sparc_finish_dynamic_symbol): Create a PLT entry if plt_offset
is set. Only mark a PLT symbol as undefined if it was not defined
by a regular object file. Create a GOT entry if got_offset is
set. Create a copy reloc if ELF_LINK_HASH_NEEDS_COPY is set.
(elf32_sparc_finish_dynamic_sections): Store dynobj in a local
variable.
(elf_backend_check_relocs): Define.
Diffstat (limited to 'bfd/libelf.h')
-rw-r--r-- | bfd/libelf.h | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/bfd/libelf.h b/bfd/libelf.h index f14ac95..d43f135 100644 --- a/bfd/libelf.h +++ b/bfd/libelf.h @@ -89,9 +89,18 @@ struct elf_link_hash_entry one. Otherwise it is NULL. */ struct elf_link_hash_entry *weakdef; - /* If we need to generate a COPY reloc, the processor specific - backend uses this to hold the offset into the reloc section. */ - bfd_vma copy_offset; + /* If this symbol requires an entry in the global offset table, the + processor specific backend uses this field to hold the offset + into the .got section. If this field is -1, then the symbol does + not require a global offset table entry. */ + bfd_vma got_offset; + + /* If this symbol requires an entry in the procedure linkage table, + the processor specific backend uses these two fields to hold the + offset into the procedure linkage section and the offset into the + .got section. If plt_offset is -1, then the symbol does not + require an entry in the procedure linkage table. */ + bfd_vma plt_offset; /* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */ char type; @@ -106,14 +115,12 @@ struct elf_link_hash_entry #define ELF_LINK_HASH_REF_DYNAMIC 04 /* Symbol is defined by a shared object. */ #define ELF_LINK_HASH_DEF_DYNAMIC 010 - /* Symbol is referenced by two or more shared objects. */ -#define ELF_LINK_HASH_REF_DYNAMIC_MULTIPLE 020 - /* Symbol is defined by two or more shared objects. */ -#define ELF_LINK_HASH_DEF_DYNAMIC_MULTIPLE 040 /* Dynamic symbol has been adjustd. */ -#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 0100 +#define ELF_LINK_HASH_DYNAMIC_ADJUSTED 020 /* Symbol is defined as weak. */ -#define ELF_LINK_HASH_DEFINED_WEAK 0200 +#define ELF_LINK_HASH_DEFINED_WEAK 040 + /* Symbol needs a copy reloc. */ +#define ELF_LINK_HASH_NEEDS_COPY 0100 }; /* ELF linker hash table. */ @@ -277,6 +284,20 @@ struct elf_backend_data boolean (*elf_backend_create_dynamic_sections) PARAMS ((bfd *abfd, struct bfd_link_info *info)); + /* The CHECK_RELOCS function is called by the add_symbols phase of + the ELF backend linker. It is called once for each section with + relocs of an object file, just after the symbols for the object + file have been added to the global linker hash table. The + function must look through the relocs and do any special handling + required. This generally means allocating space in the global + offset table, and perhaps allocating space for a reloc. The + relocs are always passed as Rela structures; if the section + actually uses Rel structures, the r_addend field will always be + zero. */ + boolean (*check_relocs) + PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *o, + const Elf_Internal_Rela *relocs)); + /* The ADJUST_DYNAMIC_SYMBOL function is called by the ELF backend linker for every symbol which is defined by a dynamic object and referenced by a regular object. This is called after all the @@ -396,8 +417,10 @@ struct bfd_elf_section_data { /* Used by the backend linker to store the symbol hash table entries associated with relocs against global symbols. */ struct elf_link_hash_entry **rel_hashes; - /* A pointer to the unswapped external relocs; this may be NULL. */ - PTR relocs; + /* A pointer to the swapped relocs. If the section uses REL relocs, + rather than RELA, all the r_addend fields will be zero. This + pointer may be NULL. It is used by the backend linker. */ + Elf_Internal_Rela *relocs; }; #define elf_section_data(sec) ((struct bfd_elf_section_data*)sec->used_by_bfd) @@ -443,6 +466,10 @@ struct elf_obj_tdata minus the sh_info field of the symbol table header. */ struct elf_link_hash_entry **sym_hashes; + /* A mapping from local symbols to offsets into the global offset + table, used when linking. This is indexed by the symbol index. */ + bfd_vma *local_got_offsets; + /* The linker ELF emulation code needs to let the backend ELF linker know what filename should be used for a dynamic object if the dynamic object is found using a search. This field is used to @@ -473,6 +500,7 @@ struct elf_obj_tdata #define elf_gp(bfd) (elf_tdata(bfd) -> gp) #define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size) #define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes) +#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got_offsets) #define elf_dt_needed_name(bfd) (elf_tdata(bfd) -> dt_needed_name) #define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) @@ -565,6 +593,10 @@ extern void bfd_elf32_swap_dyn_out PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf32_External_Dyn *)); extern boolean bfd_elf32_add_dynamic_entry PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); +extern boolean bfd_elf32_link_create_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +extern boolean bfd_elf32_link_record_dynamic_symbol + PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); /* If the target doesn't have reloc handling written yet: */ extern void bfd_elf32_no_info_to_howto PARAMS ((bfd *, arelent *, @@ -626,6 +658,10 @@ extern void bfd_elf64_swap_dyn_out PARAMS ((bfd *, const Elf_Internal_Dyn *, Elf64_External_Dyn *)); extern boolean bfd_elf64_add_dynamic_entry PARAMS ((struct bfd_link_info *, bfd_vma, bfd_vma)); +extern boolean bfd_elf64_link_create_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +extern boolean bfd_elf64_link_record_dynamic_symbol + PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); /* If the target doesn't have reloc handling written yet: */ extern void bfd_elf64_no_info_to_howto PARAMS ((bfd *, arelent *, |