diff options
| author | Mark Wielaard <[email protected]> | 2016-09-15 22:59:03 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2016-09-15 22:59:03 +0200 |
| commit | 51928153ab88f1816a39c5eaf75dc045e08e50c6 (patch) | |
| tree | ec3e0a8e9490d53005e932ea20c1b4659cdf0d77 /libebl | |
| parent | e54140c7cda200dbc2aaa84506577da55941e0ac (diff) | |
| parent | 4512aba06f73704d53cc2ba86f47b9340914e0f2 (diff) | |
Merge tag 'elfutils-0.167' into mjw/RH-DTS
elfutils 0.167 release
Conflicts:
libebl/eblopenbackend.c
src/Makefile.am
tests/Makefile.am
tests/run-readelf-A.sh
Diffstat (limited to 'libebl')
| -rw-r--r-- | libebl/ChangeLog | 40 | ||||
| -rw-r--r-- | libebl/Makefile.am | 8 | ||||
| -rw-r--r-- | libebl/ebl-hooks.h | 10 | ||||
| -rw-r--r-- | libebl/eblgstrtab.c | 365 | ||||
| -rw-r--r-- | libebl/eblobjecttypename.c | 59 | ||||
| -rw-r--r-- | libebl/eblopenbackend.c | 25 | ||||
| -rw-r--r-- | libebl/eblshflagscombine.c | 41 | ||||
| -rw-r--r-- | libebl/eblstrtab.c | 358 | ||||
| -rw-r--r-- | libebl/eblwstrtab.c | 359 | ||||
| -rw-r--r-- | libebl/libebl.h | 79 |
10 files changed, 50 insertions, 1294 deletions
diff --git a/libebl/ChangeLog b/libebl/ChangeLog index 26a4f941..0560c6ac 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,43 @@ +2016-07-08 Mark Wielaard <[email protected]> + + * Makefile.am (gen_SOURCES): Remove eblstrtab.c. + * eblstrtab.c: Removed. + * libebl.h (Ebl_Strtab): Removed. + (Ebl_Strent): Removed. + (ebl_strtabinit): Removed. + (ebl_strtabfree): Removed. + (ebl_strtabadd): Removed. + (ebl_strtabfinalize): Removed. + (ebl_strtaboffset): Removed. + (ebl_string): Removed. + +2016-07-06 Mark Wielaard <[email protected]> + + * Makefile.am (gen_SOURCES): Remove eblobjecttypename.c, + eblshflagscombine.c, eblwstrtab.c and eblgstrtab.c. + * ebl-hooks.h (object_type_name): Removed. + (sh_flags_combine): Likewise. + * eblgstrtab.c: Removed. + * eblobjecttypename.c: Removed. + * eblopenbackend.c (default_object_type_name): Removed. + (default_sh_flags_combine): Likewise. + (fill_defaults): Removed object_type_name and sh_flags_combine. + * eblshflagscombine.c: Removed. + * eblwstrtab.c: Removed. + * libebl.h (ebl_object_type_name): Removed. + (ebl_sh_flags_combine): Likewise. + (ebl_wstrtab*): Removed. + (ebl_gstrtab*): Likewise. + +2016-06-28 Richard Henderson <[email protected]> + + * ebl-hooks.h (EBLHOOK(disasm)): Add ebl parameter. + * eblopenbackend.c (machines): Add EM_BPF entry. + +2016-05-20 Andreas Schwab <[email protected]> + + * eblopenbackend.c (machines) [EM_68K]: Set class and data. + 2016-02-12 Mark Wielaard <[email protected]> * eblobjnotetypename.c (ebl_object_note_type_name): Check name is diff --git a/libebl/Makefile.am b/libebl/Makefile.am index 300d26a7..7034b61c 100644 --- a/libebl/Makefile.am +++ b/libebl/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in ## -## Copyright (C) 2000-2010, 2013 Red Hat, Inc. +## Copyright (C) 2000-2010, 2013, 2016 Red Hat, Inc. ## This file is part of elfutils. ## ## This file is free software; you can redistribute it and/or modify @@ -37,13 +37,11 @@ lib_LIBRARIES = libebl.a pkginclude_HEADERS = libebl.h -gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \ +gen_SOURCES = eblopenbackend.c eblclosebackend.c \ eblreloctypename.c eblsegmenttypename.c \ eblsectiontypename.c eblmachineflagname.c \ eblsymboltypename.c ebldynamictagname.c eblsectionname.c \ - eblobjecttypename.c eblsymbolbindingname.c \ - eblbackendname.c eblshflagscombine.c eblwstrtab.c \ - eblgstrtab.c eblosabiname.c \ + eblsymbolbindingname.c eblbackendname.c eblosabiname.c \ eblmachineflagcheck.c eblmachinesectionflagcheck.c \ eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \ ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \ diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h index 2e314464..b7253748 100644 --- a/libebl/ebl-hooks.h +++ b/libebl/ebl-hooks.h @@ -1,5 +1,5 @@ /* Backend hook signatures internal interface for libebl. - Copyright (C) 2000-2011, 2013, 2014 Red Hat, Inc. + Copyright (C) 2000-2011, 2013, 2014, 2016 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -26,9 +26,6 @@ the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* Return symbol representaton of object file type. */ -const char *EBLHOOK(object_type_name) (int, char *, size_t); - /* Return symbolic representation of relocation type. */ const char *EBLHOOK(reloc_type_name) (int, char *, size_t); @@ -80,9 +77,6 @@ const char *EBLHOOK(dynamic_tag_name) (int64_t, char *, size_t); /* Check dynamic tag. */ bool EBLHOOK(dynamic_tag_check) (int64_t); -/* Combine section header flags values. */ -GElf_Word EBLHOOK(sh_flags_combine) (GElf_Word, GElf_Word); - /* Return symbolic representation of OS ABI. */ const char *EBLHOOK(osabi_name) (int, char *, size_t); @@ -150,7 +144,7 @@ int EBLHOOK(syscall_abi) (Ebl *ebl, int *sp, int *pc, int *callno, int args[6]); /* Disassembler function. */ -int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end, +int EBLHOOK(disasm) (Ebl *ebl, const uint8_t **startp, const uint8_t *end, GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb, DisasmGetSymCB_t symcb, void *outcbarg, void *symcbarg); diff --git a/libebl/eblgstrtab.c b/libebl/eblgstrtab.c deleted file mode 100644 index 0d92c00a..00000000 --- a/libebl/eblgstrtab.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Generic string table handling. - Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <[email protected]>, 2000. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <assert.h> -#include <inttypes.h> -#include <libelf.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/param.h> - -#include "libebl.h" - -#ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - - -struct Ebl_GStrent -{ - const char *string; - size_t len; - struct Ebl_GStrent *next; - struct Ebl_GStrent *left; - struct Ebl_GStrent *right; - size_t offset; - unsigned int width; - char reverse[0]; -}; - - -struct memoryblock -{ - struct memoryblock *next; - char memory[0]; -}; - - -struct Ebl_GStrtab -{ - struct Ebl_GStrent *root; - struct memoryblock *memory; - char *backp; - size_t left; - size_t total; - unsigned int width; - bool nullstr; - - struct Ebl_GStrent null; -}; - - -/* Cache for the pagesize. We correct this value a bit so that `malloc' - is not allocating more than a page. */ -static size_t ps; - - -struct Ebl_GStrtab * -ebl_gstrtabinit (unsigned int width, bool nullstr) -{ - struct Ebl_GStrtab *ret; - - if (ps == 0) - { - ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); - assert (sizeof (struct memoryblock) < ps); - } - - ret = (struct Ebl_GStrtab *) calloc (1, sizeof (struct Ebl_GStrtab)); - if (ret != NULL) - { - ret->width = width; - ret->nullstr = nullstr; - - if (nullstr) - { - ret->null.len = 1; - ret->null.string = (char *) calloc (1, width); - } - } - - return ret; -} - - -static void -morememory (struct Ebl_GStrtab *st, size_t len) -{ - struct memoryblock *newmem; - - if (len < ps) - len = ps; - newmem = (struct memoryblock *) malloc (len); - if (newmem == NULL) - abort (); - - newmem->next = st->memory; - st->memory = newmem; - st->backp = newmem->memory; - st->left = len - offsetof (struct memoryblock, memory); -} - - -void -ebl_gstrtabfree (struct Ebl_GStrtab *st) -{ - struct memoryblock *mb = st->memory; - - while (mb != NULL) - { - void *old = mb; - mb = mb->next; - free (old); - } - - if (st->null.string != NULL) - free ((char *) st->null.string); - - free (st); -} - - -static struct Ebl_GStrent * -newstring (struct Ebl_GStrtab *st, const char *str, size_t len) -{ - /* Compute the amount of padding needed to make the structure aligned. */ - size_t align = ((__alignof__ (struct Ebl_GStrent) - - (((uintptr_t) st->backp) - & (__alignof__ (struct Ebl_GStrent) - 1))) - & (__alignof__ (struct Ebl_GStrent) - 1)); - - /* Make sure there is enough room in the memory block. */ - if (st->left < align + sizeof (struct Ebl_GStrent) + len * st->width) - { - morememory (st, sizeof (struct Ebl_GStrent) + len * st->width); - align = 0; - } - - /* Create the reserved string. */ - struct Ebl_GStrent *newstr = (struct Ebl_GStrent *) (st->backp + align); - newstr->string = str; - newstr->len = len; - newstr->width = st->width; - newstr->next = NULL; - newstr->left = NULL; - newstr->right = NULL; - newstr->offset = 0; - for (int i = len - 2; i >= 0; --i) - for (int j = st->width - 1; j >= 0; --j) - newstr->reverse[i * st->width + j] = str[(len - 2 - i) * st->width + j]; - for (size_t j = 0; j < st->width; ++j) - newstr->reverse[(len - 1) * st->width + j] = '\0'; - st->backp += align + sizeof (struct Ebl_GStrent) + len * st->width; - st->left -= align + sizeof (struct Ebl_GStrent) + len * st->width; - - return newstr; -} - - -/* XXX This function should definitely be rewritten to use a balancing - tree algorith (AVL, red-black trees). For now a simple, correct - implementation is enough. */ -static struct Ebl_GStrent ** -searchstring (struct Ebl_GStrent **sep, struct Ebl_GStrent *newstr) -{ - int cmpres; - - /* More strings? */ - if (*sep == NULL) - { - *sep = newstr; - return sep; - } - - /* Compare the strings. */ - cmpres = memcmp ((*sep)->reverse, newstr->reverse, - (MIN ((*sep)->len, newstr->len) - 1) * (*sep)->width); - if (cmpres == 0) - /* We found a matching string. */ - return sep; - else if (cmpres > 0) - return searchstring (&(*sep)->left, newstr); - else - return searchstring (&(*sep)->right, newstr); -} - - -/* Add new string. The actual string is assumed to be permanent. */ -struct Ebl_GStrent * -ebl_gstrtabadd (struct Ebl_GStrtab *st, const char *str, size_t len) -{ - struct Ebl_GStrent *newstr; - struct Ebl_GStrent **sep; - - /* Compute the string length if the caller doesn't know it. */ - if (len == 0) - { - size_t j; - - do - for (j = 0; j < st->width; ++j) - if (str[len * st->width + j] != '\0') - break; - while (j == st->width && ++len); - } - - /* Make sure all "" strings get offset 0 but only if the table was - created with a special null entry in mind. */ - if (len == 1 && st->null.string != NULL) - return &st->null; - - /* Allocate memory for the new string and its associated information. */ - newstr = newstring (st, str, len); - - /* Search in the array for the place to insert the string. If there - is no string with matching prefix and no string with matching - leading substring, create a new entry. */ - sep = searchstring (&st->root, newstr); - if (*sep != newstr) - { - /* This is not the same entry. This means we have a prefix match. */ - if ((*sep)->len > newstr->len) - { - struct Ebl_GStrent *subs; - - /* Check whether we already know this string. */ - for (subs = (*sep)->next; subs != NULL; subs = subs->next) - if (subs->len == newstr->len) - { - /* We have an exact match with a substring. Free the memory - we allocated. */ - st->left += (st->backp - (char *) newstr) * st->width; - st->backp = (char *) newstr; - - return subs; - } - - /* We have a new substring. This means we don't need the reverse - string of this entry anymore. */ - st->backp -= newstr->len; - st->left += newstr->len; - - newstr->next = (*sep)->next; - (*sep)->next = newstr; - } - else if ((*sep)->len != newstr->len) - { - /* When we get here it means that the string we are about to - add has a common prefix with a string we already have but - it is longer. In this case we have to put it first. */ - st->total += newstr->len - (*sep)->len; - newstr->next = *sep; - newstr->left = (*sep)->left; - newstr->right = (*sep)->right; - *sep = newstr; - } - else - { - /* We have an exact match. Free the memory we allocated. */ - st->left += (st->backp - (char *) newstr) * st->width; - st->backp = (char *) newstr; - - newstr = *sep; - } - } - else - st->total += newstr->len; - - return newstr; -} - - -static void -copystrings (struct Ebl_GStrent *nodep, char **freep, size_t *offsetp) -{ - struct Ebl_GStrent *subs; - - if (nodep->left != NULL) - copystrings (nodep->left, freep, offsetp); - - /* Process the current node. */ - nodep->offset = *offsetp; - *freep = (char *) mempcpy (*freep, nodep->string, nodep->len * nodep->width); - *offsetp += nodep->len * nodep->width; - - for (subs = nodep->next; subs != NULL; subs = subs->next) - { - assert (subs->len < nodep->len); - subs->offset = nodep->offset + (nodep->len - subs->len) * nodep->width; - assert (subs->offset != 0 || subs->string[0] == '\0'); - } - - if (nodep->right != NULL) - copystrings (nodep->right, freep, offsetp); -} - - -void -ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data) -{ - size_t copylen; - char *endp; - size_t nulllen = st->nullstr ? st->width : 0; - - /* Fill in the information. */ - data->d_buf = malloc (st->total + nulllen); - if (data->d_buf == NULL) - abort (); - - /* The first byte must always be zero if we created the table with a - null string. */ - if (st->nullstr) - memset (data->d_buf, '\0', st->width); - - data->d_type = ELF_T_BYTE; - data->d_size = st->total + nulllen; - data->d_off = 0; - data->d_align = 1; - data->d_version = EV_CURRENT; - - /* Now run through the tree and add all the string while also updating - the offset members of the elfstrent records. */ - endp = (char *) data->d_buf + nulllen; - copylen = nulllen; - copystrings (st->root, &endp, ©len); - assert (copylen == st->total * st->width + nulllen); -} - - -size_t -ebl_gstrtaboffset (struct Ebl_GStrent *se) -{ - return se->offset; -} diff --git a/libebl/eblobjecttypename.c b/libebl/eblobjecttypename.c deleted file mode 100644 index b0fd3724..00000000 --- a/libebl/eblobjecttypename.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Return object file type name. - Copyright (C) 2001, 2002 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <[email protected]>, 2001. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdio.h> -#include <libeblP.h> - - -const char * -ebl_object_type_name (Ebl *ebl, int object, char *buf, size_t len) -{ - const char *res; - - res = ebl != NULL ? ebl->object_type_name (object, buf, len) : NULL; - if (res == NULL) - { - /* Handle OS-specific section names. */ - if (object >= ET_LOOS && object <= ET_HIOS) - snprintf (buf, len, "LOOS+%x", object - ET_LOOS); - /* Handle processor-specific section names. */ - else if (object >= ET_LOPROC && object <= ET_HIPROC) - snprintf (buf, len, "LOPROC+%x", object - ET_LOPROC); - else - snprintf (buf, len, "%s: %d", gettext ("<unknown>"), object); - - res = buf; - } - - return res; -} diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c index 5aec99e0..4259dbe5 100644 --- a/libebl/eblopenbackend.c +++ b/libebl/eblopenbackend.c @@ -1,5 +1,5 @@ /* Generate ELF backend handle. - Copyright (C) 2000-2015 Red Hat, Inc. + Copyright (C) 2000-2016 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -48,6 +48,7 @@ const char *ppc64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen); const char *ia64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen); const char *s390_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen); const char *aarch64_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen); +const char *bpf_init (Elf *elf, GElf_Half machine, Ebl *eh, size_t ehlen); /* This table should contain the complete list of architectures as far as the ELF specification is concerned. */ @@ -80,7 +81,7 @@ static const struct { s390_init, "ebl_s390", "s390", 4, EM_S390, 0, 0 }, { NULL, "elf_m32", "m32", 3, EM_M32, 0, 0 }, - { NULL, "elf_m68k", "m68k", 4, EM_68K, 0, 0 }, + { NULL, "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB }, { NULL, "elf_m88k", "m88k", 4, EM_88K, 0, 0 }, { NULL, "elf_i860", "i860", 4, EM_860, 0, 0 }, { NULL, "ebl_s370", "s370", 4, EM_S370, 0, 0 }, @@ -139,6 +140,7 @@ static const struct { NULL, "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 }, { NULL, "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 }, { aarch64_init, "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 }, + { bpf_init, "elf_bpf", "bpf", 3, EM_BPF, 0, 0 }, }; #define nmachines (sizeof (machines) / sizeof (machines[0])) @@ -146,8 +148,6 @@ static const struct #define MAX_PREFIX_LEN 16 /* Default callbacks. Mostly they just return the error value. */ -static const char *default_object_type_name (int ignore, char *buf, - size_t len); static const char *default_reloc_type_name (int ignore, char *buf, size_t len); static bool default_reloc_type_check (int ignore); static bool default_reloc_valid_use (Elf *elf, int ignore); @@ -169,7 +169,6 @@ static const char *default_symbol_binding_name (int ignore, char *buf, static const char *default_dynamic_tag_name (int64_t ignore, char *buf, size_t len); static bool default_dynamic_tag_check (int64_t ignore); -static GElf_Word default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2); static const char *default_osabi_name (int ignore, char *buf, size_t len); static void default_destr (struct ebl *ignore); static const char *default_core_note_type_name (uint32_t, char *buf, @@ -216,7 +215,6 @@ static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info); static void fill_defaults (Ebl *result) { - result->object_type_name = default_object_type_name; result->reloc_type_name = default_reloc_type_name; result->reloc_type_check = default_reloc_type_check; result->reloc_valid_use = default_reloc_valid_use; @@ -233,7 +231,6 @@ fill_defaults (Ebl *result) result->symbol_binding_name = default_symbol_binding_name; result->dynamic_tag_name = default_dynamic_tag_name; result->dynamic_tag_check = default_dynamic_tag_check; - result->sh_flags_combine = default_sh_flags_combine; result->osabi_name = default_osabi_name; result->core_note_type_name = default_core_note_type_name; result->object_note_type_name = default_object_note_type_name; @@ -405,14 +402,6 @@ ebl_openbackend_emulation (const char *emulation) /* Default callbacks. Mostly they just return the error value. */ static const char * -default_object_type_name (int ignore __attribute__ ((unused)), - char *buf __attribute__ ((unused)), - size_t len __attribute__ ((unused))) -{ - return NULL; -} - -static const char * default_reloc_type_name (int ignore __attribute__ ((unused)), char *buf __attribute__ ((unused)), size_t len __attribute__ ((unused))) @@ -529,12 +518,6 @@ default_dynamic_tag_check (int64_t ignore __attribute__ ((unused))) return false; } -static GElf_Word -default_sh_flags_combine (GElf_Word flags1, GElf_Word flags2) -{ - return SH_FLAGS_COMBINE (flags1, flags2); -} - static void default_destr (struct ebl *ignore __attribute__ ((unused))) { diff --git a/libebl/eblshflagscombine.c b/libebl/eblshflagscombine.c deleted file mode 100644 index 4deaaaac..00000000 --- a/libebl/eblshflagscombine.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Return combines section header flags value. - Copyright (C) 2001, 2002 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <[email protected]>, 2001. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <libeblP.h> - - -GElf_Word -ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1, GElf_Word flags2) -{ - return ebl->sh_flags_combine (flags1, flags2); -} diff --git a/libebl/eblstrtab.c b/libebl/eblstrtab.c deleted file mode 100644 index 798c34c3..00000000 --- a/libebl/eblstrtab.c +++ /dev/null @@ -1,358 +0,0 @@ -/* ELF string table handling. - Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <[email protected]>, 2000. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <assert.h> -#include <inttypes.h> -#include <libelf.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/param.h> - -#include "libebl.h" -#include <system.h> - -#ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - - -struct Ebl_Strent -{ - const char *string; - size_t len; - struct Ebl_Strent *next; - struct Ebl_Strent *left; - struct Ebl_Strent *right; - size_t offset; - char reverse[0]; -}; - - -struct memoryblock -{ - struct memoryblock *next; - char memory[0]; -}; - - -struct Ebl_Strtab -{ - struct Ebl_Strent *root; - struct memoryblock *memory; - char *backp; - size_t left; - size_t total; - bool nullstr; - - struct Ebl_Strent null; -}; - - -/* Cache for the pagesize. */ -static size_t ps; -/* We correct this value a bit so that `malloc' is not allocating more - than a page. */ -#define MALLOC_OVERHEAD (2 * sizeof (void *)) - - -struct Ebl_Strtab * -ebl_strtabinit (bool nullstr) -{ - if (ps == 0) - { - ps = sysconf (_SC_PAGESIZE); - assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD); - } - - struct Ebl_Strtab *ret - = (struct Ebl_Strtab *) calloc (1, sizeof (struct Ebl_Strtab)); - if (ret != NULL) - { - ret->nullstr = nullstr; - - if (nullstr) - { - ret->null.len = 1; - ret->null.string = ""; - } - } - - return ret; -} - - -static int -morememory (struct Ebl_Strtab *st, size_t len) -{ - size_t overhead = offsetof (struct memoryblock, memory); - len += overhead + MALLOC_OVERHEAD; - - /* Allocate nearest multiple of pagesize >= len. */ - len = ((len / ps) + (len % ps != 0)) * ps - MALLOC_OVERHEAD; - - struct memoryblock *newmem = (struct memoryblock *) malloc (len); - if (newmem == NULL) - return 1; - - newmem->next = st->memory; - st->memory = newmem; - st->backp = newmem->memory; - st->left = len - overhead; - - return 0; -} - - -void -ebl_strtabfree (struct Ebl_Strtab *st) -{ - struct memoryblock *mb = st->memory; - - while (mb != NULL) - { - void *old = mb; - mb = mb->next; - free (old); - } - - free (st); -} - - -static struct Ebl_Strent * -newstring (struct Ebl_Strtab *st, const char *str, size_t len) -{ - /* Compute the amount of padding needed to make the structure aligned. */ - size_t align = ((__alignof__ (struct Ebl_Strent) - - (((uintptr_t) st->backp) - & (__alignof__ (struct Ebl_Strent) - 1))) - & (__alignof__ (struct Ebl_Strent) - 1)); - - /* Make sure there is enough room in the memory block. */ - if (st->left < align + sizeof (struct Ebl_Strent) + len) - { - if (morememory (st, sizeof (struct Ebl_Strent) + len)) - return NULL; - - align = 0; - } - - /* Create the reserved string. */ - struct Ebl_Strent *newstr = (struct Ebl_Strent *) (st->backp + align); - newstr->string = str; - newstr->len = len; - newstr->next = NULL; - newstr->left = NULL; - newstr->right = NULL; - newstr->offset = 0; - for (int i = len - 2; i >= 0; --i) - newstr->reverse[i] = str[len - 2 - i]; - newstr->reverse[len - 1] = '\0'; - st->backp += align + sizeof (struct Ebl_Strent) + len; - st->left -= align + sizeof (struct Ebl_Strent) + len; - - return newstr; -} - - -/* XXX This function should definitely be rewritten to use a balancing - tree algorith (AVL, red-black trees). For now a simple, correct - implementation is enough. */ -static struct Ebl_Strent ** -searchstring (struct Ebl_Strent **sep, struct Ebl_Strent *newstr) -{ - /* More strings? */ - if (*sep == NULL) - { - *sep = newstr; - return sep; - } - - /* Compare the strings. */ - int cmpres = memcmp ((*sep)->reverse, newstr->reverse, - MIN ((*sep)->len, newstr->len) - 1); - if (cmpres == 0) - /* We found a matching string. */ - return sep; - else if (cmpres > 0) - return searchstring (&(*sep)->left, newstr); - else - return searchstring (&(*sep)->right, newstr); -} - - -/* Add new string. The actual string is assumed to be permanent. */ -struct Ebl_Strent * -ebl_strtabadd (struct Ebl_Strtab *st, const char *str, size_t len) -{ - /* Compute the string length if the caller doesn't know it. */ - if (len == 0) - len = strlen (str) + 1; - - /* Make sure all "" strings get offset 0 but only if the table was - created with a special null entry in mind. */ - if (len == 1 && st->null.string != NULL) - return &st->null; - - /* Allocate memory for the new string and its associated information. */ - struct Ebl_Strent *newstr = newstring (st, str, len); - if (newstr == NULL) - return NULL; - - /* Search in the array for the place to insert the string. If there - is no string with matching prefix and no string with matching - leading substring, create a new entry. */ - struct Ebl_Strent **sep = searchstring (&st->root, newstr); - if (*sep != newstr) - { - /* This is not the same entry. This means we have a prefix match. */ - if ((*sep)->len > newstr->len) - { - /* Check whether we already know this string. */ - for (struct Ebl_Strent *subs = (*sep)->next; subs != NULL; - subs = subs->next) - if (subs->len == newstr->len) - { - /* We have an exact match with a substring. Free the memory - we allocated. */ - st->left += st->backp - (char *) newstr; - st->backp = (char *) newstr; - - return subs; - } - - /* We have a new substring. This means we don't need the reverse - string of this entry anymore. */ - st->backp -= newstr->len; - st->left += newstr->len; - - newstr->next = (*sep)->next; - (*sep)->next = newstr; - } - else if ((*sep)->len != newstr->len) - { - /* When we get here it means that the string we are about to - add has a common prefix with a string we already have but - it is longer. In this case we have to put it first. */ - st->total += newstr->len - (*sep)->len; - newstr->next = *sep; - newstr->left = (*sep)->left; - newstr->right = (*sep)->right; - *sep = newstr; - } - else - { - /* We have an exact match. Free the memory we allocated. */ - st->left += st->backp - (char *) newstr; - st->backp = (char *) newstr; - - newstr = *sep; - } - } - else - st->total += newstr->len; - - return newstr; -} - - -static void -copystrings (struct Ebl_Strent *nodep, char **freep, size_t *offsetp) -{ - if (nodep->left != NULL) - copystrings (nodep->left, freep, offsetp); - - /* Process the current node. */ - nodep->offset = *offsetp; - *freep = (char *) mempcpy (*freep, nodep->string, nodep->len); - *offsetp += nodep->len; - - for (struct Ebl_Strent *subs = nodep->next; subs != NULL; subs = subs->next) - { - assert (subs->len < nodep->len); - subs->offset = nodep->offset + nodep->len - subs->len; - assert (subs->offset != 0 || subs->string[0] == '\0'); - } - - if (nodep->right != NULL) - copystrings (nodep->right, freep, offsetp); -} - - -void -ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data) -{ - size_t nulllen = st->nullstr ? 1 : 0; - - /* Fill in the information. */ - data->d_buf = malloc (st->total + nulllen); - if (data->d_buf == NULL) - abort (); - - /* The first byte must always be zero if we created the table with a - null string. */ - if (st->nullstr) - *((char *) data->d_buf) = '\0'; - - data->d_type = ELF_T_BYTE; - data->d_size = st->total + nulllen; - data->d_off = 0; - data->d_align = 1; - data->d_version = EV_CURRENT; - - /* Now run through the tree and add all the string while also updating - the offset members of the elfstrent records. */ - char *endp = (char *) data->d_buf + nulllen; - size_t copylen = nulllen; - if (st->root) - copystrings (st->root, &endp, ©len); - assert (copylen == st->total + nulllen); -} - - -size_t -ebl_strtaboffset (struct Ebl_Strent *se) -{ - return se->offset; -} - - -const char * -ebl_string (struct Ebl_Strent *se) -{ - assert (se->string != NULL); - - return se->string; -} diff --git a/libebl/eblwstrtab.c b/libebl/eblwstrtab.c deleted file mode 100644 index 08e0ba77..00000000 --- a/libebl/eblwstrtab.c +++ /dev/null @@ -1,359 +0,0 @@ -/* ELF string table handling. - Copyright (C) 2000, 2001, 2002 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <[email protected]>, 2000. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <assert.h> -#include <inttypes.h> -#include <libelf.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <wchar.h> -#include <sys/param.h> - -#include "libebl.h" -#include <system.h> - -#ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - - -struct Ebl_WStrent -{ - const wchar_t *string; - size_t len; - struct Ebl_WStrent *next; - struct Ebl_WStrent *left; - struct Ebl_WStrent *right; - size_t offset; - wchar_t reverse[0]; -}; - - -struct memoryblock -{ - struct memoryblock *next; - char memory[0]; -}; - - -struct Ebl_WStrtab -{ - struct Ebl_WStrent *root; - struct memoryblock *memory; - char *backp; - size_t left; - size_t total; - bool nullstr; - - struct Ebl_WStrent null; -}; - - -/* Cache for the pagesize. We correct this value a bit so that `malloc' - is not allocating more than a page. */ -static size_t ps; - - -struct Ebl_WStrtab * -ebl_wstrtabinit (bool nullstr) -{ - struct Ebl_WStrtab *ret; - - if (ps == 0) - { - ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); - assert (sizeof (struct memoryblock) < ps); - } - - ret = (struct Ebl_WStrtab *) calloc (1, sizeof (struct Ebl_WStrtab)); - if (ret != NULL) - { - ret->nullstr = nullstr; - if (nullstr) - { - ret->null.len = 1; - ret->null.string = L""; - } - } - return ret; -} - - -static int -morememory (struct Ebl_WStrtab *st, size_t len) -{ - struct memoryblock *newmem; - - if (len < ps) - len = ps; - newmem = (struct memoryblock *) malloc (len); - if (newmem == NULL) - return 1; - - newmem->next = st->memory; - st->memory = newmem; - st->backp = newmem->memory; - st->left = len - offsetof (struct memoryblock, memory); - - return 0; -} - - -void -ebl_wstrtabfree (struct Ebl_WStrtab *st) -{ - struct memoryblock *mb = st->memory; - - while (mb != NULL) - { - void *old = mb; - mb = mb->next; - free (old); - } - - free (st); -} - - -static struct Ebl_WStrent * -newstring (struct Ebl_WStrtab *st, const wchar_t *str, size_t len) -{ - struct Ebl_WStrent *newstr; - size_t align; - int i; - - /* Compute the amount of padding needed to make the structure aligned. */ - align = ((__alignof__ (struct Ebl_WStrent) - - (((uintptr_t) st->backp) - & (__alignof__ (struct Ebl_WStrent) - 1))) - & (__alignof__ (struct Ebl_WStrent) - 1)); - - /* Make sure there is enough room in the memory block. */ - if (st->left < align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t)) - { - if (morememory (st, - sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t))) - return NULL; - - align = 0; - } - - /* Create the reserved string. */ - newstr = (struct Ebl_WStrent *) (st->backp + align); - newstr->string = str; - newstr->len = len; - newstr->next = NULL; - newstr->left = NULL; - newstr->right = NULL; - newstr->offset = 0; - for (i = len - 2; i >= 0; --i) - newstr->reverse[i] = str[len - 2 - i]; - newstr->reverse[len - 1] = L'\0'; - st->backp += align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t); - st->left -= align + sizeof (struct Ebl_WStrent) + len * sizeof (wchar_t); - - return newstr; -} - - -/* XXX This function should definitely be rewritten to use a balancing - tree algorith (AVL, red-black trees). For now a simple, correct - implementation is enough. */ -static struct Ebl_WStrent ** -searchstring (struct Ebl_WStrent **sep, struct Ebl_WStrent *newstr) -{ - int cmpres; - - /* More strings? */ - if (*sep == NULL) - { - *sep = newstr; - return sep; - } - - /* Compare the strings. */ - cmpres = wmemcmp ((*sep)->reverse, newstr->reverse, - MIN ((*sep)->len, newstr->len) - 1); - if (cmpres == 0) - /* We found a matching string. */ - return sep; - else if (cmpres > 0) - return searchstring (&(*sep)->left, newstr); - else - return searchstring (&(*sep)->right, newstr); -} - - -/* Add new string. The actual string is assumed to be permanent. */ -struct Ebl_WStrent * -ebl_wstrtabadd (struct Ebl_WStrtab *st, const wchar_t *str, size_t len) -{ - struct Ebl_WStrent *newstr; - struct Ebl_WStrent **sep; - - /* Compute the string length if the caller doesn't know it. */ - if (len == 0) - len = wcslen (str) + 1; - - /* Make sure all "" strings get offset 0 but only if the table was - created with a special null entry in mind. */ - if (len == 1 && st->null.string != NULL) - return &st->null; - - /* Allocate memory for the new string and its associated information. */ - newstr = newstring (st, str, len); - if (newstr == NULL) - return NULL; - - /* Search in the array for the place to insert the string. If there - is no string with matching prefix and no string with matching - leading substring, create a new entry. */ - sep = searchstring (&st->root, newstr); - if (*sep != newstr) - { - /* This is not the same entry. This means we have a prefix match. */ - if ((*sep)->len > newstr->len) - { - struct Ebl_WStrent *subs; - - /* Check whether we already know this string. */ - for (subs = (*sep)->next; subs != NULL; subs = subs->next) - if (subs->len == newstr->len) - { - /* We have an exact match with a substring. Free the memory - we allocated. */ - st->left += st->backp - (char *) newstr; - st->backp = (char *) newstr; - - return subs; - } - - /* We have a new substring. This means we don't need the reverse - string of this entry anymore. */ - st->backp -= newstr->len; - st->left += newstr->len; - - newstr->next = (*sep)->next; - (*sep)->next = newstr; - } - else if ((*sep)->len != newstr->len) - { - /* When we get here it means that the string we are about to - add has a common prefix with a string we already have but - it is longer. In this case we have to put it first. */ - st->total += newstr->len - (*sep)->len; - newstr->next = *sep; - newstr->left = (*sep)->left; - newstr->right = (*sep)->right; - *sep = newstr; - } - else - { - /* We have an exact match. Free the memory we allocated. */ - st->left += st->backp - (char *) newstr; - st->backp = (char *) newstr; - - newstr = *sep; - } - } - else - st->total += newstr->len; - - return newstr; -} - - -static void -copystrings (struct Ebl_WStrent *nodep, wchar_t **freep, size_t *offsetp) -{ - struct Ebl_WStrent *subs; - - if (nodep->left != NULL) - copystrings (nodep->left, freep, offsetp); - - /* Process the current node. */ - nodep->offset = *offsetp; - *freep = wmempcpy (*freep, nodep->string, nodep->len); - *offsetp += nodep->len * sizeof (wchar_t); - - for (subs = nodep->next; subs != NULL; subs = subs->next) - { - assert (subs->len < nodep->len); - subs->offset = nodep->offset + nodep->len - subs->len; - assert (subs->offset != 0 || subs->string[0] == '\0'); - } - - if (nodep->right != NULL) - copystrings (nodep->right, freep, offsetp); -} - - -void -ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data) -{ - size_t copylen; - wchar_t *endp; - size_t nulllen = st->nullstr ? 1 : 0; - - /* Fill in the information. */ - data->d_buf = malloc ((st->total + nulllen) * sizeof (wchar_t)); - if (data->d_buf == NULL) - abort (); - - /* The first byte must always be zero if we created the table with a - null string. */ - if (st->nullstr) - *((wchar_t *) data->d_buf) = L'\0'; - - data->d_type = ELF_T_BYTE; - data->d_size = st->total + nulllen; - data->d_off = 0; - data->d_align = 1; - data->d_version = EV_CURRENT; - - /* Now run through the tree and add all the string while also updating - the offset members of the elfstrent records. */ - endp = (wchar_t *) data->d_buf + nulllen; - copylen = sizeof (wchar_t) * nulllen; - copystrings (st->root, &endp, ©len); - assert (copylen == (st->total + nulllen) * sizeof (wchar_t)); -} - - -size_t -ebl_wstrtaboffset (struct Ebl_WStrent *se) -{ - return se->offset; -} diff --git a/libebl/libebl.h b/libebl/libebl.h index efcb6d60..c8e01fe9 100644 --- a/libebl/libebl.h +++ b/libebl/libebl.h @@ -1,5 +1,5 @@ /* Interface for libebl. - Copyright (C) 2000-2010, 2013, 2014, 2015 Red Hat, Inc. + Copyright (C) 2000-2010, 2013, 2014, 2015, 2016 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -89,10 +89,6 @@ extern int ebl_get_elfdata (Ebl *ebl) __attribute__ ((__pure__)); extern const char *ebl_backend_name (Ebl *ebl); /* Return relocation type name. */ -extern const char *ebl_object_type_name (Ebl *ebl, int object, - char *buf, size_t len); - -/* Return relocation type name. */ extern const char *ebl_reloc_type_name (Ebl *ebl, int reloc, char *buf, size_t len); @@ -163,10 +159,6 @@ extern bool ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr, /* Check whether only valid bits are set on the st_other symbol flag. */ extern bool ebl_check_st_other_bits (Ebl *ebl, unsigned char st_other); -/* Return combined section header flags value. */ -extern GElf_Word ebl_sh_flags_combine (Ebl *ebl, GElf_Word flags1, - GElf_Word flags2); - /* Return symbolic representation of OS ABI. */ extern const char *ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len); @@ -295,75 +287,6 @@ extern int ebl_syscall_abi (Ebl *ebl, int *sp, int *pc, extern int ebl_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info) __nonnull_attribute__ (2); -/* ELF string table handling. */ -struct Ebl_Strtab; -struct Ebl_Strent; - -/* Create new ELF string table object in memory. */ -extern struct Ebl_Strtab *ebl_strtabinit (bool nullstr); - -/* Free resources allocated for ELF string table ST. */ -extern void ebl_strtabfree (struct Ebl_Strtab *st); - -/* Add string STR (length LEN is != 0) to ELF string table ST. */ -extern struct Ebl_Strent *ebl_strtabadd (struct Ebl_Strtab *st, - const char *str, size_t len); - -/* Finalize string table ST and store size and memory location information - in DATA. */ -extern void ebl_strtabfinalize (struct Ebl_Strtab *st, Elf_Data *data); - -/* Get offset in string table for string associated with SE. */ -extern size_t ebl_strtaboffset (struct Ebl_Strent *se); - -/* Return the string associated with SE. */ -extern const char *ebl_string (struct Ebl_Strent *se); - - -/* ELF wide char string table handling. */ -struct Ebl_WStrtab; -struct Ebl_WStrent; - -/* Create new ELF wide char string table object in memory. */ -extern struct Ebl_WStrtab *ebl_wstrtabinit (bool nullstr); - -/* Free resources allocated for ELF wide char string table ST. */ -extern void ebl_wstrtabfree (struct Ebl_WStrtab *st); - -/* Add string STR (length LEN is != 0) to ELF string table ST. */ -extern struct Ebl_WStrent *ebl_wstrtabadd (struct Ebl_WStrtab *st, - const wchar_t *str, size_t len); - -/* Finalize string table ST and store size and memory location information - in DATA. */ -extern void ebl_wstrtabfinalize (struct Ebl_WStrtab *st, Elf_Data *data); - -/* Get offset in wide char string table for string associated with SE. */ -extern size_t ebl_wstrtaboffset (struct Ebl_WStrent *se); - - -/* Generic string table handling. */ -struct Ebl_GStrtab; -struct Ebl_GStrent; - -/* Create new string table object in memory. */ -extern struct Ebl_GStrtab *ebl_gstrtabinit (unsigned int width, bool nullstr); - -/* Free resources allocated for string table ST. */ -extern void ebl_gstrtabfree (struct Ebl_GStrtab *st); - -/* Add string STR (length LEN is != 0) to string table ST. */ -extern struct Ebl_GStrent *ebl_gstrtabadd (struct Ebl_GStrtab *st, - const char *str, size_t len); - -/* Finalize string table ST and store size and memory location information - in DATA. */ -extern void ebl_gstrtabfinalize (struct Ebl_GStrtab *st, Elf_Data *data); - -/* Get offset in wide char string table for string associated with SE. */ -extern size_t ebl_gstrtaboffset (struct Ebl_GStrent *se); - - /* Register map info. */ typedef struct { |
