This is elf32-i3.c in view mode; [Download] [Up]
/* Intel 80386/80486-specific support for 32-bit ELF Copyright 1993 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" #include "libbfd.h" #include "libelf.h" static CONST struct reloc_howto_struct *elf_i386_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); static void elf_i386_info_to_howto PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); static void elf_i386_info_to_howto_rel PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); static boolean elf_i386_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); #define USE_REL 1 /* 386 uses REL relocations instead of RELA */ enum reloc_type { R_386_NONE = 0, R_386_32, R_386_PC32, R_386_GOT32, R_386_PLT32, R_386_COPY, R_386_GLOB_DAT, R_386_JUMP_SLOT, R_386_RELATIVE, R_386_GOTOFF, R_386_GOTPC, R_386_max }; #if 0 static CONST char *CONST reloc_type_names[] = { "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32", "R_386_PLT32", "R_386_COPY", "R_386_GLOB_DAT", "R_386_JUMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF", "R_386_GOTPC", }; #endif static reloc_howto_type elf_howto_table[]= { HOWTO(R_386_NONE, 0,0, 0,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_NONE", true,0x00000000,0x00000000,false), HOWTO(R_386_32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_32", true,0xffffffff,0xffffffff,false), HOWTO(R_386_PC32, 0,2,32,true, 0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PC32", true,0xffffffff,0xffffffff,true), HOWTO(R_386_GOT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOT32", true,0xffffffff,0xffffffff,false), HOWTO(R_386_PLT32, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_PLT32", true,0xffffffff,0xffffffff,false), HOWTO(R_386_COPY, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_COPY", true,0xffffffff,0xffffffff,false), HOWTO(R_386_GLOB_DAT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GLOB_DAT", true,0xffffffff,0xffffffff,false), HOWTO(R_386_JUMP_SLOT, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_JUMP_SLOT",true,0xffffffff,0xffffffff,false), HOWTO(R_386_RELATIVE, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_RELATIVE", true,0xffffffff,0xffffffff,false), HOWTO(R_386_GOTOFF, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTOFF", true,0xffffffff,0xffffffff,false), HOWTO(R_386_GOTPC, 0,2,32,false,0,complain_overflow_bitfield, bfd_elf_generic_reloc,"R_386_GOTPC", true,0xffffffff,0xffffffff,false), }; #ifdef DEBUG_GEN_RELOC #define TRACE(str) fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str) #else #define TRACE(str) #endif static CONST struct reloc_howto_struct * elf_i386_reloc_type_lookup (abfd, code) bfd *abfd; bfd_reloc_code_real_type code; { switch (code) { case BFD_RELOC_NONE: TRACE ("BFD_RELOC_NONE"); return &elf_howto_table[ (int)R_386_NONE ]; case BFD_RELOC_32: TRACE ("BFD_RELOC_32"); return &elf_howto_table[ (int)R_386_32 ]; case BFD_RELOC_32_PCREL: TRACE ("BFD_RELOC_PC32"); return &elf_howto_table[ (int)R_386_PC32 ]; case BFD_RELOC_386_GOT32: TRACE ("BFD_RELOC_386_GOT32"); return &elf_howto_table[ (int)R_386_GOT32 ]; case BFD_RELOC_386_PLT32: TRACE ("BFD_RELOC_386_PLT32"); return &elf_howto_table[ (int)R_386_PLT32 ]; case BFD_RELOC_386_COPY: TRACE ("BFD_RELOC_386_COPY"); return &elf_howto_table[ (int)R_386_COPY ]; case BFD_RELOC_386_GLOB_DAT: TRACE ("BFD_RELOC_386_GLOB_DAT"); return &elf_howto_table[ (int)R_386_GLOB_DAT ]; case BFD_RELOC_386_JUMP_SLOT: TRACE ("BFD_RELOC_386_JUMP_SLOT"); return &elf_howto_table[ (int)R_386_JUMP_SLOT ]; case BFD_RELOC_386_RELATIVE: TRACE ("BFD_RELOC_386_RELATIVE"); return &elf_howto_table[ (int)R_386_RELATIVE ]; case BFD_RELOC_386_GOTOFF: TRACE ("BFD_RELOC_386_GOTOFF"); return &elf_howto_table[ (int)R_386_GOTOFF ]; case BFD_RELOC_386_GOTPC: TRACE ("BFD_RELOC_386_GOTPC"); return &elf_howto_table[ (int)R_386_GOTPC ]; default: break; } TRACE ("Unknown"); return 0; } static void elf_i386_info_to_howto (abfd, cache_ptr, dst) bfd *abfd; arelent *cache_ptr; Elf32_Internal_Rela *dst; { BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; } static void elf_i386_info_to_howto_rel (abfd, cache_ptr, dst) bfd *abfd; arelent *cache_ptr; Elf32_Internal_Rel *dst; { BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_386_max); cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; } /* Relocate an i386 ELF section. */ static boolean elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, contents, relocs, local_syms, local_sections) bfd *output_bfd; struct bfd_link_info *info; bfd *input_bfd; asection *input_section; bfd_byte *contents; Elf_Internal_Rela *relocs; Elf_Internal_Sym *local_syms; asection **local_sections; { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; rel = relocs; relend = relocs + input_section->reloc_count; for (; rel < relend; rel++) { int r_type; const reloc_howto_type *howto; long r_symndx; struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; asection *sec; bfd_vma relocation; bfd_reloc_status_type r; r_type = ELF32_R_TYPE (rel->r_info); if (r_type < 0 || r_type >= (int) R_386_max) { bfd_set_error (bfd_error_bad_value); return false; } howto = elf_howto_table + r_type; r_symndx = ELF32_R_SYM (rel->r_info); if (info->relocateable) { /* This is a relocateable link. We don't have to change anything, unless the reloc is against a section symbol, in which case we have to adjust according to where the section symbol winds up in the output section. */ if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) { bfd_vma val; sec = local_sections[r_symndx]; val = bfd_get_32 (input_bfd, contents + rel->r_offset); val += sec->output_offset + sym->st_value; bfd_put_32 (input_bfd, val, contents + rel->r_offset); } } continue; } /* This is a final link. */ h = NULL; sym = NULL; sec = NULL; if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); } else { long indx; indx = r_symndx - symtab_hdr->sh_info; h = elf_sym_hashes (input_bfd)[indx]; if (h->root.type == bfd_link_hash_defined) { sec = h->root.u.def.section; relocation = (h->root.u.def.value + sec->output_section->vma + sec->output_offset); } else if (h->root.type == bfd_link_hash_weak) relocation = 0; else { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, input_section, rel->r_offset))) return false; relocation = 0; } } r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation, (bfd_vma) 0); if (r != bfd_reloc_ok) { switch (r) { default: case bfd_reloc_outofrange: abort (); case bfd_reloc_overflow: { const char *name; if (h != NULL) name = h->root.root.string; else { name = elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name); if (name == NULL) return false; if (*name == '\0') name = bfd_section_name (input_bfd, sec); } if (! ((*info->callbacks->reloc_overflow) (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset))) return false; } break; } } } return true; } #define TARGET_LITTLE_SYM bfd_elf32_i386_vec #define TARGET_LITTLE_NAME "elf32-i386" #define ELF_ARCH bfd_arch_i386 #define ELF_MACHINE_CODE EM_386 #define elf_info_to_howto elf_i386_info_to_howto #define elf_info_to_howto_rel elf_i386_info_to_howto_rel #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup #define ELF_MAXPAGESIZE 0x1000 #define elf_backend_relocate_section elf_i386_relocate_section #include "elf32-target.h"
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.