cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

elf.c (29823B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * elf.c - ELF access library
      4 *
      5 * Adapted from kpatch (https://github.com/dynup/kpatch):
      6 * Copyright (C) 2013-2015 Josh Poimboeuf <jpoimboe@redhat.com>
      7 * Copyright (C) 2014 Seth Jennings <sjenning@redhat.com>
      8 */
      9
     10#include <sys/types.h>
     11#include <sys/stat.h>
     12#include <sys/mman.h>
     13#include <fcntl.h>
     14#include <stdio.h>
     15#include <stdlib.h>
     16#include <string.h>
     17#include <unistd.h>
     18#include <errno.h>
     19#include <objtool/builtin.h>
     20
     21#include <objtool/elf.h>
     22#include <objtool/warn.h>
     23
     24#define MAX_NAME_LEN 128
     25
     26static inline u32 str_hash(const char *str)
     27{
     28	return jhash(str, strlen(str), 0);
     29}
     30
     31#define __elf_table(name)	(elf->name##_hash)
     32#define __elf_bits(name)	(elf->name##_bits)
     33
     34#define elf_hash_add(name, node, key) \
     35	hlist_add_head(node, &__elf_table(name)[hash_min(key, __elf_bits(name))])
     36
     37#define elf_hash_for_each_possible(name, obj, member, key) \
     38	hlist_for_each_entry(obj, &__elf_table(name)[hash_min(key, __elf_bits(name))], member)
     39
     40#define elf_alloc_hash(name, size) \
     41({ \
     42	__elf_bits(name) = max(10, ilog2(size)); \
     43	__elf_table(name) = mmap(NULL, sizeof(struct hlist_head) << __elf_bits(name), \
     44				 PROT_READ|PROT_WRITE, \
     45				 MAP_PRIVATE|MAP_ANON, -1, 0); \
     46	if (__elf_table(name) == (void *)-1L) { \
     47		WARN("mmap fail " #name); \
     48		__elf_table(name) = NULL; \
     49	} \
     50	__elf_table(name); \
     51})
     52
     53static bool symbol_to_offset(struct rb_node *a, const struct rb_node *b)
     54{
     55	struct symbol *sa = rb_entry(a, struct symbol, node);
     56	struct symbol *sb = rb_entry(b, struct symbol, node);
     57
     58	if (sa->offset < sb->offset)
     59		return true;
     60	if (sa->offset > sb->offset)
     61		return false;
     62
     63	if (sa->len < sb->len)
     64		return true;
     65	if (sa->len > sb->len)
     66		return false;
     67
     68	sa->alias = sb;
     69
     70	return false;
     71}
     72
     73static int symbol_by_offset(const void *key, const struct rb_node *node)
     74{
     75	const struct symbol *s = rb_entry(node, struct symbol, node);
     76	const unsigned long *o = key;
     77
     78	if (*o < s->offset)
     79		return -1;
     80	if (*o >= s->offset + s->len)
     81		return 1;
     82
     83	return 0;
     84}
     85
     86struct symbol_hole {
     87	unsigned long key;
     88	const struct symbol *sym;
     89};
     90
     91/*
     92 * Find !section symbol where @offset is after it.
     93 */
     94static int symbol_hole_by_offset(const void *key, const struct rb_node *node)
     95{
     96	const struct symbol *s = rb_entry(node, struct symbol, node);
     97	struct symbol_hole *sh = (void *)key;
     98
     99	if (sh->key < s->offset)
    100		return -1;
    101
    102	if (sh->key >= s->offset + s->len) {
    103		if (s->type != STT_SECTION)
    104			sh->sym = s;
    105		return 1;
    106	}
    107
    108	return 0;
    109}
    110
    111struct section *find_section_by_name(const struct elf *elf, const char *name)
    112{
    113	struct section *sec;
    114
    115	elf_hash_for_each_possible(section_name, sec, name_hash, str_hash(name)) {
    116		if (!strcmp(sec->name, name))
    117			return sec;
    118	}
    119
    120	return NULL;
    121}
    122
    123static struct section *find_section_by_index(struct elf *elf,
    124					     unsigned int idx)
    125{
    126	struct section *sec;
    127
    128	elf_hash_for_each_possible(section, sec, hash, idx) {
    129		if (sec->idx == idx)
    130			return sec;
    131	}
    132
    133	return NULL;
    134}
    135
    136static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx)
    137{
    138	struct symbol *sym;
    139
    140	elf_hash_for_each_possible(symbol, sym, hash, idx) {
    141		if (sym->idx == idx)
    142			return sym;
    143	}
    144
    145	return NULL;
    146}
    147
    148struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
    149{
    150	struct rb_node *node;
    151
    152	rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) {
    153		struct symbol *s = rb_entry(node, struct symbol, node);
    154
    155		if (s->offset == offset && s->type != STT_SECTION)
    156			return s;
    157	}
    158
    159	return NULL;
    160}
    161
    162struct symbol *find_func_by_offset(struct section *sec, unsigned long offset)
    163{
    164	struct rb_node *node;
    165
    166	rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) {
    167		struct symbol *s = rb_entry(node, struct symbol, node);
    168
    169		if (s->offset == offset && s->type == STT_FUNC)
    170			return s;
    171	}
    172
    173	return NULL;
    174}
    175
    176struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset)
    177{
    178	struct rb_node *node;
    179
    180	rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) {
    181		struct symbol *s = rb_entry(node, struct symbol, node);
    182
    183		if (s->type != STT_SECTION)
    184			return s;
    185	}
    186
    187	return NULL;
    188}
    189
    190/*
    191 * Returns size of hole starting at @offset.
    192 */
    193int find_symbol_hole_containing(const struct section *sec, unsigned long offset)
    194{
    195	struct symbol_hole hole = {
    196		.key = offset,
    197		.sym = NULL,
    198	};
    199	struct rb_node *n;
    200	struct symbol *s;
    201
    202	/*
    203	 * Find the rightmost symbol for which @offset is after it.
    204	 */
    205	n = rb_find(&hole, &sec->symbol_tree, symbol_hole_by_offset);
    206
    207	/* found a symbol that contains @offset */
    208	if (n)
    209		return 0; /* not a hole */
    210
    211	/* didn't find a symbol for which @offset is after it */
    212	if (!hole.sym)
    213		return 0; /* not a hole */
    214
    215	/* @offset >= sym->offset + sym->len, find symbol after it */
    216	n = rb_next(&hole.sym->node);
    217	if (!n)
    218		return -1; /* until end of address space */
    219
    220	/* hole until start of next symbol */
    221	s = rb_entry(n, struct symbol, node);
    222	return s->offset - offset;
    223}
    224
    225struct symbol *find_func_containing(struct section *sec, unsigned long offset)
    226{
    227	struct rb_node *node;
    228
    229	rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) {
    230		struct symbol *s = rb_entry(node, struct symbol, node);
    231
    232		if (s->type == STT_FUNC)
    233			return s;
    234	}
    235
    236	return NULL;
    237}
    238
    239struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
    240{
    241	struct symbol *sym;
    242
    243	elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) {
    244		if (!strcmp(sym->name, name))
    245			return sym;
    246	}
    247
    248	return NULL;
    249}
    250
    251struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
    252				     unsigned long offset, unsigned int len)
    253{
    254	struct reloc *reloc, *r = NULL;
    255	unsigned long o;
    256
    257	if (!sec->reloc)
    258		return NULL;
    259
    260	sec = sec->reloc;
    261
    262	for_offset_range(o, offset, offset + len) {
    263		elf_hash_for_each_possible(reloc, reloc, hash,
    264					   sec_offset_hash(sec, o)) {
    265			if (reloc->sec != sec)
    266				continue;
    267
    268			if (reloc->offset >= offset && reloc->offset < offset + len) {
    269				if (!r || reloc->offset < r->offset)
    270					r = reloc;
    271			}
    272		}
    273		if (r)
    274			return r;
    275	}
    276
    277	return NULL;
    278}
    279
    280struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)
    281{
    282	return find_reloc_by_dest_range(elf, sec, offset, 1);
    283}
    284
    285static int read_sections(struct elf *elf)
    286{
    287	Elf_Scn *s = NULL;
    288	struct section *sec;
    289	size_t shstrndx, sections_nr;
    290	int i;
    291
    292	if (elf_getshdrnum(elf->elf, &sections_nr)) {
    293		WARN_ELF("elf_getshdrnum");
    294		return -1;
    295	}
    296
    297	if (elf_getshdrstrndx(elf->elf, &shstrndx)) {
    298		WARN_ELF("elf_getshdrstrndx");
    299		return -1;
    300	}
    301
    302	if (!elf_alloc_hash(section, sections_nr) ||
    303	    !elf_alloc_hash(section_name, sections_nr))
    304		return -1;
    305
    306	for (i = 0; i < sections_nr; i++) {
    307		sec = malloc(sizeof(*sec));
    308		if (!sec) {
    309			perror("malloc");
    310			return -1;
    311		}
    312		memset(sec, 0, sizeof(*sec));
    313
    314		INIT_LIST_HEAD(&sec->symbol_list);
    315		INIT_LIST_HEAD(&sec->reloc_list);
    316
    317		s = elf_getscn(elf->elf, i);
    318		if (!s) {
    319			WARN_ELF("elf_getscn");
    320			return -1;
    321		}
    322
    323		sec->idx = elf_ndxscn(s);
    324
    325		if (!gelf_getshdr(s, &sec->sh)) {
    326			WARN_ELF("gelf_getshdr");
    327			return -1;
    328		}
    329
    330		sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name);
    331		if (!sec->name) {
    332			WARN_ELF("elf_strptr");
    333			return -1;
    334		}
    335
    336		if (sec->sh.sh_size != 0) {
    337			sec->data = elf_getdata(s, NULL);
    338			if (!sec->data) {
    339				WARN_ELF("elf_getdata");
    340				return -1;
    341			}
    342			if (sec->data->d_off != 0 ||
    343			    sec->data->d_size != sec->sh.sh_size) {
    344				WARN("unexpected data attributes for %s",
    345				     sec->name);
    346				return -1;
    347			}
    348		}
    349
    350		if (sec->sh.sh_flags & SHF_EXECINSTR)
    351			elf->text_size += sec->sh.sh_size;
    352
    353		list_add_tail(&sec->list, &elf->sections);
    354		elf_hash_add(section, &sec->hash, sec->idx);
    355		elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
    356	}
    357
    358	if (opts.stats) {
    359		printf("nr_sections: %lu\n", (unsigned long)sections_nr);
    360		printf("section_bits: %d\n", elf->section_bits);
    361	}
    362
    363	/* sanity check, one more call to elf_nextscn() should return NULL */
    364	if (elf_nextscn(elf->elf, s)) {
    365		WARN("section entry mismatch");
    366		return -1;
    367	}
    368
    369	return 0;
    370}
    371
    372static void elf_add_symbol(struct elf *elf, struct symbol *sym)
    373{
    374	struct list_head *entry;
    375	struct rb_node *pnode;
    376
    377	INIT_LIST_HEAD(&sym->pv_target);
    378	sym->alias = sym;
    379
    380	sym->type = GELF_ST_TYPE(sym->sym.st_info);
    381	sym->bind = GELF_ST_BIND(sym->sym.st_info);
    382
    383	if (sym->type == STT_FILE)
    384		elf->num_files++;
    385
    386	sym->offset = sym->sym.st_value;
    387	sym->len = sym->sym.st_size;
    388
    389	rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset);
    390	pnode = rb_prev(&sym->node);
    391	if (pnode)
    392		entry = &rb_entry(pnode, struct symbol, node)->list;
    393	else
    394		entry = &sym->sec->symbol_list;
    395	list_add(&sym->list, entry);
    396	elf_hash_add(symbol, &sym->hash, sym->idx);
    397	elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name));
    398
    399	/*
    400	 * Don't store empty STT_NOTYPE symbols in the rbtree.  They
    401	 * can exist within a function, confusing the sorting.
    402	 */
    403	if (!sym->len)
    404		rb_erase(&sym->node, &sym->sec->symbol_tree);
    405}
    406
    407static int read_symbols(struct elf *elf)
    408{
    409	struct section *symtab, *symtab_shndx, *sec;
    410	struct symbol *sym, *pfunc;
    411	int symbols_nr, i;
    412	char *coldstr;
    413	Elf_Data *shndx_data = NULL;
    414	Elf32_Word shndx;
    415
    416	symtab = find_section_by_name(elf, ".symtab");
    417	if (symtab) {
    418		symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
    419		if (symtab_shndx)
    420			shndx_data = symtab_shndx->data;
    421
    422		symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize;
    423	} else {
    424		/*
    425		 * A missing symbol table is actually possible if it's an empty
    426		 * .o file. This can happen for thunk_64.o. Make sure to at
    427		 * least allocate the symbol hash tables so we can do symbol
    428		 * lookups without crashing.
    429		 */
    430		symbols_nr = 0;
    431	}
    432
    433	if (!elf_alloc_hash(symbol, symbols_nr) ||
    434	    !elf_alloc_hash(symbol_name, symbols_nr))
    435		return -1;
    436
    437	for (i = 0; i < symbols_nr; i++) {
    438		sym = malloc(sizeof(*sym));
    439		if (!sym) {
    440			perror("malloc");
    441			return -1;
    442		}
    443		memset(sym, 0, sizeof(*sym));
    444
    445		sym->idx = i;
    446
    447		if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym,
    448				      &shndx)) {
    449			WARN_ELF("gelf_getsymshndx");
    450			goto err;
    451		}
    452
    453		sym->name = elf_strptr(elf->elf, symtab->sh.sh_link,
    454				       sym->sym.st_name);
    455		if (!sym->name) {
    456			WARN_ELF("elf_strptr");
    457			goto err;
    458		}
    459
    460		if ((sym->sym.st_shndx > SHN_UNDEF &&
    461		     sym->sym.st_shndx < SHN_LORESERVE) ||
    462		    (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) {
    463			if (sym->sym.st_shndx != SHN_XINDEX)
    464				shndx = sym->sym.st_shndx;
    465
    466			sym->sec = find_section_by_index(elf, shndx);
    467			if (!sym->sec) {
    468				WARN("couldn't find section for symbol %s",
    469				     sym->name);
    470				goto err;
    471			}
    472			if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) {
    473				sym->name = sym->sec->name;
    474				sym->sec->sym = sym;
    475			}
    476		} else
    477			sym->sec = find_section_by_index(elf, 0);
    478
    479		elf_add_symbol(elf, sym);
    480	}
    481
    482	if (opts.stats) {
    483		printf("nr_symbols: %lu\n", (unsigned long)symbols_nr);
    484		printf("symbol_bits: %d\n", elf->symbol_bits);
    485	}
    486
    487	/* Create parent/child links for any cold subfunctions */
    488	list_for_each_entry(sec, &elf->sections, list) {
    489		list_for_each_entry(sym, &sec->symbol_list, list) {
    490			char pname[MAX_NAME_LEN + 1];
    491			size_t pnamelen;
    492			if (sym->type != STT_FUNC)
    493				continue;
    494
    495			if (sym->pfunc == NULL)
    496				sym->pfunc = sym;
    497
    498			if (sym->cfunc == NULL)
    499				sym->cfunc = sym;
    500
    501			coldstr = strstr(sym->name, ".cold");
    502			if (!coldstr)
    503				continue;
    504
    505			pnamelen = coldstr - sym->name;
    506			if (pnamelen > MAX_NAME_LEN) {
    507				WARN("%s(): parent function name exceeds maximum length of %d characters",
    508				     sym->name, MAX_NAME_LEN);
    509				return -1;
    510			}
    511
    512			strncpy(pname, sym->name, pnamelen);
    513			pname[pnamelen] = '\0';
    514			pfunc = find_symbol_by_name(elf, pname);
    515
    516			if (!pfunc) {
    517				WARN("%s(): can't find parent function",
    518				     sym->name);
    519				return -1;
    520			}
    521
    522			sym->pfunc = pfunc;
    523			pfunc->cfunc = sym;
    524
    525			/*
    526			 * Unfortunately, -fnoreorder-functions puts the child
    527			 * inside the parent.  Remove the overlap so we can
    528			 * have sane assumptions.
    529			 *
    530			 * Note that pfunc->len now no longer matches
    531			 * pfunc->sym.st_size.
    532			 */
    533			if (sym->sec == pfunc->sec &&
    534			    sym->offset >= pfunc->offset &&
    535			    sym->offset + sym->len == pfunc->offset + pfunc->len) {
    536				pfunc->len -= sym->len;
    537			}
    538		}
    539	}
    540
    541	return 0;
    542
    543err:
    544	free(sym);
    545	return -1;
    546}
    547
    548static struct section *elf_create_reloc_section(struct elf *elf,
    549						struct section *base,
    550						int reltype);
    551
    552int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
    553		  unsigned int type, struct symbol *sym, s64 addend)
    554{
    555	struct reloc *reloc;
    556
    557	if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA))
    558		return -1;
    559
    560	reloc = malloc(sizeof(*reloc));
    561	if (!reloc) {
    562		perror("malloc");
    563		return -1;
    564	}
    565	memset(reloc, 0, sizeof(*reloc));
    566
    567	reloc->sec = sec->reloc;
    568	reloc->offset = offset;
    569	reloc->type = type;
    570	reloc->sym = sym;
    571	reloc->addend = addend;
    572
    573	list_add_tail(&reloc->list, &sec->reloc->reloc_list);
    574	elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
    575
    576	sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize;
    577	sec->reloc->changed = true;
    578
    579	return 0;
    580}
    581
    582/*
    583 * Ensure that any reloc section containing references to @sym is marked
    584 * changed such that it will get re-generated in elf_rebuild_reloc_sections()
    585 * with the new symbol index.
    586 */
    587static void elf_dirty_reloc_sym(struct elf *elf, struct symbol *sym)
    588{
    589	struct section *sec;
    590
    591	list_for_each_entry(sec, &elf->sections, list) {
    592		struct reloc *reloc;
    593
    594		if (sec->changed)
    595			continue;
    596
    597		list_for_each_entry(reloc, &sec->reloc_list, list) {
    598			if (reloc->sym == sym) {
    599				sec->changed = true;
    600				break;
    601			}
    602		}
    603	}
    604}
    605
    606/*
    607 * The libelf API is terrible; gelf_update_sym*() takes a data block relative
    608 * index value, *NOT* the symbol index. As such, iterate the data blocks and
    609 * adjust index until it fits.
    610 *
    611 * If no data block is found, allow adding a new data block provided the index
    612 * is only one past the end.
    613 */
    614static int elf_update_symbol(struct elf *elf, struct section *symtab,
    615			     struct section *symtab_shndx, struct symbol *sym)
    616{
    617	Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF;
    618	Elf_Data *symtab_data = NULL, *shndx_data = NULL;
    619	Elf64_Xword entsize = symtab->sh.sh_entsize;
    620	int max_idx, idx = sym->idx;
    621	Elf_Scn *s, *t = NULL;
    622
    623	s = elf_getscn(elf->elf, symtab->idx);
    624	if (!s) {
    625		WARN_ELF("elf_getscn");
    626		return -1;
    627	}
    628
    629	if (symtab_shndx) {
    630		t = elf_getscn(elf->elf, symtab_shndx->idx);
    631		if (!t) {
    632			WARN_ELF("elf_getscn");
    633			return -1;
    634		}
    635	}
    636
    637	for (;;) {
    638		/* get next data descriptor for the relevant sections */
    639		symtab_data = elf_getdata(s, symtab_data);
    640		if (t)
    641			shndx_data = elf_getdata(t, shndx_data);
    642
    643		/* end-of-list */
    644		if (!symtab_data) {
    645			void *buf;
    646
    647			if (idx) {
    648				/* we don't do holes in symbol tables */
    649				WARN("index out of range");
    650				return -1;
    651			}
    652
    653			/* if @idx == 0, it's the next contiguous entry, create it */
    654			symtab_data = elf_newdata(s);
    655			if (t)
    656				shndx_data = elf_newdata(t);
    657
    658			buf = calloc(1, entsize);
    659			if (!buf) {
    660				WARN("malloc");
    661				return -1;
    662			}
    663
    664			symtab_data->d_buf = buf;
    665			symtab_data->d_size = entsize;
    666			symtab_data->d_align = 1;
    667			symtab_data->d_type = ELF_T_SYM;
    668
    669			symtab->sh.sh_size += entsize;
    670			symtab->changed = true;
    671
    672			if (t) {
    673				shndx_data->d_buf = &sym->sec->idx;
    674				shndx_data->d_size = sizeof(Elf32_Word);
    675				shndx_data->d_align = sizeof(Elf32_Word);
    676				shndx_data->d_type = ELF_T_WORD;
    677
    678				symtab_shndx->sh.sh_size += sizeof(Elf32_Word);
    679				symtab_shndx->changed = true;
    680			}
    681
    682			break;
    683		}
    684
    685		/* empty blocks should not happen */
    686		if (!symtab_data->d_size) {
    687			WARN("zero size data");
    688			return -1;
    689		}
    690
    691		/* is this the right block? */
    692		max_idx = symtab_data->d_size / entsize;
    693		if (idx < max_idx)
    694			break;
    695
    696		/* adjust index and try again */
    697		idx -= max_idx;
    698	}
    699
    700	/* something went side-ways */
    701	if (idx < 0) {
    702		WARN("negative index");
    703		return -1;
    704	}
    705
    706	/* setup extended section index magic and write the symbol */
    707	if (shndx >= SHN_UNDEF && shndx < SHN_LORESERVE) {
    708		sym->sym.st_shndx = shndx;
    709		if (!shndx_data)
    710			shndx = 0;
    711	} else {
    712		sym->sym.st_shndx = SHN_XINDEX;
    713		if (!shndx_data) {
    714			WARN("no .symtab_shndx");
    715			return -1;
    716		}
    717	}
    718
    719	if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) {
    720		WARN_ELF("gelf_update_symshndx");
    721		return -1;
    722	}
    723
    724	return 0;
    725}
    726
    727static struct symbol *
    728elf_create_section_symbol(struct elf *elf, struct section *sec)
    729{
    730	struct section *symtab, *symtab_shndx;
    731	Elf32_Word first_non_local, new_idx;
    732	struct symbol *sym, *old;
    733
    734	symtab = find_section_by_name(elf, ".symtab");
    735	if (symtab) {
    736		symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
    737	} else {
    738		WARN("no .symtab");
    739		return NULL;
    740	}
    741
    742	sym = calloc(1, sizeof(*sym));
    743	if (!sym) {
    744		perror("malloc");
    745		return NULL;
    746	}
    747
    748	sym->name = sec->name;
    749	sym->sec = sec;
    750
    751	// st_name 0
    752	sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION);
    753	// st_other 0
    754	// st_value 0
    755	// st_size 0
    756
    757	/*
    758	 * Move the first global symbol, as per sh_info, into a new, higher
    759	 * symbol index. This fees up a spot for a new local symbol.
    760	 */
    761	first_non_local = symtab->sh.sh_info;
    762	new_idx = symtab->sh.sh_size / symtab->sh.sh_entsize;
    763	old = find_symbol_by_index(elf, first_non_local);
    764	if (old) {
    765		old->idx = new_idx;
    766
    767		hlist_del(&old->hash);
    768		elf_hash_add(symbol, &old->hash, old->idx);
    769
    770		elf_dirty_reloc_sym(elf, old);
    771
    772		if (elf_update_symbol(elf, symtab, symtab_shndx, old)) {
    773			WARN("elf_update_symbol move");
    774			return NULL;
    775		}
    776
    777		new_idx = first_non_local;
    778	}
    779
    780	sym->idx = new_idx;
    781	if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) {
    782		WARN("elf_update_symbol");
    783		return NULL;
    784	}
    785
    786	/*
    787	 * Either way, we added a LOCAL symbol.
    788	 */
    789	symtab->sh.sh_info += 1;
    790
    791	elf_add_symbol(elf, sym);
    792
    793	return sym;
    794}
    795
    796int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
    797			  unsigned long offset, unsigned int type,
    798			  struct section *insn_sec, unsigned long insn_off)
    799{
    800	struct symbol *sym = insn_sec->sym;
    801	int addend = insn_off;
    802
    803	if (!sym) {
    804		/*
    805		 * Due to how weak functions work, we must use section based
    806		 * relocations. Symbol based relocations would result in the
    807		 * weak and non-weak function annotations being overlaid on the
    808		 * non-weak function after linking.
    809		 */
    810		sym = elf_create_section_symbol(elf, insn_sec);
    811		if (!sym)
    812			return -1;
    813
    814		insn_sec->sym = sym;
    815	}
    816
    817	return elf_add_reloc(elf, sec, offset, type, sym, addend);
    818}
    819
    820static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx)
    821{
    822	if (!gelf_getrel(sec->data, i, &reloc->rel)) {
    823		WARN_ELF("gelf_getrel");
    824		return -1;
    825	}
    826	reloc->type = GELF_R_TYPE(reloc->rel.r_info);
    827	reloc->addend = 0;
    828	reloc->offset = reloc->rel.r_offset;
    829	*symndx = GELF_R_SYM(reloc->rel.r_info);
    830	return 0;
    831}
    832
    833static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx)
    834{
    835	if (!gelf_getrela(sec->data, i, &reloc->rela)) {
    836		WARN_ELF("gelf_getrela");
    837		return -1;
    838	}
    839	reloc->type = GELF_R_TYPE(reloc->rela.r_info);
    840	reloc->addend = reloc->rela.r_addend;
    841	reloc->offset = reloc->rela.r_offset;
    842	*symndx = GELF_R_SYM(reloc->rela.r_info);
    843	return 0;
    844}
    845
    846static int read_relocs(struct elf *elf)
    847{
    848	struct section *sec;
    849	struct reloc *reloc;
    850	int i;
    851	unsigned int symndx;
    852	unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
    853
    854	if (!elf_alloc_hash(reloc, elf->text_size / 16))
    855		return -1;
    856
    857	list_for_each_entry(sec, &elf->sections, list) {
    858		if ((sec->sh.sh_type != SHT_RELA) &&
    859		    (sec->sh.sh_type != SHT_REL))
    860			continue;
    861
    862		sec->base = find_section_by_index(elf, sec->sh.sh_info);
    863		if (!sec->base) {
    864			WARN("can't find base section for reloc section %s",
    865			     sec->name);
    866			return -1;
    867		}
    868
    869		sec->base->reloc = sec;
    870
    871		nr_reloc = 0;
    872		for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) {
    873			reloc = malloc(sizeof(*reloc));
    874			if (!reloc) {
    875				perror("malloc");
    876				return -1;
    877			}
    878			memset(reloc, 0, sizeof(*reloc));
    879			switch (sec->sh.sh_type) {
    880			case SHT_REL:
    881				if (read_rel_reloc(sec, i, reloc, &symndx))
    882					return -1;
    883				break;
    884			case SHT_RELA:
    885				if (read_rela_reloc(sec, i, reloc, &symndx))
    886					return -1;
    887				break;
    888			default: return -1;
    889			}
    890
    891			reloc->sec = sec;
    892			reloc->idx = i;
    893			reloc->sym = find_symbol_by_index(elf, symndx);
    894			if (!reloc->sym) {
    895				WARN("can't find reloc entry symbol %d for %s",
    896				     symndx, sec->name);
    897				return -1;
    898			}
    899
    900			list_add_tail(&reloc->list, &sec->reloc_list);
    901			elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc));
    902
    903			nr_reloc++;
    904		}
    905		max_reloc = max(max_reloc, nr_reloc);
    906		tot_reloc += nr_reloc;
    907	}
    908
    909	if (opts.stats) {
    910		printf("max_reloc: %lu\n", max_reloc);
    911		printf("tot_reloc: %lu\n", tot_reloc);
    912		printf("reloc_bits: %d\n", elf->reloc_bits);
    913	}
    914
    915	return 0;
    916}
    917
    918struct elf *elf_open_read(const char *name, int flags)
    919{
    920	struct elf *elf;
    921	Elf_Cmd cmd;
    922
    923	elf_version(EV_CURRENT);
    924
    925	elf = malloc(sizeof(*elf));
    926	if (!elf) {
    927		perror("malloc");
    928		return NULL;
    929	}
    930	memset(elf, 0, offsetof(struct elf, sections));
    931
    932	INIT_LIST_HEAD(&elf->sections);
    933
    934	elf->fd = open(name, flags);
    935	if (elf->fd == -1) {
    936		fprintf(stderr, "objtool: Can't open '%s': %s\n",
    937			name, strerror(errno));
    938		goto err;
    939	}
    940
    941	if ((flags & O_ACCMODE) == O_RDONLY)
    942		cmd = ELF_C_READ_MMAP;
    943	else if ((flags & O_ACCMODE) == O_RDWR)
    944		cmd = ELF_C_RDWR;
    945	else /* O_WRONLY */
    946		cmd = ELF_C_WRITE;
    947
    948	elf->elf = elf_begin(elf->fd, cmd, NULL);
    949	if (!elf->elf) {
    950		WARN_ELF("elf_begin");
    951		goto err;
    952	}
    953
    954	if (!gelf_getehdr(elf->elf, &elf->ehdr)) {
    955		WARN_ELF("gelf_getehdr");
    956		goto err;
    957	}
    958
    959	if (read_sections(elf))
    960		goto err;
    961
    962	if (read_symbols(elf))
    963		goto err;
    964
    965	if (read_relocs(elf))
    966		goto err;
    967
    968	return elf;
    969
    970err:
    971	elf_close(elf);
    972	return NULL;
    973}
    974
    975static int elf_add_string(struct elf *elf, struct section *strtab, char *str)
    976{
    977	Elf_Data *data;
    978	Elf_Scn *s;
    979	int len;
    980
    981	if (!strtab)
    982		strtab = find_section_by_name(elf, ".strtab");
    983	if (!strtab) {
    984		WARN("can't find .strtab section");
    985		return -1;
    986	}
    987
    988	s = elf_getscn(elf->elf, strtab->idx);
    989	if (!s) {
    990		WARN_ELF("elf_getscn");
    991		return -1;
    992	}
    993
    994	data = elf_newdata(s);
    995	if (!data) {
    996		WARN_ELF("elf_newdata");
    997		return -1;
    998	}
    999
   1000	data->d_buf = str;
   1001	data->d_size = strlen(str) + 1;
   1002	data->d_align = 1;
   1003
   1004	len = strtab->sh.sh_size;
   1005	strtab->sh.sh_size += data->d_size;
   1006	strtab->changed = true;
   1007
   1008	return len;
   1009}
   1010
   1011struct section *elf_create_section(struct elf *elf, const char *name,
   1012				   unsigned int sh_flags, size_t entsize, int nr)
   1013{
   1014	struct section *sec, *shstrtab;
   1015	size_t size = entsize * nr;
   1016	Elf_Scn *s;
   1017
   1018	sec = malloc(sizeof(*sec));
   1019	if (!sec) {
   1020		perror("malloc");
   1021		return NULL;
   1022	}
   1023	memset(sec, 0, sizeof(*sec));
   1024
   1025	INIT_LIST_HEAD(&sec->symbol_list);
   1026	INIT_LIST_HEAD(&sec->reloc_list);
   1027
   1028	s = elf_newscn(elf->elf);
   1029	if (!s) {
   1030		WARN_ELF("elf_newscn");
   1031		return NULL;
   1032	}
   1033
   1034	sec->name = strdup(name);
   1035	if (!sec->name) {
   1036		perror("strdup");
   1037		return NULL;
   1038	}
   1039
   1040	sec->idx = elf_ndxscn(s);
   1041	sec->changed = true;
   1042
   1043	sec->data = elf_newdata(s);
   1044	if (!sec->data) {
   1045		WARN_ELF("elf_newdata");
   1046		return NULL;
   1047	}
   1048
   1049	sec->data->d_size = size;
   1050	sec->data->d_align = 1;
   1051
   1052	if (size) {
   1053		sec->data->d_buf = malloc(size);
   1054		if (!sec->data->d_buf) {
   1055			perror("malloc");
   1056			return NULL;
   1057		}
   1058		memset(sec->data->d_buf, 0, size);
   1059	}
   1060
   1061	if (!gelf_getshdr(s, &sec->sh)) {
   1062		WARN_ELF("gelf_getshdr");
   1063		return NULL;
   1064	}
   1065
   1066	sec->sh.sh_size = size;
   1067	sec->sh.sh_entsize = entsize;
   1068	sec->sh.sh_type = SHT_PROGBITS;
   1069	sec->sh.sh_addralign = 1;
   1070	sec->sh.sh_flags = SHF_ALLOC | sh_flags;
   1071
   1072	/* Add section name to .shstrtab (or .strtab for Clang) */
   1073	shstrtab = find_section_by_name(elf, ".shstrtab");
   1074	if (!shstrtab)
   1075		shstrtab = find_section_by_name(elf, ".strtab");
   1076	if (!shstrtab) {
   1077		WARN("can't find .shstrtab or .strtab section");
   1078		return NULL;
   1079	}
   1080	sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name);
   1081	if (sec->sh.sh_name == -1)
   1082		return NULL;
   1083
   1084	list_add_tail(&sec->list, &elf->sections);
   1085	elf_hash_add(section, &sec->hash, sec->idx);
   1086	elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name));
   1087
   1088	elf->changed = true;
   1089
   1090	return sec;
   1091}
   1092
   1093static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base)
   1094{
   1095	char *relocname;
   1096	struct section *sec;
   1097
   1098	relocname = malloc(strlen(base->name) + strlen(".rel") + 1);
   1099	if (!relocname) {
   1100		perror("malloc");
   1101		return NULL;
   1102	}
   1103	strcpy(relocname, ".rel");
   1104	strcat(relocname, base->name);
   1105
   1106	sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rel), 0);
   1107	free(relocname);
   1108	if (!sec)
   1109		return NULL;
   1110
   1111	base->reloc = sec;
   1112	sec->base = base;
   1113
   1114	sec->sh.sh_type = SHT_REL;
   1115	sec->sh.sh_addralign = 8;
   1116	sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
   1117	sec->sh.sh_info = base->idx;
   1118	sec->sh.sh_flags = SHF_INFO_LINK;
   1119
   1120	return sec;
   1121}
   1122
   1123static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base)
   1124{
   1125	char *relocname;
   1126	struct section *sec;
   1127
   1128	relocname = malloc(strlen(base->name) + strlen(".rela") + 1);
   1129	if (!relocname) {
   1130		perror("malloc");
   1131		return NULL;
   1132	}
   1133	strcpy(relocname, ".rela");
   1134	strcat(relocname, base->name);
   1135
   1136	sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rela), 0);
   1137	free(relocname);
   1138	if (!sec)
   1139		return NULL;
   1140
   1141	base->reloc = sec;
   1142	sec->base = base;
   1143
   1144	sec->sh.sh_type = SHT_RELA;
   1145	sec->sh.sh_addralign = 8;
   1146	sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
   1147	sec->sh.sh_info = base->idx;
   1148	sec->sh.sh_flags = SHF_INFO_LINK;
   1149
   1150	return sec;
   1151}
   1152
   1153static struct section *elf_create_reloc_section(struct elf *elf,
   1154					 struct section *base,
   1155					 int reltype)
   1156{
   1157	switch (reltype) {
   1158	case SHT_REL:  return elf_create_rel_reloc_section(elf, base);
   1159	case SHT_RELA: return elf_create_rela_reloc_section(elf, base);
   1160	default:       return NULL;
   1161	}
   1162}
   1163
   1164static int elf_rebuild_rel_reloc_section(struct section *sec)
   1165{
   1166	struct reloc *reloc;
   1167	int idx = 0;
   1168	void *buf;
   1169
   1170	/* Allocate a buffer for relocations */
   1171	buf = malloc(sec->sh.sh_size);
   1172	if (!buf) {
   1173		perror("malloc");
   1174		return -1;
   1175	}
   1176
   1177	sec->data->d_buf = buf;
   1178	sec->data->d_size = sec->sh.sh_size;
   1179	sec->data->d_type = ELF_T_REL;
   1180
   1181	idx = 0;
   1182	list_for_each_entry(reloc, &sec->reloc_list, list) {
   1183		reloc->rel.r_offset = reloc->offset;
   1184		reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
   1185		if (!gelf_update_rel(sec->data, idx, &reloc->rel)) {
   1186			WARN_ELF("gelf_update_rel");
   1187			return -1;
   1188		}
   1189		idx++;
   1190	}
   1191
   1192	return 0;
   1193}
   1194
   1195static int elf_rebuild_rela_reloc_section(struct section *sec)
   1196{
   1197	struct reloc *reloc;
   1198	int idx = 0;
   1199	void *buf;
   1200
   1201	/* Allocate a buffer for relocations with addends */
   1202	buf = malloc(sec->sh.sh_size);
   1203	if (!buf) {
   1204		perror("malloc");
   1205		return -1;
   1206	}
   1207
   1208	sec->data->d_buf = buf;
   1209	sec->data->d_size = sec->sh.sh_size;
   1210	sec->data->d_type = ELF_T_RELA;
   1211
   1212	idx = 0;
   1213	list_for_each_entry(reloc, &sec->reloc_list, list) {
   1214		reloc->rela.r_offset = reloc->offset;
   1215		reloc->rela.r_addend = reloc->addend;
   1216		reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
   1217		if (!gelf_update_rela(sec->data, idx, &reloc->rela)) {
   1218			WARN_ELF("gelf_update_rela");
   1219			return -1;
   1220		}
   1221		idx++;
   1222	}
   1223
   1224	return 0;
   1225}
   1226
   1227static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec)
   1228{
   1229	switch (sec->sh.sh_type) {
   1230	case SHT_REL:  return elf_rebuild_rel_reloc_section(sec);
   1231	case SHT_RELA: return elf_rebuild_rela_reloc_section(sec);
   1232	default:       return -1;
   1233	}
   1234}
   1235
   1236int elf_write_insn(struct elf *elf, struct section *sec,
   1237		   unsigned long offset, unsigned int len,
   1238		   const char *insn)
   1239{
   1240	Elf_Data *data = sec->data;
   1241
   1242	if (data->d_type != ELF_T_BYTE || data->d_off) {
   1243		WARN("write to unexpected data for section: %s", sec->name);
   1244		return -1;
   1245	}
   1246
   1247	memcpy(data->d_buf + offset, insn, len);
   1248	elf_flagdata(data, ELF_C_SET, ELF_F_DIRTY);
   1249
   1250	elf->changed = true;
   1251
   1252	return 0;
   1253}
   1254
   1255int elf_write_reloc(struct elf *elf, struct reloc *reloc)
   1256{
   1257	struct section *sec = reloc->sec;
   1258
   1259	if (sec->sh.sh_type == SHT_REL) {
   1260		reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
   1261		reloc->rel.r_offset = reloc->offset;
   1262
   1263		if (!gelf_update_rel(sec->data, reloc->idx, &reloc->rel)) {
   1264			WARN_ELF("gelf_update_rel");
   1265			return -1;
   1266		}
   1267	} else {
   1268		reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
   1269		reloc->rela.r_addend = reloc->addend;
   1270		reloc->rela.r_offset = reloc->offset;
   1271
   1272		if (!gelf_update_rela(sec->data, reloc->idx, &reloc->rela)) {
   1273			WARN_ELF("gelf_update_rela");
   1274			return -1;
   1275		}
   1276	}
   1277
   1278	elf->changed = true;
   1279
   1280	return 0;
   1281}
   1282
   1283int elf_write(struct elf *elf)
   1284{
   1285	struct section *sec;
   1286	Elf_Scn *s;
   1287
   1288	if (opts.dryrun)
   1289		return 0;
   1290
   1291	/* Update changed relocation sections and section headers: */
   1292	list_for_each_entry(sec, &elf->sections, list) {
   1293		if (sec->changed) {
   1294			s = elf_getscn(elf->elf, sec->idx);
   1295			if (!s) {
   1296				WARN_ELF("elf_getscn");
   1297				return -1;
   1298			}
   1299			if (!gelf_update_shdr(s, &sec->sh)) {
   1300				WARN_ELF("gelf_update_shdr");
   1301				return -1;
   1302			}
   1303
   1304			if (sec->base &&
   1305			    elf_rebuild_reloc_section(elf, sec)) {
   1306				WARN("elf_rebuild_reloc_section");
   1307				return -1;
   1308			}
   1309
   1310			sec->changed = false;
   1311			elf->changed = true;
   1312		}
   1313	}
   1314
   1315	/* Make sure the new section header entries get updated properly. */
   1316	elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
   1317
   1318	/* Write all changes to the file. */
   1319	if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
   1320		WARN_ELF("elf_update");
   1321		return -1;
   1322	}
   1323
   1324	elf->changed = false;
   1325
   1326	return 0;
   1327}
   1328
   1329void elf_close(struct elf *elf)
   1330{
   1331	struct section *sec, *tmpsec;
   1332	struct symbol *sym, *tmpsym;
   1333	struct reloc *reloc, *tmpreloc;
   1334
   1335	if (elf->elf)
   1336		elf_end(elf->elf);
   1337
   1338	if (elf->fd > 0)
   1339		close(elf->fd);
   1340
   1341	list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) {
   1342		list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) {
   1343			list_del(&sym->list);
   1344			hash_del(&sym->hash);
   1345			free(sym);
   1346		}
   1347		list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) {
   1348			list_del(&reloc->list);
   1349			hash_del(&reloc->hash);
   1350			free(reloc);
   1351		}
   1352		list_del(&sec->list);
   1353		free(sec);
   1354	}
   1355
   1356	free(elf);
   1357}