Home | History | Annotate | Download | only in libelf
      1 /* Return the next data element from the section after possibly converting it.
      2    Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc.
      3    This file is part of elfutils.
      4    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      5 
      6    This file is free software; you can redistribute it and/or modify
      7    it under the terms of either
      8 
      9      * the GNU Lesser General Public License as published by the Free
     10        Software Foundation; either version 3 of the License, or (at
     11        your option) any later version
     12 
     13    or
     14 
     15      * the GNU General Public License as published by the Free
     16        Software Foundation; either version 2 of the License, or (at
     17        your option) any later version
     18 
     19    or both in parallel, as here.
     20 
     21    elfutils is distributed in the hope that it will be useful, but
     22    WITHOUT ANY WARRANTY; without even the implied warranty of
     23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     24    General Public License for more details.
     25 
     26    You should have received copies of the GNU General Public License and
     27    the GNU Lesser General Public License along with this program.  If
     28    not, see <http://www.gnu.org/licenses/>.  */
     29 
     30 #ifdef HAVE_CONFIG_H
     31 # include <config.h>
     32 #endif
     33 
     34 #include <errno.h>
     35 #include <stddef.h>
     36 #include <string.h>
     37 #include <unistd.h>
     38 
     39 #include "libelfP.h"
     40 #include <system.h>
     41 #include "common.h"
     42 #include "elf-knowledge.h"
     43 
     44 
     45 #define TYPEIDX(Sh_Type) \
     46   (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM				      \
     47    ? Sh_Type								      \
     48    : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW			      \
     49       ? SHT_NUM + Sh_Type - SHT_GNU_HASH				      \
     50       : 0))
     51 
     52 /* Associate section types with libelf types.  */
     53 static const Elf_Type shtype_map[TYPEIDX (SHT_HISUNW) + 1] =
     54   {
     55       [SHT_SYMTAB] = ELF_T_SYM,
     56       [SHT_RELA] = ELF_T_RELA,
     57       [SHT_HASH] = ELF_T_WORD,
     58       [SHT_DYNAMIC] = ELF_T_DYN,
     59       [SHT_REL] = ELF_T_REL,
     60       [SHT_DYNSYM] = ELF_T_SYM,
     61       [SHT_INIT_ARRAY] = ELF_T_ADDR,
     62       [SHT_FINI_ARRAY] = ELF_T_ADDR,
     63       [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
     64       [SHT_GROUP] = ELF_T_WORD,
     65       [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
     66       [SHT_NOTE] = ELF_T_NHDR, /* Need alignment to guess ELF_T_NHDR8.  */
     67       [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
     68       [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
     69       [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
     70       [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
     71       [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
     72       [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
     73       [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
     74   };
     75 
     76 /* Associate libelf types with their internal alignment requirements.  */
     77 const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
     78   {
     79 # define TYPE_ALIGNS(Bits)						      \
     80     {									      \
     81       [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),			      \
     82       [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),			      \
     83       [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
     84       [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)),			      \
     85       [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)),			      \
     86       [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)),			      \
     87       [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)),			      \
     88       [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),			      \
     89       [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)),			      \
     90       [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)),		      \
     91       [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),			      \
     92       [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),		      \
     93       [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),			      \
     94       [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),			      \
     95       [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),			      \
     96       [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),			      \
     97       [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),		      \
     98       [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),		      \
     99       [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),		      \
    100       [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
    101       [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
    102       [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
    103       [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),			      \
    104       [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),			      \
    105       [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),			      \
    106       [ELF_T_NHDR8] = 8 /* Special case for GNU Property note.  */	      \
    107     }
    108       [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
    109       [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
    110 # undef TYPE_ALIGNS
    111   };
    112 
    113 
    114 Elf_Type
    115 internal_function
    116 __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
    117 {
    118   /* Some broken ELF ABI for 64-bit machines use the wrong hash table
    119      entry size.  See elf-knowledge.h for more information.  */
    120   if (sh_type == SHT_HASH && elf->class == ELFCLASS64)
    121     {
    122       GElf_Ehdr ehdr_mem;
    123       GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
    124       return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
    125     }
    126   else
    127     {
    128       Elf_Type t = shtype_map[TYPEIDX (sh_type)];
    129       /* Special case for GNU Property notes.  */
    130       if (t == ELF_T_NHDR && align == 8)
    131 	t = ELF_T_NHDR8;
    132       return t;
    133     }
    134 }
    135 
    136 /* Convert the data in the current section.  */
    137 static void
    138 convert_data (Elf_Scn *scn, int eclass,
    139 	      int data, size_t size, Elf_Type type)
    140 {
    141   const size_t align = __libelf_type_align (eclass, type);
    142 
    143   /* Do we need to convert the data and/or adjust for alignment?  */
    144   if (data == MY_ELFDATA || type == ELF_T_BYTE)
    145     {
    146       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
    147 	/* No need to copy, we can use the raw data.  */
    148 	scn->data_base = scn->rawdata_base;
    149       else
    150 	{
    151 	  scn->data_base = (char *) malloc (size);
    152 	  if (scn->data_base == NULL)
    153 	    {
    154 	      __libelf_seterrno (ELF_E_NOMEM);
    155 	      return;
    156 	    }
    157 
    158 	  /* The copy will be appropriately aligned for direct access.  */
    159 	  memcpy (scn->data_base, scn->rawdata_base, size);
    160 	}
    161     }
    162   else
    163     {
    164       xfct_t fp;
    165 
    166       scn->data_base = (char *) malloc (size);
    167       if (scn->data_base == NULL)
    168 	{
    169 	  __libelf_seterrno (ELF_E_NOMEM);
    170 	  return;
    171 	}
    172 
    173       /* Make sure the source is correctly aligned for the conversion
    174 	 function to directly access the data elements.  */
    175       char *rawdata_source;
    176       if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
    177 	rawdata_source = scn->rawdata_base;
    178       else
    179 	{
    180 	  rawdata_source = (char *) malloc (size);
    181 	  if (rawdata_source == NULL)
    182 	    {
    183 	      __libelf_seterrno (ELF_E_NOMEM);
    184 	      return;
    185 	    }
    186 
    187 	  /* The copy will be appropriately aligned for direct access.  */
    188 	  memcpy (rawdata_source, scn->rawdata_base, size);
    189 	}
    190 
    191       /* Get the conversion function.  */
    192       fp = __elf_xfctstom[eclass - 1][type];
    193 
    194       fp (scn->data_base, rawdata_source, size, 0);
    195 
    196       if (rawdata_source != scn->rawdata_base)
    197 	free (rawdata_source);
    198     }
    199 
    200   scn->data_list.data.d.d_buf = scn->data_base;
    201   scn->data_list.data.d.d_size = size;
    202   scn->data_list.data.d.d_type = type;
    203   scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
    204   scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
    205   scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
    206 
    207   scn->data_list.data.s = scn;
    208 }
    209 
    210 
    211 /* Store the information for the raw data in the `rawdata' element.  */
    212 int
    213 internal_function
    214 __libelf_set_rawdata_wrlock (Elf_Scn *scn)
    215 {
    216   Elf64_Off offset;
    217   Elf64_Xword size;
    218   Elf64_Xword align;
    219   Elf64_Xword flags;
    220   int type;
    221   Elf *elf = scn->elf;
    222 
    223   if (elf->class == ELFCLASS32)
    224     {
    225       Elf32_Shdr *shdr
    226 	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
    227 
    228       if (shdr == NULL)
    229 	/* Something went terribly wrong.  */
    230 	return 1;
    231 
    232       offset = shdr->sh_offset;
    233       size = shdr->sh_size;
    234       type = shdr->sh_type;
    235       align = shdr->sh_addralign;
    236       flags = shdr->sh_flags;
    237     }
    238   else
    239     {
    240       Elf64_Shdr *shdr
    241 	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
    242 
    243       if (shdr == NULL)
    244 	/* Something went terribly wrong.  */
    245 	return 1;
    246 
    247       offset = shdr->sh_offset;
    248       size = shdr->sh_size;
    249       type = shdr->sh_type;
    250       align = shdr->sh_addralign;
    251       flags = shdr->sh_flags;
    252     }
    253 
    254   /* If the section has no data (for whatever reason), leave the `d_buf'
    255      pointer NULL.  */
    256   if (size != 0 && type != SHT_NOBITS)
    257     {
    258       /* First a test whether the section is valid at all.  */
    259       size_t entsize;
    260 
    261       /* Compressed data has a header, but then compressed data.
    262 	 Make sure to set the alignment of the header explicitly,
    263 	 don't trust the file alignment for the section, it is
    264 	 often wrong.  */
    265       if ((flags & SHF_COMPRESSED) != 0)
    266 	{
    267 	  entsize = 1;
    268 	  align = __libelf_type_align (elf->class, ELF_T_CHDR);
    269 	}
    270       else if (type == SHT_HASH)
    271 	{
    272 	  GElf_Ehdr ehdr_mem;
    273 	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
    274 	  entsize = SH_ENTSIZE_HASH (ehdr);
    275 	}
    276       else
    277 	{
    278 	  Elf_Type t = shtype_map[TYPEIDX (type)];
    279 	  if (t == ELF_T_NHDR && align == 8)
    280 	    t = ELF_T_NHDR8;
    281 	  if (t == ELF_T_VDEF || t == ELF_T_NHDR || t == ELF_T_NHDR8
    282 	      || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
    283 	    entsize = 1;
    284 	  else
    285 	    entsize = __libelf_type_sizes[elf->class - 1][t];
    286 	}
    287 
    288       /* We assume it is an array of bytes if it is none of the structured
    289 	 sections we know of.  */
    290       if (entsize == 0)
    291 	entsize = 1;
    292 
    293       if (unlikely (size % entsize != 0))
    294 	{
    295 	  __libelf_seterrno (ELF_E_INVALID_DATA);
    296 	  return 1;
    297 	}
    298 
    299       /* We can use the mapped or loaded data if available.  */
    300       if (elf->map_address != NULL)
    301 	{
    302 	  /* First see whether the information in the section header is
    303 	     valid and it does not ask for too much.  Check for unsigned
    304 	     overflow.  */
    305 	  if (unlikely (offset > elf->maximum_size
    306 	      || elf->maximum_size - offset < size))
    307 	    {
    308 	      /* Something is wrong.  */
    309 	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
    310 	      return 1;
    311 	    }
    312 
    313 	  scn->rawdata_base = scn->rawdata.d.d_buf
    314 	    = (char *) elf->map_address + elf->start_offset + offset;
    315 	}
    316       else if (likely (elf->fildes != -1))
    317 	{
    318 	  /* First see whether the information in the section header is
    319 	     valid and it does not ask for too much.  Check for unsigned
    320 	     overflow.  */
    321 	  if (unlikely (offset > elf->maximum_size
    322 			|| elf->maximum_size - offset < size))
    323 	    {
    324 	      /* Something is wrong.  */
    325 	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
    326 	      return 1;
    327 	    }
    328 
    329 	  /* We have to read the data from the file.  Allocate the needed
    330 	     memory.  */
    331 	  scn->rawdata_base = scn->rawdata.d.d_buf
    332 	    = (char *) malloc (size);
    333 	  if (scn->rawdata.d.d_buf == NULL)
    334 	    {
    335 	      __libelf_seterrno (ELF_E_NOMEM);
    336 	      return 1;
    337 	    }
    338 
    339 	  ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
    340 				   elf->start_offset + offset);
    341 	  if (unlikely ((size_t) n != size))
    342 	    {
    343 	      /* Cannot read the data.  */
    344 	      free (scn->rawdata.d.d_buf);
    345 	      scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
    346 	      __libelf_seterrno (ELF_E_READ_ERROR);
    347 	      return 1;
    348 	    }
    349 	}
    350       else
    351 	{
    352 	  /* The file descriptor is already closed, we cannot get the data
    353 	     anymore.  */
    354 	  __libelf_seterrno (ELF_E_FD_DISABLED);
    355 	  return 1;
    356 	}
    357     }
    358 
    359   scn->rawdata.d.d_size = size;
    360 
    361   /* Compressed data always has type ELF_T_CHDR regardless of the
    362      section type.  */
    363   if ((flags & SHF_COMPRESSED) != 0)
    364     scn->rawdata.d.d_type = ELF_T_CHDR;
    365   else
    366     scn->rawdata.d.d_type = __libelf_data_type (elf, type, align);
    367   scn->rawdata.d.d_off = 0;
    368 
    369   /* Make sure the alignment makes sense.  d_align should be aligned both
    370      in the section (trivially true since d_off is zero) and in the file.
    371      Unfortunately we cannot be too strict because there are ELF files
    372      out there that fail this requirement.  We will try to fix those up
    373      in elf_update when writing out the image.  But for very large
    374      alignment values this can bloat the image considerably.  So here
    375      just check and clamp the alignment value to not be bigger than the
    376      actual offset of the data in the file.  Given that there is always
    377      at least an ehdr this will only trigger for alignment values > 64
    378      which should be uncommon.  */
    379   align = align ?: 1;
    380   if (type != SHT_NOBITS && align > offset)
    381     align = offset;
    382   scn->rawdata.d.d_align = align;
    383   if (elf->class == ELFCLASS32
    384       || (offsetof (struct Elf, state.elf32.ehdr)
    385 	  == offsetof (struct Elf, state.elf64.ehdr)))
    386     scn->rawdata.d.d_version =
    387       elf->state.elf32.ehdr->e_ident[EI_VERSION];
    388   else
    389     scn->rawdata.d.d_version =
    390       elf->state.elf64.ehdr->e_ident[EI_VERSION];
    391 
    392   scn->rawdata.s = scn;
    393 
    394   scn->data_read = 1;
    395 
    396   /* We actually read data from the file.  At least we tried.  */
    397   scn->flags |= ELF_F_FILEDATA;
    398 
    399   return 0;
    400 }
    401 
    402 int
    403 internal_function
    404 __libelf_set_rawdata (Elf_Scn *scn)
    405 {
    406   int result;
    407 
    408   if (scn == NULL)
    409     return 1;
    410 
    411   rwlock_wrlock (scn->elf->lock);
    412   result = __libelf_set_rawdata_wrlock (scn);
    413   rwlock_unlock (scn->elf->lock);
    414 
    415   return result;
    416 }
    417 
    418 void
    419 internal_function
    420 __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
    421 {
    422   if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
    423     {
    424       Elf *elf = scn->elf;
    425 
    426       /* Upgrade the lock to a write lock if necessary and check
    427 	 nobody else already did the work.  */
    428       if (!wrlocked)
    429 	{
    430 	  rwlock_unlock (elf->lock);
    431 	  rwlock_wrlock (elf->lock);
    432 	  if (scn->data_list_rear != NULL)
    433 	    return;
    434 	}
    435 
    436       /* Convert according to the version and the type.   */
    437       convert_data (scn, elf->class,
    438 		    (elf->class == ELFCLASS32
    439 		     || (offsetof (struct Elf, state.elf32.ehdr)
    440 			 == offsetof (struct Elf, state.elf64.ehdr))
    441 		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
    442 		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
    443 		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
    444     }
    445   else
    446     {
    447       /* This is an empty or NOBITS section.  There is no buffer but
    448 	 the size information etc is important.  */
    449       scn->data_list.data.d = scn->rawdata.d;
    450       scn->data_list.data.s = scn;
    451     }
    452 
    453   scn->data_list_rear = &scn->data_list;
    454 }
    455 
    456 Elf_Data *
    457 internal_function
    458 __elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
    459 {
    460   Elf_Data *result = NULL;
    461   Elf *elf;
    462   int locked = 0;
    463 
    464   if (scn == NULL)
    465     return NULL;
    466 
    467   if (unlikely (scn->elf->kind != ELF_K_ELF))
    468     {
    469       __libelf_seterrno (ELF_E_INVALID_HANDLE);
    470       return NULL;
    471     }
    472 
    473   /* We will need this multiple times later on.  */
    474   elf = scn->elf;
    475 
    476   /* If `data' is not NULL this means we are not addressing the initial
    477      data in the file.  But this also means this data is already read
    478      (since otherwise it is not possible to have a valid `data' pointer)
    479      and all the data structures are initialized as well.  In this case
    480      we can simply walk the list of data records.  */
    481   if (data != NULL)
    482     {
    483       Elf_Data_List *runp;
    484 
    485       /* It is not possible that if DATA is not NULL the first entry is
    486 	 returned.  But this also means that there must be a first data
    487 	 entry.  */
    488       if (scn->data_list_rear == NULL
    489 	  /* The section the reference data is for must match the section
    490 	     parameter.  */
    491 	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
    492 	{
    493 	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
    494 	  goto out;
    495 	}
    496 
    497       /* We start searching with the first entry.  */
    498       runp = &scn->data_list;
    499 
    500       while (1)
    501 	{
    502 	  /* If `data' does not match any known record punt.  */
    503 	  if (runp == NULL)
    504 	    {
    505 	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
    506 	      goto out;
    507 	    }
    508 
    509 	  if (&runp->data.d == data)
    510 	    /* Found the entry.  */
    511 	    break;
    512 
    513 	  runp = runp->next;
    514 	}
    515 
    516       /* Return the data for the next data record.  */
    517       result = runp->next ? &runp->next->data.d : NULL;
    518       goto out;
    519     }
    520 
    521   /* If the data for this section was not yet initialized do it now.  */
    522   if (scn->data_read == 0)
    523     {
    524       /* We cannot acquire a write lock while we are holding a read
    525          lock.  Therefore give up the read lock and then get the write
    526          lock.  But this means that the data could meanwhile be
    527          modified, therefore start the tests again.  */
    528       rwlock_unlock (elf->lock);
    529       rwlock_wrlock (elf->lock);
    530       locked = 1;
    531 
    532       /* Read the data from the file.  There is always a file (or
    533 	 memory region) associated with this descriptor since
    534 	 otherwise the `data_read' flag would be set.  */
    535       if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
    536 	/* Something went wrong.  The error value is already set.  */
    537 	goto out;
    538     }
    539 
    540   /* At this point we know the raw data is available.  But it might be
    541      empty in case the section has size zero (for whatever reason).
    542      Now create the converted data in case this is necessary.  */
    543   if (scn->data_list_rear == NULL)
    544     __libelf_set_data_list_rdlock (scn, locked);
    545 
    546   /* Return the first data element in the list.  */
    547   result = &scn->data_list.data.d;
    548 
    549  out:
    550   return result;
    551 }
    552 
    553 Elf_Data *
    554 elf_getdata (Elf_Scn *scn, Elf_Data *data)
    555 {
    556   Elf_Data *result;
    557 
    558   if (scn == NULL)
    559     return NULL;
    560 
    561   rwlock_rdlock (scn->elf->lock);
    562   result = __elf_getdata_rdlock (scn, data);
    563   rwlock_unlock (scn->elf->lock);
    564 
    565   return result;
    566 }
    567 INTDEF(elf_getdata)
    568