source: soft/giet_vm/mover/src/libelfpp/elfpp_section.cc @ 160

Last change on this file since 160 was 160, checked in by karaoui, 12 years ago

giet-vm new version

File size: 3.2 KB
Line 
1/*
2    This file is part of Libelfpp.
3
4    Libelfpp is free software: you can redistribute it and/or modify
5    it under the terms of the GNU Lesser General Public License as
6    published by the Free Software Foundation, either version 3 of the
7    License, or (at your option) any later version.
8
9    Libelfpp is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with Libelfpp.  If not, see
16    <http://www.gnu.org/licenses/>.
17
18   Copyright (c) Alexandre Becoulet <alexandre.becoulet@free.fr>
19*/
20
21
22#include <iostream>
23#include <stdlib.h>
24#include <cstring>
25
26#include <dpp/foreach>
27
28#include <elfpp/section>
29#include <elfpp/object>
30#include <elfpp/segment>
31#include <elfpp/symbol>
32#include <elfpp/reloc>
33
34namespace elfpp
35{
36
37  section::section(object &obj, sh_type_e type)
38    : name_(),
39      type_(type),
40      flags_(SHF_NONE),
41      vaddr_(0),
42      size_(0),
43      link_(0),
44      info_(0),
45      align_(0),
46      entsize_(0),
47      index_(0),
48      back_info_(0),
49      back_link_(0),
50      object_(&obj),
51      content_(0),
52      sym_tab_()
53  {
54  }
55
56  section::~section()
57  {
58    if (!orphan())
59      remove();
60
61    if (content_)
62      free(content_);
63
64    object_->secidx_[index_] = 0;
65
66    FOREACH(s, sym_tab_)
67      delete s->second;
68  }
69
70  void section::set_size(size_t size)
71  {
72    if (type_ != SHT_NOBITS && size_ != size)
73      {
74        content_ = (uint8_t*)realloc(content_, size);
75
76        assert(content_ || size == 0);
77
78        if (size > size_)
79          std::memset(content_ + size_, 0, size - size_);
80      }
81
82    size_ = size;
83  }
84
85  void section::add_symbol(symbol &sym)
86  {
87    sym_tab_.insert(sym_tab_map_t::value_type(sym.get_name(), &sym));
88  }
89
90  symbol & section::get_symbol(uint64_t offset)
91  {
92    symbol *res = 0;
93
94    FOREACH(i, get_symbol_table())
95      {
96        symbol *j = i->second;
97
98        if (!j->get_size())
99          continue;
100
101        if (j->get_value() <= offset && (!res || j->get_value() > res->get_value()))
102          res = j;
103      }
104
105    if (!res)
106      throw std::runtime_error("no symbol found");
107
108    if (offset - res->get_value() >= res->get_size())
109      throw std::runtime_error("offset above symbol size");
110
111    return *res;
112  }
113
114  segment * section::get_segment() const
115  {
116    if (!object_)
117      throw std::runtime_error("section is not part of an object");
118
119    // find associated segment based on section content in elf file
120    FOREACH(s, object_->get_segment_table())
121      {
122        if (get_file_offset() >= s->get_file_offset() &&
123            get_file_offset() < s->get_file_offset() + (off_t)s->get_file_size())
124          return &*s;
125      }
126
127    return 0;
128  }
129
130  uint64_t section::get_load_address() const
131  {
132    segment *s = get_segment();
133
134    if (!s)
135      throw std::runtime_error("section is not located in a segment");
136
137    return vaddr_ - s->get_vaddr() + s->get_paddr();
138  }
139
140  std::ostream & operator<<(std::ostream &o, const section &s)
141  {
142    o << "[" << s.name_ << " addr:0x" << std::hex << s.vaddr_ << " size:" << std::dec << s.size_ << "]";
143    return o;
144  }
145
146}
147
Note: See TracBrowser for help on using the repository browser.