elf32-sh.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,188 行 · 第 1/5 页
C
2,188 行
"R_SH_GNU_VTENTRY", /* name */ false, /* partial_inplace */ 0, /* src_mask */ 0, /* dst_mask */ false), /* pcrel_offset */ /* 8 bit PC relative divided by 2 - but specified in a very odd way. */ HOWTO (R_SH_LOOP_START, /* type */ 1, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ sh_elf_ignore_reloc, /* special_function */ "R_SH_LOOP_START", /* name */ true, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ true), /* pcrel_offset */ /* 8 bit PC relative divided by 2 - but specified in a very odd way. */ HOWTO (R_SH_LOOP_END, /* type */ 1, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ 8, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ sh_elf_ignore_reloc, /* special_function */ "R_SH_LOOP_END", /* name */ true, /* partial_inplace */ 0xff, /* src_mask */ 0xff, /* dst_mask */ true), /* pcrel_offset */ EMPTY_HOWTO (38), EMPTY_HOWTO (39), EMPTY_HOWTO (40), EMPTY_HOWTO (41), EMPTY_HOWTO (42), EMPTY_HOWTO (43), EMPTY_HOWTO (44), EMPTY_HOWTO (45), EMPTY_HOWTO (46), EMPTY_HOWTO (47), EMPTY_HOWTO (48), EMPTY_HOWTO (49), EMPTY_HOWTO (50), EMPTY_HOWTO (51), EMPTY_HOWTO (52), EMPTY_HOWTO (53), EMPTY_HOWTO (54), EMPTY_HOWTO (55), EMPTY_HOWTO (56), EMPTY_HOWTO (57), EMPTY_HOWTO (58), EMPTY_HOWTO (59), EMPTY_HOWTO (60), EMPTY_HOWTO (61), EMPTY_HOWTO (62), EMPTY_HOWTO (63), EMPTY_HOWTO (64), EMPTY_HOWTO (65), EMPTY_HOWTO (66), EMPTY_HOWTO (67), EMPTY_HOWTO (68), EMPTY_HOWTO (69), EMPTY_HOWTO (70), EMPTY_HOWTO (71), EMPTY_HOWTO (72), EMPTY_HOWTO (73), EMPTY_HOWTO (74), EMPTY_HOWTO (75), EMPTY_HOWTO (76), EMPTY_HOWTO (77), EMPTY_HOWTO (78), EMPTY_HOWTO (79), EMPTY_HOWTO (80), EMPTY_HOWTO (81), EMPTY_HOWTO (82), EMPTY_HOWTO (83), EMPTY_HOWTO (84), EMPTY_HOWTO (85), EMPTY_HOWTO (86), EMPTY_HOWTO (87), EMPTY_HOWTO (88), EMPTY_HOWTO (89), EMPTY_HOWTO (90), EMPTY_HOWTO (91), EMPTY_HOWTO (92), EMPTY_HOWTO (93), EMPTY_HOWTO (94), EMPTY_HOWTO (95), EMPTY_HOWTO (96), EMPTY_HOWTO (97), EMPTY_HOWTO (98), EMPTY_HOWTO (99), EMPTY_HOWTO (100), EMPTY_HOWTO (101), EMPTY_HOWTO (102), EMPTY_HOWTO (103), EMPTY_HOWTO (104), EMPTY_HOWTO (105), EMPTY_HOWTO (106), EMPTY_HOWTO (107), EMPTY_HOWTO (108), EMPTY_HOWTO (109), EMPTY_HOWTO (110), EMPTY_HOWTO (111), EMPTY_HOWTO (112), EMPTY_HOWTO (113), EMPTY_HOWTO (114), EMPTY_HOWTO (115), EMPTY_HOWTO (116), EMPTY_HOWTO (117), EMPTY_HOWTO (118), EMPTY_HOWTO (119), EMPTY_HOWTO (120), EMPTY_HOWTO (121), EMPTY_HOWTO (122), EMPTY_HOWTO (123), EMPTY_HOWTO (124), EMPTY_HOWTO (125), EMPTY_HOWTO (126), EMPTY_HOWTO (127), EMPTY_HOWTO (128), EMPTY_HOWTO (129), EMPTY_HOWTO (130), EMPTY_HOWTO (131), EMPTY_HOWTO (132), EMPTY_HOWTO (133), EMPTY_HOWTO (134), EMPTY_HOWTO (135), EMPTY_HOWTO (136), EMPTY_HOWTO (137), EMPTY_HOWTO (138), EMPTY_HOWTO (139), EMPTY_HOWTO (140), EMPTY_HOWTO (141), EMPTY_HOWTO (142), EMPTY_HOWTO (143), EMPTY_HOWTO (144), EMPTY_HOWTO (145), EMPTY_HOWTO (146), EMPTY_HOWTO (147), EMPTY_HOWTO (148), EMPTY_HOWTO (149), EMPTY_HOWTO (150), EMPTY_HOWTO (151), EMPTY_HOWTO (152), EMPTY_HOWTO (153), EMPTY_HOWTO (154), EMPTY_HOWTO (155), EMPTY_HOWTO (156), EMPTY_HOWTO (157), EMPTY_HOWTO (158), EMPTY_HOWTO (159), HOWTO (R_SH_GOT32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_GOT32", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_PLT32, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_PLT32", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ true), /* pcrel_offset */ HOWTO (R_SH_COPY, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_COPY", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_GLOB_DAT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_GLOB_DAT", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_JMP_SLOT, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_JMP_SLOT", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_RELATIVE, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_RELATIVE", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_GOTOFF, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_GOTOFF", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ false), /* pcrel_offset */ HOWTO (R_SH_GOTPC, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ 32, /* bitsize */ true, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* */ "R_SH_GOTPC", /* name */ true, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ true), /* pcrel_offset */};static bfd_reloc_status_typesh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr, symbol_section, start, end) int r_type ATTRIBUTE_UNUSED; bfd *input_bfd; asection *input_section; bfd_byte *contents; bfd_vma addr; asection *symbol_section; bfd_vma start, end;{ static bfd_vma last_addr; static asection *last_symbol_section; bfd_byte *free_contents = NULL; bfd_byte *start_ptr, *ptr, *last_ptr; int diff, cum_diff; bfd_signed_vma x; int insn; /* Sanity check the address. */ if (addr > input_section->_raw_size) return bfd_reloc_outofrange; /* We require the start and end relocations to be processed consecutively - although we allow then to be processed forwards or backwards. */ if (! last_addr) { last_addr = addr; last_symbol_section = symbol_section; return bfd_reloc_ok; } if (last_addr != addr) abort (); last_addr = 0; if (! symbol_section || last_symbol_section != symbol_section || end < start) return bfd_reloc_outofrange; /* Get the symbol_section contents. */ if (symbol_section != input_section) { if (elf_section_data (symbol_section)->this_hdr.contents != NULL) contents = elf_section_data (symbol_section)->this_hdr.contents; else { free_contents = contents = (bfd_byte *) bfd_malloc (symbol_section->_raw_size); if (contents == NULL) return bfd_reloc_outofrange; if (! bfd_get_section_contents (input_bfd, symbol_section, contents, (file_ptr) 0, symbol_section->_raw_size)) { free (contents); return bfd_reloc_outofrange; } } }#define IS_PPI(PTR) ((bfd_get_16 (input_bfd, (PTR)) & 0xfc00) == 0xf800) start_ptr = contents + start; for (cum_diff = -6, ptr = contents + end; cum_diff < 0 && ptr > start_ptr;) { for (last_ptr = ptr, ptr -= 4; ptr >= start_ptr && IS_PPI (ptr);) ptr -= 2; ptr += 2; diff = (last_ptr - ptr) >> 1; cum_diff += diff & 1; cum_diff += diff; } /* Calculate the start / end values to load into rs / re minus four - so that will cancel out the four we would otherwise have to add to addr to get the value to subtract in order to get relative addressing. */ if (cum_diff >= 0) { start -= 4; end = (ptr + cum_diff * 2) - contents; } else { bfd_vma start0 = start - 4; while (start0 && IS_PPI (contents + start0)) start0 -= 2; start0 = start - 2 - ((start - start0) & 2); start = start0 - cum_diff - 2; end = start0; } if (free_contents) free (free_contents); insn = bfd_get_16 (input_bfd, contents + addr); x = (insn & 0x200 ? end : start) - addr; if (input_section != symbol_section) x += ((symbol_section->output_section->vma + symbol_section->output_offset) - (input_section->output_section->vma + input_section->output_offset)); x >>= 1; if (x < -128 || x > 127) return bfd_reloc_overflow; x = (insn & ~0xff) | (x & 0xff); bfd_put_16 (input_bfd, x, contents + addr); return bfd_reloc_ok;}/* This function is used for normal relocs. This used to be like the COFF function, and is almost certainly incorrect for other ELF targets. */static bfd_reloc_status_typesh_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; asymbol *symbol_in; PTR data; asection *input_section; bfd *output_bfd; char **error_message ATTRIBUTE_UNUSED;{ unsigned long insn; bfd_vma sym_value; enum elf_sh_reloc_type r_type; bfd_vma addr = reloc_entry->address; bfd_byte *hit_data = addr + (bfd_byte *) data; r_type = (enum elf_sh_reloc_type) reloc_entry->howto->type; if (output_bfd != NULL) { /* Partial linking--do nothing. */ reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; } /* Almost all relocs have to do with relaxing. If any work must be done for them, it has been done in sh_relax_section. */ if (r_type == R_SH_IND12W && (symbol_in->flags & BSF_LOCAL) != 0) return bfd_reloc_ok; if (symbol_in != NULL && bfd_is_und_section (symbol_in->section)) return bfd_reloc_undefined; if (bfd_is_com_section (symbol_in->section)) sym_value = 0; else sym_value = (symbol_in->value + symbol_in->section->output_section->vma + symbol_in->section->output_offset); switch (r_type) { case R_SH_DIR32: insn = bfd_get_32 (abfd, hit_data); insn += sym_value + reloc_entry->addend; bfd_put_32 (abfd, insn, hit_data); break; case R_SH_IND12W: insn = bfd_get_16 (abfd, hit_data); sym_value += reloc_entry->addend; sym_value -= (input_section->output_section->vma + input_section->output_offset
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?