ELFSectionProgBits.hxx revision ee6cdb95525abc8c7766798148302306a100b774
1/*
2 * Copyright 2011, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ELF_SECTION_PROGBITS_HXX
18#define ELF_SECTION_PROGBITS_HXX
19
20#include "ELFTypes.h"
21#include "StubLayout.h"
22
23#include <llvm/Support/Format.h>
24#include <llvm/Support/raw_ostream.h>
25
26#include "utils/raw_ostream.h"
27
28#include <string.h>
29
30template <unsigned Bitwidth>
31template <typename Archiver>
32ELFSectionProgBits<Bitwidth> *
33ELFSectionProgBits<Bitwidth>::read(Archiver &AR,
34                                   ELFObjectTy *owner,
35                                   ELFSectionHeaderTy const *sh) {
36
37  llvm::OwningPtr<ELFSectionProgBits> result(new ELFSectionProgBits());
38
39  bool is_text_section = strcmp(sh->getName(), ".text") == 0;
40
41  if (!is_text_section) {
42    if (!result->chunk.allocate(sh->getSize())) {
43      return NULL;
44    }
45
46  } else {
47#ifdef __arm__
48    StubLayout *stubs = owner->getStubLayout();
49
50    // Count the extern function symbol
51    ELFSectionSymTabTy const *symtab =
52      static_cast<ELFSectionSymTabTy *>(owner->getSectionByName(".symtab"));
53
54    size_t func_count = symtab->getExternFuncCount();
55
56    // Calculate additional stub size
57    size_t stub_size = stubs->calcStubTableSize(func_count);
58
59    // Allocate text section
60    if (!result->chunk.allocate(sh->getSize() + stub_size)) {
61      return NULL;
62    }
63
64    stubs->initStubTable(result->chunk.getBuffer()+sh->getSize(), func_count);
65#else
66    // Allocate text section
67    if (!result->chunk.allocate(sh->getSize())) {
68      return NULL;
69    }
70#endif
71  }
72
73  result->sh = sh;
74
75  if (!result->serialize(AR)) {
76    // Unable to read the progbits section.
77    return NULL;
78  }
79
80  return result.take();
81}
82
83#endif // ELF_SECTION_PROGBITS_HXX
84