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