⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 700-nios2-2.15.patch

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+	  /* calculate the pcrelative offset from current location */+	  pcrel_offset = symval;+	  pcrel_offset -= (sec->output_section->vma + sec->output_offset);+	  pcrel_offset += irel->r_addend;++	  /* we need to compute the pcrel_offset from this instruction+	   * ie the movhi */+	  pcrel_offset -= (irel->r_offset);++	  /* does this value fit in 16 bits */+	  if ((irelalign == NULL && (long) pcrel_offset <= 0x8008+	       && (long) pcrel_offset >= -0x8000) || (irelalign != NULL+						      && (long) pcrel_offset+						      <= 0x7ffc+						      && (long) pcrel_offset+						      >= -0x8000))+	    {+	      unsigned long opcode, op_a, op_b;+	      /* get the conditional branch opcode */+	      opcode = bfd_get_32 (abfd, contents + irel->r_offset - 4);+	      /* reverse the condition */+	      switch (opcode & OP_MASK_OP)+		{+		case OP_MATCH_BEQ:+		  opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BNE;+		  break;+		case OP_MATCH_BNE:+		  opcode = (opcode & ~OP_MASK_OP) | OP_MATCH_BEQ;+		  break;+		case OP_MATCH_BGE:+		case OP_MATCH_BGEU:+		case OP_MATCH_BLT:+		case OP_MATCH_BLTU:+		  /* swap the operands */+		  op_a = (opcode & OP_MASK_RRT) << 5;+		  op_b = (opcode & OP_MASK_RRS) >> 5;+		  opcode =+		    (opcode & ~(OP_MASK_RRS | OP_MASK_RRT)) | op_a | op_b;+		  break;+		default:+		  fprintf (stderr,+			   "relaxation error - expecting conditional branch, aborting\n");+		  abort ();+		  break;+		}++	      /* we must set the branch target to zero so that the skip over the jmp doesn't get+	       * added to the jmp */+	      opcode = opcode & (~OP_MASK_IMM16);++	      /* change the opcode to the reversed conditional branch */+	      bfd_put_32 (abfd, opcode, contents + irel->r_offset - 4);+	      /* Note that we've changed the relocs, section contents, etc.  */+	      elf_section_data (sec)->relocs = internal_relocs;+	      elf_section_data (sec)->this_hdr.contents = contents;+	      symtab_hdr->contents = (unsigned char *) isymbuf;++	      /* Fix the relocation's type.  */+	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),+					   R_NIOS2_PCREL16);++	      /* this relocation's offset has also been reduced by 4 bytes */+	      irel->r_offset -= 4;++	      /* replace next two instructions with nops */+	      bfd_put_32 (abfd, OP_MATCH_NOP, contents + irel->r_offset + 4);+	      bfd_put_32 (abfd, OP_MATCH_NOP, contents + irel->r_offset + 8);+	      bfd_put_32 (abfd, OP_MATCH_NOP, contents + irel->r_offset + 12);+	    }+	}++      /* otherwise, leave alone */+    }++  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)+    {+      if (!link_info->keep_memory)+	free (isymbuf);+      else+	{+	  /* Cache the symbols for elf_link_input_bfd.  */+	  symtab_hdr->contents = (unsigned char *) isymbuf;+	}+    }++  if (contents != NULL+      && elf_section_data (sec)->this_hdr.contents != contents)+    {+      if (!link_info->keep_memory)+	free (contents);+      else+	{+	  /* Cache the section contents for elf_link_input_bfd.  */+	  elf_section_data (sec)->this_hdr.contents = contents;+	}+    }++  if (internal_relocs != NULL+      && elf_section_data (sec)->relocs != internal_relocs)+    free (internal_relocs);+++  return TRUE;++error_return:+  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)+    free (isymbuf);+  if (contents != NULL+      && elf_section_data (sec)->this_hdr.contents != contents)+    free (contents);+  if (internal_relocs != NULL+      && elf_section_data (sec)->relocs != internal_relocs)+    free (internal_relocs);++  return FALSE;+}++/* Delete some bytes from a section while relaxing.+ * Copied from mn10200 port */++static bfd_boolean+nios2_elf32_relax_delete_bytes (bfd * abfd,+				asection * sec, bfd_vma addr, int count)+{+  Elf_Internal_Shdr *symtab_hdr;+  unsigned int sec_shndx;+  bfd_byte *contents;+  Elf_Internal_Rela *irel, *irelend;+  Elf_Internal_Rela *irelalign;+  bfd_vma toaddr;+  Elf_Internal_Sym *isym;+  Elf_Internal_Sym *isymend;+  struct elf_link_hash_entry **sym_hashes;+  struct elf_link_hash_entry **end_hashes;+  unsigned int symcount;+  asection *asec;++  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);++  contents = elf_section_data (sec)->this_hdr.contents;++  /* The deletion must stop at the next ALIGN reloc for an aligment+     power larger than the number of bytes we are deleting.  */++  irelalign = NULL;+  /* +1 because we need to readjust symbols at end of section */+  toaddr = sec->_cooked_size + 1;++  irel = elf_section_data (sec)->relocs;+  irelend = irel + sec->reloc_count;++  for (; irel < irelend; irel++)+    {+      if (ELF32_R_TYPE (irel->r_info) == (int) R_NIOS2_ALIGN+	  && irel->r_offset > addr && count < (1 << irel->r_addend))+	{+	  irelalign = irel;+	  /* +1 because we need to readjust symbols at end of section */+	  toaddr = irel->r_offset + 1;+	  break;+	}+    }+++  /* Actually delete the bytes.  */+  memmove (contents + addr, contents + addr + count,+	   (size_t) ((toaddr - 1) - addr - count));++  if (irelalign == NULL)+    sec->_cooked_size -= count;+  else+    {+      int i;++#define NOP_OPCODE  (0x0001883a)++      BFD_ASSERT ((count & 3) == 0);+      for (i = 0; i < count; i += 4)+	bfd_put_32 (abfd, (bfd_vma) NOP_OPCODE,+		    contents + (toaddr - 1) - count + i);+    }++  /* get the symbol table */+  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;+  isym = (Elf_Internal_Sym *) symtab_hdr->contents;++  /* Adjust all the reloc offsets in this section.  */+  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)+    {+      /* Get the new reloc address.  */+      if ((irel->r_offset > addr && irel->r_offset < toaddr))+	irel->r_offset -= count;+    }++  /* Adjust relocations against targets in this section whose positions+   * have moved as a result of the relaxation */++  for (asec = abfd->sections; asec; asec = asec->next)+    {+      irelend = elf_section_data (asec)->relocs + asec->reloc_count;+      for (irel = elf_section_data (asec)->relocs; irel < irelend; irel++)+	{+	  Elf_Internal_Sym *sym;+	  /* if the symbol which this reloc is against doesn't change+	   * we need to change the reloc addend */++	  sym = isym + ELF32_R_SYM (irel->r_info);+	  if (sym->st_shndx == sec_shndx+	      && !(sym->st_value > addr && sym->st_value < toaddr)+	      && sym->st_value + irel->r_addend > addr+	      && sym->st_value + irel->r_addend < toaddr)+	    {+	      irel->r_addend -= count;+	    }++	}+    }++  /* Adjust the local symbols defined in this section.  */+  for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)+    {+      if (isym->st_shndx == sec_shndx+	  && isym->st_value > addr && isym->st_value < toaddr)+	isym->st_value -= count;+++    }++  /* Now adjust the global symbols defined in this section.  */+  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)+	      - symtab_hdr->sh_info);+  sym_hashes = elf_sym_hashes (abfd);+  end_hashes = sym_hashes + symcount;+  for (; sym_hashes < end_hashes; sym_hashes++)+    {+      struct elf_link_hash_entry *sym_hash = *sym_hashes;+      if ((sym_hash->root.type == bfd_link_hash_defined+	   || sym_hash->root.type == bfd_link_hash_defweak)+	  && sym_hash->root.u.def.section == sec+	  && sym_hash->root.u.def.value > addr+	  && sym_hash->root.u.def.value < toaddr)+	{+	  sym_hash->root.u.def.value -= count;+	}+    }++  return TRUE;+}++struct bfd_link_info *nios2_link_info = NULL;++void+_bfd_set_link_info (info)+     struct bfd_link_info *info;+{+  nios2_link_info = info;+}++bfd_boolean linker_force_make_executable = FALSE;++void+_bfd_set_force_make_executable (force)+     bfd_boolean force;+{+  linker_force_make_executable = force;+}++/* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a+   dangerous relocation.  */++static bfd_boolean+nios2_elf_assign_gp (bfd *output_bfd, bfd_vma *pgp, struct bfd_link_info *info)+{++  bfd_boolean gp_found;+  struct bfd_hash_entry *h;+  struct bfd_link_hash_entry *lh;++  /* If we've already figured out what GP will be, just return it. */+  *pgp = _bfd_get_gp_value (output_bfd);+  if (*pgp)+    return TRUE;++  h = bfd_hash_lookup (&info->hash->table, "_gp", FALSE, FALSE);+  lh = (struct bfd_link_hash_entry *) h;+lookup:+  if (lh)+    {+      switch (lh->type)+	{+	case bfd_link_hash_undefined:+	case bfd_link_hash_undefweak:+	case bfd_link_hash_common:+	  gp_found = FALSE;+	  break;+	case bfd_link_hash_defined:+	case bfd_link_hash_defweak:+	  gp_found = TRUE;+	  *pgp = lh->u.def.value;+	  break;+	case bfd_link_hash_indirect:+	case bfd_link_hash_warning:+	  lh = lh->u.i.link;+	  /* @@FIXME  ignoring warning for now */+	  goto lookup;+	case bfd_link_hash_new:+	default:+	  abort ();+	}+    }+  else+    gp_found = FALSE;++  if (!gp_found)+    {+      /* Only get the error once. */+      *pgp = 4;+      _bfd_set_gp_value (output_bfd, *pgp);+      return FALSE;+    }++  _bfd_set_gp_value (output_bfd, *pgp);++  return TRUE;+}++/* We have to figure out the gp value, so that we can adjust the+   symbol value correctly.  We look up the symbol _gp in the output+   BFD.  If we can't find it, we're stuck.  We cache it in the ELF+   target data.  We don't need to adjust the symbol value for an+   external symbol if we are producing relocatable output.  */++static bfd_reloc_status_type+nios2_elf_final_gp (bfd *output_bfd, asymbol *symbol, bfd_boolean relocatable, +                    char **error_message, bfd_vma *pgp, struct bfd_link_info *info)+{+  if (bfd_is_und_section (symbol->section) && !relocatable)+    {+      *pgp = 0;+      return bfd_reloc_undefined;+    }++  *pgp = _bfd_get_gp_value (output_bfd);+  if (*pgp == 0 && (!relocatable || (symbol->flags & BSF_SECTION_SYM) != 0))+    {+      /* if this is called without link_info, then+         we cannot be doing a final link */+      if (info == NULL)+	relocatable = TRUE;++      if (relocatable)+	{+	  /* Make up a value.  */+	  *pgp = symbol->section->output_section->vma + 0x4000;+	  _bfd_set_gp_value (output_bfd, *pgp);+	}+      else if (!nios2_elf_assign_gp (output_bfd, pgp, info))+	{+	  *error_message =+	    (char *)+	    _("global pointer relative relocation when _gp not defined");+	  return bfd_reloc_dangerous;+	}+    }++  return bfd_reloc_ok;+}+++/* Relocations that require special handling */++/* This is for relocations used only when relaxing to ensure+ * changes in size of section don't screw up .align */+static bfd_reloc_status_type+nios2_elf32_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,+     asymbol *symbol ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED,+     asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)+{+  if (output_bfd != NULL)+    reloc_entry->address += input_section->output_offset;+  return bfd_reloc_ok;+}++static bfd_reloc_status_type+nios2_elf32_hi16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol, void *data,+     asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)+{+  /* This part is from bfd_elf_generic_reloc.  */+  if (output_bfd != (bfd *) NULL+      && (symbol->flags & BSF_SECTION_SYM) == 0+      && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))+    {+      reloc_entry->address += input_section->output_offset;+      return bfd_reloc_ok;+    }++  if (output_bfd != NULL)+    /* FIXME: See bfd_perform_relocation.  Is this right?  */+    return bfd_reloc_ok;++  return nios2_elf32_do_hi16_relocate (abfd, reloc_entry->howto,+				       input_section,+				       data, reloc_entry->address,+				       (symbol->value+					+ symbol->section->output_section->vma+					+ symbol->section->output_offset),+				       reloc_entry->addend);+}++static bfd_reloc_status_type+nios2_elf32_lo16_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,+     void *data, asection *input_section, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)+{+/* This part is from bfd_elf_generic_reloc.  */+  if (output_bfd != (bfd *) NULL+      && (symbol->flags & BSF_SECTION_SYM) == 0+      && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))+    {+      reloc_entry->address += input_section->output_offset;+      return bfd_reloc_ok;+    }++  if (output_bfd != NULL)+    /* FIXME: See bfd_perform_relocation.  Is this right?  */+    return bfd_reloc_ok;++  return nios2_elf32_do_lo16_relocate (abfd, reloc_entry->howto,+				       input_sectio

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -