aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandrewchambers <[email protected]>2021-10-11 11:04:45 +1300
committerGitHub <[email protected]>2021-10-11 11:04:45 +1300
commiteb7790fa6db6b15ac1867256369ac524cf9ce622 (patch)
tree8935779fec3113b8987b1dfd4a3d477ee57e37a3
parent68a4c3dade355dccefe9d17c51374a95ccc8e5c4 (diff)
parent35e288326d5440d43b06fcd273fa069f22134eb8 (diff)
Merge pull request #3 from michaelforney/rela
Use Elf64_Rela for relocations.
-rw-r--r--main.c23
-rw-r--r--minias.h1
2 files changed, 13 insertions, 11 deletions
diff --git a/main.c b/main.c
index 4b60a86..1b0f071 100644
--- a/main.c
+++ b/main.c
@@ -136,16 +136,18 @@ static void initsections(void) {
text->hdr.sh_addralign = 4;
textrel = newsection();
- textrel->hdr.sh_type = SHT_REL;
+ textrel->hdr.sh_name = elfstr(shstrtab, ".rela.text");
+ textrel->hdr.sh_type = SHT_RELA;
textrel->hdr.sh_info = text->idx;
textrel->hdr.sh_link = symtab->idx;
- textrel->hdr.sh_entsize = sizeof(Elf64_Rel);
+ textrel->hdr.sh_entsize = sizeof(Elf64_Rela);
datarel = newsection();
- datarel->hdr.sh_type = SHT_REL;
+ datarel->hdr.sh_name = elfstr(shstrtab, ".rela.data");
+ datarel->hdr.sh_type = SHT_RELA;
datarel->hdr.sh_info = data->idx;
datarel->hdr.sh_link = symtab->idx;
- datarel->hdr.sh_entsize = sizeof(Elf64_Rel);
+ datarel->hdr.sh_entsize = sizeof(Elf64_Rela);
}
Relocation *newreloc() {
@@ -415,6 +417,8 @@ static void assemblereloc(const char *l, int64_t c, int nbytes, int type) {
reloc->section = cursection;
reloc->sym = sym;
reloc->offset = cursection->hdr.sh_size;
+ reloc->addend = c;
+ c = 0;
}
assembleconstant(c, nbytes);
}
@@ -1035,9 +1039,7 @@ static void resolvereloc(Relocation *reloc) {
switch (reloc->type) {
case R_X86_64_32: {
rdata = &reloc->section->data[reloc->offset];
- addend = (int32_t)rdata[0] | (int32_t)(rdata[1] << 8) |
- (int32_t)(rdata[2] << 16) | (int32_t)(rdata[3] << 24);
- value = sym->offset - reloc->offset + addend;
+ value = sym->offset - reloc->offset + reloc->addend;
rdata[0] = ((uint32_t)value & 0xff);
rdata[1] = ((uint32_t)value & 0xff00) >> 8;
rdata[2] = ((uint32_t)value & 0xff0000) >> 16;
@@ -1046,9 +1048,7 @@ static void resolvereloc(Relocation *reloc) {
}
case R_X86_64_PC32: {
rdata = &reloc->section->data[reloc->offset];
- addend = (int32_t)rdata[0] | (int32_t)(rdata[1] << 8) |
- (int32_t)(rdata[2] << 16) | (int32_t)(rdata[3] << 24);
- value = sym->offset - reloc->offset + addend;
+ value = sym->offset - reloc->offset + reloc->addend;
rdata[0] = ((uint32_t)value & 0xff);
rdata[1] = ((uint32_t)value & 0xff00) >> 8;
rdata[2] = ((uint32_t)value & 0xff0000) >> 16;
@@ -1063,7 +1063,7 @@ static void resolvereloc(Relocation *reloc) {
static void appendreloc(Relocation *reloc) {
Symbol *sym;
Section *relsection;
- Elf64_Rel elfrel;
+ Elf64_Rela elfrel;
memset(&elfrel, 0, sizeof(elfrel));
@@ -1080,6 +1080,7 @@ static void appendreloc(Relocation *reloc) {
case R_X86_64_32:
elfrel.r_info = ELF64_R_INFO(sym->idx, reloc->type);
elfrel.r_offset = reloc->offset;
+ elfrel.r_addend = reloc->addend;
break;
default:
unreachable();
diff --git a/minias.h b/minias.h
index abf1f06..750f481 100644
--- a/minias.h
+++ b/minias.h
@@ -35,6 +35,7 @@ typedef struct {
Symbol *sym;
int type;
int64_t offset;
+ int64_t addend;
} Relocation;
typedef enum {