#ifdef TARGET_DEFS_ONLY #define EM_TCC_TARGET EM_RISCV #define R_DATA_32 R_RISCV_32 #define R_DATA_PTR R_RISCV_64 #define R_JMP_SLOT R_RISCV_JUMP_SLOT #define R_GLOB_DAT R_RISCV_64 #define R_COPY R_RISCV_COPY #define R_RELATIVE R_RISCV_RELATIVE #define R_NUM R_RISCV_NUM #define ELF_START_ADDR 0x00010000 #define ELF_PAGE_SIZE 0x1000 #define PCRELATIVE_DLLPLT 1 #define RELOCATE_DLLPLT 1 #else /* !TARGET_DEFS_ONLY */ #include "tcc.h" /* Returns 1 for a code relocation, 0 for a data relocation. For unknown relocations, returns -1. */ int code_reloc (int reloc_type) { switch (reloc_type) { } tcc_error ("Unknown relocation type: %d", reloc_type); return -1; } /* Returns an enumerator to describe whether and when the relocation needs a GOT and/or PLT entry to be created. See tcc.h for a description of the different values. */ int gotplt_entry_type (int reloc_type) { switch (reloc_type) { } tcc_error ("Unknown relocation type: %d", reloc_type); return -1; } ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) { Section *plt = s1->plt; uint8_t *p; unsigned plt_offset; if (s1->output_type == TCC_OUTPUT_DLL) tcc_error("DLLs unimplemented!"); if (plt->data_offset == 0) section_ptr_add(plt, 32); plt_offset = plt->data_offset; p = section_ptr_add(plt, 16); write64le(p, got_offset); return plt_offset; } /* relocate the PLT: compute addresses and offsets in the PLT now that final address for PLT and GOT are known (see fill_program_header) */ ST_FUNC void relocate_plt(TCCState *s1) { uint8_t *p, *p_end; if (!s1->plt) return; p = s1->plt->data; p_end = p + s1->plt->data_offset; if (p < p_end) { uint64_t plt = s1->plt->sh_addr; uint64_t got = s1->got->sh_addr; uint64_t off = (got >> 12) - (plt >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); write32le(p, 0x0); write32le(p + 4, 0x0); write32le(p + 8, 0x0); write32le(p + 12, 0x0); write32le(p + 16, 0x0); write32le(p + 20, 0x0); write32le(p + 24, 0x0); write32le(p + 28, 0x0); p += 32; while (p < p_end) { uint64_t pc = plt + (p - s1->plt->data); uint64_t addr = got + read64le(p); uint64_t off = (addr >> 12) - (pc >> 12); if ((off + ((uint32_t)1 << 20)) >> 21) tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); write32le(p, 0x0); write32le(p + 4, 0x0); write32le(p + 8, 0x0); write32le(p + 12, 0x0); p += 16; } } } void relocate_init(Section *sr) {} void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) { int sym_index = ELFW(R_SYM)(rel->r_info); #ifdef DEBUG_RELOC ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; #endif switch(type) { default: fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", type, (unsigned)addr, ptr, (unsigned)val); return; } } #endif