diff options
| author | Mark Stapp <mjs@voltanet.io> | 2021-04-12 08:07:05 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-12 08:07:05 -0400 | 
| commit | 53c42c82deb8e5ee882726c97e62b21e25b03b15 (patch) | |
| tree | d9ca67ff20aa455d8680eee18726f100ce18a631 | |
| parent | 8435eae7bb059df82a886ef03a30c5dd620a21df (diff) | |
| parent | 0490ce41c133f9a801f36668dd58b326ec72a7aa (diff) | |
Merge pull request #8421 from opensourcerouting/xrelfo-arm
fix xrelfo on ARM(32) & cross-compile
| -rw-r--r-- | lib/elf_py.c | 120 | ||||
| -rw-r--r-- | pathd/subdir.am | 5 | ||||
| -rw-r--r-- | pceplib/pcep_msg_tlvs_encoding.c | 9 | ||||
| -rw-r--r-- | pceplib/test/pcep_msg_tlvs_test.c | 9 | ||||
| -rw-r--r-- | python/clippy/elf.py | 5 | 
5 files changed, 124 insertions, 24 deletions
diff --git a/lib/elf_py.c b/lib/elf_py.c index d26e443b82..b47aa3d795 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -1032,7 +1032,7 @@ static char *elfdata_strptr(Elf_Data *data, size_t offset)  static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata,  				 size_t entries, Elf_Data *symdata, -				 Elf_Data *strdata) +				 Elf_Data *strdata, Elf_Type typ)  {  	size_t i; @@ -1041,12 +1041,59 @@ static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata,  		size_t symidx;  		GElf_Rela *rela;  		GElf_Sym *sym; +		GElf_Addr rel_offs = 0;  		relw = (struct elfreloc *)typeobj_elfreloc.tp_alloc(  				&typeobj_elfreloc, 0);  		relw->ef = w; -		rela = relw->rela = gelf_getrela(reldata, i, &relw->_rela); +		if (typ == ELF_T_REL) { +			GElf_Rel _rel, *rel; +			GElf_Addr offs; + +			rel = gelf_getrel(reldata, i, &_rel); +			relw->rela = &relw->_rela; +			relw->rela->r_offset = rel->r_offset; +			relw->rela->r_info = rel->r_info; +			relw->rela->r_addend = 0; +			relw->relative = true; + +			/* REL uses the pointer contents itself instead of the +			 * RELA addend field :( ... theoretically this could +			 * be some weird platform specific encoding, but since +			 * we only care about data relocations it should +			 * always be a pointer... +			 */ +			if (elffile_virt2file(w, rel->r_offset, &offs)) { +				Elf_Data *ptr, *conv; +				GElf_Addr tmp; +				Elf_Data mem = { +					.d_buf = (void *)&tmp, +					.d_type = ELF_T_ADDR, +					.d_version = EV_CURRENT, +					.d_size = sizeof(tmp), +					.d_off = 0, +					.d_align = 0, +				}; + +				ptr = elf_getdata_rawchunk(w->elf, offs, +							   w->elfclass / 8, +							   ELF_T_ADDR); + +				conv = gelf_xlatetom(w->elf, &mem, ptr, +						     w->mmap[EI_DATA]); +				if (conv) { +					memcpy(&rel_offs, conv->d_buf, +					       conv->d_size); + +					relw->relative = false; +					relw->rela->r_addend = rel_offs; +				} +			} +		} else +			relw->rela = gelf_getrela(reldata, i, &relw->_rela); + +		rela = relw->rela;  		symidx = relw->symidx = GELF_R_SYM(rela->r_info);  		sym = relw->sym = gelf_getsym(symdata, symidx, &relw->_sym);  		if (sym) { @@ -1062,9 +1109,16 @@ static void elffile_add_dynreloc(struct elffile *w, Elf_Data *reldata,  			relw->st_value = 0;  		} -		debugf("dynreloc @ %016llx sym %5llu %016llx %s\n", -		       (long long)rela->r_offset, (unsigned long long)symidx, -		       (long long)rela->r_addend, relw->symname); +		if (typ == ELF_T_RELA) +			debugf("dynrela @ %016llx sym %5llu %016llx %s\n", +			       (long long)rela->r_offset, +			       (unsigned long long)symidx, +			       (long long)rela->r_addend, relw->symname); +		else +			debugf("dynrel @ %016llx sym %5llu (%016llx) %s\n", +			       (long long)rela->r_offset, +			       (unsigned long long)symidx, +			       (unsigned long long)rel_offs, relw->symname);  		elfrelocs_add(&w->dynrelocs, relw);  	} @@ -1166,8 +1220,10 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args,  		Elf_Data *dyndata = elf_getdata_rawchunk(w->elf,  				phdr->p_offset, phdr->p_filesz, ELF_T_DYN); -		GElf_Addr dynrela = 0, symtab = 0, strtab = 0; -		size_t dynrelasz = 0, dynrelaent = 0, strsz = 0; +		GElf_Addr dynrela = 0, dynrel = 0, symtab = 0, strtab = 0; +		size_t dynrelasz = 0, dynrelaent = 0; +		size_t dynrelsz = 0, dynrelent = 0; +		size_t strsz = 0;  		GElf_Dyn _dyn, *dyn;  		for (size_t j = 0;; j++) { @@ -1198,16 +1254,20 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args,  				dynrelaent = dyn->d_un.d_val;  				break; +			case DT_REL: +				dynrel = dyn->d_un.d_ptr; +				break;  			case DT_RELSZ: -				if (dyn->d_un.d_val) -					fprintf(stderr, -						"WARNING: ignoring non-empty DT_REL!\n"); +				dynrelsz = dyn->d_un.d_val; +				break; +			case DT_RELENT: +				dynrelent = dyn->d_un.d_val;  				break;  			}  		}  		GElf_Addr offset; -		Elf_Data *symdata = NULL, *strdata = NULL, *reladata = NULL; +		Elf_Data *symdata = NULL, *strdata = NULL;  		if (elffile_virt2file(w, symtab, &offset))  			symdata = elf_getdata_rawchunk(w->elf, offset, @@ -1217,19 +1277,37 @@ static PyObject *elffile_load(PyTypeObject *type, PyObject *args,  			strdata = elf_getdata_rawchunk(w->elf, offset,  						       strsz, ELF_T_BYTE); -		if (!dynrela || !dynrelasz || !dynrelaent) -			continue; +		size_t c; -		if (!elffile_virt2file(w, dynrela, &offset)) -			continue; +		if (dynrela && dynrelasz && dynrelaent +		    && elffile_virt2file(w, dynrela, &offset)) { +			Elf_Data *reladata = NULL; -		debugf("dynrela @%llx/%llx+%llx\n", (long long)dynrela, -		       (long long)offset, (long long)dynrelasz); +			debugf("dynrela @%llx/%llx+%llx\n", (long long)dynrela, +			       (long long)offset, (long long)dynrelasz); -		reladata = elf_getdata_rawchunk(w->elf, offset, dynrelasz, -						ELF_T_RELA); -		elffile_add_dynreloc(w, reladata, dynrelasz / dynrelaent, -				     symdata, strdata); +			reladata = elf_getdata_rawchunk(w->elf, offset, +							dynrelasz, ELF_T_RELA); + +			c = dynrelasz / dynrelaent; +			elffile_add_dynreloc(w, reladata, c, symdata, strdata, +					     ELF_T_RELA); +		} + +		if (dynrel && dynrelsz && dynrelent +		    && elffile_virt2file(w, dynrel, &offset)) { +			Elf_Data *reldata = NULL; + +			debugf("dynrel @%llx/%llx+%llx\n", (long long)dynrel, +			       (long long)offset, (long long)dynrelsz); + +			reldata = elf_getdata_rawchunk(w->elf, offset, dynrelsz, +						       ELF_T_REL); + +			c = dynrelsz / dynrelent; +			elffile_add_dynreloc(w, reldata, c, symdata, strdata, +					     ELF_T_REL); +		}  	}  #endif diff --git a/pathd/subdir.am b/pathd/subdir.am index b4501214bf..fdc08e9e97 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -22,7 +22,6 @@ pathd_libpath_a_SOURCES = \  	pathd/path_cli.c \  	pathd/path_debug.c \  	pathd/path_errors.c \ -	pathd/path_main.c \  	pathd/path_nb.c \  	pathd/path_nb_config.c \  	pathd/path_nb_state.c \ @@ -50,7 +49,9 @@ noinst_HEADERS += \  	pathd/pathd.h \  	# end -pathd_pathd_SOURCES = pathd/path_main.c +pathd_pathd_SOURCES = \ +	pathd/path_main.c \ +	# end  nodist_pathd_pathd_SOURCES = \  	yang/frr-pathd.yang.c \  	# end diff --git a/pceplib/pcep_msg_tlvs_encoding.c b/pceplib/pcep_msg_tlvs_encoding.c index 967f138143..37f3353f76 100644 --- a/pceplib/pcep_msg_tlvs_encoding.c +++ b/pceplib/pcep_msg_tlvs_encoding.c @@ -25,6 +25,15 @@   * Encoding and decoding for PCEP Object TLVs.   */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __FreeBSD__ +#include <sys/endian.h> +#else +#include <endian.h> +#endif /* __FreeBSD__ */  #include <stdlib.h>  #include <string.h> diff --git a/pceplib/test/pcep_msg_tlvs_test.c b/pceplib/test/pcep_msg_tlvs_test.c index 6b650f6823..57e1d16e91 100644 --- a/pceplib/test/pcep_msg_tlvs_test.c +++ b/pceplib/test/pcep_msg_tlvs_test.c @@ -21,6 +21,15 @@   */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __FreeBSD__ +#include <sys/endian.h> +#else +#include <endian.h> +#endif /* __FreeBSD__ */  #include <stdlib.h>  #include <CUnit/CUnit.h> diff --git a/python/clippy/elf.py b/python/clippy/elf.py index 4ed334f0c4..02cb2e38b3 100644 --- a/python/clippy/elf.py +++ b/python/clippy/elf.py @@ -162,7 +162,10 @@ class ELFDissectData(object):          for field in parent._efields[self.elfclass]:              if field[0] == fieldname:                  break -            offset += struct.calcsize(field[1]) +            spec = field[1] +            if spec == 'P': +                spec = 'I' if self.elfclass == 32 else 'Q' +            offset += struct.calcsize(spec)          else:              raise AttributeError('%r not found in %r.fields' % (fieldname, parent))  | 
