1da0c48c4Sopenharmony_ci/* Get section at specific index.
2da0c48c4Sopenharmony_ci   Copyright (C) 2005, 2008, 2015 Red Hat, Inc.
3da0c48c4Sopenharmony_ci   This file is part of elfutils.
4da0c48c4Sopenharmony_ci   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
5da0c48c4Sopenharmony_ci
6da0c48c4Sopenharmony_ci   This file is free software; you can redistribute it and/or modify
7da0c48c4Sopenharmony_ci   it under the terms of either
8da0c48c4Sopenharmony_ci
9da0c48c4Sopenharmony_ci     * the GNU Lesser General Public License as published by the Free
10da0c48c4Sopenharmony_ci       Software Foundation; either version 3 of the License, or (at
11da0c48c4Sopenharmony_ci       your option) any later version
12da0c48c4Sopenharmony_ci
13da0c48c4Sopenharmony_ci   or
14da0c48c4Sopenharmony_ci
15da0c48c4Sopenharmony_ci     * the GNU General Public License as published by the Free
16da0c48c4Sopenharmony_ci       Software Foundation; either version 2 of the License, or (at
17da0c48c4Sopenharmony_ci       your option) any later version
18da0c48c4Sopenharmony_ci
19da0c48c4Sopenharmony_ci   or both in parallel, as here.
20da0c48c4Sopenharmony_ci
21da0c48c4Sopenharmony_ci   elfutils is distributed in the hope that it will be useful, but
22da0c48c4Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
23da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24da0c48c4Sopenharmony_ci   General Public License for more details.
25da0c48c4Sopenharmony_ci
26da0c48c4Sopenharmony_ci   You should have received copies of the GNU General Public License and
27da0c48c4Sopenharmony_ci   the GNU Lesser General Public License along with this program.  If
28da0c48c4Sopenharmony_ci   not, see <http://www.gnu.org/licenses/>.  */
29da0c48c4Sopenharmony_ci
30da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H
31da0c48c4Sopenharmony_ci# include <config.h>
32da0c48c4Sopenharmony_ci#endif
33da0c48c4Sopenharmony_ci
34da0c48c4Sopenharmony_ci#include <assert.h>
35da0c48c4Sopenharmony_ci#include <stddef.h>
36da0c48c4Sopenharmony_ci#include <stdlib.h>
37da0c48c4Sopenharmony_ci
38da0c48c4Sopenharmony_ci#include "libelfP.h"
39da0c48c4Sopenharmony_ci
40da0c48c4Sopenharmony_ci#ifndef LIBELFBITS
41da0c48c4Sopenharmony_ci# define LIBELFBITS 32
42da0c48c4Sopenharmony_ci#endif
43da0c48c4Sopenharmony_ci
44da0c48c4Sopenharmony_ci
45da0c48c4Sopenharmony_ciElf_Scn *
46da0c48c4Sopenharmony_cielfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset)
47da0c48c4Sopenharmony_ci{
48da0c48c4Sopenharmony_ci  if (elf == NULL)
49da0c48c4Sopenharmony_ci    return NULL;
50da0c48c4Sopenharmony_ci
51da0c48c4Sopenharmony_ci  if (unlikely (elf->kind != ELF_K_ELF))
52da0c48c4Sopenharmony_ci    {
53da0c48c4Sopenharmony_ci      __libelf_seterrno (ELF_E_INVALID_HANDLE);
54da0c48c4Sopenharmony_ci      return NULL;
55da0c48c4Sopenharmony_ci    }
56da0c48c4Sopenharmony_ci
57da0c48c4Sopenharmony_ci  Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
58da0c48c4Sopenharmony_ci
59da0c48c4Sopenharmony_ci  /* If we have not looked at section headers before,
60da0c48c4Sopenharmony_ci     we might need to read them in first.  */
61da0c48c4Sopenharmony_ci  if (runp->cnt > 0
62da0c48c4Sopenharmony_ci      && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL)
63da0c48c4Sopenharmony_ci      && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL))
64da0c48c4Sopenharmony_ci    return NULL;
65da0c48c4Sopenharmony_ci
66da0c48c4Sopenharmony_ci  rwlock_rdlock (elf->lock);
67da0c48c4Sopenharmony_ci
68da0c48c4Sopenharmony_ci  Elf_Scn *result = NULL;
69da0c48c4Sopenharmony_ci
70da0c48c4Sopenharmony_ci  /* Find the section in the list.  */
71da0c48c4Sopenharmony_ci  while (1)
72da0c48c4Sopenharmony_ci    {
73da0c48c4Sopenharmony_ci      for (unsigned int i = 0; i < runp->cnt; ++i)
74da0c48c4Sopenharmony_ci	if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset)
75da0c48c4Sopenharmony_ci	  {
76da0c48c4Sopenharmony_ci	    result = &runp->data[i];
77da0c48c4Sopenharmony_ci
78da0c48c4Sopenharmony_ci	    /* If this section is empty, the following one has the same
79da0c48c4Sopenharmony_ci	       sh_offset.  We presume the caller is looking for a nonempty
80da0c48c4Sopenharmony_ci	       section, so keep looking if this one is empty.  */
81da0c48c4Sopenharmony_ci	    if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0
82da0c48c4Sopenharmony_ci		&& runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS)
83da0c48c4Sopenharmony_ci	      goto out;
84da0c48c4Sopenharmony_ci	  }
85da0c48c4Sopenharmony_ci
86da0c48c4Sopenharmony_ci      runp = runp->next;
87da0c48c4Sopenharmony_ci      if (runp == NULL)
88da0c48c4Sopenharmony_ci	{
89da0c48c4Sopenharmony_ci	  __libelf_seterrno (ELF_E_INVALID_OFFSET);
90da0c48c4Sopenharmony_ci	  break;
91da0c48c4Sopenharmony_ci	}
92da0c48c4Sopenharmony_ci    }
93da0c48c4Sopenharmony_ci
94da0c48c4Sopenharmony_ci out:
95da0c48c4Sopenharmony_ci  rwlock_unlock (elf->lock);
96da0c48c4Sopenharmony_ci
97da0c48c4Sopenharmony_ci  return result;
98da0c48c4Sopenharmony_ci}
99da0c48c4Sopenharmony_ciINTDEF(elfw2(LIBELFBITS,offscn))
100