43
43
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
51
50
/* Find a symbol table. */
52
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
51
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
54
i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
53
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
55
54
if (s->sh_type == SHT_SYMTAB)
58
57
if (i == e->e_shnum)
59
58
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
61
symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
62
60
entsize = s->sh_entsize;
64
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
62
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
66
i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
64
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
67
65
if (s->sh_type == SHT_RELA)
69
67
grub_dl_segment_t seg;
78
Elf32_Rela *rel, *max;
80
for (rel = (Elf32_Rela *) ((char *) e + s->sh_offset),
78
for (rel = (Elf_Rela *) ((char *) e + s->sh_offset),
81
79
max = rel + s->sh_size / s->sh_entsize;
87
85
grub_uint32_t value;
89
87
if (seg->size < rel->r_offset)
90
88
return grub_error (GRUB_ERR_BAD_MODULE,
91
89
"reloc offset is out of the segment");
93
addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset);
94
sym = (Elf32_Sym *) ((char *) symtab
95
+ entsize * ELF32_R_SYM (rel->r_info));
91
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
92
sym = (Elf_Sym *) ((char *) mod->symtab
93
+ entsize * ELF_R_SYM (rel->r_info));
97
95
/* On the PPC the value does not have an explicit
99
97
value = sym->st_value + rel->r_addend;
100
switch (ELF32_R_TYPE (rel->r_info))
98
switch (ELF_R_TYPE (rel->r_info))
102
100
case R_PPC_ADDR16_LO:
103
*(Elf32_Half *) addr = value;
101
*(Elf_Half *) addr = value;
106
104
case R_PPC_REL24:
108
Elf32_Sword delta = value - (Elf32_Word) addr;
106
Elf_Sword delta = value - (Elf_Word) addr;
110
108
if (delta << 6 >> 6 != delta)
111
109
return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow");
112
110
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
116
114
case R_PPC_ADDR16_HA:
117
*(Elf32_Half *) addr = (value + 0x8000) >> 16;
115
*(Elf_Half *) addr = (value + 0x8000) >> 16;
120
118
case R_PPC_ADDR32:
124
122
case R_PPC_REL32:
125
*addr = value - (Elf32_Word) addr;
123
*addr = value - (Elf_Word) addr;
129
127
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
130
128
"This relocation (%d) is not implemented yet",
131
ELF32_R_TYPE (rel->r_info));
129
ELF_R_TYPE (rel->r_info));
137
135
return GRUB_ERR_NONE;