-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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
+ 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., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
- {
- bfd_put_8 (abfd, code, contents + offset);
- bfd_put_8 (abfd, new_value, contents + offset + 1);
- if (start_offset != offset)
- {
- m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
- offset - start_offset);
- end_group--;
- }
- }
+ {
+ bfd_put_8 (abfd, code, contents + offset);
+ bfd_put_8 (abfd, new_value, contents + offset + 1);
+ if (start_offset != offset)
+ {
+ m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
+ offset - start_offset);
+ end_group--;
+ }
+ }
- This affects the layout of next input sections that go in our
- output section. When the symbol is part of another section that
- will go in the same output section as the current one, it's
- final address may now be incorrect (too far). We must let the
- linker re-compute all section offsets before processing this
- reloc. Code example:
-
- Initial Final
- .sect .text section size = 6 section size = 4
- jmp foo
- jmp bar
- .sect .text.foo_bar output_offset = 6 output_offset = 4
- foo: rts
- bar: rts
-
- If we process the reloc now, the jmp bar is replaced by a
- relative branch to the initial bar address (output_offset 6). */
+ This affects the layout of next input sections that go in our
+ output section. When the symbol is part of another section that
+ will go in the same output section as the current one, it's
+ final address may now be incorrect (too far). We must let the
+ linker re-compute all section offsets before processing this
+ reloc. Code example:
+
+ Initial Final
+ .sect .text section size = 6 section size = 4
+ jmp foo
+ jmp bar
+ .sect .text.foo_bar output_offset = 6 output_offset = 4
+ foo: rts
+ bar: rts
+
+ If we process the reloc now, the jmp bar is replaced by a
+ relative branch to the initial bar address (output_offset 6). */
- && prev_insn_branch)
- {
- bfd_vma offset;
- unsigned char code;
-
- offset = value - (prev_insn_branch->r_offset
- + sec->output_section->vma
- + sec->output_offset + 2);
-
- /* If the offset is still out of -128..+127 range,
- leave that far branch unchanged. */
- if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
- {
- prev_insn_branch = 0;
- continue;
- }
-
- /* Shrink the branch. */
- code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
- if (code == 0x7e)
- {
- code = 0x20;
- bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
- bfd_put_8 (abfd, 0xff,
- contents + prev_insn_branch->r_offset + 1);
- irel->r_offset = prev_insn_branch->r_offset + 1;
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_M68HC11_PCREL_8);
- m68hc11_elf_relax_delete_bytes (abfd, sec,
- irel->r_offset + 1, 1);
- }
- else
- {
- code ^= 0x1;
- bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
- bfd_put_8 (abfd, 0xff,
- contents + prev_insn_branch->r_offset + 1);
- irel->r_offset = prev_insn_branch->r_offset + 1;
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_M68HC11_PCREL_8);
- m68hc11_elf_relax_delete_bytes (abfd, sec,
- irel->r_offset + 1, 3);
- }
- prev_insn_branch = 0;
- *again = TRUE;
- }
+ && prev_insn_branch)
+ {
+ bfd_vma offset;
+ unsigned char code;
+
+ offset = value - (prev_insn_branch->r_offset
+ + sec->output_section->vma
+ + sec->output_offset + 2);
+
+ /* If the offset is still out of -128..+127 range,
+ leave that far branch unchanged. */
+ if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
+ {
+ prev_insn_branch = 0;
+ continue;
+ }
+
+ /* Shrink the branch. */
+ code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
+ if (code == 0x7e)
+ {
+ code = 0x20;
+ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
+ bfd_put_8 (abfd, 0xff,
+ contents + prev_insn_branch->r_offset + 1);
+ irel->r_offset = prev_insn_branch->r_offset + 1;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1);
+ }
+ else
+ {
+ code ^= 0x1;
+ bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
+ bfd_put_8 (abfd, 0xff,
+ contents + prev_insn_branch->r_offset + 1);
+ irel->r_offset = prev_insn_branch->r_offset + 1;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 3);
+ }
+ prev_insn_branch = 0;
+ *again = TRUE;
+ }
- unsigned char code;
- unsigned short offset;
- struct m68hc11_direct_relax *rinfo;
-
- prev_insn_branch = 0;
- offset = bfd_get_16 (abfd, contents + irel->r_offset);
- offset += value;
- if ((offset & 0xff00) != 0)
- {
- prev_insn_group = 0;
- continue;
- }
-
- if (prev_insn_group)
- {
- unsigned long old_sec_size = sec->size;
-
- /* Note that we've changed the relocation contents, etc. */
- elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
- elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- symtab_hdr->contents = (bfd_byte *) isymbuf;
- free_extsyms = NULL;
-
- m68hc11_relax_group (abfd, sec, contents, offset,
- prev_insn_group->r_offset,
- insn_group_value);
- irel = prev_insn_group;
- prev_insn_group = 0;
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_M68HC11_NONE);
- if (sec->size != old_sec_size)
- *again = TRUE;
- continue;
- }
-
- /* Get the opcode. */
- code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
- rinfo = find_relaxable_insn (code);
- if (rinfo == 0)
- {
- prev_insn_group = 0;
- continue;
- }
-
- /* Note that we've changed the relocation contents, etc. */
- elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
- elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- symtab_hdr->contents = (bfd_byte *) isymbuf;
- free_extsyms = NULL;
-
- /* Fix the opcode. */
- /* printf ("A relaxable case : 0x%02x (%s)\n",
- code, rinfo->name); */
- bfd_put_8 (abfd, rinfo->direct_code,
- contents + irel->r_offset - 1);
-
- /* Delete one byte of data (upper byte of address). */
- m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
-
- /* Fix the relocation's type. */
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_M68HC11_8);
-
- /* That will change things, so, we should relax again. */
- *again = TRUE;
- }
+ unsigned char code;
+ unsigned short offset;
+ struct m68hc11_direct_relax *rinfo;
+
+ prev_insn_branch = 0;
+ offset = bfd_get_16 (abfd, contents + irel->r_offset);
+ offset += value;
+ if ((offset & 0xff00) != 0)
+ {
+ prev_insn_group = 0;
+ continue;
+ }
+
+ if (prev_insn_group)
+ {
+ unsigned long old_sec_size = sec->size;
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) isymbuf;
+ free_extsyms = NULL;
+
+ m68hc11_relax_group (abfd, sec, contents, offset,
+ prev_insn_group->r_offset,
+ insn_group_value);
+ irel = prev_insn_group;
+ prev_insn_group = 0;
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_NONE);
+ if (sec->size != old_sec_size)
+ *again = TRUE;
+ continue;
+ }
+
+ /* Get the opcode. */
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ rinfo = find_relaxable_insn (code);
+ if (rinfo == 0)
+ {
+ prev_insn_group = 0;
+ continue;
+ }
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) isymbuf;
+ free_extsyms = NULL;
+
+ /* Fix the opcode. */
+ /* printf ("A relaxable case : 0x%02x (%s)\n",
+ code, rinfo->name); */
+ bfd_put_8 (abfd, rinfo->direct_code,
+ contents + irel->r_offset - 1);
+
+ /* Delete one byte of data (upper byte of address). */
+ m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
+
+ /* Fix the relocation's type. */
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_8);
+
+ /* That will change things, so, we should relax again. */
+ *again = TRUE;
+ }
- {
- unsigned char code;
- bfd_vma offset;
-
- prev_insn_branch = 0;
- code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
- if (code == 0x7e || code == 0xbd)
- {
- offset = value - (irel->r_offset
- + sec->output_section->vma
- + sec->output_offset + 1);
- offset += bfd_get_16 (abfd, contents + irel->r_offset);
-
- /* If the offset is still out of -128..+127 range,
- leave that far branch unchanged. */
- if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
- {
-
- /* Note that we've changed the relocation contents, etc. */
- elf_section_data (sec)->relocs = internal_relocs;
- free_relocs = NULL;
-
- elf_section_data (sec)->this_hdr.contents = contents;
- free_contents = NULL;
-
- symtab_hdr->contents = (bfd_byte *) isymbuf;
- free_extsyms = NULL;
-
- /* Shrink the branch. */
- code = (code == 0x7e) ? 0x20 : 0x8d;
- bfd_put_8 (abfd, code,
- contents + irel->r_offset - 1);
- bfd_put_8 (abfd, 0xff,
- contents + irel->r_offset);
- irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
- R_M68HC11_PCREL_8);
- m68hc11_elf_relax_delete_bytes (abfd, sec,
- irel->r_offset + 1, 1);
- /* That will change things, so, we should relax again. */
- *again = TRUE;
- }
- }
- }
+ {
+ unsigned char code;
+ bfd_vma offset;
+
+ prev_insn_branch = 0;
+ code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
+ if (code == 0x7e || code == 0xbd)
+ {
+ offset = value - (irel->r_offset
+ + sec->output_section->vma
+ + sec->output_offset + 1);
+ offset += bfd_get_16 (abfd, contents + irel->r_offset);
+
+ /* If the offset is still out of -128..+127 range,
+ leave that far branch unchanged. */
+ if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
+ {
+
+ /* Note that we've changed the relocation contents, etc. */
+ elf_section_data (sec)->relocs = internal_relocs;
+ free_relocs = NULL;
+
+ elf_section_data (sec)->this_hdr.contents = contents;
+ free_contents = NULL;
+
+ symtab_hdr->contents = (bfd_byte *) isymbuf;
+ free_extsyms = NULL;
+
+ /* Shrink the branch. */
+ code = (code == 0x7e) ? 0x20 : 0x8d;
+ bfd_put_8 (abfd, code,
+ contents + irel->r_offset - 1);
+ bfd_put_8 (abfd, 0xff,
+ contents + irel->r_offset);
+ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+ R_M68HC11_PCREL_8);
+ m68hc11_elf_relax_delete_bytes (abfd, sec,
+ irel->r_offset + 1, 1);
+ /* That will change things, so, we should relax again. */
+ *again = TRUE;
+ }
+ }
+ }
- code = bfd_get_8 (abfd, contents + irel->r_offset);
- switch (code)
- {
- /* jsr and jmp instruction are also marked with RL_JUMP
- relocs but no adjustment must be made. */
- case 0x7e:
- case 0x9d:
- case 0xbd:
- continue;
-
- case 0x12:
- case 0x13:
- branch_pos = 3;
- raddr = 4;
-
- /* Special case when we translate a brclr N,y into brclr *<addr>
- In this case, the 0x18 page2 prefix is removed.
- The reloc offset is not modified but the instruction
- size is reduced by 1. */
- if (old_offset == addr)
- raddr++;
- break;
-
- case 0x1e:
- case 0x1f:
- branch_pos = 3;
- raddr = 4;
- break;
-
- case 0x18:
- branch_pos = 4;
- raddr = 5;
- break;
-
- default:
- branch_pos = 1;
- raddr = 2;
- break;
- }
- offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
- raddr += old_offset;
- raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
- if (irel->r_offset < addr && raddr > addr)
- {
- offset -= count;
- bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
- }
- else if (irel->r_offset >= addr && raddr <= addr)
- {
- offset += count;
- bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
- }
- else
- {
- /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
- irel->r_offset, addr);*/
- }
-
- break;
+ code = bfd_get_8 (abfd, contents + irel->r_offset);
+ switch (code)
+ {
+ /* jsr and jmp instruction are also marked with RL_JUMP
+ relocs but no adjustment must be made. */
+ case 0x7e:
+ case 0x9d:
+ case 0xbd:
+ continue;
+
+ case 0x12:
+ case 0x13:
+ branch_pos = 3;
+ raddr = 4;
+
+ /* Special case when we translate a brclr N,y into brclr *<addr>
+ In this case, the 0x18 page2 prefix is removed.
+ The reloc offset is not modified but the instruction
+ size is reduced by 1. */
+ if (old_offset == addr)
+ raddr++;
+ break;
+
+ case 0x1e:
+ case 0x1f:
+ branch_pos = 3;
+ raddr = 4;
+ break;
+
+ case 0x18:
+ branch_pos = 4;
+ raddr = 5;
+ break;
+
+ default:
+ branch_pos = 1;
+ raddr = 2;
+ break;
+ }
+ offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
+ raddr += old_offset;
+ raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
+ if (irel->r_offset < addr && raddr > addr)
+ {
+ offset -= count;
+ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
+ }
+ else if (irel->r_offset >= addr && raddr <= addr)
+ {
+ offset += count;
+ bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
+ }
+ else
+ {
+ /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
+ irel->r_offset, addr);*/
+ }
+
+ break;
-static struct bfd_elf_special_section const
- m68hc11_special_sections_e[] =
-{
- { ".eeprom", 7, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- m68hc11_special_sections_s[]=
-{
- { ".softregs", 9, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- m68hc11_special_sections_p[]=
-{
- { ".page0", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const
- m68hc11_special_sections_v[]=
-{
- { ".vectors", 8, 0, SHT_PROGBITS, SHF_ALLOC },
- { NULL, 0, 0, 0, 0 }
-};
-
-static struct bfd_elf_special_section const *
- elf32_m68hc11_special_sections[27] =
+static const struct bfd_elf_special_section elf32_m68hc11_special_sections[] =
- NULL, /* 'a' */
- NULL, /* 'b' */
- NULL, /* 'c' */
- NULL, /* 'd' */
- m68hc11_special_sections_e, /* 'e' */
- NULL, /* 'f' */
- NULL, /* 'g' */
- NULL, /* 'h' */
- NULL, /* 'i' */
- NULL, /* 'j' */
- NULL, /* 'k' */
- NULL, /* 'l' */
- NULL, /* 'm' */
- NULL, /* 'n' */
- NULL, /* 'o' */
- m68hc11_special_sections_p, /* 'p' */
- NULL, /* 'q' */
- NULL, /* 'r' */
- m68hc11_special_sections_s, /* 's' */
- NULL, /* 't' */
- NULL, /* 'u' */
- m68hc11_special_sections_v, /* 'v' */
- NULL, /* 'w' */
- NULL, /* 'x' */
- NULL, /* 'y' */
- NULL, /* 'z' */
- NULL /* other */
+ { STRING_COMMA_LEN (".eeprom"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".page0"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE },
+ { STRING_COMMA_LEN (".vectors"), 0, SHT_PROGBITS, SHF_ALLOC },
+ { NULL, 0, 0, 0, 0 }