Add System.map reading code to objmanip.
[ksplice.git] / objcommon.c
blob471d261df8c1269af046978a092c7cee4424223c
1 /* Copyright (C) 2008 Jeffrey Brian Arnold <jbarnold@mit.edu>
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License, version 2.
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
14 * 02110-1301, USA.
17 #include "objcommon.h"
19 void vec_do_reserve(void **data, size_t *mem_size, size_t new_size)
21 if (new_size > *mem_size || new_size * 2 < *mem_size) {
22 if (new_size < *mem_size * 2)
23 new_size = *mem_size * 2;
24 *data = realloc(*data, new_size);
25 assert(new_size == 0 || *data != NULL);
26 *mem_size = new_size;
30 void get_syms(bfd *abfd, struct asymbolp_vec *syms)
32 long storage_needed = bfd_get_symtab_upper_bound(abfd);
33 if (storage_needed == 0)
34 return;
35 assert(storage_needed >= 0);
37 vec_init(syms);
38 vec_reserve(syms, storage_needed);
39 vec_resize(syms, bfd_canonicalize_symtab(abfd, syms->data));
40 assert(syms->size >= 0);
43 struct supersect *fetch_supersect(bfd *abfd, asection *sect,
44 struct asymbolp_vec *syms)
46 static struct supersect *supersects = NULL;
48 struct supersect *ss;
49 for (ss = supersects; ss != NULL; ss = ss->next) {
50 if (strcmp(sect->name, ss->name) == 0 && ss->parent == abfd)
51 return ss;
54 struct supersect *new = malloc(sizeof(*new));
55 new->parent = abfd;
56 new->name = malloc(strlen(sect->name) + 1);
57 strcpy(new->name, sect->name);
58 new->next = supersects;
59 supersects = new;
61 vec_init(&new->contents);
62 vec_resize(&new->contents, bfd_get_section_size(sect));
63 assert(bfd_get_section_contents
64 (abfd, sect, new->contents.data, 0, new->contents.size));
65 new->alignment = bfd_get_section_alignment(abfd, sect);
67 vec_init(&new->relocs);
68 vec_reserve(&new->relocs, bfd_get_reloc_upper_bound(abfd, sect));
69 vec_resize(&new->relocs,
70 bfd_canonicalize_reloc(abfd, sect, new->relocs.data,
71 syms->data));
72 assert(new->relocs.size >= 0);
74 return new;
77 struct supersect *new_supersects = NULL;
79 struct supersect *new_supersect(char *name)
81 struct supersect *ss;
82 for (ss = new_supersects; ss != NULL; ss = ss->next) {
83 if (strcmp(name, ss->name) == 0)
84 return ss;
87 struct supersect *new = malloc(sizeof(*new));
88 new->parent = NULL;
89 new->name = name;
90 new->next = new_supersects;
91 new_supersects = new;
93 vec_init(&new->contents);
94 new->alignment = 0;
95 vec_init(&new->relocs);
97 return new;
100 void *sect_do_grow(struct supersect *ss, size_t n, size_t size, int alignment)
102 if (ss->alignment < ffs(alignment) - 1)
103 ss->alignment = ffs(alignment) - 1;
104 int pad = ss->contents.size - align(ss->contents.size, alignment);
105 memset(vec_grow(&ss->contents, pad), 0, pad);
106 return vec_grow(&ss->contents, n * size);
109 int label_offset(const char *sym_name)
111 int i;
112 for (i = 0;
113 sym_name[i] != 0 && sym_name[i + 1] != 0 && sym_name[i + 2] != 0
114 && sym_name[i + 3] != 0; i++) {
115 if (sym_name[i] == '_' && sym_name[i + 1] == '_'
116 && sym_name[i + 2] == '_' && sym_name[i + 3] == '_')
117 return i + 4;
119 return -1;
122 const char *only_label(const char *sym_name)
124 int offset = label_offset(sym_name);
125 if (offset == -1)
126 return NULL;
127 return &sym_name[offset];
130 const char *dup_wolabel(const char *sym_name)
132 int offset, entire_strlen, label_strlen, new_strlen;
133 char *newstr;
135 offset = label_offset(sym_name);
136 if (offset == -1)
137 label_strlen = 0;
138 else
139 label_strlen = strlen(&sym_name[offset]) + strlen("____");
141 entire_strlen = strlen(sym_name);
142 new_strlen = entire_strlen - label_strlen;
143 newstr = malloc(new_strlen + 1);
144 memcpy(newstr, sym_name, new_strlen);
145 newstr[new_strlen] = 0;
146 return newstr;