Changeset View
Changeset View
Standalone View
Standalone View
libdwarf/libdwarf_elf_init.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | static const char *debug_name[] = { | ||||
".debug_static_func", | ".debug_static_func", | ||||
".debug_static_vars", | ".debug_static_vars", | ||||
".debug_typenames", | ".debug_typenames", | ||||
".debug_weaknames", | ".debug_weaknames", | ||||
NULL | NULL | ||||
}; | }; | ||||
static void | static void | ||||
_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data, | _dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, | ||||
Elf_Data *symtab_data, int endian) | Elf_Data *rel_data, Elf_Data *symtab_data, int endian) | ||||
{ | { | ||||
Dwarf_Unsigned type; | Dwarf_Unsigned type; | ||||
GElf_Rel rel; | GElf_Rel rel; | ||||
GElf_Sym sym; | GElf_Sym sym; | ||||
size_t symndx; | size_t symndx; | ||||
uint64_t offset; | uint64_t offset; | ||||
uint64_t addend; | uint64_t addend; | ||||
int size, j; | int size, j; | ||||
j = 0; | j = 0; | ||||
while (gelf_getrel(rel_data, j++, &rel) != NULL) { | while (gelf_getrel(rel_data, j++, &rel) != NULL) { | ||||
symndx = GELF_R_SYM(rel.r_info); | symndx = GELF_R_SYM(rel.r_info); | ||||
type = GELF_R_TYPE(rel.r_info); | type = GELF_R_TYPE(rel.r_info); | ||||
if (gelf_getsym(symtab_data, symndx, &sym) == NULL) | if (gelf_getsym(symtab_data, symndx, &sym) == NULL) | ||||
continue; | continue; | ||||
size = _dwarf_get_reloc_size(dbg, type); | size = _dwarf_get_reloc_size(dbg, type); | ||||
if (size == 0) | if (size == 0) | ||||
continue; /* Unknown or non-absolute relocation. */ | continue; /* Unknown or non-absolute relocation. */ | ||||
offset = rel.r_offset; | offset = rel.r_offset; | ||||
if (offset + size >= bufsize) | |||||
continue; | |||||
if (endian == ELFDATA2MSB) | if (endian == ELFDATA2MSB) | ||||
addend = _dwarf_read_msb(buf, &offset, size); | addend = _dwarf_read_msb(buf, &offset, size); | ||||
else | else | ||||
addend = _dwarf_read_lsb(buf, &offset, size); | addend = _dwarf_read_lsb(buf, &offset, size); | ||||
offset = rel.r_offset; | offset = rel.r_offset; | ||||
if (endian == ELFDATA2MSB) | if (endian == ELFDATA2MSB) | ||||
_dwarf_write_msb(buf, &offset, sym.st_value + addend, | _dwarf_write_msb(buf, &offset, sym.st_value + addend, | ||||
size); | size); | ||||
else | else | ||||
_dwarf_write_lsb(buf, &offset, sym.st_value + addend, | _dwarf_write_lsb(buf, &offset, sym.st_value + addend, | ||||
size); | size); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data, | _dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, | ||||
Elf_Data *symtab_data, int endian) | Elf_Data *rel_data, Elf_Data *symtab_data, int endian) | ||||
{ | { | ||||
Dwarf_Unsigned type; | Dwarf_Unsigned type; | ||||
GElf_Rela rela; | GElf_Rela rela; | ||||
GElf_Sym sym; | GElf_Sym sym; | ||||
size_t symndx; | size_t symndx; | ||||
uint64_t offset; | uint64_t offset; | ||||
int size, j; | int size, j; | ||||
j = 0; | j = 0; | ||||
while (gelf_getrela(rel_data, j++, &rela) != NULL) { | while (gelf_getrela(rel_data, j++, &rela) != NULL) { | ||||
symndx = GELF_R_SYM(rela.r_info); | symndx = GELF_R_SYM(rela.r_info); | ||||
type = GELF_R_TYPE(rela.r_info); | type = GELF_R_TYPE(rela.r_info); | ||||
if (gelf_getsym(symtab_data, symndx, &sym) == NULL) | if (gelf_getsym(symtab_data, symndx, &sym) == NULL) | ||||
continue; | continue; | ||||
offset = rela.r_offset; | offset = rela.r_offset; | ||||
size = _dwarf_get_reloc_size(dbg, type); | size = _dwarf_get_reloc_size(dbg, type); | ||||
if (size == 0) | if (size == 0) | ||||
continue; /* Unknown or non-absolute relocation. */ | continue; /* Unknown or non-absolute relocation. */ | ||||
if (offset + size >= bufsize) | |||||
continue; | |||||
if (endian == ELFDATA2MSB) | if (endian == ELFDATA2MSB) | ||||
_dwarf_write_msb(buf, &offset, | _dwarf_write_msb(buf, &offset, | ||||
sym.st_value + rela.r_addend, size); | sym.st_value + rela.r_addend, size); | ||||
else | else | ||||
_dwarf_write_lsb(buf, &offset, | _dwarf_write_lsb(buf, &offset, | ||||
sym.st_value + rela.r_addend, size); | sym.st_value + rela.r_addend, size); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | if (sh.sh_info == shndx && sh.sh_link == symtab) { | ||||
ed->ed_alloc = malloc(ed->ed_data->d_size); | ed->ed_alloc = malloc(ed->ed_data->d_size); | ||||
if (ed->ed_alloc == NULL) { | if (ed->ed_alloc == NULL) { | ||||
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); | DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); | ||||
return (DW_DLE_MEMORY); | return (DW_DLE_MEMORY); | ||||
} | } | ||||
memcpy(ed->ed_alloc, ed->ed_data->d_buf, | memcpy(ed->ed_alloc, ed->ed_data->d_buf, | ||||
ed->ed_data->d_size); | ed->ed_data->d_size); | ||||
if (sh.sh_type == SHT_REL) | if (sh.sh_type == SHT_REL) | ||||
_dwarf_elf_apply_rel_reloc(dbg, ed->ed_alloc, | _dwarf_elf_apply_rel_reloc(dbg, | ||||
ed->ed_alloc, ed->ed_data->d_size, | |||||
rel, symtab_data, eh.e_ident[EI_DATA]); | rel, symtab_data, eh.e_ident[EI_DATA]); | ||||
else | else | ||||
_dwarf_elf_apply_rela_reloc(dbg, ed->ed_alloc, | _dwarf_elf_apply_rela_reloc(dbg, | ||||
ed->ed_alloc, ed->ed_data->d_size, | |||||
rel, symtab_data, eh.e_ident[EI_DATA]); | rel, symtab_data, eh.e_ident[EI_DATA]); | ||||
return (DW_DLE_NONE); | return (DW_DLE_NONE); | ||||
} | } | ||||
} | } | ||||
elferr = elf_errno(); | elferr = elf_errno(); | ||||
if (elferr != 0) { | if (elferr != 0) { | ||||
DWARF_SET_ELF_ERROR(dbg, error); | DWARF_SET_ELF_ERROR(dbg, error); | ||||
▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines |