blob: 69a9f0782a03c6957fddb24befa9c6ae4d8acd2e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "elf_plt.h"
#if defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)
#if defined(OBJFORMAT_ELF)
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define _makeStub ADD_SUFFIX(makeStub)
#define needStubForRel ADD_SUFFIX(needStubForRel)
#define needStubForRela ADD_SUFFIX(needStubForRela)
unsigned
numberOfStubsForSection( ObjectCode *oc, unsigned sectionIndex) {
unsigned n = 0;
for(ElfRelocationTable *t = oc->info->relTable; t != NULL; t = t->next)
if(t->targetSectionIndex == sectionIndex)
for(size_t i=0; i < t->n_relocations; i++)
if(needStubForRel(&t->relocations[i]))
n += 1;
for(ElfRelocationATable *t = oc->info->relaTable; t != NULL; t = t->next)
if(t->targetSectionIndex == sectionIndex)
for(size_t i=0; i < t->n_relocations; i++)
if(needStubForRela(&t->relocations[i]))
n += 1;
return n;
}
bool
findStub(Section * section,
void* * addr,
uint8_t flags) {
for(Stub * s = section->info->stubs; s != NULL; s = s->next) {
if( s->target == *addr
&& s->flags == flags) {
*addr = s->addr;
return EXIT_SUCCESS;
}
}
return EXIT_FAILURE;
}
bool
makeStub(Section * section,
void* * addr,
uint8_t flags) {
Stub * s = calloc(1, sizeof(Stub));
ASSERT(s != NULL);
s->target = *addr;
s->flags = flags;
s->next = NULL;
s->addr = (uint8_t *)section->info->stub_offset + 8
+ STUB_SIZE * section->info->nstubs;
if((*_makeStub)(s))
return EXIT_FAILURE;
if(section->info->stubs == NULL) {
ASSERT(section->info->nstubs == 0);
/* no stubs yet, let's just create this one */
section->info->stubs = s;
} else {
Stub * tail = section->info->stubs;
while(tail->next != NULL) tail = tail->next;
tail->next = s;
}
section->info->nstubs += 1;
*addr = s->addr;
return EXIT_SUCCESS;
}
void
freeStubs(Section * section) {
if(section->info->nstubs == 0)
return;
Stub * last = section->info->stubs;
while(last->next != NULL) {
Stub * t = last;
last = last->next;
free(t);
}
section->info->stubs = NULL;
section->info->nstubs = 0;
}
#endif // OBJECTFORMAT_ELF
#endif // arm/aarch64_HOST_ARCH
|