38
38
return GRUB_ERR_NONE;
42
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
45
const Elf_Ehdr *e = ehdr;
52
/* Find a symbol table. */
53
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
55
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
56
if (s->sh_type == SHT_SYMTAB)
62
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
64
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
65
if (s->sh_type == SHT_RELA)
67
const Elf_Rela *rel, *max;
69
for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset),
70
max = rel + s->sh_size / s->sh_entsize;
73
if (ELF_R_TYPE (rel->r_info) == GRUB_ELF_R_PPC_REL24)
81
41
/* For low-endian reverse lis and addr_high as well as ori and addr_low. */
58
#pragma GCC diagnostic ignored "-Wcast-align"
61
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
64
const Elf_Ehdr *e = ehdr;
71
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
73
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
74
if (s->sh_type == SHT_RELA)
76
const Elf_Rela *rel, *max;
78
for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset),
79
max = rel + s->sh_size / s->sh_entsize;
82
if (ELF_R_TYPE (rel->r_info) == GRUB_ELF_R_PPC_REL24)
87
*tramp *= sizeof (struct trampoline);
98
92
/* Relocate symbols. */
100
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
94
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
95
Elf_Shdr *s, grub_dl_segment_t seg)
106
struct trampoline *tptr = mod->tramp;
108
/* Find a symbol table. */
109
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
111
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
112
if (s->sh_type == SHT_SYMTAB)
116
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
118
entsize = s->sh_entsize;
120
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
122
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
123
if (s->sh_type == SHT_RELA)
125
grub_dl_segment_t seg;
127
/* Find the target segment. */
128
for (seg = mod->segment; seg; seg = seg->next)
129
if (seg->section == s->sh_info)
99
for (rel = (Elf_Rela *) ((char *) ehdr + s->sh_offset),
100
max = (Elf_Rela *) ((char *) rel + s->sh_size);
102
rel = (Elf_Rela *) ((char *) rel + s->sh_entsize))
108
if (seg->size < rel->r_offset)
109
return grub_error (GRUB_ERR_BAD_MODULE,
110
"reloc offset is out of the segment");
112
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
113
sym = (Elf_Sym *) ((char *) mod->symtab
114
+ mod->symsize * ELF_R_SYM (rel->r_info));
116
/* On the PPC the value does not have an explicit
118
value = sym->st_value + rel->r_addend;
119
switch (ELF_R_TYPE (rel->r_info))
121
case GRUB_ELF_R_PPC_ADDR16_LO:
122
*(Elf_Half *) addr = value;
125
case GRUB_ELF_R_PPC_REL24:
127
Elf_Sword delta = value - (Elf_Word) addr;
136
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
137
max = rel + s->sh_size / s->sh_entsize;
129
if (delta << 6 >> 6 != delta)
145
if (seg->size < rel->r_offset)
146
return grub_error (GRUB_ERR_BAD_MODULE,
147
"reloc offset is out of the segment");
149
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
150
sym = (Elf_Sym *) ((char *) mod->symtab
151
+ entsize * ELF_R_SYM (rel->r_info));
153
/* On the PPC the value does not have an explicit
155
value = sym->st_value + rel->r_addend;
156
switch (ELF_R_TYPE (rel->r_info))
158
case GRUB_ELF_R_PPC_ADDR16_LO:
159
*(Elf_Half *) addr = value;
162
case GRUB_ELF_R_PPC_REL24:
164
Elf_Sword delta = value - (Elf_Word) addr;
166
if (delta << 6 >> 6 != delta)
168
COMPILE_TIME_ASSERT (sizeof (struct trampoline)
169
== GRUB_ARCH_DL_TRAMP_SIZE);
170
grub_memcpy (tptr, &trampoline_template,
172
delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;
173
tptr->lis |= (((value) >> 16) & 0xffff);
174
tptr->ori |= ((value) & 0xffff);
131
struct trampoline *tptr = mod->trampptr;
132
grub_memcpy (tptr, &trampoline_template,
134
delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;
135
tptr->lis |= (((value) >> 16) & 0xffff);
136
tptr->ori |= ((value) & 0xffff);
137
mod->trampptr = tptr + 1;
178
if (delta << 6 >> 6 != delta)
179
return grub_error (GRUB_ERR_BAD_MODULE,
180
"relocation overflow");
181
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
185
case GRUB_ELF_R_PPC_ADDR16_HA:
186
*(Elf_Half *) addr = (value + 0x8000) >> 16;
189
case GRUB_ELF_R_PPC_ADDR32:
193
case GRUB_ELF_R_PPC_REL32:
194
*addr = value - (Elf_Word) addr;
198
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
199
N_("relocation 0x%x is not implemented yet"),
200
ELF_R_TYPE (rel->r_info));
140
if (delta << 6 >> 6 != delta)
141
return grub_error (GRUB_ERR_BAD_MODULE,
142
"relocation overflow");
143
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
147
case GRUB_ELF_R_PPC_ADDR16_HA:
148
*(Elf_Half *) addr = (value + 0x8000) >> 16;
151
case GRUB_ELF_R_PPC_ADDR32:
155
case GRUB_ELF_R_PPC_REL32:
156
*addr = value - (Elf_Word) addr;
160
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
161
N_("relocation 0x%x is not implemented yet"),
162
ELF_R_TYPE (rel->r_info));
206
166
return GRUB_ERR_NONE;