1ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao/*
2ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Copyright 2011, The Android Open Source Project
3ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
4ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * you may not use this file except in compliance with the License.
6ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * You may obtain a copy of the License at
7ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
8ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
10ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
11ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * See the License for the specific language governing permissions and
14ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * limitations under the License.
15ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao */
16ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao
176ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#ifndef ELF_SECTION_PROGBITS_HXX
186ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#define ELF_SECTION_PROGBITS_HXX
196ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
206ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#include "ELFTypes.h"
212061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien#include "StubLayout.h"
226ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
236ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#include <llvm/Support/Format.h>
246ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#include <llvm/Support/raw_ostream.h>
256ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
266ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#include "utils/raw_ostream.h"
276ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
282061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien#include <string.h>
292061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
306ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chientemplate <unsigned Bitwidth>
3174f7a939f44d926babd52f59978e6b093e4bb2d0Logan Chientemplate <typename Archiver>
3274f7a939f44d926babd52f59978e6b093e4bb2d0Logan ChienELFSectionProgBits<Bitwidth> *
3374f7a939f44d926babd52f59978e6b093e4bb2d0Logan ChienELFSectionProgBits<Bitwidth>::read(Archiver &AR,
342061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien                                   ELFObjectTy *owner,
3574f7a939f44d926babd52f59978e6b093e4bb2d0Logan Chien                                   ELFSectionHeaderTy const *sh) {
3672dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  int machine = owner->getHeader()->getMachine();
3772dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  ELFSectionProgBits *secp = new ELFSectionProgBits(machine);
3872dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  llvm::OwningPtr<ELFSectionProgBits> result(secp);
3972dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  size_t max_num_stubs = 0;
40e8d2d07e1f060d434a475944e714bf8e00caf754Shih-wei Liao  // Align section boundary to 4 bytes.
41e8d2d07e1f060d434a475944e714bf8e00caf754Shih-wei Liao  size_t section_size = (sh->getSize() + 3) / 4 * 4;
42e8d2d07e1f060d434a475944e714bf8e00caf754Shih-wei Liao  size_t alloc_size = section_size;
4372dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  StubLayout *stubs = result->getStubLayout();
4472dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  if (stubs) {
4572dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    // Compute the maximal possible numbers of stubs
4672dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    std::string reltab_name(".rel" + std::string(sh->getName()));
476ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
4872dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    ELFSectionRelTableTy const *reltab =
4972dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh      static_cast<ELFSectionRelTableTy *>(
5072dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh        owner->getSectionByName(reltab_name.c_str()));
516ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
5272dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    if (reltab) {
5372dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh      // If we have relocation table, then get the approximation of
5472dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh      // maximum numbers of stubs.
5572dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh      max_num_stubs = reltab->getMaxNumStubs(owner);
5672dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    }
572061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
5872dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    // Compute the stub table size
5972dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    size_t stub_table_size = stubs->calcStubTableSize(max_num_stubs);
602061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
6172dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    // Allocate PROGBITS section with stubs table
6272dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh    alloc_size += stub_table_size;
637cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  }
642061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
6572dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  // Allocate text section
667cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  if (!result->chunk.allocate(alloc_size)) {
67fa06e91015017e8d0627d26a88e2a575643bec11Shih-wei Liao    return NULL;
68fa06e91015017e8d0627d26a88e2a575643bec11Shih-wei Liao  }
692061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
7072dca268900fa25946bade332f0fbdc2c2ff9487Andrew Hsieh  if (stubs) {
71e8d2d07e1f060d434a475944e714bf8e00caf754Shih-wei Liao    stubs->initStubTable(result->chunk.getBuffer() + section_size,
72e8d2d07e1f060d434a475944e714bf8e00caf754Shih-wei Liao                         max_num_stubs);
7374f7a939f44d926babd52f59978e6b093e4bb2d0Logan Chien  }
746ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
7574f7a939f44d926babd52f59978e6b093e4bb2d0Logan Chien  result->sh = sh;
766ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
772061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien  if (!result->serialize(AR)) {
782061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien    // Unable to read the progbits section.
792061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien    return NULL;
802061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien  }
812061b057e0922ac33b9314c1ccaa50eb7286b847Logan Chien
8274f7a939f44d926babd52f59978e6b093e4bb2d0Logan Chien  return result.take();
836ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien}
846ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien
856ea6f71f24bc6cf759b2458209f3ef86559c685aLogan Chien#endif // ELF_SECTION_PROGBITS_HXX
86