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
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
);
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)
35 assert(storage_needed
>= 0);
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 if (sect
->userdata
!= NULL
)
47 return sect
->userdata
;
49 struct supersect
*new = malloc(sizeof(*new));
52 new->name
= malloc(strlen(sect
->name
) + 1);
53 strcpy(new->name
, sect
->name
);
54 new->flags
= bfd_get_section_flags(abfd
, sect
);
56 vec_init(&new->contents
);
57 vec_resize(&new->contents
, bfd_get_section_size(sect
));
58 assert(bfd_get_section_contents
59 (abfd
, sect
, new->contents
.data
, 0, new->contents
.size
));
60 new->alignment
= bfd_get_section_alignment(abfd
, sect
);
62 vec_init(&new->relocs
);
63 vec_reserve(&new->relocs
, bfd_get_reloc_upper_bound(abfd
, sect
));
64 vec_resize(&new->relocs
,
65 bfd_canonicalize_reloc(abfd
, sect
, new->relocs
.data
,
67 assert(new->relocs
.size
>= 0);
68 vec_init(&new->new_relocs
);
73 struct supersect
*new_supersects
= NULL
;
75 struct supersect
*new_supersect(char *name
)
78 for (ss
= new_supersects
; ss
!= NULL
; ss
= ss
->next
) {
79 if (strcmp(name
, ss
->name
) == 0)
83 struct supersect
*new = malloc(sizeof(*new));
86 new->next
= new_supersects
;
88 new->flags
= SEC_ALLOC
| SEC_HAS_CONTENTS
| SEC_RELOC
;
90 vec_init(&new->contents
);
92 vec_init(&new->relocs
);
93 vec_init(&new->new_relocs
);
98 void *sect_do_grow(struct supersect
*ss
, size_t n
, size_t size
, int alignment
)
100 if (ss
->alignment
< ffs(alignment
) - 1)
101 ss
->alignment
= ffs(alignment
) - 1;
102 int pad
= ss
->contents
.size
- align(ss
->contents
.size
, alignment
);
103 memset(vec_grow(&ss
->contents
, pad
), 0, pad
);
104 return vec_grow(&ss
->contents
, n
* size
);
107 int label_offset(const char *sym_name
)
111 sym_name
[i
] != 0 && sym_name
[i
+ 1] != 0 && sym_name
[i
+ 2] != 0
112 && sym_name
[i
+ 3] != 0; i
++) {
113 if (sym_name
[i
] == '_' && sym_name
[i
+ 1] == '_'
114 && sym_name
[i
+ 2] == '_' && sym_name
[i
+ 3] == '_')
120 const char *only_label(const char *sym_name
)
122 int offset
= label_offset(sym_name
);
125 return &sym_name
[offset
];
128 const char *dup_wolabel(const char *sym_name
)
130 int offset
, entire_strlen
, label_strlen
, new_strlen
;
133 offset
= label_offset(sym_name
);
137 label_strlen
= strlen(&sym_name
[offset
]) + strlen("____");
139 entire_strlen
= strlen(sym_name
);
140 new_strlen
= entire_strlen
- label_strlen
;
141 newstr
= malloc(new_strlen
+ 1);
142 memcpy(newstr
, sym_name
, new_strlen
);
143 newstr
[new_strlen
] = 0;