?? elf32-arm.h
字號:
asection * sec; struct elf_link_hash_entry * h; bfd_vma relocation; bfd_reloc_status_type r; arelent bfd_reloc; r_symndx = ELF32_R_SYM (rel->r_info); r_type = ELF32_R_TYPE (rel->r_info); if ( r_type == R_ARM_GNU_VTENTRY || r_type == R_ARM_GNU_VTINHERIT) continue; elf32_arm_info_to_howto (input_bfd, & bfd_reloc, rel); howto = bfd_reloc.howto; 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) { sec = local_sections[r_symndx];#ifdef USE_REL arm_add_to_rel (input_bfd, contents + rel->r_offset, howto, sec->output_offset + sym->st_value);#else rel->r_addend += (sec->output_offset + sym->st_value) >> howto->rightshift;#endif } } 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 { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; while ( h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; if ( h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { int relocation_needed = 1; sec = h->root.u.def.section; /* In these cases, we don't need the relocation value. We check specially because in some obscure cases sec->output_section will be NULL. */ switch (r_type) { case R_ARM_PC24: case R_ARM_ABS32: if (info->shared && ( (!info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 ) && ((input_section->flags & SEC_ALLOC) != 0 /* DWARF will emit R_ARM_ABS32 relocations in its sections against symbols defined externally in shared libraries. We can't do anything with them here. */ || ((input_section->flags & SEC_DEBUGGING) != 0 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) ) relocation_needed = 0; break; case R_ARM_GOTPC: relocation_needed = 0; break; case R_ARM_GOT32: if (elf_hash_table(info)->dynamic_sections_created && (!info->shared || (!info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 ) ) relocation_needed = 0; break; case R_ARM_PLT32: if (h->plt.offset != (bfd_vma)-1) relocation_needed = 0; break; default: if (sec->output_section == NULL) { (*_bfd_error_handler) (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), bfd_get_filename (input_bfd), h->root.root.string, bfd_get_section_name (input_bfd, input_section)); relocation_needed = 0; } } if (relocation_needed) relocation = h->root.u.def.value + sec->output_section->vma + sec->output_offset; else relocation = 0; } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; else if (info->shared && !info->symbolic && !info->no_undefined && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; else { if (!((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, input_section, rel->r_offset, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) return false; relocation = 0; } } if (h != NULL) name = h->root.root.string; else { name = (bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, sym->st_name)); if (name == NULL || *name == '\0') name = bfd_section_name (input_bfd, sec); } r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, input_section, contents, rel, relocation, info, sec, name, (h ? ELF_ST_TYPE (h->type) : ELF_ST_TYPE (sym->st_info)), h); if (r != bfd_reloc_ok) { const char * msg = (const char *) 0; switch (r) { case bfd_reloc_overflow: /* If the overflowing reloc was to an undefined symbol, we have already printed one error message and there is no point complaining again. */ if ((! h || h->root.type != bfd_link_hash_undefined) && (!((*info->callbacks->reloc_overflow) (info, name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))) return false; break; case bfd_reloc_undefined: if (!((*info->callbacks->undefined_symbol) (info, name, input_bfd, input_section, rel->r_offset, true))) return false; break; case bfd_reloc_outofrange: msg = _("internal error: out of range error"); goto common_error; case bfd_reloc_notsupported: msg = _("internal error: unsupported relocation error"); goto common_error; case bfd_reloc_dangerous: msg = _("internal error: dangerous error"); goto common_error; default: msg = _("internal error: unknown error"); /* fall through */ common_error: if (!((*info->callbacks->warning) (info, msg, name, input_bfd, input_section, rel->r_offset))) return false; break; } } } return true;}/* Function to keep ARM specific flags in the ELF header. */static booleanelf32_arm_set_private_flags (abfd, flags) bfd *abfd; flagword flags;{ if (elf_flags_init (abfd) && elf_elfheader (abfd)->e_flags != flags) { if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN) { if (flags & EF_INTERWORK) _bfd_error_handler (_("\Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"), bfd_get_filename (abfd)); else _bfd_error_handler (_("\Warning: Clearing the interwork flag of %s due to outside request"), bfd_get_filename (abfd)); } } else { elf_elfheader (abfd)->e_flags = flags; elf_flags_init (abfd) = true; } return true;}/* Copy backend specific data from one object module to another. */static booleanelf32_arm_copy_private_bfd_data (ibfd, obfd) bfd *ibfd; bfd *obfd;{ flagword in_flags; flagword out_flags; if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return true; in_flags = elf_elfheader (ibfd)->e_flags; out_flags = elf_elfheader (obfd)->e_flags; if (elf_flags_init (obfd) && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN && in_flags != out_flags) { /* Cannot mix APCS26 and APCS32 code. */ if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26)) return false; /* Cannot mix float APCS and non-float APCS code. */ if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT)) return false; /* If the src and dest have different interworking flags then turn off the interworking bit. */ if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK)) { if (out_flags & EF_INTERWORK) _bfd_error_handler (_("\Warning: Clearing the interwork flag in %s because non-interworking code in %s has been linked with it"), bfd_get_filename (obfd), bfd_get_filename (ibfd)); in_flags &= ~EF_INTERWORK; } /* Likewise for PIC, though don't warn for this case. */ if ((in_flags & EF_PIC) != (out_flags & EF_PIC)) in_flags &= ~EF_PIC; } elf_elfheader (obfd)->e_flags = in_flags; elf_flags_init (obfd) = true; return true;}/* Merge backend specific data from an object file to the output object file when linking. */static booleanelf32_arm_merge_private_bfd_data (ibfd, obfd) bfd * ibfd; bfd * obfd;{ flagword out_flags; flagword in_flags; boolean flags_compatible = true; boolean null_input_bfd = true; asection *sec; /* Check if we have the same endianess. */ if (_bfd_generic_verify_endian_match (ibfd, obfd) == false) return false; if ( bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return true; /* The input BFD must have had its flags initialised. */ /* The following seems bogus to me -- The flags are initialized in the assembler but I don't think an elf_flags_init field is written into the object. */ /* BFD_ASSERT (elf_flags_init (ibfd)); */ in_flags = elf_elfheader (ibfd)->e_flags; out_flags = elf_elfheader (obfd)->e_flags; if (!elf_flags_init (obfd)) { /* If the input is the default architecture and had the default flags then do not bother setting the flags for the output architecture, instead allow future merges to do this. If no future merges ever set these flags then they will retain their uninitialised values, which surprise surprise, correspond to the default values. */ if (bfd_get_arch_info (ibfd)->the_default && elf_elfheader (ibfd)->e_flags == 0) return true; elf_flags_init (obfd) = true; elf_elfheader (obfd)->e_flags = in_flags; if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) && bfd_get_arch_info (obfd)->the_default) return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); return true; } /* Identical flags must be compatible. */ if (in_flags == out_flags) return true; /* Check to see if the input BFD actually contains any sections. If not, its flags may not have been initialised either, but it cannot actually cause any incompatibility. */ for (sec = ibfd->sections; sec != NULL; sec = sec->next) { /* Ignore synthetic glue sections. */ if (strcmp (sec->name, ".glue_7") && strcmp (sec->name, ".glue_7t")) { null_input_bfd = false; break; } } if (null_input_bfd) return true; /* Complain about various flag mismatches. */ if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags)) { _bfd_error_handler (_("\Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"), bfd_get_filename (ibfd), (in_flags & EF_ARM_EABIMASK) >> 24, bfd_get_filename (obfd), (out_flags & EF_ARM_EABIMASK) >> 24); return false; } /* Not sure what needs to be checked for EABI versions >= 1. */ if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN) { if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26)) { _bfd_error_handler (_("\Error: %s compiled for APCS-%d, whereas %s is compiled for APCS-%d"), bfd_get_filename (ibfd), in_flags & EF_APCS_26 ? 26 : 32, bfd_get_filename (obfd), out_flags & EF_APCS_26 ? 26 : 32); flags_compatible = false; } if ((in_flags & EF_APCS_FLOAT) != (out_flags & EF_APCS_FLOAT)) { _bfd_error_handler (_("\Error: %s passes floats in %s registers, whereas %s passes them in %s registers"), bfd_get_filename (ibfd), in_flags & EF_APCS_FLOAT ? _("float") : _("integer"), bfd_get_filename (obfd), out_flags & EF_APCS_26 ? _("float") : _("integer")); flags_compatible = false; }#ifdef EF_SOFT_FLOAT if ((in_flags & EF_SOFT_FLOAT) != (out_flags & EF_SOFT_FLOAT)) { _bfd_error_handler (_ ("\Error: %s uses %s floating point, whereas %s uses %s floating point"), bfd_get_filename (ibfd), in_flags & EF_SOFT_FLOAT ? _("soft") : _("hard"), bfd_get_filename (obfd), out_flags & EF_SOFT_FLOAT ? _("soft") : _("hard")); flags_compatible = false; }#endif /* Interworking mismatch is only a warning. */ if ((in_flags & EF_INTERWORK) != (out_flags & EF_INTERWORK)) _bfd_error_handler (_("\Warning: %s %s interworking, whereas %s %s"), bfd_get_filename (ibfd), in_flags & EF_INTERWORK ? _("supports") : _("does not support"), bfd_get_filename (obfd), out_flags & EF_INTERWORK ? _("does not") : _("does")); } return flags_compatible;}/* Display the flags
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -