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