Skip to content

Commit 8c2b0ec

Browse files
committed
* add macos support; no VMA filtering
* add macos REL sample
1 parent e9aba33 commit 8c2b0ec

File tree

9 files changed

+224
-60
lines changed

9 files changed

+224
-60
lines changed

Makefile

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,31 @@ CXXFLAGS += -std=c++11 -Ofast -fno-exceptions -fno-rtti -DNDEBUG -DPAGE_SIZE=$(s
55
LDFLAGS += -lelf
66
ASFLAGS += --strip-local-absolute
77
# Optional test objects built by target ALL
8-
REL := test_rodata.o \
9-
test_data.o \
10-
test_bss.o \
11-
test_cross_0.o \
12-
test_cross_1.o \
13-
test_bounce.o \
14-
test_bounce_neon.o \
15-
test_bounce_neon_aosoa.o \
16-
test_bounce_neon_aosoa_bg.o \
17-
test_bounce_data_aosoa_alt_0.o \
18-
test_bounce_data_aosoa_alt_1.o \
19-
test_bounce_data_aosoa_alt_2.o \
20-
test_bounce_data_aosoa_alt_3.o
8+
REL := test_text.o \
9+
test_rodata.o \
10+
test_data.o \
11+
test_bss.o \
12+
test_cross_0.o \
13+
test_cross_1.o \
14+
test_bounce.o \
15+
test_bounce_neon.o \
16+
test_bounce_neon_aosoa.o \
17+
test_bounce_neon_aosoa_bg.o \
18+
test_bounce_data_aosoa_alt_0.o \
19+
test_bounce_data_aosoa_alt_1.o \
20+
test_bounce_data_aosoa_alt_2.o \
21+
test_bounce_data_aosoa_alt_3.o
2122

2223
OBJ := $(addsuffix .o, $(basename $(filter %.s %.c %.cpp, $(SRC))))
2324

2425
$(TARGET): $(OBJ)
2526
$(CC) $^ $(LDFLAGS) -o $(TARGET)
2627

27-
reloc.o: reloc.c vma.h
28+
reloc.o: reloc.c vma.h char_ptr_arr.h
2829

2930
reloc_add_aarch64.o: reloc_add_aarch64.c insn.h
3031

31-
vma.o: vma.cpp vma.h
32+
vma.o: vma.cpp vma.h char_ptr_arr.h
3233

3334
test_bounce.o: test_bounce.s
3435
$(AS) $(ASFLAGS) --defsym FB_DIM_X=$(shell tput cols) --defsym FB_DIM_Y=$(shell tput lines) --defsym FRAMES=1024 -o $@ $^

Makefile.macos

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
SRC := reloc.c reloc_add_aarch64.c insn.h
2+
TARGET := elvenrel
3+
CFLAGS += -std=gnu11 -Ofast -DNDEBUG -DPAGE_SIZE=$(shell getconf PAGE_SIZE) -fno-stack-protector -fPIC -I/opt/homebrew/include
4+
LDFLAGS += /opt/homebrew/lib/libelf.a
5+
ASFLAGS += --target=aarch64-none-linux-gnu
6+
# Optional test objects built by target ALL
7+
REL := test_text_macos.o
8+
9+
OBJ := $(addsuffix .o, $(basename $(filter %.s %.c %.cpp, $(SRC))))
10+
11+
$(TARGET): $(OBJ)
12+
$(CC) $^ $(LDFLAGS) -o $(TARGET)
13+
14+
reloc.o: reloc.c char_ptr_arr.h
15+
16+
reloc_add_aarch64.o: reloc_add_aarch64.c insn.h
17+
18+
all: $(TARGET) $(REL)
19+
20+
clean:
21+
rm -f $(TARGET) $(OBJ) $(REL)

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
## elvenrel
22

3-
Elven Relativism -- relocation and execution of aarch64 ELF relocatable objects (REL)
3+
Elven Relativism -- relocation and execution of aarch64 ELF relocatable objects (REL) on Linux and macOS.
44

55
Program loads a multitude of ELF REL files, resolves all relocations (currently only SHT_RELA) and if symbol `_start` in some section `.text` is found, passes control to the former.
66

77
## Details
88

99
* RELs loaded in the order specified on the command line; all relocations in a given REL performed at its loading time.
1010
* Missing-symbol (SHN_UNDEF) resolution via reverse-direction search among the preceding RELs; first-match deterministic.
11-
* Support for RO sections `.rodata` and `.text`; every other type of section is RW; `.bss` addressing may take HI21/LO12.
12-
* Address-space sanitation -- disposing of pre-existing VMAs (*VMA filtering*) via string matching to VMA backing path.
11+
* Support for RO sections `.rodata` and `.text`; every other type of section is RW.
12+
* Address-space sanitation (linux-only) -- disposing of pre-existing VMAs (*VMA filtering*) via string matching to VMA backing path.
1313

1414
## ToDo
1515

@@ -24,10 +24,14 @@ Files used, with or without modifications, from external repositories:
2424
linux.org/ arch/arm64/kernel/module.c -> reloc_add_aarch64.c
2525
linux.org/ arch/arm64/lib/strlen.S -> strlen_linux.s
2626

27-
## Building
27+
## Building: linux
2828

2929
$ make all
3030

31+
## Building: macos
32+
33+
$ make -f Makefile.macos all
34+
3135
## Usage
3236

3337
```sh

char_ptr_arr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef __char_ptr_arr_H__
2+
#include <stddef.h>
3+
4+
struct char_ptr_arr_t {
5+
size_t count;
6+
char **arr;
7+
};
8+
9+
#endif /* __char_ptr_arr_H__ */
10+

reloc.c

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
#include <stdio.h>
88
#include <stdlib.h>
99
#include <string.h>
10+
#if __APPLE__ != 0
11+
#include <libelf/libelf.h>
12+
#else
1013
#include <libelf.h>
14+
#endif
1115
#include <fcntl.h>
1216
#include <stddef.h>
1317
#include <stdint.h>
@@ -16,7 +20,23 @@
1620
#include <sys/stat.h>
1721
#include <sys/mman.h>
1822

23+
#if __APPLE__ != 0
24+
#include "char_ptr_arr.h"
25+
#else
1926
#include "vma.h"
27+
#endif
28+
29+
#if __APPLE__ != 0
30+
#ifndef EM_AARCH64
31+
#define EM_AARCH64 183
32+
#endif
33+
34+
#ifndef MAP_POPULATE
35+
#define MAP_POPULATE 0
36+
#endif
37+
38+
typedef Elf64_Half Elf64_Section;
39+
#endif
2040

2141
int apply_relocate_add(Elf64_Shdr **sechdrs,
2242
unsigned int symsec,
@@ -63,12 +83,12 @@ const char *str_from_st_type(uint8_t x)
6383
return "STT_TLS";
6484
case STT_NUM:
6585
return "STT_NUM";
66-
#if 0
6786
case STT_LOOS:
6887
return "STT_LOOS";
69-
#endif
88+
#if 0
7089
case STT_GNU_IFUNC:
7190
return "STT_GNU_IFUNC";
91+
#endif
7292
case STT_HIOS:
7393
return "STT_HIOS";
7494
case STT_LOPROC:
@@ -90,12 +110,12 @@ const char *str_from_st_bind(uint8_t x)
90110
return "STB_WEAK";
91111
case STB_NUM:
92112
return "STB_NUM";
93-
#if 0
94113
case STB_LOOS:
95114
return "STB_LOOS";
96-
#endif
115+
#if 0
97116
case STB_GNU_UNIQUE:
98117
return "STB_GNU_UNIQUE";
118+
#endif
99119
case STB_HIOS:
100120
return "STB_HIOS";
101121
case STB_LOPROC:
@@ -253,14 +273,14 @@ static int
253273
_load_elf_file_details(
254274
Elf *elf,
255275
ElfDetails *ret_details,
256-
ptrdiff_t diff_exec)
276+
void *rawdata_rw,
277+
void *rawdata_ro)
257278
{
258279
ElfDetails details;
259280
char *ehdr_ident;
260281
Elf64_Ehdr *ehdr64;
261282
Elf64_Shdr *shdr64;
262283
Elf_Scn *scn;
263-
Elf_Data *data;
264284
const char *scn_name;
265285
Elf64_Shdr **section_list;
266286
size_t scn_idx, n_elf_scns;
@@ -434,33 +454,26 @@ static int
434454
}
435455
}
436456

437-
/* Resolve the vaddr and size of ELF section data */
438-
if ((data = elf_getdata(scn, 0)) != NULL) {
439-
if (shdr64->sh_size != data->d_size) {
440-
return -1;
441-
}
442-
/* Ignore empty sections */
443-
if (data->d_size != 0) {
444-
/* Section .bss does not have file backing */
445-
if (scn_idx == bss_idx) {
446-
const int prot_rw = PROT_READ | PROT_WRITE;
447-
const int flag_priv_anon = MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE;
448-
449-
void *p = mmap(NULL, data->d_size, prot_rw, flag_priv_anon, -1, 0);
450-
451-
if (p == MAP_FAILED) {
452-
fprintf(stderr, "error: cannot mmap bss\n");
453-
return -1;
454-
}
457+
/* Resolve the vaddr of non-empty ELF section data */
458+
if (shdr64->sh_size != 0) {
459+
/* Section .bss does not have file backing */
460+
if (scn_idx == bss_idx) {
461+
const int prot_rw = PROT_READ | PROT_WRITE;
462+
const int flag_priv_anon = MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE;
455463

456-
shdr64->sh_addr = (Elf64_Addr)p;
457-
} else {
458-
shdr64->sh_addr = (Elf64_Addr)data->d_buf;
464+
void *p = mmap(NULL, shdr64->sh_size, prot_rw, flag_priv_anon, -1, 0);
459465

460-
if (scn_idx == text_idx ||
461-
scn_idx == rodata_idx) {
462-
shdr64->sh_addr += diff_exec;
463-
}
466+
if (p == MAP_FAILED) {
467+
fprintf(stderr, "error: cannot mmap bss\n");
468+
return -1;
469+
}
470+
471+
shdr64->sh_addr = (Elf64_Addr)p;
472+
} else {
473+
if (scn_idx == text_idx || scn_idx == rodata_idx) {
474+
shdr64->sh_addr = (Elf64_Addr)(rawdata_ro + shdr64->sh_offset);
475+
} else {
476+
shdr64->sh_addr = (Elf64_Addr)(rawdata_rw + shdr64->sh_offset);
464477
}
465478
}
466479
}
@@ -509,16 +522,21 @@ static int
509522
relocate_elf_load_cu(
510523
Elf *elf,
511524
void **start,
512-
ptrdiff_t diff_exec,
525+
void *rawdata_rw,
526+
void *rawdata_ro,
513527
int flag_quiet)
514528
{
515529
ElfDetails details = NULL;
516530
Elf64_Sym *symtab;
517531
uint64 n_symbols, i;
518532
int rc;
519533

534+
if (!elf || !start || !rawdata_rw || !rawdata_ro) {
535+
return -1;
536+
}
537+
520538
/* Load ELF file section and symbol tables */
521-
rc = _load_elf_file_details(elf, &details, diff_exec);
539+
rc = _load_elf_file_details(elf, &details, rawdata_rw, rawdata_ro);
522540
if (rc)
523541
goto term;
524542

@@ -554,7 +572,7 @@ static int
554572
}
555573

556574
if (!flag_quiet) {
557-
printf("%2ld: %016lx %-13s %-14s %-17s %s\n",
575+
printf("%2lu: %016lx %-13s %-14s %-17s %s\n",
558576
i,
559577
symtab->st_value,
560578
str_from_st_type(ELF64_ST_TYPE(symtab->st_info)),
@@ -591,15 +609,19 @@ static int
591609
static void print_usage(char **argv)
592610
{
593611
printf("usage: %s <elf_rel_file> [<elf_rel_file>] ..\n"
612+
#if __APPLE__ == 0
594613
"\t--filter <string> : filter file mappings containing the specified string\n"
614+
#endif
595615
"\t--quiet : suppress all reports\n"
596616
"\t--help : this message\n", argv[0]);
597617
}
598618

599619
int main(int argc, char **argv)
600620
{
601621
size_t areas_capacity = 0, objs_capacity = 0;
622+
#if __APPLE__ == 0
602623
struct char_ptr_arr_t areas = { .count = 0, .arr = NULL };
624+
#endif
603625
struct char_ptr_arr_t objs = { .count = 0, .arr = NULL };
604626
Elf *prev_elf = NULL;
605627
void *start = NULL;
@@ -622,6 +644,7 @@ int main(int argc, char **argv)
622644
continue;
623645
}
624646

647+
#if __APPLE__ == 0
625648
if (!strcmp(argv[i], "--filter")) {
626649
if (++i == argc) {
627650
print_usage(argv);
@@ -634,6 +657,7 @@ int main(int argc, char **argv)
634657
continue;
635658
}
636659

660+
#endif
637661
/* Unprefixed arg must be a file */
638662
if (objs.count == objs_capacity) {
639663
objs.arr = (char **)realloc(objs.arr, objs_capacity = (objs_capacity + 1) * 2);
@@ -698,7 +722,7 @@ int main(int argc, char **argv)
698722
ehdr64->e_entry = (Elf64_Addr)prev_elf;
699723
prev_elf = elf;
700724

701-
if (relocate_elf_load_cu(elf, &start, q - p, flag_quiet)) {
725+
if (relocate_elf_load_cu(elf, &start, p, q, flag_quiet)) {
702726
fprintf(stderr, "error: cannot relocate_elf_load_cu\n");
703727
return -1;
704728
}
@@ -709,9 +733,11 @@ int main(int argc, char **argv)
709733
}
710734
}
711735

736+
#if __linux__ != 0
712737
if (areas.count && areas.arr != NULL)
713738
vma_process(&areas, flag_quiet);
714739

740+
#endif
715741
if (start != NULL)
716742
((void (*)(void))start)();
717743

0 commit comments

Comments
 (0)