reloc.h 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #if __BYTE_ORDER == __LITTLE_ENDIAN
  2. #define ENDIAN_SUFFIX "l"
  3. #else
  4. #define ENDIAN_SUFFIX ""
  5. #endif
  6. #define LDSO_ARCH "sh" ENDIAN_SUFFIX
  7. #define IS_COPY(x) ((x) == R_SH_COPY)
  8. #define IS_PLT(x) ((x) == R_SH_JMP_SLOT)
  9. static inline void do_single_reloc(
  10. struct dso *self, unsigned char *base_addr,
  11. size_t *reloc_addr, int type, size_t addend,
  12. Sym *sym, size_t sym_size,
  13. struct symdef def, size_t sym_val)
  14. {
  15. switch(type) {
  16. case R_SH_GLOB_DAT:
  17. case R_SH_JMP_SLOT:
  18. *reloc_addr = sym_val;
  19. break;
  20. case R_SH_RELATIVE:
  21. *reloc_addr = (size_t)base_addr + addend;
  22. break;
  23. case R_SH_DIR32:
  24. *reloc_addr = sym_val + addend;
  25. break;
  26. case R_SH_REL32:
  27. *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr;
  28. break;
  29. case R_SH_COPY:
  30. memcpy(reloc_addr, (void *)sym_val, sym_size);
  31. break;
  32. case R_SH_TLS_DTPMOD32:
  33. *reloc_addr += def.dso ? def.dso->tls_id : self->tls_id;
  34. break;
  35. case R_SH_TLS_DTPOFF32:
  36. *reloc_addr += def.sym->st_value;
  37. break;
  38. case R_SH_TLS_TPOFF32:
  39. *reloc_addr += def.sym
  40. ? def.sym->st_value + def.dso->tls_offset + 8
  41. : self->tls_offset + 8;
  42. break;
  43. }
  44. }