1/* Get section at specific index.
2   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Red Hat, Inc.
3   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation, version 2.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software Foundation,
16   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21
22#include <assert.h>
23#include <stddef.h>
24#include <stdlib.h>
25
26#include "libelfP.h"
27
28
29Elf_Scn *
30elf_getscn (elf, idx)
31     Elf *elf;
32     size_t idx;
33{
34  if (elf == NULL)
35    return NULL;
36
37  if (unlikely (elf->kind != ELF_K_ELF))
38    {
39      __libelf_seterrno (ELF_E_INVALID_HANDLE);
40      return NULL;
41    }
42
43  rwlock_rdlock (elf->lock);
44
45  Elf_Scn *result = NULL;
46
47  /* Find the section in the list.  */
48  Elf_ScnList *runp = (elf->class == ELFCLASS32
49		       || (offsetof (struct Elf, state.elf32.scns)
50			   == offsetof (struct Elf, state.elf64.scns))
51		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
52  while (1)
53    {
54      if (idx < runp->max)
55	{
56	  if (idx < runp->cnt)
57	    result = &runp->data[idx];
58	  else
59	    __libelf_seterrno (ELF_E_INVALID_INDEX);
60	  break;
61	}
62
63      idx -= runp->max;
64
65      runp = runp->next;
66      if (runp == NULL)
67	{
68	  __libelf_seterrno (ELF_E_INVALID_INDEX);
69	  break;
70	}
71    }
72
73  rwlock_unlock (elf->lock);
74
75  return result;
76}
77INTDEF(elf_getscn)
78