Skip to content

Commit

Permalink
Handle relocation for the target architecture only
Browse files Browse the repository at this point in the history
  • Loading branch information
tyfkda committed Jul 14, 2024
1 parent 03c934f commit 35474c3
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 94 deletions.
6 changes: 6 additions & 0 deletions include/inttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@

#if defined(__ILP32__)

#define PRId32 "ld"
#define PRIu32 "lu"
#define PRIx32 "lx"
#define PRId64 "lld"
#define PRIu64 "llu"
#define PRIx64 "llx"

#elif defined(__LP64__)

#define PRId32 "d"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRId64 "ld"
#define PRIu64 "lu"
#define PRIx64 "lx"
Expand Down
106 changes: 63 additions & 43 deletions src/as/emit_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,36 +153,16 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
UnresolvedInfo *u = unresolved->data[i];
Elf64_Rela *rela = &rela_bufs[u->src_section][rela_counts[u->src_section]++];
switch (u->kind) {
case UNRES_EXTERN:
case UNRES_EXTERN_PC32:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(symidx, u->kind == UNRES_EXTERN_PC32 ? R_X86_64_PC32
: R_X86_64_PLT32);
rela->r_addend = u->add;
}
break;
case UNRES_OTHER_SECTION:
{
LabelInfo *label = table_get(label_table, u->label);
assert(label != NULL);
int secidx = label->section + 1;
rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(secidx, R_X86_64_PC32);
rela->r_addend = u->add;
}
break;
case UNRES_ABS64:
{
#if XCC_TARGET_ARCH == XCC_ARCH_RISCV64
const int type = R_RISCV_64;
#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64
const int type = R_AARCH64_ABS64;
#else // #elif XCC_TARGET_ARCH == XCC_ARCH_X64
#elif XCC_TARGET_ARCH == XCC_ARCH_X64
const int type = R_X86_64_64;
#else
assert(false);
#endif
LabelInfo *label = table_get(label_table, u->label);
if (label == NULL || label->flag & (LF_GLOBAL | LF_REFERRED)) {
Expand All @@ -199,32 +179,55 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
}
}
break;
case UNRES_RISCV_BRANCH:
case UNRES_RISCV_RVC_BRANCH:

#if XCC_TARGET_ARCH == XCC_ARCH_X64
case UNRES_EXTERN:
case UNRES_EXTERN_PC32:
{
Elf64_Sym *sym = symtab_add(symtab, u->label);
size_t index = sym - symtab->buf;
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(index, u->kind == UNRES_RISCV_RVC_BRANCH ? R_RISCV_RVC_BRANCH
: R_RISCV_BRANCH);
rela->r_info = ELF64_R_INFO(symidx, u->kind == UNRES_EXTERN_PC32 ? R_X86_64_PC32
: R_X86_64_PLT32);
rela->r_addend = u->add;
}
break;
case UNRES_OTHER_SECTION:
{
LabelInfo *label = table_get(label_table, u->label);
assert(label != NULL);
int secidx = label->section + 1;
rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(secidx, R_X86_64_PC32);
rela->r_addend = u->add;
}
break;

// case UNRES_X64_GOT_LOAD:
// assert(!"TODO");
// break;

#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64
case UNRES_CALL:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
#if XCC_TARGET_ARCH == XCC_ARCH_RISCV64
rela->r_info = ELF64_R_INFO(symidx, R_RISCV_CALL);
#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64
rela->r_info = ELF64_R_INFO(symidx, R_AARCH64_CALL26);
#else
assert(false);
#endif
rela->r_addend = u->add;
}
break;

case UNRES_PCREL_HI:
case UNRES_PCREL_LO:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(symidx, u->kind == UNRES_PCREL_HI ? R_AARCH64_ADR_PREL_PG_HI21 : R_AARCH64_ADD_ABS_LO12_NC);
rela->r_addend = u->add;
}
break;
Expand All @@ -249,28 +252,42 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
}
break;

#elif XCC_TARGET_ARCH == XCC_ARCH_RISCV64
case UNRES_PCREL_HI:
case UNRES_PCREL_LO:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
#if XCC_TARGET_ARCH == XCC_ARCH_RISCV64
rela->r_info = ELF64_R_INFO(symidx, u->kind == UNRES_PCREL_HI ? R_RISCV_PCREL_HI20 : R_RISCV_PCREL_LO12_I);
#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64
rela->r_info = ELF64_R_INFO(symidx, u->kind == UNRES_PCREL_HI ? R_AARCH64_ADR_PREL_PG_HI21 : R_AARCH64_ADD_ABS_LO12_NC);
#else
assert(false);
#endif
rela->r_addend = u->add;
}
break;

case UNRES_X64_GOT_LOAD:
assert(!"TODO");
case UNRES_CALL:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(symidx, R_RISCV_CALL);
rela->r_addend = u->add;
}
break;

case UNRES_RISCV_BRANCH:
case UNRES_RISCV_RVC_BRANCH:
{
Elf64_Sym *sym = symtab_add(symtab, u->label);
size_t index = sym - symtab->buf;

rela->r_offset = u->offset;
rela->r_info = ELF64_R_INFO(index, u->kind == UNRES_RISCV_RVC_BRANCH ? R_RISCV_RVC_BRANCH
: R_RISCV_BRANCH);
rela->r_addend = u->add;
}
break;
case UNRES_RISCV_JAL:
case UNRES_RISCV_RVC_JUMP:
{
Expand All @@ -289,6 +306,9 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
rela->r_addend = u->add;
}
break;
#endif

default: assert(false); break;
}
}
}
Expand Down
71 changes: 27 additions & 44 deletions src/as/emit_macho.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,31 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
UnresolvedInfo *u = unresolved->data[i];
struct relocation_info *rela = &rela_bufs[u->src_section][rela_counts[u->src_section]++];
switch (u->kind) {
case UNRES_ABS64:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

rela->r_address = u->offset;
rela->r_symbolnum = symidx;
rela->r_pcrel = 0;
rela->r_length = 3;
rela->r_extern = 1;
#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64
rela->r_type = ARM64_RELOC_UNSIGNED;
#elif XCC_TARGET_ARCH == XCC_ARCH_X64
rela->r_type = X86_64_RELOC_UNSIGNED;
#else
assert(false);
#endif
}
break;

#if XCC_TARGET_ARCH == XCC_ARCH_X64
case UNRES_EXTERN:
case UNRES_EXTERN_PC32:
case UNRES_OTHER_SECTION:
{
#if XCC_TARGET_ARCH == XCC_ARCH_X64
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

Expand All @@ -139,34 +159,26 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
rela->r_length = 2;
rela->r_extern = 1;
rela->r_type = u->kind == UNRES_OTHER_SECTION ? X86_64_RELOC_SIGNED : X86_64_RELOC_BRANCH;
#else
assert(false);
#endif
}
break;
case UNRES_ABS64:
case UNRES_X64_GOT_LOAD:
{
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

// assert(u->add == 0);
rela->r_address = u->offset;
rela->r_symbolnum = symidx;
rela->r_pcrel = 0;
rela->r_length = 3;
rela->r_pcrel = 1;
rela->r_length = 2;
rela->r_extern = 1;
#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64
rela->r_type = ARM64_RELOC_UNSIGNED;
#elif XCC_TARGET_ARCH == XCC_ARCH_X64
rela->r_type = X86_64_RELOC_UNSIGNED;
#else
assert(false);
#endif
rela->r_type = X86_64_RELOC_GOT_LOAD;
}
break;

#elif XCC_TARGET_ARCH == XCC_ARCH_AARCH64
case UNRES_CALL:
{
#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

Expand All @@ -177,16 +189,12 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
rela->r_length = 2;
rela->r_extern = 1;
rela->r_type = ARM64_RELOC_BRANCH26;
#else
assert(false);
#endif
}
break;

case UNRES_GOT_HI:
case UNRES_GOT_LO:
{
#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64
LabelInfo *label = table_get(label_table, u->label);
assert(label != NULL);
int symidx = symtab_find(symtab, u->label);
Expand All @@ -199,16 +207,12 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
rela->r_length = 2;
rela->r_extern = 1;
rela->r_type = u->kind == UNRES_GOT_HI ? ARM64_RELOC_GOT_LOAD_PAGE21 : ARM64_RELOC_GOT_LOAD_PAGEOFF12;
#else
assert(false);
#endif
}
break;

case UNRES_PCREL_HI:
case UNRES_PCREL_LO:
{
#if XCC_TARGET_ARCH == XCC_ARCH_AARCH64
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

Expand All @@ -229,30 +233,9 @@ static void construct_relas(Vector *unresolved, Symtab *symtab, Table *label_tab
rela2->r_extern = 0;
rela2->r_type = ARM64_RELOC_ADDEND;
}
#else
assert(false);
#endif
}
break;

case UNRES_X64_GOT_LOAD:
{
#if XCC_TARGET_ARCH == XCC_ARCH_X64
int symidx = symtab_find(symtab, u->label);
assert(symidx >= 0);

// assert(u->add == 0);
rela->r_address = u->offset;
rela->r_symbolnum = symidx;
rela->r_pcrel = 1;
rela->r_length = 2;
rela->r_extern = 1;
rela->r_type = X86_64_RELOC_GOT_LOAD;
#else
assert(false);
#endif
}
break;

default: assert(false); break;
}
Expand Down
Loading

0 comments on commit 35474c3

Please sign in to comment.