-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsymtab.c
131 lines (94 loc) · 3.13 KB
/
symtab.c
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
void free_symtab(struct SYMTAB *sym){
if(sym->symtab)
free(sym->symtab);
}
int get_symbol_index(struct SYMTAB *symtab, const char *symname){
for(int i = 0; i < symtab->symtab_entries; i++){
if(strcmp(symtab->strtab->strtab_content[symtab->symtab[i].st_name], symname) == 0)
return i;
}
return NOT_FOUND;
}
int get_symbol_info(struct SYMTAB *symtab, const char *symname){
int index = get_symbol_index(symtab, symname);
if(index == NOT_FOUND){
fprintf(stderr, "symbol %s not found\n", symname);
return -1;
}
return symtab->symtab[index].st_info;
}
uint64_t get_symbol_size(struct SYMTAB *symtab, const char *symname){
int index = get_symbol_index(symtab, symname);
if(index == NOT_FOUND){
fprintf(stderr, "symbol %s not found\n", symname);
return -1;
}
return symtab->symtab[index].st_size;
}
Elf64_Addr get_symbol_value(struct SYMTAB *symtab, const char *symname){
int index = get_symbol_index(symtab, symname);
if(index == NOT_FOUND){
fprintf(stderr, "symbol %s not found\n", symname);
return -1;
}
return symtab->symtab[index].st_value;
}
int get_symbol_visibility(struct SYMTAB *symtab, const char *symname){
int index = get_symbol_index(symtab, symname);
if(index == NOT_FOUND){
fprintf(stderr, "symbol %s not found\n", symname);
return -1;
}
return symtab->symtab[index].st_other;
}
uint16_t get_symbol_section(struct SYMTAB *symtab, const char *symname){
int index = get_symbol_index(symtab, symname);
if(index == NOT_FOUND){
fprintf(stderr, "symbol %s not found\n", symname);
return -1;
}
return symtab->symtab[index].st_shndx;
}
int parse_symbol_table(struct shdr_table *shdr, struct SYMTAB *symtab, FILE *fh, const char *section_name){
symtab->symtab_index = get_section_index(shdr, section_name);
if(symtab->symtab_index == (uint8_t)NOT_FOUND) return NOT_FOUND;
symtab->symtab_size = shdr->shdr_table[symtab->symtab_index].sh_size;
symtab->symtab_entries = (symtab->symtab_size / shdr->shdr_table[symtab->symtab_index].sh_entsize);
symtab->symtab_offset = shdr->shdr_table[symtab->symtab_index].sh_offset;
//use malloc and memset
symtab->symtab = malloc(symtab->symtab_size);
if(!symtab->symtab){
perror("memory allocation failed");
return -1;
}
memset(symtab->symtab, 0, symtab->symtab_size);
fseek(fh, symtab->symtab_offset, SEEK_SET);
if(fread(symtab->symtab, 1, symtab->symtab_size, fh) < symtab->symtab_size){
perror("error reading file");
return -1;
}
return 0;
}
int parse_dynsym(struct shdr_table *shdr, FILE *fh){
shdr->dynsym.symtab = NULL;
int ret = parse_symbol_table(shdr, &shdr->dynsym, fh, ".dynsym");
if(ret == NOT_FOUND){
fprintf(stderr, "Section .dynsym not found\n");
return -1;
}
else if(ret == -1) return -1;
return 0;
}
int parse_symtab(struct shdr_table *shdr, FILE *fh){
shdr->symtab.symtab = NULL;
int ret = parse_symbol_table(shdr, &shdr->symtab, fh, ".symtab");
if(ret == NOT_FOUND){
fprintf(stderr, "section .symtab not found\n");
return -1;
}
else if(ret == -1) return -1;
return 0;
}