Move garbage collection from helper's cleanup_module to activate_primary.
[ksplice.git] / objcommon.c
blobcc6d3ade6ab946547c3f32d05be6a724de4542e7
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 long get_syms(bfd *abfd, asymbol ***syms_ptr)
21 long storage_needed = bfd_get_symtab_upper_bound(abfd);
22 if (storage_needed == 0)
23 return 0;
24 assert(storage_needed >= 0);
26 *syms_ptr = (asymbol **)malloc(storage_needed);
27 long num_syms = bfd_canonicalize_symtab(abfd, *syms_ptr);
28 assert(num_syms >= 0);
30 return num_syms;
33 struct supersect *fetch_supersect(bfd *abfd, asection *sect, asymbol **sympp)
35 static struct supersect *supersects = NULL;
37 struct supersect *ss;
38 for (ss = supersects; ss != NULL; ss = ss->next) {
39 if (strcmp(sect->name, ss->name) == 0 && ss->parent == abfd) {
40 return ss;
44 struct supersect *new = malloc(sizeof(*new));
45 new->parent = abfd;
46 new->name = malloc(strlen(sect->name) + 1);
47 strcpy(new->name, sect->name);
48 new->next = supersects;
49 supersects = new;
51 new->contents_size = bfd_get_section_size(sect);
52 new->contents = (void *)malloc(align(new->contents_size, 4));
53 assert(bfd_get_section_contents
54 (abfd, sect, new->contents, 0, new->contents_size));
56 int relsize = bfd_get_reloc_upper_bound(abfd, sect);
57 new->relocs = (void *)malloc(relsize);
58 new->num_relocs =
59 bfd_canonicalize_reloc(abfd, sect, new->relocs, sympp);
60 assert(new->num_relocs >= 0);
62 return new;
65 int label_offset(const char *sym_name)
67 int i;
68 for (i = 0;
69 sym_name[i] != 0 && sym_name[i + 1] != 0 && sym_name[i + 2] != 0
70 && sym_name[i + 3] != 0; i++) {
71 if (sym_name[i] == '_' && sym_name[i + 1] == '_'
72 && sym_name[i + 2] == '_' && sym_name[i + 3] == '_') {
73 return i + 4;
76 return -1;
79 const char *only_label(const char *sym_name)
81 int offset = label_offset(sym_name);
82 if (offset == -1)
83 return NULL;
84 return &sym_name[offset];
87 const char *dup_wolabel(const char *sym_name)
89 int offset, entire_strlen, label_strlen, new_strlen;
90 char *newstr;
92 offset = label_offset(sym_name);
93 if (offset == -1) {
94 label_strlen = 0;
95 } else {
96 label_strlen = strlen(&sym_name[offset]) + strlen("____");
99 entire_strlen = strlen(sym_name);
100 new_strlen = entire_strlen - label_strlen;
101 newstr = malloc(new_strlen + 1);
102 memcpy(newstr, sym_name, new_strlen);
103 newstr[new_strlen] = 0;
104 return newstr;