sec = &elf->section_data[i];
INIT_LIST_HEAD(&sec->symbol_list);
- INIT_LIST_HEAD(&sec->reloc_list);
s = elf_getscn(elf->elf, i);
if (!s) {
elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
if (is_reloc_sec(sec))
- elf->num_relocs += sec->sh.sh_size / sec->sh.sh_entsize;
+ elf->num_relocs += sec_num_entries(sec);
}
if (opts.stats) {
if (symtab_shndx)
shndx_data = symtab_shndx->data;
- symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize;
+ symbols_nr = sec_num_entries(symtab);
} else {
/*
* A missing symbol table is actually possible if it's an empty
return NULL;
}
- new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize;
+ new_idx = sec_num_entries(symtab);
if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL)
goto non_local;
{
struct reloc *reloc, empty = { 0 };
- if (reloc_idx >= rsec->sh.sh_size / elf_rela_size(elf)) {
- WARN("%s: bad reloc_idx %u for %s with size 0x%lx",
- __func__, reloc_idx, rsec->name, rsec->sh.sh_size);
+ if (reloc_idx >= sec_num_entries(rsec)) {
+ WARN("%s: bad reloc_idx %u for %s with %d relocs",
+ __func__, reloc_idx, rsec->name, sec_num_entries(rsec));
return NULL;
}
- reloc = &rsec->reloc_data[reloc_idx];
+ reloc = &rsec->relocs[reloc_idx];
if (memcmp(reloc, &empty, sizeof(empty))) {
WARN("%s: %s: reloc %d already initialized!",
return NULL;
list_add_tail(&reloc->sym_reloc_entry, &sym->reloc_list);
- list_add_tail(&reloc->list, &rsec->reloc_list);
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
return reloc;
rsec->base->rsec = rsec;
nr_reloc = 0;
- rsec->reloc_data = calloc(rsec->sh.sh_size / rsec->sh.sh_entsize,
- sizeof(*reloc));
- if (!rsec->reloc_data) {
+ rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc));
+ if (!rsec->relocs) {
perror("calloc");
return -1;
}
- for (i = 0; i < rsec->sh.sh_size / rsec->sh.sh_entsize; i++) {
- reloc = &rsec->reloc_data[i];
+ for (i = 0; i < sec_num_entries(rsec); i++) {
+ reloc = &rsec->relocs[i];
if (read_reloc(rsec, i, reloc))
return -1;
}
list_add_tail(&reloc->sym_reloc_entry, &sym->reloc_list);
- list_add_tail(&reloc->list, &rsec->reloc_list);
elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
nr_reloc++;
memset(sec, 0, sizeof(*sec));
INIT_LIST_HEAD(&sec->symbol_list);
- INIT_LIST_HEAD(&sec->reloc_list);
s = elf_newscn(elf->elf);
if (!s) {
rsec->sh.sh_info = sec->idx;
rsec->sh.sh_flags = SHF_INFO_LINK;
- rsec->reloc_data = calloc(rsec->sh.sh_size / rsec->sh.sh_entsize,
- sizeof(struct reloc));
- if (!rsec->reloc_data) {
+ rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc));
+ if (!rsec->relocs) {
perror("calloc");
return NULL;
}
GElf_Shdr sh;
struct rb_root_cached symbol_tree;
struct list_head symbol_list;
- struct list_head reloc_list;
struct section *base, *rsec;
struct symbol *sym;
Elf_Data *data;
char *name;
int idx;
bool _changed, text, rodata, noinstr, init, truncate;
- struct reloc *reloc_data;
+ struct reloc *relocs;
};
struct symbol {
};
struct reloc {
- struct list_head list;
struct hlist_node hash;
union {
GElf_Rela rela;
elf->changed |= changed;
}
+static inline unsigned int sec_num_entries(struct section *sec)
+{
+ return sec->sh.sh_size / sec->sh.sh_entsize;
+}
+
#define for_each_sec(file, sec) \
list_for_each_entry(sec, &file->elf->sections, list)
sec_for_each_sym(__sec, sym)
#define for_each_reloc(rsec, reloc) \
- list_for_each_entry(reloc, &rsec->reloc_list, list)
+ for (int __i = 0, __fake = 1; __fake; __fake = 0) \
+ for (reloc = rsec->relocs; \
+ __i < sec_num_entries(rsec); \
+ __i++, reloc++)
#define for_each_reloc_from(rsec, reloc) \
- list_for_each_entry_from(reloc, &rsec->reloc_list, list)
+ for (int __i = reloc->idx; \
+ __i < sec_num_entries(rsec); \
+ __i++, reloc++)
#define OFFSET_STRIDE_BITS 4
#define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS)